diff options
author | Guang Zhu <guangzhu@google.com> | 2013-03-05 18:51:15 -0800 |
---|---|---|
committer | Guang Zhu <guangzhu@google.com> | 2013-03-13 23:24:31 -0700 |
commit | 32abd66ebd6d63cfc631ce5f4425bb5dc4a4beac (patch) | |
tree | c40ee28427a63bdb52ec2d12a81a92e5ed85dcdc /tests/AppLaunch | |
parent | b1fa4f92dcd6380b14cbff9cb8aec9e175d7d60d (diff) | |
download | frameworks_base-32abd66ebd6d63cfc631ce5f4425bb5dc4a4beac.zip frameworks_base-32abd66ebd6d63cfc631ce5f4425bb5dc4a4beac.tar.gz frameworks_base-32abd66ebd6d63cfc631ce5f4425bb5dc4a4beac.tar.bz2 |
change how app launch is tested
new approach:
* for each app
* initial launch
* sleep 7.5s
* do 10 iterations: launch app with force stop + sleep in between
* report average of 10 launches
Change-Id: I9e68975325aa83af35620d727823f5c072aac488
Diffstat (limited to 'tests/AppLaunch')
-rw-r--r-- | tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java | 137 |
1 files changed, 99 insertions, 38 deletions
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java index fbdd333..dffb617 100644 --- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java +++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,6 +32,7 @@ import android.test.InstrumentationTestCase; import android.test.InstrumentationTestRunner; import android.util.Log; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -48,16 +49,22 @@ import java.util.Map; public class AppLaunch extends InstrumentationTestCase { private static final int JOIN_TIMEOUT = 10000; - private static final String TAG = "AppLaunch"; + private static final String TAG = AppLaunch.class.getSimpleName(); private static final String KEY_APPS = "apps"; + private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations"; + private static final int INITIAL_LAUNCH_IDLE_TIMEOUT = 7500; //7.5s to allow app to idle + private static final int POST_LAUNCH_IDLE_TIMEOUT = 750; //750ms idle for non initial launches + private static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 2000; //2s between launching apps private Map<String, Intent> mNameToIntent; private Map<String, String> mNameToProcess; private Map<String, String> mNameToResultKey; - + private Map<String, Long> mNameToLaunchTime; private IActivityManager mAm; + private int mLaunchIterations = 10; + private Bundle mResult = new Bundle(); - public void testMeasureStartUpTime() throws RemoteException { + public void testMeasureStartUpTime() throws RemoteException, NameNotFoundException { InstrumentationTestRunner instrumentation = (InstrumentationTestRunner)getInstrumentation(); Bundle args = instrumentation.getArguments(); @@ -66,25 +73,59 @@ public class AppLaunch extends InstrumentationTestCase { createMappings(); parseArgs(args); - Bundle results = new Bundle(); + // do initial app launch, without force stopping for (String app : mNameToResultKey.keySet()) { - try { - startApp(app, results); - sleep(750); - closeApp(app); - sleep(2000); - } catch (NameNotFoundException e) { - Log.i(TAG, "Application " + app + " not found"); + long launchTime = startApp(app, false); + if (launchTime <=0 ) { + mNameToLaunchTime.put(app, -1L); + // simply pass the app if launch isn't successful + // error should have already been logged by startApp + continue; + } + sleep(INITIAL_LAUNCH_IDLE_TIMEOUT); + closeApp(app, false); + sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT); + } + // do the real app launch now + for (int i = 0; i < mLaunchIterations; i++) { + for (String app : mNameToResultKey.keySet()) { + long totalLaunchTime = mNameToLaunchTime.get(app); + long launchTime = 0; + if (totalLaunchTime < 0) { + // skip if the app has previous failures + continue; + } + launchTime = startApp(app, true); + if (launchTime <= 0) { + // if it fails once, skip the rest of the launches + mNameToLaunchTime.put(app, -1L); + continue; + } + totalLaunchTime += launchTime; + mNameToLaunchTime.put(app, totalLaunchTime); + sleep(POST_LAUNCH_IDLE_TIMEOUT); + closeApp(app, true); + sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT); + } + } + for (String app : mNameToResultKey.keySet()) { + long totalLaunchTime = mNameToLaunchTime.get(app); + if (totalLaunchTime != -1) { + mResult.putDouble(mNameToResultKey.get(app), + ((double) totalLaunchTime) / mLaunchIterations); } - } - instrumentation.sendStatus(0, results); + instrumentation.sendStatus(0, mResult); } private void parseArgs(Bundle args) { mNameToResultKey = new LinkedHashMap<String, String>(); + mNameToLaunchTime = new HashMap<String, Long>(); + String launchIterations = args.getString(KEY_LAUNCH_ITERATIONS); + if (launchIterations != null) { + mLaunchIterations = Integer.parseInt(launchIterations); + } String appList = args.getString(KEY_APPS); - if (appList == null) return; @@ -97,6 +138,7 @@ public class AppLaunch extends InstrumentationTestCase { } mNameToResultKey.put(parts[0], parts[1]); + mNameToLaunchTime.put(parts[0], 0L); } } @@ -118,23 +160,26 @@ public class AppLaunch extends InstrumentationTestCase { | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); startIntent.setClassName(ri.activityInfo.packageName, ri.activityInfo.name); - mNameToIntent.put(ri.loadLabel(pm).toString(), startIntent); - mNameToProcess.put(ri.loadLabel(pm).toString(), - ri.activityInfo.processName); + String appName = ri.loadLabel(pm).toString(); + if (appName != null) { + mNameToIntent.put(appName, startIntent); + mNameToProcess.put(appName, ri.activityInfo.processName); + } } } } - private void startApp(String appName, Bundle results) + private long startApp(String appName, boolean forceStopBeforeLaunch) throws NameNotFoundException, RemoteException { Log.i(TAG, "Starting " + appName); Intent startIntent = mNameToIntent.get(appName); if (startIntent == null) { Log.w(TAG, "App does not exist: " + appName); - return; + mResult.putString(mNameToResultKey.get(appName), "App does not exist"); + return -1; } - AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent); + AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, forceStopBeforeLaunch); Thread t = new Thread(runnable); t.start(); try { @@ -143,27 +188,38 @@ public class AppLaunch extends InstrumentationTestCase { // ignore } WaitResult result = runnable.getResult(); - if(t.isAlive() || (result != null && result.result != ActivityManager.START_SUCCESS)) { + // report error if any of the following is true: + // * launch thread is alive + // * result is not null, but: + // * result is not START_SUCESS + // * or in case of no force stop, result is not TASK_TO_FRONT either + if (t.isAlive() || (result != null + && ((result.result != ActivityManager.START_SUCCESS) + && (!forceStopBeforeLaunch + && result.result != ActivityManager.START_TASK_TO_FRONT)))) { Log.w(TAG, "Assuming app " + appName + " crashed."); - reportError(appName, mNameToProcess.get(appName), results); - return; + reportError(appName, mNameToProcess.get(appName)); + return -1; } - results.putString(mNameToResultKey.get(appName), String.valueOf(result.thisTime)); + return result.thisTime; } - private void closeApp(String appName) { + private void closeApp(String appName, boolean forceStopApp) { Intent homeIntent = new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); getInstrumentation().getContext().startActivity(homeIntent); - Intent startIntent = mNameToIntent.get(appName); - if (startIntent != null) { - String packageName = startIntent.getComponent().getPackageName(); - try { - mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); - } catch (RemoteException e) { - Log.w(TAG, "Error closing app", e); + sleep(POST_LAUNCH_IDLE_TIMEOUT); + if (forceStopApp) { + Intent startIntent = mNameToIntent.get(appName); + if (startIntent != null) { + String packageName = startIntent.getComponent().getPackageName(); + try { + mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); + } catch (RemoteException e) { + Log.w(TAG, "Error closing app", e); + } } } } @@ -176,7 +232,7 @@ public class AppLaunch extends InstrumentationTestCase { } } - private void reportError(String appName, String processName, Bundle results) { + private void reportError(String appName, String processName) { ActivityManager am = (ActivityManager) getInstrumentation() .getContext().getSystemService(Context.ACTIVITY_SERVICE); List<ProcessErrorStateInfo> crashes = am.getProcessesInErrorState(); @@ -186,12 +242,12 @@ public class AppLaunch extends InstrumentationTestCase { continue; Log.w(TAG, appName + " crashed: " + crash.shortMsg); - results.putString(mNameToResultKey.get(appName), crash.shortMsg); + mResult.putString(mNameToResultKey.get(appName), crash.shortMsg); return; } } - results.putString(mNameToResultKey.get(appName), + mResult.putString(mNameToResultKey.get(appName), "Crashed for unknown reason"); Log.w(TAG, appName + " not found in process list, most likely it is crashed"); @@ -200,8 +256,11 @@ public class AppLaunch extends InstrumentationTestCase { private class AppLaunchRunnable implements Runnable { private Intent mLaunchIntent; private IActivityManager.WaitResult mResult; - public AppLaunchRunnable(Intent intent) { + private boolean mForceStopBeforeLaunch; + + public AppLaunchRunnable(Intent intent, boolean forceStopBeforeLaunch) { mLaunchIntent = intent; + mForceStopBeforeLaunch = forceStopBeforeLaunch; } public IActivityManager.WaitResult getResult() { @@ -211,7 +270,9 @@ public class AppLaunch extends InstrumentationTestCase { public void run() { try { String packageName = mLaunchIntent.getComponent().getPackageName(); - mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); + if (mForceStopBeforeLaunch) { + mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT); + } String mimeType = mLaunchIntent.getType(); if (mimeType == null && mLaunchIntent.getData() != null && "content".equals(mLaunchIntent.getData().getScheme())) { |