blob: cbd48872a8271114267f88703830ba06088fbeb7 [file] [log] [blame]
/*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.verifier;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.cts.verifier.R;
/**
* Test list activity that supports showing dialogs with pass/fail buttons instead of
* starting new activities.
* In addition to that dialogs have a 'go' button that can be configured to launch an intent.
* Instructions are shown on top of the screen and a test preparation button is provided.
*/
public abstract class DialogTestListActivity extends PassFailButtons.TestListActivity {
private final int mLayoutId;
private final int mTitleStringId;
private final int mInfoStringId;
private final int mInstructionsStringId;
protected Button mPrepareTestButton;
protected int mCurrentTestPosition;
protected DialogTestListActivity(int layoutId, int titleStringId, int infoStringId,
int instructionsStringId) {
mLayoutId = layoutId;
mTitleStringId = titleStringId;
mInfoStringId = infoStringId;
mInstructionsStringId = instructionsStringId;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(mLayoutId);
setInfoResources(mTitleStringId, mInfoStringId, -1);
setPassFailButtonClickListeners();
getPassButton().setEnabled(false);
setResult(RESULT_CANCELED);
ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
setupTests(adapter);
adapter.registerDataSetObserver(new DataSetObserver() {
@Override
public void onChanged() {
updatePassButton();
}
});
setTestListAdapter(adapter);
mCurrentTestPosition = 0;
TextView instructionTextView = (TextView)findViewById(R.id.test_instructions);
instructionTextView.setText(mInstructionsStringId);
mPrepareTestButton = (Button)findViewById(R.id.prepare_test_button);
}
/**
* Subclasses must add their tests items to the provided adapter(usually instances of
* {@link DialogTestListItem} or {@link DialogTestListItemWithIcon} but any class deriving from
* {@link TestListAdapter.TestListItem} will do).
* @param adapter The adapter to add test items to.
*/
protected abstract void setupTests(ArrayTestListAdapter adapter);
// Enable Pass Button when all tests passed.
private void updatePassButton() {
getPassButton().setEnabled(mAdapter.allTestsPassed());
}
private void showManualTestDialog(final DialogTestListItem test) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(mTitleStringId)
.setNeutralButton(R.string.go_button_text, null)
.setPositiveButton(R.string.pass_button_text, new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
clearRemainingState(test);
setTestResult(test, TestResult.TEST_RESULT_PASSED);
}
})
.setNegativeButton(R.string.fail_button_text, new AlertDialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
clearRemainingState(test);
setTestResult(test, TestResult.TEST_RESULT_FAILED);
}
});
View customView = test.getCustomView();
if (customView != null) {
dialogBuilder.setView(customView);
} else {
dialogBuilder.setMessage(test.getManualTestInstruction());
}
final AlertDialog dialog = dialogBuilder.show();
// Note: Setting the OnClickListener on the Dialog rather than the Builder, prevents the
// dialog being dismissed on onClick.
dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (!startTestIntent(test)) {
dialog.dismiss();
}
}
});
}
@Override
protected void handleItemClick(ListView l, View v, int position, long id) {
TestListAdapter.TestListItem test = (TestListAdapter.TestListItem) getListAdapter()
.getItem(position);
if (test instanceof DialogTestListItem) {
mCurrentTestPosition = position;
((DialogTestListItem)test).performTest(this);
} else {
super.handleItemClick(l, v, position, id);
}
}
/**
* Start a test's manual intent
* @param test The test the manual intent of which is to be started.
* @return true if activity could be started successfully, false otherwise.
*/
boolean startTestIntent(final DialogTestListItem test) {
final Intent intent = test.intent;
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
Toast.makeText(this, "Cannot start " + intent, Toast.LENGTH_LONG).show();
setTestResult(test, TestResult.TEST_RESULT_FAILED);
return false;
}
return true;
}
protected void clearRemainingState(final DialogTestListItem test) {
// do nothing, override in subclass if needed
}
protected void setTestResult(DialogTestListItem test, int result) {
// Bundle result in an intent to feed into handleLaunchTestResult
Intent resultIntent = new Intent();
TestResult.addResultData(resultIntent, result, test.testName, /* testDetails */ null,
/* reportLog */ null);
handleLaunchTestResult(RESULT_OK, resultIntent);
getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
}
protected void showToast(int messageId) {
String message = getString(messageId);
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
protected static class DialogTestListItem extends TestListAdapter.TestListItem {
private String mManualInstruction;
public DialogTestListItem(Context context, int nameResId, String testId) {
super(context.getString(nameResId), testId, null, null, null, null);
}
public DialogTestListItem(Context context, int nameResId, String testId,
int testInstructionResId, Intent testIntent) {
super(context.getString(nameResId), testId, testIntent, null, null, null);
mManualInstruction = context.getString(testInstructionResId);
}
public void performTest(DialogTestListActivity activity) {
activity.showManualTestDialog(this);
}
public String getManualTestInstruction() {
return mManualInstruction;
}
public Intent getManualTestIntent() {
return intent;
}
public View getCustomView() {
return null;
}
@Override
boolean isTest() {
return true;
}
}
protected static class DialogTestListItemWithIcon extends DialogTestListItem {
private final int mImageResId;
private final Context mContext;
public DialogTestListItemWithIcon(Context context, int nameResId, String testId,
int testInstructionResId, Intent testIntent, int imageResId) {
super(context, nameResId, testId, testInstructionResId, testIntent);
mContext = context;
mImageResId = imageResId;
}
@Override
public View getCustomView() {
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View view = layoutInflater.inflate(R.layout.dialog_custom_view,
null /* root */);
((ImageView) view.findViewById(R.id.sample_icon)).setImageResource(mImageResId);
((TextView) view.findViewById(R.id.message)).setText(getManualTestInstruction());
return view;
}
}
}