summaryrefslogtreecommitdiff
path: root/core/java/android/app/SystemServiceRegistry.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/app/SystemServiceRegistry.java')
-rw-r--r--core/java/android/app/SystemServiceRegistry.java617
1 files changed, 431 insertions, 186 deletions
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 4d972b13dcd3..e599a5ce81ef 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -18,13 +18,16 @@ package android.app;
import android.accounts.AccountManager;
import android.accounts.IAccountManager;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.ContextImpl.ServiceInitializationState;
import android.app.admin.DevicePolicyManager;
import android.app.admin.IDevicePolicyManager;
+import android.app.blob.BlobStoreManagerFrameworkInitializer;
import android.app.contentsuggestions.ContentSuggestionsManager;
import android.app.contentsuggestions.IContentSuggestionsManager;
-import android.app.job.IJobScheduler;
-import android.app.job.JobScheduler;
+import android.app.job.JobSchedulerFrameworkInitializer;
import android.app.prediction.AppPredictionManager;
import android.app.role.RoleControllerManager;
import android.app.role.RoleManager;
@@ -49,10 +52,15 @@ import android.content.ContentCaptureOptions;
import android.content.Context;
import android.content.IRestrictionsManager;
import android.content.RestrictionsManager;
+import android.content.integrity.AppIntegrityManager;
+import android.content.integrity.IAppIntegrityManager;
import android.content.om.IOverlayManager;
import android.content.om.OverlayManager;
+import android.content.pm.ApplicationInfo;
import android.content.pm.CrossProfileApps;
+import android.content.pm.DataLoaderManager;
import android.content.pm.ICrossProfileApps;
+import android.content.pm.IDataLoaderManager;
import android.content.pm.IPackageManager;
import android.content.pm.IShortcutService;
import android.content.pm.LauncherApps;
@@ -70,7 +78,7 @@ import android.hardware.SensorPrivacyManager;
import android.hardware.SerialManager;
import android.hardware.SystemSensorManager;
import android.hardware.biometrics.BiometricManager;
-import android.hardware.biometrics.IBiometricService;
+import android.hardware.biometrics.IAuthService;
import android.hardware.camera2.CameraManager;
import android.hardware.display.ColorDisplayManager;
import android.hardware.display.DisplayManager;
@@ -101,6 +109,8 @@ import android.media.session.MediaSessionManager;
import android.media.soundtrigger.SoundTriggerManager;
import android.media.tv.ITvInputManager;
import android.media.tv.TvInputManager;
+import android.media.tv.tunerresourcemanager.ITunerResourceManager;
+import android.media.tv.tunerresourcemanager.TunerResourceManager;
import android.net.ConnectivityDiagnosticsManager;
import android.net.ConnectivityManager;
import android.net.ConnectivityThread;
@@ -121,33 +131,24 @@ import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
-import android.net.wifi.IWifiManager;
-import android.net.wifi.IWifiScanner;
-import android.net.wifi.RttManager;
-import android.net.wifi.WifiManager;
-import android.net.wifi.WifiScanner;
-import android.net.wifi.aware.IWifiAwareManager;
-import android.net.wifi.aware.WifiAwareManager;
-import android.net.wifi.p2p.IWifiP2pManager;
-import android.net.wifi.p2p.WifiP2pManager;
-import android.net.wifi.rtt.IWifiRttManager;
-import android.net.wifi.rtt.WifiRttManager;
+import android.net.wifi.WifiFrameworkInitializer;
+import android.net.wifi.nl80211.WifiNl80211Manager;
import android.nfc.NfcManager;
import android.os.BatteryManager;
import android.os.BatteryStats;
+import android.os.BatteryStatsManager;
import android.os.BugreportManager;
import android.os.Build;
-import android.os.DeviceIdleManager;
import android.os.DropBoxManager;
import android.os.HardwarePropertiesManager;
import android.os.IBatteryPropertiesRegistrar;
import android.os.IBinder;
-import android.os.IDeviceIdleController;
import android.os.IDumpstate;
import android.os.IHardwarePropertiesManager;
import android.os.IPowerManager;
import android.os.IRecoverySystem;
import android.os.ISystemUpdateManager;
+import android.os.IThermalService;
import android.os.IUserManager;
import android.os.IncidentManager;
import android.os.PowerManager;
@@ -155,6 +156,8 @@ import android.os.RecoverySystem;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
+import android.os.StatsFrameworkInitializer;
+import android.os.SystemConfigManager;
import android.os.SystemUpdateManager;
import android.os.SystemVibrator;
import android.os.UserHandle;
@@ -163,26 +166,27 @@ import android.os.Vibrator;
import android.os.health.SystemHealthManager;
import android.os.image.DynamicSystemManager;
import android.os.image.IDynamicSystemService;
+import android.os.incremental.IIncrementalService;
+import android.os.incremental.IncrementalManager;
import android.os.storage.StorageManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManager;
import android.print.IPrintManager;
import android.print.PrintManager;
+import android.security.FileIntegrityManager;
+import android.security.IFileIntegrityService;
import android.service.oemlock.IOemLockService;
import android.service.oemlock.OemLockManager;
import android.service.persistentdata.IPersistentDataBlockService;
import android.service.persistentdata.PersistentDataBlockManager;
import android.service.vr.IVrManager;
import android.telecom.TelecomManager;
-import android.telephony.CarrierConfigManager;
import android.telephony.MmsManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
+import android.telephony.TelephonyFrameworkInitializer;
import android.telephony.TelephonyRegistryManager;
-import android.telephony.euicc.EuiccCardManager;
-import android.telephony.euicc.EuiccManager;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.Slog;
import android.view.ContextThemeWrapper;
import android.view.LayoutInflater;
import android.view.WindowManager;
@@ -204,24 +208,36 @@ 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.Objects;
/**
* Manages all of the system services that can be returned by {@link Context#getSystemService}.
* Used by {@link ContextImpl}.
+ *
+ * @hide
*/
-final class SystemServiceRegistry {
+@SystemApi
+public final class SystemServiceRegistry {
private static final String TAG = "SystemServiceRegistry";
+ /** @hide */
+ public static boolean sEnableServiceNotFoundWtf = false;
+
// Service registry information.
// This information is never changed once static initialization has completed.
private static final Map<Class<?>, String> SYSTEM_SERVICE_NAMES =
new ArrayMap<Class<?>, String>();
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =
new ArrayMap<String, ServiceFetcher<?>>();
+ private static final Map<String, String> SYSTEM_SERVICE_CLASS_NAMES = new ArrayMap<>();
+
private static int sServiceCacheSize;
+ private static volatile boolean sInitializing;
+
// Not instantiable.
private SystemServiceRegistry() { }
@@ -559,10 +575,12 @@ final class SystemServiceRegistry {
new CachedServiceFetcher<PowerManager>() {
@Override
public PowerManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
- IPowerManager service = IPowerManager.Stub.asInterface(b);
- return new PowerManager(ctx.getOuterContext(),
- service, ctx.mMainThread.getHandler());
+ IBinder powerBinder = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);
+ IPowerManager powerService = IPowerManager.Stub.asInterface(powerBinder);
+ IBinder thermalBinder = ServiceManager.getServiceOrThrow(Context.THERMAL_SERVICE);
+ IThermalService thermalService = IThermalService.Stub.asInterface(thermalBinder);
+ return new PowerManager(ctx.getOuterContext(), powerService, thermalService,
+ ctx.mMainThread.getHandler());
}});
registerService(Context.RECOVERY_SERVICE, RecoverySystem.class,
@@ -597,13 +615,6 @@ final class SystemServiceRegistry {
return SensorPrivacyManager.getInstance(ctx);
}});
- registerService(Context.STATS_MANAGER, StatsManager.class,
- new CachedServiceFetcher<StatsManager>() {
- @Override
- public StatsManager createService(ContextImpl ctx) {
- return new StatsManager(ctx.getOuterContext());
- }});
-
registerService(Context.STATUS_BAR_SERVICE, StatusBarManager.class,
new CachedServiceFetcher<StatusBarManager>() {
@Override
@@ -638,12 +649,12 @@ final class SystemServiceRegistry {
return new SystemUpdateManager(service);
}});
- registerService(Context.TELEPHONY_SERVICE, TelephonyManager.class,
- new CachedServiceFetcher<TelephonyManager>() {
- @Override
- public TelephonyManager createService(ContextImpl ctx) {
- return new TelephonyManager(ctx.getOuterContext());
- }});
+ registerService(Context.SYSTEM_CONFIG_SERVICE, SystemConfigManager.class,
+ new CachedServiceFetcher<SystemConfigManager>() {
+ @Override
+ public SystemConfigManager createService(ContextImpl ctx) {
+ return new SystemConfigManager();
+ }});
registerService(Context.TELEPHONY_REGISTRY_SERVICE, TelephonyRegistryManager.class,
new CachedServiceFetcher<TelephonyRegistryManager>() {
@@ -652,20 +663,6 @@ final class SystemServiceRegistry {
return new TelephonyRegistryManager(ctx);
}});
- registerService(Context.TELEPHONY_SUBSCRIPTION_SERVICE, SubscriptionManager.class,
- new CachedServiceFetcher<SubscriptionManager>() {
- @Override
- public SubscriptionManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- return new SubscriptionManager(ctx.getOuterContext());
- }});
-
- registerService(Context.CARRIER_CONFIG_SERVICE, CarrierConfigManager.class,
- new CachedServiceFetcher<CarrierConfigManager>() {
- @Override
- public CarrierConfigManager createService(ContextImpl ctx) {
- return new CarrierConfigManager(ctx.getOuterContext());
- }});
-
registerService(Context.TELECOM_SERVICE, TelecomManager.class,
new CachedServiceFetcher<TelecomManager>() {
@Override
@@ -673,20 +670,6 @@ final class SystemServiceRegistry {
return new TelecomManager(ctx.getOuterContext());
}});
- registerService(Context.EUICC_SERVICE, EuiccManager.class,
- new CachedServiceFetcher<EuiccManager>() {
- @Override
- public EuiccManager createService(ContextImpl ctx) {
- return new EuiccManager(ctx.getOuterContext());
- }});
-
- registerService(Context.EUICC_CARD_SERVICE, EuiccCardManager.class,
- new CachedServiceFetcher<EuiccCardManager>() {
- @Override
- public EuiccCardManager createService(ContextImpl ctx) {
- return new EuiccCardManager(ctx.getOuterContext());
- }});
-
registerService(Context.MMS_SERVICE, MmsManager.class,
new CachedServiceFetcher<MmsManager>() {
@Override
@@ -740,20 +723,20 @@ final class SystemServiceRegistry {
throws ServiceNotFoundException {
final IBinder b = ServiceManager.getService(Context.WALLPAPER_SERVICE);
if (b == null) {
- // There are 2 reason service can be null:
- // 1.Device doesn't support it - that's fine
- // 2.App is running on instant mode - should fail
+ ApplicationInfo appInfo = ctx.getApplicationInfo();
+ if (appInfo.targetSdkVersion >= Build.VERSION_CODES.P
+ && appInfo.isInstantApp()) {
+ // Instant app
+ throw new ServiceNotFoundException(Context.WALLPAPER_SERVICE);
+ }
final boolean enabled = Resources.getSystem()
.getBoolean(com.android.internal.R.bool.config_enableWallpaperService);
if (!enabled) {
- // Life moves on...
+ // Device doesn't support wallpaper, return a limited manager
return DisabledWallpaperManager.getInstance();
}
- if (ctx.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.P) {
- // Instant app
- throw new ServiceNotFoundException(Context.WALLPAPER_SERVICE);
- }
// Bad state - WallpaperManager methods will throw exception
+ Log.e(TAG, "No wallpaper service");
}
IWallpaperManager service = IWallpaperManager.Stub.asInterface(b);
return new WallpaperManager(service, ctx.getOuterContext(),
@@ -770,68 +753,6 @@ final class SystemServiceRegistry {
ConnectivityThread.getInstanceLooper());
}});
- registerService(Context.WIFI_SERVICE, WifiManager.class,
- new CachedServiceFetcher<WifiManager>() {
- @Override
- public WifiManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SERVICE);
- IWifiManager service = IWifiManager.Stub.asInterface(b);
- return new WifiManager(ctx.getOuterContext(), service,
- ConnectivityThread.getInstanceLooper());
- }});
-
- registerService(Context.WIFI_P2P_SERVICE, WifiP2pManager.class,
- new StaticServiceFetcher<WifiP2pManager>() {
- @Override
- public WifiP2pManager createService() throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_P2P_SERVICE);
- IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
- return new WifiP2pManager(service);
- }});
-
- registerService(Context.WIFI_AWARE_SERVICE, WifiAwareManager.class,
- new CachedServiceFetcher<WifiAwareManager>() {
- @Override
- public WifiAwareManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_AWARE_SERVICE);
- IWifiAwareManager service = IWifiAwareManager.Stub.asInterface(b);
- if (service == null) {
- return null;
- }
- return new WifiAwareManager(ctx.getOuterContext(), service);
- }});
-
- registerService(Context.WIFI_SCANNING_SERVICE, WifiScanner.class,
- new CachedServiceFetcher<WifiScanner>() {
- @Override
- public WifiScanner createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_SCANNING_SERVICE);
- IWifiScanner service = IWifiScanner.Stub.asInterface(b);
- return new WifiScanner(ctx.getOuterContext(), service,
- ConnectivityThread.getInstanceLooper());
- }});
-
- registerService(Context.WIFI_RTT_SERVICE, RttManager.class,
- new CachedServiceFetcher<RttManager>() {
- @Override
- public RttManager createService(ContextImpl ctx) throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_RTT_RANGING_SERVICE);
- IWifiRttManager service = IWifiRttManager.Stub.asInterface(b);
- return new RttManager(ctx.getOuterContext(),
- new WifiRttManager(ctx.getOuterContext(), service));
- }});
-
- registerService(Context.WIFI_RTT_RANGING_SERVICE, WifiRttManager.class,
- new CachedServiceFetcher<WifiRttManager>() {
- @Override
- public WifiRttManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(
- Context.WIFI_RTT_RANGING_SERVICE);
- IWifiRttManager service = IWifiRttManager.Stub.asInterface(b);
- return new WifiRttManager(ctx.getOuterContext(), service);
- }});
-
registerService(Context.ETHERNET_SERVICE, EthernetManager.class,
new CachedServiceFetcher<EthernetManager>() {
@Override
@@ -841,6 +762,14 @@ final class SystemServiceRegistry {
return new EthernetManager(ctx.getOuterContext(), service);
}});
+ registerService(Context.WIFI_NL80211_SERVICE, WifiNl80211Manager.class,
+ new CachedServiceFetcher<WifiNl80211Manager>() {
+ @Override
+ public WifiNl80211Manager createService(ContextImpl ctx) {
+ return new WifiNl80211Manager(ctx.getOuterContext());
+ }
+ });
+
registerService(Context.WINDOW_SERVICE, WindowManager.class,
new CachedServiceFetcher<WindowManager>() {
@Override
@@ -988,17 +917,11 @@ final class SystemServiceRegistry {
@Override
public BiometricManager createService(ContextImpl ctx)
throws ServiceNotFoundException {
- if (BiometricManager.hasBiometrics(ctx)) {
- final IBinder binder =
- ServiceManager.getServiceOrThrow(Context.BIOMETRIC_SERVICE);
- final IBiometricService service =
- IBiometricService.Stub.asInterface(binder);
- return new BiometricManager(ctx.getOuterContext(), service);
- } else {
- // Allow access to the manager when service is null. This saves memory
- // on devices without biometric hardware.
- return new BiometricManager(ctx.getOuterContext(), null);
- }
+ final IBinder binder =
+ ServiceManager.getServiceOrThrow(Context.AUTH_SERVICE);
+ final IAuthService service =
+ IAuthService.Stub.asInterface(binder);
+ return new BiometricManager(ctx.getOuterContext(), service);
}
});
@@ -1011,6 +934,17 @@ final class SystemServiceRegistry {
return new TvInputManager(service, ctx.getUserId());
}});
+ registerService(Context.TV_TUNER_RESOURCE_MGR_SERVICE, TunerResourceManager.class,
+ new CachedServiceFetcher<TunerResourceManager>() {
+ @Override
+ public TunerResourceManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder iBinder =
+ ServiceManager.getServiceOrThrow(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
+ ITunerResourceManager service = ITunerResourceManager.Stub.asInterface(iBinder);
+ return new TunerResourceManager(service, ctx.getUserId());
+ }});
+
registerService(Context.NETWORK_SCORE_SERVICE, NetworkScoreManager.class,
new CachedServiceFetcher<NetworkScoreManager>() {
@Override
@@ -1034,14 +968,6 @@ final class SystemServiceRegistry {
return new NetworkStatsManager(ctx.getOuterContext());
}});
- registerService(Context.JOB_SCHEDULER_SERVICE, JobScheduler.class,
- new StaticServiceFetcher<JobScheduler>() {
- @Override
- public JobScheduler createService() throws ServiceNotFoundException {
- IBinder b = ServiceManager.getServiceOrThrow(Context.JOB_SCHEDULER_SERVICE);
- return new JobSchedulerImpl(IJobScheduler.Stub.asInterface(b));
- }});
-
registerService(Context.PERSISTENT_DATA_BLOCK_SERVICE, PersistentDataBlockManager.class,
new StaticServiceFetcher<PersistentDataBlockManager>() {
@Override
@@ -1273,17 +1199,6 @@ final class SystemServiceRegistry {
}
});
- registerService(Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
- new CachedServiceFetcher<DeviceIdleManager>() {
- @Override
- public DeviceIdleManager createService(ContextImpl ctx)
- throws ServiceNotFoundException {
- IDeviceIdleController service = IDeviceIdleController.Stub.asInterface(
- ServiceManager.getServiceOrThrow(
- Context.DEVICE_IDLE_CONTROLLER));
- return new DeviceIdleManager(ctx.getOuterContext(), service);
- }});
-
registerService(Context.TIME_DETECTOR_SERVICE, TimeDetector.class,
new CachedServiceFetcher<TimeDetector>() {
@Override
@@ -1300,18 +1215,11 @@ final class SystemServiceRegistry {
return new TimeZoneDetectorImpl();
}});
- registerService(Context.TELEPHONY_IMS_SERVICE, android.telephony.ims.ImsManager.class,
- new CachedServiceFetcher<android.telephony.ims.ImsManager>() {
- @Override
- public android.telephony.ims.ImsManager createService(ContextImpl ctx) {
- return new android.telephony.ims.ImsManager(ctx.getOuterContext());
- }
- });
-
registerService(Context.PERMISSION_SERVICE, PermissionManager.class,
new CachedServiceFetcher<PermissionManager>() {
@Override
- public PermissionManager createService(ContextImpl ctx) {
+ public PermissionManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
IPackageManager packageManager = AppGlobals.getPackageManager();
return new PermissionManager(ctx.getOuterContext(), packageManager);
}});
@@ -1360,6 +1268,26 @@ final class SystemServiceRegistry {
return new DynamicSystemManager(
IDynamicSystemService.Stub.asInterface(b));
}});
+
+ registerService(Context.BATTERY_STATS_SERVICE, BatteryStatsManager.class,
+ new CachedServiceFetcher<BatteryStatsManager>() {
+ @Override
+ public BatteryStatsManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(
+ Context.BATTERY_STATS_SERVICE);
+ return new BatteryStatsManager(
+ IBatteryStats.Stub.asInterface(b));
+ }});
+ registerService(Context.DATA_LOADER_MANAGER_SERVICE, DataLoaderManager.class,
+ new CachedServiceFetcher<DataLoaderManager>() {
+ @Override
+ public DataLoaderManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(
+ Context.DATA_LOADER_MANAGER_SERVICE);
+ return new DataLoaderManager(IDataLoaderManager.Stub.asInterface(b));
+ }});
registerService(Context.LIGHTS_SERVICE, LightsManager.class,
new CachedServiceFetcher<LightsManager>() {
@Override
@@ -1367,11 +1295,69 @@ final class SystemServiceRegistry {
throws ServiceNotFoundException {
return new LightsManager(ctx);
}});
+ registerService(Context.INCREMENTAL_SERVICE, IncrementalManager.class,
+ new CachedServiceFetcher<IncrementalManager>() {
+ @Override
+ public IncrementalManager createService(ContextImpl ctx) {
+ IBinder b = ServiceManager.getService(Context.INCREMENTAL_SERVICE);
+ if (b == null) {
+ return null;
+ }
+ return new IncrementalManager(
+ IIncrementalService.Stub.asInterface(b));
+ }});
+
+ registerService(Context.FILE_INTEGRITY_SERVICE, FileIntegrityManager.class,
+ new CachedServiceFetcher<FileIntegrityManager>() {
+ @Override
+ public FileIntegrityManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(
+ Context.FILE_INTEGRITY_SERVICE);
+ return new FileIntegrityManager(ctx.getOuterContext(),
+ IFileIntegrityService.Stub.asInterface(b));
+ }});
//CHECKSTYLE:ON IndentationCheck
+ registerService(Context.APP_INTEGRITY_SERVICE, AppIntegrityManager.class,
+ new CachedServiceFetcher<AppIntegrityManager>() {
+ @Override
+ public AppIntegrityManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ IBinder b = ServiceManager.getServiceOrThrow(Context.APP_INTEGRITY_SERVICE);
+ return new AppIntegrityManager(IAppIntegrityManager.Stub.asInterface(b));
+ }});
+ registerService(Context.DREAM_SERVICE, DreamManager.class,
+ new CachedServiceFetcher<DreamManager>() {
+ @Override
+ public DreamManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ return new DreamManager(ctx);
+ }});
+
+ sInitializing = true;
+ try {
+ // Note: the following functions need to be @SystemApis, once they become mainline
+ // modules.
+ JobSchedulerFrameworkInitializer.registerServiceWrappers();
+ BlobStoreManagerFrameworkInitializer.initialize();
+ TelephonyFrameworkInitializer.registerServiceWrappers();
+ WifiFrameworkInitializer.registerServiceWrappers();
+ StatsFrameworkInitializer.registerServiceWrappers();
+ } 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];
@@ -1379,27 +1365,270 @@ 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);
- return fetcher != null ? fetcher.getService(ctx) : null;
+ if (name == null) {
+ return null;
+ }
+ final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
+ if (fetcher == null) {
+ if (sEnableServiceNotFoundWtf) {
+ Slog.wtf(TAG, "Unknown manager requested: " + name);
+ }
+ return null;
+ }
+
+ final Object ret = fetcher.getService(ctx);
+ if (sEnableServiceNotFoundWtf && ret == null) {
+ // Some services do return null in certain situations, so don't do WTF for them.
+ switch (name) {
+ case Context.CONTENT_CAPTURE_MANAGER_SERVICE:
+ case Context.APP_PREDICTION_SERVICE:
+ case Context.INCREMENTAL_SERVICE:
+ return null;
+ }
+ Slog.wtf(TAG, "Manager wrapper not available: " + name);
+ return null;
+ }
+ return ret;
}
/**
* 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);
+ if (serviceClass == null) {
+ return null;
+ }
+ final String serviceName = SYSTEM_SERVICE_NAMES.get(serviceClass);
+ if (sEnableServiceNotFoundWtf && serviceName == null) {
+ // This should be a caller bug.
+ Slog.wtf(TAG, "Unknown manager requested: " + serviceClass.getCanonicalName());
+ }
+ return serviceName;
}
/**
* 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);
+ SYSTEM_SERVICE_CLASS_NAMES.put(serviceName, serviceClass.getSimpleName());
+ }
+
+ /**
+ * Returns system service class name by system service name. This method is mostly an inverse of
+ * {@link #getSystemServiceName(Class)}
+ *
+ * @return system service class name. {@code null} if service name is invalid.
+ * @hide
+ */
+ @Nullable
+ public static String getSystemServiceClassName(@NonNull String name) {
+ return SYSTEM_SERVICE_CLASS_NAMES.get(name);
+ }
+
+ /**
+ * Callback interface used as a parameter to {@link #registerStaticService(
+ * String, Class, StaticServiceProducerWithoutBinder)}, 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
+ public interface StaticServiceProducerWithoutBinder<TServiceClass> {
+ /**
+ * Return a new service wrapper of type {@code TServiceClass}.
+ */
+ @NonNull
+ 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
+ public interface StaticServiceProducerWithBinder<TServiceClass> {
+ /**
+ * Return a new service wrapper of type {@code TServiceClass} backed by a given
+ * service binder object.
+ */
+ @NonNull
+ TServiceClass createService(@NonNull IBinder serviceBinder);
+ }
+
+ /**
+ * Callback interface used as a parameter to {@link #registerContextAwareService(
+ * String, Class, ContextAwareServiceProducerWithoutBinder)},
+ * 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
+ public interface ContextAwareServiceProducerWithoutBinder<TServiceClass> {
+ /**
+ * Return a new service wrapper of type {@code TServiceClass} tied to a given
+ * {@code context}.
+ */
+ @NonNull
+ //TODO Do we need to pass the "base context" too?
+ TServiceClass createService(@NonNull 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
+ 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}.
+ */
+ @NonNull
+ //TODO Do we need to pass the "base context" too?
+ TServiceClass createService(@NonNull Context context, @NonNull 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
+ */
+ @SystemApi
+ public static <TServiceClass> void registerStaticService(
+ @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+ @NonNull StaticServiceProducerWithBinder<TServiceClass> serviceProducer) {
+ ensureInitializing("registerStaticService");
+ Preconditions.checkStringNotEmpty(serviceName);
+ Objects.requireNonNull(serviceWrapperClass);
+ Objects.requireNonNull(serviceProducer);
+
+ registerService(serviceName, serviceWrapperClass,
+ new StaticServiceFetcher<TServiceClass>() {
+ @Override
+ public TServiceClass createService() throws ServiceNotFoundException {
+ return serviceProducer.createService(
+ ServiceManager.getServiceOrThrow(serviceName));
+ }});
+ }
+
+ /**
+ * Similar to {@link #registerStaticService(String, Class, StaticServiceProducerWithBinder)},
+ * but used for a "service wrapper" that doesn't take a service binder in its constructor.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static <TServiceClass> void registerStaticService(
+ @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+ @NonNull StaticServiceProducerWithoutBinder<TServiceClass> serviceProducer) {
+ ensureInitializing("registerStaticService");
+ Preconditions.checkStringNotEmpty(serviceName);
+ Objects.requireNonNull(serviceWrapperClass);
+ Objects.requireNonNull(serviceProducer);
+
+ registerService(serviceName, serviceWrapperClass,
+ new StaticServiceFetcher<TServiceClass>() {
+ @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
+ public static <TServiceClass> void registerContextAwareService(
+ @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+ @NonNull ContextAwareServiceProducerWithBinder<TServiceClass> serviceProducer) {
+ ensureInitializing("registerContextAwareService");
+ Preconditions.checkStringNotEmpty(serviceName);
+ Objects.requireNonNull(serviceWrapperClass);
+ Objects.requireNonNull(serviceProducer);
+
+ registerService(serviceName, serviceWrapperClass,
+ new CachedServiceFetcher<TServiceClass>() {
+ @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
+ public static <TServiceClass> void registerContextAwareService(
+ @NonNull String serviceName, @NonNull Class<TServiceClass> serviceWrapperClass,
+ @NonNull ContextAwareServiceProducerWithoutBinder<TServiceClass> serviceProducer) {
+ ensureInitializing("registerContextAwareService");
+ Preconditions.checkStringNotEmpty(serviceName);
+ Objects.requireNonNull(serviceWrapperClass);
+ Objects.requireNonNull(serviceProducer);
+
+ registerService(serviceName, serviceWrapperClass,
+ new CachedServiceFetcher<TServiceClass>() {
+ @Override
+ public TServiceClass createService(ContextImpl ctx) {
+ return serviceProducer.createService(ctx.getOuterContext());
+ }});
}
/**
@@ -1429,6 +1658,9 @@ final class SystemServiceRegistry {
public final T getService(ContextImpl ctx) {
final Object[] cache = ctx.mServiceCache;
final int[] gates = ctx.mServiceInitializationStateArray;
+ boolean interrupted = false;
+
+ T ret = null;
for (;;) {
boolean doInitialize = false;
@@ -1436,7 +1668,8 @@ final class SystemServiceRegistry {
// Return it if we already have a cached instance.
T service = (T) cache[mCacheIndex];
if (service != null || gates[mCacheIndex] == ContextImpl.STATE_NOT_FOUND) {
- return service;
+ ret = service;
+ break; // exit the for (;;)
}
// If we get here, there's no cached instance.
@@ -1479,22 +1712,33 @@ final class SystemServiceRegistry {
cache.notifyAll();
}
}
- return service;
+ ret = service;
+ break; // exit the for (;;)
}
// The other threads will wait for the first thread to call notifyAll(),
// and go back to the top and retry.
synchronized (cache) {
+ // Repeat until the state becomes STATE_READY or STATE_NOT_FOUND.
+ // We can't respond to interrupts here; just like we can't in the "doInitialize"
+ // path, so we remember the interrupt state here and re-interrupt later.
while (gates[mCacheIndex] < ContextImpl.STATE_READY) {
try {
+ // Clear the interrupt state.
+ interrupted |= Thread.interrupted();
cache.wait();
} catch (InterruptedException e) {
- Log.w(TAG, "getService() interrupted");
- Thread.currentThread().interrupt();
- return null;
+ // This shouldn't normally happen, but if someone interrupts the
+ // thread, it will.
+ Slog.w(TAG, "getService() interrupted");
+ interrupted = true;
}
}
}
}
+ if (interrupted) {
+ Thread.currentThread().interrupt();
+ }
+ return ret;
}
public abstract T createService(ContextImpl ctx) throws ServiceNotFoundException;
@@ -1557,6 +1801,7 @@ 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