summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--proguard.flags5
-rw-r--r--quickstep/res/values/override.xml20
-rw-r--r--quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java (renamed from quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java)161
-rw-r--r--quickstep/src/com/android/launcher3/uioverrides/UiFactory.java28
-rw-r--r--res/values/config.xml3
-rw-r--r--src/com/android/launcher3/Launcher.java38
-rw-r--r--src/com/android/launcher3/LauncherAppTransitionManager.java64
-rw-r--r--src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java6
8 files changed, 204 insertions, 121 deletions
diff --git a/proguard.flags b/proguard.flags
index 987fb6f12..b8cade572 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -97,6 +97,11 @@
# support jar.
-keep class android.support.v7.widget.RecyclerView { *; }
+# LauncherAppTransitionManager
+-keep class com.android.launcher3.LauncherAppTransitionManagerImpl {
+ public <init>(...);
+}
+
-keep interface com.android.launcher3.userevent.nano.LauncherLogProto.** {
*;
}
diff --git a/quickstep/res/values/override.xml b/quickstep/res/values/override.xml
new file mode 100644
index 000000000..ba99d81c0
--- /dev/null
+++ b/quickstep/res/values/override.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="app_transition_manager_class" translatable="false">com.android.launcher3.LauncherAppTransitionManagerImpl</string>
+</resources>
+
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index 47179c5a0..9968ca72c 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -26,6 +26,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Matrix;
@@ -55,11 +57,15 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
/**
* Manages the opening and closing app transitions from Launcher.
*/
-public class LauncherAppTransitionManager {
+public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManager {
private static final String TAG = "LauncherTransition";
private static final int REFRESH_RATE_MS = 16;
+ private static final String CONTROL_REMOTE_APP_TRANSITION_PERMISSION =
+ "android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS";
+
+ private static final int LAUNCHER_RESUME_START_DELAY = 150;
private static final int CLOSING_TRANSITION_DURATION_MS = 350;
// Progress = 0: All apps is fully pulled up, Progress = 1: All apps is fully pulled down.
@@ -76,60 +82,79 @@ public class LauncherAppTransitionManager {
private ImageView mFloatingView;
private boolean mIsRtl;
- public LauncherAppTransitionManager(Launcher launcher) {
- mLauncher = launcher;
- mDragLayer = launcher.getDragLayer();
- mDeviceProfile = launcher.getDeviceProfile();
+ private Animator mCurrentAnimator;
+
+ public LauncherAppTransitionManagerImpl(Context context) {
+ mLauncher = Launcher.getLauncher(context);
+ mDragLayer = mLauncher.getDragLayer();
+ mDeviceProfile = mLauncher.getDeviceProfile();
- mIsRtl = Utilities.isRtl(launcher.getResources());
+ mIsRtl = Utilities.isRtl(mLauncher.getResources());
- Resources res = launcher.getResources();
+ Resources res = mLauncher.getResources();
mContentTransY = res.getDimensionPixelSize(R.dimen.content_trans_y);
mWorkspaceTransY = res.getDimensionPixelSize(R.dimen.workspace_trans_y);
}
+ private void setCurrentAnimator(Animator animator) {
+ if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+ mCurrentAnimator.cancel();
+ }
+ mCurrentAnimator = animator;
+ }
+
/**
* @return A Bundle with remote animations that controls how the window of the opening
* targets are displayed.
*/
- public Bundle getActivityLauncherOptions(View v) {
- RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
- @Override
- public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
- Runnable finishedCallback) {
- // Post at front of queue ignoring sync barriers to make sure it gets processed
- // before the next frame.
- postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
- mAnimator = new AnimatorSet();
- mAnimator.play(getLauncherAnimators(v));
- mAnimator.play(getWindowAnimators(v, targets));
- mAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // Reset launcher to normal state
- v.setVisibility(View.VISIBLE);
- ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
-
- mDragLayer.setAlpha(1f);
- mDragLayer.setTranslationY(0f);
-
- View appsView = mLauncher.getAppsView();
- appsView.setAlpha(1f);
- appsView.setTranslationY(0f);
+ @Override
+ public Bundle getActivityLaunchOptions(Launcher launcher, View v) {
+ if (hasControlRemoteAppTransitionPermission()) {
+ try {
+ RemoteAnimationRunnerCompat runner = new LauncherAnimationRunner(mLauncher) {
+ @Override
+ public void onAnimationStart(RemoteAnimationTargetCompat[] targets,
+ Runnable finishedCallback) {
+ // Post at front of queue ignoring sync barriers to make sure it gets
+ // processed before the next frame.
+ postAtFrontOfQueueAsynchronously(v.getHandler(), () -> {
+ mAnimator = new AnimatorSet();
+ setCurrentAnimator(mAnimator);
+ mAnimator.play(getLauncherAnimators(v));
+ mAnimator.play(getWindowAnimators(v, targets));
+ mAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Reset launcher to normal state
+ v.setVisibility(View.VISIBLE);
+ ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
+
+ mDragLayer.setAlpha(1f);
+ mDragLayer.setTranslationY(0f);
+
+ View appsView = mLauncher.getAppsView();
+ appsView.setAlpha(1f);
+ appsView.setTranslationY(0f);
+
+ finishedCallback.run();
+ }
+ });
+ mAnimator.start();
+ // Because t=0 has the app icon in its original spot, we can skip the
+ // first frame and have the same movement one frame earlier.
+ mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
+ });
+ }
+ };
- finishedCallback.run();
- }
- });
- mAnimator.start();
- // Because t=0 has the app icon in its original spot, we can skip the first
- // frame and have the same movement one frame earlier.
- mAnimator.setCurrentPlayTime(REFRESH_RATE_MS);
- });
+ return ActivityOptionsCompat.makeRemoteAnimation(
+ new RemoteAnimationAdapterCompat(runner, 500, 380)).toBundle();
+ } catch (NoClassDefFoundError e) {
+ // Gracefully fall back to default launch options if the user's platform doesn't
+ // have the latest changes.
}
- };
-
- return ActivityOptionsCompat.makeRemoteAnimation(
- new RemoteAnimationAdapterCompat(runner, 500, 380)).toBundle();
+ }
+ return getDefaultActivityLaunchOptions(launcher, v);
}
/**
@@ -149,7 +174,7 @@ public class LauncherAppTransitionManager {
* Else: Animate the content so that it moves downwards and fades out.
*/
private AnimatorSet getLauncherContentAnimator(boolean show) {
- AnimatorSet hideLauncher = new AnimatorSet();
+ AnimatorSet launcherAnimator = new AnimatorSet();
float[] alphas = show
? new float[] {0, 1}
@@ -161,6 +186,9 @@ public class LauncherAppTransitionManager {
if (mLauncher.isInState(LauncherState.ALL_APPS) && !mDeviceProfile.isVerticalBarLayout()) {
// All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
View appsView = mLauncher.getAppsView();
+ appsView.setAlpha(alphas[0]);
+ appsView.setTranslationY(trans[0]);
+
ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas);
alpha.setDuration(217);
alpha.setInterpolator(Interpolators.LINEAR);
@@ -168,9 +196,12 @@ public class LauncherAppTransitionManager {
transY.setInterpolator(Interpolators.AGGRESSIVE_EASE);
transY.setDuration(350);
- hideLauncher.play(alpha);
- hideLauncher.play(transY);
+ launcherAnimator.play(alpha);
+ launcherAnimator.play(transY);
} else {
+ mDragLayer.setAlpha(alphas[0]);
+ mDragLayer.setTranslationY(trans[0]);
+
ObjectAnimator dragLayerAlpha = ObjectAnimator.ofFloat(mDragLayer, View.ALPHA, alphas);
dragLayerAlpha.setDuration(217);
dragLayerAlpha.setInterpolator(Interpolators.LINEAR);
@@ -179,10 +210,10 @@ public class LauncherAppTransitionManager {
dragLayerTransY.setInterpolator(Interpolators.AGGRESSIVE_EASE);
dragLayerTransY.setDuration(350);
- hideLauncher.play(dragLayerAlpha);
- hideLauncher.play(dragLayerTransY);
+ launcherAnimator.play(dragLayerAlpha);
+ launcherAnimator.play(dragLayerTransY);
}
- return hideLauncher;
+ return launcherAnimator;
}
/**
@@ -361,15 +392,22 @@ public class LauncherAppTransitionManager {
/**
* Registers remote animations used when closing apps to home screen.
*/
+ @Override
public void registerRemoteAnimations() {
- RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
- definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
- new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(), 0,
- CLOSING_TRANSITION_DURATION_MS));
+ if (hasControlRemoteAppTransitionPermission()) {
+ try {
+ RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
+ definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
+ new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(), 0,
+ CLOSING_TRANSITION_DURATION_MS));
// TODO: App controlled transition for unlock to home TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
- new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
+ new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
+ } catch (NoClassDefFoundError e) {
+ // Gracefully fall back if the user's platform doesn't have the latest changes
+ }
+ }
}
/**
@@ -385,11 +423,13 @@ public class LauncherAppTransitionManager {
postAtFrontOfQueueAsynchronously(handler, () -> {
// We use a separate transition for Overview mode.
if (mLauncher.isInState(LauncherState.OVERVIEW)) {
+ setCurrentAnimator(null);
finishedCallback.run();
return;
}
mAnimator = new AnimatorSet();
+ setCurrentAnimator(mAnimator);
mAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -465,7 +505,9 @@ public class LauncherAppTransitionManager {
private AnimatorSet getLauncherResumeAnimation() {
if (mLauncher.isInState(LauncherState.ALL_APPS)
|| mLauncher.getDeviceProfile().isVerticalBarLayout()) {
- return getLauncherContentAnimator(true /* show */);
+ AnimatorSet contentAnimator = getLauncherContentAnimator(true /* show */);
+ contentAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
+ return contentAnimator;
} else {
AnimatorSet workspaceAnimator = new AnimatorSet();
mLauncher.getWorkspace().setTranslationY(mWorkspaceTransY);
@@ -474,7 +516,7 @@ public class LauncherAppTransitionManager {
View.TRANSLATION_Y, mWorkspaceTransY, 0));
workspaceAnimator.play(ObjectAnimator.ofFloat(mLauncher.getWorkspace(), View.ALPHA,
0, 1f));
- workspaceAnimator.setStartDelay(150);
+ workspaceAnimator.setStartDelay(LAUNCHER_RESUME_START_DELAY);
workspaceAnimator.setDuration(333);
workspaceAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -489,7 +531,7 @@ public class LauncherAppTransitionManager {
Animator allAppsSlideIn =
ObjectAnimator.ofFloat(allAppsController, ALL_APPS_PROGRESS, startY, slideEnd);
- allAppsSlideIn.setStartDelay(150);
+ allAppsSlideIn.setStartDelay(LAUNCHER_RESUME_START_DELAY);
allAppsSlideIn.setDuration(317);
allAppsSlideIn.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
@@ -505,6 +547,11 @@ public class LauncherAppTransitionManager {
}
}
+ private boolean hasControlRemoteAppTransitionPermission() {
+ return mLauncher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* Helper method that allows us to get interpolated values for embedded
* animations with a delay and/or different duration.
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index a004dacde..b4f40c215 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -25,7 +25,6 @@ import android.view.View;
import android.view.View.AccessibilityDelegate;
import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppTransitionManager;
import com.android.launcher3.LauncherStateManager.StateHandler;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.BitmapRenderer;
@@ -84,31 +83,4 @@ public class UiFactory {
RecentsView recents = launcher.getOverviewPanel();
recents.reset();
}
-
- private static boolean hasControlRemoteAppTransitionPermission(Launcher launcher) {
- return launcher.checkSelfPermission(CONTROL_REMOTE_APP_TRANSITION_PERMISSION)
- == PackageManager.PERMISSION_GRANTED;
- }
-
- public static Bundle getActivityLaunchOptions(Launcher launcher, View v) {
- if (hasControlRemoteAppTransitionPermission(launcher)) {
- try {
- return new LauncherAppTransitionManager(launcher).getActivityLauncherOptions(v);
- } catch (NoClassDefFoundError e) {
- // Gracefully fall back to default launch options if the user's platform doesn't
- // have the latest changes.
- }
- }
- return launcher.getDefaultActivityLaunchOptions(v);
- }
-
- public static void registerRemoteAnimations(Launcher launcher) {
- if (hasControlRemoteAppTransitionPermission(launcher)) {
- try {
- new LauncherAppTransitionManager(launcher).registerRemoteAnimations();
- } catch (NoClassDefFoundError e) {
- // Gracefully fall back if the user's platform doesn't have the latest changes
- }
- }
- }
}
diff --git a/res/values/config.xml b/res/values/config.xml
index 209620038..3dddac22d 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -92,6 +92,9 @@
<!-- Name of a user event dispatcher class. -->
<string name="user_event_dispatcher_class" translatable="false"></string>
+ <!-- Name of an app transition manager class. -->
+ <string name="app_transition_manager_class" translatable="false"></string>
+
<!-- Name of a color extraction implementation class. -->
<string name="color_extraction_impl_class" translatable="false"></string>
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 5db0a3b72..a91907d44 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -214,6 +214,8 @@ public class Launcher extends BaseActivity
private static final int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
@Thunk static final int NEW_APPS_ANIMATION_DELAY = 500;
+ private LauncherAppTransitionManager mAppTransitionManager;
+
@Thunk Workspace mWorkspace;
private View mLauncherView;
@Thunk DragLayer mDragLayer;
@@ -403,8 +405,11 @@ public class Launcher extends BaseActivity
getSystemUiController().updateUiState(SystemUiController.UI_STATE_BASE_WINDOW,
Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText));
+ mAppTransitionManager = Utilities.getOverrideObject(LauncherAppTransitionManager.class,
+ this, R.string.app_transition_manager_class);
+
if (!isInMultiWindowModeCompat()) {
- UiFactory.registerRemoteAnimations(this);
+ mAppTransitionManager.registerRemoteAnimations();
}
if (mLauncherCallbacks != null) {
@@ -1918,38 +1923,11 @@ public class Launcher extends BaseActivity
}
}
- public Bundle getDefaultActivityLaunchOptions(View v) {
- if (Utilities.ATLEAST_MARSHMALLOW) {
- int left = 0, top = 0;
- int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
- if (v instanceof BubbleTextView) {
- // Launch from center of icon, not entire view
- Drawable icon = ((BubbleTextView) v).getIcon();
- if (icon != null) {
- Rect bounds = icon.getBounds();
- left = (width - bounds.width()) / 2;
- top = v.getPaddingTop();
- width = bounds.width();
- height = bounds.height();
- }
- }
- return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height)
- .toBundle();
- } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
- // On L devices, we use the device default slide-up transition.
- // On L MR1 devices, we use a custom version of the slide-up transition which
- // doesn't have the delay present in the device default.
- return ActivityOptions.makeCustomAnimation(
- this, R.anim.task_open_enter, R.anim.no_anim).toBundle();
- }
- return null;
- }
-
@TargetApi(Build.VERSION_CODES.M)
public Bundle getActivityLaunchOptions(View v, boolean useDefaultLaunchOptions) {
return useDefaultLaunchOptions
- ? getDefaultActivityLaunchOptions(v)
- : UiFactory.getActivityLaunchOptions(this, v);
+ ? mAppTransitionManager.getDefaultActivityLaunchOptions(this, v)
+ : mAppTransitionManager.getActivityLaunchOptions(this, v);
}
public Rect getViewBounds(View v) {
diff --git a/src/com/android/launcher3/LauncherAppTransitionManager.java b/src/com/android/launcher3/LauncherAppTransitionManager.java
new file mode 100644
index 000000000..9d68dc9e8
--- /dev/null
+++ b/src/com/android/launcher3/LauncherAppTransitionManager.java
@@ -0,0 +1,64 @@
+/*
+ * 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;
+
+
+import android.app.ActivityOptions;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+
+/**
+ * Manages the opening and closing app transitions from Launcher.
+ */
+public class LauncherAppTransitionManager {
+
+ public Bundle getDefaultActivityLaunchOptions(Launcher launcher, View v) {
+ if (Utilities.ATLEAST_MARSHMALLOW) {
+ int left = 0, top = 0;
+ int width = v.getMeasuredWidth(), height = v.getMeasuredHeight();
+ if (v instanceof BubbleTextView) {
+ // Launch from center of icon, not entire view
+ Drawable icon = ((BubbleTextView) v).getIcon();
+ if (icon != null) {
+ Rect bounds = icon.getBounds();
+ left = (width - bounds.width()) / 2;
+ top = v.getPaddingTop();
+ width = bounds.width();
+ height = bounds.height();
+ }
+ }
+ return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height)
+ .toBundle();
+ } else if (Utilities.ATLEAST_LOLLIPOP_MR1) {
+ // On L devices, we use the device default slide-up transition.
+ // On L MR1 devices, we use a custom version of the slide-up transition which
+ // doesn't have the delay present in the device default.
+ return ActivityOptions.makeCustomAnimation(launcher, R.anim.task_open_enter,
+ R.anim.no_anim).toBundle();
+ }
+ return null;
+ }
+
+ public Bundle getActivityLaunchOptions(Launcher launcher, View v) {
+ return getDefaultActivityLaunchOptions(launcher, v);
+ }
+
+ public void registerRemoteAnimations() {
+ }
+}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
index c857bf6a0..744125e15 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/UiFactory.java
@@ -61,10 +61,4 @@ public class UiFactory {
}
public static void resetOverview(Launcher launcher) { }
-
- public static Bundle getActivityLaunchOptions(Launcher launcher, View v) {
- return launcher.getDefaultActivityLaunchOptions(v);
- }
-
- public static void registerRemoteAnimations(Launcher launcher) { }
}