Merge "Support subattribution for manifest receivers" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
13227f7a6f
@@ -329,6 +329,7 @@ package android {
|
||||
field public static final int apiKey = 16843281; // 0x1010211
|
||||
field public static final int appCategory = 16844101; // 0x1010545
|
||||
field public static final int appComponentFactory = 16844154; // 0x101057a
|
||||
field public static final int attributionTags = 16844353; // 0x1010641
|
||||
field public static final int author = 16843444; // 0x10102b4
|
||||
field public static final int authorities = 16842776; // 0x1010018
|
||||
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
|
||||
|
||||
@@ -1086,6 +1086,13 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
*/
|
||||
public WindowLayout windowLayout;
|
||||
|
||||
/**
|
||||
* Attribution tags for finer grained calls if a {@android.content.Context#sendBroadcast(Intent,
|
||||
* String)} is used with a permission.
|
||||
* @hide
|
||||
*/
|
||||
public String[] attributionTags;
|
||||
|
||||
public ActivityInfo() {
|
||||
}
|
||||
|
||||
@@ -1114,6 +1121,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
maxAspectRatio = orig.maxAspectRatio;
|
||||
minAspectRatio = orig.minAspectRatio;
|
||||
supportsSizeChanges = orig.supportsSizeChanges;
|
||||
attributionTags = orig.attributionTags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1361,6 +1369,15 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
if (supportsSizeChanges) {
|
||||
pw.println(prefix + "supportsSizeChanges=true");
|
||||
}
|
||||
if (attributionTags != null && attributionTags.length > 0) {
|
||||
StringBuilder tags = new StringBuilder();
|
||||
tags.append(attributionTags[0]);
|
||||
for (int i = 1; i < attributionTags.length; i++) {
|
||||
tags.append(", ");
|
||||
tags.append(attributionTags[i]);
|
||||
}
|
||||
pw.println(prefix + "attributionTags=[" + tags + "]");
|
||||
}
|
||||
super.dumpBack(pw, prefix, dumpFlags);
|
||||
}
|
||||
|
||||
@@ -1406,6 +1423,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
dest.writeFloat(maxAspectRatio);
|
||||
dest.writeFloat(minAspectRatio);
|
||||
dest.writeBoolean(supportsSizeChanges);
|
||||
dest.writeString8Array(attributionTags);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1525,6 +1543,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
|
||||
maxAspectRatio = source.readFloat();
|
||||
minAspectRatio = source.readFloat();
|
||||
supportsSizeChanges = source.readBoolean();
|
||||
attributionTags = source.createString8Array();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -482,6 +482,7 @@ public class PackageInfoWithoutStateUtils {
|
||||
ai.rotationAnimation = a.getRotationAnimation();
|
||||
ai.colorMode = a.getColorMode();
|
||||
ai.windowLayout = a.getWindowLayout();
|
||||
ai.attributionTags = a.getAttributionTags();
|
||||
if ((flags & PackageManager.GET_META_DATA) != 0) {
|
||||
ai.metaData = a.getMetaData();
|
||||
}
|
||||
|
||||
@@ -82,6 +82,9 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
@Nullable
|
||||
ActivityInfo.WindowLayout windowLayout;
|
||||
|
||||
@Nullable
|
||||
String[] attributionTags;
|
||||
|
||||
public ParsedActivity(ParsedActivity other) {
|
||||
super(other);
|
||||
this.theme = other.theme;
|
||||
@@ -107,6 +110,7 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
this.rotationAnimation = other.rotationAnimation;
|
||||
this.colorMode = other.colorMode;
|
||||
this.windowLayout = other.windowLayout;
|
||||
this.attributionTags = other.attributionTags;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,6 +176,7 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
alias.requestedVrComponent = target.requestedVrComponent;
|
||||
alias.directBootAware = target.directBootAware;
|
||||
alias.setProcessName(target.getProcessName());
|
||||
alias.attributionTags = target.attributionTags;
|
||||
return alias;
|
||||
|
||||
// Not all attributes from the target ParsedActivity are copied to the alias.
|
||||
@@ -299,6 +304,7 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
} else {
|
||||
dest.writeBoolean(false);
|
||||
}
|
||||
dest.writeString8Array(this.attributionTags);
|
||||
}
|
||||
|
||||
public ParsedActivity() {
|
||||
@@ -332,6 +338,7 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
if (in.readBoolean()) {
|
||||
windowLayout = new ActivityInfo.WindowLayout(in);
|
||||
}
|
||||
this.attributionTags = in.createString8Array();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<ParsedActivity> CREATOR = new Creator<ParsedActivity>() {
|
||||
@@ -445,4 +452,9 @@ public class ParsedActivity extends ParsedMainComponent {
|
||||
public ActivityInfo.WindowLayout getWindowLayout() {
|
||||
return windowLayout;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String[] getAttributionTags() {
|
||||
return attributionTags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,6 +210,11 @@ public class ParsedActivityUtils {
|
||||
pkg.setVisibleToInstantApps(true);
|
||||
}
|
||||
|
||||
String attributionTags = sa.getString(R.styleable.AndroidManifestActivity_attributionTags);
|
||||
if (attributionTags != null) {
|
||||
activity.attributionTags = attributionTags.split("\\|");
|
||||
}
|
||||
|
||||
return parseActivityOrAlias(activity, pkg, tag, parser, res, sa, receiver,
|
||||
false /*isAlias*/, visibleToEphemeral, input,
|
||||
R.styleable.AndroidManifestActivity_parentActivityName,
|
||||
|
||||
@@ -829,7 +829,6 @@
|
||||
{@code FLAG_ACTIVITY_MULTIPLE_TASK} is set.-->
|
||||
<enum name="singleInstancePerTask" value="4" />
|
||||
</attr>
|
||||
|
||||
<!-- Specify the orientation an activity should be run in. If not
|
||||
specified, it will run in the current preferred orientation
|
||||
of the screen.
|
||||
@@ -1603,6 +1602,12 @@
|
||||
<enum name="sync" value="2" />
|
||||
</attr>
|
||||
|
||||
<!-- Attribution tag to be used for permission sub-attribution if a
|
||||
permission is checked in {@link android.content.Context#sendBroadcast(Intent, String)}.
|
||||
Multiple tags can be specified separated by '|'.
|
||||
-->
|
||||
<attr name="attributionTags" format="string" />
|
||||
|
||||
<!-- The <code>manifest</code> tag is the root of an
|
||||
<code>AndroidManifest.xml</code> file,
|
||||
describing the contents of an Android package (.apk) file. One
|
||||
@@ -2825,6 +2830,10 @@
|
||||
|
||||
<p> See {@link android.content.pm.ActivityInfo#FLAG_PREFER_MINIMAL_POST_PROCESSING} -->
|
||||
<attr name="preferMinimalPostProcessing" format="boolean"/>
|
||||
<!-- Specify the attributionTags to be used if a permission is required due to
|
||||
{@link android.content.Context#sendBroadcast(Intent, String)} being used.
|
||||
Multiple tags can be specified separated by '|'. -->
|
||||
<attr name="attributionTags"/>
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>activity-alias</code> tag declares a new
|
||||
|
||||
@@ -3087,6 +3087,7 @@
|
||||
<public name="passwordsActivity"/>
|
||||
<public name="selectableAsDefault"/>
|
||||
<public name="isAccessibilityTool"/>
|
||||
<public name="attributionTags"/>
|
||||
</public-group>
|
||||
|
||||
<public-group type="drawable" first-id="0x010800b5">
|
||||
|
||||
@@ -1416,7 +1416,7 @@ public final class BroadcastQueue {
|
||||
}
|
||||
}
|
||||
if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
|
||||
r.requiredPermissions != null && r.requiredPermissions.length > 0) {
|
||||
r.requiredPermissions != null && r.requiredPermissions.length > 0) {
|
||||
for (int i = 0; i < r.requiredPermissions.length; i++) {
|
||||
String requiredPermission = r.requiredPermissions[i];
|
||||
try {
|
||||
@@ -1424,7 +1424,7 @@ public final class BroadcastQueue {
|
||||
checkPermission(requiredPermission,
|
||||
info.activityInfo.applicationInfo.packageName,
|
||||
UserHandle
|
||||
.getUserId(info.activityInfo.applicationInfo.uid));
|
||||
.getUserId(info.activityInfo.applicationInfo.uid));
|
||||
} catch (RemoteException e) {
|
||||
perm = PackageManager.PERMISSION_DENIED;
|
||||
}
|
||||
@@ -1439,36 +1439,18 @@ public final class BroadcastQueue {
|
||||
break;
|
||||
}
|
||||
int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
|
||||
if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
|
||||
&& mService.getAppOpsManager().noteOpNoThrow(appOp,
|
||||
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
|
||||
null /* default featureId */,
|
||||
"Broadcast delivered to " + info.activityInfo.name)
|
||||
!= AppOpsManager.MODE_ALLOWED) {
|
||||
Slog.w(TAG, "Appop Denial: receiving "
|
||||
+ r.intent + " to "
|
||||
+ component.flattenToShortString()
|
||||
+ " requires appop " + AppOpsManager.permissionToOp(
|
||||
requiredPermission)
|
||||
+ " due to sender " + r.callerPackage
|
||||
+ " (uid " + r.callingUid + ")");
|
||||
skip = true;
|
||||
break;
|
||||
if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp) {
|
||||
if (!noteOpForManifestReceiver(appOp, r, info, component)) {
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!skip && r.appOp != AppOpsManager.OP_NONE
|
||||
&& mService.getAppOpsManager().noteOpNoThrow(r.appOp,
|
||||
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
|
||||
null /* default featureId */, "Broadcast delivered to " + info.activityInfo.name)
|
||||
!= AppOpsManager.MODE_ALLOWED) {
|
||||
Slog.w(TAG, "Appop Denial: receiving "
|
||||
+ r.intent + " to "
|
||||
+ component.flattenToShortString()
|
||||
+ " requires appop " + AppOpsManager.opToName(r.appOp)
|
||||
+ " due to sender " + r.callerPackage
|
||||
+ " (uid " + r.callingUid + ")");
|
||||
skip = true;
|
||||
if (!skip && r.appOp != AppOpsManager.OP_NONE) {
|
||||
if (!noteOpForManifestReceiver(r.appOp, r, info, component)) {
|
||||
skip = true;
|
||||
}
|
||||
}
|
||||
boolean isSingleton = false;
|
||||
try {
|
||||
@@ -1717,6 +1699,40 @@ public final class BroadcastQueue {
|
||||
mPendingBroadcastRecvIndex = recIdx;
|
||||
}
|
||||
|
||||
private boolean noteOpForManifestReceiver(int appOp, BroadcastRecord r, ResolveInfo info,
|
||||
ComponentName component) {
|
||||
if (info.activityInfo.attributionTags == null) {
|
||||
return noteOpForManifestReceiverInner(appOp, r, info, component, null);
|
||||
} else {
|
||||
// Attribution tags provided, noteOp each tag
|
||||
for (String tag : info.activityInfo.attributionTags) {
|
||||
if (!noteOpForManifestReceiverInner(appOp, r, info, component, tag)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean noteOpForManifestReceiverInner(int appOp, BroadcastRecord r, ResolveInfo info,
|
||||
ComponentName component, String tag) {
|
||||
if (mService.getAppOpsManager().noteOpNoThrow(appOp,
|
||||
info.activityInfo.applicationInfo.uid,
|
||||
info.activityInfo.packageName,
|
||||
tag,
|
||||
"Broadcast delivered to " + info.activityInfo.name)
|
||||
!= AppOpsManager.MODE_ALLOWED) {
|
||||
Slog.w(TAG, "Appop Denial: receiving "
|
||||
+ r.intent + " to "
|
||||
+ component.flattenToShortString()
|
||||
+ " requires appop " + AppOpsManager.opToName(appOp)
|
||||
+ " due to sender " + r.callerPackage
|
||||
+ " (uid " + r.callingUid + ")");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void maybeAddAllowBackgroundActivityStartsToken(ProcessRecord proc, BroadcastRecord r) {
|
||||
if (r == null || proc == null || !r.allowBackgroundActivityStarts) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user