Loading apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import android.content.Context; public class BlobStoreManagerFrameworkInitializer { /** Register the BlobStoreManager wrapper class */ public static void initialize() { SystemServiceRegistry.registerCachedService( SystemServiceRegistry.registerContextAwareService( Context.BLOB_STORE_SERVICE, BlobStoreManager.class, (context, service) -> new BlobStoreManager(context, IBlobStoreManager.Stub.asInterface(service))); Loading apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.javadeleted 100644 → 0 +0 −35 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.app; import android.content.Context; import android.os.DeviceIdleManager; import android.os.IDeviceIdleController; /** * @hide */ public class DeviceIdleFrameworkInitializer { private static IDeviceIdleController sIDeviceIdleController; public static void initialize() { SystemServiceRegistry.registerCachedService( Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, (context, b) -> new DeviceIdleManager( context, IDeviceIdleController.Stub.asInterface(b))); } } apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java +21 −1 Original line number Diff line number Diff line Loading @@ -19,14 +19,34 @@ package android.app.job; import android.app.JobSchedulerImpl; import android.app.SystemServiceRegistry; import android.content.Context; import android.os.DeviceIdleManager; import android.os.IDeviceIdleController; /** * Class holding initialization code for the job scheduler module. * * @hide */ public class JobSchedulerFrameworkInitializer { public static void initialize() { private JobSchedulerFrameworkInitializer() { } /** * Called by {@link SystemServiceRegistry}'s static initializer and registers * {@link JobScheduler} and other services to {@link Context}, so * {@link Context#getSystemService} can return them. * * <p>If this is called from other places, it throws a {@link IllegalStateException). * * TODO Make it a system API */ public static void registerServiceWrappers() { SystemServiceRegistry.registerStaticService( Context.JOB_SCHEDULER_SERVICE, JobScheduler.class, (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b))); SystemServiceRegistry.registerContextAwareService( Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, (context, b) -> new DeviceIdleManager( context, IDeviceIdleController.Stub.asInterface(b))); } } core/java/android/app/SystemServiceRegistry.java +204 −22 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app; import android.accounts.AccountManager; import android.accounts.IAccountManager; import android.annotation.NonNull; import android.app.ContextImpl.ServiceInitializationState; import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; Loading Loading @@ -196,10 +197,9 @@ import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.net.INetworkWatchlistManager; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.policy.PhoneLayoutInflater; import com.android.internal.util.Preconditions; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; /** * Manages all of the system services that can be returned by {@link Context#getSystemService}. Loading @@ -218,6 +218,8 @@ public final class SystemServiceRegistry { new ArrayMap<String, ServiceFetcher<?>>(); private static int sServiceCacheSize; private static volatile boolean sInitializing; // Not instantiable. private SystemServiceRegistry() { } Loading Loading @@ -1310,14 +1312,28 @@ public final class SystemServiceRegistry { }}); //CHECKSTYLE:ON IndentationCheck JobSchedulerFrameworkInitializer.initialize(); DeviceIdleFrameworkInitializer.initialize(); sInitializing = true; try { // Note: the following functions need to be @SystemApis, once they become mainline // modules. JobSchedulerFrameworkInitializer.registerServiceWrappers(); BlobStoreManagerFrameworkInitializer.initialize(); } finally { // If any of the above code throws, we're in a pretty bad shape and the process // will likely crash, but we'll reset it just in case there's an exception handler... sInitializing = false; } } /** Throws {@link IllegalStateException} if not during a static initialization. */ private static void ensureInitializing(String methodName) { Preconditions.checkState(sInitializing, "Internal error: " + methodName + " can only be called during class initialization."); } /** * Creates an array which is used to cache per-Context service instances. * @hide */ public static Object[] createServiceCache() { return new Object[sServiceCacheSize]; Loading @@ -1325,6 +1341,7 @@ public final class SystemServiceRegistry { /** * Gets a system service from a given context. * @hide */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); Loading @@ -1333,6 +1350,7 @@ public final class SystemServiceRegistry { /** * Gets the name of the system-level service that is represented by the specified class. * @hide */ public static String getSystemServiceName(Class<?> serviceClass) { return SYSTEM_SERVICE_NAMES.get(serviceClass); Loading @@ -1342,41 +1360,204 @@ public final class SystemServiceRegistry { * Statically registers a system service with the context. * This method must be called during static initialization only. */ private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { private static <T> void registerService(@NonNull String serviceName, @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } /** * APEX modules will use it to register their service wrapper. * Callback interface used as a parameter to {@link #registerStaticService( * String, Class, StaticServiceProducerNoBinder)}, which generates a service wrapper instance * that's not tied to any context and does not take a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface StaticServiceProducerNoBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass}. */ TServiceClass createService(); } /** * Callback interface used as a parameter to {@link #registerStaticService( * String, Class, StaticServiceProducerWithBinder)}, which generates a service wrapper instance * that's not tied to any context and takes a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface StaticServiceProducerWithBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} backed by a given * service binder object. */ TServiceClass createService(IBinder serviceBinder); } /** * Callback interface used as a parameter to {@link #registerContextAwareService( * String, Class, ContextAwareServiceProducerNoBinder)}, * which generates a service wrapper instance * that's tied to a specific context and does not take a service binder object in the * constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface ContextAwareServiceProducerNoBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} tied to a given * {@code context}. * * TODO Do we need to pass the "base context" too? */ TServiceClass createService(Context context); } /** * Callback interface used as a parameter to {@link #registerContextAwareService( * String, Class, ContextAwareServiceProducerWithBinder)}, * which generates a service wrapper instance * that's tied to a specific context and takes a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface ContextAwareServiceProducerWithBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} backed by a given * service binder object that's tied to a given {@code context}. * * TODO Do we need to pass the "base context" too? */ TServiceClass createService(Context context, IBinder serviceBinder); } /** * Used by apex modules to register a "service wrapper" that is not tied to any {@link Context}. * * <p>This can only be called from the methods called by the static initializer of * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) * * @param serviceName the name of the binder object, such as * {@link Context#JOB_SCHEDULER_SERVICE}. * @param serviceWrapperClass the wrapper class, such as the class of * {@link android.app.job.JobScheduler}. * @param serviceProducer Callback that takes the service binder object with the name * {@code serviceName} and returns an actual service wrapper instance. * * @hide */ public static <T> void registerStaticService(String serviceName, Class<T> serviceWrapperClass, Function<IBinder, T> serviceFetcher) { //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerStaticService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull StaticServiceProducerWithBinder<TServiceClass> serviceProducer) { ensureInitializing("registerStaticService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new StaticServiceFetcher<T>() { new StaticServiceFetcher<>() { @Override public T createService() throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(serviceName); return serviceFetcher.apply(b); public TServiceClass createService() throws ServiceNotFoundException { return serviceProducer.createService( ServiceManager.getServiceOrThrow(serviceName)); }}); } /** * APEX modules will use it to register their service wrapper. * Similar to {@link #registerStaticService(String, Class, StaticServiceProducerWithBinder)}, * but used for a "service wrapper" that doesn't take a service binder in its constructor. * * @hide */ public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass, BiFunction<Context, IBinder, T> serviceFetcher) { //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerStaticService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull StaticServiceProducerNoBinder<TServiceClass> serviceProducer) { ensureInitializing("registerStaticService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new StaticServiceFetcher<>() { @Override public TServiceClass createService() { return serviceProducer.createService(); }}); } /** * Used by apex modules to register a "service wrapper" that is tied to a specific * {@link Context}. * * <p>This can only be called from the methods called by the static initializer of * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) * * @param serviceName the name of the binder object, such as * {@link Context#JOB_SCHEDULER_SERVICE}. * @param serviceWrapperClass the wrapper class, such as the class of * {@link android.app.job.JobScheduler}. * @param serviceProducer lambda that takes the service binder object with the name * {@code serviceName}, a {@link Context} and returns an actual service wrapper instance. * * @hide */ //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerContextAwareService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) { ensureInitializing("registerContextAwareService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new CachedServiceFetcher<>() { @Override public TServiceClass createService(ContextImpl ctx) throws ServiceNotFoundException { return serviceProducer.createService( ctx.getOuterContext(), ServiceManager.getServiceOrThrow(serviceName)); }}); } /** * Similar to {@link #registerContextAwareService(String, Class, * ContextAwareServiceProducerWithBinder)}, * but used for a "service wrapper" that doesn't take a service binder in its constructor. * * @hide */ //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerContextAwareService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull ContextAwareServiceProducerNoBinder<TServiceClass> serviceProducer) { ensureInitializing("registerContextAwareService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new CachedServiceFetcher<T>() { new CachedServiceFetcher<>() { @Override public T createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(serviceName); return serviceFetcher.apply(ctx.getOuterContext(), b); public TServiceClass createService(ContextImpl ctx) { return serviceProducer.createService(ctx.getOuterContext()); }}); } Loading Loading @@ -1535,6 +1716,7 @@ public final class SystemServiceRegistry { public abstract T createService(Context applicationContext) throws ServiceNotFoundException; } /** @hide */ public static void onServiceNotFound(ServiceNotFoundException e) { // We're mostly interested in tracking down long-lived core system // components that might stumble if they obtain bad references; just Loading Loading
apex/blobstore/framework/java/android/app/blob/BlobStoreManagerFrameworkInitializer.java +1 −1 Original line number Diff line number Diff line Loading @@ -26,7 +26,7 @@ import android.content.Context; public class BlobStoreManagerFrameworkInitializer { /** Register the BlobStoreManager wrapper class */ public static void initialize() { SystemServiceRegistry.registerCachedService( SystemServiceRegistry.registerContextAwareService( Context.BLOB_STORE_SERVICE, BlobStoreManager.class, (context, service) -> new BlobStoreManager(context, IBlobStoreManager.Stub.asInterface(service))); Loading
apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.javadeleted 100644 → 0 +0 −35 Original line number Diff line number Diff line /* * Copyright (C) 2019 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.app; import android.content.Context; import android.os.DeviceIdleManager; import android.os.IDeviceIdleController; /** * @hide */ public class DeviceIdleFrameworkInitializer { private static IDeviceIdleController sIDeviceIdleController; public static void initialize() { SystemServiceRegistry.registerCachedService( Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, (context, b) -> new DeviceIdleManager( context, IDeviceIdleController.Stub.asInterface(b))); } }
apex/jobscheduler/framework/java/android/app/job/JobSchedulerFrameworkInitializer.java +21 −1 Original line number Diff line number Diff line Loading @@ -19,14 +19,34 @@ package android.app.job; import android.app.JobSchedulerImpl; import android.app.SystemServiceRegistry; import android.content.Context; import android.os.DeviceIdleManager; import android.os.IDeviceIdleController; /** * Class holding initialization code for the job scheduler module. * * @hide */ public class JobSchedulerFrameworkInitializer { public static void initialize() { private JobSchedulerFrameworkInitializer() { } /** * Called by {@link SystemServiceRegistry}'s static initializer and registers * {@link JobScheduler} and other services to {@link Context}, so * {@link Context#getSystemService} can return them. * * <p>If this is called from other places, it throws a {@link IllegalStateException). * * TODO Make it a system API */ public static void registerServiceWrappers() { SystemServiceRegistry.registerStaticService( Context.JOB_SCHEDULER_SERVICE, JobScheduler.class, (b) -> new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b))); SystemServiceRegistry.registerContextAwareService( Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class, (context, b) -> new DeviceIdleManager( context, IDeviceIdleController.Stub.asInterface(b))); } }
core/java/android/app/SystemServiceRegistry.java +204 −22 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.app; import android.accounts.AccountManager; import android.accounts.IAccountManager; import android.annotation.NonNull; import android.app.ContextImpl.ServiceInitializationState; import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; Loading Loading @@ -196,10 +197,9 @@ import com.android.internal.appwidget.IAppWidgetService; import com.android.internal.net.INetworkWatchlistManager; import com.android.internal.os.IDropBoxManagerService; import com.android.internal.policy.PhoneLayoutInflater; import com.android.internal.util.Preconditions; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; /** * Manages all of the system services that can be returned by {@link Context#getSystemService}. Loading @@ -218,6 +218,8 @@ public final class SystemServiceRegistry { new ArrayMap<String, ServiceFetcher<?>>(); private static int sServiceCacheSize; private static volatile boolean sInitializing; // Not instantiable. private SystemServiceRegistry() { } Loading Loading @@ -1310,14 +1312,28 @@ public final class SystemServiceRegistry { }}); //CHECKSTYLE:ON IndentationCheck JobSchedulerFrameworkInitializer.initialize(); DeviceIdleFrameworkInitializer.initialize(); sInitializing = true; try { // Note: the following functions need to be @SystemApis, once they become mainline // modules. JobSchedulerFrameworkInitializer.registerServiceWrappers(); BlobStoreManagerFrameworkInitializer.initialize(); } finally { // If any of the above code throws, we're in a pretty bad shape and the process // will likely crash, but we'll reset it just in case there's an exception handler... sInitializing = false; } } /** Throws {@link IllegalStateException} if not during a static initialization. */ private static void ensureInitializing(String methodName) { Preconditions.checkState(sInitializing, "Internal error: " + methodName + " can only be called during class initialization."); } /** * Creates an array which is used to cache per-Context service instances. * @hide */ public static Object[] createServiceCache() { return new Object[sServiceCacheSize]; Loading @@ -1325,6 +1341,7 @@ public final class SystemServiceRegistry { /** * Gets a system service from a given context. * @hide */ public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); Loading @@ -1333,6 +1350,7 @@ public final class SystemServiceRegistry { /** * Gets the name of the system-level service that is represented by the specified class. * @hide */ public static String getSystemServiceName(Class<?> serviceClass) { return SYSTEM_SERVICE_NAMES.get(serviceClass); Loading @@ -1342,41 +1360,204 @@ public final class SystemServiceRegistry { * Statically registers a system service with the context. * This method must be called during static initialization only. */ private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { private static <T> void registerService(@NonNull String serviceName, @NonNull Class<T> serviceClass, @NonNull ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } /** * APEX modules will use it to register their service wrapper. * Callback interface used as a parameter to {@link #registerStaticService( * String, Class, StaticServiceProducerNoBinder)}, which generates a service wrapper instance * that's not tied to any context and does not take a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface StaticServiceProducerNoBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass}. */ TServiceClass createService(); } /** * Callback interface used as a parameter to {@link #registerStaticService( * String, Class, StaticServiceProducerWithBinder)}, which generates a service wrapper instance * that's not tied to any context and takes a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface StaticServiceProducerWithBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} backed by a given * service binder object. */ TServiceClass createService(IBinder serviceBinder); } /** * Callback interface used as a parameter to {@link #registerContextAwareService( * String, Class, ContextAwareServiceProducerNoBinder)}, * which generates a service wrapper instance * that's tied to a specific context and does not take a service binder object in the * constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface ContextAwareServiceProducerNoBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} tied to a given * {@code context}. * * TODO Do we need to pass the "base context" too? */ TServiceClass createService(Context context); } /** * Callback interface used as a parameter to {@link #registerContextAwareService( * String, Class, ContextAwareServiceProducerWithBinder)}, * which generates a service wrapper instance * that's tied to a specific context and takes a service binder object in the constructor. * * @param <TServiceClass> type of the service wrapper class. * * @hide */ //@SystemApi TODO Make it a system API. public interface ContextAwareServiceProducerWithBinder<TServiceClass> { /** * Return a new service wrapper of type {@code TServiceClass} backed by a given * service binder object that's tied to a given {@code context}. * * TODO Do we need to pass the "base context" too? */ TServiceClass createService(Context context, IBinder serviceBinder); } /** * Used by apex modules to register a "service wrapper" that is not tied to any {@link Context}. * * <p>This can only be called from the methods called by the static initializer of * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) * * @param serviceName the name of the binder object, such as * {@link Context#JOB_SCHEDULER_SERVICE}. * @param serviceWrapperClass the wrapper class, such as the class of * {@link android.app.job.JobScheduler}. * @param serviceProducer Callback that takes the service binder object with the name * {@code serviceName} and returns an actual service wrapper instance. * * @hide */ public static <T> void registerStaticService(String serviceName, Class<T> serviceWrapperClass, Function<IBinder, T> serviceFetcher) { //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerStaticService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull StaticServiceProducerWithBinder<TServiceClass> serviceProducer) { ensureInitializing("registerStaticService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new StaticServiceFetcher<T>() { new StaticServiceFetcher<>() { @Override public T createService() throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(serviceName); return serviceFetcher.apply(b); public TServiceClass createService() throws ServiceNotFoundException { return serviceProducer.createService( ServiceManager.getServiceOrThrow(serviceName)); }}); } /** * APEX modules will use it to register their service wrapper. * Similar to {@link #registerStaticService(String, Class, StaticServiceProducerWithBinder)}, * but used for a "service wrapper" that doesn't take a service binder in its constructor. * * @hide */ public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass, BiFunction<Context, IBinder, T> serviceFetcher) { //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerStaticService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull StaticServiceProducerNoBinder<TServiceClass> serviceProducer) { ensureInitializing("registerStaticService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new StaticServiceFetcher<>() { @Override public TServiceClass createService() { return serviceProducer.createService(); }}); } /** * Used by apex modules to register a "service wrapper" that is tied to a specific * {@link Context}. * * <p>This can only be called from the methods called by the static initializer of * {@link SystemServiceRegistry}. (Otherwise it throws a {@link IllegalStateException}.) * * @param serviceName the name of the binder object, such as * {@link Context#JOB_SCHEDULER_SERVICE}. * @param serviceWrapperClass the wrapper class, such as the class of * {@link android.app.job.JobScheduler}. * @param serviceProducer lambda that takes the service binder object with the name * {@code serviceName}, a {@link Context} and returns an actual service wrapper instance. * * @hide */ //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerContextAwareService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) { ensureInitializing("registerContextAwareService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new CachedServiceFetcher<>() { @Override public TServiceClass createService(ContextImpl ctx) throws ServiceNotFoundException { return serviceProducer.createService( ctx.getOuterContext(), ServiceManager.getServiceOrThrow(serviceName)); }}); } /** * Similar to {@link #registerContextAwareService(String, Class, * ContextAwareServiceProducerWithBinder)}, * but used for a "service wrapper" that doesn't take a service binder in its constructor. * * @hide */ //@SystemApi TODO Make it a system API. public static <TServiceClass> void registerContextAwareService( @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass, @NonNull ContextAwareServiceProducerNoBinder<TServiceClass> serviceProducer) { ensureInitializing("registerContextAwareService"); Preconditions.checkStringNotEmpty(serviceName); Preconditions.checkNotNull(serviceWrapperClass); Preconditions.checkNotNull(serviceProducer); registerService(serviceName, serviceWrapperClass, new CachedServiceFetcher<T>() { new CachedServiceFetcher<>() { @Override public T createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(serviceName); return serviceFetcher.apply(ctx.getOuterContext(), b); public TServiceClass createService(ContextImpl ctx) { return serviceProducer.createService(ctx.getOuterContext()); }}); } Loading Loading @@ -1535,6 +1716,7 @@ public final class SystemServiceRegistry { public abstract T createService(Context applicationContext) throws ServiceNotFoundException; } /** @hide */ public static void onServiceNotFound(ServiceNotFoundException e) { // We're mostly interested in tracking down long-lived core system // components that might stumble if they obtain bad references; just Loading