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

Commit 7f936863 authored by Bryce Lee's avatar Bryce Lee
Browse files

Introduce result ranges for activity start return results.

The return result from starting activity actually represents two
pieces of information. First, it conveys whether the activity
started. Secondly, it conveys whether there was a fatal error if
the activity did not start. Many parts of the code assume that a
value greater than or equal to the defined success means that the
activity successfully started. This is not the case as there are a
number of results greater than success where the activity does not
start.

This change addresses the issue by introducing three distinct
result ranges. The first represents results where the activity
could not start due to a fatal error. The second represents results
where the activity did not start due to a non-fatal error. The last
range represents successful activity starts. Two convenience methods
have been added to ActivityManager to return whether the result
represents a fatal error and whether the result was successful.

Change-Id: Ifaf844c353641a28b03b3c2d7b6be053fd9b8b44
Fixes: 38021882
Test: cts-tradefed run cts-dev --module DevicePolicyManager --test com.android.cts.devicepolicy.DeviceOwnerTest#testLockTask_deviceOwnerUser
parent f1a00e2b
Loading
Loading
Loading
Loading
+44 −16
Original line number Original line Diff line number Diff line
@@ -126,6 +126,14 @@ public class ActivityManager {


    private static volatile boolean sSystemReady = false;
    private static volatile boolean sSystemReady = false;



    private static final int FIRST_START_FATAL_ERROR_CODE = -100;
    private static final int LAST_START_FATAL_ERROR_CODE = -1;
    private static final int FIRST_START_SUCCESS_CODE = 0;
    private static final int LAST_START_SUCCESS_CODE = 99;
    private static final int FIRST_START_NON_FATAL_ERROR_CODE = 100;
    private static final int LAST_START_NON_FATAL_ERROR_CODE = 199;

    /**
    /**
     * System property to enable task snapshots.
     * System property to enable task snapshots.
     * @hide
     * @hide
@@ -219,53 +227,56 @@ public class ActivityManager {
     */
     */
    public static final String META_HOME_ALTERNATE = "android.app.home.alternate";
    public static final String META_HOME_ALTERNATE = "android.app.home.alternate";


    // NOTE: Before adding a new start result, please reference the defined ranges to ensure the
    // result is properly categorized.

    /**
    /**
     * Result for IActivityManager.startVoiceActivity: active session is currently hidden.
     * Result for IActivityManager.startVoiceActivity: active session is currently hidden.
     * @hide
     * @hide
     */
     */
    public static final int START_VOICE_HIDDEN_SESSION = -10;
    public static final int START_VOICE_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE;


    /**
    /**
     * Result for IActivityManager.startVoiceActivity: active session does not match
     * Result for IActivityManager.startVoiceActivity: active session does not match
     * the requesting token.
     * the requesting token.
     * @hide
     * @hide
     */
     */
    public static final int START_VOICE_NOT_ACTIVE_SESSION = -9;
    public static final int START_VOICE_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 1;


    /**
    /**
     * Result for IActivityManager.startActivity: trying to start a background user
     * Result for IActivityManager.startActivity: trying to start a background user
     * activity that shouldn't be displayed for all users.
     * activity that shouldn't be displayed for all users.
     * @hide
     * @hide
     */
     */
    public static final int START_NOT_CURRENT_USER_ACTIVITY = -8;
    public static final int START_NOT_CURRENT_USER_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 2;


    /**
    /**
     * Result for IActivityManager.startActivity: trying to start an activity under voice
     * Result for IActivityManager.startActivity: trying to start an activity under voice
     * control when that activity does not support the VOICE category.
     * control when that activity does not support the VOICE category.
     * @hide
     * @hide
     */
     */
    public static final int START_NOT_VOICE_COMPATIBLE = -7;
    public static final int START_NOT_VOICE_COMPATIBLE = FIRST_START_FATAL_ERROR_CODE + 3;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
     * start had to be canceled.
     * start had to be canceled.
     * @hide
     * @hide
     */
     */
    public static final int START_CANCELED = -6;
    public static final int START_CANCELED = FIRST_START_FATAL_ERROR_CODE + 4;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
     * thing being started is not an activity.
     * thing being started is not an activity.
     * @hide
     * @hide
     */
     */
    public static final int START_NOT_ACTIVITY = -5;
    public static final int START_NOT_ACTIVITY = FIRST_START_FATAL_ERROR_CODE + 5;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
     * caller does not have permission to start the activity.
     * caller does not have permission to start the activity.
     * @hide
     * @hide
     */
     */
    public static final int START_PERMISSION_DENIED = -4;
    public static final int START_PERMISSION_DENIED = FIRST_START_FATAL_ERROR_CODE + 6;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
@@ -273,49 +284,49 @@ public class ActivityManager {
     * a result.
     * a result.
     * @hide
     * @hide
     */
     */
    public static final int START_FORWARD_AND_REQUEST_CONFLICT = -3;
    public static final int START_FORWARD_AND_REQUEST_CONFLICT = FIRST_START_FATAL_ERROR_CODE + 7;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
     * requested class is not found.
     * requested class is not found.
     * @hide
     * @hide
     */
     */
    public static final int START_CLASS_NOT_FOUND = -2;
    public static final int START_CLASS_NOT_FOUND = FIRST_START_FATAL_ERROR_CODE + 8;


    /**
    /**
     * Result for IActivityManager.startActivity: an error where the
     * Result for IActivityManager.startActivity: an error where the
     * given Intent could not be resolved to an activity.
     * given Intent could not be resolved to an activity.
     * @hide
     * @hide
     */
     */
    public static final int START_INTENT_NOT_RESOLVED = -1;
    public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9;


    /**
    /**
     * Result for IActivityManaqer.startActivity: the activity was started
     * Result for IActivityManaqer.startActivity: the activity was started
     * successfully as normal.
     * successfully as normal.
     * @hide
     * @hide
     */
     */
    public static final int START_SUCCESS = 0;
    public static final int START_SUCCESS = FIRST_START_SUCCESS_CODE;


    /**
    /**
     * Result for IActivityManaqer.startActivity: the caller asked that the Intent not
     * Result for IActivityManaqer.startActivity: the caller asked that the Intent not
     * be executed if it is the recipient, and that is indeed the case.
     * be executed if it is the recipient, and that is indeed the case.
     * @hide
     * @hide
     */
     */
    public static final int START_RETURN_INTENT_TO_CALLER = 1;
    public static final int START_RETURN_INTENT_TO_CALLER = FIRST_START_SUCCESS_CODE + 1;


    /**
    /**
     * Result for IActivityManaqer.startActivity: activity wasn't really started, but
     * Result for IActivityManaqer.startActivity: activity wasn't really started, but
     * a task was simply brought to the foreground.
     * a task was simply brought to the foreground.
     * @hide
     * @hide
     */
     */
    public static final int START_TASK_TO_FRONT = 2;
    public static final int START_TASK_TO_FRONT = FIRST_START_SUCCESS_CODE + 2;


    /**
    /**
     * Result for IActivityManaqer.startActivity: activity wasn't really started, but
     * Result for IActivityManaqer.startActivity: activity wasn't really started, but
     * the given Intent was given to the existing top activity.
     * the given Intent was given to the existing top activity.
     * @hide
     * @hide
     */
     */
    public static final int START_DELIVERED_TO_TOP = 3;
    public static final int START_DELIVERED_TO_TOP = FIRST_START_SUCCESS_CODE + 3;


    /**
    /**
     * Result for IActivityManaqer.startActivity: request was canceled because
     * Result for IActivityManaqer.startActivity: request was canceled because
@@ -323,14 +334,15 @@ public class ActivityManager {
     * (such as pressing home) is performed.
     * (such as pressing home) is performed.
     * @hide
     * @hide
     */
     */
    public static final int START_SWITCHES_CANCELED = 4;
    public static final int START_SWITCHES_CANCELED = FIRST_START_NON_FATAL_ERROR_CODE;


    /**
    /**
     * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
     * Result for IActivityManaqer.startActivity: a new activity was attempted to be started
     * while in Lock Task Mode.
     * while in Lock Task Mode.
     * @hide
     * @hide
     */
     */
    public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION = 5;
    public static final int START_RETURN_LOCK_TASK_MODE_VIOLATION =
            FIRST_START_NON_FATAL_ERROR_CODE + 1;


    /**
    /**
     * Flag for IActivityManaqer.startActivity: do special start mode where
     * Flag for IActivityManaqer.startActivity: do special start mode where
@@ -565,6 +577,22 @@ public class ActivityManager {
        mContext = context;
        mContext = context;
    }
    }


    /**
     * Returns whether the launch was successful.
     * @hide
     */
    public static final boolean isStartResultSuccessful(int result) {
        return FIRST_START_SUCCESS_CODE <= result && result <= LAST_START_SUCCESS_CODE;
    }

    /**
     * Returns whether the launch result was a fatal error.
     * @hide
     */
    public static final boolean isStartResultFatalError(int result) {
        return FIRST_START_FATAL_ERROR_CODE <= result && result <= LAST_START_FATAL_ERROR_CODE;
    }

    /**
    /**
     * Screen compatibility mode: the application most always run in
     * Screen compatibility mode: the application most always run in
     * compatibility mode.
     * compatibility mode.
+1 −1
Original line number Original line Diff line number Diff line
@@ -1921,7 +1921,7 @@ public class Instrumentation {


    /** @hide */
    /** @hide */
    public static void checkStartActivityResult(int res, Object intent) {
    public static void checkStartActivityResult(int res, Object intent) {
        if (res >= ActivityManager.START_SUCCESS) {
        if (!ActivityManager.isStartResultFatalError(res)) {
            return;
            return;
        }
        }


+1 −1
Original line number Original line Diff line number Diff line
@@ -64,7 +64,7 @@ public class WorkLockActivityController {
        options.setTaskOverlay(true, false /* canResume */);
        options.setTaskOverlay(true, false /* canResume */);


        final int result = startActivityAsUser(intent, options.toBundle(), UserHandle.USER_CURRENT);
        final int result = startActivityAsUser(intent, options.toBundle(), UserHandle.USER_CURRENT);
        if (result >= ActivityManager.START_SUCCESS) {
        if (ActivityManager.isStartResultSuccessful(result)) {
            // OK
            // OK
        } else {
        } else {
            // Starting the activity inside the task failed. We can't be sure why, so to be
            // Starting the activity inside the task failed. We can't be sure why, so to be
+1 −1
Original line number Original line Diff line number Diff line
@@ -640,7 +640,7 @@ final class UiModeManagerService extends SystemService {
                    int result = ActivityManager.getService().startActivityWithConfig(
                    int result = ActivityManager.getService().startActivityWithConfig(
                            null, null, homeIntent, null, null, null, 0, 0,
                            null, null, homeIntent, null, null, null, 0, 0,
                            mConfiguration, null, UserHandle.USER_CURRENT);
                            mConfiguration, null, UserHandle.USER_CURRENT);
                    if (result >= ActivityManager.START_SUCCESS) {
                    if (ActivityManager.isStartResultSuccessful(result)) {
                        dockAppStarted = true;
                        dockAppStarted = true;
                    } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
                    } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
                        Slog.e(TAG, "Could not start dock app: " + homeIntent
                        Slog.e(TAG, "Could not start dock app: " + homeIntent
+3 −2
Original line number Original line Diff line number Diff line
@@ -544,7 +544,7 @@ class ActivityStarter {
            ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
            ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
            ActivityStack targetStack) {
            ActivityStack targetStack) {


        if (result < START_SUCCESS) {
        if (ActivityManager.isStartResultFatalError(result)) {
            return;
            return;
        }
        }


@@ -956,7 +956,8 @@ class ActivityStarter {
            // If we are not able to proceed, disassociate the activity from the task. Leaving an
            // If we are not able to proceed, disassociate the activity from the task. Leaving an
            // activity in an incomplete state can lead to issues, such as performing operations
            // activity in an incomplete state can lead to issues, such as performing operations
            // without a window container.
            // without a window container.
            if (result < START_SUCCESS && mStartActivity.getTask() != null) {
            if (ActivityManager.isStartResultFatalError(result)
                    && mStartActivity.getTask() != null) {
                mStartActivity.getTask().removeActivity(mStartActivity);
                mStartActivity.getTask().removeActivity(mStartActivity);
            }
            }
            mService.mWindowManager.continueSurfaceLayout();
            mService.mWindowManager.continueSurfaceLayout();
Loading