From 33902557ec935b49d187af99abb4ad02a8582b34 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Mon, 14 Oct 2024 12:04:17 -0700 Subject: [PATCH 01/14] Set psDivider to gone in collapse due to updateAdapterItem suppression in test. Set PSDivider to gone during collapse animation. This is to help with https://android-build.corp.google.com/test_hub/search/?filter=&invfilter=unhealthyInvocations&invfilter=staleInvocations&query=test%3Acom.android.quickstep.TaplPrivateSpaceTest%23testPrivateSpaceLockingBehaviour&tab=clusterView&clusterId=12644122704855694316 tapl issue saying divider is there. This is because we suppress updateAdapterItem call and ps container contents aren't completely refreshed. This change is safe to do so anyways since floatingMaskView and decorator takes care of how the end result looks like. bug: 373427348 test: presubmit/tapl/manually Flag: NONE bugfixing for test flakiness Change-Id: Ia422096e022ab8de6745071707620192f03661a5 --- src/com/android/launcher3/allapps/PrivateProfileManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index e215cabcd7..e7881c4148 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -473,7 +473,8 @@ public class PrivateProfileManager extends UserProfileManager { break; } // Make the private space apps gone to "collapse". - if (mFloatingMaskView == null && isPrivateSpaceItem(currentItem)) { + if ((mFloatingMaskView == null && isPrivateSpaceItem(currentItem)) || + currentItem.viewType == VIEW_TYPE_PRIVATE_SPACE_SYS_APPS_DIVIDER) { RecyclerView.ViewHolder viewHolder = allAppsRecyclerView.findViewHolderForAdapterPosition(i); if (viewHolder != null) { From 6bb9d56ded70fed1335b36d3bc5fd99208990936 Mon Sep 17 00:00:00 2001 From: Gustav Sennton Date: Wed, 21 Aug 2024 14:55:38 +0000 Subject: [PATCH 02/14] Add animation runner for alt-tab desktop app launch Create a remote transition supporting alt-tab app-launches (app launches caused by a user using alt-tab to select a minimized app) and any minimization caused by hitting the window limit during such an app launch. Test: manual, and WindowAnimatorTest Bug: 349791584 Flag: com.android.window.flags.enable_desktop_app_launch_alttab_transitions Change-Id: I6474fff351f3d7681ca25cd7331e4955e3d1c6e0 --- .../desktop/DesktopAppLaunchTransition.kt | 166 ++++++++++++++++++ .../launcher3/desktop/WindowAnimator.kt | 100 +++++++++++ .../KeyboardQuickSwitchViewController.java | 14 +- .../taskbar/TaskbarActivityContext.java | 23 ++- .../com/android/quickstep/SystemUiProxy.java | 4 +- .../quickstep/desktop/WindowAnimatorTest.kt | 139 +++++++++++++++ 6 files changed, 435 insertions(+), 11 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt create mode 100644 quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt create mode 100644 quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt diff --git a/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt new file mode 100644 index 0000000000..dd2ff2d580 --- /dev/null +++ b/quickstep/src/com/android/launcher3/desktop/DesktopAppLaunchTransition.kt @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.desktop + +import android.animation.Animator +import android.animation.AnimatorSet +import android.animation.ValueAnimator +import android.content.Context +import android.os.IBinder +import android.view.SurfaceControl.Transaction +import android.view.WindowManager.TRANSIT_OPEN +import android.view.WindowManager.TRANSIT_TO_BACK +import android.view.WindowManager.TRANSIT_TO_FRONT +import android.window.IRemoteTransitionFinishedCallback +import android.window.RemoteTransitionStub +import android.window.TransitionInfo +import android.window.TransitionInfo.Change +import androidx.core.animation.addListener +import com.android.app.animation.Interpolators +import com.android.quickstep.RemoteRunnable +import java.util.concurrent.Executor + +/** + * [android.window.RemoteTransition] for Desktop app launches. + * + * This transition supports minimize-changes, i.e. in a launch-transition, if a window is moved back + * ([android.view.WindowManager.TRANSIT_TO_BACK]) this transition will apply a minimize animation to + * that window. + */ +class DesktopAppLaunchTransition(private val context: Context, private val mainExecutor: Executor) : + RemoteTransitionStub() { + + override fun startAnimation( + token: IBinder, + info: TransitionInfo, + t: Transaction, + transitionFinishedCallback: IRemoteTransitionFinishedCallback, + ) { + val safeTransitionFinishedCallback = RemoteRunnable { + transitionFinishedCallback.onTransitionFinished(/* wct= */ null, /* sct= */ null) + } + mainExecutor.execute { + runAnimators(info, safeTransitionFinishedCallback) + t.apply() + } + } + + private fun runAnimators(info: TransitionInfo, finishedCallback: RemoteRunnable) { + val animators = mutableListOf() + val animatorFinishedCallback: (Animator) -> Unit = { animator -> + animators -= animator + if (animators.isEmpty()) finishedCallback.run() + } + animators += createAnimators(info, animatorFinishedCallback) + animators.forEach { it.start() } + } + + private fun createAnimators( + info: TransitionInfo, + finishCallback: (Animator) -> Unit, + ): List { + val transaction = Transaction() + val launchAnimator = + createLaunchAnimator(getLaunchChange(info), transaction, finishCallback) + val minimizeChange = getMinimizeChange(info) ?: return listOf(launchAnimator) + val minimizeAnimator = createMinimizeAnimator(minimizeChange, transaction, finishCallback) + return listOf(launchAnimator, minimizeAnimator) + } + + private fun getLaunchChange(info: TransitionInfo): Change = + requireNotNull(info.changes.firstOrNull { change -> change.mode in LAUNCH_CHANGE_MODES }) { + "expected an app launch Change" + } + + private fun getMinimizeChange(info: TransitionInfo): Change? = + info.changes.firstOrNull { change -> change.mode == TRANSIT_TO_BACK } + + private fun createLaunchAnimator( + change: Change, + transaction: Transaction, + onAnimFinish: (Animator) -> Unit, + ): Animator { + val boundsAnimator = + WindowAnimator.createBoundsAnimator( + context, + launchBoundsAnimationDef, + change, + transaction, + ) + val alphaAnimator = + ValueAnimator.ofFloat(0f, 1f).apply { + duration = LAUNCH_ANIM_ALPHA_DURATION_MS + interpolator = Interpolators.LINEAR + addUpdateListener { animation -> + transaction.setAlpha(change.leash, animation.animatedValue as Float).apply() + } + } + return AnimatorSet().apply { + playTogether(boundsAnimator, alphaAnimator) + addListener(onEnd = { animation -> onAnimFinish(animation) }) + } + } + + private fun createMinimizeAnimator( + change: Change, + transaction: Transaction, + onAnimFinish: (Animator) -> Unit, + ): Animator { + val boundsAnimator = + WindowAnimator.createBoundsAnimator( + context, + minimizeBoundsAnimationDef, + change, + transaction, + ) + val alphaAnimator = + ValueAnimator.ofFloat(1f, 0f).apply { + duration = MINIMIZE_ANIM_ALPHA_DURATION_MS + interpolator = Interpolators.LINEAR + addUpdateListener { animation -> + transaction.setAlpha(change.leash, animation.animatedValue as Float).apply() + } + } + return AnimatorSet().apply { + playTogether(boundsAnimator, alphaAnimator) + addListener(onEnd = { animation -> onAnimFinish(animation) }) + } + } + + companion object { + private val LAUNCH_CHANGE_MODES = intArrayOf(TRANSIT_OPEN, TRANSIT_TO_FRONT) + + private const val LAUNCH_ANIM_ALPHA_DURATION_MS = 100L + private const val MINIMIZE_ANIM_ALPHA_DURATION_MS = 100L + + private val launchBoundsAnimationDef = + WindowAnimator.BoundsAnimationParams( + durationMs = 300, + startOffsetYDp = 12f, + startScale = 0.97f, + interpolator = Interpolators.STANDARD_DECELERATE, + ) + + private val minimizeBoundsAnimationDef = + WindowAnimator.BoundsAnimationParams( + durationMs = 200, + endOffsetYDp = 12f, + endScale = 0.97f, + interpolator = Interpolators.STANDARD_ACCELERATE, + ) + } +} diff --git a/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt b/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt new file mode 100644 index 0000000000..1a99a36b4c --- /dev/null +++ b/quickstep/src/com/android/launcher3/desktop/WindowAnimator.kt @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.desktop + +import android.animation.RectEvaluator +import android.animation.ValueAnimator +import android.content.Context +import android.graphics.Rect +import android.util.TypedValue +import android.view.SurfaceControl +import android.view.animation.Interpolator +import android.window.TransitionInfo + +/** Creates animations that can be applied to windows/surfaces. */ +object WindowAnimator { + + /** Parameters defining a window bounds animation. */ + data class BoundsAnimationParams( + val durationMs: Long, + val startOffsetYDp: Float = 0f, + val endOffsetYDp: Float = 0f, + val startScale: Float = 1f, + val endScale: Float = 1f, + val interpolator: Interpolator, + ) + + /** + * Creates an animator to reposition and scale the bounds of the leash of the given change. + * + * @param boundsAnimDef the parameters for the animation itself (duration, scale, position) + * @param change the change to which the animation should be applied + * @param transaction the transaction to apply the animation to + */ + fun createBoundsAnimator( + context: Context, + boundsAnimDef: BoundsAnimationParams, + change: TransitionInfo.Change, + transaction: SurfaceControl.Transaction, + ): ValueAnimator { + val startBounds = + createBounds( + context, + change.startAbsBounds, + boundsAnimDef.startScale, + boundsAnimDef.startOffsetYDp, + ) + val leash = change.leash + val endBounds = + createBounds( + context, + change.startAbsBounds, + boundsAnimDef.endScale, + boundsAnimDef.endOffsetYDp, + ) + return ValueAnimator.ofObject(RectEvaluator(), startBounds, endBounds).apply { + duration = boundsAnimDef.durationMs + interpolator = boundsAnimDef.interpolator + addUpdateListener { animation -> + val animBounds = animation.animatedValue as Rect + val animScale = 1 - (1 - boundsAnimDef.endScale) * animation.animatedFraction + transaction + .setPosition(leash, animBounds.left.toFloat(), animBounds.top.toFloat()) + .setScale(leash, animScale, animScale) + .apply() + } + } + } + + private fun createBounds(context: Context, origBounds: Rect, scale: Float, offsetYDp: Float) = + Rect(origBounds).apply { + check(scale in 0.0..1.0) + // Scale the bounds down with an anchor in the center + inset( + (origBounds.width().toFloat() * (1 - scale) / 2).toInt(), + (origBounds.height().toFloat() * (1 - scale) / 2).toInt(), + ) + val offsetYPx = + TypedValue.applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + offsetYDp, + context.resources.displayMetrics, + ) + .toInt() + offset(/* dx= */ 0, offsetYPx) + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java index 1c8a094c06..a80c11cc17 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.taskbar; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import android.animation.Animator; @@ -31,6 +32,7 @@ import androidx.annotation.Nullable; import com.android.internal.jank.Cuj; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; +import com.android.launcher3.desktop.DesktopAppLaunchTransition; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.taskbar.overlay.TaskbarOverlayDragLayer; import com.android.launcher3.views.BaseDragLayer; @@ -41,6 +43,7 @@ import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.QuickStepContract; +import com.android.window.flags.Flags; import java.io.PrintWriter; import java.util.List; @@ -181,7 +184,7 @@ public class KeyboardQuickSwitchViewController { Runnable onFinishCallback = () -> InteractionJankMonitorWrapper.end( Cuj.CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH); TaskbarActivityContext context = mControllers.taskbarActivityContext; - RemoteTransition remoteTransition = new RemoteTransition(new SlideInRemoteTransition( + final RemoteTransition slideInTransition = new RemoteTransition(new SlideInRemoteTransition( Utilities.isRtl(mControllers.taskbarActivityContext.getResources()), context.getDeviceProfile().overviewPageSpacing, QuickStepContract.getWindowCornerRadius(context), @@ -195,7 +198,7 @@ public class KeyboardQuickSwitchViewController { SystemUiProxy.INSTANCE.get(mKeyboardQuickSwitchView.getContext()) .showDesktopApps( mKeyboardQuickSwitchView.getDisplay().getDisplayId(), - remoteTransition)); + slideInTransition)); return -1; } // Even with a valid index, this can be null if the user tries to quick switch before the @@ -208,6 +211,13 @@ public class KeyboardQuickSwitchViewController { // Ignore attempts to run the selected task if it is already running. return -1; } + RemoteTransition remoteTransition = slideInTransition; + if (mOnDesktop && task.task1.isMinimized + && Flags.enableDesktopAppLaunchAlttabTransitions()) { + // This app is being unminimized - use our own transition runner. + remoteTransition = new RemoteTransition( + new DesktopAppLaunchTransition(context, MAIN_EXECUTOR)); + } mControllers.taskbarActivityContext.handleGroupTaskLaunch( task, remoteTransition, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 1b9614a33a..56c00cba92 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -1234,7 +1234,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } } else if (tag instanceof TaskItemInfo info) { UI_HELPER_EXECUTOR.execute(() -> - SystemUiProxy.INSTANCE.get(this).showDesktopApp(info.getTaskId())); + SystemUiProxy.INSTANCE.get(this).showDesktopApp( + info.getTaskId(), /* remoteTransition= */ null)); mControllers.taskbarStashController.updateAndAnimateTransientTaskbar( /* stash= */ true); } else if (tag instanceof WorkspaceItemInfo) { @@ -1325,7 +1326,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { GroupTask task, @Nullable RemoteTransition remoteTransition, boolean onDesktop) { - handleGroupTaskLaunch(task, remoteTransition, onDesktop, null, null); + handleGroupTaskLaunch(task, remoteTransition, onDesktop, + /* onStartCallback= */ null, /* onFinishCallback= */ null); } /** @@ -1349,17 +1351,24 @@ public class TaskbarActivityContext extends BaseTaskbarContext { UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(this).showDesktopApps(getDisplay().getDisplayId(), remoteTransition)); - } else if (onDesktop) { + return; + } + if (onDesktop) { + boolean useRemoteTransition = task.task1.isMinimized + && com.android.window.flags.Flags.enableDesktopAppLaunchAlttabTransitions(); UI_HELPER_EXECUTOR.execute(() -> { if (onStartCallback != null) { onStartCallback.run(); } - SystemUiProxy.INSTANCE.get(this).showDesktopApp(task.task1.key.id); + SystemUiProxy.INSTANCE.get(this).showDesktopApp( + task.task1.key.id, useRemoteTransition ? remoteTransition : null); if (onFinishCallback != null) { onFinishCallback.run(); } }); - } else if (task.task2 == null) { + return; + } + if (task.task2 == null) { UI_HELPER_EXECUTOR.execute(() -> { ActivityOptions activityOptions = makeDefaultActivityOptions(SPLASH_SCREEN_STYLE_UNDEFINED).options; @@ -1368,9 +1377,9 @@ public class TaskbarActivityContext extends BaseTaskbarContext { ActivityManagerWrapper.getInstance().startActivityFromRecents( task.task1.key, activityOptions); }); - } else { - mControllers.uiController.launchSplitTasks(task, remoteTransition); + return; } + mControllers.uiController.launchSplitTasks(task, remoteTransition); } /** diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 5f028937b0..4721648f62 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -1436,10 +1436,10 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { /** * If task with the given id is on the desktop, bring it to front */ - public void showDesktopApp(int taskId) { + public void showDesktopApp(int taskId, @Nullable RemoteTransition transition) { if (mDesktopMode != null) { try { - mDesktopMode.showDesktopApp(taskId); + mDesktopMode.showDesktopApp(taskId, transition); } catch (RemoteException e) { Log.w(TAG, "Failed call showDesktopApp", e); } diff --git a/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt b/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt new file mode 100644 index 0000000000..e5e6df3b1e --- /dev/null +++ b/quickstep/tests/src/com/android/quickstep/desktop/WindowAnimatorTest.kt @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.quickstep.desktop + +import android.animation.ValueAnimator +import android.content.Context +import android.content.res.Resources +import android.graphics.Rect +import android.util.DisplayMetrics +import android.view.SurfaceControl +import android.window.TransitionInfo +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread +import com.android.app.animation.Interpolators +import com.android.launcher3.desktop.WindowAnimator +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers.any +import org.mockito.ArgumentMatchers.anyFloat +import org.mockito.kotlin.mock +import org.mockito.kotlin.whenever + +@SmallTest +@RunWith(AndroidJUnit4::class) +class WindowAnimatorTest { + + private val context = mock() + private val resources = mock() + private val transaction = mock() + private val change = mock() + private val leash = mock() + + private val displayMetrics = DisplayMetrics().apply { density = 1f } + + @Before + fun setup() { + whenever(context.resources).thenReturn(resources) + whenever(resources.displayMetrics).thenReturn(displayMetrics) + whenever(change.leash).thenReturn(leash) + whenever(change.startAbsBounds).thenReturn(START_BOUNDS) + whenever(transaction.setPosition(any(), anyFloat(), anyFloat())).thenReturn(transaction) + whenever(transaction.setScale(any(), anyFloat(), anyFloat())).thenReturn(transaction) + } + + @Test + fun createBoundsAnimator_returnsCorrectDefaultAnimatorParams() = runOnUiThread { + val boundsAnimParams = + WindowAnimator.BoundsAnimationParams( + durationMs = 100L, + interpolator = Interpolators.STANDARD_ACCELERATE, + ) + + val valueAnimator = + WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction) + + assertThat(valueAnimator.duration).isEqualTo(100L) + assertThat(valueAnimator.interpolator).isEqualTo(Interpolators.STANDARD_ACCELERATE) + assertStartAndEndBounds(valueAnimator, startBounds = START_BOUNDS, endBounds = START_BOUNDS) + } + + @Test + fun createBoundsAnimator_startScaleAndOffset_returnsCorrectBounds() = runOnUiThread { + val bounds = Rect(/* left= */ 100, /* top= */ 200, /* right= */ 300, /* bottom= */ 400) + whenever(change.startAbsBounds).thenReturn(bounds) + val boundsAnimParams = + WindowAnimator.BoundsAnimationParams( + durationMs = 100L, + startOffsetYDp = 10f, + startScale = 0.5f, + interpolator = Interpolators.STANDARD_ACCELERATE, + ) + + val valueAnimator = + WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction) + + assertStartAndEndBounds( + valueAnimator, + startBounds = + Rect(/* left= */ 150, /* top= */ 260, /* right= */ 250, /* bottom= */ 360), + endBounds = bounds, + ) + } + + @Test + fun createBoundsAnimator_endScaleAndOffset_returnsCorrectBounds() = runOnUiThread { + val bounds = Rect(/* left= */ 100, /* top= */ 200, /* right= */ 300, /* bottom= */ 400) + whenever(change.startAbsBounds).thenReturn(bounds) + val boundsAnimParams = + WindowAnimator.BoundsAnimationParams( + durationMs = 100L, + endOffsetYDp = 10f, + endScale = 0.5f, + interpolator = Interpolators.STANDARD_ACCELERATE, + ) + + val valueAnimator = + WindowAnimator.createBoundsAnimator(context, boundsAnimParams, change, transaction) + + assertStartAndEndBounds( + valueAnimator, + startBounds = bounds, + endBounds = Rect(/* left= */ 150, /* top= */ 260, /* right= */ 250, /* bottom= */ 360), + ) + } + + private fun assertStartAndEndBounds( + valueAnimator: ValueAnimator, + startBounds: Rect, + endBounds: Rect, + ) { + valueAnimator.start() + valueAnimator.animatedValue + assertThat(valueAnimator.animatedValue).isEqualTo(startBounds) + valueAnimator.end() + assertThat(valueAnimator.animatedValue).isEqualTo(endBounds) + } + + companion object { + private val START_BOUNDS = + Rect(/* left= */ 10, /* top= */ 20, /* right= */ 30, /* bottom= */ 40) + } +} From f4a21b7e5c132b6a67c4882f4cc3423911cf6eab Mon Sep 17 00:00:00 2001 From: Jordan Silva Date: Mon, 14 Oct 2024 11:59:18 +0100 Subject: [PATCH 03/14] Fix RecentsView crash when DesktopTask has only 1 task and it is in split mode This CL fixes a crash happening when no other task is available in Desktop Windowing (DW), and the only task in DW is selected to be part of the pair (split mode). The crash is happening because of the following logic: - applyLoadPlan skips the staged tasks (for split) from the groupTask when adding the TaskViews to RecentsView. - If a groupTask has multiple tasks, and one of the tasks is staged, groupTask will be treated as a single task and applyLoadPlan uses the other task (not staged) to create a single TaskView in Overview. - DesktopTasks returns true for hasMultipleTasks, even when only 1 task is in DW mode. This causes a crash when the only task available in DW is staged for split. This fix will skip DesktopTaskView creation when split selection is active. In addition, it updates DesktopTask to report multiple tasks only when more than 1 task is its task list. Fix: 372357270 Fix: 372375086 Fix: 372864249 Flag: EXEMPT bugfix Test: Manual. Instructions on bug report. Change-Id: I95e32252a5cac4f6b99296422703d69d129a5a47 --- .../taskbar/TaskbarRecentAppsController.kt | 2 +- .../com/android/launcher3/taskbar/TaskbarView.java | 6 +++--- .../src/com/android/quickstep/util/DesktopTask.java | 5 +++++ .../src/com/android/quickstep/util/GroupTask.java | 7 +++++++ .../com/android/quickstep/views/RecentsView.java | 13 ++++++++----- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt index 9c34ff0eb8..3e8b615b69 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt @@ -251,7 +251,7 @@ class TaskbarRecentAppsController(context: Context, private val recentsModel: Re // Remove any newly-missing Tasks, and actual group-tasks val newShownTasks = shownTasks - .filter { !it.hasMultipleTasks() } + .filter { !it.supportsMultipleTasks() } .filter { it.task1.key.id in desktopTaskIds } .toMutableList() // Add any new Tasks, maintaining the order from previous shownTasks. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index ec9416017e..081100c0ee 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -65,8 +65,8 @@ import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.IconButtonView; -import com.android.quickstep.util.DesktopTask; import com.android.quickstep.util.GroupTask; +import com.android.quickstep.views.TaskViewType; import com.android.systemui.shared.recents.model.Task; import com.android.wm.shell.shared.bubbles.BubbleBarLocation; @@ -453,8 +453,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar // Replace any Recent views with the appropriate type if it's not already that type. final int expectedLayoutResId; boolean isCollection = false; - if (task.hasMultipleTasks()) { - if (task instanceof DesktopTask) { + if (task.supportsMultipleTasks()) { + if (task.taskViewType == TaskViewType.DESKTOP) { // TODO(b/316004172): use Desktop tile layout. expectedLayoutResId = -1; } else { diff --git a/quickstep/src/com/android/quickstep/util/DesktopTask.java b/quickstep/src/com/android/quickstep/util/DesktopTask.java index a727aa2efb..fc4fc4df78 100644 --- a/quickstep/src/com/android/quickstep/util/DesktopTask.java +++ b/quickstep/src/com/android/quickstep/util/DesktopTask.java @@ -50,6 +50,11 @@ public class DesktopTask extends GroupTask { @Override public boolean hasMultipleTasks() { + return tasks.size() > 1; + } + + @Override + public boolean supportsMultipleTasks() { return true; } diff --git a/quickstep/src/com/android/quickstep/util/GroupTask.java b/quickstep/src/com/android/quickstep/util/GroupTask.java index fba08a96b2..7aeeb2fc32 100644 --- a/quickstep/src/com/android/quickstep/util/GroupTask.java +++ b/quickstep/src/com/android/quickstep/util/GroupTask.java @@ -65,6 +65,13 @@ public class GroupTask { return task2 != null; } + /** + * Returns whether this task supports multiple tasks or not. + */ + public boolean supportsMultipleTasks() { + return taskViewType == TaskViewType.GROUPED; + } + /** * Returns a List of all the Tasks in this GroupTask */ diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 7554c4496a..e84aabcf1c 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1885,19 +1885,22 @@ public abstract class RecentsView< // taskGroups backwards populates the thumbnail grid from least recent to most recent. for (int i = taskGroups.size() - 1; i >= 0; i--) { GroupTask groupTask = taskGroups.get(i); - boolean isRemovalNeeded = stagedTaskIdToBeRemoved != INVALID_TASK_ID + boolean containsStagedTask = stagedTaskIdToBeRemoved != INVALID_TASK_ID && groupTask.containsTask(stagedTaskIdToBeRemoved); + boolean shouldSkipGroupTask = containsStagedTask && !groupTask.hasMultipleTasks(); - if (isRemovalNeeded && !groupTask.hasMultipleTasks()) { - // If the task we need to remove is not part of a pair, avoiding creating the - // TaskView. + if ((isSplitSelectionActive() && groupTask.taskViewType == TaskViewType.DESKTOP) + || shouldSkipGroupTask) { + // To avoid these tasks from being chosen as the app pair, the creation of a + // TaskView is bypassed. The staged task is already selected for the app pair, + // and the Desktop task should be hidden when selecting a pair. continue; } // If we need to remove half of a pair of tasks, force a TaskView with Type.SINGLE // to be a temporary container for the remaining task. TaskView taskView = getTaskViewFromPool( - isRemovalNeeded ? TaskViewType.SINGLE : groupTask.taskViewType); + containsStagedTask ? TaskViewType.SINGLE : groupTask.taskViewType); if (taskView instanceof GroupedTaskView) { boolean firstTaskIsLeftTopTask = groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id; From 07669e9575f2d7b4e61865f8194debdc81fe53de Mon Sep 17 00:00:00 2001 From: Schneider Victor-Tulias Date: Wed, 16 Oct 2024 10:35:10 -0400 Subject: [PATCH 04/14] Improve test isolation in AbstractLauncherUiTests - Removing suspicious duplicate uses of AbstractLauncherUiTest.initialize to prevent unnecesary launcher restarts - Adding UiDevice#pressHome to AbstractLauncherUiTests.verifyLauncherState to ensure the next test starts with a known clean state Flag: EXEMPT test fix Fixes: 372956489 Test: AbstractLauncherUiTest Change-Id: Id68ece4ab195a4f6c47aa401eb50a91b8ff70e10 --- .../src/com/android/quickstep/TaplPrivateSpaceTest.java | 2 -- .../com/android/launcher3/ui/AbstractLauncherUiTest.java | 1 + .../src/com/android/launcher3/ui/TaplWorkProfileTest.java | 1 - .../android/launcher3/ui/workspace/TaplWorkspaceTest.java | 7 ------- 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java index 800fd4aa93..b15b78e305 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java +++ b/quickstep/tests/src/com/android/quickstep/TaplPrivateSpaceTest.java @@ -56,8 +56,6 @@ public class TaplPrivateSpaceTest extends AbstractQuickStepTest { @Override public void setUp() throws Exception { super.setUp(); - initialize(this); - createAndStartPrivateProfileUser(); mDevice.pressHome(); diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index cee88ac047..b02465e300 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -415,6 +415,7 @@ public abstract class AbstractLauncherUiTest { public void verifyLauncherState() { try { // Limits UI tests affecting tests running after them. + mDevice.pressHome(); mLauncher.waitForLauncherInitialized(); if (mLauncherPid != 0) { assertEquals("Launcher crashed, pid mismatch:", diff --git a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java index b38dd4ba11..a45e3bbb84 100644 --- a/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java +++ b/tests/src/com/android/launcher3/ui/TaplWorkProfileTest.java @@ -70,7 +70,6 @@ public class TaplWorkProfileTest extends AbstractLauncherUiTest { @Override public void setUp() throws Exception { super.setUp(); - initialize(this); String output = mDevice.executeShellCommand( "pm create-user --profileOf 0 --managed TestProfile"); diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java index 490cff20b4..237f2a97a7 100644 --- a/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java +++ b/tests/src/com/android/launcher3/ui/workspace/TaplWorkspaceTest.java @@ -32,7 +32,6 @@ import com.android.launcher3.util.TestUtil; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import org.junit.After; -import org.junit.Before; import org.junit.Test; /** @@ -50,12 +49,6 @@ public class TaplWorkspaceTest extends AbstractLauncherUiTest { return launcher.getWorkspace().getCurrentPage(); } - @Before - public void setUp() throws Exception { - super.setUp(); - initialize(this); - } - @After public void tearDown() throws Exception { if (mLauncherLayout != null) { From e37b479b17e38029c1b2aa580ef87763b94520b1 Mon Sep 17 00:00:00 2001 From: Wen-Chien Wang Date: Thu, 10 Oct 2024 22:52:00 +0000 Subject: [PATCH 05/14] Fixed the opened folder on taskbar when NotifShade is shown This cl fixes the bug by closing all abstract floating views including opened folders when the notification shade is shown. Usually this was handled in the folder class where it intercepted the touch event to close it by dispatching the back key, but this didn't work when the virtual keyboard existed. More context is added in the bug. Flag: EXEMPT bug fix Fixes: 267529599 Test: Ran on a 1P device Change-Id: Ifdd357668ece2c11888ecfc69af64b1742c07d6e --- .../android/launcher3/taskbar/TaskbarActivityContext.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 46d063b0f3..2086f667ae 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -949,6 +949,12 @@ public class TaskbarActivityContext extends BaseTaskbarContext { * Hides the taskbar icons and background when the notication shade is expanded. */ private void onNotificationShadeExpandChanged(boolean isExpanded, boolean skipAnim) { + // Close all floating views within the Taskbar window to make sure nothing is shown over + // the notification shade. + if (isExpanded) { + AbstractFloatingView.closeAllOpenViewsExcept(this, TYPE_TASKBAR_OVERLAY_PROXY); + } + float alpha = isExpanded ? 0 : 1; AnimatorSet anim = new AnimatorSet(); anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().get( @@ -1538,6 +1544,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { /** * Called when we want to unstash taskbar when user performs swipes up gesture. + * * @param delayTaskbarBackground whether we will delay the taskbar background animation */ public void onSwipeToUnstashTaskbar(boolean delayTaskbarBackground) { From a2dea77229c127fca30bc66ca825fbbf7904722f Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Thu, 12 Sep 2024 22:35:45 +0000 Subject: [PATCH 06/14] Using synthetic recents transitions for Recents in Window Bug: 366021931 Flag: com.android.launcher3.enable_fallback_overview_in_window Test: manual with enableFallbackOverviewInWindow=true Change-Id: I26fbc96373b55f0a4a87756fa99347f0e4f4361b --- quickstep/src/com/android/quickstep/GestureState.java | 11 +++++++++++ .../android/quickstep/RecentsAnimationCallbacks.java | 9 ++++++++- .../src/com/android/quickstep/SystemUiProxy.java | 5 ++++- .../com/android/quickstep/TaskAnimationManager.java | 9 +++++---- .../quickstep/util/SplitSelectStateController.java | 2 +- .../util/SplitWithKeyboardShortcutController.java | 3 ++- .../android/quickstep/TaskAnimationManagerTest.java | 5 +++-- 7 files changed, 34 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index 2892d2c913..015a449cc4 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -36,6 +36,7 @@ import android.view.RemoteAnimationTarget; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.Flags; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulContainer; import com.android.quickstep.TopTaskTracker.CachedTaskInfo; @@ -301,6 +302,16 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL return mTrackpadGestureType == TrackpadGestureType.FOUR_FINGER; } + /** + * Requests that handling for this gesture should use a synthetic transition, as in that it + * will need to start a recents transition that is not backed by a system transition. This is + * generally only needed in scenarios where a system transition can not be created due to no + * changes in the WM hierarchy (ie. starting recents transition when you are already over home). + */ + public boolean useSyntheticRecentsTransition() { + return mRunningTask.isHomeTask() && Flags.enableFallbackOverviewInWindow(); + } + /** * @return the running task for this gesture. */ diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java index fc11812f0e..7d5bd377d0 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java @@ -15,7 +15,9 @@ */ package com.android.quickstep; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.view.RemoteAnimationTarget.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; @@ -29,6 +31,7 @@ import androidx.annotation.BinderThread; import androidx.annotation.NonNull; import androidx.annotation.UiThread; +import com.android.launcher3.Flags; import com.android.launcher3.Utilities; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.ActiveGestureProtoLogProxy; @@ -102,7 +105,11 @@ public class RecentsAnimationCallbacks implements long appCount = Arrays.stream(appTargets) .filter(app -> app.mode == MODE_CLOSING) .count(); - if (appCount == 0) { + + boolean isOpeningHome = Arrays.stream(appTargets).filter(app -> app.mode == MODE_OPENING + && app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME) + .count() > 0; + if (appCount == 0 && (!Flags.enableFallbackOverviewInWindow() || isOpeningHome)) { ActiveGestureProtoLogProxy.logOnRecentsAnimationStartCancelled(); // Edge case, if there are no closing app targets, then Launcher has nothing to handle notifyAnimationCanceled(); diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index c66813fe8b..14b4d60ca7 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -1535,7 +1535,7 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { * Starts the recents activity. The caller should manage the thread on which this is called. */ public boolean startRecentsActivity(Intent intent, ActivityOptions options, - RecentsAnimationListener listener) { + RecentsAnimationListener listener, boolean useSyntheticRecentsTransition) { if (mRecentTasks == null) { ActiveGestureProtoLogProxy.logRecentTasksMissing(); return false; @@ -1566,6 +1566,9 @@ public class SystemUiProxy implements ISystemUiProxy, NavHandle, SafeCloseable { } }; final Bundle optsBundle = options.toBundle(); + if (useSyntheticRecentsTransition) { + optsBundle.putBoolean("is_synthetic_recents_transition", true); + } try { mRecentTasks.startRecentsTransition(mRecentsPendingIntent, intent, optsBundle, mContext.getIApplicationThread(), runner); diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index bda292af01..56c978a318 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -296,8 +296,8 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn // TODO:(b/365777482) if flag is enabled, but on launcher it will crash. if(containerInterface.getCreatedContainer() instanceof RecentsWindowManager && Flags.enableFallbackOverviewInWindow()){ - mRecentsAnimationStartPending = - getSystemUiProxy().startRecentsActivity(intent, options, mCallbacks); + mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, options, + mCallbacks, gestureState.useSyntheticRecentsTransition()); mRecentsWindowsManager.startRecentsWindow(mCallbacks); } else { options.setPendingIntentBackgroundActivityStartMode( @@ -326,9 +326,10 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn }); } - mRecentsAnimationStartPending = getSystemUiProxy() - .startRecentsActivity(intent, options, mCallbacks); + mRecentsAnimationStartPending = getSystemUiProxy().startRecentsActivity(intent, + options, mCallbacks, false /* useSyntheticRecentsTransition */); } + if (enableHandleDelayedGestureCallbacks()) { ActiveGestureProtoLogProxy.logSettingRecentsAnimationStartPending( mRecentsAnimationStartPending); diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 511c989928..ea582c493f 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -900,7 +900,7 @@ public class SplitSelectStateController { SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) .startRecentsActivity( mOverviewComponentObserver.getOverviewIntent(), options, - callbacks); + callbacks, false /* useSyntheticRecentsTransition */); }); } diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java index 4c6e4ff359..744c08cc3c 100644 --- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java +++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java @@ -99,7 +99,8 @@ public class SplitWithKeyboardShortcutController { options.setTransientLaunch(); SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()) .startRecentsActivity(mOverviewComponentObserver.getOverviewIntent(), - ActivityOptions.makeBasic(), callbacks); + ActivityOptions.makeBasic(), callbacks, + false /* useSyntheticRecentsTransition */); }); }); } diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java index ec07b9310e..633a5756c2 100644 --- a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java +++ b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java @@ -17,8 +17,8 @@ package com.android.quickstep; import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -73,7 +73,8 @@ public class TaskAnimationManagerTest { final ArgumentCaptor optionsCaptor = ArgumentCaptor.forClass(ActivityOptions.class); - verify(mSystemUiProxy).startRecentsActivity(any(), optionsCaptor.capture(), any()); + verify(mSystemUiProxy) + .startRecentsActivity(any(), optionsCaptor.capture(), any(), anyBoolean()); assertEquals(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOW_ALWAYS, optionsCaptor.getValue().getPendingIntentBackgroundActivityStartMode()); } From fc6cc4e4093a902d4fe19c3b1dd5157ba7595daa Mon Sep 17 00:00:00 2001 From: Sukesh Ram Date: Wed, 16 Oct 2024 16:55:45 -0700 Subject: [PATCH 07/14] Cleanup for TAPL Debugging Cleaning up leftover log statements. Flag: EXEMPT bugfix Bug: 324419890 Test: Manual Change-Id: I54145d07f0699f68c44aaa34e1692c8fe2f7b780 --- .../launcher3/testing/shared/TestProtocol.java | 1 - .../android/launcher3/ui/AbstractLauncherUiTest.java | 11 ----------- 2 files changed, 12 deletions(-) diff --git a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java index 4e9143e050..825b52b5fb 100644 --- a/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java +++ b/tests/multivalentTests/shared/com/android/launcher3/testing/shared/TestProtocol.java @@ -167,7 +167,6 @@ public final class TestProtocol { public static final String PERMANENT_DIAG_TAG = "TaplTarget"; public static final String ICON_MISSING = "b/282963545"; - public static final String WIDGET_CONFIG_NULL_EXTRA_INTENT = "b/324419890"; public static final String REQUEST_FLAG_ENABLE_GRID_ONLY_OVERVIEW = "enable-grid-only-overview"; public static final String REQUEST_FLAG_ENABLE_APP_PAIRS = "enable-app-pairs"; diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index cee88ac047..df5c80d9e8 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -20,7 +20,6 @@ import static android.platform.test.flag.junit.SetFlagsRule.DefaultInitValueType import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.testing.shared.TestProtocol.ICON_MISSING; -import static com.android.launcher3.testing.shared.TestProtocol.WIDGET_CONFIG_NULL_EXTRA_INTENT; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static org.junit.Assert.assertEquals; @@ -563,23 +562,13 @@ public abstract class AbstractLauncherUiTest { @Override public void onReceive(Context context, Intent intent) { - Log.d(WIDGET_CONFIG_NULL_EXTRA_INTENT, intent == null - ? "AbstractLauncherUiTest.onReceive(): inputted intent NULL" - : "AbstractLauncherUiTest.onReceive(): inputted intent NOT NULL"); mIntent = intent; latch.countDown(); - Log.d(WIDGET_CONFIG_NULL_EXTRA_INTENT, - "AbstractLauncherUiTest.onReceive() Countdown Latch started"); } public Intent blockingGetIntent() throws InterruptedException { - Log.d(WIDGET_CONFIG_NULL_EXTRA_INTENT, - "AbstractLauncherUiTest.blockingGetIntent()"); assertTrue("Timed Out", latch.await(DEFAULT_BROADCAST_TIMEOUT_SECS, TimeUnit.SECONDS)); mTargetContext.unregisterReceiver(this); - Log.d(WIDGET_CONFIG_NULL_EXTRA_INTENT, mIntent == null - ? "AbstractLauncherUiTest.onReceive(): mIntent NULL" - : "AbstractLauncherUiTest.onReceive(): mIntent NOT NULL"); return mIntent; } From 7cbcaa7b6785d91b7b845f07d44ad64ca57afe74 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 16 Oct 2024 18:08:40 -0700 Subject: [PATCH 08/14] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie3e674cb84d50b961c50a5beb5616fbd002957db --- quickstep/res/values-af/strings.xml | 4 ++++ quickstep/res/values-am/strings.xml | 4 ++++ quickstep/res/values-ar/strings.xml | 4 ++++ quickstep/res/values-as/strings.xml | 4 ++++ quickstep/res/values-az/strings.xml | 4 ++++ quickstep/res/values-b+sr+Latn/strings.xml | 4 ++++ quickstep/res/values-be/strings.xml | 4 ++++ quickstep/res/values-bg/strings.xml | 4 ++++ quickstep/res/values-bn/strings.xml | 4 ++++ quickstep/res/values-bs/strings.xml | 4 ++++ quickstep/res/values-ca/strings.xml | 4 ++++ quickstep/res/values-cs/strings.xml | 4 ++++ quickstep/res/values-da/strings.xml | 4 ++++ quickstep/res/values-de/strings.xml | 4 ++++ quickstep/res/values-el/strings.xml | 4 ++++ quickstep/res/values-en-rAU/strings.xml | 4 ++++ quickstep/res/values-en-rCA/strings.xml | 2 ++ quickstep/res/values-en-rGB/strings.xml | 4 ++++ quickstep/res/values-en-rIN/strings.xml | 4 ++++ quickstep/res/values-es-rUS/strings.xml | 4 ++++ quickstep/res/values-es/strings.xml | 4 ++++ quickstep/res/values-et/strings.xml | 4 ++++ quickstep/res/values-eu/strings.xml | 4 ++++ quickstep/res/values-fa/strings.xml | 4 ++++ quickstep/res/values-fi/strings.xml | 4 ++++ quickstep/res/values-fr-rCA/strings.xml | 4 ++++ quickstep/res/values-fr/strings.xml | 4 ++++ quickstep/res/values-gl/strings.xml | 4 ++++ quickstep/res/values-gu/strings.xml | 4 ++++ quickstep/res/values-hi/strings.xml | 4 ++++ quickstep/res/values-hr/strings.xml | 4 ++++ quickstep/res/values-hu/strings.xml | 4 ++++ quickstep/res/values-hy/strings.xml | 4 ++++ quickstep/res/values-in/strings.xml | 4 ++++ quickstep/res/values-is/strings.xml | 4 ++++ quickstep/res/values-it/strings.xml | 4 ++++ quickstep/res/values-iw/strings.xml | 4 ++++ quickstep/res/values-ja/strings.xml | 4 ++++ quickstep/res/values-ka/strings.xml | 4 ++++ quickstep/res/values-kk/strings.xml | 4 ++++ quickstep/res/values-km/strings.xml | 4 ++++ quickstep/res/values-kn/strings.xml | 4 ++++ quickstep/res/values-ko/strings.xml | 4 ++++ quickstep/res/values-ky/strings.xml | 4 ++++ quickstep/res/values-lo/strings.xml | 4 ++++ quickstep/res/values-lt/strings.xml | 3 +++ quickstep/res/values-lv/strings.xml | 4 ++++ quickstep/res/values-mk/strings.xml | 4 ++++ quickstep/res/values-ml/strings.xml | 4 ++++ quickstep/res/values-mn/strings.xml | 4 ++++ quickstep/res/values-mr/strings.xml | 4 ++++ quickstep/res/values-ms/strings.xml | 4 ++++ quickstep/res/values-my/strings.xml | 4 ++++ quickstep/res/values-nb/strings.xml | 4 ++++ quickstep/res/values-ne/strings.xml | 4 ++++ quickstep/res/values-nl/strings.xml | 4 ++++ quickstep/res/values-or/strings.xml | 4 ++++ quickstep/res/values-pa/strings.xml | 4 ++++ quickstep/res/values-pl/strings.xml | 4 ++++ quickstep/res/values-pt-rPT/strings.xml | 4 ++++ quickstep/res/values-pt/strings.xml | 4 ++++ quickstep/res/values-ro/strings.xml | 4 ++++ quickstep/res/values-ru/strings.xml | 4 ++++ quickstep/res/values-si/strings.xml | 4 ++++ quickstep/res/values-sk/strings.xml | 4 ++++ quickstep/res/values-sl/strings.xml | 4 ++++ quickstep/res/values-sq/strings.xml | 4 ++++ quickstep/res/values-sr/strings.xml | 4 ++++ quickstep/res/values-sv/strings.xml | 4 ++++ quickstep/res/values-sw/strings.xml | 4 ++++ quickstep/res/values-ta/strings.xml | 4 ++++ quickstep/res/values-te/strings.xml | 4 ++++ quickstep/res/values-th/strings.xml | 4 ++++ quickstep/res/values-tl/strings.xml | 4 ++++ quickstep/res/values-tr/strings.xml | 4 ++++ quickstep/res/values-uk/strings.xml | 4 ++++ quickstep/res/values-ur/strings.xml | 4 ++++ quickstep/res/values-uz/strings.xml | 4 ++++ quickstep/res/values-vi/strings.xml | 4 ++++ quickstep/res/values-zh-rCN/strings.xml | 4 ++++ quickstep/res/values-zh-rHK/strings.xml | 4 ++++ quickstep/res/values-zh-rTW/strings.xml | 4 ++++ quickstep/res/values-zu/strings.xml | 4 ++++ 83 files changed, 329 insertions(+) diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml index ed90c85bc5..5cbe55638e 100644 --- a/quickstep/res/values-af/strings.xml +++ b/quickstep/res/values-af/strings.xml @@ -22,6 +22,8 @@ "Speld vas" "Vormvry" "Rekenaar" + + "Werkskerm" "Geen onlangse items nie" "Programgebruikinstellings" @@ -154,4 +156,6 @@ "Maak almal toe" "vou %1$s uit" "vou %1$s in" + + diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 0848ddd48e..ce12f9da4a 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -22,6 +22,8 @@ "ሰካ" "ነፃ ቅጽ" "ዴስክቶፕ" + + "ዴስክቶፕ" "ምንም የቅርብ ጊዜ ንጥሎች የሉም" "የመተግበሪያ አጠቃቀም ቅንብሮች" @@ -154,4 +156,6 @@ "ሁሉንም አሰናብት" "%1$sን ዘርጋ" "%1$sን ሰብስብ" + + diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml index 501654f0eb..0f3a854c14 100644 --- a/quickstep/res/values-ar/strings.xml +++ b/quickstep/res/values-ar/strings.xml @@ -22,6 +22,8 @@ "تثبيت" "شكل مجاني" "الكمبيوتر المكتبي" + + "كمبيوتر مكتبي" "ما مِن عناصر تم استخدامها مؤخرًا" "إعدادات استخدام التطبيق" @@ -154,4 +156,6 @@ "إغلاق الكل" "توسيع %1$s" "تصغير %1$s" + + diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index 1dbab02d17..1d536e840d 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -22,6 +22,8 @@ "পিন" "Freeform" "ডেস্কটপ" + + "ডেস্কটপ" "কোনো শেহতীয়া বস্তু নাই" "এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিং" @@ -154,4 +156,6 @@ "সকলো অগ্ৰাহ্য কৰক" "%1$s বিস্তাৰ কৰক" "%1$s সংকোচন কৰক" + + diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml index e211463c0c..2e6337a71f 100644 --- a/quickstep/res/values-az/strings.xml +++ b/quickstep/res/values-az/strings.xml @@ -22,6 +22,8 @@ "Sancın" "Sərbəst rejim" "Masaüstü" + + "Masaüstü" "Son elementlər yoxdur" "Tətbiq istifadə ayarları" @@ -154,4 +156,6 @@ "Hamısını kənarlaşdırın" "genişləndirin: %1$s" "yığcamlaşdırın: %1$s" + + diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index aa16f3c353..93a8d48283 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -22,6 +22,8 @@ "Zakači" "Slobodni oblik" "Računar" + + "Računari" "Nema nedavnih stavki" "Podešavanja korišćenja aplikacije" @@ -154,4 +156,6 @@ "Odbaci sve" "proširite oblačić %1$s" "skupite oblačić %1$s" + + diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index 4dcfe62c1c..3f5a6178a3 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -22,6 +22,8 @@ "Замацаваць" "Адвольная форма" "Працоўны стол" + + "Працоўны стол" "Няма новых элементаў" "Налады выкарыстання праграмы" @@ -154,4 +156,6 @@ "Закрыць усе" "%1$s: разгарнуць" "%1$s: згарнуць" + + diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml index 8ceef779a8..adabb31cbb 100644 --- a/quickstep/res/values-bg/strings.xml +++ b/quickstep/res/values-bg/strings.xml @@ -22,6 +22,8 @@ "Фиксиране" "Свободна форма" "За компютър" + + "Настолен компютър" "Няма скорошни елементи" "Настройки за използването на приложенията" @@ -154,4 +156,6 @@ "Отхвърляне на всички" "разгъване на %1$s" "свиване на %1$s" + + diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml index 14b86de345..7d93d9b323 100644 --- a/quickstep/res/values-bn/strings.xml +++ b/quickstep/res/values-bn/strings.xml @@ -22,6 +22,8 @@ "পিন করুন" "ফ্রি-ফর্ম" "ডেস্কটপ" + + "ডেস্কটপ" "কোনও সাম্প্রতিক আইটেম নেই" "অ্যাপ ব্যবহারের সেটিংস" @@ -154,4 +156,6 @@ "সব বাতিল করুন" "%1$s বড় করুন" "%1$s আড়াল করুন" + + diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index b60436cb10..2ac0ab1336 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -22,6 +22,8 @@ "Zakači" "Slobodan oblik" "Radna površina" + + "Radna površina" "Nema nedavnih stavki" "Postavke korištenja aplikacije" @@ -154,4 +156,6 @@ "Odbacivanje svega" "proširivanje oblačića %1$s" "sužavanje oblačića %1$s" + + diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml index 4447c019a1..1c27b08ddc 100644 --- a/quickstep/res/values-ca/strings.xml +++ b/quickstep/res/values-ca/strings.xml @@ -22,6 +22,8 @@ "Fixa" "Format lliure" "Escriptori" + + "Escriptori" "No hi ha cap element recent" "Configuració d\'ús d\'aplicacions" @@ -154,4 +156,6 @@ "Ignora-ho tot" "desplega %1$s" "replega %1$s" + + diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml index 711cbfa788..2f8d4b0b7b 100644 --- a/quickstep/res/values-cs/strings.xml +++ b/quickstep/res/values-cs/strings.xml @@ -22,6 +22,8 @@ "Připnout" "Neomezený režim" "Počítač" + + "Počítač" "Žádné položky z nedávné doby" "Nastavení využití aplikací" @@ -154,4 +156,6 @@ "Zavřít vše" "rozbalit %1$s" "sbalit %1$s" + + diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml index 2a5b34d838..4684af2df4 100644 --- a/quickstep/res/values-da/strings.xml +++ b/quickstep/res/values-da/strings.xml @@ -22,6 +22,8 @@ "Fastgør" "Frit format" "Computertilstand" + + "Computer" "Ingen nye elementer" "Indstillinger for appforbrug" @@ -154,4 +156,6 @@ "Afvis alle" "udvid %1$s" "skjul %1$s" + + diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 478a7a39ee..155abb4727 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -22,6 +22,8 @@ "Fixieren" "Freeform-Modus" "Desktopmodus" + + "Desktopmodus" "Keine kürzlich verwendeten Elemente" "Einstellungen zur App-Nutzung" @@ -154,4 +156,6 @@ "Alle schließen" "„%1$s“ maximieren" "„%1$s“ minimieren" + + diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml index e47b423bfb..39e891637d 100644 --- a/quickstep/res/values-el/strings.xml +++ b/quickstep/res/values-el/strings.xml @@ -22,6 +22,8 @@ "Καρφίτσωμα" "Ελεύθερη μορφή" "Υπολογιστής" + + "Υπολογιστής" "Δεν υπάρχουν πρόσφατα στοιχεία" "Ρυθμίσεις χρήσης εφαρμογής" @@ -154,4 +156,6 @@ "Παράβλεψη όλων" "ανάπτυξη %1$s" "σύμπτυξη %1$s" + + diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml index 04b04dde75..bc73bfe488 100644 --- a/quickstep/res/values-en-rAU/strings.xml +++ b/quickstep/res/values-en-rAU/strings.xml @@ -22,6 +22,8 @@ "Pin" "Freeform" "Desktop" + + "Desktop" "No recent items" "App usage settings" @@ -154,4 +156,6 @@ "Dismiss all" "expand %1$s" "collapse %1$s" + + diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml index e0787ca316..da4effbb2c 100644 --- a/quickstep/res/values-en-rCA/strings.xml +++ b/quickstep/res/values-en-rCA/strings.xml @@ -22,6 +22,7 @@ "Pin" "Freeform" "Desktop" + "Move to external display" "Desktop" "No recent items" "App usage settings" @@ -154,4 +155,5 @@ "Dismiss all" "expand %1$s" "collapse %1$s" + "Circle to Search" diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml index 04b04dde75..bc73bfe488 100644 --- a/quickstep/res/values-en-rGB/strings.xml +++ b/quickstep/res/values-en-rGB/strings.xml @@ -22,6 +22,8 @@ "Pin" "Freeform" "Desktop" + + "Desktop" "No recent items" "App usage settings" @@ -154,4 +156,6 @@ "Dismiss all" "expand %1$s" "collapse %1$s" + + diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml index 04b04dde75..bc73bfe488 100644 --- a/quickstep/res/values-en-rIN/strings.xml +++ b/quickstep/res/values-en-rIN/strings.xml @@ -22,6 +22,8 @@ "Pin" "Freeform" "Desktop" + + "Desktop" "No recent items" "App usage settings" @@ -154,4 +156,6 @@ "Dismiss all" "expand %1$s" "collapse %1$s" + + diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml index dd8de5fad4..25bbba27fa 100644 --- a/quickstep/res/values-es-rUS/strings.xml +++ b/quickstep/res/values-es-rUS/strings.xml @@ -22,6 +22,8 @@ "Fijar" "Formato libre" "Escritorio" + + "Computadoras" "No hay elementos recientes" "Configuración de uso de la app" @@ -154,4 +156,6 @@ "Descartar todo" "expandir %1$s" "contraer %1$s" + + diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index d8bbc55815..a4d7a8b1dc 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -22,6 +22,8 @@ "Fijar" "Formato libre" "Escritorio" + + "Ordenador" "No hay nada reciente" "Ajustes de uso de la aplicación" @@ -154,4 +156,6 @@ "Cerrar todo" "desplegar %1$s" "contraer %1$s" + + diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml index 114f3a187e..63d4d2fcfc 100644 --- a/quickstep/res/values-et/strings.xml +++ b/quickstep/res/values-et/strings.xml @@ -22,6 +22,8 @@ "Kinnita" "Vabavorm" "Lauaarvuti režiim" + + "Töölaud" "Hiljutisi üksusi pole" "Rakenduse kasutuse seaded" @@ -154,4 +156,6 @@ "Loobu kõigist" "Toiminguriba %1$s laiendamine" "Toiminguriba %1$s ahendamine" + + diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index 45fa5790d0..3c0698c158 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -22,6 +22,8 @@ "Ainguratu" "Modu librea" "Ordenagailua" + + "Mahaigaina" "Ez dago azkenaldi honetako ezer" "Aplikazioen erabileraren ezarpenak" @@ -154,4 +156,6 @@ "Baztertu guztiak" "zabaldu %1$s" "tolestu %1$s" + + diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index d3e38000d6..8d5d15e7e6 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -22,6 +22,8 @@ "پین" "Freeform" "حالت رایانه" + + "رایانه" "چیز جدیدی اینجا نیست" "تنظیمات استفاده از برنامه" @@ -154,4 +156,6 @@ "رد کردن همه" "ازهم باز کردن %1$s" "جمع کردن %1$s" + + diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml index 54a0c23e34..10ea9ee215 100644 --- a/quickstep/res/values-fi/strings.xml +++ b/quickstep/res/values-fi/strings.xml @@ -22,6 +22,8 @@ "Kiinnitä" "Vapaamuotoinen" "Tietokone" + + "Tietokone" "Ei viimeaikaisia kohteita" "Sovelluksen käyttöasetukset" @@ -154,4 +156,6 @@ "Hylkää kaikki" "laajenna %1$s" "tiivistä %1$s" + + diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml index 591c7b7f65..b624b4f73b 100644 --- a/quickstep/res/values-fr-rCA/strings.xml +++ b/quickstep/res/values-fr-rCA/strings.xml @@ -22,6 +22,8 @@ "Épingler" "Forme libre" "Ordinateur de bureau" + + "Ordinateur de bureau" "Aucun élément récent" "Paramètres d\'utilisation de l\'appli" @@ -154,4 +156,6 @@ "Tout ignorer" "Développer %1$s" "Réduire %1$s" + + diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 6371f30a38..3f61d65f35 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -22,6 +22,8 @@ "Épingler" "Format libre" "Ordinateur" + + "Ordinateur" "Aucun élément récent" "Paramètres de consommation de l\'application" @@ -154,4 +156,6 @@ "Tout fermer" "Développer %1$s" "Réduire %1$s" + + diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index 060328405b..d9d06a1a8a 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -22,6 +22,8 @@ "Fixar" "Forma libre" "Escritorio" + + "Ordenador" "Non hai elementos recentes" "Configuración do uso de aplicacións" @@ -154,4 +156,6 @@ "Pechar todo" "despregar %1$s" "contraer %1$s" + + diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml index 4a8e9f9642..7716d4d3ef 100644 --- a/quickstep/res/values-gu/strings.xml +++ b/quickstep/res/values-gu/strings.xml @@ -22,6 +22,8 @@ "પિન કરો" "ફ્રિફોર્મ" "ડેસ્કટૉપ" + + "ડેસ્કટૉપ" "તાજેતરની કોઈ આઇટમ નથી" "ઍપ વપરાશનું સેટિંગ" @@ -154,4 +156,6 @@ "તમામ છોડી દો" "%1$s મોટો કરો" "%1$s નાનો કરો" + + diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 2cec388ac7..02e23ec579 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -22,6 +22,8 @@ "पिन करें" "फ़्रीफ़ॉर्म" "डेस्कटॉप" + + "डेस्कटॉप" "हाल ही का कोई आइटम नहीं है" "ऐप्लिकेशन इस्तेमाल की सेटिंग" @@ -154,4 +156,6 @@ "सभी खारिज करें" "%1$s को बड़ा करें" "%1$s को छोटा करें" + + diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index ed52e90b48..a742c01bdc 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -22,6 +22,8 @@ "Prikvači" "Slobodni oblik" "Računalo" + + "Radna površina" "Nema nedavnih stavki" "Postavke upotrebe aplikacija" @@ -154,4 +156,6 @@ "Odbaci sve" "proširite oblačić %1$s" "sažmite oblačić %1$s" + + diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml index 27db3e0b3b..439d6ed55a 100644 --- a/quickstep/res/values-hu/strings.xml +++ b/quickstep/res/values-hu/strings.xml @@ -22,6 +22,8 @@ "Kitűzés" "Szabad forma" "Asztali" + + "Asztali" "Nincsenek mostanában használt elemek" "Alkalmazáshasználati beállítások" @@ -154,4 +156,6 @@ "Az összes elvetése" "%1$s kibontása" "%1$s összecsukása" + + diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml index 9a2cb2ee3e..87681c0ea1 100644 --- a/quickstep/res/values-hy/strings.xml +++ b/quickstep/res/values-hy/strings.xml @@ -22,6 +22,8 @@ "Ամրացնել" "Կամայական ձև" "Համակարգիչ" + + "Համակարգիչ" "Այստեղ դեռ ոչինչ չկա" "Հավելվածի օգտագործման կարգավորումներ" @@ -154,4 +156,6 @@ "Փակել բոլորը" "%1$s. ծավալել" "%1$s. ծալել" + + diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml index 5ddfb7e716..119ed6b8cf 100644 --- a/quickstep/res/values-in/strings.xml +++ b/quickstep/res/values-in/strings.xml @@ -22,6 +22,8 @@ "Sematkan" "Format bebas" "Desktop" + + "Desktop" "Tidak ada item yang baru dibuka" "Setelan penggunaan aplikasi" @@ -154,4 +156,6 @@ "Tutup semua" "luaskan %1$s" "ciutkan %1$s" + + diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index 3aec0ceb32..68f46565e6 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -22,6 +22,8 @@ "Festa" "Frjálst snið" "Tölva" + + "Tölva" "Engin nýleg atriði" "Notkunarstillingar forrits" @@ -154,4 +156,6 @@ "Hunsa allt" "stækka %1$s" "minnka %1$s" + + diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml index b9e6f623c6..0498c4ea41 100644 --- a/quickstep/res/values-it/strings.xml +++ b/quickstep/res/values-it/strings.xml @@ -22,6 +22,8 @@ "Blocca su schermo" "Forma libera" "Desktop" + + "Desktop" "Nessun elemento recente" "Impostazioni di utilizzo delle app" @@ -154,4 +156,6 @@ "Ignora tutte" "espandi %1$s" "comprimi %1$s" + + diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml index 2a016fa962..ad525609aa 100644 --- a/quickstep/res/values-iw/strings.xml +++ b/quickstep/res/values-iw/strings.xml @@ -22,6 +22,8 @@ "הצמדה" "מצב חופשי" "במחשב" + + "מחשב" "אין פריטים אחרונים" "הגדרות שימוש באפליקציה" @@ -154,4 +156,6 @@ "ביטול של הכול" "הרחבה של %1$s" "כיווץ של %1$s" + + diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 28b7746b43..4cfe9ed4f5 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -22,6 +22,8 @@ "固定" "フリーフォーム" "デスクトップ" + + "パソコン" "最近のアイテムはありません" "アプリの使用状況の設定" @@ -154,4 +156,6 @@ "すべて解除" "%1$sを開きます" "%1$sを閉じます" + + diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index d84d53e576..c02e9ad755 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -22,6 +22,8 @@ "ჩამაგრება" "თავისუფალი ფორმა" "დესკტოპი" + + "დესკტოპი" "ბოლოს გამოყენებული ერთეულები არ არის" "აპების გამოყენების პარამეტრები" @@ -154,4 +156,6 @@ "ყველას დახურვა" "%1$s-ის გაფართოება" "%1$s-ის ჩაკეცვა" + + diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index 4cdbfc4d94..64b3e53ddc 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -22,6 +22,8 @@ "Бекіту" "Еркін форма" "Компьютер" + + "Жұмыс үстелі" "Соңғы элементтер жоқ" "Қолданбаны пайдалану параметрлері" @@ -154,4 +156,6 @@ "Барлығын жабу" "%1$s: жаю" "%1$s: жию" + + diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index 5cf1b92737..d962ba5572 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -22,6 +22,8 @@ "ខ្ទាស់" "មុខងារទម្រង់សេរី" "ដែសថប" + + "អេក្រង់ដើម" "មិនមានធាតុថ្មីៗទេ" "ការកំណត់​ការប្រើប្រាស់​កម្មវិធី" @@ -154,4 +156,6 @@ "ច្រានចោលទាំងអស់" "ពង្រីក %1$s" "បង្រួម %1$s" + + diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml index 63b0006ee9..3a05e21dec 100644 --- a/quickstep/res/values-kn/strings.xml +++ b/quickstep/res/values-kn/strings.xml @@ -22,6 +22,8 @@ "ಪಿನ್ ಮಾಡಿ" "ಮುಕ್ತಸ್ವರೂಪ" "ಡೆಸ್ಕ್‌ಟಾಪ್" + + "ಡೆಸ್ಕ್‌ಟಾಪ್" "ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ" "ಆ್ಯಪ್‌ ಬಳಕೆಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" @@ -154,4 +156,6 @@ "ಎಲ್ಲವನ್ನು ವಜಾಗೊಳಿಸಿ" "%1$s ಅನ್ನು ವಿಸ್ತೃತಗೊಳಿಸಿ" "%1$s ಅನ್ನು ಕುಗ್ಗಿಸಿ" + + diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml index 589cc225f6..6a7ba74377 100644 --- a/quickstep/res/values-ko/strings.xml +++ b/quickstep/res/values-ko/strings.xml @@ -22,6 +22,8 @@ "고정" "자유 형식" "데스크톱" + + "데스크톱" "최근 항목이 없습니다." "앱 사용 설정" @@ -154,4 +156,6 @@ "모두 닫기" "%1$s 펼치기" "%1$s 접기" + + diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index faf5675762..e92b920bb3 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -22,6 +22,8 @@ "Кадап коюу" "Эркин форма режими" "Компьютер" + + "Компьютер" "Акыркы колдонмолор жок" "Колдонмону пайдалануу параметрлери" @@ -154,4 +156,6 @@ "Баарын четке кагуу" "%1$s жайып көрсөтүү" "%1$s жыйыштыруу" + + diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml index 622db2d1b0..f45c8ce0a6 100644 --- a/quickstep/res/values-lo/strings.xml +++ b/quickstep/res/values-lo/strings.xml @@ -22,6 +22,8 @@ "ປັກໝຸດ" "ຮູບແບບອິດສະຫລະ" "ເດັສທັອບ" + + "ເດັສທັອບ" "ບໍ່ມີລາຍການຫຼ້າສຸດ" "ການຕັ້ງຄ່າການນຳໃຊ້ແອັບ" @@ -154,4 +156,6 @@ "ປິດທັງໝົດ" "ຂະຫຍາຍ %1$s" "ຫຍໍ້ %1$s ລົງ" + + diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index a95249b508..c488859752 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -22,6 +22,8 @@ "Prisegti" "Laisva forma" "Stalinis kompiuteris" + + "Stalinis kompiuteris" "Nėra jokių naujausių elementų" "Programos naudojimo nustatymai" @@ -154,4 +156,5 @@ "Atsisakyti visų" "išskleisti „%1$s“" "sutraukti „%1$s“" + "Paieška apibrėžiant" diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml index 1892f6462e..23e64a7fff 100644 --- a/quickstep/res/values-lv/strings.xml +++ b/quickstep/res/values-lv/strings.xml @@ -22,6 +22,8 @@ "Piespraust" "Brīva forma" "Dators" + + "Darbvirsma" "Nav nesenu vienumu." "Lietotņu izmantošanas iestatījumi" @@ -154,4 +156,6 @@ "Nerādīt nevienu" "izvērst “%1$s”" "sakļaut “%1$s”" + + diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml index ce4e1b098e..f0588e88da 100644 --- a/quickstep/res/values-mk/strings.xml +++ b/quickstep/res/values-mk/strings.xml @@ -22,6 +22,8 @@ "Закачи" "Freeform" "Работна површина" + + "За компјутер" "Нема неодамнешни ставки" "Поставки за користење на апликациите" @@ -154,4 +156,6 @@ "Отфрли ги сите" "прошири %1$s" "собери %1$s" + + diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml index c15a241bdb..833090cc62 100644 --- a/quickstep/res/values-ml/strings.xml +++ b/quickstep/res/values-ml/strings.xml @@ -22,6 +22,8 @@ "പിൻ ചെയ്യുക" "ഫ്രീഫോം" "ഡെസ്‌ക്ടോപ്പ്" + + "ഡെസ്‌ക്ടോപ്പ്" "സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല" "ആപ്പ് ഉപയോഗ ക്രമീകരണം" @@ -154,4 +156,6 @@ "എല്ലാം ഡിസ്മിസ് ചെയ്യുക" "%1$s വികസിപ്പിക്കുക" "%1$s ചുരുക്കുക" + + diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml index 1ff7502644..100b8edfb4 100644 --- a/quickstep/res/values-mn/strings.xml +++ b/quickstep/res/values-mn/strings.xml @@ -22,6 +22,8 @@ "Бэхлэх" "Чөлөөтэй хувьсах" "Компьютер" + + "Дэлгэц" "Сүүлийн үеийн зүйл алга" "Апп ашиглалтын тохиргоо" @@ -154,4 +156,6 @@ "Бүгдийг үл хэрэгсэх" "%1$s-г дэлгэх" "%1$s-г хураах" + + diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 215ae3f77c..870cf4ea6d 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -22,6 +22,8 @@ "पिन करा" "फ्रीफॉर्म" "डेस्कटॉप" + + "डेस्कटॉप" "कोणतेही अलीकडील आयटम नाहीत" "अ‍ॅप वापर सेटिंग्ज" @@ -154,4 +156,6 @@ "सर्व डिसमिस करा" "%1$s चा विस्तार करा" "%1$s कोलॅप्स करा" + + diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index a1f19a95a4..bed2fce8d5 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -22,6 +22,8 @@ "Semat" "Bentuk bebas" "Desktop" + + "Desktop" "Tiada item terbaharu" "Tetapan penggunaan apl" @@ -154,4 +156,6 @@ "Ketepikan semua" "kembangkan %1$s" "kuncupkan %1$s" + + diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml index eeb774b367..ae0f66d1cb 100644 --- a/quickstep/res/values-my/strings.xml +++ b/quickstep/res/values-my/strings.xml @@ -22,6 +22,8 @@ "ပင်ထိုးရန်" "အလွတ်ပုံစံ" "ဒက်စ်တော့" + + "ဒက်စ်တော့" "မကြာမီကဖွင့်ထားသည်များ မရှိပါ" "အက်ပ်အသုံးပြုမှု ဆက်တင်များ" @@ -154,4 +156,6 @@ "အားလုံးကို ပယ်ရန်" "%1$s ကို ပိုပြပါ" "%1$s ကို လျှော့ပြပါ" + + diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml index b62b7fde0c..1ce18c1b3b 100644 --- a/quickstep/res/values-nb/strings.xml +++ b/quickstep/res/values-nb/strings.xml @@ -22,6 +22,8 @@ "Fest" "Fritt format" "Skrivebord" + + "Skrivebord" "Ingen nylige elementer" "Innstillinger for appbruk" @@ -154,4 +156,6 @@ "Lukk alle" "vis %1$s" "skjul %1$s" + + diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml index a2d4d325b3..1921fed160 100644 --- a/quickstep/res/values-ne/strings.xml +++ b/quickstep/res/values-ne/strings.xml @@ -22,6 +22,8 @@ "पिन गर्नुहोस्" "फ्रिफर्म" "डेस्कटप" + + "डेस्कटप" "हालसालैको कुनै पनि वस्तु छैन" "एपको उपयोगका सेटिङहरू" @@ -154,4 +156,6 @@ "सबै हटाउनुहोस्" "%1$s एक्स्पान्ड गर्नुहोस्" "%1$s कोल्याप्स गर्नुहोस्" + + diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml index ee876cfcfc..995d8d4849 100644 --- a/quickstep/res/values-nl/strings.xml +++ b/quickstep/res/values-nl/strings.xml @@ -22,6 +22,8 @@ "Vastzetten" "Vrije vorm" "Desktop" + + "Desktop" "Geen recente items" "Instellingen voor app-gebruik" @@ -154,4 +156,6 @@ "Alles sluiten" "%1$s uitvouwen" "%1$s samenvouwen" + + diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index 3ee59b5194..430058b24d 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -22,6 +22,8 @@ "ପିନ୍‍" "ଫ୍ରିଫର୍ମ" "ଡେସ୍କଟପ" + + "ଡେସ୍କଟପ" "ବର୍ତ୍ତମାନର କୌଣସି ଆଇଟମ ନାହିଁ" "ଆପ ବ୍ୟବହାର ସେଟିଂସ" @@ -154,4 +156,6 @@ "ସବୁ ଖାରଜ କରନ୍ତୁ" "%1$s ବିସ୍ତାର କରନ୍ତୁ" "%1$s ସଙ୍କୁଚିତ କରନ୍ତୁ" + + diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml index 1e8d52e741..d8d0907390 100644 --- a/quickstep/res/values-pa/strings.xml +++ b/quickstep/res/values-pa/strings.xml @@ -22,6 +22,8 @@ "ਪਿੰਨ ਕਰੋ" "ਫ੍ਰੀਫਾਰਮ" "ਡੈਸਕਟਾਪ" + + "ਡੈਸਕਟਾਪ" "ਕੋਈ ਹਾਲੀਆ ਆਈਟਮ ਨਹੀਂ" "ਐਪ ਵਰਤੋਂ ਦੀਆਂ ਸੈਟਿੰਗਾਂ" @@ -154,4 +156,6 @@ "ਸਭ ਖਾਰਜ ਕਰੋ" "%1$s ਦਾ ਵਿਸਤਾਰ ਕਰੋ" "%1$s ਨੂੰ ਸਮੇਟੋ" + + diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml index 64adddf55e..957e5c47e2 100644 --- a/quickstep/res/values-pl/strings.xml +++ b/quickstep/res/values-pl/strings.xml @@ -22,6 +22,8 @@ "Przypnij" "Tryb dowolny" "Pulpit" + + "Pulpit" "Brak ostatnich elementów" "Ustawienia użycia aplikacji" @@ -154,4 +156,6 @@ "Zamknij wszystkie" "rozwiń dymek: %1$s" "zwiń dymek: %1$s" + + diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 2167875719..ca7cd58bb5 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -22,6 +22,8 @@ "Fixar" "Forma livre" "Computador" + + "Computador" "Nenhum item recente" "Definições de utilização de aplicações" @@ -154,4 +156,6 @@ "Ignorar tudo" "expandir %1$s" "reduzir %1$s" + + diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml index 9309810cdf..aee1c8d758 100644 --- a/quickstep/res/values-pt/strings.xml +++ b/quickstep/res/values-pt/strings.xml @@ -22,6 +22,8 @@ "Fixar" "Forma livre" "Modo área de trabalho" + + "Computador" "Nenhum item recente" "Configurações de uso do app" @@ -154,4 +156,6 @@ "Dispensar todos" "abrir %1$s" "fechar %1$s" + + diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml index 19075cd554..c05b85b5ab 100644 --- a/quickstep/res/values-ro/strings.xml +++ b/quickstep/res/values-ro/strings.xml @@ -22,6 +22,8 @@ "Fixează" "Formă liberă" "Desktop" + + "Computer" "Niciun element recent" "Setări de utilizare a aplicației" @@ -154,4 +156,6 @@ "Închide-le pe toate" "extinde %1$s" "restrânge %1$s" + + diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index 76c4e1f646..fca0a056d3 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -22,6 +22,8 @@ "Закрепить" "Произвольная форма" "Мультиоконный режим" + + "Мультиоконный режим" "Здесь пока ничего нет." "Настройки использования приложения" @@ -154,4 +156,6 @@ "Закрыть все" "Развернуто: %1$s" "Свернуто: %1$s" + + diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index 0953b38bd1..cfbf1ddd2e 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -22,6 +22,8 @@ "අමුණන්න" "Freeform" "ඩෙස්ක්ටොපය" + + "ඩෙස්ක්ටොපය" "මෑත අයිතම නැත" "යෙදුම් භාවිත සැකසීම්" @@ -154,4 +156,6 @@ "සියල්ල ඉවතලන්න" "%1$s දිග හරින්න" "%1$s හකුළන්න" + + diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml index 9b682e6034..b3145de532 100644 --- a/quickstep/res/values-sk/strings.xml +++ b/quickstep/res/values-sk/strings.xml @@ -22,6 +22,8 @@ "Pripnúť" "Voľný režim" "Počítač" + + "Počítač" "Žiadne nedávne položky" "Nastavenia využívania aplikácie" @@ -154,4 +156,6 @@ "Zavrieť všetko" "rozbaliť %1$s" "zbaliť %1$s" + + diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index 94de1e0567..d72436a046 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -22,6 +22,8 @@ "Pripni" "Prosta oblika" "Namizni računalnik" + + "Namizni način" "Ni nedavnih elementov" "Nastavitve uporabe aplikacij" @@ -154,4 +156,6 @@ "Opusti vse" "razširitev oblačka %1$s" "strnitev oblačka %1$s" + + diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml index 29214c9701..30ba61df9f 100644 --- a/quickstep/res/values-sq/strings.xml +++ b/quickstep/res/values-sq/strings.xml @@ -22,6 +22,8 @@ "Gozhdo" "Formë e lirë" "Desktopi" + + "Desktopi" "Nuk ka asnjë artikull të fundit" "Cilësimet e përdorimit të aplikacionit" @@ -154,4 +156,6 @@ "Hiqi të gjitha" "zgjero %1$s" "palos %1$s" + + diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index d6e5d03cee..b83a4f251e 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -22,6 +22,8 @@ "Закачи" "Слободни облик" "Рачунар" + + "Рачунари" "Нема недавних ставки" "Подешавања коришћења апликације" @@ -154,4 +156,6 @@ "Одбаци све" "проширите облачић %1$s" "скупите облачић %1$s" + + diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index bba98c6fb6..5ab3866475 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -22,6 +22,8 @@ "Fäst" "Fritt format" "Dator" + + "Dator" "Listan är tom" "Inställningar för appanvändning" @@ -154,4 +156,6 @@ "Stäng alla" "utöka %1$s" "komprimera %1$s" + + diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml index f8d6a4f229..9d13df8a77 100644 --- a/quickstep/res/values-sw/strings.xml +++ b/quickstep/res/values-sw/strings.xml @@ -22,6 +22,8 @@ "Bandika" "Muundo huru" "Kompyuta ya mezani" + + "Kompyuta ya Mezani" "Hakuna vipengee vya hivi karibuni" "Mipangilio ya matumizi ya programu" @@ -154,4 +156,6 @@ "Ondoa vyote" "panua %1$s" "kunja %1$s" + + diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml index 73c6c3746f..8ac0ff8aab 100644 --- a/quickstep/res/values-ta/strings.xml +++ b/quickstep/res/values-ta/strings.xml @@ -22,6 +22,8 @@ "பின் செய்தல்" "குறிப்பிட்ட வடிவமில்லாத பயன்முறை" "டெஸ்க்டாப்" + + "டெஸ்க்டாப்" "சமீபத்தியவை எதுவுமில்லை" "ஆப்ஸ் உபயோக அமைப்புகள்" @@ -154,4 +156,6 @@ "அனைத்தையும் மூடும்" "%1$s ஐ விரிவாக்கும்" "%1$s ஐச் சுருக்கும்" + + diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 91ef8463a9..4ae7a58ed5 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -22,6 +22,8 @@ "పిన్ చేయండి" "సంప్రదాయేతర" "డెస్క్‌టాప్" + + "డెస్క్‌టాప్" "ఇటీవలి ఐటెమ్‌లు ఏవీ లేవు" "యాప్ వినియోగ సెట్టింగ్‌లు" @@ -154,4 +156,6 @@ "అన్నింటినీ విస్మరించండి" "%1$sను విస్తరించండి" "%1$sను కుదించండి" + + diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml index 2218e6d0e1..210e996664 100644 --- a/quickstep/res/values-th/strings.xml +++ b/quickstep/res/values-th/strings.xml @@ -22,6 +22,8 @@ "ปักหมุด" "รูปแบบอิสระ" "เดสก์ท็อป" + + "เดสก์ท็อป" "ไม่มีรายการล่าสุด" "การตั้งค่าการใช้แอป" @@ -154,4 +156,6 @@ "ปิดทั้งหมด" "ขยาย %1$s" "ยุบ %1$s" + + diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml index fac6a52650..13d89a269d 100644 --- a/quickstep/res/values-tl/strings.xml +++ b/quickstep/res/values-tl/strings.xml @@ -22,6 +22,8 @@ "I-pin" "Freeform" "Desktop" + + "Desktop" "Walang kamakailang item" "Mga setting ng paggamit ng app" @@ -154,4 +156,6 @@ "I-dismiss lahat" "i-expand ang %1$s" "i-collapse ang %1$s" + + diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml index d44d710365..1cb1fa7e4f 100644 --- a/quickstep/res/values-tr/strings.xml +++ b/quickstep/res/values-tr/strings.xml @@ -22,6 +22,8 @@ "Sabitle" "Serbest çalışma" "Masaüstü" + + "Masaüstü" "Yeni öğe yok" "Uygulama kullanım ayarları" @@ -154,4 +156,6 @@ "Tümünü kapat" "genişlet: %1$s" "daralt: %1$s" + + diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml index 320c2ea10e..84ddd81fbc 100644 --- a/quickstep/res/values-uk/strings.xml +++ b/quickstep/res/values-uk/strings.xml @@ -22,6 +22,8 @@ "Закріпити" "Довільна форма" "Робочий стіл" + + "Комп’ютер" "Немає нещодавніх додатків" "Налаштування використання додатка" @@ -154,4 +156,6 @@ "Закрити все" "розгорнути \"%1$s\"" "згорнути \"%1$s\"" + + diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml index c71625a117..43e97c24b7 100644 --- a/quickstep/res/values-ur/strings.xml +++ b/quickstep/res/values-ur/strings.xml @@ -22,6 +22,8 @@ "پن کریں" "فری فارم" "ڈیسک ٹاپ" + + "ڈیسک ٹاپ" "کوئی حالیہ آئٹم نہیں" "ایپ کے استعمال کی ترتیبات" @@ -154,4 +156,6 @@ "سبھی کو برخاست کریں" "%1$s کو پھیلائیں" "%1$s کو سکیڑیں" + + diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml index e37945355a..090753ff45 100644 --- a/quickstep/res/values-uz/strings.xml +++ b/quickstep/res/values-uz/strings.xml @@ -22,6 +22,8 @@ "Qadash" "Erkin shakl" "Desktop" + + "Desktop" "Yaqinda ishlatilgan ilovalar yo‘q" "Ilovadan foydalanish sozlamalari" @@ -154,4 +156,6 @@ "Hammasini yopish" "%1$sni yoyish" "%1$sni yigʻish" + + diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml index ddefb9e9c4..b0d31cbfb6 100644 --- a/quickstep/res/values-vi/strings.xml +++ b/quickstep/res/values-vi/strings.xml @@ -22,6 +22,8 @@ "Ghim" "Dạng tự do" "Máy tính" + + "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" @@ -154,4 +156,6 @@ "Đóng tất cả" "mở rộng %1$s" "thu gọn %1$s" + + diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml index 8540cd9c4c..73121b4976 100644 --- a/quickstep/res/values-zh-rCN/strings.xml +++ b/quickstep/res/values-zh-rCN/strings.xml @@ -22,6 +22,8 @@ "固定" "自由窗口" "桌面" + + "桌面设备" "近期没有任何内容" "应用使用设置" @@ -154,4 +156,6 @@ "全部关闭" "展开“%1$s”" "收起“%1$s”" + + diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index 3d16e8db3c..b934dfcf44 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -22,6 +22,8 @@ "固定" "自由形式" "桌面" + + "桌面" "最近沒有任何項目" "應用程式使用情況設定" @@ -154,4 +156,6 @@ "全部關閉" "打開%1$s" "收埋%1$s" + + diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml index bf0381205e..1cba81966b 100644 --- a/quickstep/res/values-zh-rTW/strings.xml +++ b/quickstep/res/values-zh-rTW/strings.xml @@ -22,6 +22,8 @@ "固定" "自由形式" "桌面" + + "電腦" "最近沒有任何項目" "應用程式使用情況設定" @@ -154,4 +156,6 @@ "全部關閉" "展開「%1$s」" "收合「%1$s」" + + diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml index d0d0bb646a..ee6b3b7208 100644 --- a/quickstep/res/values-zu/strings.xml +++ b/quickstep/res/values-zu/strings.xml @@ -22,6 +22,8 @@ "Phina" "I-Freeform" "Ideskithophu" + + "Ideskithophu" "Azikho izinto zakamuva" "Izilungiselelo zokusetshenziswa kohlelo lokusebenza" @@ -154,4 +156,6 @@ "Chitha konke" "nweba %1$s" "goqa %1$s" + + From fbe5044c4ef631b57aa3e4081d6b8884dd953d33 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 16 Oct 2024 18:09:30 -0700 Subject: [PATCH 09/14] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I5e1473aede364901d9b4da42154df8c7c5f90ad5 --- res/values-da/strings.xml | 2 +- res/values-kn/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 9211e7640d..0d78d9032d 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -174,7 +174,7 @@ "Genveje" "Afvis" "Luk" - "Personlige" + "Personlig" "Arbejde" "Arbejdsprofil" "Arbejdsapps har badges og kan ses af din it-administrator" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 0c46eb43e5..786cea1e58 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -21,7 +21,7 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Launcher3" "ಕೆಲಸ" - "ಅಪ್ಲಿಕೇಶನ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ" + "ಆ್ಯಪ್‌ ಅನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿಲ್ಲ" "ಅಪ್ಲಿಕೇಶನ್ ಲಭ್ಯವಿಲ್ಲ" "ಡೌನ್‌ಲೋಡ್ ಮಾಡಲಾದ ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" "ಸುರಕ್ಷಿತ ಮೋಡ್‌ನಲ್ಲಿ ವಿಜೆಟ್‌ಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" @@ -103,7 +103,7 @@ "ವಿಜೆಟ್ ಅನ್ನು ಲೋಡ್ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ" "ವಿಜೆಟ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಸೆಟಪ್ ಪೂರ್ಣಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ" - "ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." + "ಇದೊಂದು ಆ್ಯಪ್‌ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ." "ಹೆಸರನ್ನು ಎಡಿಟ್ ಮಾಡಿ" "%1$s ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ" "{count,plural, =1{{app_name} ಆ್ಯಪ್ # ಅಧಿಸೂಚನೆಯನ್ನು ಹೊಂದಿದೆ}one{{app_name} ಆ್ಯಪ್ # ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ}other{{app_name} ಆ್ಯಪ್ # ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ}}" From ea788d92bea9150d97a21d8aecb744979d585c4b Mon Sep 17 00:00:00 2001 From: samcackett Date: Mon, 14 Oct 2024 18:30:11 +0100 Subject: [PATCH 10/14] Draw live tile below Overview after launch animation A fix (see http://go/b320307512_problems) was put in to change layers when swiping from Desktop Windowing to Overview, so that the blur effect didn't apply to the live tile. The result of this change was that the tasks now sat on top of Overview and if you didn't launch the task but went back to Overview, then you could interact with them and do things like resize the task and get into a very broken state. This fix simply flips the layer ordering back after the animation completes to ensure Overview sits on top. Fix: 373400009 Flag: NONE bugfix Test: Swipe from Desktop to Overview. Swipe down from Overview to launch the live tile, but then swipe back to Overview i.e. don't launch Desktop. Try to resize the DW window. Change-Id: I80c8d72f76a8393eb8bd963df81723defd85ed97 --- .../android/quickstep/views/RecentsView.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index c405080828..c29eb1ade5 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -5564,15 +5564,13 @@ public abstract class RecentsView< remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator() .addOverviewToAppAnim(mPendingAnimation, interpolator)); mPendingAnimation.addOnFrameCallback(this::redrawLiveTile); - if (taskView instanceof DesktopTaskView && mRemoteTargetHandles != null) { - mPendingAnimation.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - runActionOnRemoteHandles(remoteTargetHandle -> - remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false)); - } - }); - } + mPendingAnimation.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + runActionOnRemoteHandles(remoteTargetHandle -> + remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(false)); + } + }); mPendingAnimation.addEndListener(isSuccess -> { if (isSuccess) { if (taskView instanceof GroupedTaskView && hasAllValidTaskIds(taskView.getTaskIds()) @@ -5604,6 +5602,13 @@ public abstract class RecentsView< protected Unit onTaskLaunchAnimationEnd(boolean success) { if (success) { resetTaskVisuals(); + } else { + // If launch animation didn't complete i.e. user dragged live tile down and then + // back up and returned to Overview, then we need to ensure we reset the + // view to draw below recents so that it can't be interacted with. + runActionOnRemoteHandles(remoteTargetHandle -> + remoteTargetHandle.getTaskViewSimulator().setDrawsBelowRecents(true)); + redrawLiveTile(); } return Unit.INSTANCE; } From 1d4e75c777c050679b0d1866fb3a5b6aea9c377d Mon Sep 17 00:00:00 2001 From: mpodolian Date: Wed, 16 Oct 2024 16:26:30 -0700 Subject: [PATCH 11/14] Refactored hotseat translation X logic Made retrieval of the hotseat translation X easier to use. Test: Manual. Set the navigation mode to 3-button. Moved the bubble bar from one side to the other. Switched the navigation mode to gestures. Moved the bubble bar from one side to the other again. Bug: 373422448 Flag: EXEMPT refactoring Change-Id: Ie69f1ecf178244008e5c752882c4b91a30928756 --- .../taskbar/TaskbarInsetsController.kt | 18 +++++++----------- .../TaskbarLauncherStateController.java | 9 ++++----- .../taskbar/TaskbarViewController.java | 9 ++++----- .../uioverrides/QuickstepLauncher.java | 5 ++--- src/com/android/launcher3/DeviceProfile.java | 15 ++++++++++----- 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index 1141a01726..55722a9b62 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -151,30 +151,26 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas DisplayController.showLockedTaskbarOnHome(context) ) { // adding the taskbar touch region - val touchableHeight: Int var left = 0 var right = context.deviceProfile.widthPx - var bubbleBarAdjustment = 0 + val touchableHeight: Int if (uiController.isAnimatingToLauncher) { val dp = controllers.taskbarActivityContext.deviceProfile touchableHeight = windowLayoutParams.height if (dp.isQsbInline) { // if Qsb is inline need to exclude search icon from touch region val isRtl = Utilities.isRtl(context.resources) - bubbleControllers?.bubbleBarViewController?.let { - if (dp.shouldAdjustHotseatOnBubblesLocationUpdate(context)) { + val navBarOffset = + bubbleControllers?.bubbleBarViewController?.let { val isBubblesOnLeft = it.bubbleBarLocation.isOnLeft(isRtl) - bubbleBarAdjustment = - dp.getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl) - } - } + dp.getHotseatTranslationXForNavBar(context, isBubblesOnLeft) + } ?: 0 val hotseatPadding: Rect = dp.getHotseatLayoutPadding(context) val borderSpacing: Int = dp.hotseatBorderSpace if (isRtl) { - right = - dp.widthPx - hotseatPadding.right + borderSpacing + bubbleBarAdjustment + right = dp.widthPx - hotseatPadding.right + borderSpacing + navBarOffset } else { - left = hotseatPadding.left - borderSpacing + bubbleBarAdjustment + left = hotseatPadding.left - borderSpacing + navBarOffset } } } else { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 39aef28d45..6e7cf9e1f1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -893,19 +893,18 @@ public class TaskbarLauncherStateController { mBubbleBarLocation = location; if (location == null) { // bubble bar is not present, hence no location, resetting the hotseat - updateHotseatAndQsbTranslationX(0, animate); + updateHotseatAndQsbTranslationX(/* targetValue = */ 0, animate); mBubbleBarLocation = null; return; } DeviceProfile deviceProfile = mLauncher.getDeviceProfile(); - if (!deviceProfile.shouldAdjustHotseatOnBubblesLocationUpdate( + if (!deviceProfile.shouldAdjustHotseatOnNavBarLocationUpdate( mControllers.taskbarActivityContext)) { return; } - boolean isRtl = isRtl(mLauncher.getResources()); - boolean isBubblesOnLeft = location.isOnLeft(isRtl); + boolean isBubblesOnLeft = location.isOnLeft(isRtl(mLauncher.getResources())); int targetX = deviceProfile - .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl); + .getHotseatTranslationXForNavBar(mLauncher, isBubblesOnLeft); updateHotseatAndQsbTranslationX(targetX, animate); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index c275536b47..e9458ff5a5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -837,12 +837,11 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar int firstRecentTaskIndex = -1; int hotseatNavBarTranslationX = 0; - if (mCurrentBubbleBarLocation != null - && taskbarDp.shouldAdjustHotseatOnBubblesLocationUpdate(mActivity)) { - boolean isRtl = mTaskbarView.isLayoutRtl(); - boolean isBubblesOnLeft = mCurrentBubbleBarLocation.isOnLeft(isRtl); + if (mCurrentBubbleBarLocation != null) { + boolean isBubblesOnLeft = mCurrentBubbleBarLocation + .isOnLeft(mTaskbarView.isLayoutRtl()); hotseatNavBarTranslationX = taskbarDp - .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl); + .getHotseatTranslationXForNavBar(mActivity, isBubblesOnLeft); } for (int i = 0; i < mTaskbarView.getChildCount(); i++) { View child = mTaskbarView.getChildAt(i); diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index acdff71e61..4ad65e1be8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -1101,10 +1101,9 @@ public class QuickstepLauncher extends Launcher implements RecentsViewContainer, if (isBubbleBarEnabled() && enableBubbleBarInPersistentTaskBar() && mBubbleBarLocation != null) { - boolean isRtl = isRtl(getResources()); - boolean isBubblesOnLeft = mBubbleBarLocation.isOnLeft(isRtl); + boolean isBubblesOnLeft = mBubbleBarLocation.isOnLeft(isRtl(getResources())); translationX += mDeviceProfile - .getHotseatTranslationXForBubbleBar(isBubblesOnLeft, isRtl); + .getHotseatTranslationXForNavBar(this, isBubblesOnLeft); } if (isBubbleBarEnabled() && mDeviceProfile.shouldAdjustHotseatForBubbleBar(getContext(), hasBubbles())) { diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index afe0ee1967..886255094f 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -2355,18 +2355,23 @@ public class DeviceProfile { /** * Returns whether Taskbar and Hotseat should adjust horizontally on bubble bar location update. */ - public boolean shouldAdjustHotseatOnBubblesLocationUpdate(Context context) { + public boolean shouldAdjustHotseatOnNavBarLocationUpdate(Context context) { return enableBubbleBar() && enableBubbleBarInPersistentTaskBar() && !DisplayController.getNavigationMode(context).hasGestures; } /** Returns hotseat translation X for the bubble bar position. */ - public int getHotseatTranslationXForBubbleBar(boolean isNavbarOnRight, boolean isRtl) { - if (isNavbarOnRight) { - return isRtl ? -navButtonsLayoutWidthPx : 0; + public int getHotseatTranslationXForNavBar(Context context, boolean isBubblesOnLeft) { + if (shouldAdjustHotseatOnNavBarLocationUpdate(context)) { + boolean isRtl = Utilities.isRtl(context.getResources()); + if (isBubblesOnLeft) { + return isRtl ? -navButtonsLayoutWidthPx : 0; + } else { + return isRtl ? 0 : navButtonsLayoutWidthPx; + } } else { - return isRtl ? 0 : navButtonsLayoutWidthPx; + return 0; } } From 3c873420e8766c3717c598ef42cb1319c20c6ec3 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 17 Oct 2024 09:50:06 -0700 Subject: [PATCH 12/14] Moving SettingsChangeLogger back to MainThreadInitializedObject SettingsChangeLogger depends on DisplayController which needs to be migrated first. Otherwise it introduces a deadlock when initializing DisplayController in constructor Bug: 373557167 Test: Manual (will merge automated tests once all culprits are resolved) Flag: EXEMPT dagger Change-Id: I2386812693e470bcee1a64d5cec49c03fd36f230 --- .../dagger/QuickstepBaseAppComponent.java | 2 - .../logging/SettingsChangeLogger.java | 42 +++++++------------ .../logging/SettingsChangeLoggerTest.kt | 8 ++-- 3 files changed, 17 insertions(+), 35 deletions(-) diff --git a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java index 335161b24c..e82d9fcd1b 100644 --- a/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java +++ b/quickstep/src/com/android/quickstep/dagger/QuickstepBaseAppComponent.java @@ -19,7 +19,6 @@ package com.android.quickstep.dagger; import com.android.launcher3.dagger.LauncherAppComponent; import com.android.launcher3.dagger.LauncherBaseAppComponent; import com.android.launcher3.model.WellbeingModel; -import com.android.quickstep.logging.SettingsChangeLogger; import com.android.quickstep.util.AsyncClockEventDelegate; import com.android.quickstep.util.ContextualSearchHapticManager; @@ -32,7 +31,6 @@ import com.android.quickstep.util.ContextualSearchHapticManager; * See {@link LauncherAppComponent} for the one actually used. */ public interface QuickstepBaseAppComponent extends LauncherBaseAppComponent { - SettingsChangeLogger getSettingsChangeLogger(); WellbeingModel getWellbeingModel(); diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java index 995635fa6c..dd721e16f6 100644 --- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java +++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java @@ -44,20 +44,16 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.dagger.ApplicationContext; -import com.android.launcher3.dagger.LauncherAppSingleton; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.model.DeviceGridState; -import com.android.launcher3.util.DaggerSingletonObject; -import com.android.launcher3.util.DaggerSingletonTracker; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.Info; -import com.android.launcher3.util.ExecutorUtil; +import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.util.SafeCloseable; import com.android.launcher3.util.SettingsCache; -import com.android.quickstep.dagger.QuickstepBaseAppComponent; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; @@ -65,12 +61,9 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.util.Optional; -import javax.inject.Inject; - /** * Utility class to log launcher settings changes */ -@LauncherAppSingleton public class SettingsChangeLogger implements DisplayController.DisplayInfoChangeListener, OnSharedPreferenceChangeListener, SafeCloseable { @@ -78,8 +71,8 @@ public class SettingsChangeLogger implements /** * Singleton instance */ - public static DaggerSingletonObject INSTANCE = - new DaggerSingletonObject<>(QuickstepBaseAppComponent::getSettingsChangeLogger); + public static MainThreadInitializedObject INSTANCE = + new MainThreadInitializedObject<>(SettingsChangeLogger::new); private static final String TAG = "SettingsChangeLogger"; private static final String BOOLEAN_PREF = "SwitchPreference"; @@ -92,31 +85,26 @@ public class SettingsChangeLogger implements private StatsLogManager.LauncherEvent mNotificationDotsEvent; private StatsLogManager.LauncherEvent mHomeScreenSuggestionEvent; - @Inject - SettingsChangeLogger(@ApplicationContext Context context, DaggerSingletonTracker tracker) { - this(context, StatsLogManager.newInstance(context), tracker); + SettingsChangeLogger(@ApplicationContext Context context) { + this(context, StatsLogManager.newInstance(context)); } @VisibleForTesting - SettingsChangeLogger(Context context, StatsLogManager statsLogManager, - DaggerSingletonTracker tracker) { + SettingsChangeLogger(Context context, StatsLogManager statsLogManager) { mContext = context; mStatsLogManager = statsLogManager; mLoggablePrefs = loadPrefKeys(context); - ExecutorUtil.executeSyncOnMainOrFail(() -> { - DisplayController.INSTANCE.get(context).addChangeListener(this); - mNavMode = DisplayController.getNavigationMode(context); + DisplayController.INSTANCE.get(context).addChangeListener(this); + mNavMode = DisplayController.getNavigationMode(context); - getPrefs(context).registerOnSharedPreferenceChangeListener(this); - getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this); + getPrefs(context).registerOnSharedPreferenceChangeListener(this); + getDevicePrefs(context).registerOnSharedPreferenceChangeListener(this); - SettingsCache settingsCache = SettingsCache.INSTANCE.get(context); - settingsCache.register(NOTIFICATION_BADGING_URI, - this::onNotificationDotsChanged); - onNotificationDotsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI)); - tracker.addCloseable(this); - }); + SettingsCache settingsCache = SettingsCache.INSTANCE.get(context); + settingsCache.register(NOTIFICATION_BADGING_URI, + this::onNotificationDotsChanged); + onNotificationDotsChanged(settingsCache.getValue(NOTIFICATION_BADGING_URI)); } private static ArrayMap loadPrefKeys(Context context) { @@ -223,8 +211,6 @@ public class SettingsChangeLogger implements public void close() { getPrefs(mContext).unregisterOnSharedPreferenceChangeListener(this); getDevicePrefs(mContext).unregisterOnSharedPreferenceChangeListener(this); - SettingsCache settingsCache = SettingsCache.INSTANCE.get(mContext); - settingsCache.unregister(NOTIFICATION_BADGING_URI, this::onNotificationDotsChanged); } @VisibleForTesting diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt index 0a607744d0..7c48ea489c 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/logging/SettingsChangeLoggerTest.kt @@ -34,7 +34,6 @@ import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NAVI import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_ENABLED import com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_THEMED_ICON_DISABLED import com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY -import com.android.launcher3.util.DaggerSingletonTracker import com.google.common.truth.Truth.assertThat import org.junit.After import org.junit.Before @@ -63,7 +62,6 @@ class SettingsChangeLoggerTest { @Mock private lateinit var mMockLogger: StatsLogManager.StatsLogger @Captor private lateinit var mEventCaptor: ArgumentCaptor - @Mock private lateinit var mTracker: DaggerSingletonTracker private var mDefaultThemedIcons = false private var mDefaultAllowRotation = false @@ -81,7 +79,7 @@ class SettingsChangeLoggerTest { // To match the default value of ALLOW_ROTATION LauncherPrefs.get(mContext).put(item = ALLOW_ROTATION, value = false) - mSystemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager, mTracker) + mSystemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager) } @After @@ -92,7 +90,7 @@ class SettingsChangeLoggerTest { @Test fun loggingPrefs_correctDefaultValue() { - val systemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager, mTracker) + val systemUnderTest = SettingsChangeLogger(mContext, mStatsLogManager) assertThat(systemUnderTest.loggingPrefs[ALLOW_ROTATION_PREFERENCE_KEY]!!.defaultValue) .isFalse() @@ -119,7 +117,7 @@ class SettingsChangeLoggerTest { LauncherPrefs.get(mContext).put(item = ALLOW_ROTATION, value = true) // This a new object so the values of mLoggablePrefs will be different - SettingsChangeLogger(mContext, mStatsLogManager, mTracker).logSnapshot(mInstanceId) + SettingsChangeLogger(mContext, mStatsLogManager).logSnapshot(mInstanceId) verify(mMockLogger, atLeastOnce()).log(mEventCaptor.capture()) val capturedEvents = mEventCaptor.allValues From 36bbc4f18f24da7c30bf433c1b52930be162f82e Mon Sep 17 00:00:00 2001 From: Jagrut Desai Date: Tue, 15 Oct 2024 14:05:24 -0700 Subject: [PATCH 13/14] Fix Hotseat stashing on user going to dream This cl simply delays the taskbar icon alignment animation and stashing animation by duration of dream animation and plays it off screen with 0 duration. Test: Manual, Presubmit Bug: 333989177 Flag: EXEMPT bugfix Change-Id: I35d26b0cf895f9990fcfd73ceebc15b0f9886476 --- .../TaskbarLauncherStateController.java | 23 +++++++------------ .../taskbar/TaskbarStashController.java | 17 +++++++++++++- .../quickstep/util/SystemUiFlagUtils.kt | 16 +++++++++++++ 3 files changed, 40 insertions(+), 16 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 707d4b3a60..0aca1b82ab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar; import static com.android.app.animation.Interpolators.EMPHASIZED; +import static com.android.app.animation.Interpolators.FINAL_FRAME; import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_ALIGNMENT; import static com.android.launcher3.Hotseat.ALPHA_CHANNEL_TASKBAR_STASH; @@ -31,11 +32,8 @@ import static com.android.launcher3.taskbar.bubbles.BubbleBarView.FADE_IN_ANIM_A import static com.android.launcher3.taskbar.bubbles.BubbleBarView.FADE_OUT_ANIM_POSITION_DURATION_MS; import static com.android.launcher3.util.FlagDebugUtils.appendFlag; import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange; +import static com.android.quickstep.util.SystemUiFlagUtils.isTaskbarHidden; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_AWAKE; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK; -import static com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_AWAKE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -378,16 +376,7 @@ public class TaskbarLauncherStateController { updateStateForFlag(FLAG_DEVICE_LOCKED, SystemUiFlagUtils.isLocked(systemUiStateFlags)); - // Taskbar is hidden whenever the device is dreaming. The dreaming state includes the - // interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in - // when the device is asleep, the second condition extends ensures that the transition from - // and to the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar - // hide/reveal animation timings. The Taskbar can show when dreaming if the glanceable hub - // is showing on top. - boolean isTaskbarHidden = (hasAnyFlag(systemUiStateFlags, SYSUI_STATE_DEVICE_DREAMING) - && !hasAnyFlag(systemUiStateFlags, SYSUI_STATE_COMMUNAL_HUB_SHOWING)) - || (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_AWAKE; - updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden); + updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags)); if (applyState) { applyState(); @@ -682,7 +671,11 @@ public class TaskbarLauncherStateController { + mIconAlignment.value + " -> " + toAlignment + ": " + duration); } - animatorSet.play(iconAlignAnim); + if (hasAnyFlag(FLAG_TASKBAR_HIDDEN)) { + iconAlignAnim.setInterpolator(FINAL_FRAME); + } else { + animatorSet.play(iconAlignAnim); + } } Interpolator interpolator = enableScalingRevealHomeAnimation() diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 8991965f61..b19da6b8e2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -30,6 +30,7 @@ import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; import static com.android.launcher3.util.FlagDebugUtils.appendFlag; import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange; import static com.android.quickstep.util.SystemActionConstants.SYSTEM_ACTION_ID_TASKBAR; +import static com.android.quickstep.util.SystemUiFlagUtils.isTaskbarHidden; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DIALOG_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING; @@ -104,6 +105,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // An internal no-op flag to determine whether we should delay the taskbar background animation private static final int FLAG_DELAY_TASKBAR_BG_TAG = 1 << 12; public static final int FLAG_STASHED_FOR_BUBBLES = 1 << 13; // show handle for stashed hotseat + public static final int FLAG_TASKBAR_HIDDEN = 1 << 14; // taskbar hidden during dream, etc... // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; @@ -215,6 +217,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba */ private static final int TRANSITION_UNSTASH_SUW_MANUAL = 3; + /** + * total duration of entering dream state animation, which we use as start delay to + * applyState() when SYSUI_STATE_DEVICE_DREAMING flag is present. Keep this in sync with + * DreamAnimationController.TOTAL_ANIM_DURATION. + */ + private static final int SKIP_TOTAL_DREAM_ANIM_DURATION = 450; + @Retention(RetentionPolicy.SOURCE) @IntDef(value = { TRANSITION_DEFAULT, @@ -1123,7 +1132,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba startDelay = getTaskbarStashStartDelayForIme(); } - applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay); + if (isTaskbarHidden(systemUiStateFlags) && !hasAnyFlag(FLAG_TASKBAR_HIDDEN)) { + updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags)); + applyState(0, SKIP_TOTAL_DREAM_ANIM_DURATION); + } else { + updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden(systemUiStateFlags)); + applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay); + } } /** diff --git a/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt b/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt index 5f4388c918..1ff05dae56 100644 --- a/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt +++ b/quickstep/src/com/android/quickstep/util/SystemUiFlagUtils.kt @@ -47,6 +47,22 @@ object SystemUiFlagUtils { !hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_GOING_AWAY) } + /** + * Taskbar is hidden whenever the device is dreaming. The dreaming state includes the + * interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in when + * the device is asleep, the second condition extends ensures that the transition from and to + * the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar hide/reveal + * animation timings. The Taskbar can show when dreaming if the glanceable hub is showing on + * top. + */ + @JvmStatic + fun isTaskbarHidden(@SystemUiStateFlags flags: Long): Boolean { + return ((hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_DEVICE_DREAMING) && + !hasAnyFlag(flags, QuickStepContract.SYSUI_STATE_COMMUNAL_HUB_SHOWING)) || + (flags and QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK) != + QuickStepContract.WAKEFULNESS_AWAKE) + } + private fun hasAnyFlag(@SystemUiStateFlags flags: Long, flagMask: Long): Boolean { return (flags and flagMask) != 0L } From 9cd3154952121389f85bc7e421ca031aef264665 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Thu, 17 Oct 2024 11:47:07 -0700 Subject: [PATCH 14/14] Moving PluginManager to dagger Multiple singletons depend on Plugin which can cause deadlock if PluginManager is initialized on main thread Test: presubmit Bug: 361850561 Bug: 373557167 Flag: EXEMPT dagger Change-Id: I79f17ac6b78a2ce60df2d27a6e794b9e4eba1b51 --- quickstep/res/values/config.xml | 1 - .../plugins/PluginManagerWrapperImpl.java | 16 ++++++++----- .../quickstep/dagger/QuickStepModule.java | 8 ++++++- res/values/config.xml | 1 - .../dagger/LauncherBaseAppComponent.java | 2 ++ .../launcher3/util/PluginManagerWrapper.java | 23 ++++++++++++------- .../widget/custom/CustomWidgetManager.java | 20 ++++++---------- .../widget/custom/CustomWidgetManagerTest.kt | 17 +++++++------- 8 files changed, 49 insertions(+), 39 deletions(-) diff --git a/quickstep/res/values/config.xml b/quickstep/res/values/config.xml index 41b2384a35..db5ff199ab 100644 --- a/quickstep/res/values/config.xml +++ b/quickstep/res/values/config.xml @@ -33,7 +33,6 @@ com.android.launcher3.taskbar.TaskbarModelCallbacksFactory com.android.launcher3.taskbar.TaskbarViewCallbacksFactory com.android.quickstep.LauncherRestoreEventLoggerImpl - com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl com.android.launcher3.taskbar.TaskbarEduTooltipController com.android.quickstep.contextualeducation.SystemContextualEduStatsManager diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java index 74572c4136..3aa196365b 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapperImpl.java @@ -27,6 +27,8 @@ import android.content.Intent; import android.content.pm.ResolveInfo; import com.android.launcher3.BuildConfig; +import com.android.launcher3.dagger.ApplicationContext; +import com.android.launcher3.dagger.LauncherAppSingleton; import com.android.launcher3.util.PluginManagerWrapper; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; @@ -34,7 +36,6 @@ import com.android.systemui.shared.plugins.PluginActionManager; import com.android.systemui.shared.plugins.PluginInstance; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.plugins.PluginPrefs; -import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager; import java.io.PrintWriter; import java.util.ArrayList; @@ -42,16 +43,17 @@ import java.util.Collections; import java.util.List; import java.util.Set; -public class PluginManagerWrapperImpl extends PluginManagerWrapper { +import javax.inject.Inject; - private static final UncaughtExceptionPreHandlerManager UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER = - new UncaughtExceptionPreHandlerManager(); +@LauncherAppSingleton +public class PluginManagerWrapperImpl extends PluginManagerWrapper { private final Context mContext; private final PluginManagerImpl mPluginManager; private final PluginEnablerImpl mPluginEnabler; - public PluginManagerWrapperImpl(Context c) { + @Inject + public PluginManagerWrapperImpl(@ApplicationContext Context c) { mContext = c; mPluginEnabler = new PluginEnablerImpl(c); List privilegedPlugins = Collections.emptyList(); @@ -64,9 +66,11 @@ public class PluginManagerWrapperImpl extends PluginManagerWrapper { c.getSystemService(NotificationManager.class), mPluginEnabler, privilegedPlugins, instanceFactory); + // Use null preHandlerManager, as the handler is never unregistered which can cause leaks + // when using multiple dagger graphs. mPluginManager = new PluginManagerImpl(c, instanceManagerFactory, BuildConfig.IS_DEBUG_DEVICE, - UNCAUGHT_EXCEPTION_PRE_HANDLER_MANAGER, mPluginEnabler, + null /* preHandlerManager */, mPluginEnabler, new PluginPrefs(c), privilegedPlugins); } diff --git a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java index 08345b85f6..ab77a7f62c 100644 --- a/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java +++ b/quickstep/src/com/android/quickstep/dagger/QuickStepModule.java @@ -15,8 +15,14 @@ */ package com.android.quickstep.dagger; +import com.android.launcher3.uioverrides.plugins.PluginManagerWrapperImpl; +import com.android.launcher3.util.PluginManagerWrapper; + +import dagger.Binds; import dagger.Module; @Module -public class QuickStepModule { +public abstract class QuickStepModule { + + @Binds abstract PluginManagerWrapper bindPluginManagerWrapper(PluginManagerWrapperImpl impl); } diff --git a/res/values/config.xml b/res/values/config.xml index 701e64a4b4..504218b78e 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -85,7 +85,6 @@ - diff --git a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java index c3508b77db..4da7c2716a 100644 --- a/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java +++ b/src/com/android/launcher3/dagger/LauncherBaseAppComponent.java @@ -20,6 +20,7 @@ import android.content.Context; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.util.DaggerSingletonTracker; +import com.android.launcher3.util.PluginManagerWrapper; import com.android.launcher3.util.ScreenOnTracker; import com.android.launcher3.util.SettingsCache; import com.android.launcher3.widget.custom.CustomWidgetManager; @@ -40,6 +41,7 @@ public interface LauncherBaseAppComponent { ScreenOnTracker getScreenOnTracker(); SettingsCache getSettingsCache(); CustomWidgetManager getCustomWidgetManager(); + PluginManagerWrapper getPluginManagerWrapper(); /** Builder for LauncherBaseAppComponent. */ interface Builder { diff --git a/src/com/android/launcher3/util/PluginManagerWrapper.java b/src/com/android/launcher3/util/PluginManagerWrapper.java index b27aa120b9..5b28570acb 100644 --- a/src/com/android/launcher3/util/PluginManagerWrapper.java +++ b/src/com/android/launcher3/util/PluginManagerWrapper.java @@ -15,32 +15,39 @@ */ package com.android.launcher3.util; -import static com.android.launcher3.util.MainThreadInitializedObject.forOverride; +import androidx.annotation.AnyThread; -import com.android.launcher3.R; +import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.dagger.LauncherBaseAppComponent; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; import java.io.PrintWriter; -public class PluginManagerWrapper implements ResourceBasedOverride, SafeCloseable { +import javax.inject.Inject; - public static final MainThreadInitializedObject INSTANCE = - forOverride(PluginManagerWrapper.class, R.string.plugin_manager_wrapper_class); +@LauncherAppSingleton +public class PluginManagerWrapper{ + public static final DaggerSingletonObject INSTANCE = + new DaggerSingletonObject<>(LauncherBaseAppComponent::getPluginManagerWrapper); + + @Inject + public PluginManagerWrapper() { } + + @AnyThread public void addPluginListener( PluginListener listener, Class pluginClass) { addPluginListener(listener, pluginClass, false); } + @AnyThread public void addPluginListener( PluginListener listener, Class pluginClass, boolean allowMultiple) { } + @AnyThread public void removePluginListener(PluginListener listener) { } - @Override - public void close() { } - public void dump(PrintWriter pw) { } } diff --git a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java index 0778172127..4aeac7639a 100644 --- a/src/com/android/launcher3/widget/custom/CustomWidgetManager.java +++ b/src/com/android/launcher3/widget/custom/CustomWidgetManager.java @@ -41,7 +41,6 @@ import com.android.launcher3.util.DaggerSingletonTracker; import com.android.launcher3.util.ExecutorUtil; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.PluginManagerWrapper; -import com.android.launcher3.util.SafeCloseable; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.systemui.plugins.CustomWidgetPlugin; @@ -61,7 +60,7 @@ import javax.inject.Inject; * CustomWidgetManager handles custom widgets implemented as a plugin. */ @LauncherAppSingleton -public class CustomWidgetManager implements PluginListener, SafeCloseable { +public class CustomWidgetManager implements PluginListener { public static final DaggerSingletonObject INSTANCE = new DaggerSingletonObject<>(LauncherBaseAppComponent::getCustomWidgetManager); @@ -75,12 +74,14 @@ public class CustomWidgetManager implements PluginListener, private final @NonNull AppWidgetManager mAppWidgetManager; @Inject - CustomWidgetManager(@ApplicationContext Context context, DaggerSingletonTracker tracker) { - this(context, AppWidgetManager.getInstance(context), tracker); + CustomWidgetManager(@ApplicationContext Context context, PluginManagerWrapper pluginManager, + DaggerSingletonTracker tracker) { + this(context, pluginManager, AppWidgetManager.getInstance(context), tracker); } @VisibleForTesting CustomWidgetManager(@ApplicationContext Context context, + PluginManagerWrapper pluginManager, @NonNull AppWidgetManager widgetManager, DaggerSingletonTracker tracker) { mContext = context; @@ -88,11 +89,9 @@ public class CustomWidgetManager implements PluginListener, mPlugins = new HashMap<>(); mCustomWidgets = new ArrayList<>(); + pluginManager.addPluginListener(this, CustomWidgetPlugin.class, true); ExecutorUtil.executeSyncOnMainOrFail(() -> { - PluginManagerWrapper.INSTANCE.get(context) - .addPluginListener(this, CustomWidgetPlugin.class, true); - if (enableSmartspaceAsAWidget()) { for (String s: context.getResources() .getStringArray(R.array.custom_widget_providers)) { @@ -110,15 +109,10 @@ public class CustomWidgetManager implements PluginListener, } } - tracker.addCloseable(this); + tracker.addCloseable(() -> pluginManager.removePluginListener(this)); }); } - @Override - public void close() { - PluginManagerWrapper.INSTANCE.get(mContext).removePluginListener(this); - } - @Override public void onPluginConnected(CustomWidgetPlugin plugin, Context context) { List providers = mAppWidgetManager diff --git a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt index 82f56b8c2e..1c25db92be 100644 --- a/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt +++ b/tests/multivalentTests/src/com/android/launcher3/widget/custom/CustomWidgetManagerTest.kt @@ -26,17 +26,19 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import com.android.launcher3.util.DaggerSingletonTracker import com.android.launcher3.util.LauncherModelHelper.SandboxModelContext import com.android.launcher3.util.PluginManagerWrapper +import com.android.launcher3.util.SafeCloseable import com.android.launcher3.util.WidgetUtils import com.android.launcher3.widget.LauncherAppWidgetHostView import com.android.launcher3.widget.LauncherAppWidgetProviderInfo import com.android.systemui.plugins.CustomWidgetPlugin -import org.junit.After import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.mockito.ArgumentCaptor +import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.mock import org.mockito.MockitoAnnotations @@ -60,16 +62,12 @@ class CustomWidgetManagerTest { @Mock private lateinit var mockAppWidgetManager: AppWidgetManager @Mock private lateinit var tracker: DaggerSingletonTracker + @Captor private lateinit var closableCaptor: ArgumentCaptor + @Before fun setUp() { MockitoAnnotations.initMocks(this) - context.putObject(PluginManagerWrapper.INSTANCE, pluginManager) - underTest = CustomWidgetManager(context, mockAppWidgetManager, tracker) - } - - @After - fun tearDown() { - underTest.close() + underTest = CustomWidgetManager(context, pluginManager, mockAppWidgetManager, tracker) } @Test @@ -80,7 +78,8 @@ class CustomWidgetManagerTest { @Test fun close_widget_manager_should_remove_plugin_listener() { - underTest.close() + verify(tracker).addCloseable(closableCaptor.capture()) + closableCaptor.allValues.forEach(SafeCloseable::close) verify(pluginManager).removePluginListener(same(underTest)) }