From ca7c61d38594ccdc29d91bcd869ad675ef184ed7 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Wed, 4 May 2022 06:06:07 +0000 Subject: [PATCH 1/7] Support fade-in divider bar with quick switch gesture Fix: 229613465 Test: quickswitch back to split pair, divider bar will fade-in as expected. Change-Id: I2746ef63ecf9a9cc5563c543cc83583955e0c938 --- quickstep/src/com/android/quickstep/TaskAnimationManager.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 2565674763..54f457d2d8 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -192,6 +192,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */); return; } + } else if (nonAppTargets != null && nonAppTargets.length > 0) { + TaskViewUtils.createSplitAuxiliarySurfacesAnimator( + RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */, + true /*shown*/, dividerAnimator -> dividerAnimator.start()); } if (mController != null) { if (mLastAppearedTaskTarget == null From 664c1c18e729a57ccb4d961042792fb45f7c36a7 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 6 May 2022 15:47:11 +0100 Subject: [PATCH 2/7] Sort hotseat items in migration to preserve position Fix: 231601760 Test: manual with local backup/restore Change-Id: Ie89f0134485296c3cd252cf6b86bb3f88a0f90de --- .../android/launcher3/model/GridSizeMigrationTaskV2.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java index e36d4cf27d..ef9250c900 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java +++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java @@ -216,14 +216,15 @@ public class GridSizeMigrationTaskV2 { return false; } + // Sort the items by the reading order. + Collections.sort(mHotseatDiff); + Collections.sort(mWorkspaceDiff); + // Migrate hotseat HotseatPlacementSolution hotseatSolution = new HotseatPlacementSolution(mDb, mSrcReader, mDestReader, mContext, mDestHotseatSize, mHotseatItems, mHotseatDiff); hotseatSolution.find(); - // Sort the items by the reading order. - Collections.sort(mWorkspaceDiff); - // Migrate workspace. // First we create a collection of the screens List screens = new ArrayList<>(); From b1436b0ae7e5a4e5a8644e4c11bd7f7d338ba7a4 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 2 May 2022 11:51:01 -0700 Subject: [PATCH 3/7] Extend recents button hitbox on tablet * Extends hitbox when recents is tapped when going from taskbar to overview. * Extended region lasts for 400ms after the animation ends. Fixes: 225885714 Test: Manual, added unit test Change-Id: I8766279c1a5bf6867f8d69ddd3af2aa3565deec2 --- .../taskbar/NavbarButtonsViewController.java | 33 ++++- .../taskbar/RecentsHitboxExtender.java | 134 ++++++++++++++++++ .../taskbar/TaskbarDragLayerController.java | 3 +- .../TaskbarLauncherStateController.java | 1 + .../taskbar/RecentsHitboxExtenderTest.java | 125 ++++++++++++++++ 5 files changed, 293 insertions(+), 3 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java create mode 100644 quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 349dd0a8f6..4758f102ab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; +import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; @@ -51,6 +52,7 @@ import android.graphics.Region.Op; import android.graphics.drawable.AnimatedVectorDrawable; import android.graphics.drawable.PaintDrawable; import android.inputmethodservice.InputMethodService; +import android.os.Handler; import android.util.Property; import android.view.Gravity; import android.view.MotionEvent; @@ -158,6 +160,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private BaseDragLayer mSeparateWindowParent; // Initialized in init. private final ViewTreeObserverWrapper.OnComputeInsetsListener mSeparateWindowInsetsComputer = this::onComputeInsetsForSeparateWindow; + private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender(); public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) { mContext = context; @@ -388,8 +391,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT || (flags & FLAG_KEYGUARD_VISIBLE) != 0, VIEW_TRANSLATE_X, navButtonSize * (isRtl ? -2 : 2), 0)); - - // home and recents buttons + // home button mHomeButton = addButton(R.drawable.ic_sysbar_home, BUTTON_HOME, navContainer, navButtonController, R.id.home); mHomeButtonAlpha = new MultiValueAlpha(mHomeButton, NUM_ALPHA_CHANNELS); @@ -399,8 +401,21 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT ALPHA_INDEX_KEYGUARD_OR_DISABLE), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_HOME) == 0)); + + // Recents button View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS, navContainer, navButtonController, R.id.recent_apps); + mHitboxExtender.init(recentsButton, mNavButtonsView, mContext.getDeviceProfile(), + () -> { + float[] recentsCoords = new float[2]; + getDescendantCoordRelativeToAncestor(recentsButton, mNavButtonsView, + recentsCoords, false); + return recentsCoords; + }, new Handler()); + recentsButton.setOnClickListener(v -> { + navButtonController.onButtonClick(BUTTON_RECENTS); + mHitboxExtender.onRecentsButtonClicked(); + }); mPropertyHolders.add(new StatePropertyHolder(recentsButton, flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_RECENTS) == 0 && !mContext.isNavBarKidsModeActive())); @@ -504,6 +519,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT View button = mAllButtons.get(i); if (button.getVisibility() == View.VISIBLE) { parent.getDescendantRectRelativeToSelf(button, mTempRect); + if (mHitboxExtender.extendedHitboxEnabled()) { + mTempRect.bottom += mContext.mDeviceProfile.getTaskbarOffsetY(); + } outRegion.op(mTempRect, Op.UNION); } } @@ -733,6 +751,17 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT return str.toString(); } + public TouchController getTouchController() { + return mHitboxExtender; + } + + /** + * @param alignment 0 -> Taskbar, 1 -> Workspace + */ + public void updateTaskbarAlignment(float alignment) { + mHitboxExtender.onAnimationProgressToOverview(alignment); + } + private class RotationButtonListener implements RotationButton.RotationButtonUpdatesCallback { @Override public void onVisibilityChanged(boolean isVisible) { diff --git a/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java b/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java new file mode 100644 index 0000000000..4651570a60 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/RecentsHitboxExtender.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2022 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.taskbar; + +import android.graphics.Rect; +import android.os.Handler; +import android.view.MotionEvent; +import android.view.TouchDelegate; +import android.view.View; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.util.TouchController; + +import java.util.function.Supplier; + +/** + * Extends the Recents touch area during the taskbar to overview animation + * to give user some error room when trying to quickly double tap recents button since it moves. + * + * Listens for icon alignment as our indication for the animation. + */ +public class RecentsHitboxExtender implements TouchController { + + private static final int RECENTS_HITBOX_TIMEOUT_MS = 500; + + private View mRecentsButton; + private View mRecentsParent; + private DeviceProfile mDeviceProfile; + private Supplier mParentCoordSupplier; + private TouchDelegate mRecentsTouchDelegate; + /** + * Will be true while the animation from taskbar to overview is occurring. + * Lifecycle of this variable slightly extends past the animation by + * {@link #RECENTS_HITBOX_TIMEOUT_MS}, so can use this variable as a proxy for if + * the current hitbox is extended or not. + */ + private boolean mAnimatingFromTaskbarToOverview; + private float mLastIconAlignment; + private final Rect mRecentsHitBox = new Rect(); + private boolean mRecentsButtonClicked; + private Handler mHandler; + private final Runnable mRecentsHitboxResetRunnable = this::reset; + + public void init(View recentsButton, View recentsParent, DeviceProfile deviceProfile, + Supplier parentCoordSupplier, Handler handler) { + mRecentsButton = recentsButton; + mRecentsParent = recentsParent; + mDeviceProfile = deviceProfile; + mParentCoordSupplier = parentCoordSupplier; + mHandler = handler; + } + + public void onRecentsButtonClicked() { + mRecentsButtonClicked = true; + } + + /** + * @param progress 0 -> Taskbar, 1 -> Overview + */ + public void onAnimationProgressToOverview(float progress) { + if (progress == 1 || progress == 0) { + // Done w/ animation + mLastIconAlignment = progress; + if (mAnimatingFromTaskbarToOverview) { + if (progress == 1) { + // Finished animation to workspace, remove the touch delegate shortly + mHandler.postDelayed(mRecentsHitboxResetRunnable, RECENTS_HITBOX_TIMEOUT_MS); + return; + } else { + // Went back to taskbar, reset immediately + mHandler.removeCallbacks(mRecentsHitboxResetRunnable); + reset(); + } + } + } + + if (mAnimatingFromTaskbarToOverview) { + return; + } + + if (progress > 0 && mLastIconAlignment == 0 && mRecentsButtonClicked) { + // Starting animation, previously we were showing taskbar + mAnimatingFromTaskbarToOverview = true; + float[] recentsCoords = mParentCoordSupplier.get(); + int x = (int) recentsCoords[0]; + int y = (int) (recentsCoords[1]); + // Extend hitbox vertically by the offset amount from mDeviceProfile.getTaskbarOffsetY() + mRecentsHitBox.set(x, y, + x + mRecentsButton.getWidth(), + y + mRecentsButton.getHeight() + mDeviceProfile.getTaskbarOffsetY() + ); + mRecentsTouchDelegate = new TouchDelegate(mRecentsHitBox, mRecentsButton); + mRecentsParent.setTouchDelegate(mRecentsTouchDelegate); + } + } + + private void reset() { + mAnimatingFromTaskbarToOverview = false; + mRecentsButton.setTouchDelegate(null); + mRecentsHitBox.setEmpty(); + mRecentsButtonClicked = false; + } + + /** + * @return {@code true} if the bounds for recents touches are currently extended + */ + public boolean extendedHitboxEnabled() { + return mAnimatingFromTaskbarToOverview; + } + + @Override + public boolean onControllerTouchEvent(MotionEvent ev) { + return mRecentsTouchDelegate.onTouchEvent(ev); + } + + @Override + public boolean onControllerInterceptTouchEvent(MotionEvent ev) { + return mRecentsHitBox.contains((int)ev.getX(), (int)ev.getY()); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 3e2695c135..99c59a8a98 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -182,7 +182,8 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa */ public TouchController[] getTouchControllers() { return new TouchController[]{mActivity.getDragController(), - mControllers.taskbarForceVisibleImmersiveController}; + mControllers.taskbarForceVisibleImmersiveController, + mControllers.navbarButtonsViewController.getTouchController()}; } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 138fb991f4..1e9a6a90f0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -427,6 +427,7 @@ import java.util.function.Supplier; // Switch taskbar and hotseat in last frame setTaskbarViewVisible(alignment < 1); + mControllers.navbarButtonsViewController.updateTaskbarAlignment(alignment); } private float getCurrentIconAlignmentRatioBetweenAppAndHome() { diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java b/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java new file mode 100644 index 0000000000..929bff3004 --- /dev/null +++ b/quickstep/tests/src/com/android/launcher3/taskbar/RecentsHitboxExtenderTest.java @@ -0,0 +1,125 @@ +package com.android.launcher3.taskbar; + +import static android.view.MotionEvent.ACTION_DOWN; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.Instrumentation; +import android.content.Context; +import android.os.Handler; +import android.view.MotionEvent; +import android.view.View; + +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + +import com.android.launcher3.DeviceProfile; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.function.Supplier; + +@RunWith(AndroidJUnit4.class) +public class RecentsHitboxExtenderTest { + + private static final int TASKBAR_OFFSET_Y = 35; + private static final int BUTTON_WIDTH = 10; + private static final int BUTTON_HEIGHT = 10; + + private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender(); + @Mock + View mMockRecentsButton; + @Mock + View mMockRecentsParent; + @Mock + DeviceProfile mMockDeviceProfile; + @Mock + Handler mMockHandler; + Context mContext; + + float[] mRecentsCoords = new float[]{0,0}; + private final Supplier mSupplier = () -> mRecentsCoords; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); + mContext = instrumentation.getContext(); + mHitboxExtender.init(mMockRecentsButton, mMockRecentsParent, mMockDeviceProfile, mSupplier, + mMockHandler); + when(mMockDeviceProfile.getTaskbarOffsetY()).thenReturn(TASKBAR_OFFSET_Y); + when(mMockRecentsButton.getContext()).thenReturn(mContext); + when(mMockRecentsButton.getWidth()).thenReturn(BUTTON_WIDTH); + when(mMockRecentsButton.getHeight()).thenReturn(BUTTON_HEIGHT); + } + + @Test + public void noRecentsButtonClick_notActive() { + mHitboxExtender.onAnimationProgressToOverview(0); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertFalse(mHitboxExtender.extendedHitboxEnabled()); + } + + @Test + public void recentsButtonClick_active() { + mHitboxExtender.onRecentsButtonClicked(); + mHitboxExtender.onAnimationProgressToOverview(0); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertTrue(mHitboxExtender.extendedHitboxEnabled()); + } + + @Test + public void homeToTaskbar_notActive() { + mHitboxExtender.onAnimationProgressToOverview(1); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertFalse(mHitboxExtender.extendedHitboxEnabled()); + } + + @Test + public void animationEndReset() { + mHitboxExtender.onRecentsButtonClicked(); + mHitboxExtender.onAnimationProgressToOverview(0); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertTrue(mHitboxExtender.extendedHitboxEnabled()); + mHitboxExtender.onAnimationProgressToOverview(1); + verify(mMockHandler, times(1)).postDelayed(any(), anyLong()); + } + + @Test + public void motionWithinHitbox() { + mHitboxExtender.onRecentsButtonClicked(); + mHitboxExtender.onAnimationProgressToOverview(0); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertTrue(mHitboxExtender.extendedHitboxEnabled()); + // Center width, past height but w/in offset bounds + MotionEvent motionEvent = getMotionEvent(ACTION_DOWN, + BUTTON_WIDTH / 2, BUTTON_HEIGHT + TASKBAR_OFFSET_Y / 2); + assertTrue(mHitboxExtender.onControllerInterceptTouchEvent(motionEvent)); + } + + @Test + public void motionOutsideHitbox() { + mHitboxExtender.onRecentsButtonClicked(); + mHitboxExtender.onAnimationProgressToOverview(0); + mHitboxExtender.onAnimationProgressToOverview(0.5f); + assertTrue(mHitboxExtender.extendedHitboxEnabled()); + // Center width, past height and offset + MotionEvent motionEvent = getMotionEvent(ACTION_DOWN, + BUTTON_WIDTH / 2, BUTTON_HEIGHT + TASKBAR_OFFSET_Y * 2); + assertFalse(mHitboxExtender.onControllerInterceptTouchEvent(motionEvent)); + } + + private MotionEvent getMotionEvent(int action, int x, int y) { + return MotionEvent.obtain(0, 0, action, x, y, 0); + } +} From d5a4d60483e1a81597c1d273f3ad795d1d1e6c33 Mon Sep 17 00:00:00 2001 From: kholoud mohamed Date: Thu, 28 Apr 2022 15:55:40 +0100 Subject: [PATCH 4/7] update enterprise strings on ACTION_DEVICE_POLICY_RESOURCE_UPDATED Also updated work folder name provider to retrieve it from dpm Bug: 218322904 Test: manual Change-Id: Id80a9e90806f3a07f132b5cc1e9871bb35df42b0 --- .../android/launcher3/LauncherAppState.java | 5 ++- src/com/android/launcher3/LauncherModel.java | 5 +++ .../launcher3/folder/FolderNameProvider.java | 21 +++++++++- .../model/ReloadStringCacheTask.java | 39 +++++++++++++++++++ .../android/launcher3/model/StringCache.java | 10 ++--- 5 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/com/android/launcher3/model/ReloadStringCacheTask.java diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index 45011590e3..597bc8da3a 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED; + import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.config.FeatureFlags.ENABLE_THEMED_ICONS; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; @@ -97,7 +99,8 @@ public class LauncherAppState implements SafeCloseable { modelChangeReceiver.register(mContext, Intent.ACTION_LOCALE_CHANGED, Intent.ACTION_MANAGED_PROFILE_AVAILABLE, Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE, - Intent.ACTION_MANAGED_PROFILE_UNLOCKED); + Intent.ACTION_MANAGED_PROFILE_UNLOCKED, + ACTION_DEVICE_POLICY_RESOURCE_UPDATED); if (FeatureFlags.IS_STUDIO_BUILD) { modelChangeReceiver.register(mContext, Context.RECEIVER_EXPORTED, ACTION_FORCE_ROLOAD); } diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java index ee6f51ed05..5c5c101355 100644 --- a/src/com/android/launcher3/LauncherModel.java +++ b/src/com/android/launcher3/LauncherModel.java @@ -16,6 +16,8 @@ package com.android.launcher3; +import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED; + import static com.android.launcher3.LauncherAppState.ACTION_FORCE_ROLOAD; import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; @@ -51,6 +53,7 @@ import com.android.launcher3.model.ModelWriter; import com.android.launcher3.model.PackageIncrementalDownloadUpdatedTask; import com.android.launcher3.model.PackageInstallStateChangedTask; import com.android.launcher3.model.PackageUpdatedTask; +import com.android.launcher3.model.ReloadStringCacheTask; import com.android.launcher3.model.ShortcutsChangedTask; import com.android.launcher3.model.UserLockStateChangedTask; import com.android.launcher3.model.data.AppInfo; @@ -278,6 +281,8 @@ public class LauncherModel extends LauncherApps.Callback implements InstallSessi user, Intent.ACTION_MANAGED_PROFILE_UNLOCKED.equals(action))); } } + } else if (ACTION_DEVICE_POLICY_RESOURCE_UPDATED.equals(action)) { + enqueueModelUpdateTask(new ReloadStringCacheTask(mModelDelegate)); } else if (IS_STUDIO_BUILD && ACTION_FORCE_ROLOAD.equals(action)) { for (Callbacks cb : getCallbacks()) { if (cb instanceof Launcher) { diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java index 2b621bd58b..502164473f 100644 --- a/src/com/android/launcher3/folder/FolderNameProvider.java +++ b/src/com/android/launcher3/folder/FolderNameProvider.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.folder; +import android.annotation.SuppressLint; +import android.app.admin.DevicePolicyManager; import android.content.ComponentName; import android.content.Context; import android.os.Process; @@ -22,11 +24,15 @@ import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; +import androidx.annotation.WorkerThread; + import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BaseModelUpdateTask; import com.android.launcher3.model.BgDataModel; +import com.android.launcher3.model.StringCache; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; @@ -94,6 +100,7 @@ public class FolderNameProvider implements ResourceBasedOverride { /** * Generate and rank the suggested Folder names. */ + @WorkerThread public void getSuggestedFolderName(Context context, ArrayList workspaceItemInfos, FolderNameInfos nameInfos) { @@ -107,8 +114,7 @@ public class FolderNameProvider implements ResourceBasedOverride { Set users = workspaceItemInfos.stream().map(w -> w.user) .collect(Collectors.toSet()); if (users.size() == 1 && !users.contains(Process.myUserHandle())) { - String workFolderName = context.getString(R.string.work_folder_name); - setAsLastSuggestion(nameInfos, workFolderName); + setAsLastSuggestion(nameInfos, getWorkFolderName(context)); } // If all the icons are from same package (e.g., main icon, shortcut, shortcut) @@ -130,6 +136,17 @@ public class FolderNameProvider implements ResourceBasedOverride { } } + @WorkerThread + @SuppressLint("NewApi") + private String getWorkFolderName(Context context) { + if (!Utilities.ATLEAST_T) { + return context.getString(R.string.work_folder_name); + } + return context.getSystemService(DevicePolicyManager.class).getResources() + .getString(StringCache.WORK_FOLDER_NAME, () -> + context.getString(R.string.work_folder_name)); + } + private Optional getAppInfoByPackageName(String packageName) { if (mAppInfos == null || mAppInfos.isEmpty()) { return Optional.empty(); diff --git a/src/com/android/launcher3/model/ReloadStringCacheTask.java b/src/com/android/launcher3/model/ReloadStringCacheTask.java new file mode 100644 index 0000000000..f4d42988bf --- /dev/null +++ b/src/com/android/launcher3/model/ReloadStringCacheTask.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.launcher3.model; + +import com.android.launcher3.LauncherAppState; + +/** + * Handles updates due to changes in Device Policy Management resources triggered by + * {@link android.app.admin.DevicePolicyManager#ACTION_DEVICE_POLICY_RESOURCE_UPDATED}. + */ +public class ReloadStringCacheTask extends BaseModelUpdateTask { + private ModelDelegate mModelDelegate; + + public ReloadStringCacheTask(ModelDelegate modelDelegate) { + mModelDelegate = modelDelegate; + } + + @Override + public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList appsList) { + synchronized (dataModel) { + mModelDelegate.loadStringCache(dataModel.stringCache); + StringCache cloneSC = dataModel.stringCache.clone(); + scheduleCallbackTask(c -> c.bindStringCache(cloneSC)); + } + } +} diff --git a/src/com/android/launcher3/model/StringCache.java b/src/com/android/launcher3/model/StringCache.java index 663a46327f..9859ddca28 100644 --- a/src/com/android/launcher3/model/StringCache.java +++ b/src/com/android/launcher3/model/StringCache.java @@ -34,6 +34,11 @@ public class StringCache { private static final String PREFIX = "Launcher."; + /** + * Work folder name. + */ + public static final String WORK_FOLDER_NAME = PREFIX + "WORK_FOLDER_NAME"; + /** * User on-boarding title for work profile apps. */ @@ -90,11 +95,6 @@ public class StringCache { private static final String ALL_APPS_PERSONAL_TAB_ACCESSIBILITY = PREFIX + "ALL_APPS_PERSONAL_TAB_ACCESSIBILITY"; - /** - * Work folder name. - */ - private static final String WORK_FOLDER_NAME = PREFIX + "WORK_FOLDER_NAME"; - /** * Label on widget tab to indicate work app widgets. */ From 8a47d5f95587a5c0ae56f2fc09436f0874c5807c Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 9 May 2022 14:54:10 +0100 Subject: [PATCH 5/7] Avoid logging LAUNCHER_OVERVIEW_GESTURE in 3 button mode - Avoid doLogGesture for app->overview in 3 button mode Bug: 219686410 Test: app -> overveiw in 3 button mode and gesture mode Change-Id: I5e65f9182be0388abfc9b07d5f08c96a3334b7b5 --- .../src/com/android/quickstep/AbsSwipeUpHandler.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 13389c0c09..f60b2253e4 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1177,6 +1177,11 @@ public abstract class AbsSwipeUpHandler, } private void doLogGesture(GestureEndTarget endTarget, @Nullable TaskView targetTask) { + if (mDp == null || !mDp.isGestureMode || mDownPos == null) { + // We probably never received an animation controller, skip logging. + return; + } + StatsLogManager.EventEnum event; switch (endTarget) { case HOME: @@ -1200,11 +1205,6 @@ public abstract class AbsSwipeUpHandler, logger.withItemInfo(targetTask.getItemInfo()); } - DeviceProfile dp = mDp; - if (dp == null || mDownPos == null) { - // We probably never received an animation controller, skip logging. - return; - } int pageIndex = endTarget == LAST_TASK || mRecentsView == null ? LOG_NO_OP_PAGE_INDEX : mRecentsView.getNextPage(); From 52bb52aeb42fcf54797f56a47b2802050619242f Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Mon, 9 May 2022 16:57:33 +0100 Subject: [PATCH 6/7] Remove long press on home button for kids mode. Fix: 229961238 Test: manual Change-Id: Idb50d4e142b1d1b0539a71b7a727d00dc76c6a68 --- .../android/launcher3/taskbar/NavbarButtonsViewController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 349dd0a8f6..e9dcf6a5aa 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -297,6 +297,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT navButtonsLayoutParams.setMarginEnd(navButtonsLayoutParams.getMarginStart()); navButtonsLayoutParams.gravity = Gravity.CENTER; mNavButtonContainer.requestLayout(); + + mHomeButton.setOnLongClickListener(null); } // Animate taskbar background when either.. From f0fd3d8e2ec49bb11596922e26ea436f1eb7e86d Mon Sep 17 00:00:00 2001 From: Becky Qiu Date: Fri, 6 May 2022 16:57:46 -0700 Subject: [PATCH 7/7] [Toast] Fix the NPE in isPersonalTab(). Don't set mUsingTab until replaceRVContainer is done. Bug: 224882720 Test: manual Change-Id: I9ebec067d06df5e890ffe3c90d49f1de51b3b981 --- .../android/launcher3/allapps/BaseAllAppsContainerView.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 4390b5162b..ded65b07bd 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -437,8 +437,12 @@ public abstract class BaseAllAppsContainerView