Apply AttributionSource during Intent delivery.
There are some Parcelables which offer to perform Binder calls, and when these are delivered via Intent extras they fallback to ActivityThread.currentAttributionSource(), instead of being tagged based on the relevant app component. This change begins using Intent.prepareToEnterProcess() as a hook to fix-up AttributionSource when those extras finally land in the destination process. It uses the relevant AttributionSource based on the Activity or Service the Intent is delivered to, which developers have control over via AppComponentFactory. In the case of <receiver> manifest elements, this change applies the first android:attributionTags value to the Context used for that BroadcastReceiver. Bug: 187097694 Test: atest AttributionTest Change-Id: I8f5197db7e8d7277d34f0ef2bb90bfdf1871186a
This commit is contained in:
@@ -3509,7 +3509,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
cl, component.getClassName(), r.intent);
|
||||
StrictMode.incrementExpectedActivityCount(activity.getClass());
|
||||
r.intent.setExtrasClassLoader(cl);
|
||||
r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
|
||||
r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
|
||||
activity.getAttributionSource());
|
||||
if (r.state != null) {
|
||||
r.state.setClassLoader(cl);
|
||||
}
|
||||
@@ -3801,7 +3802,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
for (int i=0; i<N; i++) {
|
||||
ReferrerIntent intent = intents.get(i);
|
||||
intent.setExtrasClassLoader(r.activity.getClassLoader());
|
||||
intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
|
||||
intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
|
||||
r.activity.getAttributionSource());
|
||||
r.activity.mFragments.noteStateNotSaved();
|
||||
mInstrumentation.callActivityOnNewIntent(r.activity, intent);
|
||||
}
|
||||
@@ -4241,10 +4243,15 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
if (data.info.splitName != null) {
|
||||
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
|
||||
}
|
||||
if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
|
||||
final String attributionTag = data.info.attributionTags[0];
|
||||
context = (ContextImpl) context.createAttributionContext(attributionTag);
|
||||
}
|
||||
java.lang.ClassLoader cl = context.getClassLoader();
|
||||
data.intent.setExtrasClassLoader(cl);
|
||||
data.intent.prepareToEnterProcess(
|
||||
isProtectedComponent(data.info) || isProtectedBroadcast(data.intent));
|
||||
isProtectedComponent(data.info) || isProtectedBroadcast(data.intent),
|
||||
context.getAttributionSource());
|
||||
data.setExtrasClassLoader(cl);
|
||||
receiver = packageInfo.getAppFactory()
|
||||
.instantiateReceiver(cl, data.info.name, data.intent);
|
||||
@@ -4469,7 +4476,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
if (s != null) {
|
||||
try {
|
||||
data.intent.setExtrasClassLoader(s.getClassLoader());
|
||||
data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
|
||||
data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
|
||||
s.getAttributionSource());
|
||||
try {
|
||||
if (!data.rebind) {
|
||||
IBinder binder = s.onBind(data.intent);
|
||||
@@ -4499,7 +4507,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
if (s != null) {
|
||||
try {
|
||||
data.intent.setExtrasClassLoader(s.getClassLoader());
|
||||
data.intent.prepareToEnterProcess(isProtectedComponent(createData.info));
|
||||
data.intent.prepareToEnterProcess(isProtectedComponent(createData.info),
|
||||
s.getAttributionSource());
|
||||
boolean doRebind = s.onUnbind(data.intent);
|
||||
try {
|
||||
if (doRebind) {
|
||||
@@ -4588,7 +4597,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
try {
|
||||
if (data.args != null) {
|
||||
data.args.setExtrasClassLoader(s.getClassLoader());
|
||||
data.args.prepareToEnterProcess(isProtectedComponent(createData.info));
|
||||
data.args.prepareToEnterProcess(isProtectedComponent(createData.info),
|
||||
s.getAttributionSource());
|
||||
}
|
||||
int res;
|
||||
if (!data.taskRemoved) {
|
||||
@@ -5241,7 +5251,8 @@ public final class ActivityThread extends ClientTransactionHandler
|
||||
try {
|
||||
if (ri.mData != null) {
|
||||
ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
|
||||
ri.mData.prepareToEnterProcess(isProtectedComponent(r.activityInfo));
|
||||
ri.mData.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
|
||||
r.activity.getAttributionSource());
|
||||
}
|
||||
if (DEBUG_RESULTS) Slog.v(TAG,
|
||||
"Delivering result to activity " + r + " : " + ri);
|
||||
|
||||
@@ -1774,7 +1774,8 @@ class ContextImpl extends Context {
|
||||
intent.setExtrasClassLoader(getClassLoader());
|
||||
// TODO: determine at registration time if caller is
|
||||
// protecting themselves with signature permission
|
||||
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
|
||||
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
|
||||
getAttributionSource());
|
||||
}
|
||||
return intent;
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -1651,7 +1651,8 @@ public final class LoadedApk {
|
||||
intent.setExtrasClassLoader(cl);
|
||||
// TODO: determine at registration time if caller is
|
||||
// protecting themselves with signature permission
|
||||
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent));
|
||||
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
|
||||
mContext.getAttributionSource());
|
||||
setExtrasClassLoader(cl);
|
||||
receiver.setPendingResult(this);
|
||||
receiver.onReceive(mContext, intent);
|
||||
|
||||
@@ -1190,6 +1190,11 @@ public final class BluetoothDevice implements Parcelable {
|
||||
return devices;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public void prepareToEnterProcess(AttributionSource attributionSource) {
|
||||
setAttributionSource(attributionSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o) {
|
||||
if (o instanceof BluetoothDevice) {
|
||||
|
||||
@@ -1034,14 +1034,14 @@ public class ClipData implements Parcelable {
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public void prepareToEnterProcess() {
|
||||
public void prepareToEnterProcess(AttributionSource source) {
|
||||
final int size = mItems.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Item item = mItems.get(i);
|
||||
if (item.mIntent != null) {
|
||||
// We can't recursively claim that this data is from a protected
|
||||
// component, since it may have been filled in by a malicious app
|
||||
item.mIntent.prepareToEnterProcess(false);
|
||||
item.mIntent.prepareToEnterProcess(false, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.annotation.SuppressLint;
|
||||
import android.annotation.SystemApi;
|
||||
import android.annotation.TestApi;
|
||||
import android.app.AppGlobals;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
@@ -11439,7 +11440,7 @@ public class Intent implements Parcelable, Cloneable {
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void prepareToEnterProcess(boolean fromProtectedComponent) {
|
||||
public void prepareToEnterProcess(boolean fromProtectedComponent, AttributionSource source) {
|
||||
// We just entered destination process, so we should be able to read all
|
||||
// parcelables inside.
|
||||
setDefusable(true);
|
||||
@@ -11447,10 +11448,10 @@ public class Intent implements Parcelable, Cloneable {
|
||||
if (mSelector != null) {
|
||||
// We can't recursively claim that this data is from a protected
|
||||
// component, since it may have been filled in by a malicious app
|
||||
mSelector.prepareToEnterProcess(false);
|
||||
mSelector.prepareToEnterProcess(false, source);
|
||||
}
|
||||
if (mClipData != null) {
|
||||
mClipData.prepareToEnterProcess();
|
||||
mClipData.prepareToEnterProcess(source);
|
||||
}
|
||||
|
||||
if (mContentUserHint != UserHandle.USER_CURRENT) {
|
||||
@@ -11463,6 +11464,14 @@ public class Intent implements Parcelable, Cloneable {
|
||||
if (fromProtectedComponent) {
|
||||
mLocalFlags |= LOCAL_FLAG_FROM_PROTECTED_COMPONENT;
|
||||
}
|
||||
|
||||
// Special attribution fix-up logic for any BluetoothDevice extras
|
||||
// passed via Bluetooth intents
|
||||
if (mAction != null && mAction.startsWith("android.bluetooth.")
|
||||
&& hasExtra(BluetoothDevice.EXTRA_DEVICE)) {
|
||||
final BluetoothDevice device = getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
|
||||
device.prepareToEnterProcess(source);
|
||||
}
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -7505,7 +7505,8 @@ public final class ViewRootImpl implements ViewParent,
|
||||
final View prevDragView = mCurrentDragView;
|
||||
|
||||
if (what == DragEvent.ACTION_DROP && event.mClipData != null) {
|
||||
event.mClipData.prepareToEnterProcess();
|
||||
event.mClipData.prepareToEnterProcess(
|
||||
mView.getContext().getAttributionSource());
|
||||
}
|
||||
|
||||
// Now dispatch the drag/drop event
|
||||
|
||||
Reference in New Issue
Block a user