Loading core/java/android/os/ArtModuleServiceManager.java +27 −5 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ public class ArtModuleServiceManager { /** A class that exposes the method to obtain each system service. */ public static final class ServiceRegisterer { @NonNull private final String mServiceName; private final boolean mRetry; /** @hide */ public ServiceRegisterer(@NonNull String serviceName) { public ServiceRegisterer(@NonNull String serviceName, boolean retry) { mServiceName = serviceName; mRetry = retry; } /** Loading @@ -53,27 +55,47 @@ public class ArtModuleServiceManager { */ @Nullable public IBinder waitForService() { if (mRetry) { return ServiceManager.waitForService(mServiceName); } IBinder binder = ServiceManager.getService(mServiceName); for (int remainingTimeMs = 5000; binder == null && remainingTimeMs > 0; remainingTimeMs -= 100) { // There can be a race: // 1. Client A invokes "ctl.start", which starts the service. // 2. Client A gets a service handle from `ServiceManager.getService`. // 3. Client B invokes "ctl.start", which does nothing because the service is // already running. // 4. Client A drops the service handle. The service is notified that there is no // more client at that point, so it shuts down itself. // 5. Client B cannot get a service handle from `ServiceManager.getService` because // the service is shut down. // To address this problem, we invoke "ctl.start" repeatedly. SystemProperties.set("ctl.start", mServiceName); SystemClock.sleep(100); binder = ServiceManager.getService(mServiceName); } return binder; } } /** Returns {@link ServiceRegisterer} for the "artd" service. */ @NonNull public ServiceRegisterer getArtdServiceRegisterer() { return new ServiceRegisterer("artd"); return new ServiceRegisterer("artd", true /* retry */); } /** Returns {@link ServiceRegisterer} for the "artd_pre_reboot" service. */ @NonNull @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2) public ServiceRegisterer getArtdPreRebootServiceRegisterer() { return new ServiceRegisterer("artd_pre_reboot"); return new ServiceRegisterer("artd_pre_reboot", false /* retry */); } /** Returns {@link ServiceRegisterer} for the "dexopt_chroot_setup" service. */ @NonNull @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2) public ServiceRegisterer getDexoptChrootSetupServiceRegisterer() { return new ServiceRegisterer("dexopt_chroot_setup"); return new ServiceRegisterer("dexopt_chroot_setup", true /* retry */); } } Loading
core/java/android/os/ArtModuleServiceManager.java +27 −5 Original line number Diff line number Diff line Loading @@ -37,10 +37,12 @@ public class ArtModuleServiceManager { /** A class that exposes the method to obtain each system service. */ public static final class ServiceRegisterer { @NonNull private final String mServiceName; private final boolean mRetry; /** @hide */ public ServiceRegisterer(@NonNull String serviceName) { public ServiceRegisterer(@NonNull String serviceName, boolean retry) { mServiceName = serviceName; mRetry = retry; } /** Loading @@ -53,27 +55,47 @@ public class ArtModuleServiceManager { */ @Nullable public IBinder waitForService() { if (mRetry) { return ServiceManager.waitForService(mServiceName); } IBinder binder = ServiceManager.getService(mServiceName); for (int remainingTimeMs = 5000; binder == null && remainingTimeMs > 0; remainingTimeMs -= 100) { // There can be a race: // 1. Client A invokes "ctl.start", which starts the service. // 2. Client A gets a service handle from `ServiceManager.getService`. // 3. Client B invokes "ctl.start", which does nothing because the service is // already running. // 4. Client A drops the service handle. The service is notified that there is no // more client at that point, so it shuts down itself. // 5. Client B cannot get a service handle from `ServiceManager.getService` because // the service is shut down. // To address this problem, we invoke "ctl.start" repeatedly. SystemProperties.set("ctl.start", mServiceName); SystemClock.sleep(100); binder = ServiceManager.getService(mServiceName); } return binder; } } /** Returns {@link ServiceRegisterer} for the "artd" service. */ @NonNull public ServiceRegisterer getArtdServiceRegisterer() { return new ServiceRegisterer("artd"); return new ServiceRegisterer("artd", true /* retry */); } /** Returns {@link ServiceRegisterer} for the "artd_pre_reboot" service. */ @NonNull @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2) public ServiceRegisterer getArtdPreRebootServiceRegisterer() { return new ServiceRegisterer("artd_pre_reboot"); return new ServiceRegisterer("artd_pre_reboot", false /* retry */); } /** Returns {@link ServiceRegisterer} for the "dexopt_chroot_setup" service. */ @NonNull @FlaggedApi(Flags.FLAG_USE_ART_SERVICE_V2) public ServiceRegisterer getDexoptChrootSetupServiceRegisterer() { return new ServiceRegisterer("dexopt_chroot_setup"); return new ServiceRegisterer("dexopt_chroot_setup", true /* retry */); } }