Adding Prework for Private Space integration in Launcher

This Cl adds the following:
1. Fixes for Quite Mode check maintained by Launcher
2. Addition of new Quite Mode broadcasts
3. Fixes for determining work profile user correctly.

Flag: ACONFIG com.android.launcher3.Flags.enable_private_space DEVELOPMENT
Bug: 289223923
Test: Ran Launcher3 tests
Change-Id: I5f6158b213723339e70ff99e66c5f439f5879e12
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index fd8f668..551735e 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -20,6 +20,8 @@
 
 import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD;
 import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD;
+import static com.android.launcher3.pm.UserCache.ACTION_PROFILE_AVAILABLE;
+import static com.android.launcher3.pm.UserCache.ACTION_PROFILE_UNAVAILABLE;
 import static com.android.launcher3.testing.shared.TestProtocol.sDebugTracing;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
 import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -326,6 +328,16 @@
         } else if (UserCache.ACTION_PROFILE_ADDED.equals(action)
                 || UserCache.ACTION_PROFILE_REMOVED.equals(action)) {
             forceReload();
+        } else if (ACTION_PROFILE_AVAILABLE.equals(action)
+                || ACTION_PROFILE_UNAVAILABLE.equals(action)) {
+            /*
+             * This broadcast is only available when android.os.Flags.allowPrivateProfile() is set.
+             * For Work-profile this broadcast will be sent in addition to
+             * ACTION_MANAGED_PROFILE_AVAILABLE/UNAVAILABLE.
+             * So effectively, this if block only handles the non-work profile case.
+             */
+            enqueueModelUpdateTask(new PackageUpdatedTask(
+                    PackageUpdatedTask.OP_USER_AVAILABILITY_CHANGE, user));
         }
     }
 
diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
index 72c6cb8..d822fec 100644
--- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java
@@ -80,6 +80,7 @@
 import com.android.launcher3.keyboard.FocusedItemDecorator;
 import com.android.launcher3.model.StringCache;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.recyclerview.AllAppsRecyclerViewPool;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.Themes;
@@ -203,7 +204,9 @@
 
         mWorkManager = new WorkProfileManager(
                 mActivityContext.getSystemService(UserManager.class),
-                this, mActivityContext.getStatsLogManager());
+                this,
+                mActivityContext.getStatsLogManager(),
+                UserCache.INSTANCE.get(mActivityContext));
         mAH = Arrays.asList(null, null, null);
         mNavBarScrimPaint = new Paint();
         mNavBarScrimPaint.setColor(Themes.getNavBarScrimColor(mActivityContext));
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index 9f6e0fc..051cf50 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -124,6 +124,9 @@
      * @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
