diff --git a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java index 2db8b39d94..274a347cbb 100644 --- a/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java +++ b/go/quickstep/src/com/android/quickstep/GoActivityControlHelper.java @@ -61,4 +61,9 @@ public abstract class GoActivityControlHelper im // Go does not support live tiles. return false; } + + @Override + public void onLaunchTaskFailed(T activity) { + // Go does not support gestures from one task to another. + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java index f1d6450a5f..1c66968582 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java @@ -64,10 +64,12 @@ public class BackgroundAppState extends OverviewState { public ScaleAndTranslation getOverviewScaleAndTranslation(Launcher launcher) { // Initialize the recents view scale to what it would be when starting swipe up RecentsView recentsView = launcher.getOverviewPanel(); - if (recentsView.getTaskViewCount() == 0) { + int taskCount = recentsView.getTaskViewCount(); + if (taskCount == 0) { return super.getOverviewScaleAndTranslation(launcher); } - TaskView dummyTask = recentsView.getTaskViewAt(recentsView.getCurrentPage()); + TaskView dummyTask = recentsView.getTaskViewAt(Math.max(taskCount - 1, + recentsView.getCurrentPage())); return recentsView.getTempClipAnimationHelper().updateForFullscreenOverview(dummyTask) .getScaleAndTranslation(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java index ed511f5f2f..cdc271fdd3 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/states/QuickSwitchState.java @@ -15,6 +15,9 @@ */ package com.android.launcher3.uioverrides.states; +import android.os.Handler; +import android.os.Looper; + import com.android.launcher3.Launcher; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.quickstep.views.RecentsView; @@ -27,6 +30,8 @@ import com.android.quickstep.views.TaskView; */ public class QuickSwitchState extends BackgroundAppState { + private static final String TAG = "QuickSwitchState"; + public QuickSwitchState(int id) { super(id, LauncherLogProto.ContainerType.APP); } @@ -48,7 +53,12 @@ public class QuickSwitchState extends BackgroundAppState { public void onStateTransitionEnd(Launcher launcher) { TaskView tasktolaunch = launcher.getOverviewPanel().getTaskViewAt(0); if (tasktolaunch != null) { - tasktolaunch.launchTask(false); + tasktolaunch.launchTask(false, success -> { + if (!success) { + launcher.getStateManager().goToState(OVERVIEW); + tasktolaunch.notifyTaskLaunchFailed(TAG); + } + }, new Handler(Looper.getMainLooper())); } else { launcher.getStateManager().goToState(NORMAL); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java index 2c42fd63a6..4ae6d87b8d 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/FallbackActivityControllerHelper.java @@ -224,4 +224,10 @@ public final class FallbackActivityControllerHelper implements public boolean isInLiveTileMode() { return false; } + + @Override + public void onLaunchTaskFailed(RecentsActivity activity) { + // TODO: probably go back to overview instead. + activity.getOverviewPanel().startHome(); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java index 1b82bcb578..0d06c19ab5 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java @@ -16,13 +16,17 @@ package com.android.quickstep; import static android.view.View.TRANSLATION_Y; + import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.OVERVIEW; +import static com.android.launcher3.LauncherStateManager.ANIM_ALL; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_DAMPING_RATIO; import static com.android.launcher3.allapps.AllAppsTransitionController.SPRING_STIFFNESS; +import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; +import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.quickstep.WindowTransformSwipeHandler.RECENTS_ATTACH_DURATION; @@ -44,16 +48,19 @@ import android.view.animation.Interpolator; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import androidx.dynamicanimation.animation.SpringAnimation; +import androidx.dynamicanimation.animation.SpringForce; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherInitListenerEx; import com.android.launcher3.LauncherState; +import com.android.launcher3.LauncherStateManager; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.SpringObjectAnimator; -import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.views.FloatingIconView; @@ -99,6 +106,13 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe DiscoveryBounce.showForOverviewIfNeeded(activity); } + @Override + public void onSwipeUpToHomeComplete(Launcher activity) { + // Ensure recents is at the correct position for NORMAL state. For example, when we detach + // recents, we assume the first task is invisible, making translation off by one task. + activity.getStateManager().reapplyState(); + } + @Override public void onAssistantVisibilityChanged(float visibility) { Launcher launcher = getCreatedActivity(); @@ -156,18 +170,23 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe public AnimatorPlaybackController createActivityAnimationToHome() { // Return an empty APC here since we have an non-user controlled animation to home. long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx); - AnimatorSet as = new AnimatorSet(); - as.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationStart(Animator animation) { - activity.getStateManager().goToState(NORMAL, false); - } - }); - return AnimatorPlaybackController.wrap(as, accuracy); + return activity.getStateManager().createAnimationToNewWorkspace(NORMAL, accuracy, + 0 /* animComponents */); } @Override public void playAtomicAnimation(float velocity) { + // Setup workspace with 0 duration to prepare for our staggered animation. + LauncherStateManager stateManager = activity.getStateManager(); + AnimatorSetBuilder builder = new AnimatorSetBuilder(); + // setRecentsAttachedToAppWindow() will animate recents out. + builder.addFlag(AnimatorSetBuilder.FLAG_DONT_ANIMATE_OVERVIEW); + stateManager.createAtomicAnimation(BACKGROUND_APP, NORMAL, builder, ANIM_ALL, 0); + builder.build().start(); + + // Stop scrolling so that it doesn't interfere with the translation offscreen. + recentsView.getScroller().forceFinished(true); + new StaggeredWorkspaceAnim(activity, workspaceView, velocity).start(); } }; @@ -196,12 +215,11 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe // Optimization, hide the all apps view to prevent layout while initializing activity.getAppsView().getContentView().setVisibility(View.GONE); - AccessibilityManagerCompat.sendStateEventToTest(activity, fromState.ordinal); - return new AnimationFactory() { private Animator mShelfAnim; private ShelfAnimState mShelfState; - private Animator mAttachToWindowAnim; + private Animator mAttachToWindowFadeAnim; + private SpringAnimation mAttachToWindowTranslationXAnim; private boolean mIsAttachedToWindow; @Override @@ -267,20 +285,60 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return; } mIsAttachedToWindow = attached; - if (mAttachToWindowAnim != null) { - mAttachToWindowAnim.cancel(); + if (mAttachToWindowFadeAnim != null) { + mAttachToWindowFadeAnim.cancel(); } - mAttachToWindowAnim = ObjectAnimator.ofFloat(activity.getOverviewPanel(), + RecentsView recentsView = activity.getOverviewPanel(); + mAttachToWindowFadeAnim = ObjectAnimator.ofFloat(recentsView, RecentsView.CONTENT_ALPHA, attached ? 1 : 0); - mAttachToWindowAnim.addListener(new AnimatorListenerAdapter() { + + int runningTaskIndex = recentsView.getRunningTaskIndex(); + if (runningTaskIndex == 0) { + // If we are on the first task (we haven't quick switched), translate recents in + // from the side. Calculate the start translation based on current scale/scroll. + float currScale = recentsView.getScaleX(); + float scrollOffsetX = recentsView.getScrollOffset(); + + float offscreenX = NORMAL.getOverviewScaleAndTranslation(activity).translationX; + // The first task is hidden, so offset by its width. + int firstTaskWidth = recentsView.getTaskViewAt(0).getWidth(); + offscreenX -= (firstTaskWidth + recentsView.getPageSpacing()) * currScale; + // Offset since scale pushes tasks outwards. + offscreenX += firstTaskWidth * (currScale - 1) / 2; + offscreenX = Math.max(0, offscreenX); + if (recentsView.isRtl()) { + offscreenX = -offscreenX; + } + + float fromTranslationX = attached ? offscreenX - scrollOffsetX : 0; + float toTranslationX = attached ? 0 : offscreenX - scrollOffsetX; + if (mAttachToWindowTranslationXAnim == null) { + mAttachToWindowTranslationXAnim = new SpringAnimation(recentsView, + SpringAnimation.TRANSLATION_X).setSpring(new SpringForce() + .setDampingRatio(0.8f) + .setStiffness(250)); + } + if (!recentsView.isShown() && animate) { + recentsView.setTranslationX(fromTranslationX); + mAttachToWindowTranslationXAnim.setStartValue(fromTranslationX); + } + mAttachToWindowTranslationXAnim.animateToFinalPosition(toTranslationX); + if (!animate && mAttachToWindowTranslationXAnim.canSkipToEnd()) { + mAttachToWindowTranslationXAnim.skipToEnd(); + } + + mAttachToWindowFadeAnim.setInterpolator(attached ? INSTANT : ACCEL_2); + } else { + mAttachToWindowFadeAnim.setInterpolator(ACCEL_DEACCEL); + } + mAttachToWindowFadeAnim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - mAttachToWindowAnim = null; + mAttachToWindowFadeAnim = null; } }); - mAttachToWindowAnim.setInterpolator(ACCEL_DEACCEL); - mAttachToWindowAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0); - mAttachToWindowAnim.start(); + mAttachToWindowFadeAnim.setDuration(animate ? RECENTS_ATTACH_DURATION : 0); + mAttachToWindowFadeAnim.start(); } }; } @@ -448,4 +506,9 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe return launcher != null && launcher.getStateManager().getState() == OVERVIEW && launcher.isStarted(); } + + @Override + public void onLaunchTaskFailed(Launcher launcher) { + launcher.getStateManager().goToState(OVERVIEW); + } } \ No newline at end of file diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java index 5a039cd905..6689ce3d78 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/SwipeSharedState.java @@ -15,8 +15,11 @@ */ package com.android.quickstep; +import static com.android.quickstep.TouchInteractionService.MAIN_THREAD_EXECUTOR; + import android.util.Log; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.Preconditions; import com.android.quickstep.util.RecentsAnimationListenerSet; @@ -29,7 +32,7 @@ import java.io.PrintWriter; */ public class SwipeSharedState implements SwipeAnimationListener { - private final OverviewComponentObserver mOverviewComponentObserver; + private OverviewComponentObserver mOverviewComponentObserver; private RecentsAnimationListenerSet mRecentsAnimationListener; private SwipeAnimationTargetSet mLastAnimationTarget; @@ -42,8 +45,8 @@ public class SwipeSharedState implements SwipeAnimationListener { public boolean recentsAnimationFinishInterrupted; public int nextRunningTaskId = -1; - public SwipeSharedState(OverviewComponentObserver overviewComponentObserver) { - mOverviewComponentObserver = overviewComponentObserver; + public void setOverviewComponentObserver(OverviewComponentObserver observer) { + mOverviewComponentObserver = observer; } @Override @@ -72,6 +75,12 @@ public class SwipeSharedState implements SwipeAnimationListener { private void clearListenerState() { if (mRecentsAnimationListener != null) { mRecentsAnimationListener.removeListener(this); + mRecentsAnimationListener.cancelListener(); + if (mLastAnimationRunning && mLastAnimationTarget != null) { + Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), + mLastAnimationTarget::cancelAnimation); + mLastAnimationTarget = null; + } } mRecentsAnimationListener = null; clearAnimationTarget(); @@ -98,9 +107,10 @@ public class SwipeSharedState implements SwipeAnimationListener { } clearListenerState(); - mRecentsAnimationListener = new RecentsAnimationListenerSet(mOverviewComponentObserver - .getActivityControlHelper().shouldMinimizeSplitScreen(), - this::onSwipeAnimationFinished); + boolean shouldMinimiseSplitScreen = mOverviewComponentObserver == null ? false + : mOverviewComponentObserver.getActivityControlHelper().shouldMinimizeSplitScreen(); + mRecentsAnimationListener = new RecentsAnimationListenerSet( + shouldMinimiseSplitScreen, this::onSwipeAnimationFinished); mRecentsAnimationListener.addListener(this); return mRecentsAnimationListener; } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java index 5104fb8801..b90f6c2b17 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskOverlayFactory.java @@ -24,6 +24,7 @@ import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.R; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.launcher3.util.ResourceBasedOverride; +import com.android.quickstep.views.TaskThumbnailView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; @@ -62,7 +63,7 @@ public class TaskOverlayFactory implements ResourceBasedOverride { return shortcuts; } - public TaskOverlay createOverlay(View thumbnailView) { + public TaskOverlay createOverlay(TaskThumbnailView thumbnailView) { return new TaskOverlay(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java index dc354404af..097ff46592 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java @@ -17,7 +17,12 @@ package com.android.quickstep; import static android.view.MotionEvent.ACTION_DOWN; +import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; +import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME; +import static com.android.launcher3.config.FeatureFlags.ENABLE_HINTS_IN_OVERVIEW; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; +import static com.android.launcher3.config.FeatureFlags.FAKE_LANDSCAPE_UI; +import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; @@ -27,7 +32,6 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_N import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; -import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.annotation.TargetApi; @@ -61,6 +65,7 @@ import android.view.Surface; import android.view.WindowManager; import androidx.annotation.BinderThread; +import androidx.annotation.UiThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.MainThreadExecutor; @@ -81,6 +86,7 @@ import com.android.quickstep.inputconsumers.InputConsumer; import com.android.quickstep.inputconsumers.OtherActivityInputConsumer; import com.android.quickstep.inputconsumers.OverviewInputConsumer; import com.android.quickstep.inputconsumers.OverviewWithoutFocusInputConsumer; +import com.android.quickstep.inputconsumers.ResetGestureInputConsumer; import com.android.quickstep.inputconsumers.ScreenPinnedInputConsumer; import com.android.systemui.shared.recents.IOverviewProxy; import com.android.systemui.shared.recents.ISystemUiProxy; @@ -94,7 +100,6 @@ import com.android.systemui.shared.system.SystemGestureExclusionListenerCompat; import java.io.FileDescriptor; import java.io.PrintWriter; -import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -146,10 +151,7 @@ public class TouchInteractionService extends Service implements mISystemUiProxy = ISystemUiProxy.Stub .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY)); MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::initInputMonitor); - runWhenUserUnlocked(() -> { - mRecentsModel.setSystemUiProxy(mISystemUiProxy); - mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); - }); + MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiProxySet); } @Override @@ -182,16 +184,9 @@ public class TouchInteractionService extends Service implements @Override public void onAssistantVisibilityChanged(float visibility) { - if (mOverviewComponentObserver == null) { - // Save the visibility to be applied when the user is unlocked - mPendingAssistantVisibility = visibility; - return; - } - - MAIN_THREAD_EXECUTOR.execute(() -> { - mOverviewComponentObserver.getActivityControlHelper() - .onAssistantVisibilityChanged(visibility); - }); + mLastAssistantVisibility = visibility; + MAIN_THREAD_EXECUTOR.execute( + TouchInteractionService.this::onAssistantVisibilityChanged); } public void onBackAction(boolean completed, int downX, int downY, boolean isButton, @@ -208,8 +203,7 @@ public class TouchInteractionService extends Service implements public void onSystemUiStateChanged(int stateFlags) { mSystemUiStateFlags = stateFlags; - mOverviewInteractionState.setSystemUiStateFlags(stateFlags); - mOverviewComponentObserver.onSystemUiStateChanged(stateFlags); + MAIN_THREAD_EXECUTOR.execute(TouchInteractionService.this::onSystemUiFlagsChanged); } /** Deprecated methods **/ @@ -236,6 +230,10 @@ public class TouchInteractionService extends Service implements return sConnected; } + private final SwipeSharedState mSwipeSharedState = new SwipeSharedState(); + private final InputConsumer mResetGestureInputConsumer = + new ResetGestureInputConsumer(mSwipeSharedState); + private KeyguardManager mKM; private ActivityManagerWrapper mAM; private RecentsModel mRecentsModel; @@ -246,13 +244,11 @@ public class TouchInteractionService extends Service implements private OverviewCallbacks mOverviewCallbacks; private TaskOverlayFactory mTaskOverlayFactory; private InputConsumerController mInputConsumer; - private SwipeSharedState mSwipeSharedState; private boolean mAssistantAvailable; - private float mPendingAssistantVisibility = 0; + private float mLastAssistantVisibility = 0; private @SystemUiStateFlags int mSystemUiStateFlags; private boolean mIsUserUnlocked; - private List mOnUserUnlockedCallbacks; private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -286,7 +282,7 @@ public class TouchInteractionService extends Service implements // Everything else should be initialized in initWhenUserUnlocked() below. mKM = getSystemService(KeyguardManager.class); mMainChoreographer = Choreographer.getInstance(); - mOnUserUnlockedCallbacks = new ArrayList<>(); + mAM = ActivityManagerWrapper.getInstance(); if (UserManagerCompat.getInstance(this).isUserUnlocked(Process.myUserHandle())) { initWhenUserUnlocked(); @@ -413,26 +409,21 @@ public class TouchInteractionService extends Service implements } private void initWhenUserUnlocked() { - mIsUserUnlocked = true; - - mAM = ActivityManagerWrapper.getInstance(); mRecentsModel = RecentsModel.INSTANCE.get(this); mOverviewComponentObserver = new OverviewComponentObserver(this); - mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged( - mPendingAssistantVisibility); mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver); mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this); mOverviewCallbacks = OverviewCallbacks.get(this); mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this); - mSwipeSharedState = new SwipeSharedState(mOverviewComponentObserver); mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); - mInputConsumer.registerInputConsumer(); + mIsUserUnlocked = true; - for (Runnable callback : mOnUserUnlockedCallbacks) { - callback.run(); - } - mOnUserUnlockedCallbacks.clear(); + mSwipeSharedState.setOverviewComponentObserver(mOverviewComponentObserver); + mInputConsumer.registerInputConsumer(); + onSystemUiProxySet(); + onSystemUiFlagsChanged(); + onAssistantVisibilityChanged(); // Temporarily disable model preload // new ModelPreload().start(this); @@ -440,11 +431,27 @@ public class TouchInteractionService extends Service implements Utilities.unregisterReceiverSafely(this, mUserUnlockedReceiver); } - private void runWhenUserUnlocked(Runnable callback) { + @UiThread + private void onSystemUiProxySet() { if (mIsUserUnlocked) { - callback.run(); - } else { - mOnUserUnlockedCallbacks.add(callback); + mRecentsModel.setSystemUiProxy(mISystemUiProxy); + mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy); + } + } + + @UiThread + private void onSystemUiFlagsChanged() { + if (mIsUserUnlocked) { + mOverviewInteractionState.setSystemUiStateFlags(mSystemUiStateFlags); + mOverviewComponentObserver.onSystemUiStateChanged(mSystemUiStateFlags); + } + } + + @UiThread + private void onAssistantVisibilityChanged() { + if (mIsUserUnlocked) { + mOverviewComponentObserver.getActivityControlHelper().onAssistantVisibilityChanged( + mLastAssistantVisibility); } } @@ -510,12 +517,14 @@ public class TouchInteractionService extends Service implements // launched while device is locked even after exiting direct boot mode (e.g. camera). return createDeviceLockedInputConsumer(mAM.getRunningTask(0)); } else { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } } - InputConsumer base = isInValidSystemUiState - ? newBaseConsumer(useSharedState, event) : InputConsumer.NO_OP; + // When using sharedState, bypass systemState check as this is a followup gesture and the + // first gesture started in a valid system state. + InputConsumer base = isInValidSystemUiState || useSharedState + ? newBaseConsumer(useSharedState, event) : mResetGestureInputConsumer; if (mMode == Mode.NO_BUTTON) { final ActivityControlHelper activityControl = mOverviewComponentObserver.getActivityControlHelper(); @@ -560,7 +569,7 @@ public class TouchInteractionService extends Service implements if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher && !mSwipeSharedState.recentsAnimationFinishInterrupted) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } else if (mSwipeSharedState.recentsAnimationFinishInterrupted) { // If the finish animation was interrupted, then continue using the other activity input // consumer but with the next task as the running task @@ -573,7 +582,7 @@ public class TouchInteractionService extends Service implements return createOverviewInputConsumer(event); } else if (mGestureBlockingActivity != null && runningTaskInfo != null && mGestureBlockingActivity.equals(runningTaskInfo.topActivity)) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } else { return createOtherActivityInputConsumer(event, runningTaskInfo); } @@ -604,7 +613,7 @@ public class TouchInteractionService extends Service implements return new DeviceLockedInputConsumer(this, mSwipeSharedState, mInputMonitorCompat, mSwipeTouchRegion, taskInfo.taskId); } else { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } } @@ -613,10 +622,10 @@ public class TouchInteractionService extends Service implements mOverviewComponentObserver.getActivityControlHelper(); BaseDraggingActivity activity = activityControl.getCreatedActivity(); if (activity == null) { - return InputConsumer.NO_OP; + return mResetGestureInputConsumer; } - if (activity.getRootView().hasWindowFocus()) { + if (activity.getRootView().hasWindowFocus() || mSwipeSharedState.goingToLauncher) { return new OverviewInputConsumer(activity, mInputMonitorCompat, false /* startingInActivityBounds */); } else { @@ -630,7 +639,8 @@ public class TouchInteractionService extends Service implements */ private void onConsumerInactive(InputConsumer caller) { if (mConsumer == caller) { - mConsumer = InputConsumer.NO_OP; + mConsumer = mResetGestureInputConsumer; + mUncheckedConsumer = mConsumer; } } @@ -666,6 +676,13 @@ public class TouchInteractionService extends Service implements mSwipeSharedState.dump(" ", pw); } pw.println(" mConsumer=" + mConsumer.getName()); + pw.println("FeatureFlags:"); + pw.println(" APPLY_CONFIG_AT_RUNTIME=" + APPLY_CONFIG_AT_RUNTIME.get()); + pw.println(" QUICKSTEP_SPRINGS=" + QUICKSTEP_SPRINGS.get()); + pw.println(" ADAPTIVE_ICON_WINDOW_ANIM=" + ADAPTIVE_ICON_WINDOW_ANIM.get()); + pw.println(" ENABLE_QUICKSTEP_LIVE_TILE=" + ENABLE_QUICKSTEP_LIVE_TILE.get()); + pw.println(" ENABLE_HINTS_IN_OVERVIEW=" + ENABLE_HINTS_IN_OVERVIEW.get()); + pw.println(" FAKE_LANDSCAPE_UI=" + FAKE_LANDSCAPE_UI.get()); TOUCH_INTERACTION_LOG.dump("", pw); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java index c7841d98e3..e9aa6d0780 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java @@ -21,7 +21,6 @@ import static com.android.launcher3.Utilities.SINGLE_FRAME_MS; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_1_5; import static com.android.launcher3.anim.Interpolators.DEACCEL; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2; import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; @@ -218,7 +217,7 @@ public class WindowTransformSwipeHandler Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW)); private static final String SCREENSHOT_CAPTURED_EVT = "ScreenshotCaptured"; - private static final long SHELF_ANIM_DURATION = 120; + private static final long SHELF_ANIM_DURATION = 240; public static final long RECENTS_ATTACH_DURATION = 300; // Start resisting when swiping past this factor of mTransitionDragLength. @@ -602,7 +601,7 @@ public class WindowTransformSwipeHandler } public void onMotionPauseChanged(boolean isPaused) { - setShelfState(isPaused ? PEEK : HIDE, FAST_OUT_SLOW_IN, SHELF_ANIM_DURATION); + setShelfState(isPaused ? PEEK : HIDE, OVERSHOOT_1_2, SHELF_ANIM_DURATION); } public void maybeUpdateRecentsAttachedState() { @@ -625,7 +624,10 @@ public class WindowTransformSwipeHandler : mRecentsAnimationWrapper.targetSet.findTask(mRunningTaskId); final boolean recentsAttachedToAppWindow; int runningTaskIndex = mRecentsView.getRunningTaskIndex(); - if (mContinuingLastGesture) { + if (mGestureEndTarget != null) { + recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow; + } else if (mContinuingLastGesture + && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) { recentsAttachedToAppWindow = true; animate = false; } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) { @@ -633,17 +635,16 @@ public class WindowTransformSwipeHandler recentsAttachedToAppWindow = true; animate = false; } else { - if (mGestureEndTarget != null) { - recentsAttachedToAppWindow = mGestureEndTarget.recentsAttachedToAppWindow; - } else { - recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask; - } + recentsAttachedToAppWindow = mIsShelfPeeking || mIsLikelyToStartNewTask; if (animate) { // Only animate if an adjacent task view is visible on screen. TaskView adjacentTask1 = mRecentsView.getTaskViewAt(runningTaskIndex + 1); TaskView adjacentTask2 = mRecentsView.getTaskViewAt(runningTaskIndex - 1); + float prevTranslationX = mRecentsView.getTranslationX(); + mRecentsView.setTranslationX(0); animate = (adjacentTask1 != null && adjacentTask1.getGlobalVisibleRect(TEMP_RECT)) || (adjacentTask2 != null && adjacentTask2.getGlobalVisibleRect(TEMP_RECT)); + mRecentsView.setTranslationX(prevTranslationX); } } mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); @@ -701,13 +702,7 @@ public class WindowTransformSwipeHandler SwipeAnimationTargetSet controller = mRecentsAnimationWrapper.getController(); if (controller != null) { - float offsetX = 0; - if (mRecentsView != null) { - int startScroll = mRecentsView.getScrollForPage(mRecentsView.indexOfChild( - mRecentsView.getRunningTaskView())); - offsetX = startScroll - mRecentsView.getScrollX(); - offsetX *= mRecentsView.getScaleX(); - } + float offsetX = mRecentsView == null ? 0 : mRecentsView.getScrollOffset(); float offsetScale = getTaskCurveScaleForOffsetX(offsetX, mClipAnimationHelper.getTargetRect().width()); mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale); @@ -751,6 +746,9 @@ public class WindowTransformSwipeHandler ? 0 : (progress - mShiftAtGestureStart) / (1 - mShiftAtGestureStart)); } + /** + * @param windowProgress 0 == app, 1 == overview + */ private void updateSysUiFlags(float windowProgress) { if (mRecentsView != null) { TaskView centermostTask = mRecentsView.getTaskViewAt(mRecentsView @@ -873,9 +871,7 @@ public class WindowTransformSwipeHandler @UiThread private InputConsumer createNewInputProxyHandler() { endRunningWindowAnim(); - if (mLauncherTransitionController != null) { - mLauncherTransitionController.getAnimationPlayer().end(); - } + endLauncherTransitionController(); if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { // Hide the task view, if not already hidden setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha); @@ -1217,6 +1213,9 @@ public class WindowTransformSwipeHandler if (mRecentsView != null) { mRecentsView.post(mRecentsView::resetTaskVisuals); } + // Make sure recents is in its final state + maybeUpdateRecentsAttachedState(false); + mActivityControlHelper.onSwipeUpToHomeComplete(mActivity); } }); return anim; @@ -1251,7 +1250,17 @@ public class WindowTransformSwipeHandler if (!mCanceled) { TaskView nextTask = mRecentsView.getTaskView(taskId); if (nextTask != null) { - nextTask.launchTask(false /* animate */, true /* freezeTaskList */); + nextTask.launchTask(false /* animate */, true /* freezeTaskList */, + success -> { + if (!success) { + // We couldn't launch the task, so take user to overview so they can + // decide what to do instead of staying in this broken state. + endLauncherTransitionController(); + mActivityControlHelper.onLaunchTaskFailed(mActivity); + nextTask.notifyTaskLaunchFailed(TAG); + updateSysUiFlags(1 /* windowProgress == overview */); + } + }, mMainThreadHandler); doLogGesture(NEW_TASK); } reset(); @@ -1314,6 +1323,7 @@ public class WindowTransformSwipeHandler } private void endLauncherTransitionController() { + setShelfState(ShelfAnimState.CANCEL, LINEAR, 0); if (mLauncherTransitionController != null) { mLauncherTransitionController.getAnimationPlayer().end(); mLauncherTransitionController = null; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java index 489eb278fd..a1e5d47a53 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/InputConsumer.java @@ -32,6 +32,19 @@ public interface InputConsumer { int TYPE_ACCESSIBILITY = 1 << 5; int TYPE_SCREEN_PINNED = 1 << 6; int TYPE_OVERVIEW_WITHOUT_FOCUS = 1 << 7; + int TYPE_RESET_GESTURE = 1 << 8; + + String[] NAMES = new String[] { + "TYPE_NO_OP", // 0 + "TYPE_OVERVIEW", // 1 + "TYPE_OTHER_ACTIVITY", // 2 + "TYPE_ASSISTANT", // 3 + "TYPE_DEVICE_LOCKED", // 4 + "TYPE_ACCESSIBILITY", // 5 + "TYPE_SCREEN_PINNED", // 6 + "TYPE_OVERVIEW_WITHOUT_FOCUS", // 7 + "TYPE_RESET_GESTURE", // 8 + }; InputConsumer NO_OP = () -> TYPE_NO_OP; @@ -66,23 +79,15 @@ public interface InputConsumer { } default String getName() { - switch (getType()) { - case TYPE_OVERVIEW: - return "OVERVIEW"; - case TYPE_OTHER_ACTIVITY: - return "OTHER_ACTIVITY"; - case TYPE_ASSISTANT: - return "ASSISTANT"; - case TYPE_DEVICE_LOCKED: - return "DEVICE_LOCKED"; - case TYPE_ACCESSIBILITY: - return "ACCESSIBILITY"; - case TYPE_SCREEN_PINNED: - return "SCREEN_PINNED"; - case TYPE_OVERVIEW_WITHOUT_FOCUS: - return "TYPE_OVERVIEW_WITHOUT_FOCUS"; - default: - return "NO_OP"; + String name = ""; + for (int i = 0; i < NAMES.length; i++) { + if ((getType() & (1 << i)) != 0) { + if (name.length() > 0) { + name += ":"; + } + name += NAMES[i]; + } } + return name; } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java index 70ea62796d..b021df877e 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OverviewInputConsumer.java @@ -27,7 +27,6 @@ import androidx.annotation.Nullable; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.Utilities; import com.android.launcher3.views.BaseDragLayer; -import com.android.quickstep.ActivityControlHelper; import com.android.quickstep.OverviewCallbacks; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; @@ -114,13 +113,5 @@ public class OverviewInputConsumer mActivity.dispatchKeyEvent(ev); } } - - public static InputConsumer newInstanceWithinActivityBounds( - ActivityControlHelper activityHelper) { - BaseDraggingActivity activity = activityHelper.getCreatedActivity(); - if (activity == null) { - return InputConsumer.NO_OP; - } - return new OverviewInputConsumer(activity, null, true); - } } + diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java new file mode 100644 index 0000000000..56cba2192a --- /dev/null +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/ResetGestureInputConsumer.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2019 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.inputconsumers; + +import android.view.MotionEvent; + +import com.android.quickstep.SwipeSharedState; + +/** + * A NO_OP input consumer which also resets any pending gesture + */ +public class ResetGestureInputConsumer implements InputConsumer { + + private final SwipeSharedState mSwipeSharedState; + + public ResetGestureInputConsumer(SwipeSharedState swipeSharedState) { + mSwipeSharedState = swipeSharedState; + } + + @Override + public int getType() { + return TYPE_RESET_GESTURE; + } + + @Override + public void onMotionEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN + && mSwipeSharedState.getActiveListener() != null) { + mSwipeSharedState.clearAllState(); + } + } +} diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java index 19a4963467..6dc672ecfa 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/ClipAnimationHelper.java @@ -192,6 +192,7 @@ public class ClipAnimationHelper { float cornerRadius = 0f; float scale = Math.max(params.currentRect.width(), mTargetRect.width()) / crop.width(); if (app.mode == targetSet.targetMode) { + alpha = mTaskAlphaCallback.apply(app, params.targetAlpha); if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL); mTmpMatrix.postTranslate(app.position.x, app.position.y); @@ -208,8 +209,11 @@ public class ClipAnimationHelper { } mCurrentCornerRadius = cornerRadius; } + } else if (targetSet.hasRecents) { + // If home has a different target then recents, reverse anim the + // home target. + alpha = 1 - (progress * params.targetAlpha); } - alpha = mTaskAlphaCallback.apply(app, params.targetAlpha); } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() && launcherOnTop) { crop = null; layer = Integer.MAX_VALUE; diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java index 94e704a716..83601e6175 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/RecentsAnimationListenerSet.java @@ -49,6 +49,8 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { private final Consumer mOnFinishListener; private RecentsAnimationControllerCompat mController; + private boolean mCancelled; + public RecentsAnimationListenerSet(boolean shouldMinimizeSplitScreen, Consumer onFinishListener) { mShouldMinimizeSplitScreen = shouldMinimizeSplitScreen; @@ -75,11 +77,16 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { SwipeAnimationTargetSet targetSet = new SwipeAnimationTargetSet(controller, targets, homeContentInsets, minimizedHomeBounds, mShouldMinimizeSplitScreen, mOnFinishListener); - Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { - for (SwipeAnimationListener listener : getListeners()) { - listener.onRecentsAnimationStart(targetSet); - } - }); + + if (mCancelled) { + targetSet.cancelAnimation(); + } else { + Utilities.postAsyncCallback(MAIN_THREAD_EXECUTOR.getHandler(), () -> { + for (SwipeAnimationListener listener : getListeners()) { + listener.onRecentsAnimationStart(targetSet); + } + }); + } } @Override @@ -99,4 +106,9 @@ public class RecentsAnimationListenerSet implements RecentsAnimationListener { private SwipeAnimationListener[] getListeners() { return mListeners.toArray(new SwipeAnimationListener[mListeners.size()]); } + + public void cancelListener() { + mCancelled = true; + onAnimationCanceled(false); + } } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java index f5a9e8a058..df9efa2477 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/util/SwipeAnimationTargetSet.java @@ -36,7 +36,6 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { private final boolean mShouldMinimizeSplitScreen; private final Consumer mOnFinishListener; - public final RecentsAnimationControllerCompat controller; public final Rect homeContentInsets; public final Rect minimizedHomeBounds; @@ -103,6 +102,10 @@ public class SwipeAnimationTargetSet extends RemoteAnimationTargetSet { return controller != null ? controller.screenshotTask(taskId) : null; } + public void cancelAnimation() { + finishController(false /* toRecents */, null, false /* sendUserLeaveHint */); + } + public interface SwipeAnimationListener { void onRecentsAnimationStart(SwipeAnimationTargetSet targetSet); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java index 204dd56872..5aab944a32 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/DigitalWellBeingToast.java @@ -37,7 +37,7 @@ import android.widget.TextView; import androidx.annotation.StringRes; -import com.android.launcher3.Launcher; +import com.android.launcher3.BaseActivity; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.userevent.nano.LauncherLogProto; @@ -187,12 +187,12 @@ public final class DigitalWellBeingToast extends LinearLayout { mTask.getTopComponent().getPackageName()).addFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); try { - final Launcher launcher = Launcher.getLauncher(getContext()); + final BaseActivity activity = BaseActivity.fromContext(getContext()); final ActivityOptions options = ActivityOptions.makeScaleUpAnimation( this, 0, 0, getWidth(), getHeight()); - launcher.startActivity(intent, options.toBundle()); - launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP, + activity.startActivity(intent, options.toBundle()); + activity.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP, LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this); } catch (ActivityNotFoundException e) { Log.e(TAG, "Failed to open app usage settings for task " diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java index e38a315f8a..f66e401f9a 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java @@ -892,7 +892,7 @@ public abstract class RecentsView extends PagedView impl mRunningTaskTileHidden = isHidden; TaskView runningTask = getRunningTaskView(); if (runningTask != null) { - runningTask.setAlpha(isHidden ? 0 : mContentAlpha); + runningTask.setStableAlpha(isHidden ? 0 : mContentAlpha); } } @@ -1294,7 +1294,7 @@ public abstract class RecentsView extends PagedView impl for (int i = getTaskViewCount() - 1; i >= 0; i--) { TaskView child = getTaskViewAt(i); if (!mRunningTaskTileHidden || child.getTask().key.id != mRunningTaskId) { - getChildAt(i).setAlpha(alpha); + child.setStableAlpha(alpha); } } mClearAllButton.setContentAlpha(mContentAlpha); @@ -1676,6 +1676,16 @@ public abstract class RecentsView extends PagedView impl return mClearAllButton; } + /** + * @return How many pixels the running task is offset on the x-axis due to the current scrollX. + */ + public float getScrollOffset() { + int startScroll = getScrollForPage(getRunningTaskIndex()); + int offsetX = startScroll - getScrollX(); + offsetX *= getScaleX(); + return offsetX; + } + public Consumer getEventDispatcher(RotationMode rotationMode) { if (rotationMode.isTransposed) { Matrix transform = new Matrix(); diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java index 8b8240d0a5..6f10b42fba 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskThumbnailView.java @@ -252,7 +252,7 @@ public class TaskThumbnailView extends View { } } - protected TaskView getTaskView() { + public TaskView getTaskView() { return (TaskView) getParent(); } diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java index bf3e91ff68..694d501905 100644 --- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java @@ -163,6 +163,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { private ObjectAnimator mIconAndDimAnimator; private float mIconScaleAnimStartProgress = 0; private float mFocusTransitionProgress = 1; + private float mStableAlpha = 1; private boolean mShowScreenshot; @@ -353,14 +354,15 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mIconLoadRequest = iconCache.updateIconInBackground(mTask, (task) -> { setIcon(task.icon); - if (isRunningTask()) { + if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask()) { getRecentsView().updateLiveTileIcon(task.icon); } mDigitalWellBeingToast.initialize( mTask, contentDescription -> { setContentDescription(contentDescription); - if (mDigitalWellBeingToast.getVisibility() == VISIBLE) { + if (mDigitalWellBeingToast.getVisibility() == VISIBLE + && getRecentsView() != null) { getRecentsView().onDigitalWellbeingToastShown(); } }); @@ -468,7 +470,7 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { setTranslationX(0f); setTranslationY(0f); setTranslationZ(0); - setAlpha(1f); + setAlpha(mStableAlpha); setIconScaleAndDim(1); } @@ -477,6 +479,11 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { setFullscreenProgress(0); } + public void setStableAlpha(float parentAlpha) { + mStableAlpha = parentAlpha; + setAlpha(mStableAlpha); + } + @Override public void onRecycle() { resetViewTransforms(); @@ -498,6 +505,8 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { mSnapshotView.setDimAlpha(curveInterpolation * MAX_PAGE_SCRIM_ALPHA); setCurveScale(getCurveScaleForCurveInterpolation(curveInterpolation)); + float fade = Utilities.boundToRange(1.0f - 2 * scrollState.linearInterpolation, 0f, 1f); + mTaskFooterContainer.setAlpha(fade); if (mMenuView != null) { mMenuView.setPosition(getX() - getRecentsView().getScrollX(), getY()); mMenuView.setScaleX(getScaleX()); @@ -716,6 +725,9 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { } public boolean isRunningTask() { + if (getRecentsView() == null) { + return false; + } return this == getRecentsView().getRunningTaskView(); } diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml index 18691889ff..6a595a16e5 100644 --- a/quickstep/res/layout/task.xml +++ b/quickstep/res/layout/task.xml @@ -40,6 +40,8 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" + android:animateLayoutChanges="true" + android:forceHasOverlappingRendering="true" android:layout_gravity="bottom|center_horizontal"> "إغلاق" "إعدادات استخدام التطبيق" "محو الكل" - "التطبيقات المستخدمة مؤخرًا" + "التطبيقات التي تمّ استخدامها مؤخرًا" "%1$s، %2$s" "أقل من دقيقة" "يتبقى اليوم %1$s." diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 449cc8c11d..7f4e56d260 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -20,7 +20,7 @@ "Splitscreen" - "Anpinnen" + "Fixieren" "Freeform-Modus" "Übersicht" "Keine kürzlich verwendeten Elemente" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index 356d10d5da..c6698bb480 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -27,7 +27,7 @@ "Pecha a aplicación" "Configuración do uso de aplicacións" "Borrar todo" - "Apps recentes" + "Aplicacións recentes" "%1$s (%2$s)" "<1 min" "Tempo restante hoxe %1$s" diff --git a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java index 1e8bd933f9..bee8bb8132 100644 --- a/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java +++ b/quickstep/src/com/android/launcher3/proxy/StartActivityParams.java @@ -31,7 +31,7 @@ public class StartActivityParams implements Parcelable { private static final String TAG = "StartActivityParams"; - private final PendingIntent mCallback; + private final PendingIntent mPICallback; public final int requestCode; public Intent intent; @@ -44,13 +44,17 @@ public class StartActivityParams implements Parcelable { public Bundle options; public StartActivityParams(Activity activity, int requestCode) { - mCallback = activity.createPendingResult(requestCode, new Intent(), - PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT); + this(activity.createPendingResult(requestCode, new Intent(), + PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT), requestCode); + } + + public StartActivityParams(PendingIntent pendingIntent, int requestCode) { + this.mPICallback = pendingIntent; this.requestCode = requestCode; } private StartActivityParams(Parcel parcel) { - mCallback = parcel.readTypedObject(PendingIntent.CREATOR); + mPICallback = parcel.readTypedObject(PendingIntent.CREATOR); requestCode = parcel.readInt(); intent = parcel.readTypedObject(Intent.CREATOR); @@ -70,7 +74,7 @@ public class StartActivityParams implements Parcelable { @Override public void writeToParcel(Parcel parcel, int flags) { - parcel.writeTypedObject(mCallback, flags); + parcel.writeTypedObject(mPICallback, flags); parcel.writeInt(requestCode); parcel.writeTypedObject(intent, flags); @@ -84,7 +88,9 @@ public class StartActivityParams implements Parcelable { public void deliverResult(Context context, int resultCode, Intent data) { try { - mCallback.send(context, resultCode, data); + if (mPICallback != null) { + mPICallback.send(context, resultCode, data); + } } catch (CanceledException e) { Log.e(TAG, "Unable to send back result", e); } diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java index b17d8d69c7..8675c3e02e 100644 --- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java +++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java @@ -53,6 +53,7 @@ public interface ActivityControlHelper { void onSwipeUpToRecentsComplete(T activity); + default void onSwipeUpToHomeComplete(T activity) { } void onAssistantVisibilityChanged(float visibility); @NonNull HomeAnimationFactory prepareHomeUI(T activity); @@ -92,6 +93,8 @@ public interface ActivityControlHelper { boolean isInLiveTileMode(); + void onLaunchTaskFailed(T activity); + interface ActivityInitListener { void register(); diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java index 0df4e947d3..1229293e6e 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationTargetSet.java @@ -33,20 +33,26 @@ public class RemoteAnimationTargetSet { public final RemoteAnimationTargetCompat[] unfilteredApps; public final RemoteAnimationTargetCompat[] apps; public final int targetMode; + public final boolean hasRecents; public RemoteAnimationTargetSet(RemoteAnimationTargetCompat[] apps, int targetMode) { ArrayList filteredApps = new ArrayList<>(); + boolean hasRecents = false; if (apps != null) { for (RemoteAnimationTargetCompat target : apps) { if (target.mode == targetMode) { filteredApps.add(target); } + + hasRecents |= target.activityType == + RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS; } } this.unfilteredApps = apps; this.apps = filteredApps.toArray(new RemoteAnimationTargetCompat[filteredApps.size()]); this.targetMode = targetMode; + this.hasRecents = hasRecents; } public RemoteAnimationTargetCompat findTask(int taskId) { diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 20fdff2c55..013591171c 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -22,6 +22,7 @@ import static androidx.test.InstrumentationRegistry.getInstrumentation; import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS; import static com.android.launcher3.tapl.TestHelpers.getHomeIntentInPackage; import static com.android.launcher3.tapl.TestHelpers.getLauncherInMyProcess; +import static com.android.launcher3.ui.AbstractLauncherUiTest.resolveSystemApp; import static com.android.launcher3.util.rule.ShellCommandRule.disableHeadsUpNotification; import static com.android.launcher3.util.rule.ShellCommandRule.getLauncherCommand; import static com.android.quickstep.NavigationModeSwitchRule.Mode.THREE_BUTTON; @@ -108,7 +109,7 @@ public class FallbackRecentsTest { @NavigationModeSwitch(mode = THREE_BUTTON) @Test public void goToOverviewFromApp() { - startAppFast("com.android.settings"); + startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); mLauncher.getBackground().switchToOverview(); } diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml index a80ecb0b14..bf00e9541d 100644 --- a/res/values-ar/strings.xml +++ b/res/values-ar/strings.xml @@ -85,7 +85,7 @@ "الأدوات" "الخلفيات" "الأنماط والخلفيات" - "إعدادات الشاشة الرئيسية" + "إعدادات الصفحة الرئيسية" "أوقف المشرف هذه الميزة" "السماح بتدوير الشاشة الرئيسية" "عند تدوير الهاتف" @@ -108,7 +108,7 @@ "أدوات %1$s" "قائمة الأدوات" "تم إغلاق قائمة الأدوات." - "الإضافة إلى الشاشة الرئيسية" + "إضافة إلى الشاشة الرئيسية" "نقل العنصر إلى هنا" "تمت إضافة العنصر إلى الشاشة الرئيسية" "تم حذف العنصر" diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml index 883003c5c0..5158a78164 100644 --- a/res/values-b+sr+Latn/strings.xml +++ b/res/values-b+sr+Latn/strings.xml @@ -105,7 +105,7 @@ "Vidžeti za %1$s" "Lista vidžeta" "Lista vidžeta je zatvorena" - "Dodajte na početni ekran" + "Dodaj na početni ekran" "Premesti stavku ovde" "Stavka je dodata na početni ekran" "Stavka je uklonjena" diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml index 775885caac..6d80329988 100644 --- a/res/values-bn/strings.xml +++ b/res/values-bn/strings.xml @@ -83,7 +83,7 @@ "স্টাইল এবং ওয়ালপেপার" "হোম সেটিংস" "আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে" - "হোম স্ক্রিন ঘোরানোর অনুমতি দিন" + "হোমস্ক্রীন ঘোরানোর অনুমতি দিন" "যখন ফোনটি ঘোরানো হয়" "বিজ্ঞপ্তি ডট" "চালু" @@ -104,7 +104,7 @@ "%1$s উইজেট" "উইজেটের তালিকা" "উইজেটের তালিকা বন্ধ করা হয়েছে" - "হোম স্ক্রিনে যোগ করুন" + "হোম স্ক্রীনে যোগ করুন" "এখানে আইটেম সরান" "হোম স্ক্রীনে আইটেম যোগ করা হয়েছে" "আইটেম সরানো হয়েছে" diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml index 5650457071..53bdeb2d7b 100644 --- a/res/values-bs/strings.xml +++ b/res/values-bs/strings.xml @@ -79,7 +79,7 @@ "Folder je zatvoren" "Ime foldera je promijenjeno u %1$s" "Folder: %1$s" - "Vidžeti" + "Dodaci" "Pozadinske slike" "Stilovi i pozadinske slike" "Postavke početnog ekrana" @@ -90,7 +90,7 @@ "Uključeno" "Isključeno" "Potreban je pristup obavještenjima" - "Za prikaz tačaka za obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s" + "Za prikaz tačaka obavještenja, uključite obavještenja za aplikacije za aplikaciju %1$s" "Promijeni postavke" "Prikaži tačke za obavještenja" "Dodaj ikonu na početni ekran" diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml index c0859d3b4d..19f537ffbd 100644 --- a/res/values-ca/strings.xml +++ b/res/values-ca/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Fons de pantalla" "Estils i fons de pantalla" - "Config. pantalla d\'inici" + "Configuració de pantalla d\'inici" "Desactivada per l\'administrador" "Permet la rotació de la pantalla d\'inici" "En girar el telèfon" @@ -92,7 +92,7 @@ "Per veure els punts de notificació, activa les notificacions de l\'aplicació %1$s" "Canvia la configuració" "Mostra els punts de notificació" - "Afegeix icona a la pantalla d\'inici" + "Afegeix la icona a la pantalla d\'inici" "Per a les aplicacions noves" "Desconegut" "Suprimeix" diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index dc17516bce..008910dc93 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -33,7 +33,7 @@ "Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger." "%1$d × %2$d" "%1$d i bredden og %2$d i højden" - "Tryk og hold for at placere manuelt" + "Tryk og hold nede for at placere manuelt" "Tilføj automatisk" "Søg efter apps" "Indlæser apps…" @@ -48,7 +48,7 @@ "Liste med apps" "Liste over personlige apps" "Liste over apps til arbejdet" - "Hjem" + "Startskærm" "Fjern" "Afinstaller" "Appinfo" @@ -80,8 +80,8 @@ "Mappe: %1$s" "Widgets" "Baggrunde" - "Stil og baggrunde" - "Startskærmindstillinger" + "Stilarter og baggrunde" + "Indstillinger for startskærmen" "Deaktiveret af din administrator" "Tillad rotation af startskærmen" "Når telefonen roteres" diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml index a345babd5c..1b7cd22c31 100644 --- a/res/values-de/strings.xml +++ b/res/values-de/strings.xml @@ -80,11 +80,11 @@ "Ordner: %1$s" "Widgets" "Hintergründe" - "Designs und Hintergründe" - "Startbildschirm-Einstellungen" + "Stile und Hintergründe" + "Einstellungen für den Startbildschirm" "Von deinem Administrator deaktiviert" "Drehung des Startbildschirms zulassen" - "Beim Drehen des Smartphones" + "Bei Drehung des Smartphones" "App-Benachrichtigungspunkte" "An" "Aus" @@ -93,7 +93,7 @@ "Einstellungen ändern" "App-Benachrichtigungspunkte anzeigen" "Symbol zum Startbildschirm hinzufügen" - "Bei neuen Apps" + "Für neue Apps" "Unbekannt" "Entfernen" "Suchen" diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml index 0c48b5d2cb..6692370896 100644 --- a/res/values-en-rAU/strings.xml +++ b/res/values-en-rAU/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Home screen rotation" + "Allow Homescreen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml index 0c48b5d2cb..6692370896 100644 --- a/res/values-en-rGB/strings.xml +++ b/res/values-en-rGB/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Home screen rotation" + "Allow Homescreen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml index 0c48b5d2cb..6692370896 100644 --- a/res/values-en-rIN/strings.xml +++ b/res/values-en-rIN/strings.xml @@ -83,7 +83,7 @@ "Styles & wallpapers" "Home settings" "Disabled by your admin" - "Allow Home screen rotation" + "Allow Homescreen rotation" "When phone is rotated" "Notification dots" "On" diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml index 09b1239972..ac6ffaa35f 100644 --- a/res/values-es/strings.xml +++ b/res/values-es/strings.xml @@ -85,13 +85,13 @@ "Inhabilitado por el administrador" "Permitir rotación de la pantalla de inicio" "Al girar el teléfono" - "Puntos de notificación" - "Activados" + "Burbujas de notificación" + "Activadas" "Desactivadas" "Se necesita acceso a las notificaciones" - "Para mostrar puntos de notificación, activa las notificaciones de %1$s" + "Para mostrar burbujas de notificación, activa las notificaciones de %1$s" "Cambiar ajustes" - "Mostrar puntos de notificación" + "Mostrar burbujas de notificación" "Añadir icono a la pantalla de inicio" "Para aplicaciones nuevas" "Desconocido" diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml index 1e470e15a7..cea321da27 100644 --- a/res/values-et/strings.xml +++ b/res/values-et/strings.xml @@ -27,7 +27,7 @@ "Allalaetud rakendus on turvarežiimis keelatud" "Turvarežiimis on vidinad keelatud" "Otsetee pole saadaval" - "Avakuva" + "Avaekraan" "Kohandatud toimingud" "Vidina valimiseks vajutage ja hoidke seda all." "Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks." @@ -48,16 +48,16 @@ "Rakenduste loend" "Isiklike rakenduste loend" "Töörakenduste loend" - "Avakuva" + "Avaekraan" "Eemalda" "Desinstalli" "Rakenduse teave" "Installimine" "installi otseteed" "Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta." - "avakuva seadete ja otseteede lugemine" + "loe avaekraani seadeid ja otseteid" "Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid." - "avakuva seadete ja otseteede kirjutamine" + "kirjuta avaekraani seaded ja otseteed" "Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid." "Rakendusel %1$s pole lubatud helistada" "Probleem vidina laadimisel" @@ -70,8 +70,8 @@ %1$s, %2$d märguanne "Leht %1$d/%2$d" - "Avakuva %1$d/%2$d" - "Uus avakuva leht" + "Avaekraan %1$d/%2$d" + "Uus avaekraan" "Kaust on avatud, %1$d x %2$d" "Puudutage kausta sulgemiseks" "Puudutage ümbernimetamise salvestamiseks" @@ -81,9 +81,9 @@ "Vidinad" "Taustapildid" "Stiilid ja taustapildid" - "Avakuva seaded" + "Avaekraani seaded" "Keelas administraator" - "Luba avakuva pööramine" + "Luba avaekraani pööramine" "Kui telefoni pööratakse" "Märguandetäpid" "Sees" @@ -92,7 +92,7 @@ "Märguandetäppide kuvamiseks lülitage sisse rakenduse %1$s märguanded" "Seadete muutmine" "Kuva märguandetäpid" - "Lisa ikoon avakuvasse" + "Lisa ikoon avaekraanile" "Uute rakenduste puhul" "Teadmata" "Eemalda" @@ -104,7 +104,7 @@ "Teenuse %1$s vidinad" "Vidinate loend" "Vidinate loend on suletud" - "Lisa avakuvasse" + "Lisa avaekraanile" "Teisalda üksus siia" "Üksus lisati avaekraanile" "Üksus eemaldati" diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml index 9ba46c171d..18af2fb0fc 100644 --- a/res/values-eu/strings.xml +++ b/res/values-eu/strings.xml @@ -54,11 +54,11 @@ "Aplikazioaren datuak" "Instalatu" "Instalatu lasterbideak" - "Erabiltzaileak ezer egin gabe lasterbideak gehitzeko baimena ematen die aplikazioei." + "Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei." "Irakurri hasierako ezarpenak eta lasterbideak" - "Hasierako pantailako ezarpenak eta lasterbideak irakurtzeko baimena ematen die aplikazioei." + "Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei." "Idatzi hasierako ezarpenak eta lasterbideak" - "Hasierako pantailako ezarpenak eta lasterbideak aldatzeko baimena ematen die aplikazioei." + "Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei." "%1$s aplikazioak ez du telefono-deiak egiteko baimenik" "Arazo bat izan da widgeta kargatzean" "Konfigurazioa" @@ -83,7 +83,7 @@ "Estiloak eta horma-paperak" "Hasierako pantailaren ezarpenak" "Administratzaileak desgaitu du" - "Eman hasierako pantaila biratzeko baimena" + "Baimendu hasierako pantaila biratzea" "Telefonoa biratzen denean" "Jakinarazpen-biribiltxoak" "Aktibatuta" @@ -93,7 +93,7 @@ "Aldatu ezarpenak" "Erakutsi jakinarazpen-biribiltxoak" "Gehitu ikonoa hasierako pantailan" - "Aplikazio berrien kasuan" + "Aplikazio berrietan" "Ezezaguna" "Kendu" "Bilatu" diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml index 926cdb9b1c..7e3cbdc810 100644 --- a/res/values-fa/strings.xml +++ b/res/values-fa/strings.xml @@ -33,7 +33,7 @@ "برای انتخاب یک ابزارک، دو ضربه سریع بزنید و نگه‌دارید یا از کنش‌های سفارشی استفاده کنید." "%1$d × %2$d" "‏%1$d عرض در %2$d طول" - "آن را لمس کنید و بکشید تا به‌صورت دستی اضافه شود" + "برای قرار دادن به‌صورت دستی لمس کنید و بکشید" "افزودن خودکار" "جستجوی برنامه‌ها" "درحال بارگیری برنامه‌‌ها…" diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml index 5ac514d448..9d0e3a0b0c 100644 --- a/res/values-fr-rCA/strings.xml +++ b/res/values-fr-rCA/strings.xml @@ -51,7 +51,7 @@ "Accueil" "Supprimer" "Désinstaller" - "Détails de l\'application" + "Détails de l\'appli" "Installer" "installer des raccourcis" "Permet à une application d\'ajouter des raccourcis sans l\'intervention de l\'utilisateur." diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 7b4bcb1d82..585139c758 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Fonds d\'écran" "Styles et fonds d\'écran" - "Paramètres d\'écran d\'accueil" + "Paramètres accueil" "Désactivé par votre administrateur" "Autoriser la rotation de l\'écran d\'accueil" "Lorsque vous faites pivoter le téléphone" diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml index e115a72624..769586e78a 100644 --- a/res/values-gl/strings.xml +++ b/res/values-gl/strings.xml @@ -80,14 +80,14 @@ "Cartafol: %1$s" "Widgets" "Fondos de pantalla" - "Estilos/fondos de pantalla" - "Axustes de Inicio" + "Estilos e fondos de pantalla" + "Configuración da pantalla de Inicio" "Función desactivada polo administrador" "Permitir xirar a pantalla de inicio" "Ao xirar o teléfono" "Puntos de notificacións" - "Activados" - "Desactivados" + "Opción activada" + "Opción desactivada" "Necesítase acceso ás notificacións" "Para que se mostren os puntos de notificacións, activa as notificacións da aplicación %1$s" "Cambiar configuración" diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml index b796140e5e..5f24b05210 100644 --- a/res/values-hi/strings.xml +++ b/res/values-hi/strings.xml @@ -22,9 +22,9 @@ "Launcher3" "कार्यस्‍थल" - "ऐप्‍लिकेशन इंस्‍टॉल नहीं है." - "ऐप्लिकेशन उपलब्ध नहीं है" - "डाउनलोड किए गए ऐप्लिकेशन सुरक्षित मोड में अक्षम है" + "एप्‍लिकेशन इंस्‍टॉल नहीं है." + "ऐप्स उपलब्ध नहीं है" + "डाउनलोड किए गए ऐप्स सुरक्षित मोड में अक्षम है" "विजेट सुरक्षित मोड में अक्षम हैं" "शॉर्टकट उपलब्ध नहीं है" "होम स्क्रीन" @@ -78,7 +78,7 @@ "फ़ोल्डर बंद किया गया" "फ़ोल्डर का नाम बदलकर %1$s किया गया" "फ़ोल्डर: %1$s" - "विजेट" + "शॉर्टकट" "वॉलपेपर" "स्टाइल और वॉलपेपर" "होम पेज की सेटिंग" @@ -97,9 +97,9 @@ "अज्ञात" "निकालें" "सर्च करें" - "यह ऐप्लिकेशन इंस्टॉल नहीं है" + "यह ऐप्स इंस्टॉल नहीं है" "इस आइकॉन का ऐप इंस्टॉल नहीं है. आप उसे निकाल सकते हैं या ऐप को खोज कर उसे मैन्युअल रूप से इंस्टॉल कर सकते हैं." - "%1$s डाउनलोड हो रहा है, %2$s पूरी हुई" + "%1$s डाउनलोड हो रहा है, %2$s पूर्ण" "%1$s के इंस्टॉल होने की प्रतीक्षा की जा रही है" "%1$s विजेट" "विजेट की सूची" @@ -132,7 +132,7 @@ "सूचना को खारिज किया गया" "निजी ऐप" "काम से जुड़े ऐप" - "वर्क प्रोफ़ाइल" + "कार्य प्रोफ़ाइल" "काम से जुड़े सभी ऐप्लिकेशन यहां पाएं" "काम से जुड़े हर ऐप्लिकेशन पर एक बैज (निशान) होता है और इन ऐप्लिकेशन की सुरक्षा आपका संगठन करता है. आसानी से इस्तेमाल करने के लिए ऐप्लिकेशन को अपनी होम स्क्रीन पर ले जाएं." "आपका संगठन प्रबंधित कर रहा है" diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml index 3054214b5e..0841be0fd1 100644 --- a/res/values-in/strings.xml +++ b/res/values-in/strings.xml @@ -33,7 +33,7 @@ "Tap dua kalip & tahan untuk mengambil widget atau menggunakan tindakan khusus." "%1$d × %2$d" "lebar %1$d x tinggi %2$d" - "Tap lama untuk menempatkan secara manual" + "Sentuh & tahan untuk menempatkan secara manual" "Tambahkan otomatis" "Telusuri aplikasi" "Memuat aplikasi…" @@ -81,9 +81,9 @@ "Widget" "Wallpaper" "Gaya & wallpaper" - "Setelan layar utama" + "Setelan layar Utama" "Dinonaktifkan oleh admin" - "Izinkan Layar utama diputar" + "Izinkan layar Utama diputar" "Saat ponsel diputar" "Titik notifikasi" "Aktif" diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml index c25e8795f7..6f5a4009ee 100644 --- a/res/values-iw/strings.xml +++ b/res/values-iw/strings.xml @@ -50,7 +50,7 @@ "רשימת אפליקציות עבודה" "דף הבית" "הסר" - "להסרת התקנה" + "הסר התקנה" "פרטי אפליקציה" "התקנה" "התקן קיצורי דרך" @@ -61,7 +61,7 @@ "מאפשר לאפליקציה לשנות את ההגדרות וקיצורי הדרך בדף הבית." "%1$s אינו רשאי להתקשר" "בעיה בטעינת ווידג\'ט" - "הגדרה" + "הגדר" "זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה." "תיקיה ללא שם" "%1$s מושבתת" diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml index 1cd9045b76..2e953a6cdd 100644 --- a/res/values-kk/strings.xml +++ b/res/values-kk/strings.xml @@ -34,7 +34,7 @@ "%1$d × %2$d" "Ені: %1$d, биіктігі: %2$d" "Қолмен қою үшін басып тұрыңыз" - "Автоматты қосу" + "Автоматты енгізу" "Қолданбаларды іздеу" "Қолданбалар жүктелуде…" "\"%1$s\" сұрауына сәйкес келетін қолданбалар жоқ" diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml index f4a328df14..b953ea337b 100644 --- a/res/values-km/strings.xml +++ b/res/values-km/strings.xml @@ -84,7 +84,7 @@ "ការកំណត់​ទំព័រដើម" "បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក" "អនុញ្ញាតការបងិ្វលអេក្រង់ដើម" - "នៅពេលដែលបង្វិលទូរសព្ទ" + "នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក" "ស្លាកជូនដំណឹង" "បើក" "បិទ" @@ -104,7 +104,7 @@ "ធាតុ​ក្រាហ្វិក %1$s" "បញ្ជីធាតុ​ក្រាហ្វិក" "បាន​បិទ​បញ្ជីធាតុ​ក្រាហ្វិក" - "បញ្ចូលទៅអេក្រង់ដើម" + "បន្ថែមទៅអេក្រង់ដើម" "ផ្លាស់ធាតុមកទីនេះ" "ធាតុដែលត្រូវបានបន្ថែមទៅអេក្រង់ដើម" "ធាតុដែលបានដកចេញ" diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml index 14c830064b..2e96a7ce19 100644 --- a/res/values-kn/strings.xml +++ b/res/values-kn/strings.xml @@ -104,7 +104,7 @@ "%1$s ವಿಜೆಟ್‌ಗಳು" "ವಿಜೆಟ್ ಪಟ್ಟಿ" "ವಿಜೆಟ್ ಪಟ್ಟಿಯನ್ನು ಮುಚ್ಚಲಾಗಿದೆ" - "ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸಿ" + "ಮುಖಪುಟಕ್ಕೆ ಸೇರಿಸು" "ಐಟಂ ಇಲ್ಲಿಗೆ ಸರಿಸಿ" "ಮುಖಪುಟ ಪರದೆಗೆ ಐಟಂ ಸೇರಿಸಲಾಗಿದೆ" "ಐಟಂ ತೆಗೆದುಹಾಕಲಾಗಿದೆ" diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml index 046a66253e..36b63851c5 100644 --- a/res/values-ky/strings.xml +++ b/res/values-ky/strings.xml @@ -33,7 +33,7 @@ "Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз." "%1$d × %2$d" "Туурасы: %1$d, бийиктиги: %2$d" - "Кол менен кошуу үчүн кое бербей басып туруңуз" + "Кол менен жайгаштыруу үчүн басып туруп, таштаңыз" "Автоматтык түрдө кошуу" "Колдонмолорду издөө" "Колдонмолор жүктөлүүдө…" @@ -81,7 +81,7 @@ "Виджеттер" "Тушкагаздар" "Стилдер жана тушкагаздар" - "Башкы бет жөндөөлөрү" + "Башкы беттин жөндөөлөрү" "Администраторуңуз өчүрүп койгон" "Башкы экранды айлантууга уруксат берүү" "Телефон айланганда" diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml index 4362e7cca5..e03340bdb1 100644 --- a/res/values-ml/strings.xml +++ b/res/values-ml/strings.xml @@ -78,7 +78,7 @@ "ഫോൾഡർ അടച്ചു" "ഫോൾഡറിന്റെ പേര് %1$s എന്നായി മാറ്റി" "ഫോൾഡർ: %1$s" - "വിഡ്ജെറ്റുകൾ" + "വിജറ്റുകൾ" "വാൾപേപ്പർ" "സ്‌റ്റൈലുകളും വാൾപേപ്പറുകളും" "ഹോം ക്രമീകരണം" diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml index ab02ac655c..f52f46171c 100644 --- a/res/values-mn/strings.xml +++ b/res/values-mn/strings.xml @@ -104,7 +104,7 @@ "%1$s жижиг хэрэгсэл" "Жижиг хэрэгслийн жагсаалт" "Жижиг хэрэгслийн жагсаалтыг хаасан" - "Нүүр дэлгэцэд нэмэх" + "Нүүр дэлгэц нэмэх" "Энд байршуулах" "Нүүр дэлгэцэнд нэмсэн зүйл" "Арилгасан зүйл" diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml index 19c06976b0..f6eac53997 100644 --- a/res/values-mr/strings.xml +++ b/res/values-mr/strings.xml @@ -66,8 +66,8 @@ "अनामित फोल्डर" "%1$s अक्षम केला आहे" + %1$sसाठी%2$dसूचना आहेत %1$sसाठी %2$d सूचना आहेत - %1$sसाठी%2$dसूचना आहे "%2$d पैकी %1$d पृष्ठ" "%2$d पैकी %1$d मुख्य स्क्रीन" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index fd1f7d9535..7ae4446d5f 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -50,7 +50,7 @@ "အလုပ်သုံး အက်ပ်စာရင်း" "ပင်မစာမျက်နှာ" "ဖယ်ရှားမည်" - "ဖြုတ်ရန်" + "ဖယ်ထုတ်မည်" "အက်ပ်အချက်အလက်များ" "ထည့်သွင်းရန်" "အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း" @@ -94,7 +94,7 @@ "သတိပေးချက် အစက်များ ပြရန်" "ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်" "အက်ပ်အသစ်များအတွက်" - "မသိ" + "မသိရ" "ဖယ်ရှားရန်" "ရှာဖွေရန်" "အက်ပ်မတပ်ဆင်ရသေးပါ" diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml index ec30d8c6b2..bc1b45036c 100644 --- a/res/values-nl/strings.xml +++ b/res/values-nl/strings.xml @@ -33,7 +33,7 @@ "Dubbeltik en blijf aanraken om een widget toe te voegen of aangepaste acties te gebruiken." "%1$d × %2$d" "%1$d breed en %2$d hoog" - "Tik en houd vast om handmatig te plaatsen" + "Tik op een item en houd dit vast om het handmatig te plaatsen" "Automatisch toevoegen" "Apps zoeken" "Apps laden…" @@ -80,7 +80,7 @@ "Map: %1$s" "Widgets" "Achtergrond" - "Stijl en achtergrond" + "Stijlen en achtergronden" "Instellingen startscherm" "Uitgeschakeld door je beheerder" "Draaien van startscherm toestaan" diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml index 68859605fb..e33ef7da70 100644 --- a/res/values-pl/strings.xml +++ b/res/values-pl/strings.xml @@ -106,7 +106,7 @@ "%1$s – widżety" "Lista widgetów" "Lista widgetów zamknięta" - "Dodaj do ekranu głównego" + "Dodaj do strony głównej" "Przenieś element tutaj" "Element został dodany do ekranu głównego" "Element został usunięty" diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml index 071b71e38f..68a08a9eb5 100644 --- a/res/values-pt-rPT/strings.xml +++ b/res/values-pt-rPT/strings.xml @@ -81,7 +81,7 @@ "Widgets" "Imagens de fundo" "Estilos e imagens de fundo" - "Definições de início" + "Definições da página inicial" "Desativada pelo gestor" "Permitir rotação do ecrã principal" "Quando o telemóvel é rodado" diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml index e88ff18b42..1744fa16cc 100644 --- a/res/values-pt/strings.xml +++ b/res/values-pt/strings.xml @@ -33,7 +33,7 @@ "Toque duas vezes e segure para selecionar um widget ou usar ações personalizadas." "%1$d × %2$d" "%1$d de largura por %2$d de altura" - "Toque e mantenha pressionado para mover manualmente" + "Toque e mantenha pressionado para posicionar manualmente" "Adicionar automaticamente" "Apps de pesquisa" "Carregando apps…" @@ -81,7 +81,7 @@ "Widgets" "Planos de fundo" "Estilos e planos de fundo" - "Config. tela inicial" + "Configurações da tela inicial" "Desativado pelo administrador" "Permitir rotação da tela inicial" "Quando o smartphone for girado" diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml index 1251d7e3f8..a7e8f05844 100644 --- a/res/values-ro/strings.xml +++ b/res/values-ro/strings.xml @@ -51,7 +51,7 @@ "Ecran de pornire" "Eliminați" "Dezinstalați" - "Informații despre aplicații" + "Informații aplicație" "Instalați" "instalează comenzi rapide" "Permite unei aplicații să adauge comenzi rapide fără intervenția utilizatorului." @@ -82,9 +82,9 @@ "Widgeturi" "Imagini de fundal" "Stiluri și imagini de fundal" - "Setări ecran de pornire" + "Setări pentru ecranul de pornire" "Dezactivată de administrator" - "Permite rotirea ecranului de pornire" + "Permiteți rotirea ecranului de pornire" "Când telefonul este rotit" "Puncte de notificare" "Activate" diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34e267da9b..9030a75eed 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -82,8 +82,8 @@ "Папка: %1$s" "Виджеты" "Обои" - "Стили и обои" - "Главный экран" + "Темы и обои" + "Настройки главного экрана" "Функция отключена администратором" "Разрешить поворачивать главный экран" "Когда телефон повернут" diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml index ef99a59e4e..574d3ede01 100644 --- a/res/values-si/strings.xml +++ b/res/values-si/strings.xml @@ -80,8 +80,8 @@ "ෆෝල්ඩරය: %1$s" "විජට්" "වෝල්පේපර" - "විලාස සහ වෝල්පේපර" - "නිවසේ සැකසීම්" + "විලාස සහ බිතුපත්" + "Home සැකසීම්" "ඔබගේ පරිපාලක විසින් අබල කරන ලදී" "මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න" "දුරකථනය කරකවන විට" diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml index 340a128d2b..77eeab25ec 100644 --- a/res/values-sk/strings.xml +++ b/res/values-sk/strings.xml @@ -83,7 +83,7 @@ "Miniaplikácie" "Tapety" "Štýly a tapety" - "Nastavenia plochy" + "Nastavenia Home" "Zakázané vaším správcom" "Povoliť otáčanie plochy" "Pri otočení telefónu" diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml index 4e52592687..f74fde2eb8 100644 --- a/res/values-sr/strings.xml +++ b/res/values-sr/strings.xml @@ -105,7 +105,7 @@ "Виџети за %1$s" "Листа виџета" "Листа виџета је затворена" - "Додајте на почетни екран" + "Додај на почетни екран" "Премести ставку овде" "Ставка је додата на почетни екран" "Ставка је уклоњена" diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml index 6f33c4f046..7b84ed3c1d 100644 --- a/res/values-sw/strings.xml +++ b/res/values-sw/strings.xml @@ -106,7 +106,7 @@ "Wijeti za %1$s" "Orodha ya wijeti" "Orodha ya wijeti imefungwa" - "Ongeza kwenye Skrini ya Kwanza" + "Ongeza kwenye skrini ya Kwanza" "Hamishia kipengee hapa" "Kipengee kimeongezwa kwenye skrini ya kwanza" "Kipengee kimeondolewa" diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml index 672665e430..47b25816fb 100644 --- a/res/values-ta/strings.xml +++ b/res/values-ta/strings.xml @@ -22,9 +22,9 @@ "Launcher3" "பணியிடம்" - "ஆப்ஸ் நிறுவப்படவில்லை." - "ஆப்ஸ் இல்லை" - "இறக்கிய ஆப்ஸ் பாதுகாப்பு முறையில் முடக்கப்பட்டது" + "பயன்பாடு நிறுவப்படவில்லை." + "பயன்பாடு இல்லை" + "இறக்கிய பயன்பாடு பாதுகாப்பு முறையில் முடக்கப்பட்டது" "பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன" "ஷார்ட்கட் இல்லை" "முகப்புத் திரை" @@ -51,18 +51,18 @@ "முகப்பு" "அகற்று" "நிறுவல் நீக்கு" - "ஆப்ஸ் தகவல்" + "பயன்பாட்டுத் தகவல்" "நிறுவு" "குறுக்குவழிகளை நிறுவுதல்" - "பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் ஆப்ஸை அனுமதிக்கிறது." + "பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது." "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்" - "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க ஆப்ஸை அனுமதிக்கிறது." + "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது." "முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்" - "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற ஆப்ஸை அனுமதிக்கிறது." + "முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது." "ஃபோன் அழைப்புகள் செய்ய, %1$s அனுமதிக்கப்படவில்லை" "விட்ஜெட்டை ஏற்றுவதில் சிக்கல்" "அமைவு" - "இது அமைப்பு ஆப்ஸ் என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது." + "இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது." "பெயரிடப்படாத கோப்புறை" "%1$s முடக்கப்பட்டது" @@ -78,7 +78,7 @@ "கோப்புறை மூடப்பட்டது" "கோப்புறை %1$s என மறுபெயரிடப்பட்டது" "கோப்புறை: %1$s" - "விட்ஜெட்கள்" + "ஷார்ட்கட்ஸ்" "வால்பேப்பர்கள்" "ஸ்டைல்கள் & வால்பேப்பர்கள்" "முகப்பு அமைப்புகள்" @@ -93,12 +93,12 @@ "அமைப்புகளை மாற்று" "அறிவிப்புப் புள்ளிகளைக் காட்டு" "முகப்புத் திரையில் ஐகானைச் சேர்" - "புதிய ஆப்ஸை நிறுவும்போது" + "புதிய பயன்பாடுகளுக்கு" "தெரியாதது" "அகற்று" "தேடு" - "ஆப்ஸ் நிறுவப்படவில்லை" - "ஐகானுக்கான ஆப்ஸ் நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்." + "பயன்பாடு நிறுவப்படவில்லை" + "ஐகானுக்கான பயன்பாடு நிறுவப்படவில்லை. இதை அகற்றலாம் அல்லது பயன்பாட்டைத் தேடி கைமுறையாக நிறுவலாம்." "%1$sஐப் பதிவிறக்குகிறது, %2$s முடிந்தது" "%1$sஐ நிறுவுவதற்காகக் காத்திருக்கிறது" "%1$s விட்ஜெட்டுகள்" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index c8f70fe058..528ce481bd 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -80,7 +80,7 @@ "ఫోల్డర్: %1$s" "విడ్జెట్‌లు" "వాల్‌పేపర్‌లు" - "స్ట‌యిల్స్‌ & వాల్‌పేపర్‌లు" + "శైలులు & వాల్‌పేపర్‌లు" "హోమ్ సెట్టింగ్‌లు" "మీ నిర్వాహకులు నిలిపివేసారు" "హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి" diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml index 0df94c7104..f0c241e9e8 100644 --- a/res/values-tl/strings.xml +++ b/res/values-tl/strings.xml @@ -98,7 +98,7 @@ "Alisin" "Maghanap" "Hindi naka-install ang app na ito" - "Hindi naka-install ang app para sa icon na ito. Puwede mo itong alisin, o maaari mong hanapin ang app at i-install ito nang manual." + "Hindi naka-install ang app para sa icon na ito. Maaari mo itong alisin, o maaari mong hanapin ang app at i-install ito nang manu-mano." "Dina-download na ang %1$s, tapos na ang %2$s" "Hinihintay nang mag-install ang %1$s" "Mga widget ng %1$s" diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 13ba701815..ad51464a32 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -82,8 +82,8 @@ "Папка %1$s" "Віджети" "Фонові малюнки" - "Стиль і фон" - "Налаштування головного екрана" + "Стилі й фонові малюнки" + "Налаштування Home" "Вимкнув адміністратор" "Дозволити обертання головного екрана" "Коли телефон обертається" @@ -94,7 +94,7 @@ "Щоб показувати значки сповіщень, увімкніть сповіщення в додатку %1$s" "Змінити налаштування" "Показувати значки сповіщень" - "Додавати значок на головний екран" + "Додати значок на головний екран" "Для нових додатків" "Невідомо" "Прибрати" diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml index 4f776701e5..5d7218d37e 100644 --- a/res/values-ur/strings.xml +++ b/res/values-ur/strings.xml @@ -33,7 +33,7 @@ "کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔" "%1$d × %2$d" "‏%1$d چوڑا اور ‎%2$d اونچا" - "‏دستی طور پر رکھنے کیلئے ‎ٹچ کر کے دبائے رکھیں" + "‏دستی طور پر رکھنے کیلئے ‎& ٹچ کرکے ہولڈ کریں" "خود کار طور پر شامل کریں" "ایپس تلاش کریں" "ایپس لوڈ کی جا رہی ہیں…" diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml index 69084d7041..d34a64f93a 100644 --- a/res/values-uz/strings.xml +++ b/res/values-uz/strings.xml @@ -33,7 +33,7 @@ "Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning." "%1$d × %2$d" "Eni %1$d, bo‘yi %2$d" - "Joylash uchun bosib turing" + "Qo‘lda joylashtirish uchun bosib turing" "Avtomatik chiqarish" "Ilovalarni qidirish" "Ilovalar yuklanmoqda…" @@ -83,7 +83,7 @@ "Mavzu va fon rasmlari" "Bosh ekran sozlamalari" "Administrator tomonidan o‘chirilgan" - "Bosh ekranni burishga ruxsat" + "Asosiy ekranni aylantirishga ruxsat berish" "Telefon burilganda" "Bildirishnoma belgilari" "Yoniq" @@ -95,7 +95,7 @@ "Bosh ekranga ikonka chiqarish" "Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish" "Noma’lum" - "Olib tashlash" + "O‘chirish" "Qidirish" "Ushbu ilova o‘rnatilmagan" "Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin." @@ -104,15 +104,15 @@ "%1$s vidjetlari" "Vidjetlar ro‘yxati" "Vidjetlar ro‘yxati yopildi" - "Bosh ekranga chiqarish" + "Bosh ekranga qo‘shish" "Obyektni bu yerga ko‘chirish" "Obyekt bosh ekranga qo‘shildi" "Obyekt o‘chirib tashlandi" "Qaytarish" "Obyektni ko‘chirib o‘tkazish" - "%1$s %2$s katakka olish" - "%1$s-joyga olish" - "Sevimlilarga olish (%1$s)" + "%1$s %2$s katakka ko‘chirib o‘tkazish" + "%1$s-joyga ko‘chirib o‘tkazish" + "Sevimlilarga (%1$s) ko‘chirib o‘tkazish" "Element ko‘chirib o‘tkazildi" "%1$s jildiga qo‘shish" "%1$s ilovasi bor jildga qo‘shish" diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml index 71decfca68..174ec7fe95 100644 --- a/res/values-vi/strings.xml +++ b/res/values-vi/strings.xml @@ -33,7 +33,7 @@ "Nhấn đúp và giữ để chọn tiện ích hoặc sử dụng tác vụ tùy chỉnh." "%1$d × %2$d" "Rộng %1$d x cao %2$d" - "Chạm và giữ để thêm theo cách thủ công" + "Chạm và giữ để đặt theo cách thủ công" "Tự động thêm" "Tìm kiếm ứng dụng" "Đang tải ứng dụng…" @@ -78,7 +78,7 @@ "Đã đóng thư mục" "Đã đổi tên thư mục thành %1$s" "Thư mục: %1$s" - "Tiện ích" + "Tiện ích con" "Hình nền" "Kiểu và hình nền" "Cài đặt màn hình chính" diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml index e7377440c1..de0fa89a0c 100644 --- a/res/values-zh-rHK/strings.xml +++ b/res/values-zh-rHK/strings.xml @@ -81,7 +81,7 @@ "小工具" "桌布" "樣式和桌布" - "主畫面設定" + "主螢幕設定" "已由您的管理員停用" "允許主畫面旋轉" "當手機旋轉時" diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index e971b69f1f..4d37d721f7 100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml @@ -33,7 +33,7 @@ "輕觸兩下並按住小工具即可選取,你也可以使用自訂動作。" "%1$d × %2$d" "寬度為 %1$d,高度為 %2$d" - "按住圖示即可手動新增" + "按住即可手動放置" "自動新增" "搜尋應用程式" "正在載入應用程式…" @@ -81,7 +81,7 @@ "小工具" "桌布" "樣式和桌布" - "主螢幕設定" + "Home 設定" "已由你的管理員停用" "允許旋轉主螢幕" "當手機旋轉時" diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java index 424ffde1ff..64550560ff 100644 --- a/src/com/android/launcher3/BaseActivity.java +++ b/src/com/android/launcher3/BaseActivity.java @@ -175,6 +175,10 @@ public abstract class BaseActivity extends Activity mActivityFlags &= ~ACTIVITY_STATE_STARTED & ~ACTIVITY_STATE_USER_ACTIVE; mForceInvisible = 0; super.onStop(); + + // Reset the overridden sysui flags used for the task-swipe launch animation, this is a + // catch all for if we do not get resumed (and therefore not paused below) + getSystemUiController().updateUiState(UI_STATE_OVERVIEW, 0); } @Override diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 57a9b161f9..4e905c7265 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -80,6 +80,7 @@ import android.widget.Toast; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.accessibility.LauncherAccessibilityDelegate; import com.android.launcher3.allapps.AllAppsContainerView; +import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.PropertyListBuilder; @@ -460,13 +461,18 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, private void onIdpChanged(InvariantDeviceProfile idp) { mUserEventDispatcher = null; + DeviceProfile oldWallpaperProfile = getWallpaperDeviceProfile(); initDeviceProfile(idp); dispatchDeviceProfileChanged(); reapplyUi(); mDragLayer.recreateControllers(); - // TODO: We can probably avoid rebind when only screen size changed. - rebindModel(); + // Calling onSaveInstanceState ensures that static cache used by listWidgets is + // initialized properly. + onSaveInstanceState(new Bundle()); + if (oldWallpaperProfile != getWallpaperDeviceProfile()) { + rebindModel(); + } } public void onAssistantVisibilityChanged(float visibility) { @@ -888,7 +894,6 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, mLauncherCallbacks.onStart(); } mAppWidgetHost.setListenIfResumed(true); - NotificationListener.setNotificationsChangedListener(mPopupDataProvider); RaceConditionTracker.onEvent(ON_START_EVT, EXIT); } @@ -908,6 +913,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // Refresh shortcuts if the permission changed. mModel.refreshShortcutsIfRequired(); + // Set the notification listener and fetch updated notifications when we resume + NotificationListener.setNotificationsChangedListener(mPopupDataProvider); + DiscoveryBounce.showForHomeIfNeeded(this); if (mPendingActivityRequestCode != -1 && isInState(NORMAL)) { @@ -2241,8 +2249,9 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, } mPendingExecutor = executor; if (!isInState(ALL_APPS)) { - mAppsView.getAppsStore().setDeferUpdates(true); - mPendingExecutor.execute(() -> mAppsView.getAppsStore().setDeferUpdates(false)); + mAppsView.getAppsStore().enableDeferUpdates(AllAppsStore.DEFER_UPDATES_NEXT_DRAW); + mPendingExecutor.execute(() -> mAppsView.getAppsStore().disableDeferUpdates( + AllAppsStore.DEFER_UPDATES_NEXT_DRAW)); } executor.attachTo(this); diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 49b380b41f..f964b8d9ee 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -8,18 +8,22 @@ import android.app.ActivityManager; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.Insets; import android.graphics.Paint; import android.graphics.Rect; import android.os.Build; import android.util.AttributeSet; import android.view.View; import android.view.ViewDebug; +import android.view.WindowInsets; import java.util.Collections; import java.util.List; public class LauncherRootView extends InsettableFrameLayout { + private final Rect mTempRect = new Rect(); + private final Launcher mLauncher; private final Paint mOpaquePaint; @@ -56,9 +60,7 @@ public class LauncherRootView extends InsettableFrameLayout { super.onFinishInflate(); } - @TargetApi(23) - @Override - protected boolean fitSystemWindows(Rect insets) { + private void handleSystemWindowInsets(Rect insets) { mConsumedInsets.setEmpty(); boolean drawInsetBar = false; if (mLauncher.isInMultiWindowMode() @@ -66,13 +68,13 @@ public class LauncherRootView extends InsettableFrameLayout { mConsumedInsets.left = insets.left; mConsumedInsets.right = insets.right; mConsumedInsets.bottom = insets.bottom; - insets = new Rect(0, insets.top, 0, 0); + insets.set(0, insets.top, 0, 0); drawInsetBar = true; } else if ((insets.right > 0 || insets.left > 0) && getContext().getSystemService(ActivityManager.class).isLowRamDevice()) { mConsumedInsets.left = insets.left; mConsumedInsets.right = insets.right; - insets = new Rect(0, insets.top, 0, insets.bottom); + insets.set(0, insets.top, 0, insets.bottom); drawInsetBar = true; } @@ -99,8 +101,19 @@ public class LauncherRootView extends InsettableFrameLayout { if (resetState) { mLauncher.getStateManager().reapplyState(true /* cancelCurrentAnimation */); } + } - return false; // Let children get the full insets + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + mTempRect.set(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(), + insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom()); + handleSystemWindowInsets(mTempRect); + if (Utilities.ATLEAST_Q) { + return insets.inset(mConsumedInsets.left, mConsumedInsets.top, + mConsumedInsets.right, mConsumedInsets.bottom); + } else { + return insets.replaceSystemWindowInsets(mTempRect); + } } @Override diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java index fe6b522970..8b03691c81 100644 --- a/src/com/android/launcher3/LauncherStateManager.java +++ b/src/com/android/launcher3/LauncherStateManager.java @@ -49,6 +49,7 @@ import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.anim.PropertySetter.AnimatedPropertySetter; +import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.uioverrides.UiFactory; @@ -496,6 +497,8 @@ public class LauncherStateManager { for (int i = mListeners.size() - 1; i >= 0; i--) { mListeners.get(i).onStateTransitionComplete(state); } + + AccessibilityManagerCompat.sendStateEventToTest(mLauncher, state.ordinal); } public void onWindowFocusChanged() { diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index 0d43e214ef..d68ff4451d 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -628,11 +628,12 @@ public class AllAppsContainerView extends SpringRelativeLayout implements DragSo final boolean result = super.dispatchTouchEvent(ev); switch (ev.getActionMasked()) { case MotionEvent.ACTION_DOWN: - if (result) mAllAppsStore.setDeferUpdates(true); + if (result) mAllAppsStore.enableDeferUpdates( + AllAppsStore.DEFER_UPDATES_USER_INTERACTION); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - mAllAppsStore.setDeferUpdates(false); + mAllAppsStore.disableDeferUpdates(AllAppsStore.DEFER_UPDATES_USER_INTERACTION); break; } return result; diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java index 8e7fec863b..160042e692 100644 --- a/src/com/android/launcher3/allapps/AllAppsStore.java +++ b/src/com/android/launcher3/allapps/AllAppsStore.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; -import java.util.Set; import java.util.function.Consumer; import java.util.function.Predicate; @@ -38,12 +37,19 @@ import java.util.function.Predicate; */ public class AllAppsStore { + // Defer updates flag used to defer all apps updates to the next draw. + public static final int DEFER_UPDATES_NEXT_DRAW = 1 << 0; + // Defer updates flag used to defer all apps updates while the user interacts with all apps. + public static final int DEFER_UPDATES_USER_INTERACTION = 1 << 1; + // Defer updates flag used to defer all apps updates by a test's request. + public static final int DEFER_UPDATES_TEST = 1 << 2; + private PackageUserKey mTempKey = new PackageUserKey(null, null); private final HashMap mComponentToAppMap = new HashMap<>(); private final List mUpdateListeners = new ArrayList<>(); private final ArrayList mIconContainers = new ArrayList<>(); - private boolean mDeferUpdates = false; + private int mDeferUpdatesFlags = 0; private boolean mUpdatePending = false; public Collection getApps() { @@ -62,17 +68,22 @@ public class AllAppsStore { return mComponentToAppMap.get(key); } - public void setDeferUpdates(boolean deferUpdates) { - if (mDeferUpdates != deferUpdates) { - mDeferUpdates = deferUpdates; + public void enableDeferUpdates(int flag) { + mDeferUpdatesFlags |= flag; + } - if (!mDeferUpdates && mUpdatePending) { - notifyUpdate(); - mUpdatePending = false; - } + public void disableDeferUpdates(int flag) { + mDeferUpdatesFlags &= ~flag; + if (mDeferUpdatesFlags == 0 && mUpdatePending) { + notifyUpdate(); + mUpdatePending = false; } } + public int getDeferUpdatesFlags() { + return mDeferUpdatesFlags; + } + /** * Adds or updates existing apps in the list */ @@ -95,7 +106,7 @@ public class AllAppsStore { private void notifyUpdate() { - if (mDeferUpdates) { + if (mDeferUpdatesFlags != 0) { mUpdatePending = true; return; } diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java index 7e20d11c2b..54d0db1006 100644 --- a/src/com/android/launcher3/config/BaseFlags.java +++ b/src/com/android/launcher3/config/BaseFlags.java @@ -105,7 +105,7 @@ abstract class BaseFlags { "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview"); public static final TogglableFlag ENABLE_HINTS_IN_OVERVIEW = new TogglableFlag( - "ENABLE_HINTS_IN_OVERVIEW", false, + "ENABLE_HINTS_IN_OVERVIEW", true, "Show chip hints and gleams on the overview screen"); public static final TogglableFlag FAKE_LANDSCAPE_UI = new TogglableFlag( diff --git a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java index e204c63017..c719c1c986 100644 --- a/src/com/android/launcher3/dragndrop/BaseItemDragListener.java +++ b/src/com/android/launcher3/dragndrop/BaseItemDragListener.java @@ -37,6 +37,7 @@ import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.states.InternalStateHandler; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.widget.PendingItemDragHelper; import java.util.UUID; @@ -136,6 +137,9 @@ public abstract class BaseItemDragListener extends InternalStateHandler implemen @Override public boolean shouldStartDrag(double distanceDragged) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_DRAG_TAG, "BIDL.shouldStartDrag"); + } // Stay in pre-drag mode, if workspace is locked. return !mLauncher.isWorkspaceLocked(); } diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java index 7b14fa2491..9719a1892f 100644 --- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java +++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java @@ -36,6 +36,7 @@ import android.os.Build; import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; +import android.util.Log; import android.util.Pair; import android.view.MotionEvent; import android.view.View; @@ -67,6 +68,7 @@ import com.android.launcher3.popup.PopupDataProvider.PopupDataChangeListener; import com.android.launcher3.shortcuts.DeepShortcutManager; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; +import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.touch.ItemLongClickListener; import com.android.launcher3.util.PackageUserKey; @@ -447,6 +449,11 @@ public class PopupContainerWithArrow extends ArrowPopup implements DragSource, @Override public boolean shouldStartDrag(double distanceDragged) { + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_DRAG_TAG, + "createPreDragCondition().shouldStartDrag " + distanceDragged + ", " + + mStartDragThreshold); + } return distanceDragged > mStartDragThreshold; } diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index b8476aa1da..d2e196138c 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -23,9 +23,13 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherState; +import com.android.launcher3.MainThreadExecutor; import com.android.launcher3.R; +import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.util.ResourceBasedOverride; +import java.util.concurrent.ExecutionException; + public class TestInformationHandler implements ResourceBasedOverride { public static TestInformationHandler newInstance(Context context) { @@ -77,6 +81,32 @@ public class TestInformationHandler implements ResourceBasedOverride { case TestProtocol.REQUEST_DISABLE_DEBUG_TRACING: TestProtocol.sDebugTracing = false; break; + + case TestProtocol.REQUEST_FREEZE_APP_LIST: + new MainThreadExecutor().execute(() -> + mLauncher.getAppsView().getAppsStore().enableDeferUpdates( + AllAppsStore.DEFER_UPDATES_TEST)); + break; + + case TestProtocol.REQUEST_UNFREEZE_APP_LIST: + new MainThreadExecutor().execute(() -> + mLauncher.getAppsView().getAppsStore().disableDeferUpdates( + AllAppsStore.DEFER_UPDATES_TEST)); + break; + + case TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS: { + try { + final int deferUpdatesFlags = new MainThreadExecutor().submit(() -> + mLauncher.getAppsView().getAppsStore().getDeferUpdatesFlags()).get(); + response.putInt(TestProtocol.TEST_INFO_RESPONSE_FIELD, + deferUpdatesFlags); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + break; + } } return response; } diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java index 02e6bbdd79..6ffc2d9cd1 100644 --- a/src/com/android/launcher3/testing/TestProtocol.java +++ b/src/com/android/launcher3/testing/TestProtocol.java @@ -57,6 +57,7 @@ public final class TestProtocol { } public static final String TEST_INFO_RESPONSE_FIELD = "response"; + public static final String REQUEST_HOME_TO_OVERVIEW_SWIPE_HEIGHT = "home-to-overview-swipe-height"; public static final String REQUEST_BACKGROUND_TO_OVERVIEW_SWIPE_HEIGHT = @@ -65,6 +66,10 @@ public final class TestProtocol { "all-apps-to-overview-swipe-height"; public static final String REQUEST_HOME_TO_ALL_APPS_SWIPE_HEIGHT = "home-to-all-apps-swipe-height"; + public static final String REQUEST_FREEZE_APP_LIST = "freeze-app-list"; + public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; + public static final String REQUEST_APP_LIST_FREEZE_FLAGS = "app-list-freeze-flags"; + public static boolean sDebugTracing = false; public static final String REQUEST_ENABLE_DEBUG_TRACING = "enable-debug-tracing"; public static final String REQUEST_DISABLE_DEBUG_TRACING = "disable-debug-tracing"; diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java index 4e5f7a59a9..6f53140eab 100644 --- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java +++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java @@ -43,7 +43,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.AnimatorSetBuilder; -import com.android.launcher3.compat.AccessibilityManagerCompat; import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction; @@ -541,7 +540,6 @@ public abstract class AbstractStateChangeTouchController android.util.Log.e( TestProtocol.NO_ALLAPPS_EVENT_TAG, "onSwipeInteractionCompleted 2"); } - AccessibilityManagerCompat.sendStateEventToTest(mLauncher, targetState.ordinal); } } diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 64fe2d7d79..abc93cd4b7 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -395,7 +395,7 @@ public abstract class AbstractLauncherUiTest { DEFAULT_UI_TIMEOUT)); } - protected static String resolveSystemApp(String category) { + public static String resolveSystemApp(String category) { return getInstrumentation().getContext().getPackageManager().resolveActivity( new Intent(Intent.ACTION_MAIN).addCategory(category), PackageManager.MATCH_SYSTEM_ONLY). diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 4f8b87c519..d171004fc1 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -108,47 +108,63 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { @Test @Ignore public void testPressHomeOnAllAppsContextMenu() throws Exception { - mLauncher.getWorkspace().switchToAllApps().getAppIcon("TestActivity7").openMenu(); + final AllApps allApps = mLauncher.getWorkspace().switchToAllApps(); + allApps.freeze(); + try { + allApps.getAppIcon("TestActivity7").openMenu(); + } finally { + allApps.unfreeze(); + } mLauncher.pressHome(); } public static void runAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) { - assertNotNull("allApps parameter is null", allApps); + allApps.freeze(); + try { + assertNotNull("allApps parameter is null", allApps); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); - // Test flinging forward and backward. - test.executeOnLauncher(launcher -> assertEquals( - "All Apps started in already scrolled state", 0, test.getAllAppsScroll(launcher))); + // Test flinging forward and backward. + test.executeOnLauncher(launcher -> assertEquals( + "All Apps started in already scrolled state", 0, + test.getAllAppsScroll(launcher))); - allApps.flingForward(); - assertTrue("Launcher internal state is not All Apps", - test.isInState(LauncherState.ALL_APPS)); - final Integer flingForwardY = test.getFromLauncher( - launcher -> test.getAllAppsScroll(launcher)); - test.executeOnLauncher( - launcher -> assertTrue("flingForward() didn't scroll App Apps", flingForwardY > 0)); + allApps.flingForward(); + assertTrue("Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + final Integer flingForwardY = test.getFromLauncher( + launcher -> test.getAllAppsScroll(launcher)); + test.executeOnLauncher( + launcher -> assertTrue("flingForward() didn't scroll App Apps", + flingForwardY > 0)); - allApps.flingBackward(); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); - final Integer flingBackwardY = test.getFromLauncher( - launcher -> test.getAllAppsScroll(launcher)); - test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps", - flingBackwardY < flingForwardY)); + allApps.flingBackward(); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + final Integer flingBackwardY = test.getFromLauncher( + launcher -> test.getAllAppsScroll(launcher)); + test.executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps", + flingBackwardY < flingForwardY)); - // Test scrolling down to YouTube. - assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube")); - // Test scrolling up to Camera. - assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera")); - // Test failing to find a non-existing app. - final AllApps allAppsFinal = allApps; - expectFail("All apps: could find a non-existing app", - () -> allAppsFinal.getAppIcon("NO APP")); + // Test scrolling down to YouTube. + assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube")); + // Test scrolling up to Camera. + assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera")); + // Test failing to find a non-existing app. + final AllApps allAppsFinal = allApps; + expectFail("All apps: could find a non-existing app", + () -> allAppsFinal.getAppIcon("NO APP")); - assertTrue( - "Launcher internal state is not All Apps", test.isInState(LauncherState.ALL_APPS)); + assertTrue( + "Launcher internal state is not All Apps", + test.isInState(LauncherState.ALL_APPS)); + } finally { + allApps.unfreeze(); + } } @Test @@ -199,12 +215,17 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } public static void runIconLaunchFromAllAppsTest(AbstractLauncherUiTest test, AllApps allApps) { - final AppIcon app = allApps.getAppIcon("TestActivity7"); - assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName())); - test.executeOnLauncher(launcher -> assertTrue( - "Launcher activity is the top activity; expecting another activity to be the top " - + "one", - test.isInBackground(launcher))); + allApps.freeze(); + try { + final AppIcon app = allApps.getAppIcon("TestActivity7"); + assertNotNull("AppIcon.launch returned null", app.launch(getAppPackageName())); + test.executeOnLauncher(launcher -> assertTrue( + "Launcher activity is the top activity; expecting another activity to be the top " + + "one", + test.isInBackground(launcher))); + } finally { + allApps.unfreeze(); + } } @Test @@ -260,20 +281,23 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { public void testLaunchMenuItem() throws Exception { if (!TestHelpers.isInLauncherProcess()) return; - final AppIconMenu menu = mLauncher. + final AllApps allApps = mLauncher. getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - openMenu(); + switchToAllApps(); + allApps.freeze(); + try { + final AppIconMenu menu = allApps. + getAppIcon(APP_NAME). + openMenu(); - executeOnLauncher( - launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu", - isOptionsPopupVisible(launcher))); + executeOnLauncher( + launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu", + isOptionsPopupVisible(launcher))); - final AppIconMenuItem menuItem = menu.getMenuItem(1); - final String itemName = menuItem.getText(); - - menuItem.launch(getAppPackageName()); + menu.getMenuItem(1).launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } } @Test @@ -282,12 +306,18 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { // 1. Open all apps and wait for load complete. // 2. Drag icon to homescreen. // 3. Verify that the icon works on homescreen. - mLauncher.getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - dragToWorkspace(). - getWorkspaceAppIcon(APP_NAME). - launch(getAppPackageName()); + final AllApps allApps = mLauncher.getWorkspace(). + switchToAllApps(); + allApps.freeze(); + try { + allApps. + getAppIcon(APP_NAME). + dragToWorkspace(). + getWorkspaceAppIcon(APP_NAME). + launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } executeOnLauncher(launcher -> assertTrue( "Launcher activity is the top activity; expecting another activity to be the top " + "one", @@ -302,21 +332,27 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { // 1. Open all apps and wait for load complete. // 2. Find the app and long press it to show shortcuts. // 3. Press icon center until shortcuts appear - final AppIconMenuItem menuItem = mLauncher. + final AllApps allApps = mLauncher. getWorkspace(). - switchToAllApps(). - getAppIcon(APP_NAME). - openMenu(). - getMenuItem(0); - final String shortcutName = menuItem.getText(); + switchToAllApps(); + allApps.freeze(); + try { + final AppIconMenuItem menuItem = allApps. + getAppIcon(APP_NAME). + openMenu(). + getMenuItem(0); + final String shortcutName = menuItem.getText(); - // 4. Drag the first shortcut to the home screen. - // 5. Verify that the shortcut works on home screen - // (the app opens and has the same text as the shortcut). - menuItem. - dragToWorkspace(). - getWorkspaceAppIcon(shortcutName). - launch(getAppPackageName()); + // 4. Drag the first shortcut to the home screen. + // 5. Verify that the shortcut works on home screen + // (the app opens and has the same text as the shortcut). + menuItem. + dragToWorkspace(). + getWorkspaceAppIcon(shortcutName). + launch(getAppPackageName()); + } finally { + allApps.unfreeze(); + } } public static String getAppPackageName() { diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index d03035a871..21d763e30e 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -48,6 +48,7 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { "apps_list_view"); // Wait for the recycler to populate. mLauncher.waitForObjectInContainer(appListRecycler, By.clazz(TextView.class)); + verifyNotFrozen("All apps freeze flags upon opening all apps"); } @Override @@ -210,4 +211,25 @@ public class AllApps extends LauncherInstrumentation.VisibleContainer { verifyActiveContainer(); } } + + /** + * Freezes updating app list upon app install/uninstall/update. + */ + public void freeze() { + mLauncher.getTestInfo(TestProtocol.REQUEST_FREEZE_APP_LIST); + } + + /** + * Resumes updating app list upon app install/uninstall/update. + */ + public void unfreeze() { + mLauncher.getTestInfo(TestProtocol.REQUEST_UNFREEZE_APP_LIST); + verifyNotFrozen("All apps freeze flags upon unfreezing"); + } + + private void verifyNotFrozen(String message) { + mLauncher.assertEquals(message, 0, mLauncher.getTestInfo( + TestProtocol.REQUEST_APP_LIST_FREEZE_FLAGS). + getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD)); + } } diff --git a/tests/tapl/com/android/launcher3/tapl/Launchable.java b/tests/tapl/com/android/launcher3/tapl/Launchable.java index 5190f001a7..d4bdafa764 100644 --- a/tests/tapl/com/android/launcher3/tapl/Launchable.java +++ b/tests/tapl/com/android/launcher3/tapl/Launchable.java @@ -20,7 +20,6 @@ import android.graphics.Point; import androidx.test.uiautomator.By; import androidx.test.uiautomator.BySelector; -import androidx.test.uiautomator.UiDevice; import androidx.test.uiautomator.UiObject2; import androidx.test.uiautomator.Until; @@ -70,11 +69,16 @@ abstract class Launchable { * Drags an object to the center of homescreen. */ public Workspace dragToWorkspace() { - final UiDevice device = mLauncher.getDevice(); + final Point launchableCenter = getObject().getVisibleCenter(); + final Point displaySize = mLauncher.getRealDisplaySize(); + final int width = displaySize.x / 2; Workspace.dragIconToWorkspace( mLauncher, this, - new Point(device.getDisplayWidth() / 2, device.getDisplayHeight() / 2), + new Point( + launchableCenter.x >= width ? + launchableCenter.x - width / 2 : launchableCenter.x + width / 2, + displaySize.y / 2), getLongPressIndicator()); try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "dragged launchable to workspace")) { diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index e45fca8c0f..8ebe525657 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -292,6 +292,12 @@ public final class LauncherInstrumentation { } } + void assertEquals(String message, long expected, long actual) { + if (expected != actual) { + fail(message + " expected: " + expected + " but was: " + actual); + } + } + void assertNotEquals(String message, int unexpected, int actual) { if (unexpected == actual) { failEquals(message, actual);