• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 
17 package com.android.apptransition.tests;
18 
19 import android.app.ActivityManagerNative;
20 import android.app.IActivityManager;
21 import android.app.Instrumentation;
22 import android.content.ComponentName;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.pm.ActivityInfo;
26 import android.content.pm.PackageManager;
27 import android.content.pm.PackageManager.NameNotFoundException;
28 import android.content.pm.ResolveInfo;
29 import android.os.Bundle;
30 import android.os.Environment;
31 import android.os.ParcelFileDescriptor;
32 import android.os.RemoteException;
33 import android.support.test.InstrumentationRegistry;
34 import android.support.test.launcherhelper.ILauncherStrategy;
35 import android.support.test.launcherhelper.LauncherStrategyFactory;
36 import android.support.test.rule.logging.AtraceLogger;
37 import android.support.test.uiautomator.By;
38 import android.support.test.uiautomator.UiDevice;
39 import android.support.test.uiautomator.UiObjectNotFoundException;
40 import android.support.test.uiautomator.UiObject2;
41 import android.support.test.uiautomator.Until;
42 import android.util.Log;
43 
44 import java.io.BufferedReader;
45 import java.io.File;
46 import java.io.FileInputStream;
47 import java.io.InputStream;
48 import java.io.InputStreamReader;
49 import java.io.IOException;
50 import java.util.ArrayList;
51 import java.util.HashSet;
52 import java.util.List;
53 import java.util.LinkedHashMap;
54 import java.util.Map;
55 import java.util.Set;
56 
57 import org.junit.After;
58 import org.junit.Before;
59 import org.junit.Test;
60 
61 public class AppTransitionTests {
62 
63     private static final String TAG = AppTransitionTests.class.getSimpleName();
64     private static final int JOIN_TIMEOUT = 10000;
65     private static final String DEFAULT_POST_LAUNCH_TIMEOUT = "5000";
66     private static final String DEFAULT_LAUNCH_COUNT = "10";
67     private static final String SUCCESS_MESSAGE = "Status: ok";
68     private static final String HOT_LAUNCH_MESSAGE = "Warning: Activity not started, its current"
69             + " task has been brought to the front";
70     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
71     private static final String APP_LAUNCH_CMD = "am start -W -n";
72     private static final String FORCE_STOP = "am force-stop ";
73     private static final String PRE_LAUNCH_APPS = "pre_launch_apps";
74     private static final String LAUNCH_APPS = "launch_apps";
75     private static final String KEY_LAUNCH_ITERATIONS = "launch_iteration";
76     private static final String KEY_POST_LAUNCH_TIMEOUT = "postlaunch_timeout";
77     private static final String COLD_LAUNCH = "cold_launch";
78     private static final String HOT_LAUNCH = "hot_launch";
79     private static final String NOT_SURE = "not_sure";
80     private static final String ACTIVITY = "Activity";
81     private static final String NOT_SUCCESSFUL_MESSAGE = "App launch not successful";
82     private static final String KEY_TRACE_DIRECTORY = "trace_directory";
83     private static final String KEY_TRACE_CATEGORY = "trace_categories";
84     private static final String KEY_TRACE_BUFFERSIZE = "trace_bufferSize";
85     private static final String KEY_TRACE_DUMPINTERVAL = "tracedump_interval";
86     private static final String DEFAULT_TRACE_CATEGORIES = "sched,freq,gfx,view,dalvik,webview,"
87             + "input,wm,disk,am,wm";
88     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
89     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
90     private static final String DELIMITER = ",";
91     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
92     private Context mContext;
93     private UiDevice mDevice;
94     private PackageManager mPackageManager;
95     private IActivityManager mActivityManager;
96     private ILauncherStrategy mLauncherStrategy = null;
97     private Map<String, Intent> mAppLaunchIntentsMapping = null;
98     private String mTraceDirectoryStr = null;
99     private Bundle mResult = new Bundle();
100     private Bundle mArgs;
101     private String mPreAppsList;
102     private int mLaunchIterations;
103     private int mPostLaunchTimeout;
104     private String[] mAppListArray;
105     private String[] mPreAppsListArray;
106     private File mRootTrace = null;
107     private File mRootTraceSubDir = null;
108     private int mTraceBufferSize = 0;
109     private int mTraceDumpInterval = 0;
110     private Set<String> mTraceCategoriesSet = null;
111     private AtraceLogger mAtraceLogger = null;
112     private String mComponentName = null;
113 
114     @Before
setUp()115     public void setUp() throws Exception {
116         mPackageManager = getInstrumentation().getContext().getPackageManager();
117         mContext = getInstrumentation().getContext();
118         mArgs = InstrumentationRegistry.getArguments();
119         mActivityManager = ActivityManagerNative.getDefault();
120         mDevice = UiDevice.getInstance(getInstrumentation());
121         mLauncherStrategy = LauncherStrategyFactory.getInstance(mDevice).getLauncherStrategy();
122         createLaunchIntentMappings();
123         String mAppsList = mArgs.getString(LAUNCH_APPS);
124         mPreAppsList = mArgs.getString(PRE_LAUNCH_APPS);
125         mLaunchIterations = Integer.parseInt(mArgs.getString(KEY_LAUNCH_ITERATIONS,
126                 DEFAULT_LAUNCH_COUNT));
127         mPostLaunchTimeout = Integer.parseInt(mArgs.getString(KEY_POST_LAUNCH_TIMEOUT,
128                 DEFAULT_POST_LAUNCH_TIMEOUT));
129         if (null == mAppsList && mAppsList.isEmpty()) {
130             throw new IllegalArgumentException("Need atleast one app to do the"
131                     + " app transition from launcher");
132         }
133         mAppsList = mAppsList.replaceAll("%"," ");
134         mAppListArray = mAppsList.split(DELIMITER);
135 
136         // Parse the trace parameters
137         mTraceDirectoryStr = mArgs.getString(KEY_TRACE_DIRECTORY);
138         if (isTracesEnabled()) {
139             String traceCategoriesStr = mArgs
140                     .getString(KEY_TRACE_CATEGORY, DEFAULT_TRACE_CATEGORIES);
141             mTraceBufferSize = Integer.parseInt(mArgs.getString(KEY_TRACE_BUFFERSIZE,
142                     DEFAULT_TRACE_BUFFER_SIZE));
143             mTraceDumpInterval = Integer.parseInt(mArgs.getString(KEY_TRACE_DUMPINTERVAL,
144                     DEFAULT_TRACE_DUMP_INTERVAL));
145             mTraceCategoriesSet = new HashSet<String>();
146             if (!traceCategoriesStr.isEmpty()) {
147                 String[] traceCategoriesSplit = traceCategoriesStr.split(DELIMITER);
148                 for (int i = 0; i < traceCategoriesSplit.length; i++) {
149                     mTraceCategoriesSet.add(traceCategoriesSplit[i]);
150                 }
151             }
152         }
153         mDevice.setOrientationNatural();
154         cleanTestApps();
155     }
156 
157     @After
tearDown()158     public void tearDown() throws Exception{
159         cleanTestApps();
160         getInstrumentation().sendStatus(0, mResult);
161     }
162 
163     /**
164      * Cold launch given list of apps for given launch count from the launcher screen.
165      * @throws IOException if there are issues in writing atrace file
166      * @throws InterruptedException if there are interrupt during the sleep
167      * @throws RemoteException if press home is not successful
168      */
169     @Test
testColdLaunchFromLauncher()170     public void testColdLaunchFromLauncher() throws IOException, InterruptedException,
171             RemoteException {
172         if (isTracesEnabled()) {
173             createTraceDirectory("testColdLaunchFromLauncher");
174         }
175         // Perform cold app launch from launcher screen
176         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
177             String appName = mAppListArray[appCount];
178             for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
179                 if (null != mAtraceLogger) {
180                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
181                             mTraceDumpInterval, mRootTraceSubDir,
182                             String.format("%s-%d", appName, launchCount));
183                 }
184                 mLauncherStrategy.launch(appName, mAppLaunchIntentsMapping.get(appName).
185                         getComponent().flattenToShortString().split("\\/")[0]);
186                 if (null != mAtraceLogger) {
187                     mAtraceLogger.atraceStop();
188                 }
189                 sleep(mPostLaunchTimeout);
190                 closeApps(new String[] {
191                         appName
192                 });
193                 pressUiHome();
194                 sleep(mPostLaunchTimeout);
195                 getInstrumentation().getUiAutomation()
196                         .executeShellCommand(DROP_CACHE_SCRIPT);
197             }
198             // Update the result with the component name
199             updateResult(appName);
200         }
201     }
202 
203     /**
204      * Hot launch given list of apps for given launch count from the launcher screen. Same method can be
205      * used to test app to home transition delay information as well.
206      * @throws IOException if there are issues in writing atrace file
207      * @throws InterruptedException if there are interrupt during the sleep
208      * @throws RemoteException if press home is not successful
209      */
210     @Test
testHotLaunchFromLauncher()211     public void testHotLaunchFromLauncher() throws IOException, InterruptedException,
212             RemoteException {
213         if (isTracesEnabled()) {
214             createTraceDirectory("testHotLaunchFromLauncher");
215         }
216         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
217             String appName = mAppListArray[appCount];
218             // Additional launches to account for cold launch and one hot launch.
219             if (setupAppLaunch(appName) == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
220                 continue;
221             }
222             // Hot app launch for given launch iterations.
223             for (int launchCount = 0; launchCount < (mLaunchIterations); launchCount++) {
224                 if (null != mAtraceLogger) {
225                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
226                             mTraceDumpInterval, mRootTraceSubDir,
227                             String.format("%s-%d", appName, (launchCount)));
228                 }
229                 mLauncherStrategy.launch(appName, mComponentName.split("\\/")[0]);
230                 if (null != mAtraceLogger) {
231                     mAtraceLogger.atraceStop();
232                 }
233                 sleep(mPostLaunchTimeout);
234                 pressUiHome();
235                 sleep(mPostLaunchTimeout);
236             }
237             // Update the result with the component name
238             updateResult(appName);
239         }
240     }
241 
242     /**
243      * Launch an app and press recents for given list of apps for given launch counts.
244      * @throws IOException if there are issues in writing atrace file
245      * @throws InterruptedException if there are interrupt during the sleep
246      * @throws RemoteException if press recent apps is not successful
247      */
248     @Test
testAppToRecents()249     public void testAppToRecents() throws IOException, InterruptedException, RemoteException {
250         if (isTracesEnabled()) {
251             createTraceDirectory("testAppToRecents");
252         }
253         if (null == mPreAppsList && mPreAppsList.isEmpty()) {
254             throw new IllegalArgumentException("Need atleast few apps in the "
255                     + "recents before starting the test");
256         }
257         mPreAppsList = mPreAppsList.replaceAll("%"," ");
258         mPreAppsListArray = mPreAppsList.split(DELIMITER);
259         populateRecentsList();
260         // Increment by one to account for the first cold launch and discard it
261         // while parsing
262         mLaunchIterations++;
263         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
264             String appName = mAppListArray[appCount];
265             long appLaunchTime = -1L;
266             for (int launchCount = 0; launchCount < mLaunchIterations; launchCount++) {
267                 // "NOT_SURE" for first launch because apps in the PreAppsList
268                 // could be part of AppList
269                 if (launchCount == 0) {
270                     appLaunchTime = startApp(appName, NOT_SURE);
271                 } else {
272                     appLaunchTime = startApp(appName, HOT_LAUNCH);
273                 }
274                 if (appLaunchTime == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
275                     break;
276                 }
277                 sleep(mPostLaunchTimeout);
278                 if (null != mAtraceLogger && launchCount > 0) {
279                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
280                             mTraceDumpInterval, mRootTraceSubDir,
281                             String.format("%s-%d", appName, launchCount - 1));
282                 }
283                 pressUiRecentApps();
284                 sleep(mPostLaunchTimeout);
285                 if (null != mAtraceLogger && launchCount > 0) {
286                     mAtraceLogger.atraceStop();
287                 }
288                 pressUiHome();
289                 sleep(mPostLaunchTimeout);
290             }
291             updateResult(appName);
292         }
293     }
294 
295     /**
296      * Hot launch an app from recents for given list of apps for given launch counts.
297      * @throws IOException if there are issues in writing atrace file
298      * @throws InterruptedException if there are interrupt during the sleep
299      * @throws RemoteException if press recent apps is not successful
300      */
301     @Test
testHotLaunchFromRecents()302     public void testHotLaunchFromRecents() throws IOException, InterruptedException,
303             RemoteException {
304         if (isTracesEnabled()) {
305             createTraceDirectory("testHotLaunchFromRecents");
306         }
307         if (null == mPreAppsList && mPreAppsList.isEmpty()) {
308             throw new IllegalArgumentException("Need atleast few apps in the"
309                     + " recents before starting the test");
310         }
311         mPreAppsList = mPreAppsList.replaceAll("%", " ");
312         mPreAppsListArray = mPreAppsList.split(DELIMITER);
313         populateRecentsList();
314         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
315             String appName = mAppListArray[appCount];
316             // Additional launches to account for cold launch and one hot launch.
317             if (setupAppLaunch(appName) == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
318                 continue;
319             }
320             for (int launchCount = 0; launchCount < (mLaunchIterations); launchCount++) {
321                 if (null != mAtraceLogger) {
322                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
323                             mTraceDumpInterval, mRootTraceSubDir,
324                             String.format("%s-%d", appName, (launchCount)));
325                 }
326                 openMostRecentTask();
327                 sleep(mPostLaunchTimeout);
328                 if (null != mAtraceLogger) {
329                     mAtraceLogger.atraceStop();
330                 }
331                 pressUiHome();
332                 sleep(mPostLaunchTimeout);
333             }
334             updateResult(appName);
335         }
336     }
337 
338     /**
339      * Launch given app couple of times to account for the cold launch and one hot launch and
340      * to update component name associated with the hot launch of the given app.
341      * @throws RemoteException if press home is not successful
342      * @param appName
343      * @return
344      */
setupAppLaunch(String appName)345     public long setupAppLaunch(String appName) throws RemoteException {
346         long appLaunchTime = startApp(appName, NOT_SURE);
347         if (appLaunchTime == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
348             return appLaunchTime;
349         }
350         sleep(mPostLaunchTimeout);
351         pressUiHome();
352         appLaunchTime = startApp(appName, HOT_LAUNCH);
353         if (appLaunchTime == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
354             return appLaunchTime;
355         }
356         sleep(mPostLaunchTimeout);
357         pressUiHome();
358         return appLaunchTime;
359     }
360 
361     /**
362      * Press on the recents icon
363      * @throws RemoteException if press recents is not successful
364      */
pressUiRecentApps()365     private void pressUiRecentApps() throws RemoteException {
366         mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")).click();
367     }
368 
369     /**
370      * To open the home screen.
371      * @throws RemoteException if press home is not successful
372      */
pressUiHome()373     private void pressUiHome() throws RemoteException {
374         mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "home")).click();
375     }
376 
377     /**
378      * Open recents task and click on the most recent task.
379      * @throws RemoteException if press recents is not successful
380      */
openMostRecentTask()381     public void openMostRecentTask() throws RemoteException {
382         pressUiRecentApps();
383         UiObject2 recentsView = mDevice.wait(Until.findObject(
384                 By.res(SYSTEMUI_PACKAGE, "recents_view")), 5000);
385         List<UiObject2> recentsTasks = recentsView.getChildren().get(0)
386                 .getChildren();
387         UiObject2 mostRecentTask = recentsTasks.get(recentsTasks.size() - 1);
388         mostRecentTask.click();
389     }
390 
391     /**
392      * Create sub directory under the trace root directory to store the trace files captured during
393      * the app transition.
394      * @param subDirectoryName
395      */
createTraceDirectory(String subDirectoryName)396     private void createTraceDirectory(String subDirectoryName) throws IOException {
397         mRootTrace = new File(mTraceDirectoryStr);
398         if (!mRootTrace.exists() && !mRootTrace.mkdirs()) {
399             throw new IOException("Unable to create the trace directory");
400         }
401         mRootTraceSubDir = new File(mRootTrace, subDirectoryName);
402         if (!mRootTraceSubDir.exists() && !mRootTraceSubDir.mkdirs()) {
403             throw new IOException("Unable to create the trace sub directory");
404         }
405         mAtraceLogger = AtraceLogger.getAtraceLoggerInstance(getInstrumentation());
406     }
407 
408     /**
409      * Force stop the given list of apps, clear the cache and return to home screen.
410      * @throws RemoteException if press home is not successful
411      */
cleanTestApps()412     private void cleanTestApps() throws RemoteException {
413         if (null != mPreAppsListArray && mPreAppsListArray.length > 0) {
414             closeApps(mPreAppsListArray);
415         }
416         closeApps(mAppListArray);
417         getInstrumentation().getUiAutomation()
418                         .executeShellCommand(DROP_CACHE_SCRIPT);
419         pressUiHome();
420         sleep(mPostLaunchTimeout);
421     }
422 
423     /**
424      * Populate the recents list with given list of apps.
425      * @throws RemoteException if press home is not successful
426      */
populateRecentsList()427     private void populateRecentsList() throws RemoteException {
428         for (int preAppCount = 0; preAppCount < mPreAppsListArray.length; preAppCount++) {
429             startApp(mPreAppsListArray[preAppCount], COLD_LAUNCH);
430             sleep(mPostLaunchTimeout);
431             pressUiHome();
432             sleep(mPostLaunchTimeout);
433         }
434     }
435 
436 
437     /**
438      * To obtain the app name and corresponding intent to launch the app.
439      */
createLaunchIntentMappings()440     private void createLaunchIntentMappings() {
441         mAppLaunchIntentsMapping = new LinkedHashMap<String, Intent>();
442         PackageManager pm = getInstrumentation().getContext()
443                 .getPackageManager();
444         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
445         intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
446         List<ResolveInfo> ris = pm.queryIntentActivities(intentToResolve, 0);
447         resolveLoop(ris, intentToResolve, pm);
448     }
449 
resolveLoop(List<ResolveInfo> ris, Intent intentToResolve, PackageManager pm)450     private void resolveLoop(List<ResolveInfo> ris, Intent intentToResolve, PackageManager pm) {
451         if (ris == null || ris.isEmpty()) {
452             Log.i(TAG, "Could not find any apps");
453         } else {
454             for (ResolveInfo ri : ris) {
455                 Intent startIntent = new Intent(intentToResolve);
456                 startIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
457                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
458                 startIntent.setClassName(ri.activityInfo.packageName,
459                         ri.activityInfo.name);
460                 String appName = ri.loadLabel(pm).toString();
461                 if (appName != null) {
462                     mAppLaunchIntentsMapping.put(appName, startIntent);
463                 }
464             }
465         }
466     }
467 
468     /**
469      * Launch an app using the app name and return the app launch time. If app launch time is -1
470      * then app launch is not successful.
471      * @param appName Name of an app as listed in the launcher
472      * @param launchMode Cold or Hot launch
473      * @return
474      */
startApp(String appName, String launchMode)475     private long startApp(String appName, String launchMode) {
476         Log.i(TAG, "Starting " + appName);
477         Intent startIntent = mAppLaunchIntentsMapping.get(appName);
478         if (startIntent == null) {
479             return -1L;
480         }
481         AppLaunchRunnable runnable = new AppLaunchRunnable(startIntent, launchMode);
482         Thread t = new Thread(runnable);
483         t.start();
484         try {
485             t.join(JOIN_TIMEOUT);
486         } catch (InterruptedException e) {
487             // ignore
488         }
489         mComponentName = runnable.getCmpName();
490         return runnable.getResult();
491     }
492 
493     private class AppLaunchRunnable implements Runnable {
494         private Intent mLaunchIntent;
495         private String mLaunchMode;
496         private Long mResult = -1L;
497         private String mCmpName;
498 
AppLaunchRunnable(Intent intent, String launchMode)499         public AppLaunchRunnable(Intent intent, String launchMode) {
500             mLaunchIntent = intent;
501             mLaunchMode = launchMode;
502         }
503 
getResult()504         public Long getResult() {
505             return mResult;
506         }
507 
getCmpName()508         public String getCmpName() {
509             return mCmpName;
510         }
511 
512         @Override
run()513         public void run() {
514             String packageName = mLaunchIntent.getComponent().getPackageName();
515             String componentName = mLaunchIntent.getComponent().flattenToShortString();
516             String launchCmd = String.format("%s %s", APP_LAUNCH_CMD, componentName);
517             ParcelFileDescriptor parcelDesc = getInstrumentation().getUiAutomation()
518                     .executeShellCommand(launchCmd);
519             mResult = Long.parseLong(parseLaunchTime(parcelDesc));
520         }
521 
522         /**
523          * Returns launch time if app launch is successful otherwise "-1"
524          * @param parcelDesc
525          * @return
526          */
parseLaunchTime(ParcelFileDescriptor parcelDesc)527         private String parseLaunchTime(ParcelFileDescriptor parcelDesc) {
528             String launchTime = "-1";
529             boolean launchSuccess = false;
530             mCmpName = null;
531             try {
532                 InputStream inputStream = new FileInputStream(parcelDesc.getFileDescriptor());
533                 StringBuilder appLaunchOuput = new StringBuilder();
534                 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
535                         inputStream));
536                 String line = null;
537                 int lineCount = 1;
538                 while ((line = bufferedReader.readLine()) != null) {
539                     if (lineCount == 2) {
540                         if ((mLaunchMode.contains(COLD_LAUNCH) || mLaunchMode.contains(NOT_SURE))
541                                 && line.contains(SUCCESS_MESSAGE)) {
542                             launchSuccess = true;
543                         } else if ((mLaunchMode.contains(HOT_LAUNCH) || mLaunchMode
544                                 .contains(NOT_SURE)) && line.contains(HOT_LAUNCH_MESSAGE)) {
545                             launchSuccess = true;
546                         }
547                     }
548                     if ((launchSuccess && (mLaunchMode.contains(COLD_LAUNCH)
549                             || mLaunchMode.contains(NOT_SURE)) && lineCount == 4) ||
550                             (launchSuccess && (mLaunchMode.contains(HOT_LAUNCH) ||
551                                     mLaunchMode.contains(NOT_SURE)) && lineCount == 5)) {
552                         String launchSplit[] = line.split(":");
553                         launchTime = launchSplit[1].trim();
554                     }
555                     // Needed to update the component name if the very first launch activity
556                     // is different from hot launch activity (i.e YouTube)
557                     if ((launchSuccess && (mLaunchMode.contains(HOT_LAUNCH) ||
558                             mLaunchMode.contains(NOT_SURE)) && lineCount == 4)) {
559                         String activitySplit[] = line.split(":");
560                         if (activitySplit[0].contains(ACTIVITY)) {
561                             mCmpName = activitySplit[1].trim();
562                         }
563                     }
564                     lineCount++;
565                 }
566                 inputStream.close();
567             } catch (IOException e) {
568                 Log.w(TAG, "Error writing the launch file", e);
569             }
570             return launchTime;
571         }
572     }
573 
574     /**
575      * To force stop the given list of apps based on the app name.
576      * @param appNames
577      */
closeApps(String[] appNames)578     private void closeApps(String[] appNames) {
579         for (int i = 0; i < appNames.length; i++) {
580             Intent startIntent = mAppLaunchIntentsMapping.get(appNames[i]);
581             if (startIntent != null) {
582                 String packageName = startIntent.getComponent().getPackageName();
583 
584                 getInstrumentation().getUiAutomation().executeShellCommand(
585                         FORCE_STOP + packageName);
586             }
587             sleep(1000);
588         }
589         sleep(mPostLaunchTimeout);
590     }
591 
592     /**
593      * @return
594      */
isTracesEnabled()595     private boolean isTracesEnabled(){
596         return (null != mTraceDirectoryStr && !mTraceDirectoryStr.isEmpty());
597     }
598 
599     /**
600      * Update the result status
601      * @param appName
602      */
updateResult(String appName)603     private void updateResult(String appName) {
604             // Component name needed for parsing the events log
605             if (null != mComponentName) {
606                 mResult.putString(appName, mComponentName);
607             } else {
608                 // Component name needed for parsing the events log
609                 mResult.putString(appName, mAppLaunchIntentsMapping.get(appName).
610                         getComponent().flattenToShortString());
611             }
612     }
613 
614 
615     /**
616      * To sleep for given millisecs.
617      * @param time
618      */
sleep(int time)619     private void sleep(int time) {
620         try {
621             Thread.sleep(time);
622         } catch (InterruptedException e) {
623             // ignore
624         }
625     }
626 
627     /**
628      * Return the instrumentation from the registry.
629      * @return
630      */
getInstrumentation()631     private Instrumentation getInstrumentation() {
632         return InstrumentationRegistry.getInstrumentation();
633     }
634 }
635