+     * @see com.android.launcher3.model.BgDataModel.Callbacks#FLAG_WORK_PROFILE_QUIET_MODE_ENABLED
+     * @see
+     * com.android.launcher3.model.BgDataModel.Callbacks#FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED
      */
     public boolean hasModelFlag(int mask) {
         return (mModelFlags & mask) != 0;
diff --git a/src/com/android/launcher3/allapps/WorkProfileManager.java b/src/com/android/launcher3/allapps/WorkProfileManager.java
index ac0e5a4..61c3d3f 100644
--- a/src/com/android/launcher3/allapps/WorkProfileManager.java
+++ b/src/com/android/launcher3/allapps/WorkProfileManager.java
@@ -25,10 +25,10 @@
 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.BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED;
 import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import android.os.Build;
-import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.Log;
@@ -40,12 +40,14 @@
 import androidx.annotation.RequiresApi;
 import androidx.recyclerview.widget.RecyclerView;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.LauncherPrefs;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.BaseAllAppsAdapter.AdapterItem;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip;
 
 import java.lang.annotation.Retention;
@@ -84,16 +86,19 @@
 
     private WorkModeSwitch mWorkModeSwitch;
 
+    private final UserCache mUserCache;
+
     @WorkProfileState
     private int mCurrentState;
 
     public WorkProfileManager(
             UserManager userManager, ActivityAllAppsContainerView allApps,
-            StatsLogManager statsLogManager) {
+            StatsLogManager statsLogManager, UserCache userCache) {
         mUserManager = userManager;
         mAllApps = allApps;
-        mMatcher = mAllApps.mPersonalMatcher.negate();
         mStatsLogManager = statsLogManager;
+        mUserCache = userCache;
+        mMatcher = info -> info != null && mUserCache.getUserInfo(info.user).isWork();
     }
 
     /**
@@ -103,11 +108,11 @@
     public void setWorkProfileEnabled(boolean enabled) {
         updateCurrentState(STATE_TRANSITION);
         UI_HELPER_EXECUTOR.post(() -> {
-            for (UserHandle userProfile : mUserManager.getUserProfiles()) {
-                if (Process.myUserHandle().equals(userProfile)) {
-                    continue;
+            for (UserHandle userProfile : mUserCache.getUserProfiles()) {
+                if (mUserCache.getUserInfo(userProfile).isWork()) {
+                    mUserManager.requestQuietModeEnabled(!enabled, userProfile);
+                    break;
                 }
-                mUserManager.requestQuietModeEnabled(!enabled, userProfile);
             }
         });
     }
@@ -131,7 +136,13 @@
      * Requests work profile state from {@link AllAppsStore} and updates work profile related views
      */
     public void reset() {
-        boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(FLAG_QUIET_MODE_ENABLED);
+        int quietModeFlag;
+        if (Flags.enablePrivateSpace()) {
+            quietModeFlag = FLAG_WORK_PROFILE_QUIET_MODE_ENABLED;
+        } else {
+            quietModeFlag = FLAG_QUIET_MODE_ENABLED;
+        }
+        boolean isEnabled = !mAllApps.getAppsStore().hasModelFlag(quietModeFlag);
         updateCurrentState(isEnabled ? STATE_ENABLED : STATE_DISABLED);
         if (mWorkModeSwitch != null) {
             // reset the position of the button and clear IME insets.
diff --git a/src/com/android/launcher3/model/AllAppsList.java b/src/com/android/launcher3/model/AllAppsList.java
index 8f85bfb..190eb78 100644
--- a/src/com/android/launcher3/model/AllAppsList.java
+++ b/src/com/android/launcher3/model/AllAppsList.java
@@ -79,6 +79,8 @@
      * @see Callbacks#FLAG_HAS_SHORTCUT_PERMISSION
      * @see Callbacks#FLAG_QUIET_MODE_ENABLED
      * @see Callbacks#FLAG_QUIET_MODE_CHANGE_PERMISSION
+     * @see Callbacks#FLAG_WORK_PROFILE_QUIET_MODE_ENABLED
+     * @see Callbacks#FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED
      */
     private int mFlags;
 
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 54ecc00..7f0f683 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -477,6 +477,10 @@
         int FLAG_QUIET_MODE_ENABLED = 1 << 1;
         // If launcher can change quiet mode
         int FLAG_QUIET_MODE_CHANGE_PERMISSION = 1 << 2;
+        // If quiet mode is enabled for work profile user
+        int FLAG_WORK_PROFILE_QUIET_MODE_ENABLED = 1 << 3;
+        // If quiet mode is enabled for private profile user
+        int FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED = 1 << 4;
 
         /**
          * Returns an IntSet of page ids to bind first, synchronously if possible
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 1ab0355..f4ce360 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -23,8 +23,10 @@
 import static com.android.launcher3.config.FeatureFlags.ENABLE_SMARTSPACE_REMOVAL;
 import static com.android.launcher3.config.FeatureFlags.SMARTSPACE_AS_A_WIDGET;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_HAS_SHORTCUT_PERMISSION;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
 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.BgDataModel.Callbacks.FLAG_WORK_PROFILE_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;
@@ -57,8 +59,10 @@
 
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 
 import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Flags;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
@@ -143,7 +147,7 @@
     private final InstallSessionHelper mSessionHelper;
     private final IconCache mIconCache;
 
-    private final UserManagerState mUserManagerState = new UserManagerState();
+    private final UserManagerState mUserManagerState;
 
     protected final Map<ComponentKey, AppWidgetProviderInfo> mWidgetProvidersMap = new ArrayMap<>();
     private Map<ShortcutKey, ShortcutInfo> mShortcutKeyToPinnedShortcuts;
@@ -156,6 +160,13 @@
 
     public LoaderTask(@NonNull LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel bgModel,
             ModelDelegate modelDelegate, @NonNull LauncherBinder launcherBinder) {
+        this(app, bgAllAppsList, bgModel, modelDelegate, launcherBinder, new UserManagerState());
+    }
+
+    @VisibleForTesting
+    LoaderTask(@NonNull LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel bgModel,
+            ModelDelegate modelDelegate, @NonNull LauncherBinder launcherBinder,
+            UserManagerState userManagerState) {
         mApp = app;
         mBgAllAppsList = bgAllAppsList;
         mBgDataModel = bgModel;
@@ -164,9 +175,10 @@
 
         mLauncherApps = mApp.getContext().getSystemService(LauncherApps.class);
         mUserManager = mApp.getContext().getSystemService(UserManager.class);
-        mUserCache = UserCache.INSTANCE.get(mApp.getContext());
+        mUserCache = UserCache.getInstance(mApp.getContext());
         mSessionHelper = InstallSessionHelper.INSTANCE.get(mApp.getContext());
         mIconCache = mApp.getIconCache();
+        mUserManagerState = userManagerState;
     }
 
     protected synchronized void waitForIdle() {
@@ -973,6 +985,8 @@
         mBgAllAppsList.clear();
 
         List<IconRequestInfo<AppInfo>> iconRequestInfos = new ArrayList<>();
+        boolean isWorkProfileQuiet = false;
+        boolean isPrivateProfileQuiet = false;
         for (UserHandle user : profiles) {
             // Query for the set of apps
             final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
@@ -982,6 +996,14 @@
                 return allActivityList;
             }
             boolean quietMode = mUserManagerState.isUserQuiet(user);
+
+            if (Flags.enablePrivateSpace()) {
+                if (mUserCache.getUserInfo(user).isWork()) {
+                    isWorkProfileQuiet = quietMode;
+                } else if (mUserCache.getUserInfo(user).isPrivate()) {
+                    isPrivateProfileQuiet = quietMode;
+                }
+            }
             // Create the ApplicationInfos
             for (int i = 0; i < apps.size(); i++) {
                 LauncherActivityInfo app = apps.get(i);
@@ -1023,8 +1045,13 @@
             Trace.endSection();
         }
 
-        mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
-                mUserManagerState.isAnyProfileQuietModeEnabled());
+        if (Flags.enablePrivateSpace()) {
+            mBgAllAppsList.setFlags(FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, isWorkProfileQuiet);
+            mBgAllAppsList.setFlags(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, isPrivateProfileQuiet);
+        } else {
+            mBgAllAppsList.setFlags(FLAG_QUIET_MODE_ENABLED,
+                    mUserManagerState.isAnyProfileQuietModeEnabled());
+        }
         mBgAllAppsList.setFlags(FLAG_HAS_SHORTCUT_PERMISSION,
                 hasShortcutsPermission(mApp.getContext()));
         mBgAllAppsList.setFlags(FLAG_QUIET_MODE_CHANGE_PERMISSION,
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 37a7171..9a0a6eb 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -15,7 +15,9 @@
  */
 package com.android.launcher3.model;
 
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED;
 import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED;
+import static com.android.launcher3.model.BgDataModel.Callbacks.FLAG_WORK_PROFILE_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;
 
@@ -31,6 +33,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.launcher3.Flags;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
@@ -169,14 +172,24 @@
                 break;
             case OP_USER_AVAILABILITY_CHANGE: {
                 UserManagerState ums = new UserManagerState();
-                ums.init(UserCache.INSTANCE.get(context),
-                        context.getSystemService(UserManager.class));
+                UserManager userManager = context.getSystemService(UserManager.class);
+                ums.init(UserCache.INSTANCE.get(context), userManager);
+                boolean isUserQuiet =  ums.isUserQuiet(mUser);
                 flagOp = FlagOp.NO_OP.setFlag(
-                        WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER, ums.isUserQuiet(mUser));
+                        WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER, isUserQuiet);
                 appsList.updateDisabledFlags(matcher, flagOp);
 
-                // We are not synchronizing here, as int operations are atomic
-                appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled());
+                if (Flags.enablePrivateSpace()) {
+                    UserCache userCache = UserCache.INSTANCE.get(context);
+                    if (userCache.getUserInfo(mUser).isWork()) {
+                        appsList.setFlags(FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, isUserQuiet);
+                    } else if (userCache.getUserInfo(mUser).isPrivate()) {
+                        appsList.setFlags(FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, isUserQuiet);
+                    }
+                } else {
+                    // We are not synchronizing here, as int operations are atomic
+                    appsList.setFlags(FLAG_QUIET_MODE_ENABLED, ums.isAnyProfileQuietModeEnabled());
+                }
                 break;
             }
             default:
diff --git a/src/com/android/launcher3/model/UserManagerState.java b/src/com/android/launcher3/model/UserManagerState.java
index 97a5905..720f08e 100644
--- a/src/com/android/launcher3/model/UserManagerState.java
+++ b/src/com/android/launcher3/model/UserManagerState.java
@@ -61,6 +61,9 @@
 
     /**
      * Returns true if any user profile has quiet mode enabled.
+     * <p>
+     * Do not use this for determining if a specific profile has quiet mode enabled, as their can
+     * be more than one profile in quiet mode.
      */
     public boolean isAnyProfileQuietModeEnabled() {
         for (int i = mQuietUsersHashCodeMap.size() - 1; i >= 0; i--) {
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index e2b1286..4661fd4 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -55,10 +55,18 @@
             ? Intent.ACTION_PROFILE_ACCESSIBLE : Intent.ACTION_MANAGED_PROFILE_UNLOCKED;
     public static final String ACTION_PROFILE_LOCKED = ATLEAST_U
             ? Intent.ACTION_PROFILE_INACCESSIBLE : Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE;
+    public static final String ACTION_PROFILE_AVAILABLE = "android.intent.action.PROFILE_AVAILABLE";
+    public static final String ACTION_PROFILE_UNAVAILABLE =
+            "android.intent.action.PROFILE_UNAVAILABLE";
 
     public static final MainThreadInitializedObject<UserCache> INSTANCE =
             new MainThreadInitializedObject<>(UserCache::new);
 
+    /** Returns an instance of UserCache bound to the context provided. */
+    public static UserCache getInstance(Context context) {
+        return INSTANCE.get(context);
+    }
+
     private final List<BiConsumer<UserHandle, String>> mUserEventListeners = new ArrayList<>();
     private final SimpleBroadcastReceiver mUserChangeReceiver =
             new SimpleBroadcastReceiver(this::onUsersChanged);
@@ -87,7 +95,9 @@
                 ACTION_PROFILE_ADDED,
                 ACTION_PROFILE_REMOVED,
                 ACTION_PROFILE_UNLOCKED,
-                ACTION_PROFILE_LOCKED);
+                ACTION_PROFILE_LOCKED,
+                ACTION_PROFILE_AVAILABLE,
+                ACTION_PROFILE_UNAVAILABLE);
         updateCache();
     }
 
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 78116ae..af77d03 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -101,6 +101,7 @@
     // the table can display.
     private static final float RECOMMENDATION_TABLE_HEIGHT_RATIO = 0.75f;
 
