blob: b32e9ad615db71a868923f2861b2d8531b15db50 [file] [log] [blame]
/*
* Copyright (C) 2014 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 android.app;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.util.ArrayMap;
import android.view.View;
import android.view.Window;
import java.util.ArrayList;
/**
* This class contains all persistence-related functionality for Activity Transitions.
* Activities start exit and enter Activity Transitions through this class.
*/
class ActivityTransitionState {
private static final String ENTERING_SHARED_ELEMENTS = "android:enteringSharedElements";
private static final String ENTERING_MAPPED_FROM = "android:enteringMappedFrom";
private static final String ENTERING_MAPPED_TO = "android:enteringMappedTo";
private static final String EXITING_MAPPED_FROM = "android:exitingMappedFrom";
private static final String EXITING_MAPPED_TO = "android:exitingMappedTo";
/**
* The shared elements that the calling Activity has said that they transferred to this
* Activity.
*/
private ArrayList<String> mEnteringNames;
/**
* The shared elements that this Activity as accepted and mapped to local Views.
*/
private ArrayList<String> mEnteringFrom;
/**
* The names of local Views that are mapped to those elements in mEnteringFrom.
*/
private ArrayList<String> mEnteringTo;
/**
* The names of shared elements that were shared to the called Activity.
*/
private ArrayList<String> mExitingFrom;
/**
* The names of local Views that were shared out, mapped to those elements in mExitingFrom.
*/
private ArrayList<String> mExitingTo;
/**
* The ActivityOptions used to call an Activity. Used to make the elements restore
* Visibility of exited Views.
*/
private ActivityOptions mCalledActivityOptions;
/**
* We must be able to cancel entering transitions to stop changing the Window to
* opaque when we exit before making the Window opaque.
*/
private EnterTransitionCoordinator mEnterTransitionCoordinator;
/**
* ActivityOptions used on entering this Activity.
*/
private ActivityOptions mEnterActivityOptions;
/**
* Has an exit transition been started? If so, we don't want to double-exit.
*/
private boolean mHasExited;
public ActivityTransitionState() {
}
public void readState(Bundle bundle) {
if (bundle != null) {
if (mEnterTransitionCoordinator == null || mEnterTransitionCoordinator.isReturning()) {
mEnteringNames = bundle.getStringArrayList(ENTERING_SHARED_ELEMENTS);
mEnteringFrom = bundle.getStringArrayList(ENTERING_MAPPED_FROM);
mEnteringTo = bundle.getStringArrayList(ENTERING_MAPPED_TO);
}
if (mEnterTransitionCoordinator == null) {
mExitingFrom = bundle.getStringArrayList(EXITING_MAPPED_FROM);
mExitingTo = bundle.getStringArrayList(EXITING_MAPPED_TO);
}
}
}
public void saveState(Bundle bundle) {
if (mEnteringNames != null) {
bundle.putStringArrayList(ENTERING_SHARED_ELEMENTS, mEnteringNames);
bundle.putStringArrayList(ENTERING_MAPPED_FROM, mEnteringFrom);
bundle.putStringArrayList(ENTERING_MAPPED_TO, mEnteringTo);
}
if (mExitingFrom != null) {
bundle.putStringArrayList(EXITING_MAPPED_FROM, mExitingFrom);
bundle.putStringArrayList(EXITING_MAPPED_TO, mExitingTo);
}
}
public void setEnterActivityOptions(Activity activity, ActivityOptions options) {
if (activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)
&& options != null && mEnterActivityOptions == null
&& options.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
mEnterActivityOptions = options;
if (mEnterActivityOptions.isReturning()) {
int result = mEnterActivityOptions.getResultCode();
if (result != 0) {
activity.onActivityReenter(result, mEnterActivityOptions.getResultData());
}
}
}
}
public void enterReady(Activity activity) {
if (mEnterActivityOptions == null) {
return;
}
mHasExited = false;
ArrayList<String> sharedElementNames = mEnterActivityOptions.getSharedElementNames();
ResultReceiver resultReceiver = mEnterActivityOptions.getResultReceiver();
if (mEnterActivityOptions.isReturning()) {
restoreExitedViews();
activity.getWindow().getDecorView().setVisibility(View.VISIBLE);
mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
resultReceiver, sharedElementNames, mExitingFrom, mExitingTo);
} else {
mEnterTransitionCoordinator = new EnterTransitionCoordinator(activity,
resultReceiver, sharedElementNames, null, null);
mEnteringNames = sharedElementNames;
mEnteringFrom = mEnterTransitionCoordinator.getAcceptedNames();
mEnteringTo = mEnterTransitionCoordinator.getMappedNames();
}
mExitingFrom = null;
mExitingTo = null;
mEnterActivityOptions = null;
}
public void onStop() {
restoreExitedViews();
if (mEnterTransitionCoordinator != null) {
mEnterTransitionCoordinator.stop();
mEnterTransitionCoordinator = null;
}
}
public void onResume() {
restoreExitedViews();
}
private void restoreExitedViews() {
if (mCalledActivityOptions != null) {
mCalledActivityOptions.dispatchActivityStopped();
mCalledActivityOptions = null;
}
}
public boolean startExitBackTransition(Activity activity) {
if (mEnteringNames == null) {
return false;
} else {
if (!mHasExited) {
mHasExited = true;
if (mEnterTransitionCoordinator != null) {
mEnterTransitionCoordinator.stop();
mEnterTransitionCoordinator = null;
}
ArrayMap<String, View> sharedElements = new ArrayMap<String, View>();
activity.getWindow().getDecorView().findNamedViews(sharedElements);
ExitTransitionCoordinator exitCoordinator =
new ExitTransitionCoordinator(activity, mEnteringNames, mEnteringFrom,
mEnteringTo, true);
exitCoordinator.startExit(activity.mResultCode, activity.mResultData);
}
return true;
}
}
public void startExitOutTransition(Activity activity, Bundle options) {
if (!activity.getWindow().hasFeature(Window.FEATURE_CONTENT_TRANSITIONS)) {
return;
}
mCalledActivityOptions = new ActivityOptions(options);
if (mCalledActivityOptions.getAnimationType() == ActivityOptions.ANIM_SCENE_TRANSITION) {
mExitingFrom = mCalledActivityOptions.getSharedElementNames();
mExitingTo = mCalledActivityOptions.getLocalSharedElementNames();
mCalledActivityOptions.dispatchStartExit();
}
}
}