1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts.verifier; 18 19 import android.app.AlertDialog; 20 import android.content.ContentResolver; 21 import android.content.ContentValues; 22 import android.content.Context; 23 import android.content.DialogInterface; 24 import android.content.DialogInterface.OnCancelListener; 25 import android.database.Cursor; 26 import android.view.LayoutInflater; 27 import android.view.View; 28 import android.view.View.OnClickListener; 29 30 /** 31 * {@link Activity}s to handle clicks to the pass and fail buttons of the pass fail buttons layout. 32 * 33 * <ol> 34 * <li>Include the pass fail buttons layout in your layout: 35 * <pre><include layout="@layout/pass_fail_buttons" /></pre> 36 * </li> 37 * <li>Extend one of the activities to get the click handler for the buttons.</li> 38 * <li>Make sure to call setResult(RESULT_CANCEL) in your Activity initially.</li> 39 * <li>Optionally call setInfoTextResources to add an info button that will show a 40 * dialog with instructional text.</li> 41 * </ol> 42 */ 43 public class PassFailButtons { 44 45 // Interface mostly for making documentation and refactoring easier... 46 private interface PassFailActivity { 47 48 /** 49 * Adds an initial informational dialog that appears when entering the test activity for 50 * the first time. Also enables the visibility of an "Info" button between the "Pass" and 51 * "Fail" buttons that can be clicked to show the information dialog again. 52 * <p> 53 * Call from {@link Activity#onCreate} after {@link Activity #setContentView(int)}. 54 * 55 * @param titleId for the text shown in the dialog title area 56 * @param messageId for the text shown in the dialog's body area 57 */ 58 void setInfoResources(int titleId, int messageId, int viewId); 59 60 /** 61 * Click handler for the pass and fail buttons. No need to call this ever as the XML 62 * view layout will bind to this automatically. 63 */ 64 void passFailButtonsClickHandler(View target); 65 } 66 67 public static class Activity extends android.app.Activity implements PassFailActivity { 68 69 public void setInfoResources(int titleId, int messageId, int viewId) { 70 setInfo(this, titleId, messageId, viewId); 71 } 72 73 public void passFailButtonsClickHandler(View target) { 74 setTestResultAndFinish(this, target); 75 } 76 } 77 78 public static class ListActivity extends android.app.ListActivity implements PassFailActivity { 79 80 public void setInfoResources(int titleId, int messageId, int viewId) { 81 setInfo(this, titleId, messageId, viewId); 82 } 83 84 public void passFailButtonsClickHandler(View target) { 85 setTestResultAndFinish(this, target); 86 } 87 } 88 89 private static void setInfo(final android.app.Activity activity, final int titleId, 90 final int messageId, final int viewId) { 91 // Show the middle "info" button and make it show the info dialog when clicked. 92 View infoButton = activity.findViewById(R.id.info_button); 93 infoButton.setVisibility(View.VISIBLE); 94 infoButton.setOnClickListener(new OnClickListener() { 95 public void onClick(View view) { 96 showInfoDialog(activity, titleId, messageId, viewId); 97 } 98 }); 99 100 // Show the info dialog if the user has never seen it before. 101 if (!hasSeenInfoDialog(activity)) { 102 showInfoDialog(activity, titleId, messageId, viewId); 103 } 104 } 105 106 private static boolean hasSeenInfoDialog(android.app.Activity activity) { 107 ContentResolver resolver = activity.getContentResolver(); 108 Cursor cursor = null; 109 try { 110 cursor = resolver.query( 111 TestResultsProvider.getTestNameUri(activity.getClass().getName()), 112 new String[] {TestResultsProvider.COLUMN_TEST_INFO_SEEN}, null, null, null); 113 return cursor.moveToFirst() && cursor.getInt(0) > 0; 114 } finally { 115 if (cursor != null) { 116 cursor.close(); 117 } 118 } 119 } 120 121 private static void showInfoDialog(final android.app.Activity activity, int titleId, 122 int messageId, int viewId) { 123 AlertDialog.Builder builder = new AlertDialog.Builder(activity).setIcon( 124 android.R.drawable.ic_dialog_info).setTitle(titleId); 125 if (viewId > 0) { 126 LayoutInflater inflater = (LayoutInflater) activity 127 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 128 builder.setView(inflater.inflate(viewId, null)); 129 } else { 130 builder.setMessage(messageId); 131 } 132 builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 133 public void onClick(DialogInterface dialog, int which) { 134 markSeenInfoDialog(activity); 135 } 136 }).setOnCancelListener(new OnCancelListener() { 137 public void onCancel(DialogInterface dialog) { 138 markSeenInfoDialog(activity); 139 } 140 }) 141 .show(); 142 } 143 144 private static void markSeenInfoDialog(android.app.Activity activity) { 145 ContentResolver resolver = activity.getContentResolver(); 146 ContentValues values = new ContentValues(2); 147 values.put(TestResultsProvider.COLUMN_TEST_NAME, activity.getClass().getName()); 148 values.put(TestResultsProvider.COLUMN_TEST_INFO_SEEN, 1); 149 int numUpdated = resolver.update( 150 TestResultsProvider.getTestNameUri(activity.getClass().getName()), 151 values, null, null); 152 if (numUpdated == 0) { 153 resolver.insert(TestResultsProvider.RESULTS_CONTENT_URI, values); 154 } 155 } 156 157 /** Set the test result corresponding to the button clicked and finish the activity. */ 158 private static void setTestResultAndFinish(android.app.Activity activity, View target) { 159 switch (target.getId()) { 160 case R.id.pass_button: 161 TestResult.setPassedResult(activity); 162 break; 163 164 case R.id.fail_button: 165 TestResult.setFailedResult(activity); 166 break; 167 168 default: 169 throw new IllegalArgumentException("Unknown id: " + target.getId()); 170 } 171 172 activity.finish(); 173 } 174 } 175