Merge "Hide recents during freeform to recents animation."
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 0266a37..6107dfd 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -131,6 +131,13 @@
public static final String KEY_ANIM_START_LISTENER = "android:activity.animStartListener";
/**
+ * Callback for when the last frame of the animation is played.
+ * @hide
+ */
+ private static final String KEY_ANIMATION_FINISHED_LISTENER =
+ "android:activity.animationFinishedListener";
+
+ /**
* Descriptions of app transition animations to be played during the activity launch.
*/
private static final String KEY_ANIM_SPECS = "android:activity.animSpecs";
@@ -198,6 +205,7 @@
private int mWidth;
private int mHeight;
private IRemoteCallback mAnimationStartedListener;
+ private IRemoteCallback mAnimationFinishedListener;
private ResultReceiver mTransitionReceiver;
private boolean mIsReturning;
private ArrayList<String> mSharedElementNames;
@@ -280,16 +288,15 @@
return opts;
}
- private void setOnAnimationStartedListener(Handler handler,
- OnAnimationStartedListener listener) {
+ private void setOnAnimationStartedListener(final Handler handler,
+ final OnAnimationStartedListener listener) {
if (listener != null) {
- final Handler h = handler;
- final OnAnimationStartedListener finalListener = listener;
mAnimationStartedListener = new IRemoteCallback.Stub() {
- @Override public void sendResult(Bundle data) throws RemoteException {
- h.post(new Runnable() {
+ @Override
+ public void sendResult(Bundle data) throws RemoteException {
+ handler.post(new Runnable() {
@Override public void run() {
- finalListener.onAnimationStarted();
+ listener.onAnimationStarted();
}
});
}
@@ -306,6 +313,32 @@
void onAnimationStarted();
}
+ private void setOnAnimationFinishedListener(final Handler handler,
+ final OnAnimationFinishedListener listener) {
+ if (listener != null) {
+ mAnimationFinishedListener = new IRemoteCallback.Stub() {
+ @Override
+ public void sendResult(Bundle data) throws RemoteException {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onAnimationFinished();
+ }
+ });
+ }
+ };
+ }
+ }
+
+ /**
+ * Callback for use with {@link ActivityOptions#makeThumbnailAspectScaleDownAnimation}
+ * to find out when the given animation has drawn its last frame.
+ * @hide
+ */
+ public interface OnAnimationFinishedListener {
+ void onAnimationFinished();
+ }
+
/**
* Create an ActivityOptions specifying an animation where the new
* activity is scaled from a small originating area of the screen to
@@ -523,12 +556,14 @@
/** @hide */
public static ActivityOptions makeThumbnailAspectScaleDownAnimation(View source,
AppTransitionAnimationSpec[] specs, Handler handler,
- OnAnimationStartedListener listener) {
+ OnAnimationStartedListener onAnimationStartedListener,
+ OnAnimationFinishedListener onAnimationFinishedListener) {
ActivityOptions opts = new ActivityOptions();
opts.mPackageName = source.getContext().getPackageName();
opts.mAnimationType = ANIM_THUMBNAIL_ASPECT_SCALE_DOWN;
opts.mAnimSpecs = specs;
- opts.setOnAnimationStartedListener(handler, listener);
+ opts.setOnAnimationStartedListener(handler, onAnimationStartedListener);
+ opts.setOnAnimationFinishedListener(handler, onAnimationFinishedListener);
return opts;
}
@@ -725,6 +760,10 @@
mAnimSpecs[i] = (AppTransitionAnimationSpec) specs[i];
}
}
+ if (opts.containsKey(KEY_ANIMATION_FINISHED_LISTENER)) {
+ mAnimationFinishedListener = IRemoteCallback.Stub.asInterface(
+ opts.getBinder(KEY_ANIMATION_FINISHED_LISTENER));
+ }
}
/** @hide */
@@ -800,6 +839,11 @@
}
/** @hide */
+ public IRemoteCallback getAnimationFinishedListener() {
+ return mAnimationFinishedListener;
+ }
+
+ /** @hide */
public int getExitCoordinatorKey() { return mExitCoordinatorIndex; }
/** @hide */
@@ -929,6 +973,7 @@
break;
}
mAnimSpecs = otherOptions.mAnimSpecs;
+ mAnimationFinishedListener = otherOptions.mAnimationFinishedListener;
}
/**
@@ -998,6 +1043,9 @@
if (mAnimSpecs != null) {
b.putParcelableArray(KEY_ANIM_SPECS, mAnimSpecs);
}
+ if (mAnimationFinishedListener != null) {
+ b.putBinder(KEY_ANIMATION_FINISHED_LISTENER, mAnimationFinishedListener.asBinder());
+ }
return b;
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 7adfa8d..f18b35d 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -138,7 +138,7 @@
* @hide
*/
void overridePendingAppTransitionMultiThumb(in AppTransitionAnimationSpec[] specs,
- IRemoteCallback startedCallback, boolean scaleUp);
+ IRemoteCallback startedCallback, IRemoteCallback finishedCallback, boolean scaleUp);
void overridePendingAppTransitionInPlace(String packageName, int anim);
void executeAppTransition();
void setAppStartingWindow(IBinder token, String pkg, int theme,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index dc80259..4d575bc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -32,7 +32,6 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewStub;
@@ -43,6 +42,7 @@
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationStartedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -419,6 +419,17 @@
}
@Override
+ protected void onResume() {
+ super.onResume();
+
+ final RecentsActivityLaunchState state = Recents.getConfiguration().getLaunchState();
+ if (state.startHidden) {
+ state.startHidden = false;
+ mRecentsView.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ @Override
protected void onPause() {
super.onPause();
if (mAfterPauseRunnable != null) {
@@ -645,6 +656,10 @@
ctx.postAnimationTrigger.decrement();
}
+ public final void onBusEvent(EnterRecentsWindowLastAnimationFrameEvent event) {
+ mRecentsView.setVisibility(View.VISIBLE);
+ }
+
public final void onBusEvent(AppWidgetProviderChangedEvent event) {
refreshSearchWidgetView();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
index aca816e..31ce569 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivityLaunchState.java
@@ -35,6 +35,7 @@
public boolean launchedFromSearchHome;
public boolean launchedReuseTaskStackViews;
public boolean launchedHasConfigurationChanged;
+ public boolean startHidden;
public int launchedToTaskId;
public int launchedNumVisibleTasks;
public int launchedNumVisibleThumbnails;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index c314f3f..243c0e1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -45,6 +45,7 @@
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationStartedEvent;
import com.android.systemui.recents.events.activity.HideRecentsEvent;
import com.android.systemui.recents.events.activity.IterateRecentsEvent;
+import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -69,7 +70,7 @@
* be called remotely from the system user.
*/
public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub
- implements ActivityOptions.OnAnimationStartedListener {
+ implements ActivityOptions.OnAnimationStartedListener, ActivityOptions.OnAnimationFinishedListener {
private final static String TAG = "RecentsImpl";
private final static boolean DEBUG = false;
@@ -79,7 +80,6 @@
public final static String RECENTS_PACKAGE = "com.android.systemui";
public final static String RECENTS_ACTIVITY = "com.android.systemui.recents.RecentsActivity";
-
/**
* An implementation of ITaskStackListener, that allows us to listen for changes to the system
* task stacks and update recents accordingly.
@@ -579,7 +579,7 @@
AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()];
specs.toArray(specsArray);
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
- specsArray, mHandler, this);
+ specsArray, mHandler, this, this);
} else {
// Update the destination rect
Task toTask = new Task();
@@ -757,6 +757,7 @@
launchState.launchedNumVisibleTasks = vr.numVisibleTasks;
launchState.launchedNumVisibleThumbnails = vr.numVisibleThumbnails;
launchState.launchedHasConfigurationChanged = false;
+ launchState.startHidden = topTask != null && topTask.stackId == FREEFORM_WORKSPACE_STACK_ID;
Intent intent = new Intent();
intent.setClassName(RECENTS_PACKAGE, RECENTS_ACTIVITY);
@@ -781,4 +782,9 @@
EventBus.getDefault().post(new EnterRecentsWindowAnimationStartedEvent());
}
}
+
+ @Override
+ public void onAnimationFinished() {
+ EventBus.getDefault().post(new EnterRecentsWindowLastAnimationFrameEvent());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java
new file mode 100644
index 0000000..fd023d8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/EnterRecentsWindowLastAnimationFrameEvent.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 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.systemui.recents.events.activity;
+
+import com.android.systemui.recents.events.EventBus;
+
+public class EnterRecentsWindowLastAnimationFrameEvent extends EventBus.Event {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index a8a8259..422e917 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -476,7 +476,7 @@
new AppTransitionAnimationSpec[specs.size()];
try {
WindowManagerGlobal.getWindowManagerService().overridePendingAppTransitionMultiThumb(
- specs.toArray(specsArray), callback, true /* scaleUp */);
+ specs.toArray(specsArray), callback, null, true /* scaleUp */);
} catch (RemoteException e) {
Log.w(TAG, "Error overriding app transition", e);
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 499aba9..76c4f1e 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -874,7 +874,8 @@
if (animationType == ActivityOptions.ANIM_THUMBNAIL_ASPECT_SCALE_DOWN
&& specs != null) {
service.mWindowManager.overridePendingAppTransitionMultiThumb(
- specs, pendingOptions.getOnAnimationStartListener(), false);
+ specs, pendingOptions.getOnAnimationStartListener(),
+ pendingOptions.getAnimationFinishedListener(), false);
} else {
service.mWindowManager.overridePendingAppTransitionAspectScaledThumb(
pendingOptions.getThumbnail(),
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index eb0ca23..468cf6d 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -160,6 +160,7 @@
// Used for thumbnail transitions. True if we're scaling up, false if scaling down
private boolean mNextAppTransitionScaleUp;
private IRemoteCallback mNextAppTransitionCallback;
+ private IRemoteCallback mAnimationFinishedCallback;
private int mNextAppTransitionEnter;
private int mNextAppTransitionExit;
private int mNextAppTransitionInPlace;
@@ -932,6 +933,22 @@
: new TranslateAnimation(0, fromX, 0, fromY);
set.addAnimation(scale);
set.addAnimation(translation);
+
+ final IRemoteCallback callback = mAnimationFinishedCallback;
+ if (callback != null) {
+ set.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) { }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ mH.obtainMessage(H.DO_ANIMATION_CALLBACK, callback).sendToTarget();
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) { }
+ });
+ }
return set;
}
@@ -1356,7 +1373,8 @@
}
public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
- IRemoteCallback callback, boolean scaleUp) {
+ IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
+ boolean scaleUp) {
if (isTransitionSet()) {
mNextAppTransitionType = scaleUp ? NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP
: NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN;
@@ -1378,7 +1396,8 @@
}
}
postAnimationCallback();
- mNextAppTransitionCallback = callback;
+ mNextAppTransitionCallback = onAnimationStartedCallback;
+ mAnimationFinishedCallback = onAnimationFinishedCallback;
} else {
postAnimationCallback();
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 140fbaf..75680a0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3637,9 +3637,11 @@
@Override
public void overridePendingAppTransitionMultiThumb(AppTransitionAnimationSpec[] specs,
- IRemoteCallback callback, boolean scaleUp) {
+ IRemoteCallback onAnimationStartedCallback, IRemoteCallback onAnimationFinishedCallback,
+ boolean scaleUp) {
synchronized (mWindowMap) {
- mAppTransition.overridePendingAppTransitionMultiThumb(specs, callback, scaleUp);
+ mAppTransition.overridePendingAppTransitionMultiThumb(specs, onAnimationStartedCallback,
+ onAnimationFinishedCallback, scaleUp);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 80f1094..aa242f1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -282,9 +282,8 @@
}
mTransformation.clear();
final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
- if (false && DEBUG_ANIM) Slog.v(
- TAG, "Stepped animation in " + this +
- ": more=" + more + ", xform=" + mTransformation);
+ if (false && DEBUG_ANIM) Slog.v(TAG, "Stepped animation in " + this + ": more=" + more
+ + ", xform=" + mTransformation);
return more;
}