Merge changes from topic "appOpFeatureId"
* changes: Restrict the number of features or size of ids. Use Pools for noteOp related data objects Allow apps to define featureIds in the manifest
This commit is contained in:
committed by
Android (Google) Code Review
commit
a574814474
@@ -51,6 +51,7 @@ import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.LongSparseArray;
|
||||
import android.util.LongSparseLongArray;
|
||||
import android.util.Pools;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
@@ -2341,15 +2342,31 @@ public class AppOpsManager {
|
||||
*/
|
||||
@TestApi
|
||||
@SystemApi
|
||||
@Immutable
|
||||
@DataClass(genHiddenConstructor = true)
|
||||
// @DataClass(genHiddenConstructor = true, genHiddenCopyConstructor = true)
|
||||
// genHiddenCopyConstructor does not work for @hide @SystemApi classes
|
||||
public static final class OpEventProxyInfo implements Parcelable {
|
||||
/** UID of the proxy app that noted the op */
|
||||
private final @IntRange(from = 0) int mUid;
|
||||
private @IntRange(from = 0) int mUid;
|
||||
/** Package of the proxy that noted the op */
|
||||
private final @Nullable String mPackageName;
|
||||
private @Nullable String mPackageName;
|
||||
/** ID of the feature of the proxy that noted the op */
|
||||
private final @Nullable String mFeatureId;
|
||||
private @Nullable String mFeatureId;
|
||||
|
||||
/**
|
||||
* Reinit existing object with new state.
|
||||
*
|
||||
* @param uid UID of the proxy app that noted the op
|
||||
* @param packageName Package of the proxy that noted the op
|
||||
* @param featureId ID of the feature of the proxy that noted the op
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void reinit(@IntRange(from = 0) int uid, @Nullable String packageName,
|
||||
@Nullable String featureId) {
|
||||
mUid = Preconditions.checkArgumentNonnegative(uid);
|
||||
mPackageName = packageName;
|
||||
mFeatureId = featureId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2392,6 +2409,18 @@ public class AppOpsManager {
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public OpEventProxyInfo(@NonNull OpEventProxyInfo orig) {
|
||||
mUid = orig.mUid;
|
||||
mPackageName = orig.mPackageName;
|
||||
mFeatureId = orig.mFeatureId;
|
||||
}
|
||||
|
||||
/**
|
||||
* UID of the proxy app that noted the op
|
||||
*/
|
||||
@@ -2471,14 +2500,15 @@ public class AppOpsManager {
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
@DataClass.Generated(
|
||||
time = 1576194071700L,
|
||||
time = 1576814974615L,
|
||||
codegenVersion = "1.0.14",
|
||||
sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
|
||||
inputSignatures = "private final @android.annotation.IntRange(from=0L) int mUid\nprivate final @android.annotation.Nullable java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mFeatureId\nclass OpEventProxyInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
|
||||
inputSignatures = "private @android.annotation.IntRange(from=0L) int mUid\nprivate @android.annotation.Nullable java.lang.String mPackageName\nprivate @android.annotation.Nullable java.lang.String mFeatureId\npublic void reinit(int,java.lang.String,java.lang.String)\nclass OpEventProxyInfo extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true, genHiddenCopyConstructor=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
*/
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
@@ -2490,15 +2520,48 @@ public class AppOpsManager {
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@Immutable
|
||||
//@DataClass codegen verifier is broken
|
||||
public static final class NoteOpEvent implements Parcelable {
|
||||
/** Time of noteOp event */
|
||||
public final @IntRange(from = 0) long noteTime;
|
||||
private @IntRange(from = 0) long mNoteTime;
|
||||
/** The duration of this event (in case this is a startOp event, -1 otherwise). */
|
||||
public final @IntRange(from = -1) long duration;
|
||||
private @IntRange(from = -1) long mDuration;
|
||||
/** Proxy information of the noteOp event */
|
||||
public final @Nullable OpEventProxyInfo proxy;
|
||||
private @Nullable OpEventProxyInfo mProxy;
|
||||
|
||||
/**
|
||||
* Reinit existing object with new state.
|
||||
*
|
||||
* @param noteTime Time of noteOp event
|
||||
* @param duration The duration of this event (in case this is a startOp event,
|
||||
* -1 otherwise).
|
||||
* @param proxy Proxy information of the noteOp event
|
||||
* @param proxyPool The pool to release previous {@link OpEventProxyInfo} to
|
||||
*/
|
||||
public void reinit(@IntRange(from = 0) long noteTime,
|
||||
@IntRange(from = -1) long duration,
|
||||
@Nullable OpEventProxyInfo proxy,
|
||||
@NonNull Pools.Pool<OpEventProxyInfo> proxyPool) {
|
||||
mNoteTime = Preconditions.checkArgumentNonnegative(noteTime);
|
||||
mDuration = Preconditions.checkArgumentInRange(duration, -1L, Long.MAX_VALUE,
|
||||
"duration");
|
||||
|
||||
if (mProxy != null) {
|
||||
proxyPool.release(mProxy);
|
||||
}
|
||||
mProxy = proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy constructor
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public NoteOpEvent(@NonNull NoteOpEvent original) {
|
||||
this(original.mNoteTime, original.mDuration,
|
||||
original.mProxy != null ? new OpEventProxyInfo(original.mProxy) : null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.14.
|
||||
@@ -2529,19 +2592,43 @@ public class AppOpsManager {
|
||||
@IntRange(from = 0) long noteTime,
|
||||
@IntRange(from = -1) long duration,
|
||||
@Nullable OpEventProxyInfo proxy) {
|
||||
this.noteTime = noteTime;
|
||||
this.mNoteTime = noteTime;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, noteTime,
|
||||
IntRange.class, null, mNoteTime,
|
||||
"from", 0);
|
||||
this.duration = duration;
|
||||
this.mDuration = duration;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, duration,
|
||||
IntRange.class, null, mDuration,
|
||||
"from", -1);
|
||||
this.proxy = proxy;
|
||||
this.mProxy = proxy;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
/**
|
||||
* Time of noteOp event
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @IntRange(from = 0) long getNoteTime() {
|
||||
return mNoteTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* The duration of this event (in case this is a startOp event, -1 otherwise).
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @IntRange(from = -1) long getDuration() {
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy information of the noteOp event
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @Nullable OpEventProxyInfo getProxy() {
|
||||
return mProxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
@@ -2549,11 +2636,11 @@ public class AppOpsManager {
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
byte flg = 0;
|
||||
if (proxy != null) flg |= 0x4;
|
||||
if (mProxy != null) flg |= 0x4;
|
||||
dest.writeByte(flg);
|
||||
dest.writeLong(noteTime);
|
||||
dest.writeLong(duration);
|
||||
if (proxy != null) dest.writeTypedObject(proxy, flags);
|
||||
dest.writeLong(mNoteTime);
|
||||
dest.writeLong(mDuration);
|
||||
if (mProxy != null) dest.writeTypedObject(mProxy, flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2568,20 +2655,19 @@ public class AppOpsManager {
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
byte flg = in.readByte();
|
||||
long _noteTime = in.readLong();
|
||||
long _duration = in.readLong();
|
||||
OpEventProxyInfo _proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(
|
||||
OpEventProxyInfo.CREATOR);
|
||||
long noteTime = in.readLong();
|
||||
long duration = in.readLong();
|
||||
OpEventProxyInfo proxy = (flg & 0x4) == 0 ? null : (OpEventProxyInfo) in.readTypedObject(OpEventProxyInfo.CREATOR);
|
||||
|
||||
this.noteTime = _noteTime;
|
||||
this.mNoteTime = noteTime;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, noteTime,
|
||||
IntRange.class, null, mNoteTime,
|
||||
"from", 0);
|
||||
this.duration = _duration;
|
||||
this.mDuration = duration;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
IntRange.class, null, duration,
|
||||
IntRange.class, null, mDuration,
|
||||
"from", -1);
|
||||
this.proxy = _proxy;
|
||||
this.mProxy = proxy;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
@@ -2602,10 +2688,10 @@ public class AppOpsManager {
|
||||
|
||||
/*
|
||||
@DataClass.Generated(
|
||||
time = 1574809856220L,
|
||||
time = 1576811792274L,
|
||||
codegenVersion = "1.0.14",
|
||||
sourceFile = "frameworks/base/core/java/android/app/AppOpsManager.java",
|
||||
inputSignatures = "public final @android.annotation.IntRange(from=0L) long noteTime\npublic final @android.annotation.IntRange(from=-1) long duration\npublic final @android.annotation.Nullable android.app.NoteOpEventProxyInfo proxy\nclass NoteOpEvent extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
|
||||
inputSignatures = "private @android.annotation.IntRange(from=0L) long mNoteTime\nprivate @android.annotation.IntRange(from=-1) long mDuration\nprivate @android.annotation.Nullable android.app.OpEventProxyInfo mProxy\npublic void reinit(long,long,android.app.OpEventProxyInfo,android.util.Pools.Pool<android.app.OpEventProxyInfo>)\npublic @java.lang.Override java.lang.Object clone()\nclass NoteOpEvent extends java.lang.Object implements [android.os.Parcelable, java.lang.Cloneable]\n@com.android.internal.util.DataClass")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
*/
|
||||
@@ -2751,7 +2837,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.noteTime;
|
||||
return lastEvent.getNoteTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2847,7 +2933,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.noteTime;
|
||||
return lastEvent.getNoteTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2922,7 +3008,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.duration;
|
||||
return lastEvent.getDuration();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3000,7 +3086,7 @@ public class AppOpsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
return lastEvent.proxy;
|
||||
return lastEvent.getProxy();
|
||||
}
|
||||
|
||||
private static class LongSparseArrayParceling implements
|
||||
@@ -3304,7 +3390,7 @@ public class AppOpsManager {
|
||||
toUidState, flags);
|
||||
|
||||
if (lastAccessEvent == null || (lastFeatureAccessEvent != null
|
||||
&& lastFeatureAccessEvent.noteTime > lastAccessEvent.noteTime)) {
|
||||
&& lastFeatureAccessEvent.getNoteTime() > lastAccessEvent.getNoteTime())) {
|
||||
lastAccessEvent = lastFeatureAccessEvent;
|
||||
}
|
||||
}
|
||||
@@ -3335,7 +3421,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.noteTime;
|
||||
return lastEvent.getNoteTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3418,7 +3504,7 @@ public class AppOpsManager {
|
||||
toUidState, flags);
|
||||
|
||||
if (lastAccessEvent == null || (lastFeatureAccessEvent != null
|
||||
&& lastFeatureAccessEvent.noteTime > lastAccessEvent.noteTime)) {
|
||||
&& lastFeatureAccessEvent.getNoteTime() > lastAccessEvent.getNoteTime())) {
|
||||
lastAccessEvent = lastFeatureAccessEvent;
|
||||
}
|
||||
}
|
||||
@@ -3449,7 +3535,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.noteTime;
|
||||
return lastEvent.getNoteTime();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3544,7 +3630,7 @@ public class AppOpsManager {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return lastEvent.duration;
|
||||
return lastEvent.getDuration();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3674,7 +3760,7 @@ public class AppOpsManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
return lastEvent.proxy;
|
||||
return lastEvent.getProxy();
|
||||
}
|
||||
|
||||
|
||||
@@ -7331,7 +7417,8 @@ public class AppOpsManager {
|
||||
final long key = makeKey(uidState, flag);
|
||||
|
||||
NoteOpEvent event = events.get(key);
|
||||
if (lastEvent == null || event != null && event.noteTime > lastEvent.noteTime) {
|
||||
if (lastEvent == null
|
||||
|| event != null && event.getNoteTime() > lastEvent.getNoteTime()) {
|
||||
lastEvent = event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,6 +202,7 @@ public class PackageParser {
|
||||
public static final String TAG_OVERLAY = "overlay";
|
||||
public static final String TAG_PACKAGE = "package";
|
||||
public static final String TAG_PACKAGE_VERIFIER = "package-verifier";
|
||||
public static final String TAG_FEATURE = "feature";
|
||||
public static final String TAG_PERMISSION = "permission";
|
||||
public static final String TAG_PERMISSION_GROUP = "permission-group";
|
||||
public static final String TAG_PERMISSION_TREE = "permission-tree";
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.content.pm.PackageUserState;
|
||||
import android.content.pm.SharedLibraryInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedFeature;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
|
||||
@@ -244,6 +245,9 @@ public interface AndroidPackage extends Parcelable {
|
||||
@Nullable
|
||||
List<ParsedInstrumentation> getInstrumentations();
|
||||
|
||||
@Nullable
|
||||
List<ParsedFeature> getFeatures();
|
||||
|
||||
@Nullable
|
||||
List<ParsedPermissionGroup> getPermissionGroups();
|
||||
|
||||
|
||||
@@ -793,6 +793,10 @@ public class ApkParseUtils {
|
||||
parseResult = parseKeySets(parseInput, parsingPackage, res, parser);
|
||||
success = parseResult.isSuccess();
|
||||
break;
|
||||
case PackageParser.TAG_FEATURE:
|
||||
parseResult = parseFeature(parseInput, parsingPackage, res, parser);
|
||||
success = parseResult.isSuccess();
|
||||
break;
|
||||
case PackageParser.TAG_PERMISSION_GROUP:
|
||||
parseResult = parsePermissionGroup(parseInput, parsingPackage, res,
|
||||
parser);
|
||||
@@ -880,6 +884,13 @@ public class ApkParseUtils {
|
||||
);
|
||||
}
|
||||
|
||||
if (!ComponentParseUtils.ParsedFeature.isCombinationValid(parsingPackage.getFeatures())) {
|
||||
return parseInput.error(
|
||||
INSTALL_PARSE_FAILED_BAD_MANIFEST,
|
||||
"Combination <feature> tags are not valid"
|
||||
);
|
||||
}
|
||||
|
||||
convertNewPermissions(parsingPackage);
|
||||
|
||||
convertSplitPermissions(parsingPackage);
|
||||
@@ -1260,6 +1271,31 @@ public class ApkParseUtils {
|
||||
return parseInput.success(parsingPackage);
|
||||
}
|
||||
|
||||
private static ParseResult parseFeature(
|
||||
ParseInput parseInput,
|
||||
ParsingPackage parsingPackage,
|
||||
Resources res,
|
||||
XmlResourceParser parser
|
||||
) throws IOException, XmlPullParserException {
|
||||
// TODO(b/135203078): Remove, replace with ParseResult
|
||||
String[] outError = new String[1];
|
||||
|
||||
ComponentParseUtils.ParsedFeature parsedFeature =
|
||||
ComponentParseUtils.parseFeature(res, parser, outError);
|
||||
|
||||
if (parsedFeature == null || outError[0] != null) {
|
||||
return parseInput.error(
|
||||
PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
|
||||
outError[0]
|
||||
);
|
||||
}
|
||||
|
||||
parsingPackage.addFeature(parsedFeature);
|
||||
|
||||
return parseInput.success(parsingPackage);
|
||||
}
|
||||
|
||||
|
||||
private static ParseResult parsePermissionGroup(
|
||||
ParseInput parseInput,
|
||||
ParsingPackage parsingPackage,
|
||||
|
||||
@@ -24,6 +24,9 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
|
||||
import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
|
||||
|
||||
import android.annotation.CallSuper;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.annotation.UnsupportedAppUsage;
|
||||
import android.app.ActivityTaskManager;
|
||||
import android.content.ComponentName;
|
||||
@@ -47,6 +50,7 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.PatternMatcher;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
@@ -54,6 +58,7 @@ import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.util.DataClass;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
@@ -62,6 +67,7 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -931,6 +937,186 @@ public class ComponentParseUtils {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@link android.R.styleable#AndroidManifestFeature <feature>} tag parsed from the
|
||||
* manifest.
|
||||
*/
|
||||
// @DataClass verifier is broken, hence comment out for now
|
||||
public static class ParsedFeature implements Parcelable {
|
||||
/** Maximum length of featureId */
|
||||
public static final int MAX_FEATURE_ID_LEN = 50;
|
||||
|
||||
/** Maximum amount of features per package */
|
||||
private static final int MAX_NUM_FEATURES = 1000;
|
||||
|
||||
/** Id of the feature */
|
||||
public final @NonNull String id;
|
||||
|
||||
/** User visible label fo the feature */
|
||||
public final @StringRes int label;
|
||||
|
||||
/** Ids of previously declared features this feature inherits from */
|
||||
public final @NonNull List<String> inheritFrom;
|
||||
|
||||
/**
|
||||
* @return Is this set of features a valid combination for a single package?
|
||||
*/
|
||||
public static boolean isCombinationValid(@Nullable List<ParsedFeature> features) {
|
||||
if (features == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ArraySet<String> featureIds = new ArraySet<>(features.size());
|
||||
ArraySet<String> inheritFromFeatureIds = new ArraySet<>();
|
||||
|
||||
int numFeatures = features.size();
|
||||
if (numFeatures > MAX_NUM_FEATURES) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int featureNum = 0; featureNum < numFeatures; featureNum++) {
|
||||
boolean wasAdded = featureIds.add(features.get(featureNum).id);
|
||||
if (!wasAdded) {
|
||||
// feature id is not unique
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int featureNum = 0; featureNum < numFeatures; featureNum++) {
|
||||
ParsedFeature feature = features.get(featureNum);
|
||||
|
||||
int numInheritFrom = feature.inheritFrom.size();
|
||||
for (int inheritFromNum = 0; inheritFromNum < numInheritFrom; inheritFromNum++) {
|
||||
String inheritFrom = feature.inheritFrom.get(inheritFromNum);
|
||||
|
||||
if (featureIds.contains(inheritFrom)) {
|
||||
// Cannot inherit from a feature that is still defined
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean wasAdded = inheritFromFeatureIds.add(inheritFrom);
|
||||
if (!wasAdded) {
|
||||
// inheritFrom is not unique
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.14.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
// CHECKSTYLE:OFF Generated code
|
||||
//
|
||||
// To regenerate run:
|
||||
// $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/parsing/ComponentParseUtils.java
|
||||
//
|
||||
// To exclude the generated code from IntelliJ auto-formatting enable (one-time):
|
||||
// Settings > Editor > Code Style > Formatter Control
|
||||
//@formatter:off
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new ParsedFeature.
|
||||
*
|
||||
* @param id
|
||||
* Id of the feature
|
||||
* @param label
|
||||
* User visible label fo the feature (if defined as resource)
|
||||
* @param inheritFrom
|
||||
* Ids of previously declared features this feature inherits from
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public ParsedFeature(
|
||||
@NonNull String id,
|
||||
@StringRes int label,
|
||||
@NonNull List<String> inheritFrom) {
|
||||
this.id = id;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, id);
|
||||
this.label = label;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
StringRes.class, null, label);
|
||||
this.inheritFrom = inheritFrom;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, inheritFrom);
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public void writeToParcel(@NonNull Parcel dest, int flags) {
|
||||
// You can override field parcelling by defining methods like:
|
||||
// void parcelFieldName(Parcel dest, int flags) { ... }
|
||||
|
||||
dest.writeString(id);
|
||||
dest.writeInt(label);
|
||||
dest.writeStringList(inheritFrom);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataClass.Generated.Member
|
||||
public int describeContents() { return 0; }
|
||||
|
||||
/** @hide */
|
||||
@SuppressWarnings({"unchecked", "RedundantCast"})
|
||||
@DataClass.Generated.Member
|
||||
protected ParsedFeature(@NonNull Parcel in) {
|
||||
// You can override field unparcelling by defining methods like:
|
||||
// static FieldType unparcelFieldName(Parcel in) { ... }
|
||||
|
||||
String _id = in.readString();
|
||||
int _label = in.readInt();
|
||||
List<String> _inheritFrom = new ArrayList<>();
|
||||
in.readStringList(_inheritFrom);
|
||||
|
||||
this.id = _id;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, id);
|
||||
this.label = _label;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
StringRes.class, null, label);
|
||||
this.inheritFrom = _inheritFrom;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, inheritFrom);
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public static final @NonNull Parcelable.Creator<ParsedFeature> CREATOR
|
||||
= new Parcelable.Creator<ParsedFeature>() {
|
||||
@Override
|
||||
public ParsedFeature[] newArray(int size) {
|
||||
return new ParsedFeature[size];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParsedFeature createFromParcel(@NonNull Parcel in) {
|
||||
return new ParsedFeature(in);
|
||||
}
|
||||
};
|
||||
|
||||
/*@DataClass.Generated(
|
||||
time = 1576783172965L,
|
||||
codegenVersion = "1.0.14",
|
||||
sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ComponentParseUtils.java",
|
||||
inputSignatures = "public final @android.annotation.NonNull java.lang.String id\npublic final @android.annotation.StringRes int label\npublic final @android.annotation.NonNull java.util.List<java.lang.String> inheritFrom\npublic static boolean isCombinationValid(java.util.List<android.content.pm.parsing.ParsedFeature>)\nclass ParsedFeature extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
|
||||
*/
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
//@formatter:on
|
||||
// End of generated code
|
||||
|
||||
}
|
||||
|
||||
public static class ParsedPermission extends ParsedComponent<ParsedIntentInfo> {
|
||||
|
||||
public String backgroundPermission;
|
||||
@@ -2566,6 +2752,85 @@ public class ComponentParseUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ParsedFeature parseFeature(
|
||||
Resources res,
|
||||
XmlResourceParser parser,
|
||||
String[] outError
|
||||
) throws IOException, XmlPullParserException {
|
||||
String featureId;
|
||||
int label;
|
||||
List<String> inheritFrom = null;
|
||||
|
||||
TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestFeature);
|
||||
if (sa == null) {
|
||||
outError[0] = "<feature> could not be parsed";
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
featureId = sa.getNonConfigurationString(R.styleable.AndroidManifestFeature_featureId,
|
||||
0);
|
||||
if (featureId == null) {
|
||||
outError[0] = "<featureId> does not specify android:featureId";
|
||||
return null;
|
||||
}
|
||||
if (featureId.length() > ParsedFeature.MAX_FEATURE_ID_LEN) {
|
||||
outError[0] = "<featureId> is too long. Max length is "
|
||||
+ ParsedFeature.MAX_FEATURE_ID_LEN;
|
||||
return null;
|
||||
}
|
||||
|
||||
label = sa.getResourceId(R.styleable.AndroidManifestFeature_label, 0);
|
||||
if (label == Resources.ID_NULL) {
|
||||
outError[0] = "<featureId> does not specify android:label";
|
||||
return null;
|
||||
}
|
||||
} finally {
|
||||
sa.recycle();
|
||||
}
|
||||
|
||||
int type;
|
||||
final int innerDepth = parser.getDepth();
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
|
||||
if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String tagName = parser.getName();
|
||||
if (tagName.equals("inherit-from")) {
|
||||
sa = res.obtainAttributes(parser, R.styleable.AndroidManifestFeatureInheritFrom);
|
||||
if (sa == null) {
|
||||
outError[0] = "<inherit-from> could not be parsed";
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
String inheritFromId = sa.getNonConfigurationString(
|
||||
R.styleable.AndroidManifestFeatureInheritFrom_featureId,0);
|
||||
|
||||
if (inheritFrom == null) {
|
||||
inheritFrom = new ArrayList<>();
|
||||
}
|
||||
inheritFrom.add(inheritFromId);
|
||||
} finally {
|
||||
sa.recycle();
|
||||
}
|
||||
} else {
|
||||
outError[0] = "Bad element under <feature>: " + tagName;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (inheritFrom == null) {
|
||||
inheritFrom = Collections.emptyList();
|
||||
} else {
|
||||
((ArrayList) inheritFrom).trimToSize();
|
||||
}
|
||||
|
||||
return new ParsedFeature(featureId, label, inheritFrom);
|
||||
}
|
||||
|
||||
public static ParsedPermission parsePermission(
|
||||
ParsingPackage parsingPackage,
|
||||
Resources res,
|
||||
|
||||
@@ -36,6 +36,7 @@ import android.content.pm.ServiceInfo;
|
||||
import android.content.pm.SharedLibraryInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedFeature;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
|
||||
@@ -174,6 +175,9 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
|
||||
@Nullable
|
||||
private ArrayList<ComponentParseUtils.ParsedProvider> providers;
|
||||
|
||||
@Nullable
|
||||
private ArrayList<ComponentParseUtils.ParsedFeature> features;
|
||||
|
||||
@Nullable
|
||||
private ArrayList<ComponentParseUtils.ParsedPermission> permissions;
|
||||
|
||||
@@ -580,6 +584,12 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
|
||||
return permissions;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<ParsedFeature> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCpuAbiOverride() {
|
||||
return cpuAbiOverride;
|
||||
@@ -791,6 +801,12 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageImpl addFeature(ParsedFeature feature) {
|
||||
this.features = ArrayUtils.add(this.features, feature);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PackageImpl addPermission(ParsedPermission permission) {
|
||||
this.permissions = ArrayUtils.add(this.permissions, permission);
|
||||
@@ -3021,6 +3037,7 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
|
||||
dest.writeTypedList(this.receivers);
|
||||
dest.writeTypedList(this.services);
|
||||
dest.writeTypedList(this.providers);
|
||||
dest.writeTypedList(this.features);
|
||||
dest.writeTypedList(this.permissions);
|
||||
dest.writeTypedList(this.permissionGroups);
|
||||
dest.writeTypedList(this.instrumentations);
|
||||
@@ -3173,6 +3190,7 @@ public final class PackageImpl implements ParsingPackage, ParsedPackage, Android
|
||||
this.receivers = in.createTypedArrayList(ParsedActivity.CREATOR);
|
||||
this.services = in.createTypedArrayList(ParsedService.CREATOR);
|
||||
this.providers = in.createTypedArrayList(ParsedProvider.CREATOR);
|
||||
this.features = in.createTypedArrayList(ParsedFeature.CREATOR);
|
||||
this.permissions = in.createTypedArrayList(ParsedPermission.CREATOR);
|
||||
this.permissionGroups = in.createTypedArrayList(ParsedPermissionGroup.CREATOR);
|
||||
this.instrumentations = in.createTypedArrayList(ParsedInstrumentation.CREATOR);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.pm.FeatureInfo;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedFeature;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
|
||||
import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
|
||||
@@ -64,6 +65,8 @@ public interface ParsingPackage extends AndroidPackage {
|
||||
|
||||
ParsingPackage addOverlayable(String overlayableName, String actorName);
|
||||
|
||||
ParsingPackage addFeature(ParsedFeature permission);
|
||||
|
||||
ParsingPackage addPermission(ParsedPermission permission);
|
||||
|
||||
ParsingPackage addPermissionGroup(ParsedPermissionGroup permissionGroup);
|
||||
|
||||
Reference in New Issue
Block a user