Removing multiple system RPCs to packageMAnager and userManager from UI thread

Bug: 158427348
Change-Id: Ibb1837fe932000b69cf5683bb01727fc32abca91
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 1f84c42..ec32e62 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -2455,8 +2455,9 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void bindAllApplications(AppInfo[] apps) {
-        mAppsView.getAppsStore().setApps(apps);
+    @Override
+    public void bindAllApplications(AppInfo[] apps, int flags) {
+        mAppsView.getAppsStore().setApps(apps, flags);
     }
 
     /**
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 3b1c7bb..f434c91 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -117,7 +117,7 @@
         @Override
         public void run() {
             if (mModelLoaded && hasShortcutsPermission(mApp.getContext())
-                    != mBgDataModel.hasShortcutHostPermission) {
+                    != mBgAllAppsList.hasShortcutHostPermission()) {
                 forceReload();
             }
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 1d6bb62..2ffe9d5 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -16,6 +16,9 @@
 package com.android.launcher3.allapps;
 
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
@@ -37,7 +40,6 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.StringRes;
-import androidx.dynamicanimation.animation.DynamicAnimation;
 import androidx.recyclerview.widget.DefaultItemAnimator;
 import androidx.recyclerview.widget.LinearLayoutManager;
 import androidx.recyclerview.widget.RecyclerView;
@@ -54,7 +56,6 @@
 import com.android.launcher3.keyboard.FocusedItemDecorator;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.ItemInfo;
-import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ItemInfoMatcher;
@@ -195,7 +196,7 @@
     }
 
     private void resetWorkProfile() {
-        mWorkModeSwitch.refresh();
+        mWorkModeSwitch.update(!mAllAppsStore.hasModelFlag(FLAG_QUIET_MODE_ENABLED));
         mAH[AdapterHolder.WORK].setupOverlay();
         mAH[AdapterHolder.WORK].applyPadding();
     }
@@ -431,11 +432,13 @@
     }
 
     private void setupWorkToggle() {
-        mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
-                R.layout.work_mode_switch, this, false);
-        this.addView(mWorkModeSwitch);
-        mWorkModeSwitch.setInsets(mInsets);
-        mWorkModeSwitch.post(() -> mAH[AdapterHolder.WORK].applyPadding());
+        if (Utilities.ATLEAST_P) {
+            mWorkModeSwitch = (WorkModeSwitch) mLauncher.getLayoutInflater().inflate(
+                    R.layout.work_mode_switch, this, false);
+            this.addView(mWorkModeSwitch);
+            mWorkModeSwitch.setInsets(mInsets);
+            mWorkModeSwitch.post(() -> mAH[AdapterHolder.WORK].applyPadding());
+        }
     }
 
     private void replaceRVContainer(boolean showTabs) {
@@ -470,7 +473,9 @@
         }
         reset(true /* animate */);
         if (mWorkModeSwitch != null) {
-            mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK);
+            mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK
+                    && mAllAppsStore.hasModelFlag(
+                            FLAG_HAS_SHORTCUT_PERMISSION | FLAG_QUIET_MODE_CHANGE_PERMISSION));
         }
     }
 
@@ -580,15 +585,8 @@
                         && valueAnimator.getAnimatedFraction() >= FLING_ANIMATION_THRESHOLD) {
                     int searchViewId = getSearchView().getId();
                     addSpringView(searchViewId);
-
                     finishWithShiftAndVelocity(1, velocity * FLING_VELOCITY_MULTIPLIER,
-                            new DynamicAnimation.OnAnimationEndListener() {
-                                @Override
-                                public void onAnimationEnd(DynamicAnimation animation,
-                                        boolean canceled, float value, float velocity) {
-                                    removeSpringView(searchViewId);
-                                }
-                            });
+                            (anim, canceled, value, velocity) -> removeSpringView(searchViewId));
 
                     shouldSpring = false;
                 }
