diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java index 63332e79c88b9..2fa5df72656bd 100644 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ b/core/java/android/content/pm/parsing/ParsingPackage.java @@ -27,6 +27,7 @@ import android.content.pm.FeatureInfo; import android.content.pm.PackageManager.Property; import android.content.pm.SigningDetails; import android.content.pm.parsing.component.ParsedActivity; +import android.content.pm.parsing.component.ParsedApexSystemService; import android.content.pm.parsing.component.ParsedAttribution; import android.content.pm.parsing.component.ParsedInstrumentation; import android.content.pm.parsing.component.ParsedIntentInfo; @@ -56,6 +57,8 @@ public interface ParsingPackage extends ParsingPackageRead { ParsingPackage addAdoptPermission(String adoptPermission); + ParsingPackage addApexSystemService(ParsedApexSystemService parsedApexSystemService); + ParsingPackage addConfigPreference(ConfigurationInfo configPreference); ParsingPackage addFeatureGroup(FeatureGroupInfo featureGroup); diff --git a/core/java/android/content/pm/parsing/ParsingPackageImpl.java b/core/java/android/content/pm/parsing/ParsingPackageImpl.java index 19a8ce92373da..f03ab6ab94f29 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageImpl.java +++ b/core/java/android/content/pm/parsing/ParsingPackageImpl.java @@ -35,6 +35,8 @@ import android.content.pm.PackageManager.Property; import android.content.pm.SigningDetails; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedActivityImpl; +import android.content.pm.parsing.component.ParsedApexSystemService; +import android.content.pm.parsing.component.ParsedApexSystemServiceImpl; import android.content.pm.parsing.component.ParsedAttribution; import android.content.pm.parsing.component.ParsedAttributionImpl; import android.content.pm.parsing.component.ParsedComponent; @@ -267,6 +269,9 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, @NonNull protected List activities = emptyList(); + @NonNull + protected List apexSystemServices = emptyList(); + @NonNull protected List receivers = emptyList(); @@ -763,6 +768,14 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return this; } + @Override + public final ParsingPackageImpl addApexSystemService( + ParsedApexSystemService parsedApexSystemService) { + this.apexSystemServices = CollectionUtils.add( + this.apexSystemServices, parsedApexSystemService); + return this; + } + @Override public ParsingPackageImpl addReceiver(ParsedActivity parsedReceiver) { this.receivers = CollectionUtils.add(this.receivers, parsedReceiver); @@ -832,7 +845,6 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return this; } - @Override public ParsingPackageImpl removeUsesOptionalNativeLibrary(String libraryName) { this.usesOptionalNativeLibraries = CollectionUtils.remove(this.usesOptionalNativeLibraries, libraryName); @@ -1198,6 +1210,7 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, ParsingPackageUtils.writeKeySetMapping(dest, this.keySetMapping); sForInternedStringList.parcel(this.protectedBroadcasts, dest, flags); dest.writeTypedList(this.activities); + dest.writeTypedList(this.apexSystemServices); dest.writeTypedList(this.receivers); dest.writeTypedList(this.services); dest.writeTypedList(this.providers); @@ -1339,6 +1352,8 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, this.protectedBroadcasts = sForInternedStringList.unparcel(in); this.activities = ParsingUtils.createTypedInterfaceList(in, ParsedActivityImpl.CREATOR); + this.apexSystemServices = ParsingUtils.createTypedInterfaceList(in, + ParsedApexSystemServiceImpl.CREATOR); this.receivers = ParsingUtils.createTypedInterfaceList(in, ParsedActivityImpl.CREATOR); this.services = ParsingUtils.createTypedInterfaceList(in, ParsedServiceImpl.CREATOR); this.providers = ParsingUtils.createTypedInterfaceList(in, ParsedProviderImpl.CREATOR); @@ -1704,6 +1719,12 @@ public class ParsingPackageImpl implements ParsingPackage, ParsingPackageHidden, return activities; } + @NonNull + @Override + public List getApexSystemServices() { + return apexSystemServices; + } + @NonNull @Override public List getReceivers() { diff --git a/core/java/android/content/pm/parsing/ParsingPackageRead.java b/core/java/android/content/pm/parsing/ParsingPackageRead.java index 49b3b08ec5dbe..c8113efcc7c1d 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageRead.java +++ b/core/java/android/content/pm/parsing/ParsingPackageRead.java @@ -23,6 +23,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager.Property; import android.content.pm.PackageParser; import android.content.pm.SigningDetails; +import android.content.pm.parsing.component.ParsedApexSystemService; import android.content.pm.parsing.component.ParsedAttribution; import android.content.pm.parsing.component.ParsedIntentInfo; import android.content.pm.parsing.component.ParsedPermissionGroup; @@ -55,6 +56,12 @@ public interface ParsingPackageRead extends PkgWithoutStateAppInfo, PkgWithoutSt @NonNull List getAdoptPermissions(); + /** + * @see R.styleable#AndroidManifestApexSystemService + */ + @NonNull + List getApexSystemServices(); + @NonNull List getAttributions(); diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java index 3e537c8741377..fb24cb2ef3bd5 100644 --- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java +++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java @@ -53,6 +53,8 @@ import android.content.pm.parsing.component.ComponentMutateUtils; import android.content.pm.parsing.component.ComponentParseUtils; import android.content.pm.parsing.component.ParsedActivity; import android.content.pm.parsing.component.ParsedActivityUtils; +import android.content.pm.parsing.component.ParsedApexSystemService; +import android.content.pm.parsing.component.ParsedApexSystemServiceUtils; import android.content.pm.parsing.component.ParsedAttribution; import android.content.pm.parsing.component.ParsedAttributionUtils; import android.content.pm.parsing.component.ParsedComponent; @@ -2205,6 +2207,18 @@ public class ParsingPackageUtils { result = activityResult; break; + case "apex-system-service": + ParseResult systemServiceResult = + ParsedApexSystemServiceUtils.parseApexSystemService(res, + parser, input); + if (systemServiceResult.isSuccess()) { + ParsedApexSystemService systemService = + systemServiceResult.getResult(); + pkg.addApexSystemService(systemService); + } + + result = systemServiceResult; + break; default: result = parseBaseAppChildTag(input, tagName, pkg, res, parser, flags); break; diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java new file mode 100644 index 0000000000000..fe821e04958f0 --- /dev/null +++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemService.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.parsing.component; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcelable; + +/** @hide */ +public interface ParsedApexSystemService extends Parcelable { + + @NonNull + String getName(); + + @Nullable + String getJarPath(); + + @Nullable + String getMinSdkVersion(); + + @Nullable + String getMaxSdkVersion(); + +} diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java new file mode 100644 index 0000000000000..54196fddb1fb2 --- /dev/null +++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.parsing.component; + + +import android.annotation.NonNull; +import android.annotation.Nullable; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.DataClass; +import com.android.internal.util.Parcelling; + +/** @hide **/ +@DataClass(genGetters = true, genAidl = false, genSetters = true, genParcelable = true) +@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) +public class ParsedApexSystemServiceImpl implements ParsedApexSystemService { + + @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedString.class) + @NonNull + private String name; + + @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedString.class) + @Nullable + private String jarPath; + + @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedString.class) + @Nullable + private String minSdkVersion; + + @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedString.class) + @Nullable + private String maxSdkVersion; + + public ParsedApexSystemServiceImpl() { + } + + + // Code below generated by codegen v1.0.23. + // + // DO NOT MODIFY! + // CHECKSTYLE:OFF Generated code + // + // To regenerate run: + // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java + // + // To exclude the generated code from IntelliJ auto-formatting enable (one-time): + // Settings > Editor > Code Style > Formatter Control + //@formatter:off + + + @DataClass.Generated.Member + public ParsedApexSystemServiceImpl( + @NonNull String name, + @Nullable String jarPath, + @Nullable String minSdkVersion, + @Nullable String maxSdkVersion) { + this.name = name; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, name); + this.jarPath = jarPath; + this.minSdkVersion = minSdkVersion; + this.maxSdkVersion = maxSdkVersion; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public @NonNull String getName() { + return name; + } + + @DataClass.Generated.Member + public @Nullable String getJarPath() { + return jarPath; + } + + @DataClass.Generated.Member + public @Nullable String getMinSdkVersion() { + return minSdkVersion; + } + + @DataClass.Generated.Member + public @Nullable String getMaxSdkVersion() { + return maxSdkVersion; + } + + @DataClass.Generated.Member + public @NonNull ParsedApexSystemServiceImpl setName(@NonNull String value) { + name = value; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, name); + return this; + } + + @DataClass.Generated.Member + public @NonNull ParsedApexSystemServiceImpl setJarPath(@NonNull String value) { + jarPath = value; + return this; + } + + @DataClass.Generated.Member + public @NonNull ParsedApexSystemServiceImpl setMinSdkVersion(@NonNull String value) { + minSdkVersion = value; + return this; + } + + @DataClass.Generated.Member + public @NonNull ParsedApexSystemServiceImpl setMaxSdkVersion(@NonNull String value) { + maxSdkVersion = value; + return this; + } + + @DataClass.Generated.Member + static Parcelling sParcellingForName = + Parcelling.Cache.get( + Parcelling.BuiltIn.ForInternedString.class); + static { + if (sParcellingForName == null) { + sParcellingForName = Parcelling.Cache.put( + new Parcelling.BuiltIn.ForInternedString()); + } + } + + @DataClass.Generated.Member + static Parcelling sParcellingForJarPath = + Parcelling.Cache.get( + Parcelling.BuiltIn.ForInternedString.class); + static { + if (sParcellingForJarPath == null) { + sParcellingForJarPath = Parcelling.Cache.put( + new Parcelling.BuiltIn.ForInternedString()); + } + } + + @DataClass.Generated.Member + static Parcelling sParcellingForMinSdkVersion = + Parcelling.Cache.get( + Parcelling.BuiltIn.ForInternedString.class); + static { + if (sParcellingForMinSdkVersion == null) { + sParcellingForMinSdkVersion = Parcelling.Cache.put( + new Parcelling.BuiltIn.ForInternedString()); + } + } + + @DataClass.Generated.Member + static Parcelling sParcellingForMaxSdkVersion = + Parcelling.Cache.get( + Parcelling.BuiltIn.ForInternedString.class); + static { + if (sParcellingForMaxSdkVersion == null) { + sParcellingForMaxSdkVersion = Parcelling.Cache.put( + new Parcelling.BuiltIn.ForInternedString()); + } + } + + @Override + @DataClass.Generated.Member + public void writeToParcel(@NonNull android.os.Parcel dest, int flags) { + // You can override field parcelling by defining methods like: + // void parcelFieldName(Parcel dest, int flags) { ... } + + byte flg = 0; + if (jarPath != null) flg |= 0x2; + if (minSdkVersion != null) flg |= 0x4; + if (maxSdkVersion != null) flg |= 0x8; + dest.writeByte(flg); + sParcellingForName.parcel(name, dest, flags); + sParcellingForJarPath.parcel(jarPath, dest, flags); + sParcellingForMinSdkVersion.parcel(minSdkVersion, dest, flags); + sParcellingForMaxSdkVersion.parcel(maxSdkVersion, dest, flags); + } + + @Override + @DataClass.Generated.Member + public int describeContents() { return 0; } + + /** @hide */ + @SuppressWarnings({"unchecked", "RedundantCast"}) + @DataClass.Generated.Member + protected ParsedApexSystemServiceImpl(@NonNull android.os.Parcel in) { + // You can override field unparcelling by defining methods like: + // static FieldType unparcelFieldName(Parcel in) { ... } + + byte flg = in.readByte(); + String _name = sParcellingForName.unparcel(in); + String _jarPath = sParcellingForJarPath.unparcel(in); + String _minSdkVersion = sParcellingForMinSdkVersion.unparcel(in); + String _maxSdkVersion = sParcellingForMaxSdkVersion.unparcel(in); + + this.name = _name; + com.android.internal.util.AnnotationValidations.validate( + NonNull.class, null, name); + this.jarPath = _jarPath; + this.minSdkVersion = _minSdkVersion; + this.maxSdkVersion = _maxSdkVersion; + + // onConstructed(); // You can define this method to get a callback + } + + @DataClass.Generated.Member + public static final @NonNull android.os.Parcelable.Creator CREATOR + = new android.os.Parcelable.Creator() { + @Override + public ParsedApexSystemServiceImpl[] newArray(int size) { + return new ParsedApexSystemServiceImpl[size]; + } + + @Override + public ParsedApexSystemServiceImpl createFromParcel(@NonNull android.os.Parcel in) { + return new ParsedApexSystemServiceImpl(in); + } + }; + + @DataClass.Generated( + time = 1638903241144L, + codegenVersion = "1.0.23", + sourceFile = "frameworks/base/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceImpl.java", + inputSignatures = "private @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.NonNull java.lang.String name\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String jarPath\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String minSdkVersion\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForInternedString.class) @android.annotation.Nullable java.lang.String maxSdkVersion\nclass ParsedApexSystemServiceImpl extends java.lang.Object implements [android.content.pm.parsing.component.ParsedApexSystemService]\n@com.android.internal.util.DataClass(genGetters=true, genAidl=false, genSetters=true, genParcelable=true)") + @Deprecated + private void __metadata() {} + + + //@formatter:on + // End of generated code + +} diff --git a/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java new file mode 100644 index 0000000000000..26abf48ee3915 --- /dev/null +++ b/core/java/android/content/pm/parsing/component/ParsedApexSystemServiceUtils.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.content.pm.parsing.component; + +import android.R; +import android.annotation.NonNull; +import android.content.pm.parsing.result.ParseInput; +import android.content.pm.parsing.result.ParseResult; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.content.res.XmlResourceParser; +import android.text.TextUtils; + +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; + +/** @hide */ +public class ParsedApexSystemServiceUtils { + + @NonNull + public static ParseResult parseApexSystemService( + Resources res, XmlResourceParser parser, ParseInput input) + throws XmlPullParserException, IOException { + final ParsedApexSystemServiceImpl systemService = + new ParsedApexSystemServiceImpl(); + TypedArray sa = res.obtainAttributes(parser, + R.styleable.AndroidManifestApexSystemService); + try { + String className = sa.getString( + R.styleable.AndroidManifestApexSystemService_name); + if (TextUtils.isEmpty(className)) { + return input.error(" does not have name attribute"); + } + + String jarPath = sa.getString( + R.styleable.AndroidManifestApexSystemService_path); + String minSdkVersion = sa.getString( + R.styleable.AndroidManifestApexSystemService_minSdkVersion); + String maxSdkVersion = sa.getString( + R.styleable.AndroidManifestApexSystemService_maxSdkVersion); + + systemService.setName(className) + .setMinSdkVersion(minSdkVersion) + .setMaxSdkVersion(maxSdkVersion); + if (!TextUtils.isEmpty(jarPath)) { + systemService.setJarPath(jarPath); + } + + return input.success(systemService); + } finally { + sa.recycle(); + } + } +} diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml index 91e4074b1463a..0a6ef7cf6f21f 100644 --- a/core/res/res/values/attrs_manifest.xml +++ b/core/res/res/values/attrs_manifest.xml @@ -2808,6 +2808,22 @@ + + + + + + + + + +