Add apex-system-service tag to AndroidManifest.
This change introduces a new <apex-system-service> tag to the manifest. A manifest may have multiple <apex-system-service> tags, with each tag denoting one system service that lives in an apex. If the service is not in SYSTEMSERVERCLASSPATH, the android:path attribute may be used to indicate where the jar is located on the filesystem. The minSdkVersion and maxSdkVersion attributes may be used to indicate which SDKs the service should start on. Test: atest PackageParserTest Bug: 192880996 Change-Id: I28e595b397ed8db6c412f490f12c73537972efab
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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<ParsedActivity> activities = emptyList();
|
||||
|
||||
@NonNull
|
||||
protected List<ParsedApexSystemService> apexSystemServices = emptyList();
|
||||
|
||||
@NonNull
|
||||
protected List<ParsedActivity> 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<ParsedApexSystemService> getApexSystemServices() {
|
||||
return apexSystemServices;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ParsedActivity> getReceivers() {
|
||||
|
||||
@@ -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<String> getAdoptPermissions();
|
||||
|
||||
/**
|
||||
* @see R.styleable#AndroidManifestApexSystemService
|
||||
*/
|
||||
@NonNull
|
||||
List<ParsedApexSystemService> getApexSystemServices();
|
||||
|
||||
@NonNull
|
||||
List<ParsedAttribution> getAttributions();
|
||||
|
||||
|
||||
@@ -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<ParsedApexSystemService> 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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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<String> 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<String> 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<String> 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<String> 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<ParsedApexSystemServiceImpl> CREATOR
|
||||
= new android.os.Parcelable.Creator<ParsedApexSystemServiceImpl>() {
|
||||
@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
|
||||
|
||||
}
|
||||
@@ -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<ParsedApexSystemService> 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("<apex-system-service> 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2808,6 +2808,22 @@
|
||||
<attr name="attributionTags" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- @hide The <code>apex-system-service</code> tag declares an apex system service
|
||||
that is contained within an application.
|
||||
|
||||
The apex system service tag appears as a child tag of the
|
||||
{@link #AndroidManifestApplication application} tag. -->
|
||||
<declare-styleable name="AndroidManifestApexSystemService"
|
||||
parent="AndroidManifestApplication">
|
||||
<!-- The fully qualified class name of the system service. -->
|
||||
<attr name="name" />
|
||||
<!-- The filepath to the .jar that contains the system service. If this is not provided, it
|
||||
is assumed that the system service exists in SYSTEMSERVERCLASSPATH. -->
|
||||
<attr name="path" />
|
||||
<attr name="minSdkVersion" />
|
||||
<attr name="maxSdkVersion" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>receiver</code> tag declares an
|
||||
{@link android.content.BroadcastReceiver} class that is available
|
||||
as part of the package's application components, allowing the
|
||||
@@ -3051,6 +3067,7 @@
|
||||
<declare-styleable name="AndroidManifestMetaData"
|
||||
parent="AndroidManifestApplication
|
||||
AndroidManifestActivity
|
||||
AndroidManifestApexSystemService
|
||||
AndroidManifestReceiver
|
||||
AndroidManifestProvider
|
||||
AndroidManifestService
|
||||
@@ -3085,6 +3102,7 @@
|
||||
<declare-styleable name="AndroidManifestProperty"
|
||||
parent="AndroidManifestApplication
|
||||
AndroidManifestActivity
|
||||
AndroidManifestApexSystemService
|
||||
AndroidManifestReceiver
|
||||
AndroidManifestProvider
|
||||
AndroidManifestService">
|
||||
|
||||
@@ -24,17 +24,7 @@ import android.content.pm.FeatureInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.pm.SigningDetails
|
||||
import android.content.pm.parsing.ParsingPackage
|
||||
import android.content.pm.parsing.component.ParsedActivityImpl
|
||||
import android.content.pm.parsing.component.ParsedAttributionImpl
|
||||
import android.content.pm.parsing.component.ParsedComponentImpl
|
||||
import android.content.pm.parsing.component.ParsedInstrumentationImpl
|
||||
import android.content.pm.parsing.component.ParsedIntentInfoImpl
|
||||
import android.content.pm.parsing.component.ParsedPermissionGroupImpl
|
||||
import android.content.pm.parsing.component.ParsedPermissionImpl
|
||||
import android.content.pm.parsing.component.ParsedProcessImpl
|
||||
import android.content.pm.parsing.component.ParsedProviderImpl
|
||||
import android.content.pm.parsing.component.ParsedServiceImpl
|
||||
import android.content.pm.parsing.component.ParsedUsesPermissionImpl
|
||||
import android.content.pm.parsing.component.*
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
@@ -359,6 +349,13 @@ class AndroidPackageTest : ParcelableComponentTest(AndroidPackage::class, Packag
|
||||
transformGet = { it.singleOrNull()?.name.orEmpty() },
|
||||
transformSet = { ParsedActivityImpl().apply { name = it }.withMimeGroups() }
|
||||
),
|
||||
getSetByValue(
|
||||
AndroidPackage::getApexSystemServices,
|
||||
PackageImpl::addApexSystemService,
|
||||
"TestApexSystemServiceName",
|
||||
transformGet = { it.singleOrNull()?.name.orEmpty() },
|
||||
transformSet = { ParsedApexSystemServiceImpl().apply { name = it } }
|
||||
),
|
||||
getSetByValue(
|
||||
AndroidPackage::getReceivers,
|
||||
PackageImpl::addReceiver,
|
||||
|
||||
@@ -46,6 +46,7 @@ import android.content.pm.SigningDetails;
|
||||
import android.content.pm.parsing.ParsingPackage;
|
||||
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.ParsedComponent;
|
||||
import android.content.pm.parsing.component.ParsedInstrumentation;
|
||||
import android.content.pm.parsing.component.ParsedInstrumentationImpl;
|
||||
@@ -525,6 +526,23 @@ public class PackageParserTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseApexSystemService() throws Exception {
|
||||
final File testFile = extractFile(TEST_APP4_APK);
|
||||
try {
|
||||
final ParsedPackage pkg = new TestPackageParser2().parsePackage(testFile, 0, false);
|
||||
final List<ParsedApexSystemService> systemServices = pkg.getApexSystemServices();
|
||||
for (ParsedApexSystemService systemService: systemServices) {
|
||||
assertEquals(PACKAGE_NAME + ".SystemService", systemService.getName());
|
||||
assertEquals("service-test.jar", systemService.getJarPath());
|
||||
assertEquals("30", systemService.getMinSdkVersion());
|
||||
assertEquals("31", systemService.getMaxSdkVersion());
|
||||
}
|
||||
} finally {
|
||||
testFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseModernPackageHasNoCompatPermissions() throws Exception {
|
||||
final File testFile = extractFile(TEST_APP1_APK);
|
||||
|
||||
@@ -57,6 +57,11 @@
|
||||
<property android:name="android.cts.PROPERTY_SERVICE" android:value="@integer/integer_property" />
|
||||
<property android:name="android.cts.PROPERTY_COMPONENT" android:resource="@integer/integer_property" />
|
||||
</service>
|
||||
<apex-system-service
|
||||
android:name="com.android.servicestests.apps.packageparserapp.SystemService"
|
||||
android:path="service-test.jar"
|
||||
android:minSdkVersion = "30"
|
||||
android:maxSdkVersion = "31" />
|
||||
</application>
|
||||
|
||||
<instrumentation
|
||||
|
||||
@@ -544,6 +544,7 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
|
||||
application_action["activity-alias"] = component_action;
|
||||
application_action["service"] = component_action;
|
||||
application_action["receiver"] = component_action;
|
||||
application_action["apex-system-service"] = component_action;
|
||||
|
||||
// Provider actions.
|
||||
application_action["provider"] = component_action;
|
||||
|
||||
Reference in New Issue
Block a user