1 /* 2 * Copyright (C) 2015 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 package android.voiceinteraction.common; 17 18 import android.app.VoiceInteractor.PickOptionRequest.Option; 19 import android.content.LocusId; 20 import android.os.Bundle; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.util.Log; 24 25 import java.util.ArrayList; 26 import java.util.concurrent.CountDownLatch; 27 import java.util.concurrent.TimeUnit; 28 import java.util.concurrent.locks.Condition; 29 30 public class Utils { 31 public enum TestCaseType { 32 COMPLETION_REQUEST_TEST, 33 COMPLETION_REQUEST_CANCEL_TEST, 34 CONFIRMATION_REQUEST_TEST, 35 CONFIRMATION_REQUEST_CANCEL_TEST, 36 ABORT_REQUEST_TEST, 37 ABORT_REQUEST_CANCEL_TEST, 38 PICKOPTION_REQUEST_TEST, 39 PICKOPTION_REQUEST_CANCEL_TEST, 40 COMMANDREQUEST_TEST, 41 COMMANDREQUEST_CANCEL_TEST, 42 SUPPORTS_COMMANDS_TEST 43 } 44 45 private static final String TAG = Utils.class.getSimpleName(); 46 47 public static final long OPERATION_TIMEOUT_MS = 5000; 48 49 /** CDD restricts the max size of each successful hotword result is 100 bytes. */ 50 public static final int MAX_HOTWORD_DETECTED_RESULT_SIZE = 100; 51 52 /** 53 * Limits the max value for the hotword offset. 54 * 55 * Note: Must match the definition in 56 * frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java. 57 */ 58 public static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE = 60 * 60 * 1000; // 1 hour 59 60 /** 61 * Limits the max value for the triggered audio channel. 62 * 63 * Note: Must match the definition in 64 * frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java. 65 */ 66 public static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE = 63; 67 68 /** Decide which VoiceInteractionService should be started for testing. */ 69 public static final int HOTWORD_DETECTION_SERVICE_NONE = 0; 70 public static final int HOTWORD_DETECTION_SERVICE_BASIC = 1; 71 public static final int HOTWORD_DETECTION_SERVICE_INVALIDATION = 2; 72 public static final int HOTWORD_DETECTION_SERVICE_WITHOUT_ISOLATED_PROCESS = 3; 73 public static final int HOTWORD_DETECTION_SERVICE_WITHIN_ISOLATED_PROCESS = 4; 74 75 /** 76 * Indicate which test event for testing. 77 * 78 * Note: The VIS is the abbreviation of VoiceInteractionService 79 */ 80 public static final int VIS_NORMAL_TEST = 0; 81 public static final int VIS_WITHOUT_MANAGE_HOTWORD_DETECTION_PERMISSION_TEST = 1; 82 public static final int VIS_HOLD_BIND_HOTWORD_DETECTION_PERMISSION_TEST = 2; 83 84 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_TEST = 100; 85 public static final int HOTWORD_DETECTION_SERVICE_DSP_ONDETECT_TEST = 101; 86 public static final int HOTWORD_DETECTION_SERVICE_EXTERNAL_SOURCE_ONDETECT_TEST = 102; 87 public static final int HOTWORD_DETECTION_SERVICE_FROM_SOFTWARE_TRIGGER_TEST = 103; 88 public static final int HOTWORD_DETECTION_SERVICE_MIC_ONDETECT_TEST = 104; 89 public static final int HOTWORD_DETECTION_SERVICE_DSP_ONREJECT_TEST = 105; 90 public static final int HOTWORD_DETECTION_SERVICE_PROCESS_DIED_TEST = 106; 91 public static final int HOTWORD_DETECTION_SERVICE_CALL_STOP_RECOGNITION = 107; 92 93 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SUCCESS = 1; 94 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_ILLEGAL_STATE_EXCEPTION = 2; 95 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SECURITY_EXCEPTION = 3; 96 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SHARED_MEMORY_NOT_READ_ONLY = 4; 97 public static final int HOTWORD_DETECTION_SERVICE_GET_ERROR = 5; 98 99 /** Indicate which test scenario for testing. */ 100 public static final int HOTWORD_DETECTION_SERVICE_ON_UPDATE_STATE_CRASH = 1; 101 102 public static final String TESTCASE_TYPE = "testcase_type"; 103 public static final String TESTINFO = "testinfo"; 104 public static final String BROADCAST_INTENT = "android.intent.action.VOICE_TESTAPP"; 105 public static final String TEST_PROMPT = "testprompt"; 106 public static final String PICKOPTON_1 = "one"; 107 public static final String PICKOPTON_2 = "two"; 108 public static final String PICKOPTON_3 = "3"; 109 public static final String TEST_COMMAND = "test_command"; 110 public static final String TEST_ONCOMMAND_RESULT = "test_oncommand_result"; 111 public static final String TEST_ONCOMMAND_RESULT_VALUE = "test_oncommand_result value"; 112 113 public static final String CONFIRMATION_REQUEST_SUCCESS = "confirmation ok"; 114 public static final String COMPLETION_REQUEST_SUCCESS = "completion ok"; 115 public static final String ABORT_REQUEST_SUCCESS = "abort ok"; 116 public static final String PICKOPTION_REQUEST_SUCCESS = "pickoption ok"; 117 public static final String COMMANDREQUEST_SUCCESS = "commandrequest ok"; 118 public static final String SUPPORTS_COMMANDS_SUCCESS = "supportsCommands ok"; 119 120 public static final String CONFIRMATION_REQUEST_CANCEL_SUCCESS = "confirm cancel ok"; 121 public static final String COMPLETION_REQUEST_CANCEL_SUCCESS = "completion canel ok"; 122 public static final String ABORT_REQUEST_CANCEL_SUCCESS = "abort cancel ok"; 123 public static final String PICKOPTION_REQUEST_CANCEL_SUCCESS = "pickoption cancel ok"; 124 public static final String COMMANDREQUEST_CANCEL_SUCCESS = "commandrequest cancel ok"; 125 public static final String TEST_ERROR = "Error In Test:"; 126 127 public static final String PRIVATE_OPTIONS_KEY = "private_key"; 128 public static final String PRIVATE_OPTIONS_VALUE = "private_value"; 129 130 public static final String DIRECT_ACTION_EXTRA_KEY = "directActionExtraKey"; 131 public static final String DIRECT_ACTION_EXTRA_VALUE = "directActionExtraValue"; 132 public static final String DIRECT_ACTION_FILE_NAME = "directActionFileName"; 133 public static final String DIRECT_ACTION_FILE_CONTENT = "directActionFileContent"; 134 public static final String DIRECT_ACTION_AUTHORITY = 135 "android.voiceinteraction.testapp.fileprovider"; 136 137 public static final String DIRECT_ACTIONS_KEY_CALLBACK = "callback"; 138 public static final String DIRECT_ACTIONS_KEY_CANCEL_CALLBACK = "cancelCallback"; 139 public static final String DIRECT_ACTIONS_KEY_CONTROL = "control"; 140 public static final String DIRECT_ACTIONS_KEY_COMMAND = "command"; 141 public static final String DIRECT_ACTIONS_KEY_RESULT = "result"; 142 public static final String DIRECT_ACTIONS_KEY_ACTION = "action"; 143 public static final String DIRECT_ACTIONS_KEY_ARGUMENTS = "arguments"; 144 public static final String DIRECT_ACTIONS_KEY_CLASS = "class"; 145 146 public static final String DIRECT_ACTIONS_SESSION_CMD_PERFORM_ACTION = "performAction"; 147 public static final String DIRECT_ACTIONS_SESSION_CMD_PERFORM_ACTION_CANCEL = 148 "performActionCancel"; 149 public static final String DIRECT_ACTIONS_SESSION_CMD_DETECT_ACTIONS_CHANGED = 150 "detectActionsChanged"; 151 public static final String DIRECT_ACTIONS_SESSION_CMD_GET_ACTIONS = "getActions"; 152 public static final String DIRECT_ACTIONS_SESSION_CMD_FINISH = "hide"; 153 154 public static final String DIRECT_ACTIONS_ACTIVITY_CMD_DESTROYED_INTERACTOR = 155 "destroyedInteractor"; 156 public static final String DIRECT_ACTIONS_ACTIVITY_CMD_FINISH = "finish"; 157 public static final String DIRECT_ACTIONS_ACTIVITY_CMD_INVALIDATE_ACTIONS = "invalidateActions"; 158 159 public static final String DIRECT_ACTIONS_RESULT_PERFORMED = "performed"; 160 public static final String DIRECT_ACTIONS_RESULT_CANCELLED = "cancelled"; 161 public static final String DIRECT_ACTIONS_RESULT_EXECUTING = "executing"; 162 163 public static final String DIRECT_ACTIONS_ACTION_ID = "actionId"; 164 public static final Bundle DIRECT_ACTIONS_ACTION_EXTRAS = new Bundle(); 165 static { DIRECT_ACTIONS_ACTION_EXTRAS.putString(DIRECT_ACTION_EXTRA_KEY, DIRECT_ACTION_EXTRA_VALUE)166 DIRECT_ACTIONS_ACTION_EXTRAS.putString(DIRECT_ACTION_EXTRA_KEY, 167 DIRECT_ACTION_EXTRA_VALUE); 168 } 169 public static final LocusId DIRECT_ACTIONS_LOCUS_ID = new LocusId("locusId"); 170 171 public static final String SERVICE_NAME = 172 "android.voiceinteraction.service/.MainInteractionService"; 173 174 public static final String HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT = 175 "android.intent.action.HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT"; 176 public static final String HOTWORD_DETECTION_SERVICE_ONDETECT_RESULT_INTENT = 177 "android.intent.action.HOTWORD_DETECTION_SERVICE_ONDETECT_RESULT"; 178 public static final String KEY_SERVICE_TYPE = "serviceType"; 179 public static final String KEY_TEST_EVENT = "testEvent"; 180 public static final String KEY_TEST_RESULT = "testResult"; 181 public static final String KEY_TEST_SCENARIO = "testScenario"; 182 toBundleString(Bundle bundle)183 public static final String toBundleString(Bundle bundle) { 184 if (bundle == null) { 185 return "null_bundle"; 186 } 187 StringBuffer buf = new StringBuffer("Bundle[ "); 188 String testType = bundle.getString(TESTCASE_TYPE); 189 boolean empty = true; 190 if (testType != null) { 191 empty = false; 192 buf.append("testcase type = " + testType); 193 } 194 ArrayList<String> info = bundle.getStringArrayList(TESTINFO); 195 if (info != null) { 196 for (String s : info) { 197 empty = false; 198 buf.append(s + "\n\t\t"); 199 } 200 } else { 201 for (String key : bundle.keySet()) { 202 empty = false; 203 Object value = bundle.get(key); 204 if (value instanceof Bundle) { 205 value = toBundleString((Bundle) value); 206 } 207 buf.append(key).append('=').append(value).append(' '); 208 } 209 } 210 return empty ? "empty_bundle" : buf.append(']').toString(); 211 } 212 toOptionsString(Option[] options)213 public static final String toOptionsString(Option[] options) { 214 StringBuilder sb = new StringBuilder(); 215 sb.append("{"); 216 for (int i = 0; i < options.length; i++) { 217 if (i >= 1) { 218 sb.append(", "); 219 } 220 sb.append(options[i].getLabel()); 221 } 222 sb.append("}"); 223 return sb.toString(); 224 } 225 addErrorResult(final Bundle testinfo, final String msg)226 public static final void addErrorResult(final Bundle testinfo, final String msg) { 227 testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE)) 228 .add(TEST_ERROR + " " + msg); 229 } 230 await(CountDownLatch latch)231 public static boolean await(CountDownLatch latch) { 232 try { 233 if (latch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) return true; 234 Log.e(TAG, "latch timed out"); 235 } catch (InterruptedException e) { 236 /* ignore */ 237 Log.e(TAG, "Interrupted", e); 238 } 239 return false; 240 } 241 await(Condition condition)242 public static boolean await(Condition condition) { 243 try { 244 if (condition.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) return true; 245 Log.e(TAG, "condition timed out"); 246 } catch (InterruptedException e) { 247 /* ignore */ 248 Log.e(TAG, "Interrupted", e); 249 } 250 return false; 251 } 252 getParcelableSize(Parcelable parcelable)253 public static int getParcelableSize(Parcelable parcelable) { 254 final Parcel p = Parcel.obtain(); 255 parcelable.writeToParcel(p, 0); 256 p.setDataPosition(0); 257 final int size = p.dataSize(); 258 p.recycle(); 259 return size; 260 } 261 bitCount(long value)262 public static int bitCount(long value) { 263 int bits = 0; 264 while (value > 0) { 265 bits++; 266 value = value >> 1; 267 } 268 return bits; 269 } 270 } 271