Moving various runtime flags into the common base class.
Caching the ststemApp status for workspace shortcuts.

Change-Id: I25663e1f04a9768afcca000294adcbb00ea1db7b
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 8ac8570..5eb6cc7 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -154,7 +154,7 @@
         for (int i = data.size() - 1; i >= 0; i--) {
             AppInfo info = data.get(i);
             if (matcher.matches(info, info.componentName)) {
-                info.isDisabled = op.apply(info.isDisabled);
+                info.runtimeStatusFlags = op.apply(info.runtimeStatusFlags);
                 modified.add(info);
             }
         }
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index 7d2f753..a5422aa 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -32,10 +32,6 @@
  */
 public class AppInfo extends ItemInfoWithIcon {
 
-    public static final int FLAG_SYSTEM_UNKNOWN = 0;
-    public static final int FLAG_SYSTEM_YES = 1 << 0;
-    public static final int FLAG_SYSTEM_NO = 1 << 1;
-
     /**
      * The intent used to start the application.
      */
@@ -43,16 +39,6 @@
 
     public ComponentName componentName;
 
-    /**
-     * {@see ShortcutInfo#isDisabled}
-     */
-    public int isDisabled = ShortcutInfo.DEFAULT;
-
-    /**
-     * Stores if the app is a system app or not.
-     */
-    public int isSystemApp;
-
     public AppInfo() {
         itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
     }
@@ -74,15 +60,14 @@
         this.container = ItemInfo.NO_ID;
         this.user = user;
         if (PackageManagerHelper.isAppSuspended(info.getApplicationInfo())) {
-            isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+            runtimeStatusFlags |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
         }
         if (quietModeEnabled) {
-            isDisabled |= ShortcutInfo.FLAG_DISABLED_QUIET_USER;
+            runtimeStatusFlags |= ShortcutInfo.FLAG_DISABLED_QUIET_USER;
         }
 
         intent = makeLaunchIntent(info);
-
-        isSystemApp = (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0
+        runtimeStatusFlags |= (info.getApplicationInfo().flags & ApplicationInfo.FLAG_SYSTEM) == 0
                 ? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
 
     }
@@ -92,8 +77,6 @@
         componentName = info.componentName;
         title = Utilities.trim(info.title);
         intent = new Intent(info.intent);
-        isDisabled = info.isDisabled;
-        isSystemApp = info.isSystemApp;
     }
 
     @Override
@@ -119,9 +102,4 @@
                 .setComponent(cn)
                 .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
     }
-
-    @Override
-    public boolean isDisabled() {
-        return isDisabled != 0;
-    }
 }
diff --git a/src/com/android/launcher3/ItemInfoWithIcon.java b/src/com/android/launcher3/ItemInfoWithIcon.java
index 1e020e2..1c4e88b 100644
--- a/src/com/android/launcher3/ItemInfoWithIcon.java
+++ b/src/com/android/launcher3/ItemInfoWithIcon.java
@@ -33,11 +33,70 @@
      */
     public boolean usingLowResIcon;
 
