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 96 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SUCCESS = 1; 97 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_ILLEGAL_STATE_EXCEPTION = 2; 98 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SECURITY_EXCEPTION = 3; 99 public static final int HOTWORD_DETECTION_SERVICE_TRIGGER_SHARED_MEMORY_NOT_READ_ONLY = 4; 100 public static final int HOTWORD_DETECTION_SERVICE_GET_ERROR = 5; 101 102 /** Indicate which test scenario for testing. */ 103 public static final int HOTWORD_DETECTION_SERVICE_ON_UPDATE_STATE_CRASH = 1; 104 105 /** Indicate to start a new activity for testing. */ 106 public static final int ACTIVITY_NEW = 0; 107 /** Indicate to finish an activity for testing. */ 108 public static final int ACTIVITY_FINISH = 1; 109 110 /** Indicate what kind of parameters for calling registerVisibleActivityCallback. */ 111 public static final int VISIBLE_ACTIVITY_CALLBACK_REGISTER_NORMAL = 0; 112 public static final int VISIBLE_ACTIVITY_CALLBACK_REGISTER_WITHOUT_EXECUTOR = 1; 113 public static final int VISIBLE_ACTIVITY_CALLBACK_REGISTER_WITHOUT_CALLBACK = 2; 114 115 public static final String TEST_APP_PACKAGE = "android.voiceinteraction.testapp"; 116 public static final String TESTCASE_TYPE = "testcase_type"; 117 public static final String TESTINFO = "testinfo"; 118 public static final String BROADCAST_INTENT = "android.intent.action.VOICE_TESTAPP"; 119 public static final String TEST_PROMPT = "testprompt"; 120 public static final String PICKOPTON_1 = "one"; 121 public static final String PICKOPTON_2 = "two"; 122 public static final String PICKOPTON_3 = "3"; 123 public static final String TEST_COMMAND = "test_command"; 124 public static final String TEST_ONCOMMAND_RESULT = "test_oncommand_result"; 125 public static final String TEST_ONCOMMAND_RESULT_VALUE = "test_oncommand_result value"; 126 127 public static final String CONFIRMATION_REQUEST_SUCCESS = "confirmation ok"; 128 public static final String COMPLETION_REQUEST_SUCCESS = "completion ok"; 129 public static final String ABORT_REQUEST_SUCCESS = "abort ok"; 130 public static final String PICKOPTION_REQUEST_SUCCESS = "pickoption ok"; 131 public static final String COMMANDREQUEST_SUCCESS = "commandrequest ok"; 132 public static final String SUPPORTS_COMMANDS_SUCCESS = "supportsCommands ok"; 133 134 public static final String CONFIRMATION_REQUEST_CANCEL_SUCCESS = "confirm cancel ok"; 135 public static final String COMPLETION_REQUEST_CANCEL_SUCCESS = "completion canel ok"; 136 public static final String ABORT_REQUEST_CANCEL_SUCCESS = "abort cancel ok"; 137 public static final String PICKOPTION_REQUEST_CANCEL_SUCCESS = "pickoption cancel ok"; 138 public static final String COMMANDREQUEST_CANCEL_SUCCESS = "commandrequest cancel ok"; 139 public static final String TEST_ERROR = "Error In Test:"; 140 141 public static final String PRIVATE_OPTIONS_KEY = "private_key"; 142 public static final String PRIVATE_OPTIONS_VALUE = "private_value"; 143 144 public static final String DIRECT_ACTION_EXTRA_KEY = "directActionExtraKey"; 145 public static final String DIRECT_ACTION_EXTRA_VALUE = "directActionExtraValue"; 146 public static final String DIRECT_ACTION_FILE_NAME = "directActionFileName"; 147 public static final String DIRECT_ACTION_FILE_CONTENT = "directActionFileContent"; 148 public static final String DIRECT_ACTION_AUTHORITY = 149 "android.voiceinteraction.testapp.fileprovider"; 150 151 public static final String DIRECT_ACTIONS_KEY_CANCEL_CALLBACK = "cancelCallback"; 152 public static final String DIRECT_ACTIONS_KEY_RESULT = "result"; 153 154 public static final String DIRECT_ACTIONS_SESSION_CMD_PERFORM_ACTION = "performAction"; 155 public static final String DIRECT_ACTIONS_SESSION_CMD_PERFORM_ACTION_CANCEL = 156 "performActionCancel"; 157 public static final String DIRECT_ACTIONS_SESSION_CMD_DETECT_ACTIONS_CHANGED = 158 "detectActionsChanged"; 159 public static final String DIRECT_ACTIONS_SESSION_CMD_GET_ACTIONS = "getActions"; 160 161 public static final String DIRECT_ACTIONS_ACTIVITY_CMD_DESTROYED_INTERACTOR = 162 "destroyedInteractor"; 163 public static final String DIRECT_ACTIONS_ACTIVITY_CMD_INVALIDATE_ACTIONS = "invalidateActions"; 164 165 public static final String DIRECT_ACTIONS_RESULT_PERFORMED = "performed"; 166 public static final String DIRECT_ACTIONS_RESULT_CANCELLED = "cancelled"; 167 public static final String DIRECT_ACTIONS_RESULT_EXECUTING = "executing"; 168 169 public static final String DIRECT_ACTIONS_ACTION_ID = "actionId"; 170 public static final Bundle DIRECT_ACTIONS_ACTION_EXTRAS = new Bundle(); 171 static { DIRECT_ACTIONS_ACTION_EXTRAS.putString(DIRECT_ACTION_EXTRA_KEY, DIRECT_ACTION_EXTRA_VALUE)172 DIRECT_ACTIONS_ACTION_EXTRAS.putString(DIRECT_ACTION_EXTRA_KEY, 173 DIRECT_ACTION_EXTRA_VALUE); 174 } 175 public static final LocusId DIRECT_ACTIONS_LOCUS_ID = new LocusId("locusId"); 176 177 public static final String SERVICE_NAME = 178 "android.voiceinteraction.service/.MainInteractionService"; 179 180 public static final String HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT_INTENT = 181 "android.intent.action.HOTWORD_DETECTION_SERVICE_TRIGGER_RESULT"; 182 public static final String HOTWORD_DETECTION_SERVICE_ONDETECT_RESULT_INTENT = 183 "android.intent.action.HOTWORD_DETECTION_SERVICE_ONDETECT_RESULT"; 184 public static final String KEY_SERVICE_TYPE = "serviceType"; 185 public static final String KEY_TEST_EVENT = "testEvent"; 186 public static final String KEY_TEST_RESULT = "testResult"; 187 public static final String KEY_TEST_SCENARIO = "testScenario"; 188 189 public static final String VOICE_INTERACTION_KEY_CALLBACK = "callback"; 190 public static final String VOICE_INTERACTION_KEY_CONTROL = "control"; 191 public static final String VOICE_INTERACTION_KEY_COMMAND = "command"; 192 public static final String VOICE_INTERACTION_DIRECT_ACTIONS_KEY_ACTION = "action"; 193 public static final String VOICE_INTERACTION_KEY_ARGUMENTS = "arguments"; 194 public static final String VOICE_INTERACTION_KEY_CLASS = "class"; 195 public static final String VOICE_INTERACTION_SESSION_CMD_FINISH = "hide"; 196 public static final String VOICE_INTERACTION_ACTIVITY_CMD_FINISH = "finish"; 197 198 // For v2 reliable visible activity lookup feature 199 public static final String VISIBLE_ACTIVITY_CALLBACK_ONVISIBLE_INTENT = 200 "android.intent.action.VISIBLE_ACTIVITY_CALLBACK_ONVISIBLE_INTENT"; 201 public static final String VISIBLE_ACTIVITY_CALLBACK_ONINVISIBLE_INTENT = 202 "android.intent.action.VISIBLE_ACTIVITY_CALLBACK_ONINVISIBLE_INTENT"; 203 public static final String VISIBLE_ACTIVITY_KEY_RESULT = "result"; 204 205 public static final String VISIBLE_ACTIVITY_CMD_REGISTER_CALLBACK = "registerCallback"; 206 public static final String VISIBLE_ACTIVITY_CMD_UNREGISTER_CALLBACK = "unregisterCallback"; 207 toBundleString(Bundle bundle)208 public static final String toBundleString(Bundle bundle) { 209 if (bundle == null) { 210 return "null_bundle"; 211 } 212 StringBuffer buf = new StringBuffer("Bundle[ "); 213 String testType = bundle.getString(TESTCASE_TYPE); 214 boolean empty = true; 215 if (testType != null) { 216 empty = false; 217 buf.append("testcase type = " + testType); 218 } 219 ArrayList<String> info = bundle.getStringArrayList(TESTINFO); 220 if (info != null) { 221 for (String s : info) { 222 empty = false; 223 buf.append(s + "\n\t\t"); 224 } 225 } else { 226 for (String key : bundle.keySet()) { 227 empty = false; 228 Object value = bundle.get(key); 229 if (value instanceof Bundle) { 230 value = toBundleString((Bundle) value); 231 } 232 buf.append(key).append('=').append(value).append(' '); 233 } 234 } 235 return empty ? "empty_bundle" : buf.append(']').toString(); 236 } 237 toOptionsString(Option[] options)238 public static final String toOptionsString(Option[] options) { 239 StringBuilder sb = new StringBuilder(); 240 sb.append("{"); 241 for (int i = 0; i < options.length; i++) { 242 if (i >= 1) { 243 sb.append(", "); 244 } 245 sb.append(options[i].getLabel()); 246 } 247 sb.append("}"); 248 return sb.toString(); 249 } 250 addErrorResult(final Bundle testinfo, final String msg)251 public static final void addErrorResult(final Bundle testinfo, final String msg) { 252 testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE)) 253 .add(TEST_ERROR + " " + msg); 254 } 255 await(CountDownLatch latch)256 public static boolean await(CountDownLatch latch) { 257 try { 258 if (latch.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) return true; 259 Log.e(TAG, "latch timed out"); 260 } catch (InterruptedException e) { 261 /* ignore */ 262 Log.e(TAG, "Interrupted", e); 263 } 264 return false; 265 } 266 await(Condition condition)267 public static boolean await(Condition condition) { 268 try { 269 if (condition.await(OPERATION_TIMEOUT_MS, TimeUnit.MILLISECONDS)) return true; 270 Log.e(TAG, "condition timed out"); 271 } catch (InterruptedException e) { 272 /* ignore */ 273 Log.e(TAG, "Interrupted", e); 274 } 275 return false; 276 } 277 getParcelableSize(Parcelable parcelable)278 public static int getParcelableSize(Parcelable parcelable) { 279 final Parcel p = Parcel.obtain(); 280 parcelable.writeToParcel(p, 0); 281 p.setDataPosition(0); 282 final int size = p.dataSize(); 283 p.recycle(); 284 return size; 285 } 286 bitCount(long value)287 public static int bitCount(long value) { 288 int bits = 0; 289 while (value > 0) { 290 bits++; 291 value = value >> 1; 292 } 293 return bits; 294 } 295 isVirtualDevice()296 public static boolean isVirtualDevice() { 297 final String property = PropertyUtil.getProperty("ro.hardware.virtual_device"); 298 Log.v(TAG, "virtual device property=" + property); 299 return Objects.equals(property, "1"); 300 } 301 } 302