Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-d1-dev
diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java
index 349dd0a..cbdbdb9 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.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 @@
private BaseDragLayer<TaskbarActivityContext> 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;
@@ -297,6 +300,8 @@
navButtonsLayoutParams.setMarginEnd(navButtonsLayoutParams.getMarginStart());
navButtonsLayoutParams.gravity = Gravity.CENTER;
mNavButtonContainer.requestLayout();
+
+ mHomeButton.setOnLongClickListener(null);
}
// Animate taskbar background when either..
@@ -388,8 +393,7 @@
|| (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 +403,21 @@
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 +521,9 @@
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 +753,17 @@
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 0000000..4651570
--- /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<float[]> 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<float[]> 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 3e2695c..99c59a8 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -182,7 +182,8 @@
*/
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 2be1179..052c695 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -428,6 +428,7 @@
// Switch taskbar and hotseat in last frame
setTaskbarViewVisible(alignment < 1);
+ mControllers.navbarButtonsViewController.updateTaskbarAlignment(alignment);
}
private float getCurrentIconAlignmentRatioBetweenAppAndHome() {
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 13389c0..f60b225 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -1177,6 +1177,11 @@
}
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 @@
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();
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 2565674..54f457d 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -192,6 +192,10 @@
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
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 0000000..929bff3
--- /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<float[]> 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);
+ }
+}
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 4501159..597bc8d 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 @@
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 ee6f51e..5c5c101 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.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 @@
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/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index 5bbc67e..72ca5a7 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -437,8 +437,12 @@
if (showTabs == mUsingTabs && !force) {
return;
}
+
+ // replaceRVcontainer() needs to use both mUsingTabs value to remove the old view AND
+ // showTabs value to create new view. Hence the mUsingTabs new value assignment MUST happen
+ // after this call.
+ replaceRVContainer(showTabs);
mUsingTabs = showTabs;
- replaceRVContainer(mUsingTabs);
mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.MAIN).mRecyclerView);
mAllAppsStore.unregisterIconContainer(mAH.get(AdapterHolder.WORK).mRecyclerView);
diff --git a/src/com/android/launcher3/folder/FolderNameProvider.java b/src/com/android/launcher3/folder/FolderNameProvider.java
index 2b621bd..5021644 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.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 @@
/**
* Generate and rank the suggested Folder names.
*/
+ @WorkerThread
public void getSuggestedFolderName(Context context,
ArrayList<WorkspaceItemInfo> workspaceItemInfos,
FolderNameInfos nameInfos) {
@@ -107,8 +114,7 @@
Set<UserHandle> 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 @@
}
}
+ @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<AppInfo> getAppInfoByPackageName(String packageName) {
if (mAppInfos == null || mAppInfos.isEmpty()) {
return Optional.empty();
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
index e36d4cf..ef9250c 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTaskV2.java
@@ -216,14 +216,15 @@
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<Integer> screens = new ArrayList<>();
diff --git a/src/com/android/launcher3/model/ReloadStringCacheTask.java b/src/com/android/launcher3/model/ReloadStringCacheTask.java
new file mode 100644
index 0000000..f4d4298
--- /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 663a463..9859ddc 100644
--- a/src/com/android/launcher3/model/StringCache.java
+++ b/src/com/android/launcher3/model/StringCache.java
@@ -35,6 +35,11 @@
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.
*/
private static final String WORK_PROFILE_EDU = PREFIX + "WORK_PROFILE_EDU";
@@ -91,11 +96,6 @@
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.
*/
private static final String WIDGETS_WORK_TAB = PREFIX + "WIDGETS_WORK_TAB";