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

Commit 34092cf8 authored by Guang Zhu's avatar Guang Zhu
Browse files

improve app crash detection in compatibility test

In addition to ensuring that process exists, we also need to
check that it's the right state. Because crashed foreground
activity can still get started as background service.

Bug: 20899208
Change-Id: I101e556ce757af1afb66686827c5851dd6fda620
parent 9132c5ab
Loading
Loading
Loading
Loading
+42 −16
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.util.Log;

import junit.framework.Assert;

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

@@ -102,7 +103,11 @@ public class AppCompatibility extends InstrumentationTestCase {
            // otherwise raise an
            // exception with the first error encountered.
            assertNull(getStackTrace(err), err);
            try {
                assertTrue("App crashed after launch.", processStillUp(packageName));
            } finally {
                returnHome();
            }
        } else {
            Log.d(TAG, "Missing argument, use " + PACKAGE_TO_LAUNCH +
                    " to specify the package to launch");
@@ -138,6 +143,19 @@ public class AppCompatibility extends InstrumentationTestCase {
        }
    }

    private void returnHome() {
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // Send the "home" intent and wait 2 seconds for us to get there
        mContext.startActivity(homeIntent);
        try {
            Thread.sleep(mWorkspaceLaunchTimeout);
        } catch (InterruptedException e) {
            // ignore
        }
    }

    /**
     * Launches and activity and queries for errors.
     *
@@ -150,9 +168,6 @@ public class AppCompatibility extends InstrumentationTestCase {
        // the recommended way to see if this is a tv or not.
        boolean isleanback = !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)
            && !mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
        Intent homeIntent = new Intent(Intent.ACTION_MAIN);
        homeIntent.addCategory(Intent.CATEGORY_HOME);
        homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        Intent intent;
        if (isleanback) {
            Log.d(TAG, "Leanback and relax! " + packageName);
@@ -173,14 +188,6 @@ public class AppCompatibility extends InstrumentationTestCase {
            // ignore
        }

        // Send the "home" intent and wait 2 seconds for us to get there
        mContext.startActivity(homeIntent);
        try {
            Thread.sleep(mWorkspaceLaunchTimeout);
        } catch (InterruptedException e) {
            // ignore
        }

        // See if there are any errors. We wait until down here to give ANRs as
        // much time as
        // possible to occur.
@@ -198,6 +205,12 @@ public class AppCompatibility extends InstrumentationTestCase {
        return null;
    }

    private boolean ensureForegroundActivity(RunningAppProcessInfo info) {
        Log.d(TAG, String.format("ensureForegroundActivity: proc=%s, pid=%d, state=%d",
                info.processName, info.pid, info.processState));
        return info.processState == ActivityManager.PROCESS_STATE_TOP;
    }

    /**
     * Determine if a given package is still running.
     *
@@ -207,19 +220,32 @@ public class AppCompatibility extends InstrumentationTestCase {
    private boolean processStillUp(String packageName) {
        String processName = getProcessName(packageName);
        List<RunningAppProcessInfo> runningApps = mActivityManager.getRunningAppProcesses();
        List<RunningAppProcessInfo> relatedProcs = new ArrayList<>();
        for (RunningAppProcessInfo app : runningApps) {
            if (app.processName.equalsIgnoreCase(processName)) {
                Log.d(TAG, "Found process " + app.processName);
                if (!ensureForegroundActivity(app)) {
                    Log.w(TAG, "Found process but it's not top activity.");
                    return false;
                }
                return true;
            }
            for (String relatedPackage : app.pkgList) {
                if (relatedPackage.equalsIgnoreCase(processName)) {
                    Log.d(TAG, "Found process " + app.processName);
                if (relatedPackage.equalsIgnoreCase(packageName)) {
                    relatedProcs.add(app);
                }
            }
        }
        // now that we are here, we've found no RAPI's directly matching processName, but
        // potentially a List of them with one of related packages being processName
        if (!relatedProcs.isEmpty()) {
            for (RunningAppProcessInfo app : relatedProcs) {
                if (ensureForegroundActivity(app)) {
                    return true;
                }
            }
            Log.w(TAG, "Found related processes, but none has top activity.");
        }
        Log.d(TAG, "Failed to find process " + processName + " with package name "
        Log.w(TAG, "Failed to find process " + processName + " with package name "
                + packageName);
        return false;
    }