+    private final UserCache mUserCache;
     private final UserManagerState mUserManagerState = new UserManagerState();
     private final UserHandle mCurrentUser = Process.myUserHandle();
     private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter =
@@ -192,6 +193,7 @@
                 ? resources.getDimensionPixelSize(R.dimen.all_apps_header_pill_height)
                 : 0;
 
+        mUserCache = UserCache.INSTANCE.get(context);
         mUserManagerState.init(UserCache.INSTANCE.get(context),
                 context.getSystemService(UserManager.class));
     }
@@ -311,7 +313,9 @@
         if (adapterHolder.mAdapterType == AdapterHolder.SEARCH) {
             mNoWidgetsView.setText(R.string.no_search_results);
         } else if (adapterHolder.mAdapterType == AdapterHolder.WORK
-                && mUserManagerState.isAnyProfileQuietModeEnabled()
+                && mUserCache.getUserProfiles().stream()
+                .filter(userHandle -> mUserCache.getUserInfo(userHandle).isWork())
+                .anyMatch(mUserManagerState::isUserQuiet)
                 && mActivityContext.getStringCache() != null) {
             mNoWidgetsView.setText(mActivityContext.getStringCache().workProfilePausedTitle);
         } else {
diff --git a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
index 036f2d8..def27b8 100644
--- a/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
+++ b/tests/src/com/android/launcher3/model/LoaderTaskTest.kt
@@ -1,10 +1,12 @@
 package com.android.launcher3.model
 
-import android.appwidget.AppWidgetManager
+import android.content.Context
 import android.os.UserHandle
+import android.platform.test.flag.junit.SetFlagsRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import androidx.test.platform.app.InstrumentationRegistry
+import com.android.launcher3.Flags
 import com.android.launcher3.InvariantDeviceProfile
 import com.android.launcher3.LauncherAppState
 import com.android.launcher3.LauncherModel
@@ -12,19 +14,25 @@
 import com.android.launcher3.icons.IconCache
 import com.android.launcher3.icons.cache.CachingLogic
 import com.android.launcher3.icons.cache.IconCacheUpdateHandler
+import com.android.launcher3.pm.UserCache
 import com.android.launcher3.util.Executors.MODEL_EXECUTOR
 import com.android.launcher3.util.LooperIdleLock
+import com.android.launcher3.util.UserIconInfo
+import com.android.launcher3.util.rule.StaticMockitoRule
 import com.google.common.truth.Truth
 import java.util.concurrent.CountDownLatch
 import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
 import org.mockito.Mock
+import org.mockito.Mockito
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.Spy
 
 private const val INSERTION_STATEMENT_FILE = "databases/workspace_items.sql"
 
@@ -40,7 +48,13 @@
     @Mock private lateinit var iconCache: IconCache
     @Mock private lateinit var idleLock: LooperIdleLock
     @Mock private lateinit var iconCacheUpdateHandler: IconCacheUpdateHandler
-    @Mock private lateinit var appWidgetManager: AppWidgetManager
+    @Mock private lateinit var userCache: UserCache
+
+    @Spy private var userManagerState: UserManagerState? = UserManagerState()
+
+    @get:Rule(order = 0) val staticMockitoRule = StaticMockitoRule(UserCache::class.java)
+    @get:Rule(order = 1)
+    val setFlagsRule = SetFlagsRule().apply { initAllFlagsToReleaseConfigDefault() }
 
     @Before
     fun setup() {
@@ -63,8 +77,7 @@
         `when`(launcherBinder.newIdleLock(any(LoaderTask::class.java))).thenReturn(idleLock)
         `when`(idleLock.awaitLocked(1000)).thenReturn(false)
         `when`(iconCache.updateHandler).thenReturn(iconCacheUpdateHandler)
-        `when`(appWidgetManager.getInstalledProvidersForProfile(any(UserHandle::class.java)))
-            .thenReturn(emptyList())
+        `when`(UserCache.getInstance(any(Context::class.java))).thenReturn(userCache)
     }
 
     @Test
@@ -95,6 +108,48 @@
         verify(modelDelegate).modelLoadComplete()
         verify(transaction).commit()
     }
