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