@@ -647,7 +645,7 @@
 
         void setupOverlay() {
             if (!mIsWork || recyclerView == null) return;
-            boolean workDisabled = UserCache.INSTANCE.get(mLauncher).isAnyProfileQuietModeEnabled();
+            boolean workDisabled = mAllAppsStore.hasModelFlag(FLAG_QUIET_MODE_ENABLED);
             if (mWorkDisabled == workDisabled) return;
             recyclerView.setContentDescription(workDisabled ? mLauncher.getString(
                     R.string.work_apps_paused_content_description) : null);
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index b11312c..3ae0a18 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -52,6 +52,7 @@
 
     private final List<OnUpdateListener> mUpdateListeners = new CopyOnWriteArrayList<>();
     private final ArrayList<ViewGroup> mIconContainers = new ArrayList<>();
+    private int mModelFlags;
 
     private int mDeferUpdatesFlags = 0;
     private boolean mUpdatePending = false;
@@ -63,11 +64,21 @@
     /**
      * Sets the current set of apps.
      */
-    public void setApps(AppInfo[] apps) {
+    public void setApps(AppInfo[] apps, int flags) {
         mApps = apps;
+        mModelFlags = flags;
         notifyUpdate();
     }
 
+    /**
+     * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_QUIET_MODE_ENABLED
+     * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+     * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
+     */
+    public boolean hasModelFlag(int mask) {
+        return (mModelFlags & mask) != 0;
+    }
+
     public AppInfo getApp(ComponentKey key) {
         mTempInfo.componentName = key.componentName;
         mTempInfo.user = key.user;
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 6692af5..4567ee6 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -15,11 +15,8 @@
  */
 package com.android.launcher3.allapps;
 
-import static com.android.launcher3.util.PackageManagerHelper.hasShortcutsPermission;
-
 import android.content.Context;
 import android.content.SharedPreferences;
-import android.content.pm.PackageManager;
 import android.graphics.Rect;
 import android.os.AsyncTask;
 import android.os.Process;
@@ -59,7 +56,6 @@
     public WorkModeSwitch(Context context, AttributeSet attrs) {
         super(context, attrs);
         init();
-
     }
 
     public WorkModeSwitch(Context context, AttributeSet attrs, int defStyleAttr) {
@@ -73,9 +69,7 @@
     }
 
     @Override
-    public void setChecked(boolean checked) {
-
-    }
+    public void setChecked(boolean checked) { }
 
     @Override
     public void toggle() {
@@ -84,20 +78,17 @@
         trySetQuietModeEnabledToAllProfilesAsync(isChecked());
     }
 
-    private void setCheckedInternal(boolean checked) {
-        super.setChecked(checked);
+    /**
+     * Sets the enabled or disabled state of the button
+     * @param isChecked
+     */
+    public void update(boolean isChecked) {
+        super.setChecked(isChecked);
         setCompoundDrawablesRelativeWithIntrinsicBounds(
-                checked ? R.drawable.ic_corp : R.drawable.ic_corp_off, 0, 0, 0);
-    }
-
-    public void refresh() {
-        if (!shouldShowWorkSwitch()) return;
-        UserCache userManager = UserCache.INSTANCE.get(getContext());
-        setCheckedInternal(!userManager.isAnyProfileQuietModeEnabled());
+                isChecked ? R.drawable.ic_corp : R.drawable.ic_corp_off, 0, 0, 0);
         setEnabled(true);
     }
 
-
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
@@ -116,12 +107,6 @@
         return super.onTouchEvent(ev);
     }
 
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        super.onLayout(changed, l, t, r, b);
-        this.setVisibility(shouldShowWorkSwitch() ? VISIBLE : GONE);
-    }
-
     private void trySetQuietModeEnabledToAllProfilesAsync(boolean enabled) {
         new SetQuietModeEnabledAsyncTask(enabled, new WeakReference<>(this)).execute();
     }
@@ -138,13 +123,12 @@
      * Animates in/out work profile toggle panel based on the tab user is on
      */
     public void setWorkTabVisible(boolean workTabVisible) {
-        if (!shouldShowWorkSwitch()) return;
         clearAnimation();
         if (workTabVisible) {
             setVisibility(VISIBLE);
             setAlpha(0);
             animate().alpha(1).start();
-            showTipifNeeded();
+            showTipIfNeeded();
         } else {
             animate().alpha(0).withEndAction(() -> this.setVisibility(GONE)).start();
         }
@@ -201,16 +185,10 @@
         }
     }
 
