From cfbe9be5b3b701d95fb24fa0f7c8d9be43eec776 Mon Sep 17 00:00:00 2001 From: Adam Powell Date: Wed, 6 Nov 2013 14:58:58 -0800 Subject: Add support for cross-activity scenes and transitions * Add theme attributes for specifying a top-level TransitionManager for an activity window. * Add window feature for automatic content transitions. This automatically assigns/creates a Scene for setContentView calls. * Add named transitions. This allows apps to define APIs for handshake-agreements about which exit/entrance transitions to play. * Add new transition type for ActivityOptions. This lets the system use ActivityOptions to communicate transition specifics and arguments to the called activity. * Have ActivityManager pass appropriate ActivityOptions through to the called Activity. Have the called activity call back into the caller to let it know which transition of a possible requested set was chosen. Still to do: * Define and pass arguments for transitions. This will require defining a Parcelable version of TransitionValues and deciding how much leeway apps should have for these things. * Determine how to appropriately filter the ActivityOptions bundle so that only appropriate data reaches the target. * Determine if generalizing the auto-Scenes functionality to ViewGroups is appropriate. Change-Id: I10684b926129ab2fbc1adec9ef31767237acae79 --- core/java/android/app/ActivityThread.java | 37 +++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'core/java/android/app/ActivityThread.java') diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5e3dc02..e667bad 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -56,6 +56,7 @@ import android.os.DropBoxManager; import android.os.Environment; import android.os.Handler; import android.os.IBinder; +import android.os.IRemoteCallback; import android.os.Looper; import android.os.Message; import android.os.MessageQueue; @@ -68,12 +69,15 @@ import android.os.SystemClock; import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; +import android.transition.Scene; +import android.transition.TransitionManager; import android.util.AndroidRuntimeException; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; import android.util.LogPrinter; +import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SuperNotCalledException; @@ -284,6 +288,7 @@ public final class ActivityThread { boolean isForward; int pendingConfigChanges; boolean onlyLocalRequest; + Bundle activityOptions; View mPendingRemoveWindow; WindowManager mPendingRemoveWindowManager; @@ -576,9 +581,10 @@ public final class ActivityThread { } public final void scheduleResumeActivity(IBinder token, int processState, - boolean isForward) { + boolean isForward, Bundle resumeArgs) { updateProcessState(processState, false); - sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0); + sendMessage(H.RESUME_ACTIVITY, new Pair(token, resumeArgs), + isForward ? 1 : 0); } public final void scheduleSendResult(IBinder token, List results) { @@ -594,7 +600,8 @@ public final class ActivityThread { ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, int procState, Bundle state, List pendingResults, List pendingNewIntents, boolean notResumed, boolean isForward, - String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { + String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler, + Bundle resumeArgs) { updateProcessState(procState, false); @@ -616,6 +623,7 @@ public final class ActivityThread { r.profileFile = profileName; r.profileFd = profileFd; r.autoStopProfiler = autoStopProfiler; + r.activityOptions = resumeArgs; updatePendingConfiguration(curConfig); @@ -1189,7 +1197,7 @@ public final class ActivityThread { switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); - ActivityClientRecord r = (ActivityClientRecord)msg.obj; + final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck( r.activityInfo.applicationInfo, r.compatInfo); @@ -1235,7 +1243,8 @@ public final class ActivityThread { break; case RESUME_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); - handleResumeActivity((IBinder)msg.obj, true, + final Pair resumeArgs = (Pair) msg.obj; + handleResumeActivity(resumeArgs.first, resumeArgs.second, true, msg.arg1 != 0, true); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; @@ -2032,7 +2041,7 @@ public final class ActivityThread { + ", comp=" + name + ", token=" + token); } - return performLaunchActivity(r, null); + return performLaunchActivity(r, null, null); } public final Activity getActivity(IBinder token) { @@ -2085,7 +2094,8 @@ public final class ActivityThread { sendMessage(H.CLEAN_UP_CONTEXT, cci); } - private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { + private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent, + Bundle options) { // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); ActivityInfo aInfo = r.activityInfo; @@ -2143,7 +2153,7 @@ public final class ActivityThread { + r.activityInfo.name + " with config " + config); activity.attach(appContext, this, getInstrumentation(), r.token, r.ident, app, r.intent, r.activityInfo, title, r.parent, - r.embeddedID, r.lastNonConfigurationInstances, config); + r.embeddedID, r.lastNonConfigurationInstances, config, options); if (customIntent != null) { activity.mIntent = customIntent; @@ -2242,12 +2252,13 @@ public final class ActivityThread { if (localLOGV) Slog.v( TAG, "Handling launch of " + r); - Activity a = performLaunchActivity(r, customIntent); + + Activity a = performLaunchActivity(r, customIntent, r.activityOptions); if (a != null) { r.createdConfig = new Configuration(mConfiguration); Bundle oldState = r.state; - handleResumeActivity(r.token, false, r.isForward, + handleResumeActivity(r.token, r.activityOptions, false, r.isForward, !r.activity.mFinished && !r.startsNotResumed); if (!r.activity.mFinished && r.startsNotResumed) { @@ -2808,12 +2819,13 @@ public final class ActivityThread { r.mPendingRemoveWindowManager = null; } - final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, - boolean reallyResume) { + final void handleResumeActivity(IBinder token, Bundle resumeArgs, + boolean clearHide, boolean isForward, boolean reallyResume) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); + // TODO Push resumeArgs into the activity for consideration ActivityClientRecord r = performResumeActivity(token, clearHide); if (r != null) { @@ -3734,6 +3746,7 @@ public final class ActivityThread { } } r.startsNotResumed = tmp.startsNotResumed; + r.activityOptions = null; handleLaunchActivity(r, currentIntent); } -- cgit v1.1