Merge "Introduce initOrder for apex-system-services."
This commit is contained in:
committed by
Android (Google) Code Review
commit
8b326737de
@@ -35,4 +35,6 @@ public interface ParsedApexSystemService extends Parcelable {
|
||||
@Nullable
|
||||
String getMaxSdkVersion();
|
||||
|
||||
int getInitOrder();
|
||||
|
||||
}
|
||||
|
||||
@@ -45,10 +45,11 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
@Nullable
|
||||
private String maxSdkVersion;
|
||||
|
||||
private int initOrder;
|
||||
|
||||
public ParsedApexSystemServiceImpl() {
|
||||
}
|
||||
|
||||
|
||||
// Code below generated by codegen v1.0.23.
|
||||
//
|
||||
// DO NOT MODIFY!
|
||||
@@ -67,13 +68,15 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
@NonNull String name,
|
||||
@Nullable String jarPath,
|
||||
@Nullable String minSdkVersion,
|
||||
@Nullable String maxSdkVersion) {
|
||||
@Nullable String maxSdkVersion,
|
||||
int initOrder) {
|
||||
this.name = name;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
NonNull.class, null, name);
|
||||
this.jarPath = jarPath;
|
||||
this.minSdkVersion = minSdkVersion;
|
||||
this.maxSdkVersion = maxSdkVersion;
|
||||
this.initOrder = initOrder;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
@@ -98,6 +101,11 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
return maxSdkVersion;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public int getInitOrder() {
|
||||
return initOrder;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull ParsedApexSystemServiceImpl setName(@NonNull String value) {
|
||||
name = value;
|
||||
@@ -124,6 +132,12 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
return this;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull ParsedApexSystemServiceImpl setInitOrder( int value) {
|
||||
initOrder = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
@DataClass.Generated.Member
|
||||
static Parcelling<String> sParcellingForName =
|
||||
Parcelling.Cache.get(
|
||||
@@ -183,6 +197,7 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
sParcellingForJarPath.parcel(jarPath, dest, flags);
|
||||
sParcellingForMinSdkVersion.parcel(minSdkVersion, dest, flags);
|
||||
sParcellingForMaxSdkVersion.parcel(maxSdkVersion, dest, flags);
|
||||
dest.writeInt(initOrder);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -201,6 +216,7 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
String _jarPath = sParcellingForJarPath.unparcel(in);
|
||||
String _minSdkVersion = sParcellingForMinSdkVersion.unparcel(in);
|
||||
String _maxSdkVersion = sParcellingForMaxSdkVersion.unparcel(in);
|
||||
int _initOrder = in.readInt();
|
||||
|
||||
this.name = _name;
|
||||
com.android.internal.util.AnnotationValidations.validate(
|
||||
@@ -208,6 +224,7 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
this.jarPath = _jarPath;
|
||||
this.minSdkVersion = _minSdkVersion;
|
||||
this.maxSdkVersion = _maxSdkVersion;
|
||||
this.initOrder = _initOrder;
|
||||
|
||||
// onConstructed(); // You can define this method to get a callback
|
||||
}
|
||||
@@ -227,10 +244,10 @@ public class ParsedApexSystemServiceImpl implements ParsedApexSystemService {
|
||||
};
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1638903241144L,
|
||||
time = 1641307133386L,
|
||||
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)")
|
||||
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\nprivate int initOrder\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() {}
|
||||
|
||||
|
||||
@@ -53,10 +53,13 @@ public class ParsedApexSystemServiceUtils {
|
||||
R.styleable.AndroidManifestApexSystemService_minSdkVersion);
|
||||
String maxSdkVersion = sa.getString(
|
||||
R.styleable.AndroidManifestApexSystemService_maxSdkVersion);
|
||||
int initOrder = sa.getInt(R.styleable.AndroidManifestApexSystemService_initOrder, 0);
|
||||
|
||||
systemService.setName(className)
|
||||
.setMinSdkVersion(minSdkVersion)
|
||||
.setMaxSdkVersion(maxSdkVersion);
|
||||
.setMaxSdkVersion(maxSdkVersion)
|
||||
.setInitOrder(initOrder);
|
||||
|
||||
if (!TextUtils.isEmpty(jarPath)) {
|
||||
systemService.setJarPath(jarPath);
|
||||
}
|
||||
|
||||
@@ -2825,6 +2825,14 @@
|
||||
<attr name="path" />
|
||||
<attr name="minSdkVersion" />
|
||||
<attr name="maxSdkVersion" />
|
||||
<!-- The order in which the apex system services are initiated. When there are dependencies
|
||||
among apex system services, setting this attribute for each of them ensures that they are
|
||||
created in the order required by those dependencies. The apex-system-services that are
|
||||
started manually within SystemServer ignore the initOrder and are not considered for
|
||||
automatic starting of the other services.
|
||||
The value is a simple integer, with higher number being initialized first. If not specified,
|
||||
the default order is 0. -->
|
||||
<attr name="initOrder" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<!-- The <code>receiver</code> tag declares an
|
||||
|
||||
@@ -413,9 +413,11 @@ public abstract class ApexManager {
|
||||
throws PackageManagerException;
|
||||
|
||||
/**
|
||||
* Get a map of system services defined in an apex mapped to the jar files they reside in.
|
||||
* Get a list of apex system services implemented in an apex.
|
||||
*
|
||||
* <p>The list is sorted by initOrder for consistency.
|
||||
*/
|
||||
public abstract Map<String, String> getApexSystemServices();
|
||||
public abstract List<ApexSystemServiceInfo> getApexSystemServices();
|
||||
|
||||
/**
|
||||
* Dumps various state information to the provided {@link PrintWriter} object.
|
||||
@@ -448,7 +450,7 @@ public abstract class ApexManager {
|
||||
* Map of all apex system services to the jar files they are contained in.
|
||||
*/
|
||||
@GuardedBy("mLock")
|
||||
private Map<String, String> mApexSystemServices = new ArrayMap<>();
|
||||
private List<ApexSystemServiceInfo> mApexSystemServices = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Contains the list of {@code packageName}s of apks-in-apex for given
|
||||
@@ -604,14 +606,19 @@ public abstract class ApexManager {
|
||||
}
|
||||
|
||||
String name = service.getName();
|
||||
if (mApexSystemServices.containsKey(name)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Duplicate apex-system-service %s from %s, %s",
|
||||
name, mApexSystemServices.get(name), service.getJarPath()));
|
||||
for (ApexSystemServiceInfo info : mApexSystemServices) {
|
||||
if (info.getName().equals(name)) {
|
||||
throw new IllegalStateException(String.format(
|
||||
"Duplicate apex-system-service %s from %s, %s",
|
||||
name, info.mJarPath, service.getJarPath()));
|
||||
}
|
||||
}
|
||||
|
||||
mApexSystemServices.put(name, service.getJarPath());
|
||||
ApexSystemServiceInfo info = new ApexSystemServiceInfo(
|
||||
service.getName(), service.getJarPath(), service.getInitOrder());
|
||||
mApexSystemServices.add(info);
|
||||
}
|
||||
Collections.sort(mApexSystemServices);
|
||||
mPackageNameToApexModuleName.put(packageInfo.packageName, ai.moduleName);
|
||||
if (ai.isActive) {
|
||||
if (activePackagesSet.contains(packageInfo.packageName)) {
|
||||
@@ -1132,7 +1139,7 @@ public abstract class ApexManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getApexSystemServices() {
|
||||
public List<ApexSystemServiceInfo> getApexSystemServices() {
|
||||
synchronized (mLock) {
|
||||
Preconditions.checkState(mApexSystemServices != null,
|
||||
"APEX packages have not been scanned");
|
||||
@@ -1418,10 +1425,10 @@ public abstract class ApexManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getApexSystemServices() {
|
||||
public List<ApexSystemServiceInfo> getApexSystemServices() {
|
||||
// TODO(satayev): we can't really support flattened apex use case, and need to migrate
|
||||
// the manifest entries into system's manifest asap.
|
||||
return Collections.emptyMap();
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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 com.android.server.pm;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* A helper class that contains information about apex-system-service to be used within system
|
||||
* server process.
|
||||
*/
|
||||
public final class ApexSystemServiceInfo implements Comparable<ApexSystemServiceInfo> {
|
||||
|
||||
final String mName;
|
||||
@Nullable
|
||||
final String mJarPath;
|
||||
final int mInitOrder;
|
||||
|
||||
public ApexSystemServiceInfo(String name, String jarPath, int initOrder) {
|
||||
this.mName = name;
|
||||
this.mJarPath = jarPath;
|
||||
this.mInitOrder = initOrder;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
public String getJarPath() {
|
||||
return mJarPath;
|
||||
}
|
||||
|
||||
public int getInitOrder() {
|
||||
return mInitOrder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ApexSystemServiceInfo other) {
|
||||
if (mInitOrder == other.mInitOrder) {
|
||||
return mName.compareTo(other.mName);
|
||||
}
|
||||
// higher initOrder values take precedence
|
||||
return -Integer.compare(mInitOrder, other.mInitOrder);
|
||||
}
|
||||
}
|
||||
@@ -152,6 +152,7 @@ import com.android.server.os.NativeTombstoneManagerService;
|
||||
import com.android.server.os.SchedulingPolicyService;
|
||||
import com.android.server.people.PeopleService;
|
||||
import com.android.server.pm.ApexManager;
|
||||
import com.android.server.pm.ApexSystemServiceInfo;
|
||||
import com.android.server.pm.CrossProfileAppsService;
|
||||
import com.android.server.pm.DataLoaderManagerService;
|
||||
import com.android.server.pm.DynamicCodeLoggingService;
|
||||
@@ -220,8 +221,8 @@ import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -1459,7 +1460,7 @@ public final class SystemServer implements Dumpable {
|
||||
// TelecomLoader hooks into classes with defined HFP logic,
|
||||
// so check for either telephony or microphone.
|
||||
if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE) ||
|
||||
mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
|
||||
mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
|
||||
t.traceBegin("StartTelecomLoaderService");
|
||||
mSystemServiceManager.startService(TelecomLoaderService.class);
|
||||
t.traceEnd();
|
||||
@@ -1467,7 +1468,7 @@ public final class SystemServer implements Dumpable {
|
||||
|
||||
t.traceBegin("StartTelephonyRegistry");
|
||||
telephonyRegistry = new TelephonyRegistry(
|
||||
context, new TelephonyRegistry.ConfigurationProvider());
|
||||
context, new TelephonyRegistry.ConfigurationProvider());
|
||||
ServiceManager.addService("telephony.registry", telephonyRegistry);
|
||||
t.traceEnd();
|
||||
|
||||
@@ -2998,7 +2999,9 @@ public final class SystemServer implements Dumpable {
|
||||
t.traceEnd();
|
||||
t.traceBegin("MakeTelephonyRegistryReady");
|
||||
try {
|
||||
if (telephonyRegistryF != null) telephonyRegistryF.systemRunning();
|
||||
if (telephonyRegistryF != null) {
|
||||
telephonyRegistryF.systemRunning();
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
reportWtf("Notifying TelephonyRegistry running", e);
|
||||
}
|
||||
@@ -3063,10 +3066,12 @@ public final class SystemServer implements Dumpable {
|
||||
*/
|
||||
private void startApexServices(@NonNull TimingsTraceAndSlog t) {
|
||||
t.traceBegin("startApexServices");
|
||||
Map<String, String> services = ApexManager.getInstance().getApexSystemServices();
|
||||
// TODO(satayev): introduce android:order for services coming the same apexes
|
||||
for (String name : new TreeSet<>(services.keySet())) {
|
||||
String jarPath = services.get(name);
|
||||
// TODO(b/192880996): get the list from "android" package, once the manifest entries
|
||||
// are migrated to system manifest.
|
||||
List<ApexSystemServiceInfo> services = ApexManager.getInstance().getApexSystemServices();
|
||||
for (ApexSystemServiceInfo info : services) {
|
||||
String name = info.getName();
|
||||
String jarPath = info.getJarPath();
|
||||
t.traceBegin("starting " + name);
|
||||
if (TextUtils.isEmpty(jarPath)) {
|
||||
mSystemServiceManager.startService(name);
|
||||
|
||||
@@ -32,7 +32,7 @@ apex_test {
|
||||
name: "test_com.android.server",
|
||||
manifest: "manifest.json",
|
||||
androidManifest: "AndroidManifest.xml",
|
||||
java_libs: ["FakeApexSystemService"],
|
||||
java_libs: ["FakeApexSystemServices"],
|
||||
file_contexts: ":apex.test-file_contexts",
|
||||
key: "test_com.android.server.key",
|
||||
updatable: false,
|
||||
|
||||
@@ -21,21 +21,29 @@
|
||||
<application android:hasCode="false" android:testOnly="true">
|
||||
<apex-system-service
|
||||
android:name="com.android.server.testing.FakeApexSystemService"
|
||||
android:path="/apex/test_com.android.server/javalib/FakeApexSystemService.jar"
|
||||
android:minSdkVersion="30"/>
|
||||
android:path="/apex/test_com.android.server/javalib/FakeApexSystemServices.jar"
|
||||
android:minSdkVersion="30"
|
||||
/>
|
||||
|
||||
<apex-system-service
|
||||
android:name="com.android.server.testing.FakeApexSystemService2"
|
||||
android:path="/apex/test_com.android.server/javalib/FakeApexSystemServices.jar"
|
||||
android:minSdkVersion="30"
|
||||
android:initOrder="1"
|
||||
/>
|
||||
|
||||
<!-- Always inactive system service, since maxSdkVersion is low -->
|
||||
<apex-system-service
|
||||
android:name="com.android.apex.test.OldApexSystemService"
|
||||
android:path="/apex/com.android.apex.test/javalib/fake.jar"
|
||||
android:name="com.android.server.testing.OldApexSystemService"
|
||||
android:path="/apex/test_com.android.server/javalib/fake.jar"
|
||||
android:minSdkVersion="1"
|
||||
android:maxSdkVersion="1"
|
||||
/>
|
||||
|
||||
<!-- Always inactive system service, since minSdkVersion is high -->
|
||||
<apex-system-service
|
||||
android:name="com.android.apex.test.NewApexSystemService"
|
||||
android:path="/apex/com.android.apex.test/javalib/fake.jar"
|
||||
android:name="com.android.server.testing.NewApexSystemService"
|
||||
android:path="/apex/test_com.android.server/javalib/fake.jar"
|
||||
android:minSdkVersion="999999"
|
||||
/>
|
||||
</application>
|
||||
|
||||
@@ -8,7 +8,7 @@ package {
|
||||
}
|
||||
|
||||
java_library {
|
||||
name: "FakeApexSystemService",
|
||||
name: "FakeApexSystemServices",
|
||||
srcs: ["**/*.java"],
|
||||
sdk_version: "system_server_current",
|
||||
libs: [
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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 com.android.server.testing;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.server.SystemService;
|
||||
|
||||
/**
|
||||
* A fake system service that just logs when it is started.
|
||||
*/
|
||||
public class FakeApexSystemService2 extends SystemService {
|
||||
|
||||
private static final String TAG = "FakeApexSystemService";
|
||||
|
||||
public FakeApexSystemService2(@NonNull Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
Log.d(TAG, "FakeApexSystemService2 onStart");
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,10 @@ import org.junit.rules.RuleChain;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RunWith(DeviceJUnit4ClassRunner.class)
|
||||
public class ApexSystemServicesTestCases extends BaseHostJUnit4Test {
|
||||
|
||||
@@ -67,7 +71,7 @@ public class ApexSystemServicesTestCases extends BaseHostJUnit4Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noApexSystemServerStartsWithoutApex() throws Exception {
|
||||
public void testNoApexSystemServiceStartsWithoutApex() throws Exception {
|
||||
mPreparer.reboot();
|
||||
|
||||
assertThat(getFakeApexSystemServiceLogcat())
|
||||
@@ -75,7 +79,7 @@ public class ApexSystemServicesTestCases extends BaseHostJUnit4Test {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void apexSystemServerStarts() throws Exception {
|
||||
public void testApexSystemServiceStarts() throws Exception {
|
||||
// Pre-install the apex
|
||||
String apex = "test_com.android.server.apex";
|
||||
mPreparer.pushResourceFile(apex, "/system/apex/" + apex);
|
||||
@@ -86,9 +90,40 @@ public class ApexSystemServicesTestCases extends BaseHostJUnit4Test {
|
||||
.contains("FakeApexSystemService onStart");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitOrder() throws Exception {
|
||||
// Pre-install the apex
|
||||
String apex = "test_com.android.server.apex";
|
||||
mPreparer.pushResourceFile(apex, "/system/apex/" + apex);
|
||||
// Reboot activates the apex
|
||||
mPreparer.reboot();
|
||||
|
||||
assertThat(getFakeApexSystemServiceLogcat().lines()
|
||||
.map(ApexSystemServicesTestCases::getDebugMessage)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList()))
|
||||
.containsExactly(
|
||||
// Second service has a higher initOrder and must be started first
|
||||
"FakeApexSystemService2 onStart",
|
||||
"FakeApexSystemService onStart"
|
||||
)
|
||||
.inOrder();
|
||||
}
|
||||
|
||||
private String getFakeApexSystemServiceLogcat() throws DeviceNotAvailableException {
|
||||
return mDevice.executeAdbCommand("logcat", "-v", "brief", "-d", "FakeApexSystemService:D",
|
||||
"*:S");
|
||||
}
|
||||
|
||||
private static final Pattern DEBUG_MESSAGE =
|
||||
Pattern.compile("(FakeApexSystemService[0-9]* onStart)");
|
||||
|
||||
private static String getDebugMessage(String logcatLine) {
|
||||
return DEBUG_MESSAGE.matcher(logcatLine)
|
||||
.results()
|
||||
.map(m -> m.group(1))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
|
||||
@SmallTest
|
||||
@Presubmit
|
||||
@@ -136,9 +136,10 @@ public class ApexManagerTest {
|
||||
mApexManager.scanApexPackagesTraced(mPackageParser2,
|
||||
ParallelPackageParser.makeExecutorService());
|
||||
|
||||
Map<String, String> services = mApexManager.getApexSystemServices();
|
||||
List<ApexSystemServiceInfo> services = mApexManager.getApexSystemServices();
|
||||
assertThat(services).hasSize(1);
|
||||
assertThat(services).containsKey("com.android.apex.test.ApexSystemService");
|
||||
assertThat(services.stream().map(ApexSystemServiceInfo::getName).findFirst().orElse(null))
|
||||
.matches("com.android.apex.test.ApexSystemService");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user