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();
+ }
}