AppLaunch.java revision 32abd66ebd6d63cfc631ce5f4425bb5dc4a4beac
1f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine/* 232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu * Copyright (C) 2013 The Android Open Source Project 3f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * 4f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * Licensed under the Apache License, Version 2.0 (the "License"); 5f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * you may not use this file except in compliance with the License. 6f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * You may obtain a copy of the License at 7f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * 8f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * http://www.apache.org/licenses/LICENSE-2.0 9f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * 10f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * Unless required by applicable law or agreed to in writing, software 11f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * distributed under the License is distributed on an "AS IS" BASIS, 12f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * See the License for the specific language governing permissions and 14f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * limitations under the License. 15f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine */ 16f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavinepackage com.android.tests.applaunch; 17f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 18f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.app.ActivityManager; 19f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.app.ActivityManager.ProcessErrorStateInfo; 20f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.app.ActivityManagerNative; 21f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.app.IActivityManager; 2213f77349778fbe95d665542be6f05006879854e2Guang Zhuimport android.app.IActivityManager.WaitResult; 23f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.content.Context; 24f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.content.Intent; 25f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.content.pm.PackageManager; 26f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.content.pm.PackageManager.NameNotFoundException; 27f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.content.pm.ResolveInfo; 28f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.os.Bundle; 29f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.os.RemoteException; 30f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.os.UserHandle; 31f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.test.InstrumentationTestCase; 32f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.test.InstrumentationTestRunner; 33f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport android.util.Log; 34f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 3532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhuimport java.util.HashMap; 36c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhuimport java.util.LinkedHashMap; 37f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport java.util.List; 38f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavineimport java.util.Map; 39f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 40f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine/** 41f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * This test is intended to measure the time it takes for the apps to start. 42f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * Names of the applications are passed in command line, and the 43f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * test starts each application, and reports the start up time in milliseconds. 44f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * The instrumentation expects the following key to be passed on the command line: 45f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * apps - A list of applications to start and their corresponding result keys 46f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * in the following format: 47f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine * -e apps <app name>^<result key>|<app name>^<result key> 48f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine */ 49f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavinepublic class AppLaunch extends InstrumentationTestCase { 50f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 51f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private static final int JOIN_TIMEOUT = 10000; 5232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private static final String TAG = AppLaunch.class.getSimpleName(); 53f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private static final String KEY_APPS = "apps"; 5432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations"; 5532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private static final int INITIAL_LAUNCH_IDLE_TIMEOUT = 7500; //7.5s to allow app to idle 5632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private static final int POST_LAUNCH_IDLE_TIMEOUT = 750; //750ms idle for non initial launches 5732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 2000; //2s between launching apps 58f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 59f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private Map<String, Intent> mNameToIntent; 60f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private Map<String, String> mNameToProcess; 61f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private Map<String, String> mNameToResultKey; 6232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private Map<String, Long> mNameToLaunchTime; 63f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private IActivityManager mAm; 6432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private int mLaunchIterations = 10; 6532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private Bundle mResult = new Bundle(); 66f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 6732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu public void testMeasureStartUpTime() throws RemoteException, NameNotFoundException { 68f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine InstrumentationTestRunner instrumentation = 69f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine (InstrumentationTestRunner)getInstrumentation(); 703a34d17412a5a304e39be1966a16627677d2136fSvetoslav Bundle args = instrumentation.getArguments(); 71f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine mAm = ActivityManagerNative.getDefault(); 72f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 73f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine createMappings(); 74f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine parseArgs(args); 75f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 7632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // do initial app launch, without force stopping 77f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine for (String app : mNameToResultKey.keySet()) { 7832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu long launchTime = startApp(app, false); 7932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (launchTime <=0 ) { 8032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToLaunchTime.put(app, -1L); 8132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // simply pass the app if launch isn't successful 8232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // error should have already been logged by startApp 8332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu continue; 8432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 8532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu sleep(INITIAL_LAUNCH_IDLE_TIMEOUT); 8632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu closeApp(app, false); 8732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT); 8832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 8932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // do the real app launch now 9032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu for (int i = 0; i < mLaunchIterations; i++) { 9132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu for (String app : mNameToResultKey.keySet()) { 9232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu long totalLaunchTime = mNameToLaunchTime.get(app); 9332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu long launchTime = 0; 9432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (totalLaunchTime < 0) { 9532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // skip if the app has previous failures 9632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu continue; 9732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 9832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu launchTime = startApp(app, true); 9932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (launchTime <= 0) { 10032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // if it fails once, skip the rest of the launches 10132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToLaunchTime.put(app, -1L); 10232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu continue; 10332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 10432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu totalLaunchTime += launchTime; 10532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToLaunchTime.put(app, totalLaunchTime); 10632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu sleep(POST_LAUNCH_IDLE_TIMEOUT); 10732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu closeApp(app, true); 10832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT); 10932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 11032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 11132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu for (String app : mNameToResultKey.keySet()) { 11232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu long totalLaunchTime = mNameToLaunchTime.get(app); 11332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (totalLaunchTime != -1) { 11432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mResult.putDouble(mNameToResultKey.get(app), 11532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu ((double) totalLaunchTime) / mLaunchIterations); 116f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 117f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 11832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu instrumentation.sendStatus(0, mResult); 119f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 120f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 121f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private void parseArgs(Bundle args) { 122c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu mNameToResultKey = new LinkedHashMap<String, String>(); 12332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToLaunchTime = new HashMap<String, Long>(); 12432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu String launchIterations = args.getString(KEY_LAUNCH_ITERATIONS); 12532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (launchIterations != null) { 12632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mLaunchIterations = Integer.parseInt(launchIterations); 12732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 128f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine String appList = args.getString(KEY_APPS); 129f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (appList == null) 130f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine return; 131f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 132f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine String appNames[] = appList.split("\\|"); 133f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine for (String pair : appNames) { 134f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine String[] parts = pair.split("\\^"); 135f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (parts.length != 2) { 136f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.e(TAG, "The apps key is incorectly formatted"); 137f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine fail(); 138f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 139f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 140f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine mNameToResultKey.put(parts[0], parts[1]); 14132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToLaunchTime.put(parts[0], 0L); 142f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 143f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 144f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 145f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private void createMappings() { 146c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu mNameToIntent = new LinkedHashMap<String, Intent>(); 147c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu mNameToProcess = new LinkedHashMap<String, String>(); 148f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 149f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine PackageManager pm = getInstrumentation().getContext() 150f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine .getPackageManager(); 151f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Intent intentToResolve = new Intent(Intent.ACTION_MAIN); 152f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER); 153f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine List<ResolveInfo> ris = pm.queryIntentActivities(intentToResolve, 0); 154f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (ris == null || ris.isEmpty()) { 155f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.i(TAG, "Could not find any apps"); 156f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } else { 157f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine for (ResolveInfo ri : ris) { 158f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Intent startIntent = new Intent(intentToResolve); 159f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 160f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 161f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine startIntent.setClassName(ri.activityInfo.packageName, 162f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine ri.activityInfo.name); 16332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu String appName = ri.loadLabel(pm).toString(); 16432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (appName != null) { 16532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToIntent.put(appName, startIntent); 16632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mNameToProcess.put(appName, ri.activityInfo.processName); 16732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 168f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 169f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 170f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 171f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 17232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private long startApp(String appName, boolean forceStopBeforeLaunch) 173f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine throws NameNotFoundException, RemoteException { 174f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.i(TAG, "Starting " + appName); 175f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 176f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Intent startIntent = mNameToIntent.get(appName); 177c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu if (startIntent == null) { 178c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu Log.w(TAG, "App does not exist: " + appName); 17932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mResult.putString(mNameToResultKey.get(appName), "App does not exist"); 18032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu return -1; 181c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu } 18232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, forceStopBeforeLaunch); 183f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Thread t = new Thread(runnable); 184f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine t.start(); 185f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine try { 186f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine t.join(JOIN_TIMEOUT); 187f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } catch (InterruptedException e) { 188f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine // ignore 189f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 190c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu WaitResult result = runnable.getResult(); 19132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // report error if any of the following is true: 19232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // * launch thread is alive 19332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // * result is not null, but: 19432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // * result is not START_SUCESS 19532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu // * or in case of no force stop, result is not TASK_TO_FRONT either 19632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (t.isAlive() || (result != null 19732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu && ((result.result != ActivityManager.START_SUCCESS) 19832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu && (!forceStopBeforeLaunch 19932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu && result.result != ActivityManager.START_TASK_TO_FRONT)))) { 200f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.w(TAG, "Assuming app " + appName + " crashed."); 20132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu reportError(appName, mNameToProcess.get(appName)); 20232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu return -1; 203f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 20432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu return result.thisTime; 205f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 206f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 20732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private void closeApp(String appName, boolean forceStopApp) { 208f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Intent homeIntent = new Intent(Intent.ACTION_MAIN); 209f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine homeIntent.addCategory(Intent.CATEGORY_HOME); 210f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK 211f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 212f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine getInstrumentation().getContext().startActivity(homeIntent); 21332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu sleep(POST_LAUNCH_IDLE_TIMEOUT); 21432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (forceStopApp) { 21532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu Intent startIntent = mNameToIntent.get(appName); 21632abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (startIntent != null) { 21732abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu String packageName = startIntent.getComponent().getPackageName(); 21832abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu try { 21932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); 22032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } catch (RemoteException e) { 22132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu Log.w(TAG, "Error closing app", e); 22232abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 22313f77349778fbe95d665542be6f05006879854e2Guang Zhu } 22413f77349778fbe95d665542be6f05006879854e2Guang Zhu } 225f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 226f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 227f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private void sleep(int time) { 228f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine try { 229f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Thread.sleep(time); 230f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } catch (InterruptedException e) { 231f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine // ignore 232f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 233f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 234f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 23532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private void reportError(String appName, String processName) { 236f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine ActivityManager am = (ActivityManager) getInstrumentation() 237f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine .getContext().getSystemService(Context.ACTIVITY_SERVICE); 238f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine List<ProcessErrorStateInfo> crashes = am.getProcessesInErrorState(); 239f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (crashes != null) { 240f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine for (ProcessErrorStateInfo crash : crashes) { 241f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (!crash.processName.equals(processName)) 242f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine continue; 243f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 244f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.w(TAG, appName + " crashed: " + crash.shortMsg); 24532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mResult.putString(mNameToResultKey.get(appName), crash.shortMsg); 246f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine return; 247f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 248f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 249f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 25032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mResult.putString(mNameToResultKey.get(appName), 251f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine "Crashed for unknown reason"); 252f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.w(TAG, appName 253f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine + " not found in process list, most likely it is crashed"); 254f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 255f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 256f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private class AppLaunchRunnable implements Runnable { 257f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private Intent mLaunchIntent; 258f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine private IActivityManager.WaitResult mResult; 25932abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu private boolean mForceStopBeforeLaunch; 26032abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu 26132abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu public AppLaunchRunnable(Intent intent, boolean forceStopBeforeLaunch) { 262f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine mLaunchIntent = intent; 26332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mForceStopBeforeLaunch = forceStopBeforeLaunch; 264f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 265f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 266f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine public IActivityManager.WaitResult getResult() { 267f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine return mResult; 268f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 269f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 270f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine public void run() { 271f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine try { 272c28a062ffd7edbdbd936c750fa3ec3f81b0d1b44Guang Zhu String packageName = mLaunchIntent.getComponent().getPackageName(); 27332abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu if (mForceStopBeforeLaunch) { 27432abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); 27532abd66ebd6d63cfc631ce5f4425bb5dc4a4beacGuang Zhu } 276f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine String mimeType = mLaunchIntent.getType(); 277f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine if (mimeType == null && mLaunchIntent.getData() != null 278f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine && "content".equals(mLaunchIntent.getData().getScheme())) { 279f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine mimeType = mAm.getProviderMimeType(mLaunchIntent.getData(), 280f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine UserHandle.USER_CURRENT); 281f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 282f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine 283f265ea9d8307282ff1da3915978625a94fc2859eDianne Hackborn mResult = mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType, 284f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine null, null, 0, mLaunchIntent.getFlags(), null, null, null, 285f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine UserHandle.USER_CURRENT); 286f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } catch (RemoteException e) { 287f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine Log.w(TAG, "Error launching app", e); 288f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 289f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 290f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine } 291f58e5b6cdcecee6184784b3a6ac33f60341de170Maxim Siniavine} 292