+
+    @Test
+    fun setsQuietModeFlagCorrectlyForWorkProfile() =
+        with(BgDataModel()) {
+            setFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE)
+            val MAIN_HANDLE = UserHandle.of(0)
+            val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
+            `when`(userCache.userProfiles).thenReturn(mockUserHandles)
+            `when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
+            `when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 1))
+
+            LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder, userManagerState)
+                .runSyncOnBackgroundThread()
+
+            verify(bgAllAppsList)
+                .setFlags(BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, true)
+            verify(bgAllAppsList)
+                .setFlags(BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, false)
+            verify(bgAllAppsList, Mockito.never())
+                .setFlags(BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED, true)
+        }
+
+    @Test
+    fun setsQuietModeFlagCorrectlyForPrivateProfile() =
+        with(BgDataModel()) {
+            setFlagsRule.enableFlags(Flags.FLAG_ENABLE_PRIVATE_SPACE)
+            val MAIN_HANDLE = UserHandle.of(0)
+            val mockUserHandles = arrayListOf<UserHandle>(MAIN_HANDLE)
+            `when`(userCache.userProfiles).thenReturn(mockUserHandles)
+            `when`(userManagerState?.isUserQuiet(MAIN_HANDLE)).thenReturn(true)
+            `when`(userCache.getUserInfo(MAIN_HANDLE)).thenReturn(UserIconInfo(MAIN_HANDLE, 3))
+
+            LoaderTask(app, bgAllAppsList, this, modelDelegate, launcherBinder, userManagerState)
+                .runSyncOnBackgroundThread()
+
+            verify(bgAllAppsList)
+                .setFlags(BgDataModel.Callbacks.FLAG_WORK_PROFILE_QUIET_MODE_ENABLED, false)
+            verify(bgAllAppsList)
+                .setFlags(BgDataModel.Callbacks.FLAG_PRIVATE_PROFILE_QUIET_MODE_ENABLED, true)
+            verify(bgAllAppsList, Mockito.never())
+                .setFlags(BgDataModel.Callbacks.FLAG_QUIET_MODE_ENABLED, true)
+        }
 }
 
 private fun LoaderTask.runSyncOnBackgroundThread() {
diff --git a/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java b/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
index ba416ae..3411fc1 100644
--- a/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
+++ b/tests/src/com/android/launcher3/ui/ActivityAllAppsContainerViewTest.java
@@ -18,14 +18,19 @@
 import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
 
 import static com.android.launcher3.model.data.AppInfo.EMPTY_ARRAY;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.when;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -34,15 +39,20 @@
 import com.android.launcher3.allapps.WorkProfileManager;
 import com.android.launcher3.logging.StatsLogManager;
 import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.pm.UserCache;
 import com.android.launcher3.util.ActivityContextWrapper;
+import com.android.launcher3.util.UserIconInfo;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 
+import java.util.Arrays;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class ActivityAllAppsContainerViewTest {
@@ -50,19 +60,38 @@
     private static final UserHandle WORK_HANDLE = new UserHandle(13);
     @Mock
     private StatsLogManager mStatsLogManager;
+    @Mock
+    private UserCache mUserCache;
+    @Mock
+    private UserManager mUserManager;
     private AppInfo[] mWorkAppInfo;
     private ActivityAllAppsContainerView<?> mActivityAllAppsContainerView;
     private WorkProfileManager mWorkManager;
+    private Context mContext;
+
+    @Rule public final SetFlagsRule mSetFlagsRule = getFlagsRule();
+
+    private SetFlagsRule getFlagsRule() {
+        SetFlagsRule flagsRule = new SetFlagsRule();
+        flagsRule.initAllFlagsToReleaseConfigDefault();
+        return flagsRule;
+    }
 
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        Context context = new ActivityContextWrapper(getApplicationContext());
-        mActivityAllAppsContainerView = new ActivityAllAppsContainerView(context);
-        mWorkManager = new WorkProfileManager(context.getSystemService(UserManager.class),
-                mActivityAllAppsContainerView, mStatsLogManager);
+        mContext = new ActivityContextWrapper(getApplicationContext());
+        mActivityAllAppsContainerView = new ActivityAllAppsContainerView(mContext);
+        when(mUserCache.getUserProfiles())
+                .thenReturn(Arrays.asList(Process.myUserHandle(), WORK_HANDLE));
+        when(mUserCache.getUserInfo(Process.myUserHandle()))
+                .thenReturn(new UserIconInfo(Process.myUserHandle(), 0));
+        when(mUserCache.getUserInfo(WORK_HANDLE))
+                .thenReturn(new UserIconInfo(WORK_HANDLE, 1));
+        mWorkManager = new WorkProfileManager(mUserManager, mActivityAllAppsContainerView,
+                mStatsLogManager, mUserCache);
         mActivityAllAppsContainerView.setWorkManager(mWorkManager);
-        ComponentName componentName = new ComponentName(context,
+        ComponentName componentName = new ComponentName(mContext,
                 "com.android.launcher3.tests.Activity" + "Gmail");
         AppInfo gmailWorkAppInfo = new AppInfo(componentName, "Gmail", WORK_HANDLE, new Intent());
         mWorkAppInfo = new AppInfo[]{gmailWorkAppInfo};
@@ -85,4 +114,22 @@
 
         assertThat(mActivityAllAppsContainerView.shouldShowTabs()).isEqualTo(true);
     }
+
+    @Test
+    public void testWorkProfileEnabled_requestQuietModeCalledCorrectly() throws Exception {
+        /* Setup */
+        when(mUserManager.requestQuietModeEnabled(false, WORK_HANDLE))
+                .thenReturn(true);
+
+        /* Execution */
+        mWorkManager.setWorkProfileEnabled(true);
+
+        /* Assertion */
+        awaitTasksCompleted();
+        Mockito.verify(mUserManager).requestQuietModeEnabled(false, WORK_HANDLE);
+    }
+
+    private static void awaitTasksCompleted() throws Exception {
+        UI_HELPER_EXECUTOR.submit(() -> null).get();
+    }
 }