+    /**
+     * Indicates that the icon is disabled due to safe mode restrictions.
+     */
+    public static final int FLAG_DISABLED_SAFEMODE = 1 << 0;
+
+    /**
+     * Indicates that the icon is disabled as the app is not available.
+     */
+    public static final int FLAG_DISABLED_NOT_AVAILABLE = 1 << 1;
+
+    /**
+     * Indicates that the icon is disabled as the app is suspended
+     */
+    public static final int FLAG_DISABLED_SUSPENDED = 1 << 2;
+
+    /**
+     * Indicates that the icon is disabled as the user is in quiet mode.
+     */
+    public static final int FLAG_DISABLED_QUIET_USER = 1 << 3;
+
+    /**
+     * Indicates that the icon is disabled as the publisher has disabled the actual shortcut.
+     */
+    public static final int FLAG_DISABLED_BY_PUBLISHER = 1 << 4;
+
+    /**
+     * Indicates that the icon is disabled as the user partition is currently locked.
+     */
+    public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5;
+
+    public static final int FLAG_DISABLED_MASK = FLAG_DISABLED_SAFEMODE |
+            FLAG_DISABLED_NOT_AVAILABLE | FLAG_DISABLED_SUSPENDED |
+            FLAG_DISABLED_QUIET_USER | FLAG_DISABLED_BY_PUBLISHER | FLAG_DISABLED_LOCKED_USER;
+
+
+    /**
+     * The item points to a system app.
+     */
+    public static final int FLAG_SYSTEM_YES = 1 << 6;
+
+    /**
+     * The item points to a non system app.
+     */
+    public static final int FLAG_SYSTEM_NO = 1 << 7;
+
+    public static final int FLAG_SYSTEM_MASK = FLAG_SYSTEM_YES | FLAG_SYSTEM_NO;
+
+    /**
+     * Status associated with the system state of the underlying item. This is calculated every
+     * time a new info is created and not persisted on the disk.
+     */
+    public int runtimeStatusFlags = 0;
+
     protected ItemInfoWithIcon() { }
 
     protected ItemInfoWithIcon(ItemInfoWithIcon info) {
         super(info);
         iconBitmap = info.iconBitmap;
         usingLowResIcon = info.usingLowResIcon;
+        runtimeStatusFlags = info.runtimeStatusFlags;
+    }
+
+    @Override
+    public boolean isDisabled() {
+        return (runtimeStatusFlags & FLAG_DISABLED_MASK) != 0;
     }
 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 2593c49..1542703 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -19,6 +19,11 @@
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_QUIET_USER;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
 import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.NORMAL;
@@ -2053,10 +2058,10 @@
         // Open shortcut
         final ShortcutInfo shortcut = (ShortcutInfo) tag;
 
