Start using the new activity options argument.
New class lets you make an options bundle defining a custom animation,
as an alternative to Activity.overridePendingTransition().
Change-Id: I8e209bf52398a98ab9f1bcafa1ec0a580dae57c0
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index caee1ab..d21212f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2258,7 +2258,7 @@
for (int i=0; i<N; i++) {
PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
- pal.startFlags, doResume && i == (N-1));
+ pal.startFlags, doResume && i == (N-1), null);
}
mPendingActivityLaunches.clear();
}
@@ -4252,7 +4252,8 @@
public IIntentSender getIntentSender(int type,
String packageName, IBinder token, String resultWho,
- int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
+ int requestCode, Intent[] intents, String[] resolvedTypes,
+ int flags, Bundle options) {
enforceNotIsolatedCaller("getIntentSender");
// Refuse possible leaked file descriptors
if (intents != null) {
@@ -4278,6 +4279,11 @@
"Intent array length does not match resolvedTypes length");
}
}
+ if (options != null) {
+ if (options.hasFileDescriptors()) {
+ throw new IllegalArgumentException("File descriptors passed in options");
+ }
+ }
synchronized(this) {
int callingUid = Binder.getCallingUid();
@@ -4300,7 +4306,7 @@
Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
+ Binder.getOrigCallingUid());
return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
- token, resultWho, requestCode, intents, resolvedTypes, flags);
+ token, resultWho, requestCode, intents, resolvedTypes, flags, options);
} catch (RemoteException e) {
throw new SecurityException(e);
@@ -4310,7 +4316,8 @@
IIntentSender getIntentSenderLocked(int type,
String packageName, int callingUid, IBinder token, String resultWho,
- int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
+ int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
+ Bundle options) {
if (DEBUG_MU)
Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
ActivityRecord activity = null;
@@ -4332,7 +4339,7 @@
PendingIntentRecord.Key key = new PendingIntentRecord.Key(
type, packageName, activity, resultWho,
- requestCode, intents, resolvedTypes, flags);
+ requestCode, intents, resolvedTypes, flags, options);
WeakReference<PendingIntentRecord> ref;
ref = mIntentSenderRecords.get(key);
PendingIntentRecord rec = ref != null ? ref.get() : null;
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index b42d98ea..53cb2b0 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -20,6 +20,7 @@
import com.android.server.am.ActivityStack.ActivityState;
import android.app.Activity;
+import android.app.ActivityOptions;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -95,6 +96,7 @@
ArrayList results; // pending ActivityResult objs we have received
HashSet<WeakReference<PendingIntentRecord>> pendingResults; // all pending intents for this act
ArrayList newIntents; // any pending new intents for single-top mode
+ ActivityOptions pendingOptions; // most recently given options
HashSet<ConnectionRecord> connections; // All ConnectionRecord we hold
UriPermissionOwner uriPermissions; // current special URI access perms.
ProcessRecord app; // if non-null, hosting application
@@ -538,6 +540,28 @@
}
}
+ void updateOptionsLocked(Bundle options) {
+ if (options != null) {
+ pendingOptions = new ActivityOptions(options);
+ }
+ }
+
+ void applyOptionsLocked() {
+ if (pendingOptions != null) {
+ if (pendingOptions.isCustomAnimation()) {
+ service.mWindowManager.overridePendingAppTransition(
+ pendingOptions.getPackageName(),
+ pendingOptions.getCustomEnterResId(),
+ pendingOptions.getCustomExitResId());
+ }
+ pendingOptions = null;
+ }
+ }
+
+ void clearOptionsLocked() {
+ pendingOptions = null;
+ }
+
void removeUriPermissionsLocked() {
if (uriPermissions != null) {
uriPermissions.removeUriPermissionsLocked();
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 13ee008..7e8df35 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -22,6 +22,7 @@
import android.app.Activity;
import android.app.ActivityManager;
+import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.app.IActivityManager;
import android.app.IThumbnailRetriever;
@@ -1456,6 +1457,7 @@
// We are starting up the next activity, so tell the window manager
// that the previous one will be hidden soon. This way it can know
// to ignore it when computing the desired screen orientation.
+ boolean noAnim = false;
if (prev != null) {
if (prev.finishing) {
if (DEBUG_TRANSITION) Slog.v(TAG,
@@ -1474,6 +1476,7 @@
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: prev=" + prev);
if (mNoAnimActivities.contains(next)) {
+ noAnim = true;
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, false);
} else {
@@ -1490,6 +1493,7 @@
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare open transition: no previous");
if (mNoAnimActivities.contains(next)) {
+ noAnim = true;
mService.mWindowManager.prepareAppTransition(
WindowManagerPolicy.TRANSIT_NONE, false);
} else {
@@ -1497,6 +1501,11 @@
WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, false);
}
}
+ if (!noAnim) {
+ next.applyOptionsLocked();
+ } else {
+ next.clearOptionsLocked();
+ }
if (next.app != null && next.app.thread != null) {
if (DEBUG_SWITCH) Slog.v(TAG, "Resume running: " + next);
@@ -1655,7 +1664,7 @@
}
private final void startActivityLocked(ActivityRecord r, boolean newTask,
- boolean doResume, boolean keepCurTransition) {
+ boolean doResume, boolean keepCurTransition, Bundle options) {
final int NH = mHistory.size();
int addPos = -1;
@@ -1748,6 +1757,7 @@
: WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN, keepCurTransition);
mNoAnimActivities.remove(r);
}
+ r.updateOptionsLocked(options);
mService.mWindowManager.addAppToken(
addPos, r.appToken, r.task.taskId, r.info.screenOrientation, r.fullscreen);
boolean doShow = true;
@@ -2457,7 +2467,7 @@
}
err = startActivityUncheckedLocked(r, sourceRecord,
- startFlags, true);
+ startFlags, true, options);
if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
// Someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
@@ -2480,7 +2490,8 @@
}
final int startActivityUncheckedLocked(ActivityRecord r,
- ActivityRecord sourceRecord, int startFlags, boolean doResume) {
+ ActivityRecord sourceRecord, int startFlags, boolean doResume,
+ Bundle options) {
final Intent intent = r.intent;
final int callingUid = r.launchedFromUid;
final int userId = r.userId;
@@ -2591,6 +2602,7 @@
// We really do want to push this one into the
// user's face, right now.
moveHomeToFrontFromLaunchLocked(launchFlags);
+ r.updateOptionsLocked(options);
moveTaskToFrontLocked(taskTop.task, r);
}
}
@@ -2794,6 +2806,7 @@
if (where >= 0) {
ActivityRecord top = moveActivityToFrontLocked(where);
logStartActivity(EventLogTags.AM_NEW_INTENT, r, top.task);
+ top.updateOptionsLocked(options);
top.deliverNewIntentLocked(callingUid, r.intent);
if (doResume) {
resumeTopActivityLocked(null);
@@ -2829,7 +2842,7 @@
EventLog.writeEvent(EventLogTags.AM_CREATE_TASK, r.task.taskId);
}
logStartActivity(EventLogTags.AM_CREATE_ACTIVITY, r, r.task);
- startActivityLocked(r, newTask, doResume, keepCurTransition);
+ startActivityLocked(r, newTask, doResume, keepCurTransition, options);
return ActivityManager.START_SUCCESS;
}
@@ -2944,7 +2957,7 @@
ActivityManager.INTENT_SENDER_ACTIVITY, "android",
realCallingUid, null, null, 0, new Intent[] { intent },
new String[] { resolvedType }, PendingIntent.FLAG_CANCEL_CURRENT
- | PendingIntent.FLAG_ONE_SHOT);
+ | PendingIntent.FLAG_ONE_SHOT, null);
Intent newIntent = new Intent();
if (requestCode >= 0) {
@@ -3095,9 +3108,15 @@
"FLAG_CANT_SAVE_STATE not supported here");
}
+ Bundle theseOptions;
+ if (options != null && i == intents.length-1) {
+ theseOptions = options;
+ } else {
+ theseOptions = null;
+ }
int res = startActivityLocked(caller, intent, resolvedTypes[i],
aInfo, resultTo, null, -1, callingPid, callingUid,
- 0, options, componentSpecified, outActivity);
+ 0, theseOptions, componentSpecified, outActivity);
if (res < 0) {
return res;
}
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 9676084..ad15da1 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -49,6 +49,7 @@
final int requestCode;
final Intent requestIntent;
final String requestResolvedType;
+ final Bundle options;
Intent[] allIntents;
String[] allResolvedTypes;
final int flags;
@@ -57,7 +58,7 @@
private static final int ODD_PRIME_NUMBER = 37;
Key(int _t, String _p, ActivityRecord _a, String _w,
- int _r, Intent[] _i, String[] _it, int _f) {
+ int _r, Intent[] _i, String[] _it, int _f, Bundle _o) {
type = _t;
packageName = _p;
activity = _a;
@@ -68,6 +69,7 @@
allIntents = _i;
allResolvedTypes = _it;
flags = _f;
+ options = _o;
int hash = 23;
hash = (ODD_PRIME_NUMBER*hash) + _f;
@@ -215,6 +217,13 @@
boolean sendFinish = finishedReceiver != null;
switch (key.type) {
case ActivityManager.INTENT_SENDER_ACTIVITY:
+ if (options == null) {
+ options = key.options;
+ } else if (key.options != null) {
+ Bundle opts = new Bundle(key.options);
+ opts.putAll(options);
+ options = opts;
+ }
try {
if (key.allIntents != null && key.allIntents.length > 1) {
Intent[] allIntents = new Intent[key.allIntents.length];