summaryrefslogtreecommitdiffstats
path: root/quickstep/src
diff options
context:
space:
mode:
Diffstat (limited to 'quickstep/src')
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java76
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java7
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java62
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java31
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java2
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/OverviewState.java9
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java2
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java6
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java15
-rw-r--r--quickstep/src/com/android/quickstep/ActivityControlHelper.java50
-rw-r--r--quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java12
-rw-r--r--quickstep/src/com/android/quickstep/OverviewCommandHelper.java10
-rw-r--r--quickstep/src/com/android/quickstep/OverviewInteractionState.java11
-rw-r--r--quickstep/src/com/android/quickstep/QuickScrubController.java2
-rw-r--r--quickstep/src/com/android/quickstep/RecentsActivity.java4
-rw-r--r--quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java30
-rw-r--r--quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java19
-rw-r--r--quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java30
-rw-r--r--quickstep/src/com/android/quickstep/util/TransformedRect.java32
-rw-r--r--quickstep/src/com/android/quickstep/views/ClearAllButton.java9
-rw-r--r--quickstep/src/com/android/quickstep/views/LauncherRecentsView.java11
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsView.java174
-rw-r--r--quickstep/src/com/android/quickstep/views/RecentsViewContainer.java30
-rw-r--r--quickstep/src/com/android/quickstep/views/ShelfScrimView.java9
-rw-r--r--quickstep/src/com/android/quickstep/views/TaskView.java22
25 files changed, 456 insertions, 209 deletions
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 2e31ef239..6703bb546 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -184,7 +184,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
// before our internal listeners.
mLauncher.getStateManager().setCurrentAnimation(anim);
- anim.play(getIconAnimator(v));
+ Rect windowTargetBounds = getWindowTargetBounds(targetCompats);
+ anim.play(getIconAnimator(v, windowTargetBounds));
if (launcherClosing) {
Pair<AnimatorSet, Runnable> launcherContentAnimator =
getLauncherContentAnimator(true /* isAppOpening */);
@@ -196,7 +197,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
}
});
}
- anim.play(getOpeningWindowAnimators(v, targetCompats));
+ anim.play(getOpeningWindowAnimators(v, targetCompats, windowTargetBounds));
}
if (launcherClosing) {
@@ -213,7 +214,26 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
return ActivityOptionsCompat.makeRemoteAnimation(new RemoteAnimationAdapterCompat(
runner, duration, statusBarTransitionDelay));
}
- return getDefaultActivityLaunchOptions(launcher, v);
+ return super.getActivityLaunchOptions(launcher, v);
+ }
+
+ /**
+ * Return the window bounds of the opening target.
+ * In multiwindow mode, we need to get the final size of the opening app window target to help
+ * figure out where the floating view should animate to.
+ */
+ private Rect getWindowTargetBounds(RemoteAnimationTargetCompat[] targets) {
+ Rect bounds = new Rect(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx);
+ if (mLauncher.isInMultiWindowModeCompat()) {
+ for (RemoteAnimationTargetCompat target : targets) {
+ if (target.mode == MODE_OPENING) {
+ bounds.set(target.sourceContainerBounds);
+ bounds.offsetTo(target.position.x, target.position.y);
+ return bounds;
+ }
+ }
+ }
+ return bounds;
}
public void setRemoteAnimationProvider(RemoteAnimationProvider animationProvider) {
@@ -382,7 +402,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
/**
* @return Animator that controls the icon used to launch the target.
*/
- private AnimatorSet getIconAnimator(View v) {
+ private AnimatorSet getIconAnimator(View v, Rect windowTargetBounds) {
final boolean isBubbleTextView = v instanceof BubbleTextView;
mFloatingView = new View(mLauncher);
if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
@@ -418,7 +438,7 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
viewLocationLeft += rect.left;
viewLocationTop += rect.top;
int viewLocationStart = mIsRtl
- ? mDeviceProfile.widthPx - rect.right
+ ? windowTargetBounds.width() - rect.right
: viewLocationLeft;
LayoutParams lp = new LayoutParams(rect.width(), rect.height());
lp.ignoreInsets = true;
@@ -438,12 +458,15 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
v.setVisibility(View.INVISIBLE);
AnimatorSet appIconAnimatorSet = new AnimatorSet();
- // Animate the app icon to the center
- float centerX = mDeviceProfile.widthPx / 2;
- float centerY = mDeviceProfile.heightPx / 2;
+ int[] dragLayerBounds = new int[2];
+ mDragLayer.getLocationOnScreen(dragLayerBounds);
+
+ // Animate the app icon to the center of the window bounds in screen coordinates.
+ float centerX = windowTargetBounds.centerX() - dragLayerBounds[0];
+ float centerY = windowTargetBounds.centerY() - dragLayerBounds[1];
float xPosition = mIsRtl
- ? mDeviceProfile.widthPx - lp.getMarginStart() - rect.width()
+ ? windowTargetBounds.width() - lp.getMarginStart() - rect.width()
: lp.getMarginStart();
float dX = centerX - xPosition - (lp.width / 2);
float dY = centerY - lp.topMargin - (lp.height / 2);
@@ -469,8 +492,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
// Scale the app icon to take up the entire screen. This simplifies the math when
// animating the app window position / scale.
- float maxScaleX = mDeviceProfile.widthPx / (float) rect.width();
- float maxScaleY = mDeviceProfile.heightPx / (float) rect.height();
+ float maxScaleX = windowTargetBounds.width() / (float) rect.width();
+ float maxScaleY = windowTargetBounds.height() / (float) rect.height();
float scale = Math.max(maxScaleX, maxScaleY);
ObjectAnimator scaleAnim = ObjectAnimator
.ofFloat(mFloatingView, SCALE_PROPERTY, startScale, scale);
@@ -505,7 +528,8 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
/**
* @return Animator that controls the window of the opening targets.
*/
- private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets) {
+ private ValueAnimator getOpeningWindowAnimators(View v, RemoteAnimationTargetCompat[] targets,
+ Rect windowTargetBounds) {
Rect bounds = new Rect();
if (v.getParent() instanceof DeepShortcutView) {
// Deep shortcut views have their icon drawn in a separate view.
@@ -544,31 +568,35 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
float iconHeight = bounds.height() * mFloatingView.getScaleY();
// Scale the app window to match the icon size.
- float scaleX = iconWidth / mDeviceProfile.widthPx;
- float scaleY = iconHeight / mDeviceProfile.heightPx;
+ float scaleX = iconWidth / windowTargetBounds.width();
+ float scaleY = iconHeight / windowTargetBounds.height();
float scale = Math.min(1f, Math.min(scaleX, scaleY));
matrix.setScale(scale, scale);
// Position the scaled window on top of the icon
- int deviceWidth = mDeviceProfile.widthPx;
- int deviceHeight = mDeviceProfile.heightPx;
- float scaledWindowWidth = deviceWidth * scale;
- float scaledWindowHeight = deviceHeight * scale;
+ int windowWidth = windowTargetBounds.width();
+ int windowHeight = windowTargetBounds.height();
+ float scaledWindowWidth = windowWidth * scale;
+ float scaledWindowHeight = windowHeight * scale;
float offsetX = (scaledWindowWidth - iconWidth) / 2;
float offsetY = (scaledWindowHeight - iconHeight) / 2;
- mFloatingView.getLocationInWindow(floatingViewBounds);
+ if (mLauncher.isInMultiWindowModeCompat()) {
+ mFloatingView.getLocationOnScreen(floatingViewBounds);
+ } else {
+ mFloatingView.getLocationInWindow(floatingViewBounds);
+ }
float transX0 = floatingViewBounds[0] - offsetX;
float transY0 = floatingViewBounds[1] - offsetY;
matrix.postTranslate(transX0, transY0);
// Animate the window crop so that it starts off as a square, and then reveals
// horizontally.
- float cropHeight = deviceHeight * easePercent + deviceWidth * (1 - easePercent);
- float initialTop = (deviceHeight - deviceWidth) / 2f;
+ float cropHeight = windowHeight * easePercent + windowWidth * (1 - easePercent);
+ float initialTop = (windowHeight - windowWidth) / 2f;
crop.left = 0;
crop.top = (int) (initialTop * (1 - easePercent));
- crop.right = deviceWidth;
+ crop.right = windowWidth;
crop.bottom = (int) (crop.top + cropHeight);
TransactionCompat t = new TransactionCompat();
@@ -579,10 +607,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
for (RemoteAnimationTargetCompat target : targets) {
if (target.mode == MODE_OPENING) {
t.setAlpha(target.leash, mAlpha.value);
-
- // TODO: This isn't correct at the beginning of the animation, but better
- // than nothing.
- matrix.postTranslate(target.position.x, target.position.y);
t.setMatrix(target.leash, matrix);
t.setWindowCrop(target.leash, crop);
t.deferTransactionUntil(target.leash, surface, getNextFrameNumber(surface));
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index d86ba6aa6..1eaa8bc92 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -18,8 +18,6 @@ package com.android.launcher3.uioverrides;
import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS;
import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
-import android.view.View;
-
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
@@ -62,11 +60,6 @@ public class AllAppsState extends LauncherState {
}
@Override
- public View getFinalFocus(Launcher launcher) {
- return launcher.getAppsView();
- }
-
- @Override
public float[] getWorkspaceScaleAndTranslation(Launcher launcher) {
float[] scaleAndTranslation = LauncherState.OVERVIEW.getWorkspaceScaleAndTranslation(
launcher);
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 000000000..2e6dcc0e7
--- /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/FastOverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
index a11625a34..43d982230 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/FastOverviewState.java
@@ -15,7 +15,13 @@
*/
package com.android.launcher3.uioverrides;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Rect;
+
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
import com.android.quickstep.QuickScrubController;
import com.android.quickstep.views.RecentsView;
@@ -24,6 +30,12 @@ import com.android.quickstep.views.RecentsView;
*/
public class FastOverviewState extends OverviewState {
+ private static final float MAX_PREVIEW_SCALE_UP = 1.3f;
+ /**
+ * Vertical transition of the task previews relative to the full container.
+ */
+ public static final float OVERVIEW_TRANSLATION_FACTOR = 0.5f;
+
private static final int STATE_FLAGS = FLAG_DISABLE_RESTORE | FLAG_DISABLE_INTERACTION
| FLAG_OVERVIEW_UI | FLAG_HIDE_BACK_BUTTON | FLAG_DISABLE_ACCESSIBILITY;
@@ -45,6 +57,23 @@ public class FastOverviewState extends OverviewState {
@Override
public float[] getOverviewScaleAndTranslationYFactor(Launcher launcher) {
- return new float[] {1f, 0.5f};
+ RecentsView recentsView = launcher.getOverviewPanel();
+ recentsView.getTaskSize(sTempRect);
+
+ return new float[] {getOverviewScale(launcher.getDeviceProfile(), sTempRect, launcher),
+ OVERVIEW_TRANSLATION_FACTOR};
+ }
+
+ public static float getOverviewScale(DeviceProfile dp, Rect taskRect, Context context) {
+ if (dp.isVerticalBarLayout()) {
+ return 1f;
+ }
+
+ Resources res = context.getResources();
+ float usedHeight = taskRect.height() + res.getDimension(R.dimen.task_thumbnail_top_margin);
+ float usedWidth = taskRect.width() + 2 * (res.getDimension(R.dimen.recents_page_spacing)
+ + res.getDimension(R.dimen.quickscrub_adjacent_visible_width));
+ return Math.min(Math.min(dp.availableHeightPx / usedHeight,
+ dp.availableWidthPx / usedWidth), MAX_PREVIEW_SCALE_UP);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
index 68773b418..6d1061990 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/LandscapeEdgeSwipeController.java
@@ -72,7 +72,7 @@ public class LandscapeEdgeSwipeController extends AbstractStateChangeTouchContro
@Override
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
- if (mFromState == NORMAL && targetState == OVERVIEW) {
+ if (mStartState == NORMAL && targetState == OVERVIEW) {
RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 3a49294c5..9169ffbc1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -83,11 +83,6 @@ public class OverviewState extends LauncherState {
DiscoveryBounce.showForOverviewIfNeeded(launcher);
}
- @Override
- public View getFinalFocus(Launcher launcher) {
- return launcher.getOverviewPanel();
- }
-
public PageAlphaProvider getWorkspacePageAlphaProvider(Launcher launcher) {
return new PageAlphaProvider(DEACCEL_2) {
@Override
@@ -100,9 +95,9 @@ public class OverviewState extends LauncherState {
@Override
public int getVisibleElements(Launcher launcher) {
if (launcher.getDeviceProfile().isVerticalBarLayout()) {
- return 0;
+ return VERTICAL_SWIPE_INDICATOR;
} else {
- return HOTSEAT_SEARCH_BOX |
+ return HOTSEAT_SEARCH_BOX | VERTICAL_SWIPE_INDICATOR |
(launcher.getAppsView().getFloatingHeaderView().hasVisibleContent()
? ALL_APPS_HEADER_EXTRA : HOTSEAT_ICONS);
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 987f952ba..3fb7cd480 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -202,7 +202,7 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
@Override
protected void onSwipeInteractionCompleted(LauncherState targetState, int logAction) {
super.onSwipeInteractionCompleted(targetState, logAction);
- if (mFromState == NORMAL && targetState == OVERVIEW) {
+ if (mStartState == NORMAL && targetState == OVERVIEW) {
RecentsModel.getInstance(mLauncher).onOverviewShown(true, TAG);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
index e43b24a6a..e3aabd6c8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -15,6 +15,7 @@
*/
package com.android.launcher3.uioverrides;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.AnimatorSetBuilder.ANIM_OVERVIEW_FADE;
@@ -24,7 +25,6 @@ import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR;
import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_TRANSLATION_Y_FACTOR;
import static com.android.quickstep.views.LauncherRecentsView.TRANSLATION_Y_FACTOR;
-import static com.android.quickstep.views.RecentsView.ADJACENT_SCALE;
import static com.android.quickstep.views.RecentsViewContainer.CONTENT_ALPHA;
import android.animation.ValueAnimator;
@@ -59,7 +59,7 @@ public class RecentsViewStateController implements StateHandler {
public void setState(LauncherState state) {
mRecentsViewContainer.setContentAlpha(state.overviewUi ? 1 : 0);
float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
- mRecentsView.setAdjacentScale(scaleTranslationYFactor[0]);
+ SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]);
mRecentsView.setTranslationYFactor(scaleTranslationYFactor[1]);
if (state.overviewUi) {
mRecentsView.updateEmptyMessage();
@@ -77,7 +77,7 @@ public class RecentsViewStateController implements StateHandler {
PropertySetter setter = config.getPropertySetter(builder);
float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
Interpolator scaleInterpolator = builder.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR);
- setter.setFloat(mRecentsView, ADJACENT_SCALE, scaleTranslationYFactor[0], scaleInterpolator);
+ setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0], scaleInterpolator);
Interpolator transYInterpolator = scaleInterpolator;
if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
transYInterpolator = Interpolators.clampToProgress(QUICK_SCRUB_START_INTERPOLATOR, 0,
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index b371677f3..d0c7b2117 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -19,6 +19,7 @@ package com.android.launcher3.uioverrides;
import static android.view.View.VISIBLE;
import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
import static com.android.launcher3.AbstractFloatingView.TYPE_HIDE_BACK_BUTTON;
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
import static com.android.launcher3.LauncherState.ALL_APPS;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.LauncherState.OVERVIEW;
@@ -78,11 +79,13 @@ public class UiFactory {
}
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
@@ -96,10 +99,6 @@ public class UiFactory {
.setBackButtonAlpha(shouldBackButtonBeHidden ? 0 : 1, true /* animate */);
}
- public static void setBackButtonAlpha(Launcher launcher, float alpha, boolean animate) {
- OverviewInteractionState.getInstance(launcher).setBackButtonAlpha(alpha,animate);
- }
-
public static void resetOverview(Launcher launcher) {
RecentsView recents = launcher.getOverviewPanel();
recents.reset();
@@ -209,7 +208,7 @@ public class UiFactory {
public static void prepareToShowOverview(Launcher launcher) {
RecentsView overview = launcher.getOverviewPanel();
if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
- overview.setAdjacentScale(1.33f);
+ SCALE_PROPERTY.set(overview, 1.33f);
}
}
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index ae0affee0..e202c574a 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -20,6 +20,8 @@ import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
+import static com.android.quickstep.TouchConsumer.INTERACTION_QUICK_SCRUB;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_ROTATION;
@@ -48,9 +50,12 @@ import com.android.launcher3.allapps.AllAppsTransitionController;
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.uioverrides.FastOverviewState;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.TouchConsumer.InteractionType;
import com.android.quickstep.util.LayoutUtils;
+import com.android.quickstep.util.TransformedRect;
import com.android.quickstep.util.RemoteAnimationProvider;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.LauncherLayoutListener;
@@ -83,7 +88,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
void onTransitionCancelled(T activity, boolean activityVisible);
- int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect);
+ int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect);
void onSwipeUpComplete(T activity);
@@ -147,8 +153,8 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
@Override
public float getTranslationYForQuickScrub(Launcher activity) {
LauncherRecentsView recentsView = activity.getOverviewPanel();
- float transYFactor = FAST_OVERVIEW.getOverviewScaleAndTranslationYFactor(activity)[1];
- return recentsView.computeTranslationYForFactor(transYFactor);
+ return recentsView.computeTranslationYForFactor(
+ FastOverviewState.OVERVIEW_TRANSLATION_FACTOR);
}
@Override
@@ -157,14 +163,18 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
- public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
- LayoutUtils.calculateLauncherTaskSize(context, dp, outRect);
+ public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect) {
+ LayoutUtils.calculateLauncherTaskSize(context, dp, outRect.rect);
+ if (interactionType == INTERACTION_QUICK_SCRUB) {
+ outRect.scale = FastOverviewState.getOverviewScale(dp, outRect.rect, context);
+ }
if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
} else {
- return dp.heightPx - outRect.bottom;
+ return dp.heightPx - outRect.rect.bottom;
}
}
@@ -204,9 +214,10 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
return new AnimationFactory() {
@Override
- public void createActivityController(long transitionLength) {
+ public void createActivityController(long transitionLength,
+ @InteractionType int interactionType) {
createActivityControllerInternal(activity, activityVisible, startState,
- transitionLength, callback);
+ transitionLength, interactionType, callback);
}
@Override
@@ -218,13 +229,16 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
private void createActivityControllerInternal(Launcher activity, boolean wasVisible,
LauncherState startState, long transitionLength,
+ @InteractionType int interactionType,
Consumer<AnimatorPlaybackController> callback) {
+ LauncherState endState = interactionType == INTERACTION_QUICK_SCRUB
+ ? FAST_OVERVIEW : OVERVIEW;
if (wasVisible) {
DeviceProfile dp = activity.getDeviceProfile();
long accuracy = 2 * Math.max(dp.widthPx, dp.heightPx);
activity.getStateManager().goToState(startState, false);
callback.accept(activity.getStateManager()
- .createAnimationToNewWorkspace(OVERVIEW, accuracy));
+ .createAnimationToNewWorkspace(endState, accuracy));
return;
}
@@ -238,7 +252,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
float scrollRange = Math.max(controller.getShiftRange(), 1);
float progressDelta = (transitionLength / scrollRange);
- float endProgress = OVERVIEW.getVerticalProgress(activity);
+ float endProgress = endState.getVerticalProgress(activity);
float startProgress = endProgress + progressDelta;
ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(
controller, ALL_APPS_PROGRESS, startProgress, endProgress);
@@ -381,14 +395,15 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
}
@Override
- public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect) {
- LayoutUtils.calculateFallbackTaskSize(context, dp, outRect);
+ public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context,
+ @InteractionType int interactionType, TransformedRect outRect) {
+ LayoutUtils.calculateFallbackTaskSize(context, dp, outRect.rect);
if (dp.isVerticalBarLayout()) {
Rect targetInsets = dp.getInsets();
int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
return dp.hotseatBarSizePx + dp.hotseatBarSidePaddingPx + hotseatInset;
} else {
- return dp.heightPx - outRect.bottom;
+ return dp.heightPx - outRect.rect.bottom;
}
}
@@ -401,7 +416,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
public AnimationFactory prepareRecentsUI(RecentsActivity activity, boolean activityVisible,
Consumer<AnimatorPlaybackController> callback) {
if (activityVisible) {
- return (transitionLength) -> { };
+ return (transitionLength, interactionType) -> { };
}
RecentsViewContainer rv = activity.getOverviewPanelContainer();
@@ -418,11 +433,12 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
rv.setContentAlpha(1);
}
createActivityController(getSwipeUpDestinationAndLength(
- activity.getDeviceProfile(), activity, new Rect()));
+ activity.getDeviceProfile(), activity, INTERACTION_NORMAL,
+ new TransformedRect()), INTERACTION_NORMAL);
}
@Override
- public void createActivityController(long transitionLength) {
+ public void createActivityController(long transitionLength, int interactionType) {
if (!isAnimatingHome) {
return;
}
@@ -543,7 +559,7 @@ public interface ActivityControlHelper<T extends BaseDraggingActivity> {
default void onRemoteAnimationReceived(RemoteAnimationTargetSet targets) { }
- void createActivityController(long transitionLength);
+ void createActivityController(long transitionLength, @InteractionType int interactionType);
default void onTransitionCancelled() { }
}
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 23738fb25..9ba332831 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -265,12 +265,10 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
if (Looper.myLooper() != Looper.getMainLooper()) {
startActivity.run();
- if (!mIsDeferredDownTarget) {
- try {
- drawWaitLock.await(LAUNCHER_DRAW_TIMEOUT_MS, TimeUnit.MILLISECONDS);
- } catch (Exception e) {
- // We have waited long enough for launcher to draw
- }
+ try {
+ drawWaitLock.await(LAUNCHER_DRAW_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ // We have waited long enough for launcher to draw
}
} else {
// We should almost always get touch-town on background thread. This is an edge case
@@ -326,10 +324,10 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
mPassedInitialSlop = true;
}
- notifyGestureStarted();
if (mInteractionHandler != null) {
mInteractionHandler.updateInteractionType(interactionType);
}
+ notifyGestureStarted();
}
@Override
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index 7b2932383..41a45501d 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -21,6 +21,7 @@ import static android.content.Intent.ACTION_PACKAGE_REMOVED;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
+import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
import static com.android.systemui.shared.system.ActivityManagerWrapper
.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
import static com.android.systemui.shared.system.PackageManagerWrapper
@@ -59,6 +60,7 @@ import com.android.quickstep.ActivityControlHelper.AnimationFactory;
import com.android.quickstep.ActivityControlHelper.FallbackActivityControllerHelper;
import com.android.quickstep.ActivityControlHelper.LauncherActivityControllerHelper;
import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.TransformedRect;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -282,7 +284,7 @@ public class OverviewCommandHelper {
});
factory.onRemoteAnimationReceived(null);
if (wasVisible) {
- factory.createActivityController(RECENTS_LAUNCH_DURATION);
+ factory.createActivityController(RECENTS_LAUNCH_DURATION, INTERACTION_NORMAL);
}
mActivity = activity;
mRecentsView = mActivity.getOverviewPanel();
@@ -342,9 +344,9 @@ public class OverviewCommandHelper {
loc[0] + rootView.getWidth(), loc[1] + rootView.getHeight());
clipHelper.updateSource(homeBounds, runningTaskTarget);
- Rect targetRect = new Rect();
- mHelper.getSwipeUpDestinationAndLength(
- mActivity.getDeviceProfile(), mActivity, targetRect);
+ TransformedRect targetRect = new TransformedRect();
+ mHelper.getSwipeUpDestinationAndLength(mActivity.getDeviceProfile(), mActivity,
+ INTERACTION_NORMAL, targetRect);
clipHelper.updateTargetRect(targetRect);
clipHelper.prepareAnimation(false /* isOpening */);
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index d60574676..922a7ff29 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -91,6 +91,7 @@ public class OverviewInteractionState {
// These are updated on the background thread
private ISystemUiProxy mISystemUiProxy;
private boolean mSwipeUpEnabled = true;
+ private float mBackButtonAlpha = 1;
private Runnable mOnSwipeUpSettingChangedListener;
@@ -117,7 +118,14 @@ public class OverviewInteractionState {
return mSwipeUpEnabled;
}
+ 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();
@@ -128,6 +136,9 @@ public class OverviewInteractionState {
}
private boolean handleUiMessage(Message msg) {
+ 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;
}
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index abb479dea..8e1a3d5d8 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -49,7 +49,7 @@ public class QuickScrubController implements OnAlarmListener {
* Snap to a new page when crossing these thresholds. The first and last auto-advance.
*/
private static final float[] QUICK_SCRUB_THRESHOLDS = new float[] {
- 0.04f, 0.27f, 0.50f, 0.73f, 0.96f
+ 0.05f, 0.20f, 0.35f, 0.50f, 0.65f, 0.80f, 0.95f
};
private static final String TAG = "QuickScrubController";
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index b472d611a..3adb290bb 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -176,8 +176,8 @@ public class RecentsActivity extends BaseDraggingActivity {
}
@Override
- public ActivityOptions getActivityLaunchOptions(final View v, boolean useDefaultLaunchOptions) {
- if (useDefaultLaunchOptions || !(v instanceof TaskView)) {
+ public ActivityOptions getActivityLaunchOptions(final View v) {
+ if (!(v instanceof TaskView)) {
return null;
}
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index 84b217648..191c237f6 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -65,6 +65,7 @@ import com.android.quickstep.ActivityControlHelper.AnimationFactory;
import com.android.quickstep.ActivityControlHelper.LayoutListener;
import com.android.quickstep.TouchConsumer.InteractionType;
import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.TransformedRect;
import com.android.quickstep.util.RemoteAnimationTargetSet;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
@@ -181,7 +182,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private LayoutListener mLayoutListener;
private RecentsView mRecentsView;
private QuickScrubController mQuickScrubController;
- private AnimationFactory mAnimationFactory = (t) -> { };
+ private AnimationFactory mAnimationFactory = (t, i) -> { };
private Runnable mLauncherDrawnCallback;
@@ -272,8 +273,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
| STATE_SCALED_CONTROLLER_APP,
this::notifyTransitionCancelled);
- mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START,
- this::onQuickScrubStart);
+ mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
+ | STATE_APP_CONTROLLER_RECEIVED, this::onQuickScrubStart);
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
| STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_CURRENT_TASK_FINISHED
@@ -302,9 +303,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private void initTransitionEndpoints(DeviceProfile dp) {
mDp = dp;
- Rect tempRect = new Rect();
+ TransformedRect tempRect = new TransformedRect();
mTransitionDragLength = mActivityControlHelper
- .getSwipeUpDestinationAndLength(dp, mContext, tempRect);
+ .getSwipeUpDestinationAndLength(dp, mContext, mInteractionType, tempRect);
mClipAnimationHelper.updateTargetRect(tempRect);
}
@@ -488,7 +489,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
*/
public void buildAnimationController() {
initTransitionEndpoints(mActivity.getDeviceProfile());
- mAnimationFactory.createActivityController(mTransitionDragLength);
+ mAnimationFactory.createActivityController(mTransitionDragLength, mInteractionType);
}
private void onAnimatorPlaybackControllerCreated(AnimatorPlaybackController anim) {
@@ -793,13 +794,16 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
int scrollForFirstTask = mRecentsView.getScrollForPage(0);
int scrollForSecondTask = mRecentsView.getChildCount() > 1
? mRecentsView.getScrollForPage(1) : scrollForFirstTask;
- int offsetFromFirstTask = scrollForFirstTask - scrollForSecondTask;
- final float interpolation;
- if (mRecentsView.getWidth() == 0) {
- interpolation = scrollForSecondTask == scrollForFirstTask ? 0 : 1;
- } else {
- interpolation = (float) offsetFromFirstTask / (mRecentsView.getWidth() / 2);
- }
+ float offsetFromFirstTask = scrollForFirstTask - scrollForSecondTask;
+
+ TransformedRect tempRect = new TransformedRect();
+ mActivityControlHelper
+ .getSwipeUpDestinationAndLength(mDp, mContext, mInteractionType, tempRect);
+ float distanceToReachEdge = mDp.widthPx / 2 + tempRect.rect.width() / 2 +
+ mContext.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
+ float interpolation = Math.min(1,
+ Math.abs(offsetFromFirstTask) / distanceToReachEdge);
+
mClipAnimationHelper.offsetTarget(
firstTask.getCurveScaleForInterpolation(interpolation), offsetFromFirstTask,
mActivityControlHelper.getTranslationYForQuickScrub(mActivity),
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 9e2de3395..c5d74c7d9 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.Canvas;
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 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity> {
// 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/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
index 8c7f104a6..a654482f9 100644
--- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -80,6 +80,7 @@ public class ClipAnimationHelper {
private final RectF mTmpRectF = new RectF();
private float mTargetScale = 1f;
+ private float mOffsetScale = 1f;
private Interpolator mInterpolator = LINEAR;
// We translate y slightly faster than the rest of the animation for quick scrub.
private Interpolator mOffsetYInterpolator = LINEAR;
@@ -106,11 +107,13 @@ public class ClipAnimationHelper {
updateSourceStack(target);
}
- public void updateTargetRect(Rect targetRect) {
+ public void updateTargetRect(TransformedRect targetRect) {
+ mOffsetScale = targetRect.scale;
mSourceRect.set(mSourceInsets.left, mSourceInsets.top,
mSourceStackBounds.width() - mSourceInsets.right,
mSourceStackBounds.height() - mSourceInsets.bottom);
- mTargetRect.set(targetRect);
+ mTargetRect.set(targetRect.rect);
+ Utilities.scaleRectFAboutCenter(mTargetRect, targetRect.scale);
mTargetRect.offset(mHomeStackBounds.left - mSourceStackBounds.left,
mHomeStackBounds.top - mSourceStackBounds.top);
@@ -145,7 +148,8 @@ public class ClipAnimationHelper {
synchronized (mTargetOffset) {
// Stay lined up with the center of the target, since it moves for quick scrub.
- currentRect.offset(mTargetOffset.x * progress, mTargetOffset.y * offsetYProgress);
+ currentRect.offset(mTargetOffset.x * mOffsetScale * progress,
+ mTargetOffset.y * offsetYProgress);
}
mClipRect.left = (int) (mSourceWindowClipInsets.left * progress);
@@ -219,16 +223,20 @@ public class ClipAnimationHelper {
mSourceInsets.set(activity.getDeviceProfile().getInsets());
}
- Rect targetRect = new Rect();
- dl.getDescendantRectRelativeToSelf(ttv, targetRect);
+ TransformedRect targetRect = new TransformedRect();
+ dl.getDescendantRectRelativeToSelf(ttv, targetRect.rect);
updateTargetRect(targetRect);
- // Transform the clip relative to the target rect.
- float scale = mTargetRect.width() / mSourceRect.width();
- mSourceWindowClipInsets.left = mSourceWindowClipInsets.left * scale;
- mSourceWindowClipInsets.top = mSourceWindowClipInsets.top * scale;
- mSourceWindowClipInsets.right = mSourceWindowClipInsets.right * scale;
- mSourceWindowClipInsets.bottom = mSourceWindowClipInsets.bottom * scale;
+ if (target == null) {
+ // Transform the clip relative to the target rect. Only do this in the case where we
+ // aren't applying the insets to the app windows (where the clip should be in target app
+ // space)
+ float scale = mTargetRect.width() / mSourceRect.width();
+ mSourceWindowClipInsets.left = mSourceWindowClipInsets.left * scale;
+ mSourceWindowClipInsets.top = mSourceWindowClipInsets.top * scale;
+ mSourceWindowClipInsets.right = mSourceWindowClipInsets.right * scale;
+ mSourceWindowClipInsets.bottom = mSourceWindowClipInsets.bottom * scale;
+ }
}
private void updateStackBoundsToMultiWindowTaskSize(BaseDraggingActivity activity) {
diff --git a/quickstep/src/com/android/quickstep/util/TransformedRect.java b/quickstep/src/com/android/quickstep/util/TransformedRect.java
new file mode 100644
index 000000000..79f11e405
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/util/TransformedRect.java
@@ -0,0 +1,32 @@
+/*
+ * 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.quickstep.util;
+
+import android.graphics.Rect;
+
+/**
+ * A wrapper around {@link Rect} with additional transformation properties
+ */
+public class TransformedRect {
+
+ public final Rect rect = new Rect();
+ public float scale = 1;
+
+ public void set(TransformedRect transformedRect) {
+ rect.set(transformedRect.rect);
+ scale = transformedRect.scale;
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
index d5c43a0f5..25e3dc6c1 100644
--- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java
+++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java
@@ -19,6 +19,7 @@ package com.android.quickstep.views;
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;
@@ -43,4 +44,12 @@ public class ClearAllButton extends Button {
}
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/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 950f7fb99..5aca4f326 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -35,6 +35,9 @@ import android.view.ViewDebug;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
+import com.android.launcher3.R;
+import com.android.launcher3.anim.Interpolators;
+import com.android.launcher3.views.ScrimView;
import com.android.quickstep.OverviewInteractionState;
import com.android.quickstep.util.ClipAnimationHelper;
import com.android.quickstep.util.LayoutUtils;
@@ -136,6 +139,12 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
}
anim.play(ObjectAnimator.ofFloat(
mActivity.getAllAppsController(), ALL_APPS_PROGRESS, allAppsProgressOffscreen));
+
+ ObjectAnimator dragHandleAnim = ObjectAnimator.ofInt(
+ mActivity.findViewById(R.id.scrim_view), ScrimView.DRAG_HANDLE_ALPHA, 0);
+ dragHandleAnim.setInterpolator(Interpolators.ACCEL_2);
+ anim.play(dragHandleAnim);
+
return anim;
}
@@ -150,7 +159,7 @@ public class LauncherRecentsView extends RecentsView<Launcher> {
mActivity.getStateManager().goToState(NORMAL, false /* animate */);
} else {
LauncherState state = mActivity.getStateManager().getState();
- mActivity.getAllAppsController().setProgress(state.getVerticalProgress(mActivity));
+ mActivity.getAllAppsController().setState(state);
}
super.onTaskLaunched(success);
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index a6da89f20..dee15d0d7 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -41,18 +41,21 @@ import android.graphics.drawable.Drawable;
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;
import android.util.ArraySet;
import android.util.AttributeSet;
-import android.util.FloatProperty;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.ListView;
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
@@ -96,19 +99,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private final Rect mTempRect = new Rect();
- public static final FloatProperty<RecentsView> ADJACENT_SCALE =
- new FloatProperty<RecentsView>("adjacentScale") {
- @Override
- public void setValue(RecentsView recentsView, float v) {
- recentsView.setAdjacentScale(v);
- }
-
- @Override
- public Float get(RecentsView recentsView) {
- return recentsView.mAdjacentScale;
- }
- };
- public static final boolean FLIP_RECENTS = true;
private static final int DISMISS_TASK_DURATION = 300;
// The threshold at which we update the SystemUI flags when animating from the task into the app
private static final float UPDATE_SYSUI_FLAGS_THRESHOLD = 0.6f;
@@ -119,6 +109,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private final QuickScrubController mQuickScrubController;
private final float mFastFlingVelocity;
private final RecentsModel mModel;
+ private final int mTaskTopMargin;
private final ScrollState mScrollState = new ScrollState();
// Keeps track of the previously known visible tasks for purposes of loading/unloading task data
@@ -229,8 +220,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
@ViewDebug.ExportedProperty(category = "launcher")
private float mContentAlpha = 1;
- @ViewDebug.ExportedProperty(category = "launcher")
- private float mAdjacentScale = 1;
// Keeps track of task views whose visual state should not be reset
private ArraySet<TaskView> mIgnoreResetTaskViews = new ArraySet<>();
@@ -266,11 +255,10 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
mQuickScrubController = new QuickScrubController(mActivity, this);
mModel = RecentsModel.getInstance(context);
- mIsRtl = Utilities.isRtl(getResources());
- if (FLIP_RECENTS) {
- mIsRtl = !mIsRtl;
- }
+ mIsRtl = !Utilities.isRtl(getResources());
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+ mTaskTopMargin = getResources()
+ .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
mEmptyIcon.setCallback(this);
@@ -283,6 +271,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
.getDimensionPixelSize(R.dimen.recents_empty_message_text_padding);
setWillNotDraw(false);
updateEmptyMessage();
+ setFocusable(false);
}
public boolean isRtl() {
@@ -518,8 +507,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
DeviceProfile dp = mActivity.getDeviceProfile();
getTaskSize(dp, mTempRect);
- mTempRect.top -= getResources()
- .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
+ mTempRect.top -= mTaskTopMargin;
setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
dp.availableWidthPx + mInsets.left - mTempRect.right,
dp.availableHeightPx + mInsets.top - mTempRect.bottom);
@@ -581,6 +569,11 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
* 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);
@@ -927,21 +920,16 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
set.play(anim);
}
- private void snapToPageRelative(int delta) {
+ private boolean snapToPageRelative(int delta, boolean cycle) {
if (getPageCount() == 0) {
- return;
+ return false;
}
- snapToPage((getNextPage() + getPageCount() + delta) % getPageCount());
- }
-
- @Override
- public void onVisibilityAggregated(boolean isVisible) {
- super.onVisibilityAggregated(isVisible);
- if (isVisible && !isFocused()) {
- // Having focus, even in touch mode, keeps us from losing [Alt+]Tab by preventing
- // switching to keyboard mode.
- requestFocus();
+ final int newPageUnbound = getNextPage() + delta;
+ if (!cycle && (newPageUnbound < 0 || newPageUnbound >= getChildCount())) {
+ return false;
}
+ snapToPage((newPageUnbound + getPageCount()) % getPageCount());
+ return true;
}
private void runDismissAnimation(PendingAnimation pendingAnim) {
@@ -967,14 +955,12 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (event.getAction() == KeyEvent.ACTION_DOWN) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_TAB:
- snapToPageRelative(event.isShiftPressed() ? -1 : 1);
- return true;
+ return snapToPageRelative(event.isShiftPressed() ? -1 : 1,
+ event.isAltPressed() /* cycle */);
case KeyEvent.KEYCODE_DPAD_RIGHT:
- snapToPageRelative(mIsRtl ? -1 : 1);
- return true;
+ return snapToPageRelative(mIsRtl ? -1 : 1, false /* cycle */);
case KeyEvent.KEYCODE_DPAD_LEFT:
- snapToPageRelative(mIsRtl ? 1 : -1);
- return true;
+ return snapToPageRelative(mIsRtl ? 1 : -1, false /* cycle */);
case KeyEvent.KEYCODE_DEL:
case KeyEvent.KEYCODE_FORWARD_DEL:
dismissTask((TaskView) getChildAt(getNextPage()), true /*animateTaskView*/,
@@ -992,8 +978,22 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
return super.dispatchKeyEvent(event);
}
- public void snapToTaskAfterNext() {
- snapToPageRelative(1);
+ @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:
+ case FOCUS_RIGHT:
+ case FOCUS_LEFT:
+ setCurrentPage(getChildCount() - 1);
+ break;
+ }
+ }
}
public float getContentAlpha() {
@@ -1016,36 +1016,7 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
updateClearAllButtonAlpha();
}
- public void setAdjacentScale(float adjacentScale) {
- if (mAdjacentScale == adjacentScale) {
- return;
- }
- mAdjacentScale = adjacentScale;
- TaskView currTask = getPageAt(mCurrentPage);
- if (currTask == null) {
- return;
- }
- currTask.setZoomScale(mAdjacentScale);
-
- if (mCurrentPage - 1 >= 0) {
- TaskView adjacentTask = getPageAt(mCurrentPage - 1);
- float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
- mAdjacentScale, 0);
- adjacentTask.setZoomScale(scaleAndTranslation[0]);
- adjacentTask.setTranslationX(-scaleAndTranslation[1]);
- adjacentTask.setTranslationY(scaleAndTranslation[2]);
- }
- if (mCurrentPage + 1 < getChildCount()) {
- TaskView adjacentTask = getPageAt(mCurrentPage + 1);
- float[] scaleAndTranslation = getAdjacentScaleAndTranslation(currTask, adjacentTask,
- mAdjacentScale, 0);
- adjacentTask.setZoomScale(scaleAndTranslation[0]);
- adjacentTask.setTranslationX(scaleAndTranslation[1]);
- adjacentTask.setTranslationY(scaleAndTranslation[2]);
- }
- }
-
- private float[] getAdjacentScaleAndTranslation(TaskView currTask, TaskView adjacentTask,
+ private float[] getAdjacentScaleAndTranslation(TaskView currTask,
float currTaskToScale, float currTaskToTranslationY) {
float displacement = currTask.getWidth() * (currTaskToScale - currTask.getCurveScale());
sTempFloatArray[0] = currTaskToScale;
@@ -1058,7 +1029,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
public void onViewAdded(View child) {
super.onViewAdded(child);
child.setAlpha(mContentAlpha);
- setAdjacentScale(mAdjacentScale);
onChildViewsChanged();
}
@@ -1084,6 +1054,12 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
updateEmptyStateUi(changed);
+
+ // Set the pivot points to match the task preview center
+ setPivotY(((mInsets.top + getPaddingTop() + mTaskTopMargin)
+ + (getHeight() - mInsets.bottom - getPaddingBottom())) / 2);
+ setPivotX(((mInsets.left + getPaddingLeft())
+ + (getWidth() - mInsets.right - getPaddingRight())) / 2);
}
private void updateEmptyStateUi(boolean sizeChanged) {
@@ -1154,14 +1130,14 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
if (taskIndex - 1 >= 0) {
TaskView adjacentTask = getPageAt(taskIndex - 1);
float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
- adjacentTask, toScale, toTranslationY);
+ toScale, toTranslationY);
scaleAndTranslation[1] = -scaleAndTranslation[1];
anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
}
if (taskIndex + 1 < getPageCount()) {
TaskView adjacentTask = getPageAt(taskIndex + 1);
float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
- adjacentTask, toScale, toTranslationY);
+ toScale, toTranslationY);
anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
}
} else {
@@ -1300,25 +1276,59 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private void onChildViewsChanged() {
final int childCount = getChildCount();
mClearAllButton.setVisibility(childCount == 0 ? INVISIBLE : VISIBLE);
+ setFocusable(childCount != 0);
}
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);
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ outChildren.add(getChildAt(i));
}
}
@Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+
+ final AccessibilityNodeInfo.CollectionInfo
+ collectionInfo = AccessibilityNodeInfo.CollectionInfo.obtain(
+ 1, getChildCount(), false,
+ AccessibilityNodeInfo.CollectionInfo.SELECTION_MODE_NONE);
+ info.setCollectionInfo(collectionInfo);
+ }
+
+ @Override
+ public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+ super.onInitializeAccessibilityEvent(event);
+
+ if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+ final int visiblePageNumber = getChildCount() - getCurrentPage() - 1;
+ event.setFromIndex(visiblePageNumber);
+ event.setToIndex(visiblePageNumber);
+ event.setItemCount(getChildCount());
+ }
+ }
+
+ @Override
+ public CharSequence getAccessibilityClassName() {
+ // To hear position-in-list related feedback from Talkback.
+ return ListView.class.getName();
+ }
+
+ @Override
protected boolean isPageOrderFlipped() {
- return FLIP_RECENTS;
+ return true;
+ }
+
+ 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 429432b2f..31c8b6448 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewContainer.java
@@ -23,12 +23,14 @@ import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
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") {
@@ -64,14 +66,18 @@ public class RecentsViewContainer extends InsettableFrameLayout {
});
mRecentsView = findViewById(R.id.overview_panel);
- final InsettableFrameLayout.LayoutParams params =
- (InsettableFrameLayout.LayoutParams) mClearAllButton.getLayoutParams();
- params.gravity = Gravity.TOP | (RecentsView.FLIP_RECENTS ? Gravity.START : Gravity.END);
- mClearAllButton.setLayoutParams(params);
mClearAllButton.forceHasOverlappingRendering(false);
mRecentsView.setClearAllButton(mClearAllButton);
mClearAllButton.setRecentsView(mRecentsView);
+
+ if (mRecentsView.isRtl()) {
+ mClearAllButton.setNextFocusRightId(mRecentsView.getId());
+ mRecentsView.setNextFocusLeftId(mClearAllButton.getId());
+ } else {
+ mClearAllButton.setNextFocusLeftId(mRecentsView.getId());
+ mRecentsView.setNextFocusRightId(mClearAllButton.getId());
+ }
}
@Override
@@ -104,4 +110,18 @@ public class RecentsViewContainer extends InsettableFrameLayout {
mRecentsView.setContentAlpha(alpha);
setVisibility(alpha > 0 ? VISIBLE : GONE);
}
+
+ @Override
+ public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
+ if (mRecentsView.getChildCount() > 0) {
+ // Carousel is first in tab order.
+ views.add(mRecentsView);
+ views.add(mClearAllButton);
+ }
+ }
+
+ public boolean requestFocus(int direction, Rect previouslyFocusedRect) {
+ return mRecentsView.requestFocus(direction, previouslyFocusedRect) ||
+ super.requestFocus(direction, previouslyFocusedRect);
+ }
} \ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 24afd4868..aca8351a0 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -154,15 +154,6 @@ public class ShelfScrimView extends ScrimView {
}
@Override
- protected void updateDragHandleAlpha() {
- if (mDrawingFlatColor) {
- super.updateDragHandleAlpha();
- } else if (mDragHandle != null) {
- mDragHandle.setAlpha(255);
- }
- }
-
- @Override
protected void onDraw(Canvas canvas) {
float translate = drawBackground(canvas);
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 82aa45a18..5413a1319 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 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
}
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()));
@@ -168,7 +169,7 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
final ActivityOptions opts;
if (animate) {
opts = BaseDraggingActivity.fromContext(getContext())
- .getActivityLaunchOptions(this, false);
+ .getActivityLaunchOptions(this);
} else {
opts = ActivityOptions.makeCustomAnimation(getContext(), 0, 0);
}
@@ -318,12 +319,21 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
context.getText(menuOption.labelResId)));
}
}
+
+ final RecentsView recentsView = getRecentsView();
+ recentsView.addTaskAccessibilityActionsExtra(info);
+
+ final AccessibilityNodeInfo.CollectionItemInfo itemInfo =
+ AccessibilityNodeInfo.CollectionItemInfo.obtain(
+ 0, 1, recentsView.getChildCount() - recentsView.indexOfChild(this) - 1, 1,
+ false);
+ info.setCollectionItemInfo(itemInfo);
}
@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 +349,15 @@ public class TaskView extends FrameLayout implements TaskCallbacks, PageCallback
}
}
+ 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) {