Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e0ae8d6 authored by Tsu Chiang Chuang's avatar Tsu Chiang Chuang Committed by Android (Google) Code Review
Browse files

Merge "Make sure the app is still app after launching. Bug:8755950" into jb-mr2-dev

parents 2f4cc8ea 14c716be
Loading
Loading
Loading
Loading
+61 −14
Original line number Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.compatibilitytest;

import android.app.ActivityManager;
import android.app.ActivityManager.ProcessErrorStateInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.test.InstrumentationTestCase;
import android.util.Log;
@@ -28,9 +31,11 @@ import android.util.Log;
import junit.framework.Assert;

import java.util.Collection;
import java.util.List;

/**
 * Application Compatibility Test that launches an application and detects crashes.
 * Application Compatibility Test that launches an application and detects
 * crashes.
 */
public class AppCompatibility extends InstrumentationTestCase {

@@ -83,7 +88,9 @@ public class AppCompatibility extends InstrumentationTestCase {
    }

    /**
     * Actual test case that launches the package and throws an exception on the first error.
     * Actual test case that launches the package and throws an exception on the
     * first error.
     *
     * @throws Exception
     */
    public void testAppStability() throws Exception {
@@ -91,9 +98,11 @@ public class AppCompatibility extends InstrumentationTestCase {
        if (packageName != null) {
            Log.d(TAG, "Launching app " + packageName);
            Collection<ProcessErrorStateInfo> err = launchActivity(packageName);
            // Make sure there are no errors when launching the application, otherwise raise an
            // Make sure there are no errors when launching the application,
            // otherwise raise an
            // exception with the first error encountered.
            assertNull(getFirstError(err), err);
            assertTrue("App crashed after launch.", processStillUp(packageName));
        } else {
            Log.d(TAG, "Missing argument, use " + PACKAGE_TO_LAUNCH +
                    " to specify the package to launch");
@@ -102,6 +111,7 @@ public class AppCompatibility extends InstrumentationTestCase {

    /**
     * Gets the first error in collection and return the long message for it.
     *
     * @param in {@link Collection} of {@link ProcessErrorStateInfo} to parse.
     * @return {@link String} the long message of the error.
     */
@@ -118,8 +128,11 @@ public class AppCompatibility extends InstrumentationTestCase {

    /**
     * Launches and activity and queries for errors.
     * @param packageName {@link String} the package name of the application to launch.
     * @return  {@link Collection} of {@link ProcessErrorStateInfo} detected during the app launch.
     *
     * @param packageName {@link String} the package name of the application to
     *            launch.
     * @return {@link Collection} of {@link ProcessErrorStateInfo} detected
     *         during the app launch.
     */
    private Collection<ProcessErrorStateInfo> launchActivity(String packageName) {
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
@@ -129,14 +142,20 @@ public class AppCompatibility extends InstrumentationTestCase {
        Intent intent = mPackageManager.getLaunchIntentForPackage(packageName);
        // Skip if the apk does not have a launch intent.
        if (intent == null) {
            Log.d(TAG, "Skipping " + packageName + "; missing launch intent");
            return null;
        }

        // We check for any Crash or ANR dialogs that are already up, and we ignore them.  This is
        // so that we don't report crashes that were caused by prior apps (which those particular
        // tests should have caught and reported already).  Otherwise, test failures would cascade
        // from the initial broken app to many/all of the tests following that app's launch.
        final Collection<ProcessErrorStateInfo> preErr = mActivityManager.getProcessesInErrorState();
        // We check for any Crash or ANR dialogs that are already up, and we
        // ignore them. This is
        // so that we don't report crashes that were caused by prior apps (which
        // those particular
        // tests should have caught and reported already). Otherwise, test
        // failures would cascade
        // from the initial broken app to many/all of the tests following that
        // app's launch.
        final Collection<ProcessErrorStateInfo> preErr =
                mActivityManager.getProcessesInErrorState();

        // Launch Activity
        mContext.startActivity(intent);
@@ -155,15 +174,43 @@ public class AppCompatibility extends InstrumentationTestCase {
            // ignore
        }

        // See if there are any errors.  We wait until down here to give ANRs as much time as
        // See if there are any errors. We wait until down here to give ANRs as
        // much time as
        // possible to occur.
        final Collection<ProcessErrorStateInfo> postErr =
                mActivityManager.getProcessesInErrorState();
        // Take the difference between the error processes we see now, and the ones that were
        // Take the difference between the error processes we see now, and the
        // ones that were
        // present when we started
        if (preErr != null && postErr != null) {
            postErr.removeAll(preErr);
        }
        return postErr;
    }

    /**
     * Determine if a given package is still running.
     *
     * @param packageName {@link String} package to look for
     * @return True if package is running, false otherwise.
     */
    private boolean processStillUp(String packageName) {
        try {
            PackageInfo packageInfo = mPackageManager.getPackageInfo(packageName, 0);
            String processName = packageInfo.applicationInfo.processName;
            List<RunningAppProcessInfo> runningApps = mActivityManager.getRunningAppProcesses();
            for (RunningAppProcessInfo app : runningApps) {
                if (app.processName.equalsIgnoreCase(processName)) {
                    Log.d(TAG, "Found process " + app.processName);
                    return true;
                }
            }
            Log.d(TAG, "Failed to find process " + processName + " with package name "
                    + packageName);
        } catch (NameNotFoundException e) {
            Log.w(TAG, "Failed to find package " + packageName);
            return false;
        }
        return false;
    }
}