--- /dev/null
+/*
+ * Copyright (C) 2010 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.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnCancelListener;
+import android.database.Cursor;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+/**
+ * {@link Activity}s to handle clicks to the pass and fail buttons of the pass fail buttons layout.
+ *
+ * <ol>
+ * <li>Include the pass fail buttons layout in your layout:
+ * <pre><include layout="@layout/pass_fail_buttons" /></pre>
+ * </li>
+ * <li>Extend one of the activities to get the click handler for the buttons.</li>
+ * <li>Make sure to call setResult(RESULT_CANCEL) in your Activity initially.</li>
+ * <li>Optionally call setInfoTextResources to add an info button that will show a
+ * dialog with instructional text.</li>
+ * </ol>
+ */
+public class PassFailButtons {
+
+ // Interface mostly for making documentation and refactoring easier...
+ private interface PassFailActivity {
+
+ /**
+ * Adds an initial informational dialog that appears when entering the test activity for
+ * the first time. Also enables the visibility of an "Info" button between the "Pass" and
+ * "Fail" buttons that can be clicked to show the information dialog again.
+ * <p>
+ * Call from {@link Activity#onCreate} after {@link Activity #setContentView(int)}.
+ *
+ * @param titleId for the text shown in the dialog title area
+ * @param messageId for the text shown in the dialog's body area
+ */
+ void setInfoResources(int titleId, int messageId, int viewId);
+
+ /**
+ * Click handler for the pass and fail buttons. No need to call this ever as the XML
+ * view layout will bind to this automatically.
+ */
+ void passFailButtonsClickHandler(View target);
+ }
+
+ public static class Activity extends android.app.Activity implements PassFailActivity {
+
+ public void setInfoResources(int titleId, int messageId, int viewId) {
+ setInfo(this, titleId, messageId, viewId);
+ }
+
+ public void passFailButtonsClickHandler(View target) {
+ setTestResultAndFinish(this, target);
+ }
+ }
+
+ public static class ListActivity extends android.app.ListActivity implements PassFailActivity {
+
+ public void setInfoResources(int titleId, int messageId, int viewId) {
+ setInfo(this, titleId, messageId, viewId);
+ }
+
+ public void passFailButtonsClickHandler(View target) {
+ setTestResultAndFinish(this, target);
+ }
+ }
+
+ private static void setInfo(final android.app.Activity activity, final int titleId,
+ final int messageId, final int viewId) {
+ // Show the middle "info" button and make it show the info dialog when clicked.
+ View infoButton = activity.findViewById(R.id.info_button);
+ infoButton.setVisibility(View.VISIBLE);
+ infoButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View view) {
+ showInfoDialog(activity, titleId, messageId, viewId);
+ }
+ });
+
+ // Show the info dialog if the user has never seen it before.
+ if (!hasSeenInfoDialog(activity)) {
+ showInfoDialog(activity, titleId, messageId, viewId);
+ }
+ }
+
+ private static boolean hasSeenInfoDialog(android.app.Activity activity) {
+ ContentResolver resolver = activity.getContentResolver();
+ Cursor cursor = null;
+ try {
+ cursor = resolver.query(
+ TestResultsProvider.getTestNameUri(activity.getClass().getName()),
+ new String[] {TestResultsProvider.COLUMN_TEST_INFO_SEEN}, null, null, null);
+ return cursor.moveToFirst() && cursor.getInt(0) > 0;
+ } finally {
+ if (cursor != null) {
+ cursor.close();
+ }
+ }
+ }
+
+ private static void showInfoDialog(final android.app.Activity activity, int titleId,
+ int messageId, int viewId) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(activity).setIcon(
+ android.R.drawable.ic_dialog_info).setTitle(titleId);
+ if (viewId > 0) {
+ LayoutInflater inflater = (LayoutInflater) activity
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ builder.setView(inflater.inflate(viewId, null));
+ } else {
+ builder.setMessage(messageId);
+ }
+ builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ markSeenInfoDialog(activity);
+ }
+ }).setOnCancelListener(new OnCancelListener() {
+ public void onCancel(DialogInterface dialog) {
+ markSeenInfoDialog(activity);
+ }
+ })
+ .show();
+ }
+
+ private static void markSeenInfoDialog(android.app.Activity activity) {
+ ContentResolver resolver = activity.getContentResolver();
+ ContentValues values = new ContentValues(2);
+ values.put(TestResultsProvider.COLUMN_TEST_NAME, activity.getClass().getName());
+ values.put(TestResultsProvider.COLUMN_TEST_INFO_SEEN, 1);
+ int numUpdated = resolver.update(
+ TestResultsProvider.getTestNameUri(activity.getClass().getName()),
+ values, null, null);
+ if (numUpdated == 0) {
+ resolver.insert(TestResultsProvider.RESULTS_CONTENT_URI, values);
+ }
+ }
+
+ /** Set the test result corresponding to the button clicked and finish the activity. */
+ private static void setTestResultAndFinish(android.app.Activity activity, View target) {
+ switch (target.getId()) {
+ case R.id.pass_button:
+ TestResult.setPassedResult(activity);
+ break;
+
+ case R.id.fail_button:
+ TestResult.setFailedResult(activity);
+ break;
+
+ default:
+ throw new IllegalArgumentException("Unknown id: " + target.getId());
+ }
+
+ activity.finish();
+ }
+}