Merge \"App launch - Test app changes\" into nyc-dev
am: 8fabbb89c0
Change-Id: I304e8791b2ea72bd527fa0c8abd2c748c90e866c
diff --git a/tests/AppLaunch/Android.mk b/tests/AppLaunch/Android.mk
index c0560fd..e6f6c39 100644
--- a/tests/AppLaunch/Android.mk
+++ b/tests/AppLaunch/Android.mk
@@ -11,7 +11,9 @@
LOCAL_CERTIFICATE := platform
LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
include $(BUILD_PACKAGE)
# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/AppLaunch/AndroidManifest.xml b/tests/AppLaunch/AndroidManifest.xml
index ac6760b..7dfd7ba 100644
--- a/tests/AppLaunch/AndroidManifest.xml
+++ b/tests/AppLaunch/AndroidManifest.xml
@@ -3,6 +3,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.tests.applaunch"
android:sharedUserId="android.uid.system" >
+
+ <uses-permission android:name="android.permission.REAL_GET_TASKS" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-sdk
+ android:minSdkVersion="22"
+ android:targetSdkVersion="24" />
+
<instrumentation android:label="Measure app start up time"
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.tests.applaunch" />
@@ -10,4 +18,4 @@
<application android:label="App Launch Test">
<uses-library android:name="android.test.runner" />
</application>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
index 085b7aa..2346f85 100644
--- a/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
+++ b/tests/AppLaunch/src/com/android/tests/applaunch/AppLaunch.java
@@ -15,14 +15,13 @@
*/
package com.android.tests.applaunch;
+import java.io.OutputStreamWriter;
+
import android.accounts.Account;
import android.accounts.AccountManager;
+import android.app.ActivityManagerNative;
import android.app.ActivityManager;
import android.app.ActivityManager.ProcessErrorStateInfo;
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.IActivityManager.WaitResult;
-import android.app.UiAutomation;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -31,16 +30,29 @@
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.app.UiAutomation;
+import android.app.IActivityManager;
+import android.app.IActivityManager.WaitResult;
+import android.support.test.rule.logging.AtraceLogger;
import android.test.InstrumentationTestCase;
import android.test.InstrumentationTestRunner;
import android.util.Log;
-
+import java.io.File;
+import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
+import java.util.ArrayList;
import java.util.Map;
import java.util.Set;
+import android.os.ParcelFileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.InputStreamReader;
/**
* This test is intended to measure the time it takes for the apps to start.
@@ -55,27 +67,66 @@
private static final int JOIN_TIMEOUT = 10000;
private static final String TAG = AppLaunch.class.getSimpleName();
- private static final String KEY_APPS = "apps";
- private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations";
// optional parameter: comma separated list of required account types before proceeding
// with the app launch
private static final String KEY_REQUIRED_ACCOUNTS = "required_accounts";
- private static final String KEY_SKIP_INITIAL_LAUNCH = "skip_initial_launch";
+ private static final String KEY_APPS = "apps";
+ private static final String KEY_TRIAL_LAUNCH = "trial_launch";
+ private static final String KEY_LAUNCH_ITERATIONS = "launch_iterations";
+ private static final String KEY_LAUNCH_ORDER = "launch_order";
+ private static final String KEY_DROP_CACHE = "drop_cache";
+ private static final String KEY_SIMPLEPPERF_CMD = "simpleperf_cmd";
+ private static final String KEY_TRACE_ITERATIONS = "trace_iterations";
+ private static final String KEY_LAUNCH_DIRECTORY = "launch_directory";
+ private static final String KEY_TRACE_DIRECTORY = "trace_directory";
+ private static final String KEY_TRACE_CATEGORY = "trace_categories";
+ private static final String KEY_TRACE_BUFFERSIZE = "trace_bufferSize";
+ private static final String KEY_TRACE_DUMPINTERVAL = "tracedump_interval";
private static final String WEARABLE_ACTION_GOOGLE =
"com.google.android.wearable.action.GOOGLE";
private static final int INITIAL_LAUNCH_IDLE_TIMEOUT = 60000; //60s 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 static final int BETWEEN_LAUNCH_SLEEP_TIMEOUT = 5000; //5s between launching apps
+ private static final String LAUNCH_SUB_DIRECTORY = "launch_logs";
+ private static final String LAUNCH_FILE = "applaunch.txt";
+ private static final String TRACE_SUB_DIRECTORY = "atrace_logs";
+ private static final String DEFAULT_TRACE_CATEGORIES = "sched,freq,gfx,view,dalvik,webview,"
+ + "input,wm,disk,am,wm";
+ private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
+ private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
+ private static final String TRIAL_LAUNCH = "TRAIL_LAUNCH";
+ private static final String DELIMITER = ",";
+ private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
+ private static final String APP_LAUNCH_CMD = "am start -W -n";
+ private static final String SUCCESS_MESSAGE = "Status: ok";
+ private static final String THIS_TIME = "ThisTime:";
+ private static final String LAUNCH_ITERATION = "LAUNCH_ITERATION - %d";
+ private static final String TRACE_ITERATION = "TRACE_ITERATION - %d";
+ private static final String LAUNCH_ITERATION_PREFIX = "LAUNCH_ITERATION";
+ private static final String TRACE_ITERATION_PREFIX = "TRACE_ITERATION";
+ private static final String LAUNCH_ORDER_CYCLIC = "cyclic";
+ private static final String LAUNCH_ORDER_SEQUENTIAL = "sequential";
+
private Map<String, Intent> mNameToIntent;
private Map<String, String> mNameToProcess;
+ private List<LaunchOrder> mLaunchOrderList = new ArrayList<LaunchOrder>();
private Map<String, String> mNameToResultKey;
- private Map<String, Long> mNameToLaunchTime;
+ private Map<String, List<Long>> mNameToLaunchTime;
private IActivityManager mAm;
+ private String mSimplePerfCmd = null;
+ private String mLaunchOrder = null;
+ private boolean mDropCache = false;
private int mLaunchIterations = 10;
+ private int mTraceLaunchCount = 0;
+ private String mTraceDirectoryStr = null;
private Bundle mResult = new Bundle();
private Set<String> mRequiredAccounts;
- private boolean mSkipInitialLaunch = false;
+ private boolean mTrailLaunch = true;
+ private File mFile = null;
+ private FileOutputStream mOutputStream = null;
+ private BufferedWriter mBufferedWriter = null;
+
@Override
protected void setUp() throws Exception {
@@ -89,69 +140,231 @@
super.tearDown();
}
- public void testMeasureStartUpTime() throws RemoteException, NameNotFoundException {
+ public void testMeasureStartUpTime() throws RemoteException, NameNotFoundException,
+ IOException, InterruptedException {
InstrumentationTestRunner instrumentation =
(InstrumentationTestRunner)getInstrumentation();
Bundle args = instrumentation.getArguments();
mAm = ActivityManagerNative.getDefault();
-
+ String launchDirectory = args.getString(KEY_LAUNCH_DIRECTORY);
+ mTraceDirectoryStr = args.getString(KEY_TRACE_DIRECTORY);
+ mDropCache = Boolean.parseBoolean(args.getString(KEY_DROP_CACHE));
+ mSimplePerfCmd = args.getString(KEY_SIMPLEPPERF_CMD);
+ mLaunchOrder = args.getString(KEY_LAUNCH_ORDER, LAUNCH_ORDER_CYCLIC);
createMappings();
parseArgs(args);
checkAccountSignIn();
- if (!mSkipInitialLaunch) {
- // do initial app launch, without force stopping
- for (String app : mNameToResultKey.keySet()) {
- 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;
- } else {
- mNameToLaunchTime.put(app, launchTime);
- }
- sleep(INITIAL_LAUNCH_IDLE_TIMEOUT);
- closeApp(app, false);
- sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
+ // Root directory for applaunch file to log the app launch output
+ // Will be useful in case of simpleperf command is used
+ File launchRootDir = null;
+ if (null != launchDirectory && !launchDirectory.isEmpty()) {
+ launchRootDir = new File(launchDirectory);
+ if (!launchRootDir.exists() && !launchRootDir.mkdirs()) {
+ throw new IOException("Unable to create the destination directory");
}
}
- // do the real app launch now
- for (int i = 0; i < mLaunchIterations; i++) {
- for (String app : mNameToResultKey.keySet()) {
- long prevLaunchTime = mNameToLaunchTime.get(app);
- long launchTime = 0;
- if (prevLaunchTime < 0) {
- // skip if the app has previous failures
- continue;
+
+ try {
+ File launchSubDir = new File(launchRootDir, LAUNCH_SUB_DIRECTORY);
+ if (!launchSubDir.exists() && !launchSubDir.mkdirs()) {
+ throw new IOException("Unable to create the lauch file sub directory");
+ }
+ mFile = new File(launchSubDir, LAUNCH_FILE);
+ mOutputStream = new FileOutputStream(mFile);
+ mBufferedWriter = new BufferedWriter(new OutputStreamWriter(
+ mOutputStream));
+
+ // Root directory for trace file during the launches
+ File rootTrace = null;
+ File rootTraceSubDir = null;
+ int traceBufferSize = 0;
+ int traceDumpInterval = 0;
+ Set<String> traceCategoriesSet = null;
+ if (null != mTraceDirectoryStr && !mTraceDirectoryStr.isEmpty()) {
+ rootTrace = new File(mTraceDirectoryStr);
+ if (!rootTrace.exists() && !rootTrace.mkdirs()) {
+ throw new IOException("Unable to create the trace directory");
}
- launchTime = startApp(app, true);
- if (launchTime <= 0) {
- // if it fails once, skip the rest of the launches
- mNameToLaunchTime.put(app, -1L);
- continue;
+ rootTraceSubDir = new File(rootTrace, TRACE_SUB_DIRECTORY);
+ if (!rootTraceSubDir.exists() && !rootTraceSubDir.mkdirs()) {
+ throw new IOException("Unable to create the trace sub directory");
}
- // keep the min launch time
- if (launchTime < prevLaunchTime) {
- mNameToLaunchTime.put(app, launchTime);
+ assertNotNull("Trace iteration parameter is mandatory",
+ args.getString(KEY_TRACE_ITERATIONS));
+ mTraceLaunchCount = Integer.parseInt(args.getString(KEY_TRACE_ITERATIONS));
+ String traceCategoriesStr = args
+ .getString(KEY_TRACE_CATEGORY, DEFAULT_TRACE_CATEGORIES);
+ traceBufferSize = Integer.parseInt(args.getString(KEY_TRACE_BUFFERSIZE,
+ DEFAULT_TRACE_BUFFER_SIZE));
+ traceDumpInterval = Integer.parseInt(args.getString(KEY_TRACE_DUMPINTERVAL,
+ DEFAULT_TRACE_DUMP_INTERVAL));
+ traceCategoriesSet = new HashSet<String>();
+ if (!traceCategoriesStr.isEmpty()) {
+ String[] traceCategoriesSplit = traceCategoriesStr.split(DELIMITER);
+ for (int i = 0; i < traceCategoriesSplit.length; i++) {
+ traceCategoriesSet.add(traceCategoriesSplit[i]);
+ }
}
- sleep(POST_LAUNCH_IDLE_TIMEOUT);
- closeApp(app, true);
- sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
+ }
+
+ // Get the app launch order based on launch order, trial launch,
+ // launch iterations and trace iterations
+ setLaunchOrder();
+
+ for (LaunchOrder launch : mLaunchOrderList) {
+
+ // App launch times for trial launch will not be used for final
+ // launch time calculations.
+ if (launch.getLaunchReason().equals(TRIAL_LAUNCH)) {
+ // In the "applaunch.txt" file, trail launches is referenced using
+ // "TRIAL_LAUNCH"
+ long launchTime = startApp(launch.getApp(), true, launch.getLaunchReason());
+ if (launchTime < 0) {
+ List<Long> appLaunchList = new ArrayList<Long>();
+ appLaunchList.add(-1L);
+ mNameToLaunchTime.put(launch.getApp(), appLaunchList);
+ // simply pass the app if launch isn't successful
+ // error should have already been logged by startApp
+ continue;
+ }
+ sleep(INITIAL_LAUNCH_IDLE_TIMEOUT);
+ closeApp(launch.getApp(), true);
+ dropCache();
+ sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
+ }
+
+ // App launch times used for final calculation
+ if (launch.getLaunchReason().contains(LAUNCH_ITERATION_PREFIX)) {
+ long launchTime = -1;
+ if (null != mNameToLaunchTime.get(launch.getApp())) {
+ long firstLaunchTime = mNameToLaunchTime.get(launch.getApp()).get(0);
+ if (firstLaunchTime < 0) {
+ // skip if the app has failures while launched first
+ continue;
+ }
+ }
+ // In the "applaunch.txt" file app launches are referenced using
+ // "LAUNCH_ITERATION - ITERATION NUM"
+ launchTime = startApp(launch.getApp(), true, launch.getLaunchReason());
+ if (launchTime < 0) {
+ // if it fails once, skip the rest of the launches
+ List<Long> appLaunchList = new ArrayList<Long>();
+ appLaunchList.add(-1L);
+ mNameToLaunchTime.put(launch.getApp(), appLaunchList);
+ continue;
+ } else {
+ if (null != mNameToLaunchTime.get(launch.getApp())) {
+ mNameToLaunchTime.get(launch.getApp()).add(launchTime);
+ } else {
+ List<Long> appLaunchList = new ArrayList<Long>();
+ appLaunchList.add(launchTime);
+ mNameToLaunchTime.put(launch.getApp(), appLaunchList);
+ }
+ }
+ sleep(POST_LAUNCH_IDLE_TIMEOUT);
+ closeApp(launch.getApp(), true);
+ dropCache();
+ sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
+ }
+
+ // App launch times for trace launch will not be used for final
+ // launch time calculations.
+ if (launch.getLaunchReason().contains(TRACE_ITERATION_PREFIX)) {
+ AtraceLogger atraceLogger = AtraceLogger
+ .getAtraceLoggerInstance(getInstrumentation());
+ // Start the trace
+ try {
+ atraceLogger.atraceStart(traceCategoriesSet, traceBufferSize,
+ traceDumpInterval, rootTraceSubDir,
+ String.format("%s-%s", launch.getApp(), launch.getLaunchReason()));
+ startApp(launch.getApp(), true, launch.getLaunchReason());
+ sleep(POST_LAUNCH_IDLE_TIMEOUT);
+ } finally {
+ // Stop the trace
+ atraceLogger.atraceStop();
+ closeApp(launch.getApp(), true);
+ dropCache();
+ sleep(BETWEEN_LAUNCH_SLEEP_TIMEOUT);
+ }
+ }
+ }
+ } finally {
+ if (null != mBufferedWriter) {
+ mBufferedWriter.close();
}
}
+
for (String app : mNameToResultKey.keySet()) {
- long launchTime = mNameToLaunchTime.get(app);
- if (launchTime != -1) {
- mResult.putLong(mNameToResultKey.get(app), launchTime);
+ StringBuilder launchTimes = new StringBuilder();
+ for (Long launch : mNameToLaunchTime.get(app)) {
+ launchTimes.append(launch);
+ launchTimes.append(",");
}
+ mResult.putString(mNameToResultKey.get(app), launchTimes.toString());
}
instrumentation.sendStatus(0, mResult);
}
+ /**
+ * If launch order is "cyclic" then apps will be launched one after the
+ * other for each iteration count.
+ * If launch order is "sequential" then each app will be launched for given number
+ * iterations at once before launching the other apps.
+ */
+ private void setLaunchOrder() {
+ if (LAUNCH_ORDER_CYCLIC.equalsIgnoreCase(mLaunchOrder)) {
+ if (mTrailLaunch) {
+ for (String app : mNameToResultKey.keySet()) {
+ mLaunchOrderList.add(new LaunchOrder(app, TRIAL_LAUNCH));
+ }
+ }
+ for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
+ for (String app : mNameToResultKey.keySet()) {
+ mLaunchOrderList.add(new LaunchOrder(app,
+ String.format(LAUNCH_ITERATION, launchCount)));
+ }
+ }
+ if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
+ for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
+ for (String app : mNameToResultKey.keySet()) {
+ mLaunchOrderList.add(new LaunchOrder(app,
+ String.format(TRACE_ITERATION, traceCount)));
+ }
+ }
+ }
+ } else if (LAUNCH_ORDER_SEQUENTIAL.equalsIgnoreCase(mLaunchOrder)) {
+ for (String app : mNameToResultKey.keySet()) {
+ if (mTrailLaunch) {
+ mLaunchOrderList.add(new LaunchOrder(app, TRIAL_LAUNCH));
+ }
+ for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
+ mLaunchOrderList.add(new LaunchOrder(app,
+ String.format(LAUNCH_ITERATION, launchCount)));
+ }
+ if (mTraceDirectoryStr != null && !mTraceDirectoryStr.isEmpty()) {
+ for (int traceCount = 0; traceCount < mTraceLaunchCount; traceCount++) {
+ mLaunchOrderList.add(new LaunchOrder(app,
+ String.format(TRACE_ITERATION, traceCount)));
+ }
+ }
+ }
+ } else {
+ assertTrue("Launch order is not valid parameter", false);
+ }
+ }
+
+ private void dropCache() {
+ if (true == mDropCache) {
+ assertNotNull("Issue in dropping the cache",
+ getInstrumentation().getUiAutomation()
+ .executeShellCommand(DROP_CACHE_SCRIPT));
+ }
+ }
+
private void parseArgs(Bundle args) {
mNameToResultKey = new LinkedHashMap<String, String>();
- mNameToLaunchTime = new HashMap<String, Long>();
+ mNameToLaunchTime = new HashMap<String, List<Long>>();
String launchIterations = args.getString(KEY_LAUNCH_ITERATIONS);
if (launchIterations != null) {
mLaunchIterations = Integer.parseInt(launchIterations);
@@ -169,7 +382,7 @@
}
mNameToResultKey.put(parts[0], parts[1]);
- mNameToLaunchTime.put(parts[0], 0L);
+ mNameToLaunchTime.put(parts[0], null);
}
String requiredAccounts = args.getString(KEY_REQUIRED_ACCOUNTS);
if (requiredAccounts != null) {
@@ -178,7 +391,7 @@
mRequiredAccounts.add(accountType);
}
}
- mSkipInitialLaunch = "true".equals(args.getString(KEY_SKIP_INITIAL_LAUNCH));
+ mTrailLaunch = "true".equals(args.getString(KEY_TRIAL_LAUNCH));
}
private boolean hasLeanback(Context context) {
@@ -222,7 +435,7 @@
}
}
- private long startApp(String appName, boolean forceStopBeforeLaunch)
+ private long startApp(String appName, boolean forceStopBeforeLaunch, String launchReason)
throws NameNotFoundException, RemoteException {
Log.i(TAG, "Starting " + appName);
@@ -230,9 +443,10 @@
if (startIntent == null) {
Log.w(TAG, "App does not exist: " + appName);
mResult.putString(mNameToResultKey.get(appName), "App does not exist");
- return -1;
+ return -1L;
}
- AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, forceStopBeforeLaunch);
+ AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, forceStopBeforeLaunch ,
+ launchReason);
Thread t = new Thread(runnable);
t.start();
try {
@@ -240,21 +454,7 @@
} catch (InterruptedException e) {
// ignore
}
- WaitResult result = runnable.getResult();
- // report error if any of the following is true:
- // * launch thread is alive
- // * result is not null, but:
- // * result is not START_SUCCESS
- // * 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));
- return -1;
- }
- return result.thisTime;
+ return runnable.getResult();
}
private void checkAccountSignIn() {
@@ -337,39 +537,117 @@
+ " not found in process list, most likely it is crashed");
}
- private class AppLaunchRunnable implements Runnable {
- private Intent mLaunchIntent;
- private IActivityManager.WaitResult mResult;
- private boolean mForceStopBeforeLaunch;
+ private class LaunchOrder {
+ private String mApp;
+ private String mLaunchReason;
- public AppLaunchRunnable(Intent intent, boolean forceStopBeforeLaunch) {
- mLaunchIntent = intent;
- mForceStopBeforeLaunch = forceStopBeforeLaunch;
+ LaunchOrder(String app,String launchReason){
+ mApp = app;
+ mLaunchReason = launchReason;
}
- public IActivityManager.WaitResult getResult() {
+ public String getApp() {
+ return mApp;
+ }
+
+ public void setApp(String app) {
+ mApp = app;
+ }
+
+ public String getLaunchReason() {
+ return mLaunchReason;
+ }
+
+ public void setLaunchReason(String launchReason) {
+ mLaunchReason = launchReason;
+ }
+ }
+
+ private class AppLaunchRunnable implements Runnable {
+ private Intent mLaunchIntent;
+ private Long mResult;
+ private boolean mForceStopBeforeLaunch;
+ private String mLaunchReason;
+
+ public AppLaunchRunnable(Intent intent, boolean forceStopBeforeLaunch,
+ String launchReason) {
+ mLaunchIntent = intent;
+ mForceStopBeforeLaunch = forceStopBeforeLaunch;
+ mLaunchReason = launchReason;
+ }
+
+ public Long getResult() {
return mResult;
}
public void run() {
try {
String packageName = mLaunchIntent.getComponent().getPackageName();
+ String componentName = mLaunchIntent.getComponent().flattenToShortString();
if (mForceStopBeforeLaunch) {
mAm.forceStopPackage(packageName, UserHandle.USER_CURRENT);
}
- String mimeType = mLaunchIntent.getType();
- if (mimeType == null && mLaunchIntent.getData() != null
- && "content".equals(mLaunchIntent.getData().getScheme())) {
- mimeType = mAm.getProviderMimeType(mLaunchIntent.getData(),
- UserHandle.USER_CURRENT);
+ String launchCmd = String.format("%s %s", APP_LAUNCH_CMD, componentName);
+ if (null != mSimplePerfCmd) {
+ launchCmd = String.format("%s %s", mSimplePerfCmd, launchCmd);
}
-
- mResult = mAm.startActivityAndWait(null, null, mLaunchIntent, mimeType,
- null, null, 0, mLaunchIntent.getFlags(), null, null,
- UserHandle.USER_CURRENT);
+ Log.v(TAG, "Final launch cmd:" + launchCmd);
+ ParcelFileDescriptor parcelDesc = getInstrumentation().getUiAutomation()
+ .executeShellCommand(launchCmd);
+ mResult = Long.parseLong(parseLaunchTimeAndWrite(parcelDesc, String.format
+ ("App Launch :%s %s",
+ componentName, mLaunchReason)), 10);
} catch (RemoteException e) {
Log.w(TAG, "Error launching app", e);
}
}
+
+ /**
+ * Method to parse the launch time info and write the result to file
+ *
+ * @param parcelDesc
+ * @return
+ */
+ private String parseLaunchTimeAndWrite(ParcelFileDescriptor parcelDesc, String headerInfo) {
+ String launchTime = "-1";
+ boolean launchSuccess = false;
+ try {
+ InputStream inputStream = new FileInputStream(parcelDesc.getFileDescriptor());
+ StringBuilder appLaunchOuput = new StringBuilder();
+ /* SAMPLE OUTPUT :
+ Starting: Intent { cmp=com.google.android.calculator/com.android.calculator2.Calculator }
+ Status: ok
+ Activity: com.google.android.calculator/com.android.calculator2.Calculator
+ ThisTime: 357
+ TotalTime: 357
+ WaitTime: 377
+ Complete*/
+ BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
+ inputStream));
+ String line = null;
+ int lineCount = 1;
+ mBufferedWriter.newLine();
+ mBufferedWriter.write(headerInfo);
+ mBufferedWriter.newLine();
+ while ((line = bufferedReader.readLine()) != null) {
+ if (lineCount == 2 && line.contains(SUCCESS_MESSAGE)) {
+ launchSuccess = true;
+ }
+ if (launchSuccess && lineCount == 4) {
+ String launchSplit[] = line.split(":");
+ launchTime = launchSplit[1].trim();
+ }
+ mBufferedWriter.write(line);
+ mBufferedWriter.newLine();
+ lineCount++;
+ }
+ mBufferedWriter.flush();
+ inputStream.close();
+ } catch (IOException e) {
+ Log.w(TAG, "Error writing the launch file", e);
+ }
+ return launchTime;
+ }
+
}
}