Dynamically load statsd-service
Previously, service-statsd.jar was on the SYSTEM_SERVER_CLASSPATH. This CL loads StatsCompanion from SystemServer.java dynamically so that the jar does not have to be on the classpath. Bug: 146064616 Test: boots Change-Id: Ia0e98ed0b6e35da01b38ead2fcf45d440eae31c3
This commit is contained in:
@@ -25,10 +25,13 @@ import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManagerInternal;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.utils.TimingsTraceAndSlog;
|
||||
|
||||
import dalvik.system.PathClassLoader;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -62,6 +65,9 @@ public class SystemServiceManager {
|
||||
// Services that should receive lifecycle events.
|
||||
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
|
||||
|
||||
// Map of paths to PathClassLoader, so we don't load the same path multiple times.
|
||||
private final ArrayMap<String, PathClassLoader> mLoadedPaths = new ArrayMap<>();
|
||||
|
||||
private int mCurrentPhase = -1;
|
||||
|
||||
private UserManagerInternal mUserManagerInternal;
|
||||
@@ -75,20 +81,46 @@ public class SystemServiceManager {
|
||||
*
|
||||
* @return The service instance.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public SystemService startService(String className) {
|
||||
final Class<SystemService> serviceClass;
|
||||
final Class<SystemService> serviceClass = loadClassFromLoader(className,
|
||||
this.getClass().getClassLoader());
|
||||
return startService(serviceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a service by class name and a path that specifies the jar where the service lives.
|
||||
*
|
||||
* @return The service instance.
|
||||
*/
|
||||
public SystemService startServiceFromJar(String className, String path) {
|
||||
PathClassLoader pathClassLoader = mLoadedPaths.get(path);
|
||||
if (pathClassLoader == null) {
|
||||
// NB: the parent class loader should always be the system server class loader.
|
||||
// Changing it has implications that require discussion with the mainline team.
|
||||
pathClassLoader = new PathClassLoader(path, this.getClass().getClassLoader());
|
||||
mLoadedPaths.put(path, pathClassLoader);
|
||||
}
|
||||
final Class<SystemService> serviceClass = loadClassFromLoader(className, pathClassLoader);
|
||||
return startService(serviceClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* Loads and initializes a class from the given classLoader. Returns the class.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static Class<SystemService> loadClassFromLoader(String className,
|
||||
ClassLoader classLoader) {
|
||||
try {
|
||||
serviceClass = (Class<SystemService>)Class.forName(className);
|
||||
return (Class<SystemService>) Class.forName(className, true, classLoader);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
Slog.i(TAG, "Starting " + className);
|
||||
throw new RuntimeException("Failed to create service " + className
|
||||
+ ": service class not found, usually indicates that the caller should "
|
||||
+ " from class loader " + classLoader.toString() + ": service class not "
|
||||
+ "found, usually indicates that the caller should "
|
||||
+ "have called PackageManager.hasSystemFeature() to check whether the "
|
||||
+ "feature is available on this device before trying to start the "
|
||||
+ "services that implement it", ex);
|
||||
+ "services that implement it. Also ensure that the correct path for the "
|
||||
+ "classloader is supplied, if applicable.", ex);
|
||||
}
|
||||
return startService(serviceClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -212,6 +212,8 @@ public final class SystemServer {
|
||||
"com.android.server.print.PrintManagerService";
|
||||
private static final String COMPANION_DEVICE_MANAGER_SERVICE_CLASS =
|
||||
"com.android.server.companion.CompanionDeviceManagerService";
|
||||
private static final String STATS_COMPANION_APEX_PATH =
|
||||
"/apex/com.android.os.statsd/javalib/service-statsd.jar";
|
||||
private static final String STATS_COMPANION_LIFECYCLE_CLASS =
|
||||
"com.android.server.stats.StatsCompanion$Lifecycle";
|
||||
private static final String USB_SERVICE_CLASS =
|
||||
@@ -1972,7 +1974,8 @@ public final class SystemServer {
|
||||
|
||||
// Statsd helper
|
||||
t.traceBegin("StartStatsCompanion");
|
||||
mSystemServiceManager.startService(STATS_COMPANION_LIFECYCLE_CLASS);
|
||||
mSystemServiceManager.startServiceFromJar(
|
||||
STATS_COMPANION_LIFECYCLE_CLASS, STATS_COMPANION_APEX_PATH);
|
||||
t.traceEnd();
|
||||
|
||||
// Incidentd and dumpstated helper
|
||||
|
||||
Reference in New Issue
Block a user