Home | History | Annotate | Download | only in tests
      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.ActivityManager;
     20 import android.app.IActivityManager;
     21 import android.app.Instrumentation;
     22 import android.content.Context;
     23 import android.content.Intent;
     24 import android.content.pm.PackageManager;
     25 import android.content.pm.ResolveInfo;
     26 import android.os.Bundle;
     27 import android.os.ParcelFileDescriptor;
     28 import android.os.RemoteException;
     29 import android.support.test.InstrumentationRegistry;
     30 import android.support.test.launcherhelper.ILauncherStrategy;
     31 import android.support.test.launcherhelper.LauncherStrategyFactory;
     32 import android.support.test.rule.logging.AtraceLogger;
     33 import android.support.test.uiautomator.By;
     34 import android.support.test.uiautomator.UiDevice;
     35 import android.support.test.uiautomator.UiObject2;
     36 import android.support.test.uiautomator.Until;
     37 import android.util.Log;
     38 
     39 import java.io.BufferedReader;
     40 import java.io.File;
     41 import java.io.FileInputStream;
     42 import java.io.InputStream;
     43 import java.io.InputStreamReader;
     44 import java.io.IOException;
     45 import java.util.HashSet;
     46 import java.util.HashMap;
     47 import java.util.List;
     48 import java.util.LinkedHashMap;
     49 import java.util.Map;
     50 import java.util.Set;
     51 
     52 import org.junit.After;
     53 import org.junit.Before;
     54 import org.junit.Test;
     55 
     56 public class AppTransitionTests {
     57 
     58     private static final String TAG = AppTransitionTests.class.getSimpleName();
     59     private static final int JOIN_TIMEOUT = 10000;
     60     private static final int DEFAULT_DROP_CACHE_DELAY = 2000;
     61     private static final String DEFAULT_POST_LAUNCH_TIMEOUT = "5000";
     62     private static final String DEFAULT_LAUNCH_COUNT = "10";
     63     private static final String SUCCESS_MESSAGE = "Status: ok";
     64     private static final String HOT_LAUNCH_MESSAGE = "Warning: Activity not started, its current"
     65             + " task has been brought to the front";
     66     private static final String DROP_CACHE_SCRIPT = "/data/local/tmp/dropCache.sh";
     67     private static final String APP_LAUNCH_CMD = "am start -W -n";
     68     private static final String FORCE_STOP = "am force-stop ";
     69     private static final String PRE_LAUNCH_APPS = "pre_launch_apps";
     70     private static final String LAUNCH_APPS = "launch_apps";
     71     private static final String KEY_LAUNCH_ITERATIONS = "launch_iteration";
     72     private static final String KEY_POST_LAUNCH_TIMEOUT = "postlaunch_timeout";
     73     private static final String COLD_LAUNCH = "cold_launch";
     74     private static final String HOT_LAUNCH = "hot_launch";
     75     private static final String NOT_SURE = "not_sure";
     76     private static final String ACTIVITY = "Activity";
     77     private static final String NOT_SUCCESSFUL_MESSAGE = "App launch not successful";
     78     private static final String KEY_TRACE_DIRECTORY = "trace_directory";
     79     private static final String KEY_TRACE_CATEGORY = "trace_categories";
     80     private static final String KEY_TRACE_BUFFERSIZE = "trace_bufferSize";
     81     private static final String KEY_TRACE_DUMPINTERVAL = "tracedump_interval";
     82     private static final String DEFAULT_TRACE_CATEGORIES = "sched,freq,gfx,view,dalvik,webview,"
     83             + "input,wm,disk,am,wm";
     84     private static final String DEFAULT_TRACE_BUFFER_SIZE = "20000";
     85     private static final String DEFAULT_TRACE_DUMP_INTERVAL = "10";
     86     private static final String DELIMITER = ",";
     87     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
     88     private Context mContext;
     89     private UiDevice mDevice;
     90     private PackageManager mPackageManager;
     91     private IActivityManager mActivityManager;
     92     private ILauncherStrategy mLauncherStrategy = null;
     93     private Map<String, Intent> mAppLaunchIntentsMapping = null;
     94     private String mTraceDirectoryStr = null;
     95     private Bundle mResult = new Bundle();
     96     private Bundle mArgs;
     97     private String mPreAppsList;
     98     private int mLaunchIterations;
     99     private int mPostLaunchTimeout;
    100     private String[] mAppListArray;
    101     private String[] mPreAppsListArray;
    102     private File mRootTrace = null;
    103     private File mRootTraceSubDir = null;
    104     private int mTraceBufferSize = 0;
    105     private int mTraceDumpInterval = 0;
    106     private Set<String> mTraceCategoriesSet = null;
    107     private AtraceLogger mAtraceLogger = null;
    108     private String mComponentName = null;
    109     private Map<String,String> mPreAppsComponentName = new HashMap<String, String>();
    110 
    111     @Before
    112     public void setUp() throws Exception {
    113         mPackageManager = getInstrumentation().getContext().getPackageManager();
    114         mContext = getInstrumentation().getContext();
    115         mArgs = InstrumentationRegistry.getArguments();
    116         mActivityManager = ActivityManager.getService();
    117         mDevice = UiDevice.getInstance(getInstrumentation());
    118         mLauncherStrategy = LauncherStrategyFactory.getInstance(mDevice).getLauncherStrategy();
    119         createLaunchIntentMappings();
    120         String mAppsList = mArgs.getString(LAUNCH_APPS);
    121         mPreAppsList = mArgs.getString(PRE_LAUNCH_APPS);
    122         mLaunchIterations = Integer.parseInt(mArgs.getString(KEY_LAUNCH_ITERATIONS,
    123                 DEFAULT_LAUNCH_COUNT));
    124         mPostLaunchTimeout = Integer.parseInt(mArgs.getString(KEY_POST_LAUNCH_TIMEOUT,
    125                 DEFAULT_POST_LAUNCH_TIMEOUT));
    126         if (null == mAppsList && mAppsList.isEmpty()) {
    127             throw new IllegalArgumentException("Need atleast one app to do the"
    128                     + " app transition from launcher");
    129         }
    130         mAppsList = mAppsList.replaceAll("%"," ");
    131         mAppListArray = mAppsList.split(DELIMITER);
    132 
    133         // Parse the trace parameters
    134         mTraceDirectoryStr = mArgs.getString(KEY_TRACE_DIRECTORY);
    135         if (isTracesEnabled()) {
    136             String traceCategoriesStr = mArgs
    137                     .getString(KEY_TRACE_CATEGORY, DEFAULT_TRACE_CATEGORIES);
    138             mTraceBufferSize = Integer.parseInt(mArgs.getString(KEY_TRACE_BUFFERSIZE,
    139                     DEFAULT_TRACE_BUFFER_SIZE));
    140             mTraceDumpInterval = Integer.parseInt(mArgs.getString(KEY_TRACE_DUMPINTERVAL,
    141                     DEFAULT_TRACE_DUMP_INTERVAL));
    142             mTraceCategoriesSet = new HashSet<String>();
    143             if (!traceCategoriesStr.isEmpty()) {
    144                 String[] traceCategoriesSplit = traceCategoriesStr.split(DELIMITER);
    145                 for (int i = 0; i < traceCategoriesSplit.length; i++) {
    146                     mTraceCategoriesSet.add(traceCategoriesSplit[i]);
    147                 }
    148             }
    149         }
    150         mDevice.setOrientationNatural();
    151         sleep(mPostLaunchTimeout);
    152         cleanTestApps();
    153     }
    154 
    155     @After
    156     public void tearDown() throws Exception{
    157         cleanTestApps();
    158         getInstrumentation().sendStatus(0, mResult);
    159     }
    160 
    161     /**
    162      * Cold launch given list of apps for given launch count from the launcher screen.
    163      * @throws IOException if there are issues in writing atrace file
    164      * @throws InterruptedException if there are interrupt during the sleep
    165      * @throws RemoteException if press home is not successful
    166      */
    167     @Test
    168     public void testColdLaunchFromLauncher() throws IOException, InterruptedException,
    169             RemoteException {
    170         if (isTracesEnabled()) {
    171             createTraceDirectory("testColdLaunchFromLauncher");
    172         }
    173         // Perform cold app launch from launcher screen
    174         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
    175             String appName = mAppListArray[appCount];
    176             // Additional launch to account for cold launch
    177             if (setupAppLaunch(appName) == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
    178                 continue;
    179             }
    180             closeApps(new String[] {
    181                     appName
    182             });
    183             getInstrumentation().getUiAutomation()
    184                     .executeShellCommand(DROP_CACHE_SCRIPT);
    185             sleep(DEFAULT_DROP_CACHE_DELAY);
    186             for (int launchCount = 0; launchCount <= mLaunchIterations; launchCount++) {
    187                 if (null != mAtraceLogger) {
    188                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
    189                             mTraceDumpInterval, mRootTraceSubDir,
    190                             String.format("%s-%d", appName, launchCount));
    191                 }
    192                 mLauncherStrategy.launch(appName, mComponentName.split("\\/")[0]);
    193                 if (null != mAtraceLogger) {
    194                     mAtraceLogger.atraceStop();
    195                 }
    196                 sleep(mPostLaunchTimeout);
    197                 mDevice.pressHome();
    198 		mDevice.waitForIdle();
    199                 closeApps(new String[] {
    200                         appName
    201                 });
    202                 sleep(mPostLaunchTimeout);
    203                 getInstrumentation().getUiAutomation()
    204                         .executeShellCommand(DROP_CACHE_SCRIPT);
    205                 sleep(DEFAULT_DROP_CACHE_DELAY);
    206             }
    207             mComponentName = null;
    208             // Update the result with the component name
    209             updateResult(appName);
    210         }
    211     }
    212 
    213     /**
    214      * Hot launch given list of apps for given launch count from the launcher screen. Same method can be
    215      * used to test app to home transition delay information as well.
    216      * @throws IOException if there are issues in writing atrace file
    217      * @throws InterruptedException if there are interrupt during the sleep
    218      * @throws RemoteException if press home is not successful
    219      */
    220     @Test
    221     public void testHotLaunchFromLauncher() throws IOException, InterruptedException,
    222             RemoteException {
    223         if (isTracesEnabled()) {
    224             createTraceDirectory("testHotLaunchFromLauncher");
    225         }
    226         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
    227             String appName = mAppListArray[appCount];
    228             // Additional launch to account for cold launch
    229             if (setupAppLaunch(appName) == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
    230                 continue;
    231             }
    232             // Hot app launch for given (launch iterations + 1) times.
    233             for (int launchCount = 0; launchCount <= (mLaunchIterations); launchCount++) {
    234                 if (null != mAtraceLogger) {
    235                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
    236                             mTraceDumpInterval, mRootTraceSubDir,
    237                             String.format("%s-%d", appName, (launchCount)));
    238                 }
    239                 mLauncherStrategy.launch(appName, mComponentName.split("\\/")[0]);
    240                 if (null != mAtraceLogger) {
    241                     mAtraceLogger.atraceStop();
    242                 }
    243                 sleep(mPostLaunchTimeout);
    244                 mDevice.pressHome();
    245                 sleep(mPostLaunchTimeout);
    246             }
    247             mComponentName = null;
    248             // Update the result with the component name
    249             updateResult(appName);
    250         }
    251     }
    252 
    253     /**
    254      * Launch an app and press recents for given list of apps for given launch counts.
    255      * @throws IOException if there are issues in writing atrace file
    256      * @throws InterruptedException if there are interrupt during the sleep
    257      * @throws RemoteException if press recent apps is not successful
    258      */
    259     @Test
    260     public void testAppToRecents() throws IOException, InterruptedException, RemoteException {
    261         if (isTracesEnabled()) {
    262             createTraceDirectory("testAppToRecents");
    263         }
    264         if (null == mPreAppsList && mPreAppsList.isEmpty()) {
    265             throw new IllegalArgumentException("Need atleast few apps in the "
    266                     + "recents before starting the test");
    267         }
    268         mPreAppsList = mPreAppsList.replaceAll("%"," ");
    269         mPreAppsListArray = mPreAppsList.split(DELIMITER);
    270         mPreAppsComponentName.clear();
    271         populateRecentsList();
    272         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
    273             String appName = mAppListArray[appCount];
    274             long appLaunchTime = -1L;
    275             for (int launchCount = 0; launchCount <= mLaunchIterations; launchCount++) {
    276                 mLauncherStrategy.launch(appName, mPreAppsComponentName.get(appName).split(
    277                         "\\/")[0]);
    278                 sleep(mPostLaunchTimeout);
    279                 if (null != mAtraceLogger && launchCount > 0) {
    280                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
    281                             mTraceDumpInterval, mRootTraceSubDir,
    282                             String.format("%s-%d", appName, launchCount - 1));
    283                 }
    284                 pressUiRecentApps();
    285                 sleep(mPostLaunchTimeout);
    286                 if (null != mAtraceLogger && launchCount > 0) {
    287                     mAtraceLogger.atraceStop();
    288                 }
    289                 mDevice.pressHome();
    290                 sleep(mPostLaunchTimeout);
    291             }
    292             updateResult(appName);
    293         }
    294     }
    295 
    296     /**
    297      * Hot launch an app from recents for given list of apps for given launch counts.
    298      * @throws IOException if there are issues in writing atrace file
    299      * @throws InterruptedException if there are interrupt during the sleep
    300      * @throws RemoteException if press recent apps is not successful
    301      */
    302     @Test
    303     public void testHotLaunchFromRecents() throws IOException, InterruptedException,
    304             RemoteException {
    305         if (isTracesEnabled()) {
    306             createTraceDirectory("testHotLaunchFromRecents");
    307         }
    308         if (null == mPreAppsList && mPreAppsList.isEmpty()) {
    309             throw new IllegalArgumentException("Need atleast few apps in the"
    310                     + " recents before starting the test");
    311         }
    312         mPreAppsList = mPreAppsList.replaceAll("%", " ");
    313         mPreAppsListArray = mPreAppsList.split(DELIMITER);
    314         mPreAppsComponentName.clear();
    315         populateRecentsList();
    316         for (int appCount = 0; appCount < mAppListArray.length; appCount++) {
    317             String appName = mAppListArray[appCount];
    318             // To bring the app to launch as first item from recents task.
    319             mLauncherStrategy.launch(appName, mPreAppsComponentName.get(appName).split(
    320                     "\\/")[0]);
    321             sleep(mPostLaunchTimeout);
    322             for (int launchCount = 0; launchCount <= mLaunchIterations; launchCount++) {
    323                 if (null != mAtraceLogger) {
    324                     mAtraceLogger.atraceStart(mTraceCategoriesSet, mTraceBufferSize,
    325                             mTraceDumpInterval, mRootTraceSubDir,
    326                             String.format("%s-%d", appName, (launchCount)));
    327                 }
    328                 openMostRecentTask();
    329                 sleep(mPostLaunchTimeout);
    330                 if (null != mAtraceLogger) {
    331                     mAtraceLogger.atraceStop();
    332                 }
    333                 mDevice.pressHome();
    334                 sleep(mPostLaunchTimeout);
    335             }
    336             updateResult(appName);
    337         }
    338     }
    339 
    340     /**
    341      * Launch given app to account for the cold launch and track
    342      * component name associated with the app.
    343      * @throws RemoteException if press home is not successful
    344      * @param appName
    345      * @return
    346      */
    347     public long setupAppLaunch(String appName) throws RemoteException {
    348         long appLaunchTime = startApp(appName, NOT_SURE);
    349         if (appLaunchTime == ILauncherStrategy.LAUNCH_FAILED_TIMESTAMP) {
    350             return appLaunchTime;
    351         }
    352         sleep(mPostLaunchTimeout);
    353         mDevice.pressHome();
    354         sleep(mPostLaunchTimeout);
    355         return appLaunchTime;
    356     }
    357 
    358     /**
    359      * Press on the recents icon
    360      * @throws RemoteException if press recents is not successful
    361      */
    362     private void pressUiRecentApps() throws RemoteException {
    363         mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "recent_apps")).click();
    364     }
    365 
    366     /**
    367      * To open the home screen.
    368      * @throws RemoteException if press home is not successful
    369      */
    370     private void pressUiHome() throws RemoteException {
    371         mDevice.findObject(By.res(SYSTEMUI_PACKAGE, "home")).click();
    372     }
    373 
    374     /**
    375      * Open recents task and click on the most recent task.
    376      * @throws RemoteException if press recents is not successful
    377      */
    378     public void openMostRecentTask() throws RemoteException {
    379         pressUiRecentApps();
    380         UiObject2 recentsView = mDevice.wait(Until.findObject(
    381                 By.res(SYSTEMUI_PACKAGE, "recents_view")), 5000);
    382         List<UiObject2> recentsTasks = recentsView.getChildren().get(0)
    383                 .getChildren();
    384         UiObject2 mostRecentTask = recentsTasks.get(recentsTasks.size() - 1);
    385         mostRecentTask.click();
    386     }
    387 
    388     /**
    389      * Create sub directory under the trace root directory to store the trace files captured during
    390      * the app transition.
    391      * @param subDirectoryName
    392      */
    393     private void createTraceDirectory(String subDirectoryName) throws IOException {
    394         mRootTrace = new File(mTraceDirectoryStr);
    395         if (!mRootTrace.exists() && !mRootTrace.mkdirs()) {
    396             throw new IOException("Unable to create the trace directory");
    397         }
    398         mRootTraceSubDir = new File(mRootTrace, subDirectoryName);
    399         if (!mRootTraceSubDir.exists() && !mRootTraceSubDir.mkdirs()) {
    400             throw new IOException("Unable to create the trace sub directory");
    401         }
    402         mAtraceLogger = AtraceLogger.getAtraceLoggerInstance(getInstrumentation());
    403     }
    404 
    405     /**
    406      * Force stop the given list of apps, clear the cache and return to home screen.
    407      * @throws RemoteException if press home is not successful
    408      */
    409     private void cleanTestApps() throws RemoteException {
    410         if (null != mPreAppsListArray && mPreAppsListArray.length > 0) {
    411             closeApps(mPreAppsListArray);
    412         }
    413         closeApps(mAppListArray);
    414         getInstrumentation().getUiAutomation()
    415                         .executeShellCommand(DROP_CACHE_SCRIPT);
    416         sleep(DEFAULT_DROP_CACHE_DELAY);
    417         mDevice.pressHome();
    418         sleep(mPostLaunchTimeout);
    419     }
    420 
    421     /**
    422      * Populate the recents list with given list of apps.
    423      * @throws RemoteException if press home is not successful
    424      */
    425     private void populateRecentsList() throws RemoteException {
    426         for (int preAppCount = 0; preAppCount < mPreAppsListArray.length; preAppCount++) {
    427             startApp(mPreAppsListArray[preAppCount], NOT_SURE);
    428             mPreAppsComponentName.put(mPreAppsListArray[preAppCount], mComponentName);
    429             sleep(mPostLaunchTimeout);
    430             mDevice.pressHome();
    431             sleep(mPostLaunchTimeout);
    432         }
    433         mComponentName = null;
    434     }
    435 
    436 
    437     /**
    438      * To obtain the app name and corresponding intent to launch the app.
    439      */
    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 
    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      */
    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 
    499         public AppLaunchRunnable(Intent intent, String launchMode) {
    500             mLaunchIntent = intent;
    501             mLaunchMode = launchMode;
    502         }
    503 
    504         public Long getResult() {
    505             return mResult;
    506         }
    507 
    508         public String getCmpName() {
    509             return mCmpName;
    510         }
    511 
    512         @Override
    513         public void run() {
    514             String packageName = mLaunchIntent.getComponent().getPackageName();
    515             String componentName = mLaunchIntent.getComponent().flattenToString();
    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          */
    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 == 3)) {
    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      */
    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      */
    595     private boolean isTracesEnabled(){
    596         return (null != mTraceDirectoryStr && !mTraceDirectoryStr.isEmpty());
    597     }
    598 
    599     /**
    600      * Update the result status
    601      * @param appName
    602      */
    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().flattenToString());
    611             }
    612     }
    613 
    614 
    615     /**
    616      * To sleep for given millisecs.
    617      * @param time
    618      */
    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      */
    631     private Instrumentation getInstrumentation() {
    632         return InstrumentationRegistry.getInstrumentation();
    633     }
    634 }
    635