Loading core/java/android/app/ActivityManagerInternal.java +2 −1 Original line number Diff line number Diff line Loading @@ -1328,7 +1328,8 @@ public abstract class ActivityManagerInternal { * Add a creator token for all embedded intents (stored as extra) of the given intent. * * @param intent The given intent * @param creatorPackage the package name of the creator app. * @hide */ public abstract void addCreatorToken(Intent intent); public abstract void addCreatorToken(Intent intent, String creatorPackage); } core/java/android/content/Intent.java +42 −3 Original line number Diff line number Diff line Loading @@ -888,6 +888,22 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_ACTIVITY_RECOGNIZER = "android.intent.action.ACTIVITY_RECOGNIZER"; /** @hide */ public static void maybeMarkAsMissingCreatorToken(Object object) { if (object instanceof Intent intent) { maybeMarkAsMissingCreatorTokenInternal(intent); } } private static void maybeMarkAsMissingCreatorTokenInternal(Intent intent) { boolean isForeign = (intent.mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0; boolean isWithoutTrustedCreatorToken = (intent.mLocalFlags & Intent.LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT) == 0; if (isForeign && isWithoutTrustedCreatorToken) { intent.addExtendedFlags(EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN); } } /** * Represents a shortcut/live folder icon resource. * Loading Loading @@ -7684,10 +7700,8 @@ public class Intent implements Parcelable, Cloneable { /** * This flag indicates the creator token of this intent has been verified. * * @hide */ public static final int LOCAL_FLAG_CREATOR_TOKEN_VERIFIED = 1 << 6; private static final int LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT = 1 << 6; /** @hide */ @IntDef(flag = true, prefix = { "EXTENDED_FLAG_" }, value = { Loading Loading @@ -12243,6 +12257,30 @@ public class Intent implements Parcelable, Cloneable { } } /** @hide */ public void checkCreatorToken() { if (mExtras == null) return; if (mCreatorTokenInfo != null && mCreatorTokenInfo.mExtraIntentKeys != null) { for (String key : mCreatorTokenInfo.mExtraIntentKeys) { try { Intent extraIntent = mExtras.getParcelable(key, Intent.class); if (extraIntent == null) { Log.w(TAG, "The key {" + key + "} does not correspond to an intent in the bundle."); continue; } extraIntent.mLocalFlags |= LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT; } catch (Exception e) { Log.e(TAG, "Failed to validate creator token. key: " + key + ".", e); } } } // mark the bundle as intent extras after calls to getParcelable. // otherwise, the logic to mark missing token would run before // mark trusted creator token present. mExtras.setIsIntentExtra(); } public void writeToParcel(Parcel out, int flags) { out.writeString8(mAction); Uri.writeToParcel(out, mData); Loading Loading @@ -12730,6 +12768,7 @@ public class Intent implements Parcelable, Cloneable { } mLocalFlags |= localFlags; checkCreatorToken(); // Special attribution fix-up logic for any BluetoothDevice extras // passed via Bluetooth intents core/java/android/os/BaseBundle.java +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.util.ArrayMap; import android.util.Log; import android.util.MathUtils; Loading Loading @@ -401,6 +402,9 @@ public class BaseBundle { synchronized (this) { object = unwrapLazyValueFromMapLocked(i, clazz, itemTypes); } if ((mFlags & Bundle.FLAG_VERIFY_TOKENS_PRESENT) != 0) { Intent.maybeMarkAsMissingCreatorToken(object); } } return (clazz != null) ? clazz.cast(object) : (T) object; } Loading core/java/android/os/Bundle.java +11 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @VisibleForTesting static final int FLAG_HAS_BINDERS = 1 << 12; /** * Indicates there may be intents with creator tokens contained in this bundle. When unparceled, * they should be verified if tokens are missing or invalid. */ static final int FLAG_VERIFY_TOKENS_PRESENT = 1 << 13; /** * Status when the Bundle can <b>assert</b> that the underlying Parcel DOES NOT contain Loading Loading @@ -274,6 +280,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { return orig; } /** {@hide} */ public void setIsIntentExtra() { mFlags |= FLAG_VERIFY_TOKENS_PRESENT; } /** * Mark if this Bundle is okay to "defuse." That is, it's okay for system * processes to ignore any {@link BadParcelableException} encountered when Loading services/core/java/com/android/server/am/ActivityManagerService.java +42 −30 Original line number Diff line number Diff line Loading @@ -5542,7 +5542,6 @@ public class ActivityManagerService extends IActivityManager.Stub public int sendIntentSender(IApplicationThread caller, IIntentSender target, IBinder allowlistToken, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { addCreatorToken(intent); if (target instanceof PendingIntentRecord) { final PendingIntentRecord originalRecord = (PendingIntentRecord) target; Loading Loading @@ -5584,7 +5583,6 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { if (allowlistToken != null) { final int callingUid = Binder.getCallingUid(); final String packageName; final long token = Binder.clearCallingIdentity(); Loading @@ -5593,10 +5591,15 @@ public class ActivityManagerService extends IActivityManager.Stub } finally { Binder.restoreCallingIdentity(token); } if (allowlistToken != null) { Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target." + " Calling package: " + packageName + "; intent: " + intent + "; options: " + options); } addCreatorToken(intent, packageName); target.send(code, intent, resolvedType, null, null, requiredPermission, options); } catch (RemoteException e) { Loading Loading @@ -13628,7 +13631,7 @@ public class ActivityManagerService extends IActivityManager.Stub throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); enforceAllowedToStartOrBindServiceIfSdkSandbox(service); addCreatorToken(service); addCreatorToken(service, callingPackage); if (service != null) { // Refuse possible leaked file descriptors if (service.hasFileDescriptors()) { Loading Loading @@ -13890,7 +13893,7 @@ public class ActivityManagerService extends IActivityManager.Stub validateServiceInstanceName(instanceName); addCreatorToken(service); addCreatorToken(service, callingPackage); try { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { final ComponentName cn = service.getComponent(); Loading Loading @@ -17174,7 +17177,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); } addCreatorToken(service); addCreatorToken(service, callingPackage); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { Loading Loading @@ -18002,8 +18005,8 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override public void addCreatorToken(Intent intent) { ActivityManagerService.this.addCreatorToken(intent); public void addCreatorToken(Intent intent, String creatorPackage) { ActivityManagerService.this.addCreatorToken(intent, creatorPackage); } } Loading Loading @@ -19160,9 +19163,9 @@ public class ActivityManagerService extends IActivityManager.Stub private final Key mKeyFields; private final WeakReference<IntentCreatorToken> mRef; public IntentCreatorToken(int creatorUid, Intent intent) { public IntentCreatorToken(int creatorUid, String creatorPackage, Intent intent) { super(); this.mKeyFields = new Key(creatorUid, intent); this.mKeyFields = new Key(creatorUid, creatorPackage, intent); mRef = new WeakReference<>(this); } Loading @@ -19170,7 +19173,10 @@ public class ActivityManagerService extends IActivityManager.Stub return mKeyFields.mCreatorUid; } /** {@hide} */ public String getCreatorPackage() { return mKeyFields.mCreatorPackage; } public static boolean isValid(@NonNull Intent intent) { IBinder binder = intent.getCreatorToken(); IntentCreatorToken token = null; Loading @@ -19178,7 +19184,8 @@ public class ActivityManagerService extends IActivityManager.Stub token = (IntentCreatorToken) binder; } return token != null && token.mKeyFields.equals( new Key(token.mKeyFields.mCreatorUid, intent)); new Key(token.mKeyFields.mCreatorUid, token.mKeyFields.mCreatorPackage, intent)); } @Override Loading @@ -19202,8 +19209,9 @@ public class ActivityManagerService extends IActivityManager.Stub } private static class Key { private Key(int creatorUid, Intent intent) { private Key(int creatorUid, String creatorPackage, Intent intent) { this.mCreatorUid = creatorUid; this.mCreatorPackage = creatorPackage; this.mAction = intent.getAction(); this.mData = intent.getData(); this.mType = intent.getType(); Loading @@ -19220,6 +19228,7 @@ public class ActivityManagerService extends IActivityManager.Stub } private final int mCreatorUid; private final String mCreatorPackage; private final String mAction; private final Uri mData; private final String mType; Loading @@ -19233,17 +19242,20 @@ public class ActivityManagerService extends IActivityManager.Stub if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Key key = (Key) o; return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags && Objects.equals( mAction, key.mAction) && Objects.equals(mData, key.mData) && Objects.equals(mType, key.mType) && Objects.equals(mPackage, key.mPackage) && Objects.equals(mComponent, key.mComponent) return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags && Objects.equals(mCreatorPackage, key.mCreatorPackage) && Objects.equals(mAction, key.mAction) && Objects.equals(mData, key.mData) && Objects.equals(mType, key.mType) && Objects.equals(mPackage, key.mPackage) && Objects.equals(mComponent, key.mComponent) && Objects.equals(mClipDataUris, key.mClipDataUris); } @Override public int hashCode() { return Objects.hash(mCreatorUid, mAction, mData, mType, mPackage, mComponent, mFlags, mClipDataUris); return Objects.hash(mCreatorUid, mCreatorPackage, mAction, mData, mType, mPackage, mComponent, mFlags, mClipDataUris); } } } Loading @@ -19254,7 +19266,7 @@ public class ActivityManagerService extends IActivityManager.Stub * @param intent The given intent * @hide */ public void addCreatorToken(@Nullable Intent intent) { public void addCreatorToken(@Nullable Intent intent, String creatorPackage) { if (!preventIntentRedirect()) return; if (intent == null || intent.getExtraIntentKeys() == null) return; Loading @@ -19267,7 +19279,7 @@ public class ActivityManagerService extends IActivityManager.Stub continue; } Slog.wtf(TAG, "A creator token is added to an intent."); IBinder creatorToken = createIntentCreatorToken(extraIntent); IBinder creatorToken = createIntentCreatorToken(extraIntent, creatorPackage); if (creatorToken != null) { extraIntent.setCreatorToken(creatorToken); } Loading @@ -19280,15 +19292,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } private IBinder createIntentCreatorToken(Intent intent) { private IBinder createIntentCreatorToken(Intent intent, String creatorPackage) { if (IntentCreatorToken.isValid(intent)) return null; int creatorUid = getCallingUid(); IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, intent); IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, creatorPackage, intent); IntentCreatorToken token; synchronized (sIntentCreatorTokenCache) { WeakReference<IntentCreatorToken> ref = sIntentCreatorTokenCache.get(key); if (ref == null || ref.get() == null) { token = new IntentCreatorToken(creatorUid, intent); token = new IntentCreatorToken(creatorUid, creatorPackage, intent); sIntentCreatorTokenCache.put(key, token.mRef); } else { token = ref.get(); Loading
core/java/android/app/ActivityManagerInternal.java +2 −1 Original line number Diff line number Diff line Loading @@ -1328,7 +1328,8 @@ public abstract class ActivityManagerInternal { * Add a creator token for all embedded intents (stored as extra) of the given intent. * * @param intent The given intent * @param creatorPackage the package name of the creator app. * @hide */ public abstract void addCreatorToken(Intent intent); public abstract void addCreatorToken(Intent intent, String creatorPackage); }
core/java/android/content/Intent.java +42 −3 Original line number Diff line number Diff line Loading @@ -888,6 +888,22 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_ACTIVITY_RECOGNIZER = "android.intent.action.ACTIVITY_RECOGNIZER"; /** @hide */ public static void maybeMarkAsMissingCreatorToken(Object object) { if (object instanceof Intent intent) { maybeMarkAsMissingCreatorTokenInternal(intent); } } private static void maybeMarkAsMissingCreatorTokenInternal(Intent intent) { boolean isForeign = (intent.mLocalFlags & LOCAL_FLAG_FROM_PARCEL) != 0; boolean isWithoutTrustedCreatorToken = (intent.mLocalFlags & Intent.LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT) == 0; if (isForeign && isWithoutTrustedCreatorToken) { intent.addExtendedFlags(EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN); } } /** * Represents a shortcut/live folder icon resource. * Loading Loading @@ -7684,10 +7700,8 @@ public class Intent implements Parcelable, Cloneable { /** * This flag indicates the creator token of this intent has been verified. * * @hide */ public static final int LOCAL_FLAG_CREATOR_TOKEN_VERIFIED = 1 << 6; private static final int LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT = 1 << 6; /** @hide */ @IntDef(flag = true, prefix = { "EXTENDED_FLAG_" }, value = { Loading Loading @@ -12243,6 +12257,30 @@ public class Intent implements Parcelable, Cloneable { } } /** @hide */ public void checkCreatorToken() { if (mExtras == null) return; if (mCreatorTokenInfo != null && mCreatorTokenInfo.mExtraIntentKeys != null) { for (String key : mCreatorTokenInfo.mExtraIntentKeys) { try { Intent extraIntent = mExtras.getParcelable(key, Intent.class); if (extraIntent == null) { Log.w(TAG, "The key {" + key + "} does not correspond to an intent in the bundle."); continue; } extraIntent.mLocalFlags |= LOCAL_FLAG_TRUSTED_CREATOR_TOKEN_PRESENT; } catch (Exception e) { Log.e(TAG, "Failed to validate creator token. key: " + key + ".", e); } } } // mark the bundle as intent extras after calls to getParcelable. // otherwise, the logic to mark missing token would run before // mark trusted creator token present. mExtras.setIsIntentExtra(); } public void writeToParcel(Parcel out, int flags) { out.writeString8(mAction); Uri.writeToParcel(out, mData); Loading Loading @@ -12730,6 +12768,7 @@ public class Intent implements Parcelable, Cloneable { } mLocalFlags |= localFlags; checkCreatorToken(); // Special attribution fix-up logic for any BluetoothDevice extras // passed via Bluetooth intents
core/java/android/os/BaseBundle.java +4 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static java.util.Objects.requireNonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.Intent; import android.util.ArrayMap; import android.util.Log; import android.util.MathUtils; Loading Loading @@ -401,6 +402,9 @@ public class BaseBundle { synchronized (this) { object = unwrapLazyValueFromMapLocked(i, clazz, itemTypes); } if ((mFlags & Bundle.FLAG_VERIFY_TOKENS_PRESENT) != 0) { Intent.maybeMarkAsMissingCreatorToken(object); } } return (clazz != null) ? clazz.cast(object) : (T) object; } Loading
core/java/android/os/Bundle.java +11 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,12 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { @VisibleForTesting static final int FLAG_HAS_BINDERS = 1 << 12; /** * Indicates there may be intents with creator tokens contained in this bundle. When unparceled, * they should be verified if tokens are missing or invalid. */ static final int FLAG_VERIFY_TOKENS_PRESENT = 1 << 13; /** * Status when the Bundle can <b>assert</b> that the underlying Parcel DOES NOT contain Loading Loading @@ -274,6 +280,11 @@ public final class Bundle extends BaseBundle implements Cloneable, Parcelable { return orig; } /** {@hide} */ public void setIsIntentExtra() { mFlags |= FLAG_VERIFY_TOKENS_PRESENT; } /** * Mark if this Bundle is okay to "defuse." That is, it's okay for system * processes to ignore any {@link BadParcelableException} encountered when Loading
services/core/java/com/android/server/am/ActivityManagerService.java +42 −30 Original line number Diff line number Diff line Loading @@ -5542,7 +5542,6 @@ public class ActivityManagerService extends IActivityManager.Stub public int sendIntentSender(IApplicationThread caller, IIntentSender target, IBinder allowlistToken, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) { addCreatorToken(intent); if (target instanceof PendingIntentRecord) { final PendingIntentRecord originalRecord = (PendingIntentRecord) target; Loading Loading @@ -5584,7 +5583,6 @@ public class ActivityManagerService extends IActivityManager.Stub intent = new Intent(Intent.ACTION_MAIN); } try { if (allowlistToken != null) { final int callingUid = Binder.getCallingUid(); final String packageName; final long token = Binder.clearCallingIdentity(); Loading @@ -5593,10 +5591,15 @@ public class ActivityManagerService extends IActivityManager.Stub } finally { Binder.restoreCallingIdentity(token); } if (allowlistToken != null) { Slog.wtf(TAG, "Send a non-null allowlistToken to a non-PI target." + " Calling package: " + packageName + "; intent: " + intent + "; options: " + options); } addCreatorToken(intent, packageName); target.send(code, intent, resolvedType, null, null, requiredPermission, options); } catch (RemoteException e) { Loading Loading @@ -13628,7 +13631,7 @@ public class ActivityManagerService extends IActivityManager.Stub throws TransactionTooLargeException { enforceNotIsolatedCaller("startService"); enforceAllowedToStartOrBindServiceIfSdkSandbox(service); addCreatorToken(service); addCreatorToken(service, callingPackage); if (service != null) { // Refuse possible leaked file descriptors if (service.hasFileDescriptors()) { Loading Loading @@ -13890,7 +13893,7 @@ public class ActivityManagerService extends IActivityManager.Stub validateServiceInstanceName(instanceName); addCreatorToken(service); addCreatorToken(service, callingPackage); try { if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) { final ComponentName cn = service.getComponent(); Loading Loading @@ -17174,7 +17177,7 @@ public class ActivityManagerService extends IActivityManager.Stub Slog.v(TAG_SERVICE, "startServiceInPackage: " + service + " type=" + resolvedType); } addCreatorToken(service); addCreatorToken(service, callingPackage); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { Loading Loading @@ -18002,8 +18005,8 @@ public class ActivityManagerService extends IActivityManager.Stub } @Override public void addCreatorToken(Intent intent) { ActivityManagerService.this.addCreatorToken(intent); public void addCreatorToken(Intent intent, String creatorPackage) { ActivityManagerService.this.addCreatorToken(intent, creatorPackage); } } Loading Loading @@ -19160,9 +19163,9 @@ public class ActivityManagerService extends IActivityManager.Stub private final Key mKeyFields; private final WeakReference<IntentCreatorToken> mRef; public IntentCreatorToken(int creatorUid, Intent intent) { public IntentCreatorToken(int creatorUid, String creatorPackage, Intent intent) { super(); this.mKeyFields = new Key(creatorUid, intent); this.mKeyFields = new Key(creatorUid, creatorPackage, intent); mRef = new WeakReference<>(this); } Loading @@ -19170,7 +19173,10 @@ public class ActivityManagerService extends IActivityManager.Stub return mKeyFields.mCreatorUid; } /** {@hide} */ public String getCreatorPackage() { return mKeyFields.mCreatorPackage; } public static boolean isValid(@NonNull Intent intent) { IBinder binder = intent.getCreatorToken(); IntentCreatorToken token = null; Loading @@ -19178,7 +19184,8 @@ public class ActivityManagerService extends IActivityManager.Stub token = (IntentCreatorToken) binder; } return token != null && token.mKeyFields.equals( new Key(token.mKeyFields.mCreatorUid, intent)); new Key(token.mKeyFields.mCreatorUid, token.mKeyFields.mCreatorPackage, intent)); } @Override Loading @@ -19202,8 +19209,9 @@ public class ActivityManagerService extends IActivityManager.Stub } private static class Key { private Key(int creatorUid, Intent intent) { private Key(int creatorUid, String creatorPackage, Intent intent) { this.mCreatorUid = creatorUid; this.mCreatorPackage = creatorPackage; this.mAction = intent.getAction(); this.mData = intent.getData(); this.mType = intent.getType(); Loading @@ -19220,6 +19228,7 @@ public class ActivityManagerService extends IActivityManager.Stub } private final int mCreatorUid; private final String mCreatorPackage; private final String mAction; private final Uri mData; private final String mType; Loading @@ -19233,17 +19242,20 @@ public class ActivityManagerService extends IActivityManager.Stub if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Key key = (Key) o; return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags && Objects.equals( mAction, key.mAction) && Objects.equals(mData, key.mData) && Objects.equals(mType, key.mType) && Objects.equals(mPackage, key.mPackage) && Objects.equals(mComponent, key.mComponent) return mCreatorUid == key.mCreatorUid && mFlags == key.mFlags && Objects.equals(mCreatorPackage, key.mCreatorPackage) && Objects.equals(mAction, key.mAction) && Objects.equals(mData, key.mData) && Objects.equals(mType, key.mType) && Objects.equals(mPackage, key.mPackage) && Objects.equals(mComponent, key.mComponent) && Objects.equals(mClipDataUris, key.mClipDataUris); } @Override public int hashCode() { return Objects.hash(mCreatorUid, mAction, mData, mType, mPackage, mComponent, mFlags, mClipDataUris); return Objects.hash(mCreatorUid, mCreatorPackage, mAction, mData, mType, mPackage, mComponent, mFlags, mClipDataUris); } } } Loading @@ -19254,7 +19266,7 @@ public class ActivityManagerService extends IActivityManager.Stub * @param intent The given intent * @hide */ public void addCreatorToken(@Nullable Intent intent) { public void addCreatorToken(@Nullable Intent intent, String creatorPackage) { if (!preventIntentRedirect()) return; if (intent == null || intent.getExtraIntentKeys() == null) return; Loading @@ -19267,7 +19279,7 @@ public class ActivityManagerService extends IActivityManager.Stub continue; } Slog.wtf(TAG, "A creator token is added to an intent."); IBinder creatorToken = createIntentCreatorToken(extraIntent); IBinder creatorToken = createIntentCreatorToken(extraIntent, creatorPackage); if (creatorToken != null) { extraIntent.setCreatorToken(creatorToken); } Loading @@ -19280,15 +19292,15 @@ public class ActivityManagerService extends IActivityManager.Stub } } private IBinder createIntentCreatorToken(Intent intent) { private IBinder createIntentCreatorToken(Intent intent, String creatorPackage) { if (IntentCreatorToken.isValid(intent)) return null; int creatorUid = getCallingUid(); IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, intent); IntentCreatorToken.Key key = new IntentCreatorToken.Key(creatorUid, creatorPackage, intent); IntentCreatorToken token; synchronized (sIntentCreatorTokenCache) { WeakReference<IntentCreatorToken> ref = sIntentCreatorTokenCache.get(key); if (ref == null || ref.get() == null) { token = new IntentCreatorToken(creatorUid, intent); token = new IntentCreatorToken(creatorUid, creatorPackage, intent); sIntentCreatorTokenCache.put(key, token.mRef); } else { token = ref.get();