From 05b6d1fb7e88009433500a39e7dc1d0280ab1885 Mon Sep 17 00:00:00 2001 From: Shan Huang Date: Fri, 29 Mar 2024 21:25:23 -0700 Subject: [PATCH 01/20] Generate progress events from app process for app animations. Bug: 261654570 Flag: None Test: atest BackNavigationControllerTest Test: atest OnBackInvokedCallbackGestureTest Test: atest BackAnimationControllerTest Test: atest BackTouchTrackerTest Test: atest WindowOnBackInvokedDispatcherTest Change-Id: I075c099d59012825583fd9beda29a33d00f4d077 --- .../android/quickstep/LauncherBackAnimationController.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 79b09fdbec..225b127d9d 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -220,6 +220,11 @@ public class LauncherBackAnimationController { } }); } + + @Override + public void setTriggerBack(boolean triggerBack) { + // TODO(b/261654570): track touch from the Launcher process. + } } private static class RemoteAnimationRunnerStub extends IRemoteAnimationRunner.Stub { From 86b57551785b7989c91b82a8b5327cad2aa90317 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 8 Apr 2024 15:36:31 -0700 Subject: [PATCH 02/20] Reset allAppsVisible if folding to phone upon recreateTaskbar. For taskbar unification, we should reset this bit to false when folding into phone orientation. Otherwise, we will reinit Taskbar AllApps over the phone UI which is unexpected behavior. Test: Manual Flag: N/A Fix: 293379641 Change-Id: I53c38c8b4df477191be3c21b7750c55a71c7336f (cherry picked from commit 6d63e7796dacadd60bbe1d7a667f0f728decd383) Merged-In: I53c38c8b4df477191be3c21b7750c55a71c7336f --- .../src/com/android/launcher3/taskbar/TaskbarManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index ecbc7e7fdc..65979b4ddc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -473,8 +473,8 @@ public class TaskbarManager { LauncherAppState.getIDP(mContext).getDeviceProfile(mContext) : null; // All Apps action is unrelated to navbar unification, so we only need to check DP. - mAllAppsActionManager.setTaskbarPresent(dp != null && dp.isTaskbarPresent); - + final boolean isLargeScreenTaskbar = dp != null && dp.isTaskbarPresent; + mAllAppsActionManager.setTaskbarPresent(isLargeScreenTaskbar); destroyExistingTaskbar(); boolean isTaskbarEnabled = dp != null && isTaskbarEnabled(dp); @@ -497,6 +497,7 @@ public class TaskbarManager { } mSharedState.startTaskbarVariantIsTransient = DisplayController.isTransientTaskbar(mTaskbarActivityContext); + mSharedState.allAppsVisible = mSharedState.allAppsVisible && isLargeScreenTaskbar; mTaskbarActivityContext.init(mSharedState); if (mActivity != null) { From ea789033808fcc9e3e855f100aeb80ea5bc9da0e Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Mon, 22 Apr 2024 19:35:26 -0700 Subject: [PATCH 03/20] Adding screenrecord to get more information about the test Test: testWorkspace Flag: NA Bug: 331261431 Change-Id: Ifeaa0fe287c2cbf0b9c1c468c494752fe7f35d37 --- .../com/android/launcher3/ui/workspace/TaplWorkspaceTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java index 9afde0db28..490cff20b4 100644 --- a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java +++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java @@ -29,6 +29,7 @@ import com.android.launcher3.tapl.Workspace; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.util.LauncherLayoutBuilder; import com.android.launcher3.util.TestUtil; +import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import org.junit.After; import org.junit.Before; @@ -67,6 +68,7 @@ public class TaplWorkspaceTest extends AbstractLauncherUiTest { * move between workspaces. After, make sure we can launch an app from the Workspace. * @throws Exception if we can't set the defaults icons that will appear at the beginning. */ + @ScreenRecord // b/331261431 @Test public void testWorkspace() throws Exception { // Set workspace that includes the chrome Activity app icon on the hotseat. From ce0f8595b7c2681a5633bcbb9188d5f4aafec0b4 Mon Sep 17 00:00:00 2001 From: helencheuk Date: Wed, 17 Apr 2024 17:27:00 +0100 Subject: [PATCH 04/20] Disable launcher focus outline animation Bug: 335424188 Test: Manual Flag: ACONFIG com.android.launcher3.enable_focus_outline Teamfood Change-Id: I31c63607c914da956d7c6139cc5089fe419f40e1 --- src/com/android/launcher3/PagedView.java | 5 +++- .../keyboard/ItemFocusIndicatorHelper.java | 3 ++- .../keyboard/ViewGroupFocusHelper.java | 23 +++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 1c23644243..cc9f08eadc 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -485,7 +485,10 @@ public abstract class PagedView extends ViewGrou super.onVisibilityAggregated(isVisible); } - protected boolean isPageInTransition() { + /** + * Returns true if the page is in the middle of transition to another page + */ + public boolean isPageInTransition() { return mIsPageInTransition; } diff --git a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java index 456cde8d45..480e8f3e56 100644 --- a/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java +++ b/src/com/android/launcher3/keyboard/ItemFocusIndicatorHelper.java @@ -246,7 +246,8 @@ public abstract class ItemFocusIndicatorHelper implements AnimatorUpdateListe protected void setCurrentItem(T item) { mCurrentItem = item; - mShift = 0; + // Set it to end value directly to skip the animation for outline + mShift = Flags.enableFocusOutline() ? 1 : 0; mTargetItem = null; } diff --git a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java index 4653bf12f3..21d157a41b 100644 --- a/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java +++ b/src/com/android/launcher3/keyboard/ViewGroupFocusHelper.java @@ -19,6 +19,7 @@ package com.android.launcher3.keyboard; import android.graphics.Rect; import android.view.View; +import com.android.launcher3.Flags; import com.android.launcher3.PagedView; /** @@ -34,6 +35,28 @@ public class ViewGroupFocusHelper extends FocusIndicatorHelper { mContainer = container; } + @Override + protected boolean shouldDraw(View item) { + if (Flags.enableFocusOutline()) { + // Not draw outline in page transition because the outline just remains fully + // persistent during the transition and does not look smooth + return super.shouldDraw(item) && !isInPageTransition(item); + } else { + return super.shouldDraw(item); + } + } + + private boolean isInPageTransition(View view) { + if (view == null || !(view.getParent() instanceof View)) { + return false; + } + boolean isInTransition = false; + if (view instanceof PagedView) { + isInTransition = ((PagedView) view).isPageInTransition(); + } + return isInTransition || isInPageTransition((View) view.getParent()); + } + @Override public void viewToRect(View v, Rect outRect) { // Using FocusedRect here allows views to provide their custom rect for drawing outline, From 9188c1b45b6070e6611e2a2cc56bdbda0f488c69 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Sat, 23 Mar 2024 19:35:50 +0000 Subject: [PATCH 05/20] Revert "Hide task bar when folding before the new config renders the correct task bar" This reverts commit dfb334f1e16e35a745d8ff03edc06f3ae14e7cfc. Reason for revert: A bunch of WM fixes are in (b/291562764) Change-Id: I9d08dab976cda112f802ee91256c09ef2026a01f (cherry picked from commit 4dbac6caa9aa8b0bc99100c9c6bb06047ecfa3e6) --- .../taskbar/TaskbarActivityContext.java | 20 ----------- .../taskbar/TaskbarDragLayerController.java | 6 ---- .../launcher3/taskbar/TaskbarManager.java | 33 +------------------ 3 files changed, 1 insertion(+), 58 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index eaee6ce647..53791265ab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -36,14 +36,12 @@ import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN; -import static com.android.launcher3.taskbar.TaskbarDragLayerController.TASKBAR_REAPPEAR_DELAY_MS; import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName; import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_VISIBLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING; import android.animation.AnimatorSet; -import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; @@ -81,7 +79,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; -import com.android.launcher3.anim.AnimatedFloat; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.apppairs.AppPairIcon; import com.android.launcher3.config.FeatureFlags; @@ -1419,23 +1416,6 @@ public class TaskbarActivityContext extends BaseTaskbarContext { }); } - public void hideTaskbarWhenFolding() { - AnimatedFloat alphaAnim = mControllers.taskbarDragLayerController.getTaskbarAlpha(); - alphaAnim.cancelAnimation(); - alphaAnim.updateValue(0); - ObjectAnimator animator = alphaAnim.animateToValue(1).setDuration(0); - animator.setStartDelay(TASKBAR_REAPPEAR_DELAY_MS); - animator.start(); - } - - public void cancelHideTaskbarWhenFolding() { - mControllers.taskbarDragLayerController.getTaskbarAlpha().cancelAnimation(); - } - - public void resetHideTaskbarWhenUnfolding() { - mControllers.taskbarDragLayerController.getTaskbarAlpha().updateValue(1); - } - protected boolean isUserSetupComplete() { return mIsUserSetupComplete; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index e48c20dd61..ff890fb18e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -44,12 +44,6 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa private static final boolean DEBUG = SystemProperties.getBoolean( "persist.debug.draw_taskbar_debug_ui", false); - // Delay to reset the task bar alpha back to 1 after fading it for transition from unfold to - // fold. Normally this is not needed since the new task bar is recreated after fading, but in - // case something goes wrong this provides a fallback mechanism to make sure the task bar is - // visible after the transition finishes. - public static final long TASKBAR_REAPPEAR_DELAY_MS = 2000; - private final TaskbarActivityContext mActivity; private final TaskbarDragLayer mTaskbarDragLayer; private final int mFolderMargin; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index ecbc7e7fdc..e4f9ba5260 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -29,7 +29,6 @@ import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.DisplayController.CHANGE_TASKBAR_PINNING; import static com.android.launcher3.util.DisplayController.TASKBAR_NOT_DESTROYED_TAG; -import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange; import static com.android.quickstep.util.SystemActionConstants.ACTION_SHOW_TASKBAR; @@ -43,7 +42,6 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.res.Configuration; -import android.hardware.devicestate.DeviceStateManager; import android.hardware.display.DisplayManager; import android.net.Uri; import android.os.Handler; @@ -111,7 +109,6 @@ public class TaskbarManager { private final Context mContext; private final @Nullable Context mNavigationBarPanelContext; - private final DeviceStateManager mDeviceStateManager; private WindowManager mWindowManager; private FrameLayout mTaskbarRootLayout; private boolean mAddedWindow; @@ -180,8 +177,7 @@ public class TaskbarManager { } }; - private final UnfoldTransitionProgressProvider.TransitionProgressListener - mUnfoldTransitionProgressListener = + UnfoldTransitionProgressProvider.TransitionProgressListener mUnfoldTransitionProgressListener = new UnfoldTransitionProgressProvider.TransitionProgressListener() { @Override public void onTransitionStarted() { @@ -210,9 +206,6 @@ public class TaskbarManager { } }; - private final DeviceStateManager.FoldStateListener mFoldStateListener; - private Boolean mFolded; - @SuppressLint("WrongConstant") public TaskbarManager( TouchInteractionService service, AllAppsActionManager allAppsActionManager) { @@ -240,29 +233,6 @@ public class TaskbarManager { } }; } - // Temporary solution to mitigate the visual jump from folding the device. Currently, the - // screen turns on much earlier than we receive the onConfigurationChanged callback or - // receiving the correct device profile. While the ideal the solution is to align turning - // the screen on after onConfigurationChanged (by either delaying turning on the screen or - // figuring out what is causing the delay in getting onConfigurationChanged callback), one - // easy temporary mitigation is to dimming the bar so that the visual jump isn't as glaring. - mFoldStateListener = new DeviceStateManager.FoldStateListener(mContext, folded -> { - boolean firstTime = mFolded == null; - if (mTaskbarActivityContext == null) { - return; - } - if (!firstTime && mFolded.booleanValue() != folded) { - mTaskbarActivityContext.cancelHideTaskbarWhenFolding(); - } - mFolded = folded; - if (folded && !firstTime) { - mTaskbarActivityContext.hideTaskbarWhenFolding(); - } else { - mTaskbarActivityContext.resetHideTaskbarWhenUnfolding(); - } - }); - mDeviceStateManager = mContext.getSystemService(DeviceStateManager.class); - mDeviceStateManager.registerCallback(MAIN_EXECUTOR, mFoldStateListener); mNavButtonController = new TaskbarNavButtonController(service, SystemUiProxy.INSTANCE.get(mContext), new Handler(), AssistUtils.newInstance(mContext)); @@ -619,7 +589,6 @@ public class TaskbarManager { Log.d(TASKBAR_NOT_DESTROYED_TAG, "unregistering component callbacks from destroy()."); mContext.unregisterComponentCallbacks(mComponentCallbacks); mContext.unregisterReceiver(mShutdownReceiver); - mDeviceStateManager.unregisterCallback(mFoldStateListener); } public @Nullable TaskbarActivityContext getCurrentActivityContext() { From 944a7a61ec411ac1def013b7cfdb275f0d1921c4 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 24 Apr 2024 17:33:45 +0100 Subject: [PATCH 06/20] Use BaseContainerInterface.getTaskDimension for windowSize in DesktopTaskView - Instead of using widthPx/heightPx, use BaseContainerInterface.getTaskDimension that takes into account of whether Taskbar is persistent or pinned Fix: 336788597 Test: Swipe up from Desktop; press recents button from Desktop Flag: ACONFIG com.android.window.flags.enable_desktop_windowing_mode DEVELOPMENT Change-Id: I04d3b5bbc577ea650f8a9dc45cc6d01bca3f6466 --- .../com/android/quickstep/views/DesktopTaskView.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 964f531df9..87820f2fc5 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -23,6 +23,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import android.content.Context; import android.content.pm.PackageManager; import android.graphics.Point; +import android.graphics.PointF; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; @@ -45,6 +46,7 @@ import com.android.launcher3.desktop.DesktopRecentsTransitionController; import com.android.launcher3.icons.IconProvider; import com.android.launcher3.util.CancellableTask; import com.android.launcher3.util.RunnableList; +import com.android.quickstep.BaseContainerInterface; import com.android.quickstep.RecentsModel; import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.util.RecentsOrientedState; @@ -87,6 +89,8 @@ public class DesktopTaskView extends TaskView { private int mChildCountAtInflation; + private final PointF mTempPointF = new PointF(); + public DesktopTaskView(Context context) { this(context, null); } @@ -431,8 +435,10 @@ public class DesktopTaskView extends TaskView { return; } - int windowWidth = mContainer.getDeviceProfile().widthPx; - int windowHeight = mContainer.getDeviceProfile().heightPx; + BaseContainerInterface.getTaskDimension(mContext, mContainer.getDeviceProfile(), + mTempPointF); + int windowWidth = (int) mTempPointF.x; + int windowHeight = (int) mTempPointF.y; float scaleWidth = containerWidth / (float) windowWidth; float scaleHeight = containerHeight / (float) windowHeight; From 430fdee946da7a7e5b0318b487072c0bca41ab73 Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Wed, 17 Apr 2024 12:48:34 -0700 Subject: [PATCH 07/20] [omni] Read haptic bit from AGSA. Bug: 335475048 Flag: legacy OVERRIDE_LPNH_LPH_THRESHOLDS disabled Test: manual Change-Id: I8e4ebd9f7faecc236763db367be63cc47e7c0e31 --- quickstep/src/com/android/quickstep/SystemUiProxy.java | 5 +++-- .../com/android/quickstep/util/AssistStateManager.java | 10 +++++----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index ab9840f645..b0b25897ad 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -460,10 +460,11 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { } @Override - public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier) { + public void setOverrideHomeButtonLongPress(long duration, float slopMultiplier, + boolean haptic) { if (mSystemUiProxy != null) { try { - mSystemUiProxy.setOverrideHomeButtonLongPress(duration, slopMultiplier); + mSystemUiProxy.setOverrideHomeButtonLongPress(duration, slopMultiplier, haptic); } catch (RemoteException e) { Log.w(TAG, "Failed call setOverrideHomeButtonLongPress", e); } diff --git a/quickstep/src/com/android/quickstep/util/AssistStateManager.java b/quickstep/src/com/android/quickstep/util/AssistStateManager.java index 4a35c3b947..42db65fbe4 100644 --- a/quickstep/src/com/android/quickstep/util/AssistStateManager.java +++ b/quickstep/src/com/android/quickstep/util/AssistStateManager.java @@ -33,11 +33,6 @@ public class AssistStateManager implements ResourceBasedOverride, SafeCloseable public AssistStateManager() {} - /** Whether search supports haptic on invocation. */ - public boolean supportsCommitHaptic() { - return false; - } - /** Whether search is available. */ public boolean isSearchAvailable() { return false; @@ -90,6 +85,11 @@ public class AssistStateManager implements ResourceBasedOverride, SafeCloseable return 0; } + /** Get the haptic bit overridden by AGSA. */ + public Optional getShouldPlayHapticOverride() { + return Optional.empty(); + } + /** Return {@code true} if the Settings toggle is enabled. */ public boolean isSettingsAllEntrypointsEnabled() { return false; From e0d81cb35197fa95c085f0c2766074232103b4d8 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 24 Apr 2024 09:50:58 -0700 Subject: [PATCH 08/20] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Iec1f86e7d253eef8d040c6e257d1704b9b1dbc19 --- quickstep/res/values-af/strings.xml | 2 ++ quickstep/res/values-am/strings.xml | 2 ++ quickstep/res/values-ar/strings.xml | 2 ++ quickstep/res/values-as/strings.xml | 2 ++ quickstep/res/values-az/strings.xml | 2 ++ quickstep/res/values-b+sr+Latn/strings.xml | 2 ++ quickstep/res/values-be/strings.xml | 5 +++-- quickstep/res/values-bg/strings.xml | 5 +++-- quickstep/res/values-bn/strings.xml | 5 +++-- quickstep/res/values-bs/strings.xml | 5 +++-- quickstep/res/values-ca/strings.xml | 2 ++ quickstep/res/values-cs/strings.xml | 2 ++ quickstep/res/values-da/strings.xml | 5 +++-- quickstep/res/values-de/strings.xml | 5 +++-- quickstep/res/values-el/strings.xml | 2 ++ quickstep/res/values-en-rAU/strings.xml | 2 ++ quickstep/res/values-en-rCA/strings.xml | 1 + quickstep/res/values-en-rGB/strings.xml | 2 ++ quickstep/res/values-en-rIN/strings.xml | 2 ++ quickstep/res/values-en-rXC/strings.xml | 1 + quickstep/res/values-es-rUS/strings.xml | 5 +++-- quickstep/res/values-es/strings.xml | 5 +++-- quickstep/res/values-et/strings.xml | 5 +++-- quickstep/res/values-eu/strings.xml | 5 +++-- quickstep/res/values-fa/strings.xml | 2 ++ quickstep/res/values-fi/strings.xml | 5 +++-- quickstep/res/values-fr-rCA/strings.xml | 2 ++ quickstep/res/values-fr/strings.xml | 2 ++ quickstep/res/values-gl/strings.xml | 5 +++-- quickstep/res/values-gu/strings.xml | 5 +++-- quickstep/res/values-hi/strings.xml | 5 +++-- quickstep/res/values-hr/strings.xml | 5 +++-- quickstep/res/values-hu/strings.xml | 2 ++ quickstep/res/values-hy/strings.xml | 5 +++-- quickstep/res/values-in/strings.xml | 2 ++ quickstep/res/values-is/strings.xml | 2 ++ quickstep/res/values-it/strings.xml | 2 ++ quickstep/res/values-iw/strings.xml | 2 ++ quickstep/res/values-ja/strings.xml | 2 ++ quickstep/res/values-ka/strings.xml | 2 ++ quickstep/res/values-kk/strings.xml | 5 +++-- quickstep/res/values-km/strings.xml | 2 ++ quickstep/res/values-kn/strings.xml | 2 ++ quickstep/res/values-ko/strings.xml | 5 +++-- quickstep/res/values-ky/strings.xml | 5 +++-- quickstep/res/values-lo/strings.xml | 2 ++ quickstep/res/values-lt/strings.xml | 2 ++ quickstep/res/values-lv/strings.xml | 5 +++-- quickstep/res/values-mk/strings.xml | 5 +++-- quickstep/res/values-ml/strings.xml | 2 ++ quickstep/res/values-mn/strings.xml | 5 +++-- quickstep/res/values-mr/strings.xml | 2 ++ quickstep/res/values-ms/strings.xml | 2 ++ quickstep/res/values-my/strings.xml | 5 +++-- quickstep/res/values-nb/strings.xml | 2 ++ quickstep/res/values-ne/strings.xml | 2 ++ quickstep/res/values-nl/strings.xml | 5 +++-- quickstep/res/values-or/strings.xml | 5 +++-- quickstep/res/values-pa/strings.xml | 2 ++ quickstep/res/values-pl/strings.xml | 2 ++ quickstep/res/values-pt-rPT/strings.xml | 2 ++ quickstep/res/values-pt/strings.xml | 5 +++-- quickstep/res/values-ro/strings.xml | 5 +++-- quickstep/res/values-ru/strings.xml | 2 ++ quickstep/res/values-si/strings.xml | 2 ++ quickstep/res/values-sk/strings.xml | 2 ++ quickstep/res/values-sl/strings.xml | 5 +++-- quickstep/res/values-sq/strings.xml | 5 +++-- quickstep/res/values-sr/strings.xml | 2 ++ quickstep/res/values-sv/strings.xml | 5 +++-- quickstep/res/values-sw/strings.xml | 2 ++ quickstep/res/values-ta/strings.xml | 5 +++-- quickstep/res/values-te/strings.xml | 2 ++ quickstep/res/values-th/strings.xml | 2 ++ quickstep/res/values-tl/strings.xml | 5 +++-- quickstep/res/values-tr/strings.xml | 5 +++-- quickstep/res/values-uk/strings.xml | 5 +++-- quickstep/res/values-ur/strings.xml | 2 ++ quickstep/res/values-uz/strings.xml | 2 ++ quickstep/res/values-vi/strings.xml | 5 +++-- quickstep/res/values-zh-rCN/strings.xml | 5 +++-- quickstep/res/values-zh-rHK/strings.xml | 4 +++- quickstep/res/values-zh-rTW/strings.xml | 2 ++ quickstep/res/values-zu/strings.xml | 2 ++ 84 files changed, 203 insertions(+), 73 deletions(-) diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml index 6a749d1ecb..ab1dd78297 100644 --- a/quickstep/res/values-af/strings.xml +++ b/quickstep/res/values-af/strings.xml @@ -138,6 +138,8 @@ "Skuif na links bo" "Skuif na regs onder" "{count,plural, =1{Wys nog # app.}other{Wys nog # apps.}}" + + "%1$s en %2$s" "Voeg nou app by werkskerm" "Kanselleer" diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 500cc3d46f..e7fe0fa6da 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -138,6 +138,8 @@ "ወደ ላይ/ግራ ይውሰዱ" "ወደ ታች/ቀኝ ይውሰዱ" "{count,plural, =1{ተጨማሪ # መተግበሪያ አሳይ።}one{ተጨማሪ # መተግበሪያ አሳይ።}other{ተጨማሪ # መተግበሪያዎች አሳይ።}}" + + "%1$s እና %2$s" "መተግበሪያን ወደ ዴስክቶፕ በማከል ላይ" "ይቅር" diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml index de2c8b1df2..e98fc2ffbf 100644 --- a/quickstep/res/values-ar/strings.xml +++ b/quickstep/res/values-ar/strings.xml @@ -138,6 +138,8 @@ "الانتقال إلى يمين الشاشة أو أعلاها" "الانتقال إلى يسار الشاشة أو أسفلها" "{count,plural, =1{إظهار تطبيق واحد آخر}zero{إظهار # تطبيق آخر}two{إظهار تطبيقَين آخرَين}few{إظهار # تطبيقات أخرى}many{إظهار # تطبيقًا آخر}other{إظهار # تطبيق آخر}}" + + "\"%1$s\" و\"%2$s\"" "إضافة تطبيق إلى سطح المكتب" "إلغاء" diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index c483fb1b49..9b75dad3a4 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -138,6 +138,8 @@ "ওপৰৰ বাঁওফাললৈ নিয়ক" "তলৰ সোঁফাললৈ নিয়ক" "{count,plural, =1{আৰু # টা এপ্‌ দেখুৱাওক।}one{আৰু # টা এপ্‌ দেখুৱাওক।}other{আৰু # টা এপ্‌ দেখুৱাওক।}}" + + "%1$s আৰু %2$s" "ডেস্কটপত এপ্ যোগ দি থকা হৈছে" "বাতিল কৰক" diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml index 1500e827a4..25a0fc8578 100644 --- a/quickstep/res/values-az/strings.xml +++ b/quickstep/res/values-az/strings.xml @@ -138,6 +138,8 @@ "Yuxarı/sola köçürün" "Aşağı/sağa köçürün" "{count,plural, =1{Daha # tətbiqi göstərin.}other{Daha # tətbiqi göstərin.}}" + + "%1$s%2$s" "Tətbiqin masaüstünə əlavə edilməsi" "Ləğv edin" diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index 9529776233..aaa7d8c50a 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -138,6 +138,8 @@ "Premesti gore levo" "Premesti dole desno" "{count,plural, =1{Prikaži još # aplikaciju.}one{Prikaži još # aplikaciju.}few{Prikaži još # aplikacije.}other{Prikaži još # aplikacija.}}" + + "%1$s i %2$s" "Dodaje se aplikacija na radnu povrršinu" "Otkaži" diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index 6b20866e58..4d65ecd52e 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Замацаваць" "Адвольная форма" - - + "Працоўны стол" "Няма новых элементаў" "Налады выкарыстання праграмы" "Ачысціць усё" @@ -139,6 +138,8 @@ "Перамясціць уверх/улева" "Перамясціць уніз/управа" "{count,plural, =1{Паказаць ячшэ # праграму.}one{Паказаць ячшэ # праграму.}few{Паказаць ячшэ # праграмы.}many{Паказаць ячшэ # праграм.}other{Паказаць ячшэ # праграмы.}}" + + "%1$s і %2$s" "Дадаванне праграмы на камп\'ютар" "Скасаваць" diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml index 8631d8b292..bf42a231ce 100644 --- a/quickstep/res/values-bg/strings.xml +++ b/quickstep/res/values-bg/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Фиксиране" "Свободна форма" - - + "За компютър" "Няма скорошни елементи" "Настройки за използването на приложенията" "Изчистване на всички" @@ -139,6 +138,8 @@ "Преместване горе/вляво" "Преместване долу/вдясно" "{count,plural, =1{Показване на още # приложение.}other{Показване на още # приложения.}}" + + "%1$s и %2$s" "Приложението се добавя на настолния компютър" "Отказ" diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml index 948d07de94..89a5e76d21 100644 --- a/quickstep/res/values-bn/strings.xml +++ b/quickstep/res/values-bn/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "পিন করুন" "ফ্রি-ফর্ম" - - + "ডেস্কটপ" "কোনও সাম্প্রতিক আইটেম নেই" "অ্যাপ ব্যবহারের সেটিংস" "সবকিছু খালি করুন" @@ -139,6 +138,8 @@ "উপরে/বাঁদিকে সরান" "নিচে/ডানদিকে সরান" "{count,plural, =1{আরও #টি অ্যাপ দেখুন।}one{আরও #টি অ্যাপ দেখুন।}other{আরও #টি অ্যাপ দেখুন।}}" + + "%1$s%2$s" "ডেস্কটপে অ্যাপ যোগ করা হচ্ছে" "বাতিল করুন" diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index 15da445547..059c14cf00 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Zakači" "Slobodan oblik" - - + "Radna površina" "Nema nedavnih stavki" "Postavke korištenja aplikacije" "Obriši sve" @@ -139,6 +138,8 @@ "Premjesti gore lijevo" "Premjesti dolje desno" "{count,plural, =1{Prikaži još # aplikaciju.}one{Prikaži još # aplikaciju.}few{Prikaži još # aplikacije.}other{Prikaži još # aplikacija.}}" + + "%1$s i %2$s" "Dodavanje aplikacije na radnu površinu" "Otkaži" diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml index 62ae01b48d..f2118ebe9f 100644 --- a/quickstep/res/values-ca/strings.xml +++ b/quickstep/res/values-ca/strings.xml @@ -138,6 +138,8 @@ "Mou a la part superior o a l\'esquerra" "Mou a la part inferior o a la dreta" "{count,plural, =1{Mostra # aplicació més.}other{Mostra # aplicacions més.}}" + + "%1$s i %2$s" "S\'està afegint l\'aplicació a l\'ordinador" "Cancel·la" diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml index a07ffc568c..0771ace367 100644 --- a/quickstep/res/values-cs/strings.xml +++ b/quickstep/res/values-cs/strings.xml @@ -138,6 +138,8 @@ "Přesunout doleva nahoru" "Přesunout doprava dolů" "{count,plural, =1{Zobrazit # další aplikaci.}few{Zobrazit # další aplikace.}many{Zobrazit # další aplikace.}other{Zobrazit # dalších aplikací.}}" + + "%1$s%2$s" "Přidání aplikace na plochu" "Zrušit" diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml index a1ca3c5ef4..a805762e8a 100644 --- a/quickstep/res/values-da/strings.xml +++ b/quickstep/res/values-da/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fastgør" "Frit format" - - + "Computertilstand" "Ingen nye elementer" "Indstillinger for appforbrug" "Ryd alt" @@ -139,6 +138,8 @@ "Flyt til toppen eller venstre side" "Flyt til bunden eller højre side" "{count,plural, =1{Vis # app mere.}one{Vis # app mere.}other{Vis # apps mere.}}" + + "%1$s og %2$s" "Appen føjes til computeren" "Annuller" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 73c3f04821..b1ce2d5be6 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fixieren" "Freeform-Modus" - - + "Desktopmodus" "Keine kürzlich verwendeten Elemente" "Einstellungen zur App-Nutzung" "Alle Apps schließen" @@ -139,6 +138,8 @@ "Nach oben / Nach links verschieben" "Nach unten / Nach rechts verschieben" "{count,plural, =1{# weitere App anzeigen}other{# weitere Apps anzeigen}}" + + "%1$s und %2$s" "Hinzufügen einer App zum Desktop" "Abbrechen" diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml index 55e535b149..030d834e9e 100644 --- a/quickstep/res/values-el/strings.xml +++ b/quickstep/res/values-el/strings.xml @@ -138,6 +138,8 @@ "Μετακίνηση επάνω/αριστερά" "Μετακίνηση κάτω/δεξιά" "{count,plural, =1{Εμφάνιση # ακόμα εφαρμογής.}other{Εμφάνιση # ακόμα εφαρμογών.}}" + + "%1$s και %2$s" "Γίνεται προσθήκη εφαρμογής στον υπολογιστή" "Ακύρωση" diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml index 64c68e05cc..a083fa4af3 100644 --- a/quickstep/res/values-en-rAU/strings.xml +++ b/quickstep/res/values-en-rAU/strings.xml @@ -138,6 +138,8 @@ "Move to top/left" "Move to bottom/right" "{count,plural, =1{Show # more app.}other{Show # more apps.}}" + + "%1$s and %2$s" "Adding app to desktop" "Cancel" diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml index 4daaa90be4..cadf7eedf7 100644 --- a/quickstep/res/values-en-rCA/strings.xml +++ b/quickstep/res/values-en-rCA/strings.xml @@ -138,6 +138,7 @@ "Move to top/left" "Move to bottom/right" "{count,plural, =1{Show # more app.}other{Show # more apps.}}" + "{count,plural, =1{Show # desktop app.}other{Show # desktop apps.}}" "%1$s and %2$s" "Adding app to Desktop" "Cancel" diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml index 64c68e05cc..a083fa4af3 100644 --- a/quickstep/res/values-en-rGB/strings.xml +++ b/quickstep/res/values-en-rGB/strings.xml @@ -138,6 +138,8 @@ "Move to top/left" "Move to bottom/right" "{count,plural, =1{Show # more app.}other{Show # more apps.}}" + + "%1$s and %2$s" "Adding app to desktop" "Cancel" diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml index 64c68e05cc..a083fa4af3 100644 --- a/quickstep/res/values-en-rIN/strings.xml +++ b/quickstep/res/values-en-rIN/strings.xml @@ -138,6 +138,8 @@ "Move to top/left" "Move to bottom/right" "{count,plural, =1{Show # more app.}other{Show # more apps.}}" + + "%1$s and %2$s" "Adding app to desktop" "Cancel" diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml index 19e6aa0255..7f1aa13760 100644 --- a/quickstep/res/values-en-rXC/strings.xml +++ b/quickstep/res/values-en-rXC/strings.xml @@ -138,6 +138,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎Move to top/left‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎Move to bottom/right‎‏‎‎‏‎" "{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎Show # more app.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‎‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‎‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎Show # more apps.‎‏‎‎‏‎}}" + "{count,plural, =1{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎Show # desktop app.‎‏‎‎‏‎}other{‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‏‎‎‎‏‎‏‏‏‏‏‏‎‎‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‏‏‎‏‏‏‏‎‎‎‎Show # desktop apps.‎‏‎‎‏‎}}" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‏‏‎‎‏‎‎‎‎‏‏‏‎‎‎‎‏‏‏‏‎‎‏‎‏‎‏‏‎‏‎‎‎‏‏‏‏‏‏‎‎‎‎‎‏‎‎‎‎‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ and ‎‏‎‎‏‏‎%2$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‎‏‎‏‎‏‏‎‎‎‏‏‏‎‎‏‏‎‏‎‎‏‏‎‏‎‎‎‎‎‎‏‎‏‏‏‎‎Adding app to Desktop‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‎‏‎‏‎‎‎‏‎‏‎‏‎‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎Cancel‎‏‎‎‏‎" diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml index aa568f39f9..0a92029deb 100644 --- a/quickstep/res/values-es-rUS/strings.xml +++ b/quickstep/res/values-es-rUS/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fijar" "Formato libre" - - + "Escritorio" "No hay elementos recientes" "Configuración de uso de la app" "Cerrar todo" @@ -139,6 +138,8 @@ "Mover a la parte superior o izquierda" "Mover a la parte inferior o derecha" "{count,plural, =1{Mostrar # app más.}other{Mostrar # apps más.}}" + + "%1$s y %2$s" "Agregando app al escritorio" "Cancelar" diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index 27eceb8bed..0d1ebe09ea 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fijar" "Formato libre" - - + "Ordenador" "No hay nada reciente" "Ajustes de uso de la aplicación" "Borrar todo" @@ -139,6 +138,8 @@ "Mover arriba/a la izquierda" "Mover abajo/a la derecha" "{count,plural, =1{Mostrar # aplicación más.}other{Mostrar # aplicaciones más.}}" + + "%1$s y %2$s" "Añadiendo aplicación al ordenador" "Cancelar" diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml index bffce79a27..77529cb1e9 100644 --- a/quickstep/res/values-et/strings.xml +++ b/quickstep/res/values-et/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Kinnita" "Vabavorm" - - + "Lauaarvuti režiim" "Hiljutisi üksusi pole" "Rakenduse kasutuse seaded" "Sule kõik" @@ -139,6 +138,8 @@ "Teisalda üles/vasakule" "Teisalda alla/paremale" "{count,plural, =1{Kuva veel # rakendus.}other{Kuva veel # rakendust.}}" + + "%1$s ja %2$s" "Rakenduse lisamine arvutisse" "Tühista" diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index 39fc48974d..8a504ec077 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Ainguratu" "Modu librea" - - + "Ordenagailua" "Ez dago azkenaldi honetako ezer" "Aplikazioen erabileraren ezarpenak" "Garbitu guztiak" @@ -139,6 +138,8 @@ "Eraman gora, ezkerretara" "Eraman behera, eskuinetara" "{count,plural, =1{Erakutsi beste # aplikazio.}other{Erakutsi beste # aplikazio.}}" + + "%1$s eta %2$s" "Aplikazioa mahaigainean gehitzen" "Utzi" diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index a3e5b7fc0e..814104509a 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -138,6 +138,8 @@ "انتقال به بالا/ چپ" "انتقال به پایین/ راست" "{count,plural, =1{نمایش # برنامه دیگر.}one{نمایش # برنامه دیگر.}other{نمایش # برنامه دیگر.}}" + + "%1$s و %2$s" "درحال افزودن برنامه به رایانه" "لغو" diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml index 40c4fc270d..18331a29d2 100644 --- a/quickstep/res/values-fi/strings.xml +++ b/quickstep/res/values-fi/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Kiinnitä" "Vapaamuotoinen" - - + "Tietokone" "Ei viimeaikaisia kohteita" "Sovelluksen käyttöasetukset" "Poista kaikki" @@ -139,6 +138,8 @@ "Siirrä ylös tai vasemmalle" "Siirrä alas tai oikealle" "{count,plural, =1{Näytä # muu sovellus.}other{Näytä # muuta sovellusta.}}" + + "%1$s ja %2$s" "Sovelluksen lisääminen työpöydälle" "Peru" diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml index 10aa359098..467a72a766 100644 --- a/quickstep/res/values-fr-rCA/strings.xml +++ b/quickstep/res/values-fr-rCA/strings.xml @@ -138,6 +138,8 @@ "Déplacer vers le coin supérieur gauche de l\'écran" "Déplacer vers le coin inférieur droit de l\'écran" "{count,plural, =1{Afficher # autre application.}one{Afficher # autre application.}other{Afficher # autres applications.}}" + + "%1$s et %2$s" "Ajout de l\'application au bureau en cours…" "Annuler" diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 457d425b20..20b9bab218 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -138,6 +138,8 @@ "Déplacer en haut ou à gauche" "Déplacer en bas ou à droite" "{count,plural, =1{Afficher # autre appli}one{Afficher # autre appli}other{Afficher # autre applis}}" + + "%1$s et %2$s" "Ajout de l\'appli au bureau" "Annuler" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index 0be8958eb7..71ebcf7ca0 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fixar" "Forma libre" - - + "Escritorio" "Non hai elementos recentes" "Configuración do uso de aplicacións" "Borrar todo" @@ -139,6 +138,8 @@ "Mover á parte superior ou á esquerda" "Mover á parte inferior ou á dereita" "{count,plural, =1{Mostrar # aplicación máis.}other{Mostrar # aplicacións máis.}}" + + "%1$s e %2$s" "Engadindo aplicación ao ordenador" "Cancelar" diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml index 644240aaad..cb3c03f901 100644 --- a/quickstep/res/values-gu/strings.xml +++ b/quickstep/res/values-gu/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "પિન કરો" "ફ્રિફોર્મ" - - + "ડેસ્કટૉપ" "તાજેતરની કોઈ આઇટમ નથી" "ઍપ વપરાશનું સેટિંગ" "બધું સાફ કરો" @@ -139,6 +138,8 @@ "સૌથી ઉપર ડાબી બાજુએ ખસેડો" "સૌથી નીચે જમણી બાજુએ ખસેડો" "{count,plural, =1{વધુ # ઍપ બતાવો.}one{વધુ # ઍપ બતાવો.}other{વધુ # ઍપ બતાવો.}}" + + "%1$s અને %2$s" "ડેસ્કટૉપ પર ઍપ ઉમેરી રહ્યાં છીએ" "રદ કરો" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index b2da5dba7d..ebe7d89133 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "पिन करें" "फ़्रीफ़ॉर्म" - - + "डेस्कटॉप" "हाल ही का कोई आइटम नहीं है" "ऐप्लिकेशन इस्तेमाल की सेटिंग" "सभी हटाएं" @@ -139,6 +138,8 @@ "ऊपर/बाईं तरफ़ ले जाएं" "नीचे/दाईं तरफ़ ले जाएं" "{count,plural, =1{# और ऐप्लिकेशन दिखाएं.}one{# और ऐप्लिकेशन दिखाएं.}other{# और ऐप्लिकेशन दिखाएं.}}" + + "%1$s और %2$s" "डेस्कटॉप पर ऐप्लिकेशन जोड़ा जा रहा है" "रद्द करें" diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index b68d9611cf..a8875ad1da 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Prikvači" "Slobodni oblik" - - + "Računalo" "Nema nedavnih stavki" "Postavke upotrebe aplikacija" "Izbriši sve" @@ -139,6 +138,8 @@ "Premjesti gore/lijevo" "Premjesti dolje/desno" "{count,plural, =1{Prikaži još # aplikaciju}one{Prikaži još # aplikaciju}few{Prikaži još # aplikacije}other{Prikaži još # aplikacija}}" + + "%1$s i %2$s" "Dodavanje aplikacije na radnu površinu" "Odustani" diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml index 006184b713..4650f4d606 100644 --- a/quickstep/res/values-hu/strings.xml +++ b/quickstep/res/values-hu/strings.xml @@ -138,6 +138,8 @@ "Mozgatás felülre vagy a bal oldalra" "Mozgatás alulra vagy a jobb oldalra" "{count,plural, =1{# további alkalmazás megjelenítése.}other{# további alkalmazás megjelenítése.}}" + + "%1$s és %2$s" "Alkalmazás hozzáadása az asztalhoz" "Mégse" diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml index e0646aa972..04049a9c6c 100644 --- a/quickstep/res/values-hy/strings.xml +++ b/quickstep/res/values-hy/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Ամրացնել" "Կամայական ձև" - - + "Համակարգիչ" "Այստեղ դեռ ոչինչ չկա" "Հավելվածի օգտագործման կարգավորումներ" "Փակել բոլորը" @@ -139,6 +138,8 @@ "Տեղափոխել վերևի ձախ անկյուն" "Տեղափոխել ներքևի աջ անկյուն" "{count,plural, =1{Ցուցադրել ևս # հավելված։}one{Ցուցադրել ևս # հավելված։}other{Ցուցադրել ևս # հավելված։}}" + + "%1$s և %2$s" "Հավելվածն ավելացվում է աշխատասեղանին" "Չեղարկել" diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml index 34a8b2ba95..833a568497 100644 --- a/quickstep/res/values-in/strings.xml +++ b/quickstep/res/values-in/strings.xml @@ -138,6 +138,8 @@ "Pindahkan ke atas/kiri" "Pindahkan ke bawah/kanan" "{count,plural, =1{Tampilkan # aplikasi lainnya.}other{Tampilkan # aplikasi lainnya.}}" + + "%1$s dan %2$s" "Menambahkan aplikasi ke Desktop" "Batalkan" diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index d5f24880bb..5d3693db18 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -138,6 +138,8 @@ "Færa efst/til vinstri" "Færa neðst/til hægri" "{count,plural, =1{Sýna # forrit í viðbót.}one{Sýna # forrit í viðbót.}other{Sýna # forrit í viðbót.}}" + + "%1$s og %2$s" "Forriti bætt við skjáborð" "Hætta við" diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml index c38243f124..a9391f6949 100644 --- a/quickstep/res/values-it/strings.xml +++ b/quickstep/res/values-it/strings.xml @@ -138,6 +138,8 @@ "Sposta in alto/a sinistra" "Sposta in basso/a destra" "{count,plural, =1{Mostra # altra app.}other{Mostra altre # app.}}" + + "%1$s e %2$s" "Aggiunta app a desktop in corso…" "Annulla" diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml index 9d6b246083..7514ba1bfe 100644 --- a/quickstep/res/values-iw/strings.xml +++ b/quickstep/res/values-iw/strings.xml @@ -138,6 +138,8 @@ "העברה לפינה השמאלית/העליונה" "העברה לפינה הימנית/התחתונה" "{count,plural, =1{הצגת אפליקציה אחת (#) נוספת.}one{הצגת # אפליקציות נוספות.}two{הצגת # אפליקציות נוספות.}other{הצגת # אפליקציות נוספות.}}" + + "%1$s ו-%2$s" "האפליקציה מתווספת לשולחן העבודה" "ביטול" diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 69b39547da..0cc9f89e9f 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -138,6 +138,8 @@ "上 / 左に移動" "下 / 右に移動" "{count,plural, =1{他 # 件のアプリを表示できます。}other{他 # 件のアプリを表示できます。}}" + + "%1$s%2$s" "アプリをデスクトップに追加する" "キャンセル" diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index 4306f1fc5f..d24a698dde 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -138,6 +138,8 @@ "ზემოთ/მარცხნივ გადატანა" "ქვემოთ/მარჯვნივ გადატანა" "{count,plural, =1{#-ით მეტი აპის ჩენება}other{#-ით მეტი აპის ჩვენება.}}" + + "%1$s და %2$s" "მიმდინარეობს აპის დესკტოპზე დამატება" "გაუქმება" diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index 2a124526ae..5073a3fe12 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Бекіту" "Еркін форма" - - + "Компьютер" "Соңғы элементтер жоқ" "Қолданбаны пайдалану параметрлері" "Барлығын өшіру" @@ -139,6 +138,8 @@ "Жоғары/солға жылжыту" "Төмен/оңға жылжыту" "{count,plural, =1{Тағы # қолданбаны көрсету.}other{Тағы # қолданбаны көрсету.}}" + + "%1$s және %2$s" "Жұмыс үстеліне қолданба қосу" "Бас тарту" diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index bcec9558ad..0d9aa52e1b 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -138,6 +138,8 @@ "ផ្លាស់ទីទៅខាងលើ/ឆ្វេង" "ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ" "{count,plural, =1{បង្ហាញកម្មវិធី # ទៀត។}other{បង្ហាញ​កម្មវិធី # ទៀត។}}" + + "%1$s និង %2$s" "កំពុងបញ្ចូល​កម្មវិធីទៅកុំព្យូទ័រ" "បោះបង់" diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml index 4df7f3abfc..e4ff655728 100644 --- a/quickstep/res/values-kn/strings.xml +++ b/quickstep/res/values-kn/strings.xml @@ -138,6 +138,8 @@ "ಮೇಲಿನ/ಎಡಭಾಗಕ್ಕೆ ಸರಿಸಿ" "ಕೆಳಗಿನ/ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ" "{count,plural, =1{ಇನ್ನೂ # ಆ್ಯಪ್ ಅನ್ನು ತೋರಿಸಿ.}one{ಇನ್ನೂ # ಆ್ಯಪ್‌ಗಳನ್ನು ತೋರಿಸಿ.}other{ಇನ್ನೂ # ಆ್ಯಪ್‌ಗಳನ್ನು ತೋರಿಸಿ.}}" + + "%1$s ಮತ್ತು %2$s" "ಡೆಸ್ಕ್‌ಟಾಪ್‌ಗೆ ಆ್ಯಪ್ ಅನ್ನು ಸೇರಿಸಲಾಗುತ್ತಿದೆ" "ರದ್ದುಮಾಡಿ" diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml index 0fba87d103..90486bde4d 100644 --- a/quickstep/res/values-ko/strings.xml +++ b/quickstep/res/values-ko/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "고정" "자유 형식" - - + "데스크톱" "최근 항목이 없습니다." "앱 사용 설정" "모두 삭제" @@ -139,6 +138,8 @@ "상단/왼쪽으로 이동" "하단/오른쪽으로 이동" "{count,plural, =1{앱 #개 더 표시}other{앱 #개 더 표시}}" + + "%1$s%2$s" "데스크톱에 앱 추가하기" "취소" diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index 061952c953..00573c38b0 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Кадап коюу" "Эркин форма режими" - - + "Компьютер" "Акыркы колдонмолор жок" "Колдонмону пайдалануу параметрлери" "Баарын тазалоо" @@ -139,6 +138,8 @@ "Жогорку/сол бурчка жылдыруу" "Төмөнкү/оң бурчка жылдыруу" "{count,plural, =1{Дагы # колдонмону көрсөтүү.}other{Дагы # колдонмону көрсөтүү.}}" + + "%1$s жана %2$s" "Колдонмону иш тактага кошуу" "Жокко чыгаруу" diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml index 9496dd53ea..c2ec34fb9d 100644 --- a/quickstep/res/values-lo/strings.xml +++ b/quickstep/res/values-lo/strings.xml @@ -138,6 +138,8 @@ "ຍ້າຍໄປຊ້າຍ/ເທິງ" "ຍ້າຍໄປຂວາ/ລຸ່ມ" "{count,plural, =1{ສະແດງອີກ # ແອັບ.}other{ສະແດງອີກ # ແອັບ.}}" + + "%1$s ແລະ %2$s" "ການເພີ່ມແອັບໄປໃສ່ເດັສທັອບ" "ຍົກເລີກ" diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index 47c36707e4..a4ca18787a 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -138,6 +138,8 @@ "Perkelti aukštyn, kairėn" "Perkelti žemyn, dešinėn" "{count,plural, =1{Rodyti dar # programą.}one{Rodyti dar # programą.}few{Rodyti dar # programas.}many{Rodyti dar # programos.}other{Rodyti dar # programų.}}" + + "„%1$s“ ir „%2$s“" "Pridedama programa prie darbalaukio" "Atšaukti" diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml index 276120bd57..7fef8806b7 100644 --- a/quickstep/res/values-lv/strings.xml +++ b/quickstep/res/values-lv/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Piespraust" "Brīva forma" - - + "Dators" "Nav nesenu vienumu." "Lietotņu izmantošanas iestatījumi" "Notīrīt visu" @@ -139,6 +138,8 @@ "Pārvietot uz augšējo/kreiso stūri" "Pārvietot uz apakšējo/labo stūri" "{count,plural, =1{Rādīt vēl # lietotni}zero{Rādīt vēl # lietotnes}one{Rādīt vēl # lietotni}other{Rādīt vēl # lietotnes}}" + + "“%1$s” un “%2$s”" "Notiek lietotnes pievienošana datoram" "Atcelt" diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml index 539448d87c..832bd74b3b 100644 --- a/quickstep/res/values-mk/strings.xml +++ b/quickstep/res/values-mk/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Закачи" "Freeform" - - + "Компјутер" "Нема неодамнешни ставки" "Поставки за користење на апликациите" "Избриши ги сите" @@ -139,6 +138,8 @@ "Премести горе лево" "Премести долу десно" "{count,plural, =1{Прикажи уште # апликација.}one{Прикажи уште # апликација.}other{Прикажи уште # апликации.}}" + + "%1$s и %2$s" "Додавање на апликацијата во „Работна површина“" "Откажи" diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml index 90ceeffc26..6432438130 100644 --- a/quickstep/res/values-ml/strings.xml +++ b/quickstep/res/values-ml/strings.xml @@ -138,6 +138,8 @@ "മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക" "താഴേക്കോ വലത്തേക്കോ നീക്കുക" "{count,plural, =1{# ആപ്പ് കൂടി കാണിക്കുക.}other{# ആപ്പുകൾ കൂടി കാണിക്കുക.}}" + + "%1$s, %2$s" "ആപ്പ് ഡെസ്ക്ടോപ്പിലേക്ക് ചേർക്കുന്നു" "റദ്ദാക്കുക" diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml index c021d21977..4ab619e2d8 100644 --- a/quickstep/res/values-mn/strings.xml +++ b/quickstep/res/values-mn/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Бэхлэх" "Чөлөөтэй хувьсах" - - + "Компьютер" "Сүүлийн үеийн зүйл алга" "Апп ашиглалтын тохиргоо" "Бүгдийг арилгах" @@ -139,6 +138,8 @@ "Зүүн дээд хэсэг рүү зөөх" "Баруун доод хэсэг рүү зөөх" "{count,plural, =1{Өөр # аппыг харуулна уу.}other{Өөр # аппыг харуулна уу.}}" + + "%1$s болон %2$s" "Компьютерт апп нэмж байна" "Цуцлах" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 3fea03b9cf..cae868d791 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -138,6 +138,8 @@ "सर्वात वरती/डावीकडे हलवा" "तळाशी/उजवीकडे हलवा" "{count,plural, =1{आणखी # अ‍ॅप दाखवा.}other{आणखी # अ‍ॅप्स दाखवा.}}" + + "%1$s आणि %2$s" "डेस्कटॉपवर ॲप जोडत आहे" "रद्द करा" diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index d998176d5d..92f6a643c5 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -138,6 +138,8 @@ "Alihkan ke atas/kiri" "Alihkan ke bawah/kanan" "{count,plural, =1{Tunjukkan # lagi apl.}other{Tunjukkan # lagi apl.}}" + + "%1$s dan %2$s" "Menambahkan apl pada Desktop" "Batal" diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml index 66c4e5fe21..f694c394d2 100644 --- a/quickstep/res/values-my/strings.xml +++ b/quickstep/res/values-my/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "ပင်ထိုးရန်" "အလွတ်ပုံစံ" - - + "ဒက်စ်တော့" "မကြာမီကဖွင့်ထားသည်များ မရှိပါ" "အက်ပ်အသုံးပြုမှု ဆက်တင်များ" "အားလုံးရှင်းရန်" @@ -139,6 +138,8 @@ "အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်" "အောက်ခြေ/ညာဘက်သို့ ရွှေ့ရန်" "{count,plural, =1{နောက်ထပ်အက်ပ် # ခု ပြပါ။}other{နောက်ထပ်အက်ပ် # ခု ပြပါ။}}" + + "%1$s နှင့် %2$s" "‘ဒက်စ်တော့’ တွင် အက်ပ်ကို ထည့်ခြင်း" "မလုပ်တော့" diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml index 6ee48dc639..54f259649b 100644 --- a/quickstep/res/values-nb/strings.xml +++ b/quickstep/res/values-nb/strings.xml @@ -138,6 +138,8 @@ "Flytt til øverst/venstre" "Flytt til nederst/høyre" "{count,plural, =1{Vis # app til.}other{Vis # apper til.}}" + + "%1$s og %2$s" "Legg til apper på datamaskin" "Avbryt" diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml index f6668c16d1..401e13b8e8 100644 --- a/quickstep/res/values-ne/strings.xml +++ b/quickstep/res/values-ne/strings.xml @@ -138,6 +138,8 @@ "सिरान/बायाँतिर सार्नुहोस्" "फेद/दायाँतिर सार्नुहोस्" "{count,plural, =1{थप # एप देखाउनुहोस्।}other{थप # वटा एप देखाउनुहोस्।}}" + + "%1$s%2$s" "डेस्कटपमा एप हालिँदै छ" "रद्द गर्नुहोस्" diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml index c2888685e2..e2e0dbede4 100644 --- a/quickstep/res/values-nl/strings.xml +++ b/quickstep/res/values-nl/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Vastzetten" "Vrije vorm" - - + "Desktop" "Geen recente items" "Instellingen voor app-gebruik" "Alles wissen" @@ -139,6 +138,8 @@ "Naar boven/links verplaatsen" "Naar beneden/rechts verplaatsen" "{count,plural, =1{Nog # app tonen.}other{Nog # apps tonen.}}" + + "%1$s en %2$s" "App toevoegen aan desktop" "Annuleren" diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index a7c5d44738..d05fe1e199 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "ପିନ୍‍" "ଫ୍ରିଫର୍ମ" - - + "ଡେସ୍କଟପ" "ବର୍ତ୍ତମାନର କୌଣସି ଆଇଟମ ନାହିଁ" "ଆପ ବ୍ୟବହାର ସେଟିଂସ" "ସବୁ ଖାଲି କରନ୍ତୁ" @@ -139,6 +138,8 @@ "ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ" "ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ" "{count,plural, =1{ଅଧିକ #ଟି ଆପ ଦେଖାନ୍ତୁ।}other{ଅଧିକ #ଟି ଆପ୍ସ ଦେଖାନ୍ତୁ।}}" + + "%1$s ଏବଂ %2$s" "ଡେସ୍କଟପରେ ଆପ ଯୋଗ କରାଯାଉଛି" "ବାତିଲ କରନ୍ତୁ" diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml index 15be242f5b..3256033302 100644 --- a/quickstep/res/values-pa/strings.xml +++ b/quickstep/res/values-pa/strings.xml @@ -138,6 +138,8 @@ "ਸਿਖਰਲੇ/ਖੱਬੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" "ਹੇਠਾਂ/ਸੱਜੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" "{count,plural, =1{# ਹੋਰ ਐਪ ਦਿਖਾਓ।}one{# ਹੋਰ ਐਪ ਦਿਖਾਓ।}other{# ਹੋਰ ਐਪਾਂ ਦਿਖਾਓ।}}" + + "%1$s ਅਤੇ %2$s" "ਐਪ ਨੂੰ ਡੈਸਕਟਾਪ \'ਤੇ ਸ਼ਾਮਲ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ" "ਰੱਦ ਕਰੋ" diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml index 11f46bc28b..479273390a 100644 --- a/quickstep/res/values-pl/strings.xml +++ b/quickstep/res/values-pl/strings.xml @@ -138,6 +138,8 @@ "Przesuń w górny lewy róg" "Przesuń w dolny prawy róg" "{count,plural, =1{Pokaż jeszcze # aplikację.}few{Pokaż jeszcze # aplikacje.}many{Pokaż jeszcze # aplikacji.}other{Pokaż jeszcze # aplikacji.}}" + + "%1$s%2$s" "Dodaję aplikację do komputera" "Anuluj" diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 5af1bf63a5..4f96a38a0c 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -138,6 +138,8 @@ "Mover para a parte superior esquerda" "Mover para a part superior direita" "{count,plural, =1{Mostrar mais # app.}other{Mostrar mais # apps.}}" + + "%1$s e %2$s" "A adicionar a app ao computador" "Cancelar" diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml index 9ea746c6a0..2530361c8c 100644 --- a/quickstep/res/values-pt/strings.xml +++ b/quickstep/res/values-pt/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fixar" "Forma livre" - - + "Computador" "Nenhum item recente" "Configurações de uso do app" "Remover tudo" @@ -139,6 +138,8 @@ "Mover para cima/para a esquerda" "Mover para baixo/para a direita" "{count,plural, =1{Mostrar mais # app.}one{Mostrar mais # app.}other{Mostrar mais # apps.}}" + + "%1$s e %2$s" "Adicionando app ao computador" "Cancelar" diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml index e45e45aacd..0d54d0dd64 100644 --- a/quickstep/res/values-ro/strings.xml +++ b/quickstep/res/values-ro/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fixează" "Formă liberă" - - + "Computer" "Niciun element recent" "Setări de utilizare a aplicației" "Șterge tot" @@ -139,6 +138,8 @@ "Mută în stânga sus" "Mută în dreapta jos" "{count,plural, =1{Afișează încă # aplicație}few{Afișează încă # aplicații}other{Afișează încă # de aplicații}}" + + "%1$s și %2$s" "Se adaugă aplicația pe computer" "Anulează" diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index 5369d1e468..41e0f35636 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -138,6 +138,8 @@ "Переместить вверх или влево" "Переместить вниз или вправо" "{count,plural, =1{Показать ещё # приложение}one{Показать ещё # приложение}few{Показать ещё # приложения}many{Показать ещё # приложений}other{Показать ещё # приложения}}" + + "%1$s и %2$s" "Добавление приложения на компьютер" "Отмена" diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index 3b7598bccd..f90dd288f0 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -138,6 +138,8 @@ "ඉහළ/වම වෙත ගෙන යන්න" "පහළ/දකුණ වෙත ගෙන යන්න" "{count,plural, =1{තවත් # යෙදුමක් පෙන්වන්න.}one{තවත් යෙදුම් #ක් පෙන්වන්න.}other{තවත් යෙදුම් #ක් පෙන්වන්න.}}" + + "%1$s සහ %2$s" "ඩෙස්ක්ටොප් වෙත යෙදුම එක් කිරීම" "අවලංගු කරන්න" diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml index c01f2f03e5..3b5639c3cf 100644 --- a/quickstep/res/values-sk/strings.xml +++ b/quickstep/res/values-sk/strings.xml @@ -138,6 +138,8 @@ "Presunúť hore alebo doľava" "Presunúť dole alebo doprava" "{count,plural, =1{Zobraziť # ďalšiu aplikáciu.}few{Zobraziť # ďalšie aplikácie.}many{Show # more apps.}other{Zobraziť # ďalších aplikácií.}}" + + "%1$s%2$s" "Pridanie aplikácie na plochu" "Zrušiť" diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index 58e34f28be..6714240f38 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Pripni" "Prosta oblika" - - + "Namizni računalnik" "Ni nedavnih elementov" "Nastavitve uporabe aplikacij" "Počisti vse" @@ -139,6 +138,8 @@ "Premakni na vrh/levo" "Premakni na dno/desno" "{count,plural, =1{Pokaži še # aplikacijo.}one{Pokaži še # aplikacijo.}two{Pokaži še # aplikaciji.}few{Pokaži še # aplikacije.}other{Pokaži še # aplikacij.}}" + + "%1$s in %2$s" "Dodajanje aplikacije na namizje" "Prekliči" diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml index 7ae201f265..f67efb66be 100644 --- a/quickstep/res/values-sq/strings.xml +++ b/quickstep/res/values-sq/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Gozhdo" "Formë e lirë" - - + "Desktopi" "Nuk ka asnjë artikull të fundit" "Cilësimet e përdorimit të aplikacionit" "Pastroji të gjitha" @@ -139,6 +138,8 @@ "Lëviz në krye/majtas" "Lëviz në fund/djathtas" "{count,plural, =1{Shfaq # aplikacion tjetër.}other{Shfaq # aplikacione të tjera.}}" + + "%1$s dhe %2$s" "Shtimi i aplikacionit te desktopi" "Anulo" diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index 2a7239e78c..5ad5c1f962 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -138,6 +138,8 @@ "Премести горе лево" "Премести доле десно" "{count,plural, =1{Прикажи још # апликацију.}one{Прикажи још # апликацију.}few{Прикажи још # апликације.}other{Прикажи још # апликација.}}" + + "%1$s и %2$s" "Додаје се апликација на радну поврршину" "Откажи" diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index 808cfe9855..67f7928646 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Fäst" "Fritt format" - - + "Dator" "Listan är tom" "Inställningar för appanvändning" "Rensa alla" @@ -139,6 +138,8 @@ "Flytta högst upp/till vänster" "Flytta längst ned/till höger" "{count,plural, =1{Visa # app till.}other{Visa # appar till.}}" + + "%1$s och %2$s" "Lägger till appen på skrivbordet" "Avbryt" diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml index ba960ecf69..8f4d3fd258 100644 --- a/quickstep/res/values-sw/strings.xml +++ b/quickstep/res/values-sw/strings.xml @@ -138,6 +138,8 @@ "Sogeza juu/kushoto" "Sogeza chini/kulia" "{count,plural, =1{Onyesha programu # zaidi.}other{Onyesha programu # zaidi.}}" + + "%1$s na %2$s" "Kuweka programu kwenye Eneo-kazi" "Ghairi" diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml index c5cbfcd303..5a4630ec2b 100644 --- a/quickstep/res/values-ta/strings.xml +++ b/quickstep/res/values-ta/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "பின் செய்தல்" "குறிப்பிட்ட வடிவமில்லாத பயன்முறை" - - + "டெஸ்க்டாப்" "சமீபத்தியவை எதுவுமில்லை" "ஆப்ஸ் உபயோக அமைப்புகள்" "எல்லாம் அழி" @@ -139,6 +138,8 @@ "மேலே/இடதுபுறம் நகர்த்தும்" "கீழே/வலதுபுறம் நகர்த்தும்" "{count,plural, =1{மேலும் # ஆப்ஸைக் காட்டு.}other{மேலும் # ஆப்ஸைக் காட்டு.}}" + + "%1$s மற்றும் %2$s" "ஆப்ஸை டெஸ்க்டாப்பில் சேர்க்கிறது" "ரத்துசெய்" diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index f2c06b4a1a..ceee6e509b 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -138,6 +138,8 @@ "ఎగువ/ఎడమ వైపునకు తరలించండి" "దిగువ/కుడి వైపునకు తరలించండి" "{count,plural, =1{మరో # యాప్‌ను చూడండి.}other{మరో # యాప్‌లను చూడండి.}}" + + "%1$s, %2$s" "డెస్క్‌టాప్‌నకు యాప్‌ను జోడిస్తోంది" "రద్దు చేయండి" diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml index c5f0b3e7b3..71f9950952 100644 --- a/quickstep/res/values-th/strings.xml +++ b/quickstep/res/values-th/strings.xml @@ -138,6 +138,8 @@ "ย้ายไปที่ด้านบนหรือด้านซ้าย" "ย้ายไปที่ด้านล่างหรือด้านขวา" "{count,plural, =1{แสดงเพิ่มเติมอีก # แอป}other{แสดงเพิ่มเติมอีก # แอป}}" + + "%1$s และ %2$s" "การเพิ่มแอปไปยังเดสก์ท็อป" "ยกเลิก" diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml index 5fbc57b740..3c3acc1839 100644 --- a/quickstep/res/values-tl/strings.xml +++ b/quickstep/res/values-tl/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "I-pin" "Freeform" - - + "Desktop" "Walang kamakailang item" "Mga setting ng paggamit ng app" "I-clear lahat" @@ -139,6 +138,8 @@ "Ilipat sa itaas/kaliwa" "Ilipat sa ibaba/kanan" "{count,plural, =1{Magpakita ng # pang app.}one{Magpakita ng # pang app.}other{Magpakita ng # pang app.}}" + + "%1$s at %2$s" "Idinaragdag ang app sa Desktop" "Kanselahin" diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml index 79f8ad113e..45d2fc4302 100644 --- a/quickstep/res/values-tr/strings.xml +++ b/quickstep/res/values-tr/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Sabitle" "Serbest çalışma" - - + "Masaüstü" "Yeni öğe yok" "Uygulama kullanım ayarları" "Tümünü temizle" @@ -139,6 +138,8 @@ "Sol üste taşı" "Sağ alta taşı" "{count,plural, =1{# uygulama daha göster.}other{# uygulama daha göster}}" + + "%1$s ve %2$s" "Uygulama Masaüstü\'ne ekleniyor" "İptal" diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml index c1ef51d2fb..4838552771 100644 --- a/quickstep/res/values-uk/strings.xml +++ b/quickstep/res/values-uk/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Закріпити" "Довільна форма" - - + "Комп’ютер" "Немає нещодавніх додатків" "Налаштування використання додатка" "Очистити все" @@ -139,6 +138,8 @@ "Перемістити вгору або вліво" "Перемістити вниз або вправо" "{count,plural, =1{Показати ще # додаток.}one{Показати ще # додаток.}few{Показати ще # додатки.}many{Показати ще # додатків.}other{Показати ще # додатка.}}" + + "%1$s та %2$s" "Встановлення додатка на комп’ютер" "Скасувати" diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml index 69b4ba1177..ee96e5c45b 100644 --- a/quickstep/res/values-ur/strings.xml +++ b/quickstep/res/values-ur/strings.xml @@ -138,6 +138,8 @@ "اوپر/بائیں طرف منتقل کریں" "نیچے/دائیں طرف منتقل کریں" "{count,plural, =1{# مزید ایپ دکھائیں۔}other{# مزید ایپس دکھائیں۔}}" + + "%1$s اور %2$s" "ڈیسک ٹاپ پر ایپ شامل کرنا" "منسوخ کریں" diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml index f548c199c7..41e6d24f28 100644 --- a/quickstep/res/values-uz/strings.xml +++ b/quickstep/res/values-uz/strings.xml @@ -138,6 +138,8 @@ "Yuqoriga yoki chapga oʻtkazish" "Pastga yoki oʻngga oʻtkazish" "{count,plural, =1{Yana # ta ilovani chiqarish}other{Yana # ta ilovani chiqarish}}" + + "%1$s va %2$s" "Ilova kompyuterga qoʻshilmoqda" "Bekor qilish" diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml index 136e1d2af0..709fb10f5f 100644 --- a/quickstep/res/values-vi/strings.xml +++ b/quickstep/res/values-vi/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Ghim" "Dạng tự do" - - + "Máy tính" "Không có mục gần đây nào" "Cài đặt mức sử dụng ứng dụng" "Xóa tất cả" @@ -139,6 +138,8 @@ "Chuyển lên trên cùng/sang bên trái" "Chuyển xuống dưới cùng/sang bên phải" "{count,plural, =1{Hiện thêm # ứng dụng.}other{Hiện thêm # ứng dụng.}}" + + "%1$s%2$s" "Đang thêm ứng dụng vào máy tính" "Huỷ" diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml index b90d6bf14d..d30fdfaeaa 100644 --- a/quickstep/res/values-zh-rCN/strings.xml +++ b/quickstep/res/values-zh-rCN/strings.xml @@ -21,8 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "固定" "自由窗口" - - + "桌面设备" "近期没有任何内容" "应用使用设置" "全部清除" @@ -139,6 +138,8 @@ "移到顶部/左侧" "移到底部/右侧" "{count,plural, =1{显示另外 # 个应用。}other{显示另外 # 个应用。}}" + + "%1$s%2$s" "将应用添加到桌面" "取消" diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index 45cf781f69..d8e698c9ec 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -21,7 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "固定" "自由形式" - "電腦" + "桌面" "最近沒有任何項目" "應用程式使用情況設定" "全部清除" @@ -138,6 +138,8 @@ "移至上方/左側" "移至底部/右側" "{count,plural, =1{顯示另外 # 個應用程式。}other{顯示另外 # 個應用程式。}}" + + "「%1$s」和「%2$s」" "正在新增應用程式至桌面" "取消" diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml index ef811c47b5..98465a6a60 100644 --- a/quickstep/res/values-zh-rTW/strings.xml +++ b/quickstep/res/values-zh-rTW/strings.xml @@ -138,6 +138,8 @@ "移到上方/左側" "移到底部/右側" "{count,plural, =1{再多顯示 # 個應用程式。}other{再多顯示 # 個應用程式。}}" + + "「%1$s」和「%2$s」" "新增應用程式至桌面" "取消" diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml index 71c9227cff..bbb6631125 100644 --- a/quickstep/res/values-zu/strings.xml +++ b/quickstep/res/values-zu/strings.xml @@ -138,6 +138,8 @@ "Hamba phezulu/kwesokunxele" "Hamba phansi/kwesokudla" "{count,plural, =1{Bonisa i-app e-# ngaphezulu.}one{Bonisa ama-app angu-# ngaphezulu.}other{Bonisa ama-app angu-# ngaphezulu.}}" + + "I-%1$s ne-%2$s" "Yengeza i-app ku-Deskithophu" "Khansela" From 31329478122ca9e77131546aa295bbd567d8a688 Mon Sep 17 00:00:00 2001 From: Shamali P Date: Wed, 24 Apr 2024 15:08:25 +0000 Subject: [PATCH 09/20] Limit number of items grouped on a row to 3. With shortcuts this allows for more space to display two word title below without ellipsizing it. (screen/4pJvcFFKJhooqZU) Also let widget description show upto 3 lines to more of it to show when stacked (screen/7xv8ng4H7iRLU79) Bug: N/A Flag: N/A Test: Screenshot Change-Id: Ia4e30f943f602b811e607d9cb52152f78cdc20e5 --- res/layout/widget_cell_content.xml | 2 +- src/com/android/launcher3/widget/util/WidgetsTableUtils.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml index 12453a50c1..8f786bf973 100644 --- a/res/layout/widget_cell_content.xml +++ b/res/layout/widget_cell_content.xml @@ -78,7 +78,7 @@ android:gravity="center_horizontal" android:textSize="@dimen/widget_cell_font_size" android:textColor="?android:attr/textColorSecondary" - android:maxLines="2" + android:maxLines="3" android:ellipsize="end" android:fadingEdge="horizontal" android:alpha="0.7" /> diff --git a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java index 5e0e203074..edaf4749b5 100644 --- a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java +++ b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java @@ -31,6 +31,7 @@ import java.util.stream.Collectors; /** An utility class which groups {@link WidgetItem}s into a table. */ public final class WidgetsTableUtils { + private static final int MAX_ITEMS_IN_ROW = 3; /** * Groups widgets in the following order: @@ -125,7 +126,8 @@ public final class WidgetsTableUtils { widgetItemsAtRow.add(widgetItem); containerSizeForRow = containerSize; currentRowWidth = containerWidth; - } else if ((currentRowWidth + containerWidth) <= rowPx + } else if (widgetItemsAtRow.size() < MAX_ITEMS_IN_ROW + && (currentRowWidth + containerWidth) <= rowPx && widgetItem.hasSameType(widgetItemsAtRow.get(numOfWidgetItems - 1)) && containerSize.equals(containerSizeForRow)) { // Group items in the same row if From 9478a40898180a24f13dfa5591d6eebe3ee3e05f Mon Sep 17 00:00:00 2001 From: Shamali P Date: Mon, 22 Apr 2024 15:27:52 +0000 Subject: [PATCH 10/20] Update the app-specific picker to have a container like the main picker This is to ensure widgets are displayed with same container across the two pickers. * http://screencast/cast/NDYxNjMzNDExNjY1MTAwOHwwMTBlYzkwZC0wNg * http://screencast/cast/NjY1NzAyNzY5NzgwMzI2NHwyYTg3ZWIzNS0wNw * http://screencast/cast/NTYyMzcwMTc4NDQ5NDA4MHw3Y2JlZDEwZS04Mw Bug: 328812171 Flag: N/A Test: Manual - need to build a SS test for this opened - 336284716 Change-Id: I42b743b99cf6f47b7bade57de01b130df78ac1e9 --- res/layout/widgets_bottom_sheet_content.xml | 9 +++++++-- res/values/dimens.xml | 2 ++ .../launcher3/widget/WidgetsBottomSheet.java | 20 ------------------- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml index 065c2edf91..7da1846b18 100644 --- a/res/layout/widgets_bottom_sheet_content.xml +++ b/res/layout/widgets_bottom_sheet_content.xml @@ -41,8 +41,13 @@ android:id="@+id/widgets_table_scroll_view" android:layout_width="match_parent" android:layout_height="wrap_content" - android:fadeScrollbars="false" - android:layout_marginTop="16dp"> + android:layout_marginTop="16dp" + android:layout_marginBottom="24dp" + android:layout_marginHorizontal="@dimen/widget_bottom_sheet_horizontal_margin" + android:background="@drawable/widgets_surface_background" + android:scrollbarThumbVertical="@drawable/widget_picker_preview_pane_scroll_thumb" + android:clipToOutline="true" + android:clipChildren="true"> 0dp 24dp 24dp + + 16dp 0.5dp 1dp diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index b14ec4294e..3be6c68055 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -21,7 +21,6 @@ import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_BOTTOM_ import android.content.Context; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.IntProperty; import android.util.Pair; import android.view.Gravity; import android.view.LayoutInflater; @@ -50,22 +49,6 @@ import java.util.List; * Bottom sheet for the "Widgets" system shortcut in the long-press popup. */ public class WidgetsBottomSheet extends BaseWidgetSheet { - private static final String TAG = "WidgetsBottomSheet"; - - private static final IntProperty PADDING_BOTTOM = - new IntProperty("paddingBottom") { - @Override - public void setValue(View view, int paddingBottom) { - view.setPadding(view.getPaddingLeft(), view.getPaddingTop(), - view.getPaddingRight(), paddingBottom); - } - - @Override - public Integer get(View view) { - return view.getPaddingBottom(); - } - }; - private static final int DEFAULT_CLOSE_DURATION = 200; private static final long EDUCATION_TIP_DELAY_MS = 300; @@ -119,9 +102,6 @@ public class WidgetsBottomSheet extends BaseWidgetSheet { mContent = findViewById(R.id.widgets_bottom_sheet); setContentBackgroundWithParent( getContext().getDrawable(R.drawable.bg_rounded_corner_bottom_sheet), mContent); - View scrollView = findViewById(R.id.widgets_table_scroll_view); - scrollView.setOutlineProvider(mViewOutlineProvider); - scrollView.setClipToOutline(true); } @Override From d4997cf063f908e0d9ce3fe66844bf27531613a0 Mon Sep 17 00:00:00 2001 From: Shamali P Date: Tue, 23 Apr 2024 23:32:29 +0000 Subject: [PATCH 11/20] Align the margins between handle, text, and container with main picker. Also aligns style to match main picker which doesn't set header style. Requested by Jane / UX. Bug: 328812171 Flag: N/A Test: Manual - need to build a SS test for this opened - 336284716 Change-Id: I15fb82e807fdaa55bbfaaf73872273d1d6e84f97 --- res/layout/widgets_bottom_sheet_content.xml | 5 ++--- res/values/dimens.xml | 1 + 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/layout/widgets_bottom_sheet_content.xml b/res/layout/widgets_bottom_sheet_content.xml index 7da1846b18..0a1407e098 100644 --- a/res/layout/widgets_bottom_sheet_content.xml +++ b/res/layout/widgets_bottom_sheet_content.xml @@ -25,11 +25,10 @@ android:layout_width="@dimen/bottom_sheet_handle_width" android:layout_height="@dimen/bottom_sheet_handle_height" android:layout_gravity="center_horizontal" - android:layout_marginBottom="@dimen/bottom_sheet_handle_margin" + android:layout_marginBottom="@dimen/widgets_bottom_sheet_handle_margin" android:visibility="gone" android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/> 32dp 4dp 16dp + 24dp 2dp From 1f9bb1372c5239741cd0fea8f9d915a301f64abd Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Wed, 24 Apr 2024 17:50:53 +0000 Subject: [PATCH 12/20] Put Receiver unregistration on Background thread. Bug: 336722585 Test: Verified manually this doesn't break the build. Flag: NA Change-Id: If083d5c4ca7749946b50f5d4b64a5ea87f5651ce --- src/com/android/launcher3/util/LockedUserState.kt | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/util/LockedUserState.kt b/src/com/android/launcher3/util/LockedUserState.kt index 0a87594fde..94f9e4fb69 100644 --- a/src/com/android/launcher3/util/LockedUserState.kt +++ b/src/com/android/launcher3/util/LockedUserState.kt @@ -56,12 +56,16 @@ class LockedUserState(private val mContext: Context) : SafeCloseable { private fun notifyUserUnlocked() { mUserUnlockedActions.executeAllAndDestroy() - mUserUnlockedReceiver.unregisterReceiverSafely(mContext) + Executors.THREAD_POOL_EXECUTOR.execute { + mUserUnlockedReceiver.unregisterReceiverSafely(mContext) + } } /** Stops the receiver from listening for ACTION_USER_UNLOCK broadcasts. */ override fun close() { - mUserUnlockedReceiver.unregisterReceiverSafely(mContext) + Executors.THREAD_POOL_EXECUTOR.execute { + mUserUnlockedReceiver.unregisterReceiverSafely(mContext) + } } /** From b63fd9b7e1540055332e74591b8d3084574c539b Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Wed, 24 Apr 2024 15:18:49 -0700 Subject: [PATCH 13/20] testDragToFolder is stable; promoting to presubmit Bug: 187761685, 233075289 Test: presubmit Flag: N/A Change-Id: I303ea378cef3e05dfc19ce10c0fc3698a66ecf4c --- tests/src/com/android/launcher3/dragging/TaplDragTest.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/src/com/android/launcher3/dragging/TaplDragTest.java b/tests/src/com/android/launcher3/dragging/TaplDragTest.java index d64d096c72..1c41ded1b9 100644 --- a/tests/src/com/android/launcher3/dragging/TaplDragTest.java +++ b/tests/src/com/android/launcher3/dragging/TaplDragTest.java @@ -21,8 +21,6 @@ import static com.android.launcher3.util.TestConstants.AppNames.MAPS_APP_NAME; import static com.android.launcher3.util.TestConstants.AppNames.PHOTOS_APP_NAME; import static com.android.launcher3.util.TestConstants.AppNames.STORE_APP_NAME; import static com.android.launcher3.util.TestConstants.AppNames.TEST_APP_NAME; -import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; -import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -43,8 +41,6 @@ import com.android.launcher3.tapl.Workspace; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; import com.android.launcher3.util.TestUtil; -import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; -import com.android.launcher3.util.rule.TestStabilityRule; import org.junit.Test; @@ -67,9 +63,6 @@ public class TaplDragTest extends AbstractLauncherUiTest { */ @Test @PortraitLandscape - @ScreenRecord - // Staging; will be promoted to presubmit if stable - @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) @PlatinumTest(focusArea = "launcher") public void testDragToFolder() { // TODO: add the use case to drag an icon to an existing folder. Currently it either fails From 884dbdac37ca31d307177a6ff33639d17e2173c0 Mon Sep 17 00:00:00 2001 From: Jagrut Desai Date: Wed, 24 Apr 2024 16:12:07 -0700 Subject: [PATCH 14/20] Promote TaplTestsPersistentTaskbar to Presubmit Test: Presubmit Bug: 320490387 Flag: NONE Change-Id: Ib09ac5d3e909864b9ef2c20a6dda79e4ed857227 --- .../src/com/android/quickstep/TaplTestsPersistentTaskbar.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java index a9ff161cbc..df73e0913e 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsPersistentTaskbar.java @@ -15,8 +15,6 @@ */ package com.android.quickstep; -import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL; -import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT; import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; import android.graphics.Rect; @@ -25,7 +23,6 @@ import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape; -import com.android.launcher3.util.rule.TestStabilityRule; import com.android.quickstep.NavigationModeSwitchRule.NavigationModeSwitch; import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; @@ -48,7 +45,6 @@ public class TaplTestsPersistentTaskbar extends AbstractTaplTestsTaskbar { @Test @NavigationModeSwitch(mode = NavigationModeSwitchRule.Mode.THREE_BUTTON) - @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) public void testThreeButtonsTaskbarBoundsAfterConfigChangeDuringIme() { Rect taskbarBoundsBefore = getTaskbar().getVisibleBounds(); // Go home and to an IME activity (any configuration change would do, as long as it From fa402d1da9fa892069571fbe2b5c02c74f8d957d Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Thu, 25 Apr 2024 10:57:01 +0100 Subject: [PATCH 15/20] Avoid adding unnecessary topMargin to TaskThumbnails in DesktopTaskView - TaskThumbnails in DesktopTaskView already take into account topMarign during onMeasure, we should avoid adding double margin - mTaskThumbnailViewDeprecated's visibility is always GONE, so no need to set margin either Fix: 336968808 Test: manual, image test to follow-up Flag: ACONFIG com.android.window.flags.enable_desktop_windowing_mode DEVELOPMENT Change-Id: I6a7cb128ead0b042974b95199ab720cafc3bcc18 --- .../com/android/quickstep/views/DesktopTaskView.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 964f531df9..2a1b0c0b8b 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -38,7 +38,6 @@ import android.widget.FrameLayout; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.desktop.DesktopRecentsTransitionController; @@ -305,16 +304,7 @@ public class DesktopTaskView extends TaskView { @Override protected void setThumbnailOrientation(RecentsOrientedState orientationState) { - DeviceProfile deviceProfile = mContainer.getDeviceProfile(); - int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx; - - LayoutParams snapshotParams = (LayoutParams) mTaskThumbnailViewDeprecated.getLayoutParams(); - snapshotParams.topMargin = thumbnailTopMargin; - - for (int i = 0; i < mSnapshotViewMap.size(); i++) { - TaskThumbnailViewDeprecated thumbnailView = mSnapshotViewMap.valueAt(i); - thumbnailView.setLayoutParams(snapshotParams); - } + // no-op } @Override From 42e3196011e0c5250acecbc6a77e2c72eb2dba0b Mon Sep 17 00:00:00 2001 From: Himanshu Gupta Date: Wed, 24 Apr 2024 14:46:47 +0100 Subject: [PATCH 16/20] Fix Accessbility bugs for PS. This Cl contains: 1. Alt text for Lock/Unlock button as per state. 2. Alt text for Header when Locked. 3. Removing Header from accessibility target when unlocked. Bug: 328024119 Test: Manual Flag: NA Change-Id: I791176afdae4fc6eb9387080aa036c1aed2a03a9 --- res/layout/private_space_header.xml | 9 ++++++--- res/values/strings.xml | 6 ++++-- .../launcher3/allapps/PrivateProfileManager.java | 13 +++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/res/layout/private_space_header.xml b/res/layout/private_space_header.xml index 84554e48e6..cefe39430b 100644 --- a/res/layout/private_space_header.xml +++ b/res/layout/private_space_header.xml @@ -25,7 +25,9 @@ android:clipToOutline="true" android:gravity="center_vertical" android:textDirection="locale" - android:orientation="horizontal"> + android:orientation="horizontal" + android:contentDescription="@string/ps_container_lock_button_content_description" + android:importantForAccessibility="yes"> + android:contentDescription="@string/ps_container_lock_button_content_description"> + android:theme="@style/PrivateSpaceHeaderTextStyle" + android:importantForAccessibility="no"/> \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index e1c7d64323..da5b70962f 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -487,8 +487,10 @@ Private Private Space Settings - - Lock/Unlock Private Space + + Private, unlocked. + + Private, locked. Lock Private Space Transitioning diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index 7e975df713..551fa944bb 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -112,6 +112,8 @@ public class PrivateProfileManager extends UserProfileManager { private Runnable mOnPSHeaderAdded; @Nullable private RelativeLayout mPSHeader; + private final String mLockedStateContentDesc; + private final String mUnLockedStateContentDesc; public PrivateProfileManager(UserManager userManager, ActivityAllAppsContainerView allApps, @@ -125,6 +127,10 @@ public class PrivateProfileManager extends UserProfileManager { UI_HELPER_EXECUTOR.post(() -> initializeInBackgroundThread(appContext)); mPsHeaderHeight = mAllApps.getContext().getResources().getDimensionPixelSize( R.dimen.ps_header_height); + mLockedStateContentDesc = mAllApps.getContext() + .getString(R.string.ps_container_lock_button_content_description); + mUnLockedStateContentDesc = mAllApps.getContext() + .getString(R.string.ps_container_unlock_button_content_description); } /** Adds Private Space Header to the layout. */ @@ -398,11 +404,13 @@ public class PrivateProfileManager extends UserProfileManager { lockText.setVisibility(VISIBLE); lockButton.setVisibility(VISIBLE); lockButton.setOnClickListener(view -> lockingAction(/* lock */ true)); + lockButton.setContentDescription(mUnLockedStateContentDesc); } case STATE_DISABLED -> { lockText.setVisibility(GONE); lockButton.setVisibility(VISIBLE); lockButton.setOnClickListener(view -> lockingAction(/* lock */ false)); + lockButton.setContentDescription(mLockedStateContentDesc); } default -> lockButton.setVisibility(GONE); } @@ -412,9 +420,14 @@ public class PrivateProfileManager extends UserProfileManager { if (getCurrentState() == STATE_DISABLED) { header.setOnClickListener(view -> lockingAction(/* lock */ false)); header.setClickable(true); + // Add header as accessibility target when disabled. + header.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); + header.setContentDescription(mLockedStateContentDesc); } else { header.setOnClickListener(null); header.setClickable(false); + // Remove header from accessibility target when enabled. + header.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO); } } From 1e7e52b92302cd4769232a775ae7b4a15d668fa0 Mon Sep 17 00:00:00 2001 From: mpodolian Date: Mon, 22 Apr 2024 11:41:11 +0100 Subject: [PATCH 17/20] Removed arrow animation on selected bubble closing. We should first decide how we would like to animate dismissal of the selected bubble, and than implement arrow animation. The issue exists because background is shrinked without an animation. Test: Visual Fixes: 293350516 Flag: ACONFIG com.android.wm.shell.enable_bubble_bar DEVELOPMENT Change-Id: Ia0cf04671bf9e93c98c45c99a21865055462e6df --- .../launcher3/taskbar/bubbles/BubbleBarView.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index 1003c3f8e0..79774aab1f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -120,6 +120,7 @@ public class BubbleBarView extends FrameLayout { // Whether the bar is expanded (i.e. the bubble activity is being displayed). private boolean mIsBarExpanded = false; // The currently selected bubble view. + @Nullable private BubbleView mSelectedBubbleView; private BubbleBarLocation mBubbleBarLocation = BubbleBarLocation.DEFAULT; // The click listener when the bubble bar is collapsed. @@ -204,6 +205,7 @@ public class BubbleBarView extends FrameLayout { // If the bar was just collapsed and the overflow was the last bubble that was // selected, set the first bubble as selected. if (!mIsBarExpanded && mUpdateSelectedBubbleAfterCollapse != null + && mSelectedBubbleView != null && mSelectedBubbleView.getBubble() instanceof BubbleBarOverflow) { BubbleView firstBubble = (BubbleView) getChildAt(0); mUpdateSelectedBubbleAfterCollapse.accept(firstBubble.getBubble().getKey()); @@ -533,6 +535,10 @@ public class BubbleBarView extends FrameLayout { @Override public void removeView(View view) { super.removeView(view); + if (view == mSelectedBubbleView) { + mSelectedBubbleView = null; + mBubbleBarBackground.showArrow(false); + } updateWidth(); } @@ -688,8 +694,12 @@ public class BubbleBarView extends FrameLayout { * Sets which bubble view should be shown as selected. */ public void setSelectedBubble(BubbleView view) { + BubbleView previouslySelectedBubble = mSelectedBubbleView; mSelectedBubbleView = view; - updateArrowForSelected(/* shouldAnimate= */ true); + mBubbleBarBackground.showArrow(view != null); + // TODO: (b/283309949) remove animation should be implemented first, so than arrow + // animation is adjusted, skip animation for now + updateArrowForSelected(previouslySelectedBubble != null); } /** @@ -714,6 +724,10 @@ public class BubbleBarView extends FrameLayout { // Find the center of the bubble when it's expanded, set the arrow position to it. final float tx = arrowPositionForSelectedWhenExpanded(); final float currentArrowPosition = mBubbleBarBackground.getArrowPositionX(); + if (tx == currentArrowPosition) { + // arrow position remains unchanged + return; + } if (shouldAnimate && currentArrowPosition > expandedWidth()) { Log.d(TAG, "arrow out of bounds of expanded view, skip animation"); shouldAnimate = false; From 4e955ed606b576ebaf9ea7d1348933c9a0aa11a8 Mon Sep 17 00:00:00 2001 From: Daniel Akinola Date: Thu, 25 Apr 2024 15:47:57 +0000 Subject: [PATCH 18/20] Revert "Force calculator to launch in fullscreen for quickswitch tests" This reverts commit 41fcfc1f723b4d3c9e08c38d5c0c944c8db5052b. Reason for revert: was only a temporary fix while investigating issue, should be unnecessary after ag/27089675 is landed. Change-Id: Ic1ab614cfc0e7bf4b82c8d0eaa1662fd4129932a --- .../src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java index 7ab72f28e2..43ebb1752a 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsKeyboardQuickSwitch.java @@ -65,7 +65,7 @@ public class TaplTestsKeyboardQuickSwitch extends AbstractQuickStepTest { public void setUp() throws Exception { Assume.assumeTrue(mLauncher.isTablet()); super.setUp(); - startAppFastInFullscreen(CALCULATOR_APP_PACKAGE); + startAppFast(CALCULATOR_APP_PACKAGE); startTestActivity(2); } From 56ccf74899e5be7dcc309998373bfb3be29c33ac Mon Sep 17 00:00:00 2001 From: Daniel Akinola Date: Thu, 25 Apr 2024 15:49:06 +0000 Subject: [PATCH 19/20] Revert "Force calculator to launch in fullscreen for taskbar tests" This reverts commit 8771dfe3dd3bdae6a179df91ded9fb349fe85f70. Reason for revert: was only a temporary fix while investigating issue, should be unnecessary after ag/27089675 is landed. Change-Id: I5963dc77f31eb45c1cdd100788b045891de2d716 --- .../quickstep/AbstractTaplTestsTaskbar.java | 2 +- .../launcher3/ui/AbstractLauncherUiTest.java | 33 ++----------------- 2 files changed, 3 insertions(+), 32 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java index ca5fb70bea..fc757b44c9 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractTaplTestsTaskbar.java @@ -55,7 +55,7 @@ public class AbstractTaplTestsTaskbar extends AbstractQuickStepTest { "com.android.launcher3.testcomponent.BaseTestingActivity"); mLauncherLayout = TestUtil.setLauncherDefaultLayout(mTargetContext, layoutBuilder); AbstractLauncherUiTest.initialize(this); - startAppFastInFullscreen(CALCULATOR_APP_PACKAGE); + startAppFast(CALCULATOR_APP_PACKAGE); mLauncher.enableBlockTimeout(true); mLauncher.showTaskbarIfHidden(); } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 9c289d6f8c..99e15ba8aa 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -15,10 +15,7 @@ */ package com.android.launcher3.ui; -import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT; -import static android.view.Display.DEFAULT_DISPLAY; import static androidx.test.InstrumentationRegistry.getInstrumentation; @@ -29,7 +26,6 @@ import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.app.ActivityOptions; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -575,21 +571,6 @@ public abstract class AbstractLauncherUiTest { true /* newTask */); } - /** alternative of startAppFast where app is guaranteed to launch in fullscreen mode */ - public static void startAppFastInFullscreen(String packageName) { - ActivityOptions options = ActivityOptions.makeBasic(); - options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); - options.setLaunchDisplayId(DEFAULT_DISPLAY); - options.setLaunchActivityType(ACTIVITY_TYPE_STANDARD); - - startIntent( - getInstrumentation().getContext().getPackageManager().getLaunchIntentForPackage( - packageName), - By.pkg(packageName).depth(0), - true /* newTask */, - options); - } - public static void startTestActivity(String activityName, String activityLabel) { final String packageName = getAppPackageName(); final Intent intent = getInstrumentation().getContext().getPackageManager(). @@ -625,8 +606,7 @@ public abstract class AbstractLauncherUiTest { false /* newTask */); } - private static void startIntent( - Intent intent, BySelector selector, boolean newTask, ActivityOptions options) { + private static void startIntent(Intent intent, BySelector selector, boolean newTask) { intent.addCategory(Intent.CATEGORY_LAUNCHER); if (newTask) { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -634,12 +614,7 @@ public abstract class AbstractLauncherUiTest { intent.addFlags( Intent.FLAG_ACTIVITY_MULTIPLE_TASK | Intent.FLAG_ACTIVITY_NEW_DOCUMENT); } - - if (options != null) { - getInstrumentation().getTargetContext().startActivity(intent, options.toBundle()); - } else { - getInstrumentation().getTargetContext().startActivity(intent); - } + getInstrumentation().getTargetContext().startActivity(intent); assertTrue("App didn't start: " + selector, TestHelpers.wait(Until.hasObject(selector), DEFAULT_UI_TIMEOUT)); @@ -650,10 +625,6 @@ public abstract class AbstractLauncherUiTest { DEFAULT_ACTIVITY_TIMEOUT, launcherInstrumentation); } - private static void startIntent(Intent intent, BySelector selector, boolean newTask) { - startIntent(intent, selector, newTask, null); - } - public static ActivityInfo resolveSystemAppInfo(String category) { return getInstrumentation().getContext().getPackageManager().resolveActivity( new Intent(Intent.ACTION_MAIN).addCategory(category), From 9ac6f426104de8d6155802a9870da2888c19ae14 Mon Sep 17 00:00:00 2001 From: Charlie Anderson Date: Tue, 23 Apr 2024 10:33:14 -0400 Subject: [PATCH 20/20] Reapply "add more unit tests for WorkspaceItemProcessor" Also, add more unit tests around Widgets. This reverts commit d9ed5f301b559873ac9b37c2c4f4245ceb82f380. Test: Added unit tests Flag: N/A Bug: 330906931 Bug: 294386159 Change-Id: I8de74bce8bddd06e5ce1399d26253cb936281bee --- .../model/WorkspaceItemProcessorTest.kt | 468 ++++++++++++++++-- 1 file changed, 416 insertions(+), 52 deletions(-) diff --git a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt index c2e73fcb15..6bbcf85187 100644 --- a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt +++ b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt @@ -24,18 +24,29 @@ import android.content.pm.LauncherApps import android.content.pm.PackageInstaller import android.content.pm.ShortcutInfo import android.os.UserHandle +import android.platform.test.annotations.EnableFlags import android.util.LongSparseArray +import com.android.dx.mockito.inline.extended.ExtendedMockito +import com.android.launcher3.Flags.FLAG_ENABLE_SUPPORT_FOR_ARCHIVING import com.android.launcher3.LauncherAppState import com.android.launcher3.LauncherSettings.Favorites +import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_DESKTOP import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION +import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER +import com.android.launcher3.Utilities import com.android.launcher3.Utilities.EMPTY_PERSON_ARRAY +import com.android.launcher3.backuprestore.LauncherRestoreEventLogger import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.MISSING_INFO +import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.MISSING_WIDGET_PROVIDER import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.PROFILE_DELETED import com.android.launcher3.model.data.FolderInfo import com.android.launcher3.model.data.IconRequestInfo import com.android.launcher3.model.data.ItemInfo +import com.android.launcher3.model.data.LauncherAppWidgetInfo +import com.android.launcher3.model.data.LauncherAppWidgetInfo.FLAG_RESTORE_STARTED +import com.android.launcher3.model.data.LauncherAppWidgetInfo.FLAG_UI_NOT_READY import com.android.launcher3.model.data.WorkspaceItemInfo import com.android.launcher3.pm.UserCache import com.android.launcher3.shortcuts.ShortcutKey @@ -43,11 +54,14 @@ import com.android.launcher3.util.ComponentKey import com.android.launcher3.util.PackageManagerHelper import com.android.launcher3.util.PackageUserKey import com.android.launcher3.util.UserIconInfo +import com.android.launcher3.widget.LauncherAppWidgetProviderInfo import com.android.launcher3.widget.WidgetInflater +import com.android.launcher3.widget.WidgetSections import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertWithMessage import org.junit.Before import org.junit.Test +import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito.RETURNS_DEEP_STUBS import org.mockito.Mockito.mock @@ -56,8 +70,10 @@ import org.mockito.Mockito.verify import org.mockito.kotlin.any import org.mockito.kotlin.anyOrNull import org.mockito.kotlin.doAnswer +import org.mockito.kotlin.eq import org.mockito.kotlin.mock import org.mockito.kotlin.whenever +import org.mockito.quality.Strictness class WorkspaceItemProcessorTest { @@ -73,29 +89,31 @@ class WorkspaceItemProcessorTest { @Mock private lateinit var mockUserManagerState: UserManagerState @Mock private lateinit var mockWidgetInflater: WidgetInflater - private lateinit var intent: Intent - private lateinit var userHandle: UserHandle - private lateinit var iconRequestInfos: MutableList> - private lateinit var componentName: ComponentName - private lateinit var unlockedUsersArray: LongSparseArray - private lateinit var keyToPinnedShortcutsMap: MutableMap - private lateinit var installingPkgs: HashMap - private lateinit var allDeepShortcuts: MutableList + private var intent: Intent = Intent() + private var mUserHandle: UserHandle = UserHandle(0) + private var mIconRequestInfos: MutableList> = mutableListOf() + private var mComponentName: ComponentName = ComponentName("package", "class") + private var mUnlockedUsersArray: LongSparseArray = LongSparseArray() + private var mKeyToPinnedShortcutsMap: MutableMap = mutableMapOf() + private var mInstallingPkgs: HashMap = hashMapOf() + private var mAllDeepShortcuts: MutableList = mutableListOf() + private var mWidgetProvidersMap: MutableMap = + mutableMapOf() + private var mPendingPackages: MutableSet = mutableSetOf() private lateinit var itemProcessorUnderTest: WorkspaceItemProcessor @Before fun setup() { - userHandle = UserHandle(0) + mUserHandle = UserHandle(0) mockIconRequestInfo = mock>() - iconRequestInfos = mutableListOf(mockIconRequestInfo) mockWorkspaceInfo = mock() mockBgDataModel = mock() - componentName = ComponentName("package", "class") - unlockedUsersArray = LongSparseArray(1).apply { put(101, true) } + mComponentName = ComponentName("package", "class") + mUnlockedUsersArray = LongSparseArray(1).apply { put(101, true) } intent = Intent().apply { - component = componentName + component = mComponentName `package` = "pkg" putExtra(ShortcutKey.EXTRA_SHORTCUT_ID, "") } @@ -112,17 +130,17 @@ class WorkspaceItemProcessorTest { } mockPmHelper = mock().apply { - whenever(getAppLaunchIntent(componentName.packageName, userHandle)) + whenever(getAppLaunchIntent(mComponentName.packageName, mUserHandle)) .thenReturn(intent) } mockLauncherApps = mock().apply { - whenever(isPackageEnabled("package", userHandle)).thenReturn(true) - whenever(isActivityEnabled(componentName, userHandle)).thenReturn(true) + whenever(isPackageEnabled("package", mUserHandle)).thenReturn(true) + whenever(isActivityEnabled(mComponentName, mUserHandle)).thenReturn(true) } mockCursor = mock(LoaderCursor::class.java, RETURNS_DEEP_STUBS).apply { - user = userHandle + user = mUserHandle itemType = ITEM_TYPE_APPLICATION id = 1 restoreFlag = 1 @@ -137,15 +155,18 @@ class WorkspaceItemProcessorTest { mockUserCache = mock().apply { val userIconInfo = - mock().apply() { whenever(isPrivate).thenReturn(false) } + mock().apply { whenever(isPrivate).thenReturn(false) } whenever(getUserInfo(any())).thenReturn(userIconInfo) } mockUserManagerState = mock() mockWidgetInflater = mock() - keyToPinnedShortcutsMap = mutableMapOf() - installingPkgs = hashMapOf() - allDeepShortcuts = mutableListOf() + mKeyToPinnedShortcutsMap = mutableMapOf() + mInstallingPkgs = hashMapOf() + mAllDeepShortcuts = mutableListOf() + mWidgetProvidersMap = mutableMapOf() + mIconRequestInfos = mutableListOf() + mPendingPackages = mutableSetOf() } /** @@ -159,18 +180,18 @@ class WorkspaceItemProcessorTest { userCache: UserCache = mockUserCache, userManagerState: UserManagerState = mockUserManagerState, launcherApps: LauncherApps = mockLauncherApps, - shortcutKeyToPinnedShortcuts: Map = keyToPinnedShortcutsMap, + shortcutKeyToPinnedShortcuts: Map = mKeyToPinnedShortcutsMap, app: LauncherAppState = mockAppState, bgDataModel: BgDataModel = mockBgDataModel, - widgetProvidersMap: MutableMap = mutableMapOf(), + widgetProvidersMap: MutableMap = mWidgetProvidersMap, widgetInflater: WidgetInflater = mockWidgetInflater, pmHelper: PackageManagerHelper = mockPmHelper, - iconRequestInfos: MutableList> = mutableListOf(), + iconRequestInfos: MutableList> = mIconRequestInfos, isSdCardReady: Boolean = false, - pendingPackages: MutableSet = mutableSetOf(), - unlockedUsers: LongSparseArray = unlockedUsersArray, - installingPkgs: HashMap = hashMapOf(), - allDeepShortcuts: MutableList = mutableListOf() + pendingPackages: MutableSet = mPendingPackages, + unlockedUsers: LongSparseArray = mUnlockedUsersArray, + installingPkgs: HashMap = mInstallingPkgs, + allDeepShortcuts: MutableList = mAllDeepShortcuts ) = WorkspaceItemProcessor( c = cursor, @@ -241,8 +262,8 @@ class WorkspaceItemProcessorTest { fun `When app has empty String target package then mark deleted`() { // Given - componentName = ComponentName("", "") - intent.component = componentName + mComponentName = ComponentName("", "") + intent.component = mComponentName intent.`package` = "" // When @@ -267,7 +288,7 @@ class WorkspaceItemProcessorTest { .isEqualTo(0) // currently gets marked restored twice, although markRestore() has check for restoreFlag verify(mockCursor, times(2)).markRestored() - assertThat(iconRequestInfos).containsExactly(mockIconRequestInfo) + assertThat(mIconRequestInfos).containsExactly(mockIconRequestInfo) verify(mockCursor).checkAndAddItem(mockWorkspaceInfo, mockBgDataModel, null) } @@ -277,12 +298,12 @@ class WorkspaceItemProcessorTest { // Given mockLauncherApps = mock().apply { - whenever(isPackageEnabled("package", userHandle)).thenReturn(true) - whenever(isActivityEnabled(componentName, userHandle)).thenReturn(false) + whenever(isPackageEnabled("package", mUserHandle)).thenReturn(true) + whenever(isActivityEnabled(mComponentName, mUserHandle)).thenReturn(false) } mockPmHelper = mock().apply { - whenever(getAppLaunchIntent(componentName.packageName, userHandle)) + whenever(getAppLaunchIntent(mComponentName.packageName, mUserHandle)) .thenReturn(intent) } @@ -295,7 +316,7 @@ class WorkspaceItemProcessorTest { .that(mockCursor.restoreFlag) .isEqualTo(0) verify(mockCursor.updater().put(Favorites.INTENT, intent.toUri(0))).commit() - assertThat(iconRequestInfos).containsExactly(mockIconRequestInfo) + assertThat(mIconRequestInfos).containsExactly(mockIconRequestInfo) verify(mockCursor).checkAndAddItem(mockWorkspaceInfo, mockBgDataModel, null) } @@ -305,12 +326,13 @@ class WorkspaceItemProcessorTest { // Given mockLauncherApps = mock().apply { - whenever(isPackageEnabled("package", userHandle)).thenReturn(true) - whenever(isActivityEnabled(componentName, userHandle)).thenReturn(false) + whenever(isPackageEnabled("package", mUserHandle)).thenReturn(true) + whenever(isActivityEnabled(mComponentName, mUserHandle)).thenReturn(false) } mockPmHelper = mock().apply { - whenever(getAppLaunchIntent(componentName.packageName, userHandle)).thenReturn(null) + whenever(getAppLaunchIntent(mComponentName.packageName, mUserHandle)) + .thenReturn(null) } // When @@ -349,20 +371,20 @@ class WorkspaceItemProcessorTest { whenever(persons).thenReturn(EMPTY_PERSON_ARRAY) } val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user) - keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo - iconRequestInfos = mutableListOf() + mKeyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo + mIconRequestInfos = mutableListOf() // When itemProcessorUnderTest = - createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts) + createWorkspaceItemProcessorUnderTest(allDeepShortcuts = mAllDeepShortcuts) itemProcessorUnderTest.processItem() // Then assertWithMessage("item restoreFlag should be set to 0") .that(mockCursor.restoreFlag) .isEqualTo(0) - assertThat(iconRequestInfos).isEmpty() - assertThat(allDeepShortcuts).containsExactly(expectedShortcutInfo) + assertThat(mIconRequestInfos).isEmpty() + assertThat(mAllDeepShortcuts).containsExactly(expectedShortcutInfo) verify(mockCursor).markRestored() verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull()) } @@ -372,8 +394,8 @@ class WorkspaceItemProcessorTest { // Given mockCursor.itemType = ITEM_TYPE_DEEP_SHORTCUT - iconRequestInfos = mutableListOf() - keyToPinnedShortcutsMap = hashMapOf() + mIconRequestInfos = mutableListOf() + mKeyToPinnedShortcutsMap = hashMapOf() // When itemProcessorUnderTest = createWorkspaceItemProcessorUnderTest() @@ -383,7 +405,7 @@ class WorkspaceItemProcessorTest { assertWithMessage("item restoreFlag should be set to 0") .that(mockCursor.restoreFlag) .isEqualTo(0) - assertThat(iconRequestInfos).isEmpty() + assertThat(mIconRequestInfos).isEmpty() verify(mockCursor, times(0)).checkAndAddItem(any(), any(), anyOrNull()) verify(mockCursor) .markDeleted( @@ -408,25 +430,25 @@ class WorkspaceItemProcessorTest { whenever(disabledReason).thenReturn(0) whenever(persons).thenReturn(EMPTY_PERSON_ARRAY) } - iconRequestInfos = mutableListOf() + mIconRequestInfos = mutableListOf() // Make sure shortcuts map has expected key from expected package - intent.`package` = componentName.packageName + intent.`package` = mComponentName.packageName val shortcutKey = ShortcutKey.fromIntent(intent, mockCursor.user) - keyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo + mKeyToPinnedShortcutsMap[shortcutKey] = expectedShortcutInfo // set intent package back to null to test scenario intent.`package` = null // When itemProcessorUnderTest = - createWorkspaceItemProcessorUnderTest(allDeepShortcuts = allDeepShortcuts) + createWorkspaceItemProcessorUnderTest(allDeepShortcuts = mAllDeepShortcuts) itemProcessorUnderTest.processItem() // Then assertWithMessage("item restoreFlag should be set to 0") .that(mockCursor.restoreFlag) .isEqualTo(0) - assertThat(iconRequestInfos).isEmpty() - assertThat(allDeepShortcuts).containsExactly(expectedShortcutInfo) + assertThat(mIconRequestInfos).isEmpty() + assertThat(mAllDeepShortcuts).containsExactly(expectedShortcutInfo) verify(mockCursor).markRestored() verify(mockCursor).checkAndAddItem(any(), any(), anyOrNull()) } @@ -478,4 +500,346 @@ class WorkspaceItemProcessorTest { assertThat(actualFolderInfo.options).isEqualTo(expectedFolderInfo.options) verify(mockCursor).checkAndAddItem(actualFolderInfo, mockBgDataModel, null) } + + @Test + fun `When valid TYPE_REAL App Widget then add item`() { + + // Given + val expectedProvider = "com.google.android.testApp/com.android.testApp.testAppProvider" + val expectedComponentName = + ComponentName.unflattenFromString(expectedProvider)!!.flattenToString() + val expectedRestoreStatus = FLAG_UI_NOT_READY + val expectedAppWidgetId = 0 + mockCursor.apply { + itemType = ITEM_TYPE_APPWIDGET + user = mUserHandle + restoreFlag = FLAG_UI_NOT_READY + container = CONTAINER_DESKTOP + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(appWidgetProvider).thenReturn(expectedProvider) + whenever(appWidgetId).thenReturn(expectedAppWidgetId) + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(options).thenReturn(0) + whenever(appWidgetSource).thenReturn(20) + whenever(applyCommonProperties(any())).thenCallRealMethod() + whenever( + updater() + .put(Favorites.APPWIDGET_PROVIDER, expectedComponentName) + .put(Favorites.APPWIDGET_ID, expectedAppWidgetId) + .put(Favorites.RESTORED, expectedRestoreStatus) + .commit() + ) + .thenReturn(1) + } + val expectedWidgetInfo = + LauncherAppWidgetInfo().apply { + appWidgetId = expectedAppWidgetId + providerName = ComponentName.unflattenFromString(expectedProvider) + restoreStatus = expectedRestoreStatus + } + val expectedWidgetProviderInfo = + mock().apply { + provider = ComponentName.unflattenFromString(expectedProvider) + whenever(user).thenReturn(mUserHandle) + } + val inflationResult = + WidgetInflater.InflationResult( + type = WidgetInflater.TYPE_REAL, + widgetInfo = expectedWidgetProviderInfo + ) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + val packageUserKey = PackageUserKey("com.google.android.testApp", mUserHandle) + mInstallingPkgs[packageUserKey] = PackageInstaller.SessionInfo() + + // When + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + itemProcessorUnderTest.processItem() + + // Then + val widgetInfoCaptor = ArgumentCaptor.forClass(LauncherAppWidgetInfo::class.java) + verify(mockCursor).checkAndAddItem(widgetInfoCaptor.capture(), eq(mockBgDataModel)) + val actualWidgetInfo = widgetInfoCaptor.value + with(actualWidgetInfo) { + assertThat(providerName).isEqualTo(expectedWidgetInfo.providerName) + assertThat(restoreStatus).isEqualTo(expectedWidgetInfo.restoreStatus) + assertThat(targetComponent).isEqualTo(expectedWidgetInfo.targetComponent) + assertThat(appWidgetId).isEqualTo(expectedWidgetInfo.appWidgetId) + } + val expectedComponentKey = + ComponentKey(expectedWidgetProviderInfo.provider, expectedWidgetProviderInfo.user) + assertThat(mWidgetProvidersMap[expectedComponentKey]).isEqualTo(expectedWidgetProviderInfo) + } + + @Test + fun `When valid Pending Widget then checkAndAddItem`() { + + // Given + mockCursor = + mock().apply { + itemType = ITEM_TYPE_APPWIDGET + id = 1 + user = UserHandle(1) + restoreFlag = FLAG_UI_NOT_READY + container = CONTAINER_DESKTOP + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(appWidgetProvider) + .thenReturn("com.google.android.testApp/com.android.testApp.testAppProvider") + whenever(appWidgetId).thenReturn(0) + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(options).thenReturn(0) + whenever(appWidgetSource).thenReturn(20) + whenever(applyCommonProperties(any())).thenCallRealMethod() + } + val mockProviderInfo = + mock().apply { + provider = mock() + whenever(user).thenReturn(UserHandle(1)) + } + val inflationResult = + WidgetInflater.InflationResult( + type = WidgetInflater.TYPE_PENDING, + widgetInfo = mockProviderInfo + ) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + + // When + itemProcessorUnderTest.processItem() + + // Then + verify(mockCursor).checkAndAddItem(any(), any()) + } + + @Test + fun `When Unrestored Pending App Widget then mark deleted`() { + + // Given + val expectedProvider = "com.google.android.testApp/com.android.testApp.testAppProvider" + mockCursor = + mock().apply { + itemType = ITEM_TYPE_APPWIDGET + id = 1 + user = UserHandle(1) + restoreFlag = FLAG_UI_NOT_READY + container = CONTAINER_DESKTOP + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(appWidgetProvider).thenReturn(expectedProvider) + whenever(appWidgetId).thenReturn(0) + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(options).thenReturn(0) + whenever(appWidgetSource).thenReturn(20) + whenever(applyCommonProperties(any())).thenCallRealMethod() + } + mInstallingPkgs = hashMapOf() + val inflationResult = + WidgetInflater.InflationResult(type = WidgetInflater.TYPE_PENDING, widgetInfo = null) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + val expectedComponentName = ComponentName.unflattenFromString(expectedProvider) + + // When + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + itemProcessorUnderTest.processItem() + + // Then + verify(mockCursor) + .markDeleted( + "processWidget: Unrestored Pending widget removed: id=1, appWidgetId=0, component=$expectedComponentName, restoreFlag:=4", + LauncherRestoreEventLogger.RestoreError.APP_NOT_INSTALLED + ) + } + + @Test + fun `When Pending App Widget has not started restore then update db and add item`() { + + val mockitoSession = + ExtendedMockito.mockitoSession() + .strictness(Strictness.LENIENT) + .mockStatic(WidgetSections::class.java) + .startMocking() + try { + // Given + val expectedProvider = "com.google.android.testApp/com.android.testApp.testAppProvider" + val expectedComponentName = + ComponentName.unflattenFromString(expectedProvider)!!.flattenToString() + val expectedRestoreStatus = FLAG_UI_NOT_READY or FLAG_RESTORE_STARTED + val expectedAppWidgetId = 0 + mockCursor.apply { + itemType = ITEM_TYPE_APPWIDGET + user = mUserHandle + restoreFlag = FLAG_UI_NOT_READY + container = CONTAINER_DESKTOP + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(appWidgetProvider).thenReturn(expectedProvider) + whenever(appWidgetId).thenReturn(expectedAppWidgetId) + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(options).thenReturn(0) + whenever(appWidgetSource).thenReturn(20) + whenever(applyCommonProperties(any())).thenCallRealMethod() + whenever( + updater() + .put(Favorites.APPWIDGET_PROVIDER, expectedComponentName) + .put(Favorites.APPWIDGET_ID, expectedAppWidgetId) + .put(Favorites.RESTORED, expectedRestoreStatus) + .commit() + ) + .thenReturn(1) + } + val inflationResult = + WidgetInflater.InflationResult( + type = WidgetInflater.TYPE_PENDING, + widgetInfo = null + ) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + val packageUserKey = PackageUserKey("com.google.android.testApp", mUserHandle) + mInstallingPkgs[packageUserKey] = PackageInstaller.SessionInfo() + + // When + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + itemProcessorUnderTest.processItem() + + // Then + val expectedWidgetInfo = + LauncherAppWidgetInfo().apply { + appWidgetId = expectedAppWidgetId + providerName = ComponentName.unflattenFromString(expectedProvider) + restoreStatus = expectedRestoreStatus + } + verify( + mockCursor + .updater() + .put(Favorites.APPWIDGET_PROVIDER, expectedProvider) + .put(Favorites.APPWIDGET_ID, expectedAppWidgetId) + .put(Favorites.RESTORED, expectedRestoreStatus) + ) + .commit() + val widgetInfoCaptor = ArgumentCaptor.forClass(LauncherAppWidgetInfo::class.java) + verify(mockCursor).checkAndAddItem(widgetInfoCaptor.capture(), eq(mockBgDataModel)) + val actualWidgetInfo = widgetInfoCaptor.value + with(actualWidgetInfo) { + assertThat(providerName).isEqualTo(expectedWidgetInfo.providerName) + assertThat(restoreStatus).isEqualTo(expectedWidgetInfo.restoreStatus) + assertThat(targetComponent).isEqualTo(expectedWidgetInfo.targetComponent) + assertThat(appWidgetId).isEqualTo(expectedWidgetInfo.appWidgetId) + } + } finally { + mockitoSession.finishMocking() + } + } + + @Test + @EnableFlags(FLAG_ENABLE_SUPPORT_FOR_ARCHIVING) + fun `When Archived Pending App Widget then checkAndAddItem`() { + val mockitoSession = + ExtendedMockito.mockitoSession().mockStatic(Utilities::class.java).startMocking() + try { + // Given + val expectedProvider = "com.google.android.testApp/com.android.testApp.testAppProvider" + val expectedComponentName = ComponentName.unflattenFromString(expectedProvider) + val expectedPackage = expectedComponentName!!.packageName + mockPmHelper = + mock().apply { + whenever(isAppArchived(expectedPackage)).thenReturn(true) + } + mockCursor = + mock().apply { + itemType = ITEM_TYPE_APPWIDGET + id = 1 + user = UserHandle(1) + restoreFlag = FLAG_UI_NOT_READY + container = CONTAINER_DESKTOP + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(appWidgetProvider).thenReturn(expectedProvider) + whenever(appWidgetId).thenReturn(0) + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(options).thenReturn(0) + whenever(appWidgetSource).thenReturn(20) + whenever(applyCommonProperties(any())).thenCallRealMethod() + } + mInstallingPkgs = hashMapOf() + val inflationResult = + WidgetInflater.InflationResult( + type = WidgetInflater.TYPE_PENDING, + widgetInfo = null + ) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + + // When + itemProcessorUnderTest.processItem() + + // Then + verify(mockCursor).checkAndAddItem(any(), any()) + } finally { + mockitoSession.finishMocking() + } + } + + @Test + fun `When widget inflation result is TYPE_DELETE then mark deleted`() { + // Given + val expectedProvider = "com.google.android.testApp/com.android.testApp.testAppProvider" + val expectedComponentName = ComponentName.unflattenFromString(expectedProvider) + val expectedPackage = expectedComponentName!!.packageName + mockPmHelper = + mock().apply { + whenever(isAppArchived(expectedPackage)).thenReturn(true) + } + mockCursor = + mock().apply { + itemType = ITEM_TYPE_APPWIDGET + id = 1 + user = UserHandle(1) + container = CONTAINER_DESKTOP + whenever(spanX).thenReturn(2) + whenever(spanY).thenReturn(1) + whenever(appWidgetProvider).thenReturn(expectedProvider) + whenever(isOnWorkspaceOrHotseat).thenCallRealMethod() + whenever(applyCommonProperties(any())).thenCallRealMethod() + } + mInstallingPkgs = hashMapOf() + val inflationResult = + WidgetInflater.InflationResult( + type = WidgetInflater.TYPE_DELETE, + widgetInfo = null, + reason = "test_delete_reason", + restoreErrorType = MISSING_WIDGET_PROVIDER + ) + mockWidgetInflater = + mock().apply { + whenever(inflateAppWidget(any())).thenReturn(inflationResult) + } + itemProcessorUnderTest = + createWorkspaceItemProcessorUnderTest(widgetProvidersMap = mWidgetProvidersMap) + + // When + itemProcessorUnderTest.processItem() + + // Then + verify(mockCursor).markDeleted(inflationResult.reason, inflationResult.restoreErrorType) + } }