Merge "Internal API for cross-task Activity used by assistant." into nyc-mr1-dev
This commit is contained in:
@@ -4219,6 +4219,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
|
public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
|
||||||
@Nullable Bundle options) {
|
@Nullable Bundle options) {
|
||||||
if (mParent == null) {
|
if (mParent == null) {
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar =
|
Instrumentation.ActivityResult ar =
|
||||||
mInstrumentation.execStartActivity(
|
mInstrumentation.execStartActivity(
|
||||||
this, mMainThread.getApplicationThread(), mToken, this,
|
this, mMainThread.getApplicationThread(), mToken, this,
|
||||||
@@ -4267,6 +4268,14 @@ public class Activity extends ContextThemeWrapper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Bundle transferSpringboardActivityOptions(Bundle options) {
|
||||||
|
if (options == null && (mWindow != null && !mWindow.isActive())) {
|
||||||
|
return mActivityTransitionState.transferEnterActivityOptions();
|
||||||
|
} else {
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide Implement to provide correct calling token.
|
* @hide Implement to provide correct calling token.
|
||||||
*/
|
*/
|
||||||
@@ -4282,6 +4291,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
if (mParent != null) {
|
if (mParent != null) {
|
||||||
throw new RuntimeException("Can't be called from a child");
|
throw new RuntimeException("Can't be called from a child");
|
||||||
}
|
}
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
|
Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(
|
||||||
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode,
|
this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode,
|
||||||
options, user);
|
options, user);
|
||||||
@@ -4317,6 +4327,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
if (mParent != null) {
|
if (mParent != null) {
|
||||||
throw new RuntimeException("Can't be called from a child");
|
throw new RuntimeException("Can't be called from a child");
|
||||||
}
|
}
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar =
|
Instrumentation.ActivityResult ar =
|
||||||
mInstrumentation.execStartActivity(
|
mInstrumentation.execStartActivity(
|
||||||
this, mMainThread.getApplicationThread(), mToken, this,
|
this, mMainThread.getApplicationThread(), mToken, this,
|
||||||
@@ -4349,6 +4360,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
if (mParent != null) {
|
if (mParent != null) {
|
||||||
throw new RuntimeException("Can't be called from a child");
|
throw new RuntimeException("Can't be called from a child");
|
||||||
}
|
}
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar =
|
Instrumentation.ActivityResult ar =
|
||||||
mInstrumentation.execStartActivityAsCaller(
|
mInstrumentation.execStartActivityAsCaller(
|
||||||
this, mMainThread.getApplicationThread(), mToken, this,
|
this, mMainThread.getApplicationThread(), mToken, this,
|
||||||
@@ -4788,6 +4800,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
*/
|
*/
|
||||||
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
|
public void startActivityFromChild(@NonNull Activity child, @RequiresPermission Intent intent,
|
||||||
int requestCode, @Nullable Bundle options) {
|
int requestCode, @Nullable Bundle options) {
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar =
|
Instrumentation.ActivityResult ar =
|
||||||
mInstrumentation.execStartActivity(
|
mInstrumentation.execStartActivity(
|
||||||
this, mMainThread.getApplicationThread(), mToken, child,
|
this, mMainThread.getApplicationThread(), mToken, child,
|
||||||
@@ -4853,6 +4866,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
if (referrer != null) {
|
if (referrer != null) {
|
||||||
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
|
intent.putExtra(Intent.EXTRA_REFERRER, referrer);
|
||||||
}
|
}
|
||||||
|
options = transferSpringboardActivityOptions(options);
|
||||||
Instrumentation.ActivityResult ar =
|
Instrumentation.ActivityResult ar =
|
||||||
mInstrumentation.execStartActivity(
|
mInstrumentation.execStartActivity(
|
||||||
this, mMainThread.getApplicationThread(), mToken, who,
|
this, mMainThread.getApplicationThread(), mToken, who,
|
||||||
@@ -6650,11 +6664,11 @@ public class Activity extends ContextThemeWrapper
|
|||||||
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
|
mVisibleFromClient = !mWindow.getWindowStyle().getBoolean(
|
||||||
com.android.internal.R.styleable.Window_windowNoDisplay, false);
|
com.android.internal.R.styleable.Window_windowNoDisplay, false);
|
||||||
mFragments.dispatchActivityCreated();
|
mFragments.dispatchActivityCreated();
|
||||||
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final void performCreate(Bundle icicle) {
|
final void performCreate(Bundle icicle) {
|
||||||
restoreHasCurrentPermissionRequest(icicle);
|
restoreHasCurrentPermissionRequest(icicle);
|
||||||
|
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
|
||||||
onCreate(icicle);
|
onCreate(icicle);
|
||||||
mActivityTransitionState.readState(icicle);
|
mActivityTransitionState.readState(icicle);
|
||||||
performCreateCommon();
|
performCreateCommon();
|
||||||
@@ -6662,6 +6676,7 @@ public class Activity extends ContextThemeWrapper
|
|||||||
|
|
||||||
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
|
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
|
||||||
restoreHasCurrentPermissionRequest(icicle);
|
restoreHasCurrentPermissionRequest(icicle);
|
||||||
|
mActivityTransitionState.setEnterActivityOptions(this, getActivityOptions());
|
||||||
onCreate(icicle, persistentState);
|
onCreate(icicle, persistentState);
|
||||||
mActivityTransitionState.readState(icicle);
|
mActivityTransitionState.readState(icicle);
|
||||||
performCreateCommon();
|
performCreateCommon();
|
||||||
|
|||||||
@@ -31,10 +31,13 @@ import android.os.IRemoteCallback;
|
|||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.ResultReceiver;
|
import android.os.ResultReceiver;
|
||||||
|
import android.transition.Transition;
|
||||||
|
import android.transition.TransitionManager;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
import android.view.AppTransitionAnimationSpec;
|
import android.view.AppTransitionAnimationSpec;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -640,10 +643,71 @@ public class ActivityOptions {
|
|||||||
public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
|
public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
|
||||||
Pair<View, String>... sharedElements) {
|
Pair<View, String>... sharedElements) {
|
||||||
ActivityOptions opts = new ActivityOptions();
|
ActivityOptions opts = new ActivityOptions();
|
||||||
if (!activity.getWindow().hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
|
makeSceneTransitionAnimation(activity, activity.getWindow(), opts,
|
||||||
opts.mAnimationType = ANIM_DEFAULT;
|
activity.mExitTransitionListener, sharedElements);
|
||||||
return opts;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call this immediately prior to startActivity to begin a shared element transition
|
||||||
|
* from a non-Activity. The window must support Window.FEATURE_ACTIVITY_TRANSITIONS.
|
||||||
|
* The exit transition will start immediately and the shared element transition will
|
||||||
|
* start once the launched Activity's shared element is ready.
|
||||||
|
* <p>
|
||||||
|
* When all transitions have completed and the shared element has been transfered,
|
||||||
|
* the window's decor View will have its visibility set to View.GONE.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
@SafeVarargs
|
||||||
|
public static ActivityOptions startSharedElementAnimation(Window window,
|
||||||
|
Pair<View, String>... sharedElements) {
|
||||||
|
ActivityOptions opts = new ActivityOptions();
|
||||||
|
final View decorView = window.getDecorView();
|
||||||
|
if (decorView == null) {
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
final ExitTransitionCoordinator exit =
|
||||||
|
makeSceneTransitionAnimation(null, window, opts, null, sharedElements);
|
||||||
|
if (exit != null) {
|
||||||
|
HideWindowListener listener = new HideWindowListener(window, exit);
|
||||||
|
exit.setHideSharedElementsCallback(listener);
|
||||||
|
exit.startExit();
|
||||||
|
}
|
||||||
|
return opts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should be called when the {@link #startSharedElementAnimation(Window, Pair[])}
|
||||||
|
* animation must be stopped and the Views reset. This can happen if there was an error
|
||||||
|
* from startActivity or a springboard activity and the animation should stop and reset.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static void stopSharedElementAnimation(Window window) {
|
||||||
|
final View decorView = window.getDecorView();
|
||||||
|
if (decorView == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ExitTransitionCoordinator exit = (ExitTransitionCoordinator)
|
||||||
|
decorView.getTag(com.android.internal.R.id.cross_task_transition);
|
||||||
|
if (exit != null) {
|
||||||
|
exit.cancelPendingTransitions();
|
||||||
|
decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, null);
|
||||||
|
TransitionManager.endTransitions((ViewGroup) decorView);
|
||||||
|
exit.resetViews();
|
||||||
|
exit.clearState();
|
||||||
|
decorView.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ExitTransitionCoordinator makeSceneTransitionAnimation(Activity activity, Window window,
|
||||||
|
ActivityOptions opts, SharedElementCallback callback,
|
||||||
|
Pair<View, String>[] sharedElements) {
|
||||||
|
if (!window.hasFeature(Window.FEATURE_ACTIVITY_TRANSITIONS)) {
|
||||||
|
opts.mAnimationType = ANIM_DEFAULT;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
opts.mAnimationType = ANIM_SCENE_TRANSITION;
|
opts.mAnimationType = ANIM_SCENE_TRANSITION;
|
||||||
|
|
||||||
ArrayList<String> names = new ArrayList<String>();
|
ArrayList<String> names = new ArrayList<String>();
|
||||||
@@ -665,18 +729,22 @@ public class ActivityOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, names, names,
|
ExitTransitionCoordinator exit = new ExitTransitionCoordinator(activity, window,
|
||||||
views, false);
|
callback, names, names, views, false);
|
||||||
opts.mTransitionReceiver = exit;
|
opts.mTransitionReceiver = exit;
|
||||||
opts.mSharedElementNames = names;
|
opts.mSharedElementNames = names;
|
||||||
opts.mIsReturning = false;
|
opts.mIsReturning = (activity == null);
|
||||||
|
if (activity == null) {
|
||||||
|
opts.mExitCoordinatorIndex = -1;
|
||||||
|
} else {
|
||||||
opts.mExitCoordinatorIndex =
|
opts.mExitCoordinatorIndex =
|
||||||
activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
|
activity.mActivityTransitionState.addExitTransitionCoordinator(exit);
|
||||||
return opts;
|
}
|
||||||
|
return exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public static ActivityOptions makeSceneTransitionAnimation(Activity activity,
|
static ActivityOptions makeSceneTransitionAnimation(Activity activity,
|
||||||
ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
|
ExitTransitionCoordinator exitCoordinator, ArrayList<String> sharedElementNames,
|
||||||
int resultCode, Intent resultData) {
|
int resultCode, Intent resultData) {
|
||||||
ActivityOptions opts = new ActivityOptions();
|
ActivityOptions opts = new ActivityOptions();
|
||||||
@@ -900,6 +968,16 @@ public class ActivityOptions {
|
|||||||
return mIsReturning;
|
return mIsReturning;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the ActivityOptions was created with
|
||||||
|
* {@link #startSharedElementAnimation(Window, Pair[])}.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
boolean isCrossTask() {
|
||||||
|
return mExitCoordinatorIndex < 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** @hide */
|
/** @hide */
|
||||||
public ArrayList<String> getSharedElementNames() {
|
public ArrayList<String> getSharedElementNames() {
|
||||||
return mSharedElementNames;
|
return mSharedElementNames;
|
||||||
@@ -1191,4 +1269,65 @@ public class ActivityOptions {
|
|||||||
+ ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
|
+ ", mAnimationType=" + mAnimationType + ", mStartX=" + mStartX + ", mStartY="
|
||||||
+ mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
|
+ mStartY + ", mWidth=" + mWidth + ", mHeight=" + mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class HideWindowListener extends Transition.TransitionListenerAdapter
|
||||||
|
implements ExitTransitionCoordinator.HideSharedElementsCallback {
|
||||||
|
private final Window mWindow;
|
||||||
|
private final ExitTransitionCoordinator mExit;
|
||||||
|
private final boolean mWaitingForTransition;
|
||||||
|
private boolean mTransitionEnded;
|
||||||
|
private boolean mSharedElementHidden;
|
||||||
|
private ArrayList<View> mSharedElements;
|
||||||
|
|
||||||
|
public HideWindowListener(Window window, ExitTransitionCoordinator exit) {
|
||||||
|
mWindow = window;
|
||||||
|
mExit = exit;
|
||||||
|
mSharedElements = new ArrayList<>(exit.mSharedElements);
|
||||||
|
Transition transition = mWindow.getExitTransition();
|
||||||
|
if (transition != null) {
|
||||||
|
transition.addListener(this);
|
||||||
|
mWaitingForTransition = true;
|
||||||
|
} else {
|
||||||
|
mWaitingForTransition = false;
|
||||||
|
}
|
||||||
|
View decorView = mWindow.getDecorView();
|
||||||
|
if (decorView != null) {
|
||||||
|
if (decorView.getTag(com.android.internal.R.id.cross_task_transition) != null) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Cannot start a transition while one is running");
|
||||||
|
}
|
||||||
|
decorView.setTagInternal(com.android.internal.R.id.cross_task_transition, exit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransitionEnd(Transition transition) {
|
||||||
|
mTransitionEnded = true;
|
||||||
|
hideWhenDone();
|
||||||
|
transition.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hideSharedElements() {
|
||||||
|
mSharedElementHidden = true;
|
||||||
|
hideWhenDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideWhenDone() {
|
||||||
|
if (mSharedElementHidden && (!mWaitingForTransition || mTransitionEnded)) {
|
||||||
|
mExit.resetViews();
|
||||||
|
int numSharedElements = mSharedElements.size();
|
||||||
|
for (int i = 0; i < numSharedElements; i++) {
|
||||||
|
View view = mSharedElements.get(i);
|
||||||
|
view.requestLayout();
|
||||||
|
}
|
||||||
|
View decorView = mWindow.getDecorView();
|
||||||
|
if (decorView != null) {
|
||||||
|
decorView.setTagInternal(
|
||||||
|
com.android.internal.R.id.cross_task_transition, null);
|
||||||
|
decorView.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,12 @@ class ActivityTransitionState {
|
|||||||
|
|
||||||
private boolean mIsEnterTriggered;
|
private boolean mIsEnterTriggered;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The ActivityOptions Bundle. This is used to transfer ActivityOptions through a
|
||||||
|
* springboard Activity.
|
||||||
|
*/
|
||||||
|
private Bundle mEnterBundle;
|
||||||
|
|
||||||
public ActivityTransitionState() {
|
public ActivityTransitionState() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +156,10 @@ class ActivityTransitionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
|
public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
|
||||||
|
if (options != null && mEnterBundle == null &&
|
||||||
|
options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
|
||||||
|
mEnterBundle = options.toBundle();
|
||||||
|
}
|
||||||
final Window window = activity.getWindow();
|
final Window window = activity.getWindow();
|
||||||
if (window == null) {
|
if (window == null) {
|
||||||
return;
|
return;
|
||||||
@@ -185,7 +195,12 @@ class ActivityTransitionState {
|
|||||||
activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
|
activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
|
mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
|
||||||
resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning());
|
resultReceiver, sharedElementNames, mEnterActivityOptions.isReturning(),
|
||||||
|
mEnterActivityOptions.isCrossTask());
|
||||||
|
if (mEnterActivityOptions.isCrossTask()) {
|
||||||
|
mExitingFrom = new ArrayList<>(mEnterActivityOptions.getSharedElementNames());
|
||||||
|
mExitingTo = new ArrayList<>(mEnterActivityOptions.getSharedElementNames());
|
||||||
|
}
|
||||||
|
|
||||||
if (!mIsEnterPostponed) {
|
if (!mIsEnterPostponed) {
|
||||||
startEnter();
|
startEnter();
|
||||||
@@ -224,6 +239,13 @@ class ActivityTransitionState {
|
|||||||
mEnterActivityOptions = null;
|
mEnterActivityOptions = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bundle transferEnterActivityOptions() {
|
||||||
|
mEnterActivityOptions = null;
|
||||||
|
Bundle options = mEnterBundle;
|
||||||
|
mEnterBundle = null;
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
public void onStop() {
|
public void onStop() {
|
||||||
restoreExitedViews();
|
restoreExitedViews();
|
||||||
if (mEnterTransitionCoordinator != null) {
|
if (mEnterTransitionCoordinator != null) {
|
||||||
@@ -275,7 +297,8 @@ class ActivityTransitionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void restoreReenteringViews() {
|
private void restoreReenteringViews() {
|
||||||
if (mEnterTransitionCoordinator != null && mEnterTransitionCoordinator.isReturning()) {
|
if (mEnterTransitionCoordinator != null && mEnterTransitionCoordinator.isReturning() &&
|
||||||
|
!mEnterTransitionCoordinator.isCrossTask()) {
|
||||||
mEnterTransitionCoordinator.forceViewsToAppear();
|
mEnterTransitionCoordinator.forceViewsToAppear();
|
||||||
mExitingFrom = null;
|
mExitingFrom = null;
|
||||||
mExitingTo = null;
|
mExitingTo = null;
|
||||||
@@ -302,8 +325,9 @@ class ActivityTransitionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mReturnExitCoordinator =
|
mReturnExitCoordinator = new ExitTransitionCoordinator(activity,
|
||||||
new ExitTransitionCoordinator(activity, mEnteringNames, null, null, true);
|
activity.getWindow(), activity.mEnterTransitionListener, mEnteringNames,
|
||||||
|
null, null, true);
|
||||||
if (enterViewsTransition != null && decor != null) {
|
if (enterViewsTransition != null && decor != null) {
|
||||||
enterViewsTransition.resume(decor);
|
enterViewsTransition.resume(decor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,12 +59,14 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
private boolean mIsViewsTransitionStarted;
|
private boolean mIsViewsTransitionStarted;
|
||||||
private Transition mEnterViewsTransition;
|
private Transition mEnterViewsTransition;
|
||||||
private OnPreDrawListener mViewsReadyListener;
|
private OnPreDrawListener mViewsReadyListener;
|
||||||
|
private final boolean mIsCrossTask;
|
||||||
|
|
||||||
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
|
public EnterTransitionCoordinator(Activity activity, ResultReceiver resultReceiver,
|
||||||
ArrayList<String> sharedElementNames, boolean isReturning) {
|
ArrayList<String> sharedElementNames, boolean isReturning, boolean isCrossTask) {
|
||||||
super(activity.getWindow(), sharedElementNames,
|
super(activity.getWindow(), sharedElementNames,
|
||||||
getListener(activity, isReturning), isReturning);
|
getListener(activity, isReturning && !isCrossTask), isReturning);
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
|
mIsCrossTask = isCrossTask;
|
||||||
setResultReceiver(resultReceiver);
|
setResultReceiver(resultReceiver);
|
||||||
prepareEnter();
|
prepareEnter();
|
||||||
Bundle resultReceiverBundle = new Bundle();
|
Bundle resultReceiverBundle = new Bundle();
|
||||||
@@ -85,6 +87,10 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isCrossTask() {
|
||||||
|
return mIsCrossTask;
|
||||||
|
}
|
||||||
|
|
||||||
public void viewInstancesReady(ArrayList<String> accepted, ArrayList<String> localNames,
|
public void viewInstancesReady(ArrayList<String> accepted, ArrayList<String> localNames,
|
||||||
ArrayList<View> localViews) {
|
ArrayList<View> localViews) {
|
||||||
boolean remap = false;
|
boolean remap = false;
|
||||||
@@ -325,7 +331,9 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
if (mActivity == null || decorView == null) {
|
if (mActivity == null || decorView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!isCrossTask()) {
|
||||||
mActivity.overridePendingTransition(0, 0);
|
mActivity.overridePendingTransition(0, 0);
|
||||||
|
}
|
||||||
if (!mIsReturning) {
|
if (!mIsReturning) {
|
||||||
mWasOpaque = mActivity.convertToTranslucent(null, null);
|
mWasOpaque = mActivity.convertToTranslucent(null, null);
|
||||||
Drawable background = decorView.getBackground();
|
Drawable background = decorView.getBackground();
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import android.transition.TransitionManager;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
|
import android.view.Window;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@@ -59,18 +60,20 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
private Bundle mExitSharedElementBundle;
|
private Bundle mExitSharedElementBundle;
|
||||||
private boolean mIsExitStarted;
|
private boolean mIsExitStarted;
|
||||||
private boolean mSharedElementsHidden;
|
private boolean mSharedElementsHidden;
|
||||||
|
private HideSharedElementsCallback mHideSharedElementsCallback;
|
||||||
|
|
||||||
public ExitTransitionCoordinator(Activity activity, ArrayList<String> names,
|
public ExitTransitionCoordinator(Activity activity, Window window,
|
||||||
|
SharedElementCallback listener, ArrayList<String> names,
|
||||||
ArrayList<String> accepted, ArrayList<View> mapped, boolean isReturning) {
|
ArrayList<String> accepted, ArrayList<View> mapped, boolean isReturning) {
|
||||||
super(activity.getWindow(), names, getListener(activity, isReturning), isReturning);
|
super(window, names, listener, isReturning);
|
||||||
viewsReady(mapSharedElements(accepted, mapped));
|
viewsReady(mapSharedElements(accepted, mapped));
|
||||||
stripOffscreenViews();
|
stripOffscreenViews();
|
||||||
mIsBackgroundReady = !isReturning;
|
mIsBackgroundReady = !isReturning;
|
||||||
mActivity = activity;
|
mActivity = activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SharedElementCallback getListener(Activity activity, boolean isReturning) {
|
void setHideSharedElementsCallback(HideSharedElementsCallback callback) {
|
||||||
return isReturning ? activity.mEnterTransitionListener : activity.mExitTransitionListener;
|
mHideSharedElementsCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -188,6 +191,9 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
|
|
||||||
private void hideSharedElements() {
|
private void hideSharedElements() {
|
||||||
moveSharedElementsFromOverlay();
|
moveSharedElementsFromOverlay();
|
||||||
|
if (mHideSharedElementsCallback != null) {
|
||||||
|
mHideSharedElementsCallback.hideSharedElements();
|
||||||
|
}
|
||||||
if (!mIsHidden) {
|
if (!mIsHidden) {
|
||||||
hideViews(mSharedElements);
|
hideViews(mSharedElements);
|
||||||
}
|
}
|
||||||
@@ -207,7 +213,11 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
startTransition(new Runnable() {
|
startTransition(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
if (mActivity != null) {
|
||||||
beginTransitions();
|
beginTransitions();
|
||||||
|
} else {
|
||||||
|
startExitTransition();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -508,4 +518,8 @@ class ExitTransitionCoordinator extends ActivityTransitionCoordinator {
|
|||||||
return getWindow().getSharedElementExitTransition();
|
return getWindow().getSharedElementExitTransition();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface HideSharedElementsCallback {
|
||||||
|
void hideSharedElements();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1940,6 +1940,26 @@ public abstract class Transition implements Cloneable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the transition to move to its end state, ending all the animators.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
void forceToEnd(ViewGroup sceneRoot) {
|
||||||
|
ArrayMap<Animator, AnimationInfo> runningAnimators = getRunningAnimators();
|
||||||
|
int numOldAnims = runningAnimators.size();
|
||||||
|
if (sceneRoot != null) {
|
||||||
|
WindowId windowId = sceneRoot.getWindowId();
|
||||||
|
for (int i = numOldAnims - 1; i >= 0; i--) {
|
||||||
|
AnimationInfo info = runningAnimators.valueAt(i);
|
||||||
|
if (info.view != null && windowId != null && windowId.equals(info.windowId)) {
|
||||||
|
Animator anim = runningAnimators.keyAt(i);
|
||||||
|
anim.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method cancels a transition that is currently running.
|
* This method cancels a transition that is currently running.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -440,7 +440,7 @@ public class TransitionManager {
|
|||||||
ArrayList<Transition> copy = new ArrayList(runningTransitions);
|
ArrayList<Transition> copy = new ArrayList(runningTransitions);
|
||||||
for (int i = copy.size() - 1; i >= 0; i--) {
|
for (int i = copy.size() - 1; i >= 0; i--) {
|
||||||
final Transition transition = copy.get(i);
|
final Transition transition = copy.get(i);
|
||||||
transition.end();
|
transition.forceToEnd(sceneRoot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package android.transition;
|
package android.transition;
|
||||||
|
|
||||||
import com.android.internal.R;
|
|
||||||
|
|
||||||
import android.animation.TimeInterpolator;
|
import android.animation.TimeInterpolator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.TypedArray;
|
import android.content.res.TypedArray;
|
||||||
@@ -26,6 +24,8 @@ import android.util.AttributeSet;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.android.internal.R;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,6 +498,16 @@ public class TransitionSet extends Transition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@Override
|
||||||
|
void forceToEnd(ViewGroup sceneRoot) {
|
||||||
|
super.forceToEnd(sceneRoot);
|
||||||
|
int numTransitions = mTransitions.size();
|
||||||
|
for (int i = 0; i < numTransitions; ++i) {
|
||||||
|
mTransitions.get(i).forceToEnd(sceneRoot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
TransitionSet setSceneRoot(ViewGroup sceneRoot) {
|
TransitionSet setSceneRoot(ViewGroup sceneRoot) {
|
||||||
super.setSceneRoot(sceneRoot);
|
super.setSceneRoot(sceneRoot);
|
||||||
|
|||||||
@@ -127,4 +127,6 @@
|
|||||||
<item type="id" name="accessibilityActionContextClick" />
|
<item type="id" name="accessibilityActionContextClick" />
|
||||||
|
|
||||||
<item type="id" name="remote_input_tag" />
|
<item type="id" name="remote_input_tag" />
|
||||||
|
|
||||||
|
<item type="id" name="cross_task_transition" />
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -2612,4 +2612,7 @@
|
|||||||
<java-symbol type="array" name="config_defaultPinnerServiceFiles" />
|
<java-symbol type="array" name="config_defaultPinnerServiceFiles" />
|
||||||
|
|
||||||
<java-symbol type="string" name="suspended_widget_accessibility" />
|
<java-symbol type="string" name="suspended_widget_accessibility" />
|
||||||
|
|
||||||
|
<!-- Used internally for assistant to launch activity transitions -->
|
||||||
|
<java-symbol type="id" name="cross_task_transition" />
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user