Merge "Introduce result ranges for activity start return results." into oc-dev
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9af74ba..0925217 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -126,6 +126,14 @@
 
     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.
      * @hide
@@ -219,53 +227,56 @@
      */
     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.
      * @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
      * the requesting token.
      * @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
      * activity that shouldn't be displayed for all users.
      * @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
      * control when that activity does not support the VOICE category.
      * @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
      * start had to be canceled.
      * @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
      * thing being started is not an activity.
      * @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
      * caller does not have permission to start the activity.
      * @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
@@ -273,49 +284,49 @@
      * a result.
      * @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
      * requested class is not found.
      * @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
      * given Intent could not be resolved to an activity.
      * @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
      * successfully as normal.
      * @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
      * be executed if it is the recipient, and that is indeed the case.
      * @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
      * a task was simply brought to the foreground.
      * @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
      * the given Intent was given to the existing top activity.
      * @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
@@ -323,14 +334,15 @@
      * (such as pressing home) is performed.
      * @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
      * while in Lock Task Mode.
      * @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
@@ -566,6 +578,22 @@
     }
 
     /**
+     * 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
      * compatibility mode.
      * @hide
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 69ed439..16cbb7c 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1921,7 +1921,7 @@
 
     /** @hide */
     public static void checkStartActivityResult(int res, Object intent) {
-        if (res >= ActivityManager.START_SUCCESS) {
+        if (!ActivityManager.isStartResultFatalError(res)) {
             return;
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
index 5eb483d..f198229 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/WorkLockActivityController.java
@@ -64,7 +64,7 @@
         options.setTaskOverlay(true, false /* canResume */);
 
         final int result = startActivityAsUser(intent, options.toBundle(), UserHandle.USER_CURRENT);
-        if (result >= ActivityManager.START_SUCCESS) {
+        if (ActivityManager.isStartResultSuccessful(result)) {
             // OK
         } else {
             // Starting the activity inside the task failed. We can't be sure why, so to be
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 04421cc..6b5366a 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -640,7 +640,7 @@
                     int result = ActivityManager.getService().startActivityWithConfig(
                             null, null, homeIntent, null, null, null, 0, 0,
                             mConfiguration, null, UserHandle.USER_CURRENT);
-                    if (result >= ActivityManager.START_SUCCESS) {
+                    if (ActivityManager.isStartResultSuccessful(result)) {
                         dockAppStarted = true;
                     } else if (result != ActivityManager.START_INTENT_NOT_RESOLVED) {
                         Slog.e(TAG, "Could not start dock app: " + homeIntent
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 6d4eb5b..a2eec5c 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -544,7 +544,7 @@
             ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
             ActivityStack targetStack) {
 
-        if (result < START_SUCCESS) {
+        if (ActivityManager.isStartResultFatalError(result)) {
             return;
         }
 
@@ -956,7 +956,8 @@
             // 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
             // without a window container.
-            if (result < START_SUCCESS && mStartActivity.getTask() != null) {
+            if (ActivityManager.isStartResultFatalError(result)
+                    && mStartActivity.getTask() != null) {
                 mStartActivity.getTask().removeActivity(mStartActivity);
             }
             mService.mWindowManager.continueSurfaceLayout();
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index f79f6f4..29f9f7c 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -546,12 +546,12 @@
             try {
                 code = mActivityManagerInternal.startActivitiesAsPackage(publisherPackage,
                         userId, intents, startActivityOptions);
-                if (code >= ActivityManager.START_SUCCESS) {
+                if (ActivityManager.isStartResultSuccessful(code)) {
                     return true; // Success
                 } else {
                     Log.e(TAG, "Couldn't start activity, code=" + code);
                 }
-                return code >= ActivityManager.START_SUCCESS;
+                return false;
             } catch (SecurityException e) {
                 if (DEBUG) {
                     Slog.d(TAG, "SecurityException while launching intent", e);