Merge changes from topic "comet-landscape" into main
* changes:
Update Responsive Grid tests with aspect ratio group
Refactoring Responsive Grid XML specs for more flexibility
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 22ab79d..165ed80 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -20,6 +20,8 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_OPTIMIZE_MEASURE;
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
import static com.android.app.animation.Interpolators.EMPHASIZED;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.PENDING_SPLIT_SELECT_INFO;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE;
import static com.android.launcher3.LauncherSettings.Animation.DEFAULT_NO_ICON;
import static com.android.launcher3.LauncherSettings.Animation.VIEW_BACKGROUND;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index b5709f7..92aa9fa 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -17,7 +17,6 @@
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
-import static com.android.launcher3.testing.shared.TestProtocol.SPLIT_LEAK;
import static com.android.launcher3.testing.shared.TestProtocol.testLogD;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -273,7 +272,6 @@
*/
@MainThread
public void clearProxy() {
- testLogD(SPLIT_LEAK, "systemUiProxy clearingProxy");
setProxy(null, null, null, null, null, null, null, null, null, null, null, null, null);
}
@@ -1224,7 +1222,7 @@
}
try {
mBackAnimation.setBackToLauncherCallback(callback, runner);
- } catch (RemoteException e) {
+ } catch (RemoteException | SecurityException e) {
Log.e(TAG, "Failed call setBackToLauncherCallback", e);
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java
index 3d8191d..ddddc89 100644
--- a/quickstep/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java
@@ -197,7 +197,11 @@
remoteTargetHandles = gluer.assignTargets(targets);
}
}
+ final int recentsActivityRotation =
+ recentsView.getPagedViewOrientedState().getRecentsActivityRotation();
for (RemoteTargetHandle remoteTargetGluer : remoteTargetHandles) {
+ remoteTargetGluer.getTaskViewSimulator().getOrientationState().setRecentsRotation(
+ recentsActivityRotation);
remoteTargetGluer.getTransformParams().setSyncTransactionApplier(applier);
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 1b3d759..f264364 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -208,7 +208,12 @@
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- if (ENABLE_SHELL_TRANSITIONS) {
+ if (dismissTask) {
+ // Just start the home intent so the user is prompted to unlock the device.
+ // This will come back and cancel the interaction.
+ startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null, TAG);
+ mHomeLaunched = true;
+ } else if (ENABLE_SHELL_TRANSITIONS) {
if (mTaskAnimationManager.getCurrentCallbacks() != null) {
if (mRecentsAnimationController != null) {
finishRecentsAnimationForShell(dismissTask);
@@ -218,11 +223,6 @@
mDismissTask = dismissTask;
}
}
- } else if (dismissTask) {
- // For now, just start the home intent so user is prompted to
- // unlock the device.
- startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null, TAG);
- mHomeLaunched = true;
}
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index 07c85bb..d38376c 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -120,7 +120,7 @@
if (longPressRunnable != null) {
OtherActivityInputConsumer oaic = getInputConsumerOfClass(
OtherActivityInputConsumer.class);
- if (oaic != null) {
+ if (oaic != null && oaic.hasStartedTouchTracking()) {
oaic.setForceFinishRecentsTransitionCallback(longPressRunnable);
setActive(mCurrentDownEvent);
} else {
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index e724547..eedd204 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -413,6 +413,14 @@
}
/**
+ * Returns whether this input consumer has started touch tracking (if touch tracking is not
+ * deferred).
+ */
+ public boolean hasStartedTouchTracking() {
+ return mInteractionHandler != null;
+ }
+
+ /**
* Called when the gesture has ended. Does not correlate to the completion of the interaction as
* the animation can still be running.
*/
diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
index 16235e0..12568ea 100644
--- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
+++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java
@@ -162,6 +162,7 @@
@Before
public void setUp() {
mLauncher.onTestStart();
+ AbstractLauncherUiTest.waitForSetupWizardDismissal();
AbstractLauncherUiTest.verifyKeyguardInvisible();
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 1899472..4075c55 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -336,7 +336,6 @@
@Test
@PortraitLandscape
@NavigationModeSwitch
- @PlatinumTest(focusArea = "launcher")
public void testPressBack() throws Exception {
InstrumentationRegistry.getInstrumentation().getUiAutomation().adoptShellPermissionIdentity(
READ_DEVICE_CONFIG_PERMISSION);
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
index ee0fbb8..d3bf56f 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsSplitscreen.java
@@ -108,7 +108,6 @@
}
@Test
- @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemExistsOnSplitPair() throws Exception {
assumeTrue("App pairs feature is currently not enabled, no test needed",
Flags.enableAppPairs());
@@ -124,7 +123,6 @@
}
@Test
- @Ignore("Enable once App Pairs flagged on. These cause memory leaks b/297135374")
public void testSaveAppPairMenuItemDoesNotExistOnSingleTask() throws Exception {
assumeTrue("App pairs feature is currently not enabled, no test needed",
Flags.enableAppPairs());
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 39f1477..138e1b3 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -133,7 +133,7 @@
<string name="widgets_list_closed" msgid="6141506579418771922">"ವಿಜೆಟ್ ಪಟ್ಟಿಯನ್ನು ಮುಚ್ಚಲಾಗಿದೆ"</string>
<string name="action_add_to_workspace" msgid="215894119683164916">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಸೇರಿಸಿ"</string>
<string name="action_move_here" msgid="2170188780612570250">"ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ"</string>
- <string name="item_added_to_workspace" msgid="4211073925752213539">"ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"</string>
+ <string name="item_added_to_workspace" msgid="4211073925752213539">"ಹೋಮ್ ಸ್ಕ್ರೀನ್ಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ"</string>
<string name="item_removed" msgid="851119963877842327">"ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="undo" msgid="4151576204245173321">"ರದ್ದುಮಾಡಿ"</string>
<string name="action_move" msgid="4339390619886385032">"ಐಟಂ ಸರಿಸಿ"</string>
diff --git a/src/com/android/launcher3/AppWidgetResizeFrame.java b/src/com/android/launcher3/AppWidgetResizeFrame.java
index 189db21..79b831e 100644
--- a/src/com/android/launcher3/AppWidgetResizeFrame.java
+++ b/src/com/android/launcher3/AppWidgetResizeFrame.java
@@ -32,6 +32,7 @@
import androidx.annotation.Nullable;
import androidx.annotation.Px;
+import com.android.launcher3.LauncherConstants.ActivityCodes;
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.celllayout.CellLayoutLayoutParams;
import com.android.launcher3.celllayout.CellPosMapper.CellPos;
@@ -270,7 +271,7 @@
.startConfigActivity(
mLauncher,
mWidgetView.getAppWidgetId(),
- Launcher.REQUEST_RECONFIGURE_APPWIDGET);
+ ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET);
});
if (!hasSeenReconfigurableWidgetEducationTip()) {
post(() -> {
diff --git a/src/com/android/launcher3/DropTargetHandler.kt b/src/com/android/launcher3/DropTargetHandler.kt
index 78f2862..e022159 100644
--- a/src/com/android/launcher3/DropTargetHandler.kt
+++ b/src/com/android/launcher3/DropTargetHandler.kt
@@ -4,6 +4,7 @@
import android.view.View
import com.android.launcher3.BaseDraggingActivity.EVENT_RESUMED
import com.android.launcher3.DropTarget.DragObject
+import com.android.launcher3.LauncherConstants.ActivityCodes
import com.android.launcher3.SecondaryDropTarget.DeferredOnComplete
import com.android.launcher3.dragndrop.DragLayer
import com.android.launcher3.logging.StatsLogManager.LauncherEvent
@@ -46,7 +47,7 @@
mLauncher.appWidgetHolder.startConfigActivity(
mLauncher,
widgetId,
- Launcher.REQUEST_RECONFIGURE_APPWIDGET
+ ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET
)
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec2816b..dd03035 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -33,6 +33,28 @@
import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_WIDGET_TRANSITION;
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_BIND_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_BIND_PENDING_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_CREATE_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_CREATE_SHORTCUT;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_PICK_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE_CURRENT_SCREEN_IDS;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE_PENDING_ACTIVITY_RESULT;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE_PENDING_REQUEST_ARGS;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE_PENDING_REQUEST_CODE;
+import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE_WIDGET_PANEL;
+import static com.android.launcher3.LauncherConstants.TraceEvents.COLD_STARTUP_TRACE_COOKIE;
+import static com.android.launcher3.LauncherConstants.TraceEvents.COLD_STARTUP_TRACE_METHOD_NAME;
+import static com.android.launcher3.LauncherConstants.TraceEvents.DISPLAY_ALL_APPS_TRACE_COOKIE;
+import static com.android.launcher3.LauncherConstants.TraceEvents.DISPLAY_ALL_APPS_TRACE_METHOD_NAME;
+import static com.android.launcher3.LauncherConstants.TraceEvents.DISPLAY_WORKSPACE_TRACE_METHOD_NAME;
+import static com.android.launcher3.LauncherConstants.TraceEvents.DISPLAY_WORKSPACE_TRACE_COOKIE;
+import static com.android.launcher3.LauncherConstants.TraceEvents.ON_CREATE_EVT;
+import static com.android.launcher3.LauncherConstants.TraceEvents.ON_NEW_INTENT_EVT;
+import static com.android.launcher3.LauncherConstants.TraceEvents.ON_RESUME_EVT;
+import static com.android.launcher3.LauncherConstants.TraceEvents.ON_START_EVT;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -267,15 +289,6 @@
static final boolean DEBUG_STRICT_MODE = false;
- private static final int REQUEST_CREATE_SHORTCUT = 1;
- private static final int REQUEST_CREATE_APPWIDGET = 5;
-
- private static final int REQUEST_PICK_APPWIDGET = 9;
-
- private static final int REQUEST_BIND_APPWIDGET = 11;
- public static final int REQUEST_BIND_PENDING_APPWIDGET = 12;
- public static final int REQUEST_RECONFIGURE_APPWIDGET = 13;
-
private static final float BOUNCE_ANIMATION_TENSION = 1.3f;
/**
@@ -284,30 +297,9 @@
*/
protected static final int REQUEST_LAST = 100;
- // Type: int
- protected static final String RUNTIME_STATE = "launcher.state";
- // Type: PendingRequestArgs
- private static final String RUNTIME_STATE_PENDING_REQUEST_ARGS = "launcher.request_args";
- // Type: int
- private static final String RUNTIME_STATE_PENDING_REQUEST_CODE = "launcher.request_code";
- // Type: ActivityResultInfo
- private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
- // Type: SparseArray<Parcelable>
- private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
- // Type int[]
- private static final String RUNTIME_STATE_CURRENT_SCREEN_IDS = "launcher.current_screen_ids";
-
- // Type PendingSplitSelectInfo<Parcelable>
- protected static final String PENDING_SPLIT_SELECT_INFO = "launcher.pending_split_select_info";
-
public static final String INTENT_ACTION_ALL_APPS_TOGGLE =
"launcher.intent_action_all_apps_toggle";
- public static final String ON_CREATE_EVT = "Launcher.onCreate";
- public static final String ON_START_EVT = "Launcher.onStart";
- public static final String ON_RESUME_EVT = "Launcher.onResume";
- public static final String ON_NEW_INTENT_EVT = "Launcher.onNewIntent";
-
private static boolean sIsNewProcess = true;
private StateManager<LauncherState> mStateManager;
@@ -319,13 +311,6 @@
private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk @VisibleForTesting public static final int NEW_APPS_ANIMATION_DELAY = 500;
- private static final String DISPLAY_WORKSPACE_TRACE_METHOD_NAME = "DisplayWorkspaceFirstFrame";
- public static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps";
- public static final int DISPLAY_WORKSPACE_TRACE_COOKIE = 0;
- public static final int DISPLAY_ALL_APPS_TRACE_COOKIE = 1;
- private static final String COLD_STARTUP_TRACE_METHOD_NAME = "LauncherColdStartup";
- public static final int COLD_STARTUP_TRACE_COOKIE = 2;
-
private static final FloatProperty<Workspace<?>> WORKSPACE_WIDGET_SCALE =
WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION);
private static final FloatProperty<Hotseat> HOTSEAT_WIDGET_SCALE =
@@ -2803,10 +2788,8 @@
Map<PackageUserKey, Integer> packageUserKeytoUidMap) {
mModelCallbacks.bindAllApplications(apps, flags, packageUserKeytoUidMap);
if (Utilities.ATLEAST_S) {
- Trace.endAsyncSection(
- Launcher.DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
- Launcher.DISPLAY_ALL_APPS_TRACE_COOKIE
- );
+ Trace.endAsyncSection(DISPLAY_ALL_APPS_TRACE_METHOD_NAME,
+ DISPLAY_ALL_APPS_TRACE_COOKIE);
}
}
diff --git a/src/com/android/launcher3/LauncherConstants.java b/src/com/android/launcher3/LauncherConstants.java
new file mode 100644
index 0000000..1abfeb9
--- /dev/null
+++ b/src/com/android/launcher3/LauncherConstants.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 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;
+
+public class LauncherConstants {
+
+ /**
+ * Trace events to visualize using Systrace tool.
+ */
+ public static class TraceEvents {
+
+ public static final String DISPLAY_ALL_APPS_TRACE_METHOD_NAME = "DisplayAllApps";
+ public static final int DISPLAY_WORKSPACE_TRACE_COOKIE = 0;
+ public static final int DISPLAY_ALL_APPS_TRACE_COOKIE = 1;
+ public static final int COLD_STARTUP_TRACE_COOKIE = 2;
+ public static final String ON_CREATE_EVT = "Launcher.onCreate";
+ public static final String ON_START_EVT = "Launcher.onStart";
+ public static final String ON_RESUME_EVT = "Launcher.onResume";
+ public static final String ON_NEW_INTENT_EVT = "Launcher.onNewIntent";
+ static final String DISPLAY_WORKSPACE_TRACE_METHOD_NAME = "DisplayWorkspaceFirstFrame";
+ static final String COLD_STARTUP_TRACE_METHOD_NAME = "LauncherColdStartup";
+ }
+
+ /**
+ * This are the different codes the Launcher can receive when a new Launcher Intent is created.
+ */
+ public static class ActivityCodes {
+
+ public static final int REQUEST_BIND_PENDING_APPWIDGET = 12;
+ public static final int REQUEST_RECONFIGURE_APPWIDGET = 13;
+ static final int REQUEST_CREATE_SHORTCUT = 1;
+ static final int REQUEST_CREATE_APPWIDGET = 5;
+ static final int REQUEST_PICK_APPWIDGET = 9;
+ static final int REQUEST_BIND_APPWIDGET = 11;
+ }
+
+ /**
+ * Keys used to get the saved values of the previous Activity instance.
+ */
+ public static class SavedInstanceKeys {
+
+ // Type: int
+ public static final String RUNTIME_STATE = "launcher.state";
+ // Type PendingSplitSelectInfo<Parcelable>
+ public static final String PENDING_SPLIT_SELECT_INFO = "launcher.pending_split_select_info";
+ // Type: PendingRequestArgs
+ static final String RUNTIME_STATE_PENDING_REQUEST_ARGS = "launcher.request_args";
+ // Type: int
+ static final String RUNTIME_STATE_PENDING_REQUEST_CODE = "launcher.request_code";
+ // Type: ActivityResultInfo
+ static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
+ // Type: SparseArray<Parcelable>
+ static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
+ // Type int[]
+ static final String RUNTIME_STATE_CURRENT_SCREEN_IDS = "launcher.current_screen_ids";
+ }
+}
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/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index 18200f6..69fa673 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -169,6 +169,9 @@
LauncherPrefs.get(getContext())
.put(THEMED_ICONS, values.getAsBoolean(BOOLEAN_VALUE));
getContext().getContentResolver().notifyChange(uri, null);
+ mActivePreviews.values().forEach(observer ->
+ observer.renderer.refreshIcons()
+ );
return 1;
}
default:
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
index 3330448..346f644 100644
--- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -35,9 +35,12 @@
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.LauncherApps;
import android.content.res.TypedArray;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
@@ -76,6 +79,7 @@
import com.android.launcher3.celllayout.CellPosMapper;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.icons.IconProvider;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.BgDataModel;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
@@ -83,6 +87,7 @@
import com.android.launcher3.model.WidgetsModel;
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
+import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.LauncherAppWidgetInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.pm.InstallSessionHelper;
@@ -188,6 +193,8 @@
private final SparseIntArray mWallpaperColorResources;
private final SparseArray<Size> mLauncherWidgetSpanInfo;
+ private final Map<BubbleTextView, WorkspaceItemInfo> mIcons = new HashMap<>();
+
public LauncherPreviewRenderer(Context context,
InvariantDeviceProfile idp,
WallpaperColors wallpaperColorsOverride,
@@ -366,11 +373,43 @@
return CellPosMapper.DEFAULT;
}
+ /**
+ * Refreshes icon to update based on resource changes.
+ */
+ public void refreshIcons() {
+ mUiHandler.post(() -> {
+ IconProvider iconProvider = null;
+ int iconDpi = -1;
+ for (Map.Entry<BubbleTextView, WorkspaceItemInfo> entry : mIcons.entrySet()) {
+ BubbleTextView icon = entry.getKey();
+ ItemInfoWithIcon info = entry.getValue();
+ // get monochrome themed icon if it was not initially cached
+ if (info.bitmap.getMono() == null) {
+ if (iconProvider == null || iconDpi == -1) {
+ LauncherAppState appState = LauncherAppState.getInstance(mContext);
+ iconProvider = appState.getIconProvider();
+ iconDpi = appState.getInvariantDeviceProfile().fillResIconDpi;
+ }
+ LauncherActivityInfo activityInfo = mContext.getSystemService(
+ LauncherApps.class)
+ .resolveActivity(info.getIntent(), info.user);
+ Drawable iconDrawable = iconProvider.getIcon(activityInfo, iconDpi);
+ LauncherIcons iconFactory = LauncherIcons.obtain(mContext);
+ info.bitmap = iconFactory.createBadgedIconBitmap(iconDrawable);
+ }
+ // update icon based on whether themed icon is enabled
+ icon.reapplyItemInfo(info);
+ }
+ }
+ );
+ }
+
private void inflateAndAddIcon(WorkspaceItemInfo info) {
CellLayout screen = mWorkspaceScreens.get(info.screenId);
BubbleTextView icon = (BubbleTextView) mHomeElementInflater.inflate(
R.layout.app_icon, screen, false);
icon.applyFromWorkspaceItem(info);
+ mIcons.put(icon, info);
addInScreenFromBind(icon, info);
}
@@ -477,6 +516,8 @@
currentWorkspaceItems, otherWorkspaceItems);
filterCurrentWorkspaceItems(currentScreenIds, dataModel.appWidgets, currentAppWidgets,
otherAppWidgets);
+
+ mIcons.clear();
for (ItemInfo itemInfo : currentWorkspaceItems) {
switch (itemInfo.itemType) {
case Favorites.ITEM_TYPE_APPLICATION:
diff --git a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
index 683354b..1bac765 100644
--- a/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
+++ b/src/com/android/launcher3/graphics/PreviewSurfaceRenderer.java
@@ -201,6 +201,13 @@
}
}
+ /**
+ * Refreshes icon to update based on resource changes.
+ */
+ public void refreshIcons() {
+ mRenderer.refreshIcons();
+ }
+
/***
* Generates a new context overriding the theme color and the display size without affecting the
* main application context
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/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java
index 8c12547..db32829 100644
--- a/src/com/android/launcher3/touch/ItemClickHandler.java
+++ b/src/com/android/launcher3/touch/ItemClickHandler.java
@@ -15,8 +15,8 @@
*/
package com.android.launcher3.touch;
-import static com.android.launcher3.Launcher.REQUEST_BIND_PENDING_APPWIDGET;
-import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_BIND_PENDING_APPWIDGET;
+import static com.android.launcher3.LauncherConstants.ActivityCodes.REQUEST_RECONFIGURE_APPWIDGET;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER;
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index 6f74fd9..99485be 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -257,8 +257,6 @@
throw new RuntimeException("Max size is too small for preview");
}
return BitmapRenderer.createHardwareBitmap(size, size, c -> {
- drawBoxWithShadow(c, size, size);
-
LauncherIcons li = LauncherIcons.obtain(mContext);
Drawable icon = li.createBadgedIconBitmap(
mutateOnMainThread(info.getFullResIcon(
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/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index ee151bb..bd9da0a 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -42,18 +42,7 @@
</receiver>
<receiver
- android:name="com.android.launcher3.testcomponent.AppWidgetNoConfigLarge"
- android:exported="true"
- android:label="No Config Large">
- <intent-filter>
- <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
- </intent-filter>
- <meta-data android:name="android.appwidget.provider"
- android:resource="@xml/appwidget_no_config_large"/>
- </receiver>
-
- <receiver
- android:name="com.android.launcher3.testcomponent.AppWdigetHidden"
+ android:name="com.android.launcher3.testcomponent.AppWidgetHidden"
android:exported="true"
android:label="Hidden widget">
<intent-filter>
@@ -84,7 +73,7 @@
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
- android:resource="@xml/appwidget_no_config"/>
+ android:resource="@xml/appwidget_no_config_large"/>
</receiver>
<receiver
diff --git a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
index eb45ded..3e80e6b 100644
--- a/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
+++ b/tests/shared/com/android/launcher3/testing/shared/TestProtocol.java
@@ -158,7 +158,6 @@
public static final String PERMANENT_DIAG_TAG = "TaplTarget";
public static final String TWO_TASKBAR_LONG_CLICKS = "b/262282528";
public static final String ICON_MISSING = "b/282963545";
- public static final String SPLIT_LEAK = "b/302551868";
public static final String REQUEST_EMULATE_DISPLAY = "emulate-display";
public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display";
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/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 4184868..9bfafcf 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -187,7 +187,7 @@
Utilities.enableRunningInTestHarnessForTests();
mLauncher.setSystemHealthSupplier(startTime -> TestCommandReceiver.callCommand(
TestCommandReceiver.GET_SYSTEM_HEALTH_MESSAGE, startTime.toString())
- .getString("result"));
+ .getString("result"));
mLauncher.setOnSettledStateAction(
containerType -> executeOnLauncher(
launcher ->
@@ -248,6 +248,7 @@
public void setUp() throws Exception {
mLauncher.onTestStart();
+ waitForSetupWizardDismissal();
if (TestStabilityRule.isPresubmit()) {
aggressivelyUnlockSysUi();
} else {
@@ -308,6 +309,36 @@
Log.d(TAG, "Keyguard is not visible");
}
+ // b/309008042
+ private static boolean sFirstTimeWaitingForWizard = true;
+
+ // b/309008042
+ static {
+ waitForSetupWizardDismissal();
+ }
+
+ // b/309008042
+ // TODO(309471958) Productize killing/dismissal of setup wizard.
+ /** Waits for setup wizard to go away. */
+ public static void waitForSetupWizardDismissal() {
+ if (sFirstTimeWaitingForWizard && TestStabilityRule.isPresubmit()) {
+ try {
+ UiDevice.getInstance(getInstrumentation()).executeShellCommand(
+ "am force-stop com.google.android.setupwizard");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ final boolean wizardDismissed = TestHelpers.wait(
+ Until.gone(By.pkg("com.google.android.setupwizard").depth(0)),
+ sFirstTimeWaitingForWizard ? 120000 : 0);
+ sFirstTimeWaitingForWizard = false;
+ // b/309496273
+// Assert.assertTrue("Setup wizard is still visible",
+// wizardDismissed);
+ }
+
public static void verifyKeyguardInvisible() {
final boolean keyguardAlreadyVisible = sSeenKeyguard;
@@ -422,6 +453,7 @@
// flakiness.
protected void waitForLauncherCondition(
String message, Function<Launcher, Boolean> condition, long timeout) {
+ waitForSetupWizardDismissal();
verifyKeyguardInvisible();
if (!TestHelpers.isInLauncherProcess()) return;
Wait.atMost(message, () -> getFromLauncher(condition), timeout, mLauncher);
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();
+ }
}