-        if (shortcut.isDisabled != 0) {
-            if ((shortcut.isDisabled &
-                    ~ShortcutInfo.FLAG_DISABLED_SUSPENDED &
-                    ~ShortcutInfo.FLAG_DISABLED_QUIET_USER) == 0) {
+        if (shortcut.isDisabled()) {
+            if ((shortcut.runtimeStatusFlags &
+                    ~FLAG_DISABLED_SUSPENDED &
+                    ~FLAG_DISABLED_QUIET_USER) == 0) {
                 // If the app is only disabled because of the above flags, launch activity anyway.
                 // Framework will tell the user why the app is suspended.
             } else {
@@ -2067,10 +2072,10 @@
                 }
                 // Otherwise just use a generic error message.
                 int error = R.string.activity_not_available;
-                if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {
+                if ((shortcut.runtimeStatusFlags & FLAG_DISABLED_SAFEMODE) != 0) {
                     error = R.string.safemode_shortcut_error;
-                } else if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_BY_PUBLISHER) != 0 ||
-                        (shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_LOCKED_USER) != 0) {
+                } else if ((shortcut.runtimeStatusFlags & FLAG_DISABLED_BY_PUBLISHER) != 0 ||
+                        (shortcut.runtimeStatusFlags & FLAG_DISABLED_LOCKED_USER) != 0) {
                     error = R.string.shortcut_not_available;
                 }
                 Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index adf008b..ec608ca 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -65,13 +65,6 @@
     public static final int FLAG_SUPPORTS_WEB_UI = 16; //0B10000;
 
     /**
-     * Indicates if it represents a common type mentioned in {@link CommonAppTypeParser}.
-     * Upto 15 different types supported.
-     */
-    @Deprecated
-    public static final int FLAG_RESTORED_APP_TYPE = 0B0011110000;
-
-    /**
      * The intent used to start the application.
      */
     public Intent intent;
@@ -83,42 +76,6 @@
     public Intent.ShortcutIconResource iconResource;
 
     /**
-     * Indicates that the icon is disabled due to safe mode restrictions.
-     */
-    public static final int FLAG_DISABLED_SAFEMODE = 1 << 0;
-
-    /**
-     * Indicates that the icon is disabled as the app is not available.
-     */
-    public static final int FLAG_DISABLED_NOT_AVAILABLE = 1 << 1;
-
-    /**
-     * Indicates that the icon is disabled as the app is suspended
-     */
-    public static final int FLAG_DISABLED_SUSPENDED = 1 << 2;
-
-    /**
-     * Indicates that the icon is disabled as the user is in quiet mode.
-     */
-    public static final int FLAG_DISABLED_QUIET_USER = 1 << 3;
-
-    /**
-     * Indicates that the icon is disabled as the publisher has disabled the actual shortcut.
-     */
-    public static final int FLAG_DISABLED_BY_PUBLISHER = 1 << 4;
-
-    /**
-     * Indicates that the icon is disabled as the user partition is currently locked.
-     */
-    public static final int FLAG_DISABLED_LOCKED_USER = 1 << 5;
-
-    /**
-     * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
-     * sd-card is not available).
-     */
-    public int isDisabled = DEFAULT;
-
-    /**
      * A message to display when the user tries to start a disabled shortcut.
      * This is currently only used for deep shortcuts.
      */
@@ -142,7 +99,6 @@
         iconResource = info.iconResource;
         status = info.status;
         mInstallProgress = info.mInstallProgress;
-        isDisabled = info.isDisabled;
     }
 
     /** TODO: Remove this.  It's only called by ApplicationInfo.makeShortcut. */
@@ -150,7 +106,6 @@
         super(info);
         title = Utilities.trim(info.title);
         intent = new Intent(info.intent);
-        isDisabled = info.isDisabled;
     }
 
     /**
@@ -219,9 +174,9 @@
         contentDescription = UserManagerCompat.getInstance(context)
                 .getBadgedLabelForUser(label, user);
         if (shortcutInfo.isEnabled()) {
-            isDisabled &= ~FLAG_DISABLED_BY_PUBLISHER;
+            runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER;
         } else {
-            isDisabled |= FLAG_DISABLED_BY_PUBLISHER;
+            runtimeStatusFlags |= FLAG_DISABLED_BY_PUBLISHER;
         }
         disabledMessage = shortcutInfo.getDisabledMessage();
     }
@@ -233,11 +188,6 @@
     }
 
     @Override
-    public boolean isDisabled() {
-        return isDisabled != 0;
-    }
-
-    @Override
     public ComponentName getTargetComponent() {
         ComponentName cn = super.getTargetComponent();
         if (cn == null && (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 8e83a30..68a441a 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -1,5 +1,8 @@
 package com.android.launcher3;
 
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_SYSTEM_MASK;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_SYSTEM_NO;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -83,10 +86,10 @@
             return false;
         }
 
-        if (info instanceof AppInfo) {
-            AppInfo appInfo = (AppInfo) info;
-            if (appInfo.isSystemApp != AppInfo.FLAG_SYSTEM_UNKNOWN) {
-                return (appInfo.isSystemApp & AppInfo.FLAG_SYSTEM_NO) != 0;
+        if (info instanceof ItemInfoWithIcon) {
+            ItemInfoWithIcon iconInfo = (ItemInfoWithIcon) info;
+            if ((iconInfo.runtimeStatusFlags & FLAG_SYSTEM_MASK) != 0) {
+                return (iconInfo.runtimeStatusFlags & FLAG_SYSTEM_NO) != 0;
             }
         }
         return getUninstallTarget(info) != null;
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java
index 06493b2..ed5cfeb 100644
--- a/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java
+++ b/src/com/android/launcher3/discovery/AppDiscoveryAppInfo.java
@@ -41,7 +41,6 @@
         this.intent = item.isInstantApp ? item.launchIntent : item.installIntent;
         this.title = item.title;
         this.iconBitmap = item.bitmap;
-        this.isDisabled = ShortcutInfo.DEFAULT;
         this.usingLowResIcon = false;
         this.isInstantApp = item.isInstantApp;
         this.isRecent = item.isRecent;
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index bc7da9b..47f370a 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -16,11 +16,15 @@
 
 package com.android.launcher3.model;
 
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_SYSTEM_NO;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_SYSTEM_YES;
+
 import android.content.ComponentName;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.Intent.ShortcutIconResource;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.database.Cursor;
 import android.database.CursorWrapper;
@@ -274,8 +278,13 @@
             info.iconBitmap = icon != null ? icon : info.iconBitmap;
         }
 
-        if (lai != null && PackageManagerHelper.isAppSuspended(lai.getApplicationInfo())) {
-            info.isDisabled = ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+        if (lai != null) {
+            ApplicationInfo appInfo = lai.getApplicationInfo();
+            if (PackageManagerHelper.isAppSuspended(appInfo)) {
+                info.runtimeStatusFlags |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+            }
+            info.runtimeStatusFlags |= (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0
+                    ? FLAG_SYSTEM_NO : FLAG_SYSTEM_YES;
         }
 
         // from the db
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 5386fb4..c2cfebb 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -27,8 +27,6 @@
 import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Process;
-import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
@@ -76,6 +74,9 @@
 import java.util.Map;
 import java.util.concurrent.CancellationException;
 
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
 
 /**
@@ -466,13 +467,13 @@
                                                     true /* badged */, fallbackIconProvider);
                                     if (pmHelper.isAppSuspended(
                                             pinnedShortcut.getPackage(), info.user)) {
-                                        info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+                                        info.runtimeStatusFlags |= FLAG_DISABLED_SUSPENDED;
                                     }
                                     intent = info.intent;
                                 } else {
                                     // Create a shortcut info in disabled mode for now.
                                     info = c.loadSimpleShortcut();
-                                    info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
+                                    info.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
                                 }
                             } else { // item type == ITEM_TYPE_SHORTCUT
                                 info = c.loadSimpleShortcut();
@@ -480,7 +481,7 @@
                                 // Shortcuts are only available on the primary profile
                                 if (!TextUtils.isEmpty(targetPkg)
                                         && pmHelper.isAppSuspended(targetPkg, c.user)) {
-                                    disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+                                    disabledState |= FLAG_DISABLED_SUSPENDED;
                                 }
 
                                 // App shortcuts that used to be automatically added to Launcher
@@ -503,9 +504,9 @@
                                 info.rank = c.getInt(rankIndex);
                                 info.spanX = 1;
                                 info.spanY = 1;
-                                info.isDisabled |= disabledState;
+                                info.runtimeStatusFlags |= disabledState;
                                 if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
-                                    info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
+                                    info.runtimeStatusFlags |= FLAG_DISABLED_SAFEMODE;
                                 }
 
                                 if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 53a9862..470dadf 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -244,9 +244,9 @@
                                 infoUpdated = true;
                             }
 
-                            int oldDisabledFlags = si.isDisabled;
-                            si.isDisabled = flagOp.apply(si.isDisabled);
-                            if (si.isDisabled != oldDisabledFlags) {
+                            int oldRuntimeFlags = si.runtimeStatusFlags;
+                            si.runtimeStatusFlags = flagOp.apply(si.runtimeStatusFlags);
+                            if (si.runtimeStatusFlags != oldRuntimeFlags) {
                                 shortcutUpdated = true;
                             }
                         }
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 8170f9a..2e9ac72 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -15,6 +15,8 @@
  */
 package com.android.launcher3.model;
 
+import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
+
 import android.content.Context;
 import android.os.UserHandle;
 
@@ -87,12 +89,12 @@
                         removedKeys.add(key);
                         continue;
                     }
-                    si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
+                    si.runtimeStatusFlags &= ~FLAG_DISABLED_LOCKED_USER;
                     si.updateFromDeepShortcutInfo(shortcut, context);
                     si.iconBitmap = LauncherIcons.createShortcutIcon(shortcut, context,
                             si.iconBitmap);
                 } else {
-                    si.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
+                    si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
                 }
                 updatedShortcutInfos.add(si);
             }