-    private boolean shouldShowWorkSwitch() {
-        return Utilities.ATLEAST_P && (hasShortcutsPermission(getContext())
-                || getContext().checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
-                == PackageManager.PERMISSION_GRANTED);
-    }
-
     /**
      * Shows a work tip on the Nth work tab open
      */
-    public void showTipifNeeded() {
+    public void showTipIfNeeded() {
         Context context = getContext();
         SharedPreferences prefs = Utilities.getPrefs(context);
         int tipCounter = prefs.getInt(KEY_WORK_TIP_COUNTER, WORK_TIP_THRESHOLD);
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 4f349ca..eb5d106 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -35,6 +35,7 @@
 import com.android.launcher3.AppFilter;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
 import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.model.BgDataModel.Callbacks;
 import com.android.launcher3.model.data.AppInfo;
 import com.android.launcher3.model.data.PromiseAppInfo;
 import com.android.launcher3.pm.PackageInstallInfo;
@@ -73,6 +74,13 @@
     private AlphabeticIndexCompat mIndex;
 
     /**
+     * @see Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+     * @see Callbacks#FLAG_QUIET_MODE_ENABLED
+     * @see Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
+     */
+    private int mFlags;
+
+    /**
      * Boring constructor.
      */
     public AllAppsList(IconCache iconCache, AppFilter appFilter) {
@@ -91,6 +99,33 @@
     }
 
     /**
+     * Helper to checking {@link Callbacks#FLAG_HAS_SHORTCUT_PERMISSION}
+     */
+    public boolean hasShortcutHostPermission() {
+        return (mFlags & Callbacks.FLAG_HAS_SHORTCUT_PERMISSION) != 0;
+    }
+
+    /**
+     * Sets or clears the provided flag
+     */
+    public void setFlags(int flagMask, boolean enabled) {
+        if (enabled) {
+            mFlags |= flagMask;
+        } else {
+            mFlags &= ~flagMask;
+        }
+        mDataChanged = true;
+    }
+
+    /**
+     * Returns the model flags
+     */
+    public int getFlags() {
+        return mFlags;
+    }
+
+
+    /**
      * Add the supplied ApplicationInfo objects to the list, and enqueue it into the
      * list to broadcast when notify() is called.
      *
diff --git a/src/com/android/launcher3/model/BaseLoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
index ab921ea..8b0ef7b 100644
--- a/src/com/android/launcher3/model/BaseLoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -96,7 +96,8 @@
     public void bindAllApps() {
         // shallow copy
         AppInfo[] apps = mBgAllAppsList.copyData();
-        executeCallbacksTask(c -> c.bindAllApplications(apps), mUiExecutor);
+        int flags = mBgAllAppsList.getFlags();
+        executeCallbacksTask(c -> c.bindAllApplications(apps, flags), mUiExecutor);
     }
 
     public abstract void bindWidgets();
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 7ce970d..9013cba 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -117,7 +117,8 @@
     public void bindApplicationsIfNeeded() {
         if (mAllAppsList.getAndResetChangeFlag()) {
             AppInfo[] apps = mAllAppsList.copyData();
-            scheduleCallbackTask(c -> c.bindAllApplications(apps));
+            int flags = mAllAppsList.getFlags();
+            scheduleCallbackTask(c -> c.bindAllApplications(apps, flags));
         }
     }
 }
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 2522a49..9bef847 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -98,9 +98,11 @@
     public final ArrayList<AppInfo> cachedPredictedItems = new ArrayList<>();
 
     /**
-     * True if the launcher has permission to access deep shortcuts.
+     * @see Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
+     * @see Callbacks#FLAG_QUIET_MODE_ENABLED
+     * @see Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
      */
-    public boolean hasShortcutHostPermission;
+    public int flags;
 
     /**
      * Maps all launcher activities to counts of their shortcuts.
@@ -347,6 +349,13 @@
     }
 
     public interface Callbacks {
+        // If the launcher has permission to access deep shortcuts.
+        int FLAG_HAS_SHORTCUT_PERMISSION = 1 << 0;
+        // If quiet mode is enabled for any user
+        int FLAG_QUIET_MODE_ENABLED = 1 << 1;
+        // If launcher can change quiet mode
+        int FLAG_QUIET_MODE_CHANGE_PERMISSION = 1 << 2;
+
         /**
          * Returns the page number to bind first, synchronously if possible or -1
          */
@@ -370,7 +379,7 @@
         void executeOnNextDraw(ViewOnDrawExecutor executor);
         void bindDeepShortcutMap(HashMap<ComponentKey, Integer> deepShortcutMap);
 
-        void bindAllApplications(AppInfo[] apps);
+        void bindAllApplications(AppInfo[] apps, int flags);
 
         /**
          * Binds predicted appInfos at at available prediction slots.
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 244de96..165d1ea 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -65,7 +65,7 @@
 
     private static final String TAG = "LoaderCursor";
 
-    public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
+    public final LongSparseArray<UserHandle> allUsers;
 
     private final Uri mContentUri;
     private final Context mContext;
@@ -100,9 +100,11 @@
     public int itemType;
     public int restoreFlag;
 
-    public LoaderCursor(Cursor cursor, Uri contentUri, LauncherAppState app) {
+    public LoaderCursor(Cursor cursor, Uri contentUri, LauncherAppState app,
+            UserManagerState userManagerState) {
         super(cursor);
 
+        allUsers = userManagerState.allUsers;
         mContentUri = contentUri;
         mContext = app.getContext();
         mIconCache = app.getIconCache();
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index d05d70b..f2073ef 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -17,6 +17,9 @@
 package com.android.launcher3.model;
 
 import static com.android.launcher3.config.FeatureFlags.MULTI_DB_GRID_MIRATION_ALGO;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_CHANGE_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
 import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems;
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
 import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
@@ -35,6 +38,7 @@
 import android.content.pm.LauncherApps;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ShortcutInfo;
 import android.net.Uri;
 import android.os.UserHandle;
@@ -120,6 +124,8 @@
     private final InstallSessionHelper mSessionHelper;
     private final IconCache mIconCache;
 
+    private final UserManagerState mUserManagerState = new UserManagerState();
+
     private boolean mStopped;
 
     public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
@@ -333,7 +339,8 @@
 
             Map<ShortcutKey, ShortcutInfo> shortcutKeyToPinnedShortcuts = new HashMap<>();
             final LoaderCursor c = new LoaderCursor(
-                    contentResolver.query(contentUri, null, null, null, null), contentUri, mApp);
+                    contentResolver.query(contentUri, null, null, null, null), contentUri, mApp,
+                    mUserManagerState);
 
             Map<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
 
@@ -352,12 +359,13 @@
                         LauncherSettings.Favorites.OPTIONS);
 
                 final LongSparseArray<UserHandle> allUsers = c.allUsers;
-                final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
                 final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
+
+                mUserManagerState.init(mUserCache, mUserManager);
+
                 for (UserHandle user : mUserCache.getUserProfiles()) {
                     long serialNo = mUserCache.getSerialNumberForUser(user);
                     allUsers.put(serialNo, user);
-                    quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
 
                     boolean userUnlocked = mUserManager.isUserUnlocked(user);
 
@@ -404,8 +412,8 @@
                                 continue;
                             }
 
-                            int disabledState = quietMode.get(c.serialNumber) ?
-                                    WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
+                            int disabledState = mUserManagerState.isUserQuiet(c.serialNumber)
+                                    ? WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER : 0;
                             ComponentName cn = intent.getComponent();
                             targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
 
@@ -862,8 +870,8 @@
             for (ComponentKey key : componentKeys) {
                 l = mLauncherApps.getActivityList(key.componentName.getPackageName(), key.user);
                 if (l.size() == 0) continue;
-                boolean quietMode = mUserManager.isQuietModeEnabled(key.user);
-                AppInfo info = new AppInfo(l.get(0), key.user, quietMode);
+                AppInfo info = new AppInfo(l.get(0), key.user,
+                        mUserManagerState.isUserQuiet(key.user));
                 mBgDataModel.cachedPredictedItems.add(info);
                 mIconCache.getTitleAndIcon(info, false);
             }
@@ -883,7 +891,7 @@
             if (apps == null || apps.isEmpty()) {
                 return allActivityList;
             }
-            boolean quietMode = mUserManager.isQuietModeEnabled(user);
+            boolean quietMode = mUserManagerState.isUserQuiet(user);
             // Create the ApplicationInfos
             for (int i = 0; i < apps.size(); i++) {
                 LauncherActivityInfo app = apps.get(i);
@@ -905,11 +913,19 @@
             List<LauncherActivityInfo> l = mLauncherApps.getActivityList(
                     item.componentName.getPackageName(), item.user);
             for (LauncherActivityInfo info : l) {
-                boolean quietMode = mUserManager.isQuietModeEnabled(item.user);
+                boolean quietMode = mUserManagerState.isUserQuiet(item.user);
                 mBgAllAppsList.add(new AppInfo(info, item.user, quietMode), info);
             }
         }
 
+        mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
+                mUserManagerState.isAnyProfileQuietModeEnabled());
+        mBgAllAppsList.setFlags(FLAG_HAS_SHORTCUT_PERMISSION,
+                hasShortcutsPermission(mApp.getContext()));
+        mBgAllAppsList.setFlags(FLAG_QUIET_MODE_CHANGE_PERMISSION,
+                mApp.getContext().checkSelfPermission("android.permission.MODIFY_QUIET_MODE")
+                        == PackageManager.PERMISSION_GRANTED);
+
         mBgAllAppsList.getAndResetChangeFlag();
         return allActivityList;
     }
@@ -917,8 +933,8 @@
     private List<ShortcutInfo> loadDeepShortcuts() {
         List<ShortcutInfo> allShortcuts = new ArrayList<>();
         mBgDataModel.deepShortcutMap.clear();
-        mBgDataModel.hasShortcutHostPermission = hasShortcutsPermission(mApp.getContext());
-        if (mBgDataModel.hasShortcutHostPermission) {
+
+        if (mBgAllAppsList.hasShortcutHostPermission()) {
             for (UserHandle user : mUserCache.getUserProfiles()) {
                 if (mUserManager.isUserUnlocked(user)) {
                     List<ShortcutInfo> shortcuts = new ShortcutRequest(mApp.getContext(), user)
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 2fa6051..7cd467e 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.model;
 
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
 import static com.android.launcher3.model.data.WorkspaceItemInfo.FLAG_AUTOINSTALL_ICON;
 import static com.android.launcher3.model.data.WorkspaceItemInfo.FLAG_RESTORED_ICON;
 
@@ -41,6 +42,7 @@
 import com.android.launcher3.model.data.ItemInfo;
 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
 import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.shortcuts.ShortcutRequest;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.IntSparseArrayMap;
@@ -149,14 +151,21 @@
                 if (DEBUG) Log.d(TAG, "mAllAppsList.(un)suspend " + N);
                 appsList.updateDisabledFlags(matcher, flagOp);
                 break;
-            case OP_USER_AVAILABILITY_CHANGE:
-                flagOp = context.getSystemService(UserManager.class).isQuietModeEnabled(mUser)
+            case OP_USER_AVAILABILITY_CHANGE: {
+                UserManagerState ums = new UserManagerState();
+                ums.init(UserCache.INSTANCE.get(context),
+                        context.getSystemService(UserManager.class));
+                flagOp = ums.isUserQuiet(mUser)
                         ? FlagOp.addFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER)
                         : FlagOp.removeFlag(WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER);
                 // We want to update all packages for this user.
                 matcher = ItemInfoMatcher.ofUser(mUser);
                 appsList.updateDisabledFlags(matcher, flagOp);
+
+                // We are not synchronizing here, as int operations are atomic
+                appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled());
                 break;
+            }
         }
 
         bindApplicationsIfNeeded();
diff --git a/src/com/android/launcher3/model/UserManagerState.java b/src/com/android/launcher3/model/UserManagerState.java
new file mode 100644
index 0000000..3a4206c
--- /dev/null
+++ b/src/com/android/launcher3/model/UserManagerState.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.model;
+
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.LongSparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.launcher3.pm.UserCache;
+
+/**
+ * Utility class to manager store and user manager state at any particular time
+ */
+public class UserManagerState {
+
+    public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
+
+    private final LongSparseArray<Boolean> mQuietUsersSerialNoMap = new LongSparseArray<>();
+    private final SparseBooleanArray mQuietUsersHashCodeMap = new SparseBooleanArray();
+
+    /**
+     * Initialises the state values for all users
+     */
+    public void init(UserCache userCache, UserManager userManager) {
+        for (UserHandle user : userCache.getUserProfiles()) {
+            long serialNo = userCache.getSerialNumberForUser(user);
+            boolean isUserQuiet = userManager.isQuietModeEnabled(user);
+            allUsers.put(serialNo, user);
+            mQuietUsersHashCodeMap.put(user.hashCode(), isUserQuiet);
+            mQuietUsersSerialNoMap.put(serialNo, isUserQuiet);
+        }
+    }
+
+    /**
+     * Returns true if quiet mode is enabled for the provided user
+     */
+    public boolean isUserQuiet(long serialNo) {
+        return mQuietUsersSerialNoMap.get(serialNo);
+    }
+
+    /**
+     * Returns true if quiet mode is enabled for the provided user
+     */
+    public boolean isUserQuiet(UserHandle user) {
+        return mQuietUsersHashCodeMap.get(user.hashCode());
+    }
+
+    /**
+     * Returns true if any user profile has quiet mode enabled.
+     */
+    public boolean isAnyProfileQuietModeEnabled() {
+        for (int i = mQuietUsersHashCodeMap.size() - 1; i >= 0; i--) {
+            if (mQuietUsersHashCodeMap.valueAt(i)) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index f723256..5aab41a 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.content.Intent;
-import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArrayMap;
@@ -107,22 +106,6 @@
     }
 
     /**
-     * Returns true if any user profile has quiet mode enabled.
-     */
-    public boolean isAnyProfileQuietModeEnabled() {
-        List<UserHandle> userProfiles = getUserProfiles();
-        for (UserHandle userProfile : userProfiles) {
-            if (Process.myUserHandle().equals(userProfile)) {
-                continue;
-            }
-            if (mUserManager.isQuietModeEnabled(userProfile)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * @see UserManager#getSerialNumberForUser(UserHandle)
      */
     public long getSerialNumberForUser(UserHandle user) {
@@ -160,16 +143,4 @@
         List<UserHandle> users = mUserManager.getUserProfiles();
         return users == null ? Collections.emptyList() : users;
     }
-
-    /**
-     * Returns true is there is at least one user profile enabled
-     */
-    public boolean hasWorkProfile() {
-        synchronized (this) {
-            if (mUsers != null) {
-                return mUsers.size() > 1;
-            }
-        }
-        return getUserProfiles().size() > 1;
-    }
 }
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 4a15af1..21ad275 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -296,8 +296,8 @@
     }
 
     @Override
-    public void bindAllApplications(AppInfo[] apps) {
-        mAppsView.getAppsStore().setApps(apps);
+    public void bindAllApplications(AppInfo[] apps, int flags) {
+        mAppsView.getAppsStore().setApps(apps, flags);
     }
 
     public PopupDataProvider getPopupDataProvider() {
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index ddde6d3..86f3431 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.util;
 
-import static android.content.pm.PackageInstaller.SessionInfo;
 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
 
 import android.app.AppOpsManager;
@@ -45,8 +44,6 @@
 import android.util.Pair;
 import android.widget.Toast;
 
-import androidx.annotation.NonNull;
-
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -348,15 +345,4 @@
         }
         return false;
     }
-
-    /**
-     * Returns the created time in millis of given session info. Returns 0 if not available.
-     */
-    public static long getSessionCreatedTimeInMillis(@NonNull final SessionInfo info) {
-        try {
-            return (long) SessionInfo.class.getDeclaredMethod("getCreatedMillis").invoke(info);
-        } catch (Exception e) {
-            return 0;
-        }
-    }
 }