Merge changes from topic "am-f1734de0-a8c9-409e-bd1b-c22b2df61ce2" into ub-launcher3-master
* changes:
[automerger] Skip processing fallback icons as they are already badged and have shadow am: fbf327f9ee
Skip processing fallback icons as they are already badged and have shadow
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index fde22eb..b7c5793 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -72,7 +72,7 @@
android:stateNotNeeded="true"
android:windowSoftInputMode="adjustPan"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|navigation"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity=""
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 065663d..cab20a3 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -155,6 +155,7 @@
CONFIRM = 4; // Indicates thata confirmation screen was accepted
STOP = 5; // Indicates onStop() was called (screen time out, power off)
RECENTS_BUTTON = 6; // Indicates that Recents button was pressed
+ RESUME = 7; // Indicates onResume() was called
}
optional Type type = 1;
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index ac38906..778866d 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -54,7 +54,7 @@
android:stateNotNeeded="true"
android:theme="@style/LauncherTheme"
android:screenOrientation="unspecified"
- android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
+ android:configChanges="keyboard|keyboardHidden|mcc|mnc|navigation|orientation|screenSize|screenLayout|smallestScreenSize"
android:resizeableActivity="true"
android:resumeWhilePausing="true"
android:taskAffinity="" />
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 5e25fd8..53a6ceb 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/layout/overview_clear_all_button.xml b/quickstep/res/layout/overview_clear_all_button.xml
index 9c4b618..25615e0 100644
--- a/quickstep/res/layout/overview_clear_all_button.xml
+++ b/quickstep/res/layout/overview_clear_all_button.xml
@@ -11,4 +11,5 @@
android:textColor="?attr/workspaceTextColor"
android:visibility="invisible"
android:textSize="14sp"
+ android:importantForAccessibility="no"
/>
\ No newline at end of file
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 429f3a2..f163872 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -13,9 +13,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.quickstep.views.TaskView xmlns:android="http://schemas.android.com/apk/res/android"
+<com.android.quickstep.views.TaskView
+ xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:focusable="false"
android:elevation="4dp">
<com.android.quickstep.views.TaskThumbnailView
@@ -29,5 +31,6 @@
android:layout_width="@dimen/task_thumbnail_icon_size"
android:layout_height="@dimen/task_thumbnail_icon_size"
android:importantForAccessibility="no"
+ android:focusable="false"
android:layout_gravity="top|center_horizontal" />
</com.android.quickstep.views.TaskView>
\ No newline at end of file
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 80ee577..2e31ef2 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -127,13 +127,6 @@
private RemoteAnimationProvider mRemoteAnimationProvider;
- private final AnimatorListenerAdapter mReapplyStateListener = new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mLauncher.getStateManager().reapplyState();
- }
- };
-
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
@@ -260,7 +253,13 @@
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
// Make sure recents gets fixed up by resetting task alphas and scales, etc.
- windowAnimEndListener = mReapplyStateListener;
+ windowAnimEndListener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mLauncher.getStateManager().moveToRestState();
+ mLauncher.getStateManager().reapplyState();
+ }
+ };
} else {
AnimatorPlaybackController controller =
mLauncher.getStateManager()
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
new file mode 100644
index 0000000..2e6dcc0
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import android.animation.ValueAnimator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.quickstep.OverviewInteractionState;
+
+public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler {
+
+ private static final String TAG = "BackButtonAlphaHandler";
+
+ private final Launcher mLauncher;
+ private final OverviewInteractionState mOverviewInteractionState;
+
+ public BackButtonAlphaHandler(Launcher launcher) {
+ mLauncher = launcher;
+ mOverviewInteractionState = OverviewInteractionState.getInstance(mLauncher);
+ }
+
+ @Override
+ public void setState(LauncherState state) {
+ UiFactory.onLauncherStateOrFocusChanged(mLauncher);
+ }
+
+ @Override
+ public void setStateWithAnimation(LauncherState toState,
+ AnimatorSetBuilder builder, LauncherStateManager.AnimationConfig config) {
+ if (!config.playNonAtomicComponent()) {
+ return;
+ }
+ float fromAlpha = mOverviewInteractionState.getBackButtonAlpha();
+ float toAlpha = toState.hideBackButton ? 0 : 1;
+ if (Float.compare(fromAlpha, toAlpha) != 0) {
+ ValueAnimator anim = ValueAnimator.ofFloat(fromAlpha, toAlpha);
+ anim.setDuration(config.duration);
+ anim.addUpdateListener(valueAnimator -> {
+ final float alpha = (float) valueAnimator.getAnimatedValue();
+ mOverviewInteractionState.setBackButtonAlpha(alpha, false);
+ });
+ builder.play(anim);
+ }
+ }
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 54ecb28..987f952 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -189,14 +189,8 @@
if (isFling && expectedDuration != 0) {
// Update all apps interpolator to add a bit of overshoot starting from currFraction
final float currFraction = mCurrentAnimation.getProgressFraction();
- mAllAppsInterpolatorWrapper.baseInterpolator
- = new OvershootInterpolator(Math.min(Math.abs(velocity) / 3, 3f)) {
- @Override
- public float getInterpolation(float t) {
- return super.getInterpolation(t) + ((1 - t) * currFraction);
- }
- };
- animator.setFloatValues(0, 1);
+ mAllAppsInterpolatorWrapper.baseInterpolator = Interpolators.clampToProgress(
+ new OvershootInterpolator(Math.min(Math.abs(velocity), 3f)), currFraction, 1);
animator.setDuration(Math.min(expectedDuration, ATOMIC_DURATION))
.setInterpolator(LINEAR);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 3e80d2c..76820b6 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -78,11 +78,13 @@
}
public static StateHandler[] getStateHandler(Launcher launcher) {
- return new StateHandler[] {
- launcher.getAllAppsController(), launcher.getWorkspace(),
- new RecentsViewStateController(launcher)};
+ return new StateHandler[] {launcher.getAllAppsController(), launcher.getWorkspace(),
+ new RecentsViewStateController(launcher), new BackButtonAlphaHandler(launcher)};
}
+ /**
+ * Sets the back button visibility based on the current state/window focus.
+ */
public static void onLauncherStateOrFocusChanged(Launcher launcher) {
boolean shouldBackButtonBeHidden = launcher != null
&& launcher.getStateManager().getState().hideBackButton
@@ -93,7 +95,7 @@
TYPE_ALL & ~TYPE_HIDE_BACK_BUTTON) == null;
}
OverviewInteractionState.getInstance(launcher)
- .setBackButtonVisible(!shouldBackButtonBeHidden);
+ .setBackButtonAlpha(shouldBackButtonBeHidden ? 0 : 1, true /* animate */);
}
public static void resetOverview(Launcher launcher) {
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 538e23c..15f5aa5 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -163,7 +163,7 @@
mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
break;
case ACTION_QUICK_STEP:
- mConsumer.onQuickStep(event.getX(), event.getY(), event.getEventTime());
+ mConsumer.onQuickStep(event);
break;
default:
Log.e(TAG, "Invalid virtual event: " + event.getAction());
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 2d41a5b..23738fb 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -82,6 +82,7 @@
private final PointF mLastPos = new PointF();
private int mActivePointerId = INVALID_POINTER_ID;
private boolean mPassedInitialSlop;
+ // Used for non-deferred gestures to determine when to start dragging
private int mQuickStepDragSlop;
private float mStartDisplacement;
private WindowTransformSwipeHandler mInteractionHandler;
@@ -160,15 +161,14 @@
}
mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
float displacement = getDisplacement(ev);
- if (!mPassedInitialSlop
- && Math.abs(displacement) > mQuickStepDragSlop) {
- mPassedInitialSlop = true;
- mStartDisplacement = displacement;
-
- // If we deferred starting the window animation on touch down, then
- // start tracking now
- if (mIsDeferredDownTarget) {
- startTouchTrackingForWindowAnimation(ev.getEventTime());
+ if (!mPassedInitialSlop) {
+ if (!mIsDeferredDownTarget) {
+ // Normal gesture, ensure we pass the drag slop before we start tracking
+ // the gesture
+ if (Math.abs(displacement) > mQuickStepDragSlop) {
+ mPassedInitialSlop = true;
+ mStartDisplacement = displacement;
+ }
}
}
@@ -353,7 +353,14 @@
}
@Override
- public void onQuickStep(float eventX, float eventY, long eventTime) {
+ public void onQuickStep(MotionEvent ev) {
+ if (mIsDeferredDownTarget) {
+ // Deferred gesture, start the animation and gesture tracking once we pass the actual
+ // touch slop
+ startTouchTrackingForWindowAnimation(ev.getEventTime());
+ mPassedInitialSlop = true;
+ mStartDisplacement = getDisplacement(ev);
+ }
notifyGestureStarted();
}
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index 420406c..922a7ff 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -17,7 +17,6 @@
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_SWIPE_UP;
-import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
import static com.android.systemui.shared.system.SettingsCompat.SWIPE_UP_SETTING_NAME;
@@ -46,7 +45,6 @@
*
* - FLAG_DISABLE_QUICK_SCRUB
* - FLAG_DISABLE_SWIPE_UP
- * - FLAG_HIDE_BACK_BUTTON
* - FLAG_SHOW_OVERVIEW_BUTTON
*
* @see com.android.systemui.shared.system.NavigationBarCompat.InteractionType and associated flags.
@@ -81,7 +79,7 @@
}
private static final int MSG_SET_PROXY = 200;
- private static final int MSG_SET_BACK_BUTTON_VISIBLE = 201;
+ private static final int MSG_SET_BACK_BUTTON_ALPHA = 201;
private static final int MSG_SET_SWIPE_UP_ENABLED = 202;
private final SwipeUpGestureEnabledSettingObserver mSwipeUpSettingObserver;
@@ -92,13 +90,17 @@
// These are updated on the background thread
private ISystemUiProxy mISystemUiProxy;
- private boolean mBackButtonVisible = true;
private boolean mSwipeUpEnabled = true;
+ private float mBackButtonAlpha = 1;
private Runnable mOnSwipeUpSettingChangedListener;
private OverviewInteractionState(Context context) {
mContext = context;
+
+ // Data posted to the uihandler will be sent to the bghandler. Data is sent to uihandler
+ // because of its high send frequency and data may be very different than the previous value
+ // For example, send back alpha on uihandler to avoid flickering when setting its visibility
mUiHandler = new Handler(this::handleUiMessage);
mBgHandler = new Handler(UiThreadHelper.getBackgroundLooper(), this::handleBgMessage);
@@ -116,9 +118,16 @@
return mSwipeUpEnabled;
}
- public void setBackButtonVisible(boolean visible) {
- mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_VISIBLE);
- mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_VISIBLE, visible ? 1 : 0, 0)
+ public float getBackButtonAlpha() {
+ return mBackButtonAlpha;
+ }
+
+ public void setBackButtonAlpha(float alpha, boolean animate) {
+ if (!mSwipeUpEnabled) {
+ alpha = 1;
+ }
+ mUiHandler.removeMessages(MSG_SET_BACK_BUTTON_ALPHA);
+ mUiHandler.obtainMessage(MSG_SET_BACK_BUTTON_ALPHA, animate ? 1 : 0, 0, alpha)
.sendToTarget();
}
@@ -127,7 +136,10 @@
}
private boolean handleUiMessage(Message msg) {
- mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2).sendToTarget();
+ if (msg.what == MSG_SET_BACK_BUTTON_ALPHA) {
+ mBackButtonAlpha = (float) msg.obj;
+ }
+ mBgHandler.obtainMessage(msg.what, msg.arg1, msg.arg2, msg.obj).sendToTarget();
return true;
}
@@ -136,9 +148,9 @@
case MSG_SET_PROXY:
mISystemUiProxy = (ISystemUiProxy) msg.obj;
break;
- case MSG_SET_BACK_BUTTON_VISIBLE:
- mBackButtonVisible = msg.arg1 != 0;
- break;
+ case MSG_SET_BACK_BUTTON_ALPHA:
+ applyBackButtonAlpha((float) msg.obj, msg.arg1 == 1);
+ return true;
case MSG_SET_SWIPE_UP_ENABLED:
mSwipeUpEnabled = msg.arg1 != 0;
resetHomeBounceSeenOnQuickstepEnabledFirstTime();
@@ -162,10 +174,8 @@
return;
}
- int flags;
- if (mSwipeUpEnabled) {
- flags = mBackButtonVisible ? 0 : FLAG_HIDE_BACK_BUTTON;
- } else {
+ int flags = 0;
+ if (!mSwipeUpEnabled) {
flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
}
try {
@@ -175,6 +185,18 @@
}
}
+ @WorkerThread
+ private void applyBackButtonAlpha(float alpha, boolean animate) {
+ if (mISystemUiProxy == null) {
+ return;
+ }
+ try {
+ mISystemUiProxy.setBackButtonAlpha(alpha, animate);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Unable to update overview back button alpha", e);
+ }
+ }
+
private class SwipeUpGestureEnabledSettingObserver extends ContentObserver {
private Handler mHandler;
private ContentResolver mResolver;
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index 28b06fb..abb479d 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -63,6 +63,7 @@
private final BaseActivity mActivity;
private boolean mInQuickScrub;
+ private boolean mWaitingForTaskLaunch;
private int mQuickScrubSection;
private boolean mStartedFromHome;
private boolean mFinishedTransitionToQuickScrub;
@@ -79,11 +80,11 @@
}
public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) {
+ prepareQuickScrub(TAG);
mInQuickScrub = true;
mStartedFromHome = startingFromHome;
mQuickScrubSection = 0;
mFinishedTransitionToQuickScrub = false;
- mOnFinishedTransitionToQuickScrubRunnable = null;
mActivityControlHelper = controlHelper;
snapToNextTaskIfAvailable();
@@ -99,11 +100,17 @@
Runnable launchTaskRunnable = () -> {
TaskView taskView = mRecentsView.getPageAt(page);
if (taskView != null) {
+ mWaitingForTaskLaunch = true;
taskView.launchTask(true, (result) -> {
if (!result) {
taskView.notifyTaskLaunchFailed(TAG);
breakOutOfQuickScrub();
+ } else {
+ mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
+ LauncherLogProto.Action.Direction.NONE, page,
+ TaskUtils.getComponentKeyForTask(taskView.getTask().key));
}
+ mWaitingForTaskLaunch = false;
}, taskView.getHandler());
} else {
breakOutOfQuickScrub();
@@ -123,9 +130,19 @@
mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
}
}
- mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
- LauncherLogProto.Action.Direction.NONE, page,
- TaskUtils.getComponentKeyForTask(mRecentsView.getPageAt(page).getTask().key));
+ }
+
+ /**
+ * Initializes the UI for quick scrub, returns true if success.
+ */
+ public boolean prepareQuickScrub(String tag) {
+ if (mWaitingForTaskLaunch || mInQuickScrub) {
+ Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
+ return false;
+ }
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ mRecentsView.setNextPageSwitchRunnable(null);
+ return true;
}
/**
@@ -166,9 +183,11 @@
public void onFinishedTransitionToQuickScrub() {
mFinishedTransitionToQuickScrub = true;
- if (mOnFinishedTransitionToQuickScrubRunnable != null) {
- mOnFinishedTransitionToQuickScrubRunnable.run();
- mOnFinishedTransitionToQuickScrubRunnable = null;
+ Runnable action = mOnFinishedTransitionToQuickScrubRunnable;
+ // Clear the runnable before executing it, to prevent potential recursion.
+ mOnFinishedTransitionToQuickScrubRunnable = null;
+ if (action != null) {
+ action.run();
}
}
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index d7fad43..2b0c98f 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -98,12 +98,13 @@
if (v.getTag() instanceof ItemInfo) {
ItemInfo itemInfo = (ItemInfo) v.getTag();
ComponentName componentName = itemInfo.getTargetComponent();
+ int userId = itemInfo.user.getIdentifier();
if (componentName != null) {
for (int i = 0; i < recentsView.getChildCount(); i++) {
TaskView taskView = recentsView.getPageAt(i);
if (recentsView.isTaskViewVisible(taskView)) {
- Task task = taskView.getTask();
- if (componentName.equals(task.key.getComponent())) {
+ Task.TaskKey key = taskView.getTask().key;
+ if (componentName.equals(key.getComponent()) && userId == key.userId) {
return taskView;
}
}
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 1290ec3..aa844d8 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -46,7 +46,7 @@
default void onQuickScrubProgress(float progress) { }
- default void onQuickStep(float eventX, float eventY, long eventTime) { }
+ default void onQuickStep(MotionEvent ev) { }
/**
* Called on the binder thread to allow the consumer to process the motion event before it is
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index bd05b6d..aecb66c 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -334,7 +334,7 @@
}
@Override
- public void onQuickStep(float eventX, float eventY, long eventTime) {
+ public void onQuickStep(MotionEvent ev) {
if (mInvalidated) {
return;
}
@@ -349,12 +349,20 @@
return;
}
if (interactionType == INTERACTION_QUICK_SCRUB) {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ return;
+ }
OverviewCallbacks.get(mActivity).closeAllWindows();
ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
mStartPending = true;
Runnable action = () -> {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mInvalidated = true;
+ return;
+ }
mActivityHelper.onQuickInteractionStart(mActivity, null, true);
mQuickScrubController.onQuickScrubProgress(mLastProgress);
mStartPending = false;
@@ -384,7 +392,7 @@
@Override
public void onQuickScrubProgress(float progress) {
mLastProgress = progress;
- if (mInvalidated || mEndPending) {
+ if (mInvalidated || mStartPending) {
return;
}
mQuickScrubController.onQuickScrubProgress(progress);
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 807dae8..84b2176 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -109,6 +109,8 @@
private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14;
private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15;
+ private static final int STATE_RESUME_LAST_TASK = 1 << 16;
+
private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
| STATE_LAUNCHER_STARTED;
@@ -139,6 +141,7 @@
"STATE_QUICK_SCRUB_END",
"STATE_CAPTURE_SCREENSHOT",
"STATE_SCREENSHOT_CAPTURED",
+ "STATE_RESUME_LAST_TASK",
};
public static final long MAX_SWIPE_DURATION = 350;
@@ -187,6 +190,7 @@
private boolean mGestureStarted;
private int mLogAction = Touch.SWIPE;
private float mCurrentQuickScrubProgress;
+ private boolean mQuickScrubBlocked;
private @InteractionType int mInteractionType = INTERACTION_NORMAL;
@@ -239,9 +243,12 @@
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED,
this::sendRemoteAnimationsToAnimationFactory);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
- | STATE_SCALED_CONTROLLER_APP,
+
+ mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
+ this::resumeLastTaskForQuickstep);
+ mStateCallback.addCallback(STATE_RESUME_LAST_TASK | STATE_APP_CONTROLLER_RECEIVED,
this::resumeLastTask);
+
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
| STATE_ACTIVITY_MULTIPLIER_COMPLETE
| STATE_CAPTURE_SCREENSHOT,
@@ -258,9 +265,6 @@
| STATE_GESTURE_COMPLETED,
this::setupLauncherUiAfterSwipeUpAnimation);
- mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
- this::reset);
-
mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher);
@@ -657,9 +661,15 @@
}
@UiThread
+ private void resumeLastTaskForQuickstep() {
+ setStateOnUiThread(STATE_RESUME_LAST_TASK);
+ doLogGesture(false /* toLauncher */);
+ reset();
+ }
+
+ @UiThread
private void resumeLastTask() {
mRecentsAnimationWrapper.finish(false /* toHome */, null);
- doLogGesture(false /* toLauncher */);
}
public void reset() {
@@ -760,6 +770,11 @@
}
private void onQuickScrubStart() {
+ if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+ mQuickScrubBlocked = true;
+ setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
+ return;
+ }
if (mLauncherTransitionController != null) {
mLauncherTransitionController.getAnimationPlayer().end();
mLauncherTransitionController = null;
@@ -793,12 +808,16 @@
}
private void onFinishedTransitionToQuickScrub() {
+ if (mQuickScrubBlocked) {
+ return;
+ }
mQuickScrubController.onFinishedTransitionToQuickScrub();
}
public void onQuickScrubProgress(float progress) {
mCurrentQuickScrubProgress = progress;
- if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null) {
+ if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null
+ || mQuickScrubBlocked) {
return;
}
mQuickScrubController.onQuickScrubProgress(progress);
@@ -809,6 +828,9 @@
}
private void switchToFinalAppAfterQuickScrub() {
+ if (mQuickScrubBlocked) {
+ return;
+ }
mQuickScrubController.onQuickScrubEnd();
// Normally this is handled in reset(), but since we are still scrubbing after the
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 9e2de33..c5d74c7 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -20,8 +20,10 @@
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;
+import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
import com.android.quickstep.RecentsActivity;
import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.views.RecentsView;
@@ -71,4 +73,21 @@
// Just use the activity task size for multi-window as well.
return false;
}
+
+ @Override
+ public void addTaskAccessibilityActionsExtra(AccessibilityNodeInfo info) {
+ info.addAction(
+ new AccessibilityNodeInfo.AccessibilityAction(
+ R.string.recents_clear_all,
+ getContext().getText(R.string.recents_clear_all)));
+ }
+
+ @Override
+ public boolean performTaskAccessibilityActionExtra(int action) {
+ if (action == R.string.recents_clear_all) {
+ dismissAllTasks();
+ return true;
+ }
+ return false;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index f3a0e4f..25e3dc6 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -19,10 +19,10 @@
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS;
import android.content.Context;
+import android.graphics.Rect;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
-import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.Button;
public class ClearAllButton extends Button {
@@ -37,14 +37,6 @@
}
@Override
- public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
- super.onInitializeAccessibilityNodeInfo(info);
- // Should be visible to accessibility even when completely covered by the task.
- // Otherwise, we won't be able to scroll to it.
- info.setVisibleToUser(true);
- }
-
- @Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
final boolean res = super.performAccessibilityAction(action, arguments);
if (action == ACTION_ACCESSIBILITY_FOCUS) {
@@ -52,4 +44,12 @@
}
return res;
}
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+ if (focused) {
+ mRecentsView.revealClearAllButton();
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index aeff476..ae8ebbe 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -41,6 +41,7 @@
import android.os.Build;
import android.os.Handler;
import android.os.UserHandle;
+import android.support.annotation.Nullable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
@@ -53,7 +54,7 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
-import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
@@ -582,6 +583,11 @@
* and unloads the associated task data for tasks that are no longer visible.
*/
public void loadVisibleTaskData() {
+ if (!mOverviewStateEnabled) {
+ // Skip loading visible task data if we've already left the overview state
+ return;
+ }
+
RecentsTaskLoader loader = mModel.getRecentsTaskLoader();
int centerPageIndex = getPageNearestToCenterOfScreen();
int lower = Math.max(0, centerPageIndex - 2);
@@ -968,6 +974,13 @@
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_TAB:
+ if (!event.isAltPressed() &&
+ getNextPage() ==
+ (event.isShiftPressed() ? 0 : getChildCount() - 1)) {
+ // If not Alt-Tab navigation, don't loop forever in the carousel and leave
+ // it once we reached the end.
+ return false;
+ }
snapToPageRelative(event.isShiftPressed() ? -1 : 1);
return true;
case KeyEvent.KEYCODE_DPAD_RIGHT:
@@ -993,6 +1006,22 @@
return super.dispatchKeyEvent(event);
}
+ @Override
+ protected void onFocusChanged(boolean gainFocus, int direction,
+ @Nullable Rect previouslyFocusedRect) {
+ super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
+ if (gainFocus && getChildCount() > 0) {
+ switch (direction) {
+ case FOCUS_FORWARD:
+ setCurrentPage(0);
+ break;
+ case FOCUS_BACKWARD:
+ setCurrentPage(getChildCount() - 1);
+ break;
+ }
+ }
+ }
+
public void snapToTaskAfterNext() {
snapToPageRelative(1);
}
@@ -1002,6 +1031,7 @@
}
public void setContentAlpha(float alpha) {
+ alpha = Utilities.boundToRange(alpha, 0, 1);
mContentAlpha = alpha;
for (int i = getChildCount() - 1; i >= 0; i--) {
TaskView child = getPageAt(i);
@@ -1264,10 +1294,6 @@
@Override
protected void notifyPageSwitchListener(int prevPage) {
super.notifyPageSwitchListener(prevPage);
- View currChild = getChildAt(mCurrentPage);
- if (currChild != null) {
- currChild.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- }
loadVisibleTaskData();
}
@@ -1303,12 +1329,34 @@
private void onChildViewsChanged() {
final int childCount = getChildCount();
- mClearAllButton.setAccessibilityTraversalAfter(
- childCount == 0 ? NO_ID : getChildAt(childCount - 1).getId());
mClearAllButton.setVisibility(childCount == 0 ? INVISIBLE : VISIBLE);
}
public void revealClearAllButton() {
+ setCurrentPage(getChildCount() - 1); // Loads tasks info if needed.
scrollTo(mIsRtl ? 0 : computeMaxScrollX(), 0);
}
+
+ @Override
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
+ if (FLIP_RECENTS) {
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ outChildren.add(getChildAt(i));
+ }
+ } else {
+ super.addChildrenForAccessibility(outChildren);
+ }
+ }
+
+ @Override
+ protected boolean isPageOrderFlipped() {
+ return FLIP_RECENTS;
+ }
+
+ public void addTaskAccessibilityActionsExtra(AccessibilityNodeInfo info) {
+ }
+
+ public boolean performTaskAccessibilityActionExtra(int action) {
+ return false;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
index 429432b..06e2e89 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -25,10 +25,13 @@
import android.util.FloatProperty;
import android.view.Gravity;
import android.view.MotionEvent;
+import android.view.View;
import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.R;
+import java.util.ArrayList;
+
public class RecentsViewContainer extends InsettableFrameLayout {
public static final FloatProperty<RecentsViewContainer> CONTENT_ALPHA =
new FloatProperty<RecentsViewContainer>("contentAlpha") {
@@ -104,4 +107,11 @@
mRecentsView.setContentAlpha(alpha);
setVisibility(alpha > 0 ? VISIBLE : GONE);
}
+
+ @Override
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+ // Carousel is first in tab order.
+ views.add(mRecentsView);
+ views.add(mClearAllButton);
+ }
}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 82aa45a..2f1a0fe 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -17,6 +17,7 @@
package com.android.quickstep.views;
import static android.widget.Toast.LENGTH_SHORT;
+
import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA_MULTIPLIER;
import android.animation.Animator;
@@ -116,7 +117,7 @@
}
launchTask(true /* animate */);
BaseActivity.fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
- Touch.TAP, Direction.NONE, ((RecentsView) getParent()).indexOfChild(this),
+ Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
TaskUtils.getComponentKeyForTask(getTask().key));
});
setOutlineProvider(new TaskOutlineProvider(getResources()));
@@ -318,12 +319,14 @@
context.getText(menuOption.labelResId)));
}
}
+
+ getRecentsView().addTaskAccessibilityActionsExtra(info);
}
@Override
public boolean performAccessibilityAction(int action, Bundle arguments) {
if (action == R.string.accessibility_close_task) {
- ((RecentsView) getParent()).dismissTask(this, true /*animateTaskView*/,
+ getRecentsView().dismissTask(this, true /*animateTaskView*/,
true /*removeTask*/);
return true;
}
@@ -339,9 +342,15 @@
}
}
+ if (getRecentsView().performTaskAccessibilityActionExtra(action)) return true;
+
return super.performAccessibilityAction(action, arguments);
}
+ private RecentsView getRecentsView() {
+ return (RecentsView) getParent();
+ }
+
public void notifyTaskLaunchFailed(String tag) {
String msg = "Failed to launch task";
if (mTask != null) {
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 5e7b117..02d793e 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -23,8 +23,7 @@
android:layout_height="match_parent"
android:clipChildren="true"
android:clipToPadding="false"
- android:focusable="true"
- android:focusableInTouchMode="true"
+ android:focusable="false"
android:saveEnabled="false" >
<include layout="@layout/all_apps_rv_layout" />
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 5a1c158..c75509e 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -101,10 +101,12 @@
}
public final void close(boolean animate) {
- animate &= !Utilities.isPowerSaverOn(getContext());
+ animate &= !Utilities.isPowerSaverPreventingAnimation(getContext());
+ if (mIsOpen) {
+ BaseActivity.fromContext(getContext()).getUserEventDispatcher()
+ .resetElapsedContainerMillis("container closed");
+ }
handleClose(animate);
- BaseActivity.fromContext(getContext()).getUserEventDispatcher()
- .resetElapsedContainerMillis("container closed");
mIsOpen = false;
}
@@ -121,9 +123,11 @@
protected abstract boolean isOfType(@FloatingViewType int type);
- public void onBackPressed() {
+ /** @return Whether the back is consumed. If false, Launcher will handle the back as well. */
+ public boolean onBackPressed() {
logActionCommand(Action.Command.BACK);
close(true);
+ return true;
}
@Override
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 7979082..6c2fd8e 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -1980,7 +1980,7 @@
// Animations are disabled in power save mode, causing the repeated animation to jump
// spastically between beginning and end states. Since this looks bad, we don't repeat
// the animation in power save mode.
- if (!Utilities.isPowerSaverOn(getContext())) {
+ if (!Utilities.isPowerSaverPreventingAnimation(getContext())) {
va.setRepeatMode(ValueAnimator.REVERSE);
va.setRepeatCount(ValueAnimator.INFINITE);
}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index e851499..14390ec 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -50,6 +50,7 @@
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.Parcelable;
import android.os.Process;
import android.os.StrictMode;
@@ -243,6 +244,10 @@
private RotationHelper mRotationHelper;
+
+ private final Handler mHandler = new Handler();
+ private final Runnable mLogOnDelayedResume = this::logOnDelayedResume;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
if (DEBUG_STRICT_MODE) {
@@ -727,10 +732,11 @@
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onStop();
}
- mAppWidgetHost.setListenIfResumed(false);
-
getUserEventDispatcher().logActionCommand(Action.Command.STOP,
mStateManager.getState().containerType, -1);
+
+ mAppWidgetHost.setListenIfResumed(false);
+
NotificationListener.removeNotificationsChangedListener();
getStateManager().moveToRestState();
@@ -751,13 +757,23 @@
UiFactory.onStart(this);
}
+ private void logOnDelayedResume() {
+ if (hasBeenResumed()) {
+ getUserEventDispatcher().logActionCommand(Action.Command.RESUME,
+ mStateManager.getState().containerType, -1);
+ getUserEventDispatcher().startSession();
+ }
+ }
+
@Override
protected void onResume() {
TraceHelper.beginSection("ON_RESUME");
super.onResume();
TraceHelper.partitionSection("ON_RESUME", "superCall");
- getUserEventDispatcher().resetElapsedSessionMillis();
+ mHandler.removeCallbacks(mLogOnDelayedResume);
+ Utilities.postAsyncCallback(mHandler, mLogOnDelayedResume);
+
setOnResumeCallback(null);
// Process any items that were added while Launcher was away.
InstallShortcutReceiver.disableAndFlushInstallQueue(
@@ -1583,8 +1599,8 @@
// by using if-else statements.
UserEventDispatcher ued = getUserEventDispatcher();
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this);
- if (topView != null) {
- topView.onBackPressed();
+ if (topView != null && topView.onBackPressed()) {
+ // Handled by the floating view.
} else if (!isInState(NORMAL)) {
LauncherState lastState = mStateManager.getLastState();
ued.logActionCommand(Action.Command.BACK, mStateManager.getState().containerType,
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index e6fc4c6..3fcdee9 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -396,7 +396,6 @@
setRestState(null);
}
- UiFactory.onLauncherStateOrFocusChanged(mLauncher);
UiFactory.onLauncherStateOrResumeChanged(mLauncher);
}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index a98867d..efbd004 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -1495,12 +1495,20 @@
return Math.abs(delta) > 0;
}
- public void scrollLeft() {
- if (getNextPage() > 0) snapToPage(getNextPage() - 1);
+ public boolean scrollLeft() {
+ if (getNextPage() > 0) {
+ snapToPage(getNextPage() - 1);
+ return true;
+ }
+ return false;
}
- public void scrollRight() {
- if (getNextPage() < getChildCount() -1) snapToPage(getNextPage() + 1);
+ public boolean scrollRight() {
+ if (getNextPage() < getChildCount() - 1) {
+ snapToPage(getNextPage() + 1);
+ return true;
+ }
+ return false;
}
@Override
@@ -1510,17 +1518,24 @@
return ScrollView.class.getName();
}
+ protected boolean isPageOrderFlipped() {
+ return false;
+ }
+
/* Accessibility */
@SuppressWarnings("deprecation")
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
+ final boolean pagesFlipped = isPageOrderFlipped();
info.setScrollable(getPageCount() > 1);
if (getCurrentPage() < getPageCount() - 1) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
+ info.addAction(pagesFlipped ? AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD
+ : AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
}
if (getCurrentPage() > 0) {
- info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
+ info.addAction(pagesFlipped ? AccessibilityNodeInfo.ACTION_SCROLL_FORWARD
+ : AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
}
// Accessibility-wise, PagedView doesn't support long click, so disabling it.
@@ -1549,19 +1564,19 @@
if (super.performAccessibilityAction(action, arguments)) {
return true;
}
+ final boolean pagesFlipped = isPageOrderFlipped();
switch (action) {
case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: {
- if (getCurrentPage() < getPageCount() - 1) {
- scrollRight();
+ if (pagesFlipped ? scrollLeft() : scrollRight()) {
return true;
}
} break;
case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: {
- if (getCurrentPage() > 0) {
- scrollLeft();
+ if (pagesFlipped ? scrollRight() : scrollLeft()) {
return true;
}
- } break;
+ }
+ break;
}
return false;
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 006dc95..4bd9a9b 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -39,7 +39,6 @@
import android.os.Message;
import android.os.PowerManager;
import android.os.TransactionTooLargeException;
-import android.support.v4.os.BuildCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -83,7 +82,8 @@
private static final Matrix sMatrix = new Matrix();
private static final Matrix sInverseMatrix = new Matrix();
- public static final boolean ATLEAST_P = BuildCompat.isAtLeastP();
+ public static final boolean ATLEAST_P =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
public static final boolean ATLEAST_OREO_MR1 =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1;
@@ -492,7 +492,11 @@
LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
}
- public static boolean isPowerSaverOn(Context context) {
+ public static boolean isPowerSaverPreventingAnimation(Context context) {
+ if (ATLEAST_P) {
+ // Battery saver mode no longer prevents animations.
+ return false;
+ }
PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
return powerManager.isPowerSaveMode();
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2df34d5..6631f77 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2961,25 +2961,29 @@
}
@Override
- public void scrollLeft() {
+ public boolean scrollLeft() {
+ boolean result = false;
if (!workspaceInModalState() && !mIsSwitchingState) {
- super.scrollLeft();
+ result = super.scrollLeft();
}
Folder openFolder = Folder.getOpen(mLauncher);
if (openFolder != null) {
openFolder.completeDragExit();
}
+ return result;
}
@Override
- public void scrollRight() {
+ public boolean scrollRight() {
+ boolean result = false;
if (!workspaceInModalState() && !mIsSwitchingState) {
- super.scrollRight();
+ result = super.scrollRight();
}
Folder openFolder = Folder.getOpen(mLauncher);
if (openFolder != null) {
openFolder.completeDragExit();
}
+ return result;
}
/**
diff --git a/src/com/android/launcher3/allapps/DiscoveryBounce.java b/src/com/android/launcher3/allapps/DiscoveryBounce.java
index 4c0ac92..6b04384 100644
--- a/src/com/android/launcher3/allapps/DiscoveryBounce.java
+++ b/src/com/android/launcher3/allapps/DiscoveryBounce.java
@@ -84,6 +84,14 @@
}
@Override
+ public boolean onBackPressed() {
+ super.onBackPressed();
+ // Go back to the previous state (from a user's perspective this floating view isn't
+ // something to go back from).
+ return false;
+ }
+
+ @Override
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
handleClose(false);
return false;
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVP.java b/src/com/android/launcher3/compat/UserManagerCompatVP.java
index 2e8a8eb..fa3902b 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVP.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVP.java
@@ -15,41 +15,20 @@
*/
package com.android.launcher3.compat;
+import android.annotation.TargetApi;
import android.content.Context;
+import android.os.Build;
import android.os.UserHandle;
-import android.os.UserManager;
-import android.util.Log;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
+@TargetApi(Build.VERSION_CODES.P)
public class UserManagerCompatVP extends UserManagerCompatVNMr1 {
- private static final String TAG = "UserManagerCompatVP";
-
- private Method mRequestQuietModeEnabled;
UserManagerCompatVP(Context context) {
super(context);
- // TODO: Replace it with proper API call once SDK is ready.
- try {
- mRequestQuietModeEnabled = UserManager.class.getDeclaredMethod(
- "requestQuietModeEnabled", boolean.class, UserHandle.class);
- } catch (NoSuchMethodException e) {
- Log.e(TAG, "requestQuietModeEnabled is not available", e);
- }
}
@Override
public boolean requestQuietModeEnabled(boolean enableQuietMode, UserHandle user) {
- if (mRequestQuietModeEnabled == null) {
- return false;
- }
- try {
- return (boolean)
- mRequestQuietModeEnabled.invoke(mUserManager, enableQuietMode, user);
- } catch (IllegalAccessException | InvocationTargetException e) {
- Log.e(TAG, "Failed to invoke mRequestQuietModeEnabled", e);
- }
- return false;
+ return mUserManager.requestQuietModeEnabled(enableQuietMode, user);
}
}
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index b49952f..6b13da7 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -1437,12 +1437,13 @@
}
@Override
- public void onBackPressed() {
+ public boolean onBackPressed() {
if (isEditingName()) {
mFolderName.dispatchBackKey();
} else {
super.onBackPressed();
}
+ return true;
}
@Override
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 850c948..1842e19 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -125,6 +125,7 @@
return null;
}
+ private boolean mSessionStarted;
private long mElapsedContainerMillis;
private long mElapsedSessionMillis;
private long mActionDurationMillis;
@@ -216,9 +217,11 @@
public void logActionCommand(int command, Target srcTarget, Target dstTarget) {
LauncherEvent event = newLauncherEvent(newCommandAction(command), srcTarget);
- if (command == Action.Command.STOP && mAppOrTaskLaunch) {
- // Prevent double logging by skipping STOP when app or task has been launched.
- return;
+ if (command == Action.Command.STOP) {
+ if (mAppOrTaskLaunch || !mSessionStarted) {
+ mSessionStarted = false;
+ return;
+ }
}
if (dstTarget != null) {
@@ -405,7 +408,8 @@
}
- public final void resetElapsedSessionMillis() {
+ public final void startSession() {
+ mSessionStarted = true;
mElapsedSessionMillis = SystemClock.uptimeMillis();
mElapsedContainerMillis = SystemClock.uptimeMillis();
}
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index e29250a..24382b7 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -209,11 +209,13 @@
@Override
public void onAnimationSuccess(Animator animation) {
cancelAtomicComponentsController();
- mAtomicComponentsStartProgress = mCurrentAnimation.getProgressFraction();
- long duration = (long) (getShiftRange() * 2);
- mAtomicComponentsController = AnimatorPlaybackController.wrap(
- createAtomicAnimForState(mFromState, mToState, duration), duration);
- mAtomicComponentsController.dispatchOnStart();
+ if (mCurrentAnimation != null) {
+ mAtomicComponentsStartProgress = mCurrentAnimation.getProgressFraction();
+ long duration = (long) (getShiftRange() * 2);
+ mAtomicComponentsController = AnimatorPlaybackController.wrap(
+ createAtomicAnimForState(mFromState, mToState, duration), duration);
+ mAtomicComponentsController.dispatchOnStart();
+ }
}
});
}
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 6bbce00..ea05cdc 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -118,6 +118,7 @@
ViewCompat.setAccessibilityDelegate(this, mAccessibilityHelper);
mAM = (AccessibilityManager) context.getSystemService(ACCESSIBILITY_SERVICE);
+ setFocusable(false);
}
@NonNull
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index e93dd5a..db98f9a 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -56,4 +56,6 @@
}
public static void prepareToShowOverview(Launcher launcher) { }
+
+ public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) { }
}