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.assist.common; 17 18 import android.content.ComponentName; 19 import android.content.Context; 20 import android.content.Intent; 21 import android.content.pm.PackageManager; 22 import android.os.Bundle; 23 import android.os.LocaleList; 24 import android.os.Process; 25 import android.util.Log; 26 27 import org.json.JSONObject; 28 29 import java.util.ArrayList; 30 import java.util.Locale; 31 32 public class Utils { 33 private static final String TAG = Utils.class.getSimpleName(); 34 public static final String TESTCASE_TYPE = "testcase_type"; 35 public static final String TESTINFO = "testinfo"; 36 public static final String ACTION_PREFIX = "android.intent.action."; 37 public static final String BROADCAST_INTENT = ACTION_PREFIX + "ASSIST_TESTAPP"; 38 public static final String BROADCAST_ASSIST_DATA_INTENT = ACTION_PREFIX + "ASSIST_DATA"; 39 public static final String BROADCAST_INTENT_START_ASSIST = ACTION_PREFIX + "START_ASSIST"; 40 public static final String ASSIST_RECEIVER_REGISTERED = ACTION_PREFIX + "ASSIST_READY"; 41 public static final String ACTION_END_OF_TEST = ACTION_PREFIX + "END_OF_TEST"; 42 43 public static final String ACTION_INVALIDATE = "invalidate_action"; 44 public static final String GET_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "GET_CONTENT_VIEW_HEIGHT"; 45 public static final String BROADCAST_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "VIEW_HEIGHT"; 46 public static final String SCROLL_TEXTVIEW_ACTION = ACTION_PREFIX + "TEXTVIEW_SCROLL"; 47 public static final String SCROLL_SCROLLVIEW_ACTION = ACTION_PREFIX + "SCROLLVIEW_SCROLL"; 48 public static final String TEST_ERROR = "Error In Test:"; 49 50 public static final String ASSIST_STRUCTURE_KEY = "assist_structure"; 51 public static final String ASSIST_CONTENT_KEY = "assist_content"; 52 public static final String ASSIST_BUNDLE_KEY = "assist_bundle"; 53 public static final String ASSIST_IS_ACTIVITY_ID_NULL = "assist_is_activity_id_null"; 54 public static final String ASSIST_SCREENSHOT_KEY = "assist_screenshot"; 55 public static final String SCREENSHOT_COLOR_KEY = "set_screenshot_color"; 56 public static final String COMPARE_SCREENSHOT_KEY = "compare_screenshot"; 57 public static final String ON_SHOW_ARGS_KEY = "on_show_args"; 58 public static final String DISPLAY_WIDTH_KEY = "display_width"; 59 public static final String DISPLAY_HEIGHT_KEY = "dislay_height"; 60 public static final String DISPLAY_AREA_BOUNDS_KEY = "display_area_bounds"; 61 public static final String SCROLL_X_POSITION = "scroll_x_position"; 62 public static final String SCROLL_Y_POSITION = "scroll_y_position"; 63 public static final String SHOW_SESSION_FLAGS_TO_SET = "show_session_flags_to_set"; 64 65 /** Lifecycle Test intent constants */ 66 public static final String LIFECYCLE_PREFIX = ACTION_PREFIX + "lifecycle_"; 67 public static final String LIFECYCLE_HASRESUMED = LIFECYCLE_PREFIX + "hasResumed"; 68 public static final String LIFECYCLE_HASFOCUS = LIFECYCLE_PREFIX + "hasFocus"; 69 public static final String LIFECYCLE_LOSTFOCUS = LIFECYCLE_PREFIX + "lostFocus"; 70 public static final String LIFECYCLE_ONPAUSE = LIFECYCLE_PREFIX + "onpause"; 71 public static final String LIFECYCLE_ONSTOP = LIFECYCLE_PREFIX + "onstop"; 72 public static final String LIFECYCLE_ONDESTROY = LIFECYCLE_PREFIX + "ondestroy"; 73 74 /** Focus Change Test intent constants */ 75 public static final String GAINED_FOCUS = ACTION_PREFIX + "focus_changed"; 76 public static final String LOST_FOCUS = ACTION_PREFIX + "lost_focus"; 77 78 public static final String APP_3P_HASRESUMED = ACTION_PREFIX + "app_3p_hasResumed"; 79 public static final String APP_3P_HASDRAWED = ACTION_PREFIX + "app_3p_hasDrawed"; 80 public static final String TEST_ACTIVITY_DESTROY = ACTION_PREFIX + "test_activity_destroy"; 81 public static final String TEST_ACTIVITY_WEBVIEW_LOADED = ACTION_PREFIX + "test_activity_webview_hasResumed"; 82 83 // Notice: timeout belows have to be long because some devices / form factors (like car) are 84 // slower. 85 86 /** Timeout for getting back assist context */ 87 public static final int TIMEOUT_MS = 6 * 1_000; 88 /** Timeout for an activity to resume */ 89 public static final int ACTIVITY_ONRESUME_TIMEOUT_MS = 12 * 1_000; 90 91 public static final String EXTRA_REGISTER_RECEIVER = "register_receiver"; 92 93 /** Extras for passing the Assistant's ContentView's dimensions*/ 94 public static final String EXTRA_CONTENT_VIEW_HEIGHT = "extra_content_view_height"; 95 public static final String EXTRA_CONTENT_VIEW_WIDTH = "extra_content_view_width"; 96 public static final String EXTRA_DISPLAY_POINT = "extra_display_point"; 97 98 /* 99 * Extras used to pass RemoteCallback objects responsible for IPC between test, app, and 100 * service. 101 */ 102 public static final String EXTRA_REMOTE_CALLBACK = "extra_remote_callback"; 103 public static final String EXTRA_REMOTE_CALLBACK_ACTION = "extra_remote_callback_action"; 104 105 public static final String EXTRA_REMOTE_CALLBACK_RECEIVING = "extra_remote_callback_receiving"; 106 public static final String EXTRA_REMOTE_CALLBACK_RECEIVING_ACTION = "extra_remote_callback_receiving_action"; 107 108 /** Test name suffixes */ 109 public static final String ASSIST_STRUCTURE = "ASSIST_STRUCTURE"; 110 public static final String DISABLE_CONTEXT = "DISABLE_CONTEXT"; 111 public static final String FLAG_SECURE = "FLAG_SECURE"; 112 public static final String LIFECYCLE = "LIFECYCLE"; 113 public static final String LIFECYCLE_NOUI = "LIFECYCLE_NOUI"; 114 public static final String SCREENSHOT = "SCREENSHOT"; 115 public static final String EXTRA_ASSIST = "EXTRA_ASSIST"; 116 public static final String VERIFY_CONTENT_VIEW = "VERIFY_CONTENT_VIEW"; 117 public static final String TEXTVIEW = "TEXTVIEW"; 118 public static final String LARGE_VIEW_HIERARCHY = "LARGE_VIEW_HIERARCHY"; 119 public static final String WEBVIEW = "WEBVIEW"; 120 public static final String FOCUS_CHANGE = "FOCUS_CHANGE"; 121 122 /** Session intent constants */ 123 public static final String HIDE_SESSION = "android.intent.action.hide_session"; 124 public static final String HIDE_SESSION_COMPLETE = "android.intent.action.hide_session_complete"; 125 126 /** Lifecycle activity intent constants */ 127 /** Session intent constants */ 128 public static final String HIDE_LIFECYCLE_ACTIVITY 129 = "android.intent.action.hide_lifecycle_activity"; 130 131 /** Stub html view to load into WebView */ 132 public static final String WEBVIEW_HTML_URL = "http://dev.null/thou/should?not=pass"; 133 public static final String WEBVIEW_HTML_DOMAIN = "dev.null"; 134 public static final LocaleList WEBVIEW_LOCALE_LIST = new LocaleList(Locale.ROOT, Locale.US); 135 public static final String WEBVIEW_HTML_GREETING = "Hello WebView!"; 136 public static final String WEBVIEW_HTML = "<html><body><div><p>" + WEBVIEW_HTML_GREETING 137 + "</p></div></body></html>"; 138 139 /** Extra data to add to assist data and assist content */ 140 private static Bundle EXTRA_ASSIST_BUNDLE; 141 private static String STRUCTURED_JSON; 142 143 private static String MY_UID_EXTRA = "my_uid"; 144 getStructuredJSON()145 public static final String getStructuredJSON() throws Exception { 146 if (STRUCTURED_JSON == null) { 147 STRUCTURED_JSON = new JSONObject() 148 .put("@type", "MusicRecording") 149 .put("@id", "https://example/music/recording") 150 .put("url", "android-app://com.example/https/music/album") 151 .put("name", "Album Title") 152 .put("hello", "hi there") 153 .put("knownNull", null) 154 .put("unicode value", "\ud800\udc35") 155 .put("empty string", "") 156 .put("LongString", 157 "lkasdjfalsdkfjalsdjfalskj9i9234jl1w23j4o123j412l3j421l3kj412l3kj1l3k4j32") 158 .put("\ud800\udc35", "any-value") 159 .put("key with spaces", "any-value") 160 .toString(); 161 } 162 return STRUCTURED_JSON; 163 } 164 getExtraAssistBundle()165 public static final Bundle getExtraAssistBundle() { 166 if (EXTRA_ASSIST_BUNDLE == null) { 167 EXTRA_ASSIST_BUNDLE = new Bundle(); 168 addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE, /* addMyUid= */ false); 169 } 170 return EXTRA_ASSIST_BUNDLE; 171 } 172 addExtraAssistDataToBundle(Bundle data)173 public static void addExtraAssistDataToBundle(Bundle data) { 174 addExtraAssistDataToBundle(data, /* addMyUid= */ true); 175 176 } 177 addExtraAssistDataToBundle(Bundle data, boolean addMyUid)178 private static void addExtraAssistDataToBundle(Bundle data, boolean addMyUid) { 179 data.putString("hello", "there"); 180 data.putBoolean("isthis_true_or_false", true); 181 data.putInt("number", 123); 182 if (addMyUid) { 183 Log.i(TAG, "adding " + MY_UID_EXTRA + "=" + Process.myUid()); 184 data.putInt(MY_UID_EXTRA, Process.myUid()); 185 } 186 } 187 188 /** 189 * The test app associated with each test. 190 */ getTestAppComponent(String testCaseType)191 public static final ComponentName getTestAppComponent(String testCaseType) { 192 switch (testCaseType) { 193 case ASSIST_STRUCTURE: 194 case LARGE_VIEW_HIERARCHY: 195 case DISABLE_CONTEXT: 196 return new ComponentName( 197 "android.assist.testapp", "android.assist.testapp.TestApp"); 198 case FLAG_SECURE: 199 return new ComponentName( 200 "android.assist.testapp", "android.assist.testapp.SecureActivity"); 201 case LIFECYCLE: 202 case LIFECYCLE_NOUI: 203 return new ComponentName( 204 "android.assist.testapp", "android.assist.testapp.LifecycleActivity"); 205 case SCREENSHOT: 206 return new ComponentName( 207 "android.assist.testapp", "android.assist.testapp.ScreenshotActivity"); 208 case EXTRA_ASSIST: 209 return new ComponentName( 210 "android.assist.testapp", "android.assist.testapp.ExtraAssistDataActivity"); 211 case TEXTVIEW: 212 return new ComponentName( 213 "android.assist.testapp", "android.assist.testapp.TextViewActivity"); 214 case WEBVIEW: 215 return new ComponentName( 216 "android.assist.testapp", "android.assist.testapp.WebViewActivity"); 217 case FOCUS_CHANGE: 218 return new ComponentName( 219 "android.assist.testapp", "android.assist.testapp.FocusChangeActivity"); 220 default: 221 return new ComponentName("",""); 222 } 223 } 224 225 /** 226 * Sets the proper action used to launch an activity in the testapp package. 227 */ setTestAppAction(Intent intent, String testCaseName)228 public static void setTestAppAction(Intent intent, String testCaseName) { 229 intent.putExtra(Utils.TESTCASE_TYPE, testCaseName); 230 intent.setAction("android.intent.action.TEST_APP_" + testCaseName); 231 } 232 233 /** 234 * Returns the amount of time to wait for assist data. 235 */ getAssistDataTimeout(String testCaseType)236 public static final int getAssistDataTimeout(String testCaseType) { 237 switch (testCaseType) { 238 case SCREENSHOT: 239 // needs to wait for 3p activity to resume before receiving assist data. 240 return TIMEOUT_MS + ACTIVITY_ONRESUME_TIMEOUT_MS; 241 default: 242 return TIMEOUT_MS; 243 } 244 } 245 toBundleString(Bundle bundle)246 public static final String toBundleString(Bundle bundle) { 247 if (bundle == null) { 248 return "*** Bundle is null ****"; 249 } 250 StringBuffer buf = new StringBuffer("Bundle is: "); 251 String testType = bundle.getString(TESTCASE_TYPE); 252 if (testType != null) { 253 buf.append("testcase type = " + testType); 254 } 255 ArrayList<String> info = bundle.getStringArrayList(TESTINFO); 256 if (info != null) { 257 for (String s : info) { 258 buf.append(s + "\n\t\t"); 259 } 260 } 261 return buf.toString(); 262 } 263 addErrorResult(final Bundle testinfo, final String msg)264 public static final void addErrorResult(final Bundle testinfo, final String msg) { 265 testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE)) 266 .add(TEST_ERROR + " " + msg); 267 } 268 getExpectedUid(Bundle extras)269 public static int getExpectedUid(Bundle extras) { 270 return extras.getInt(MY_UID_EXTRA); 271 } 272 bundleOfRemoteAction(String action)273 public static Bundle bundleOfRemoteAction(String action) { 274 Bundle bundle = new Bundle(); 275 bundle.putString(Utils.EXTRA_REMOTE_CALLBACK_ACTION, action); 276 return bundle; 277 } 278 isAutomotive(Context context)279 public static boolean isAutomotive(Context context) { 280 return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); 281 } 282 } 283