1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.LOLLIPOP; 4 import static android.os.Build.VERSION_CODES.M; 5 import static android.os.Build.VERSION_CODES.N; 6 import static android.os.Build.VERSION_CODES.N_MR1; 7 import static android.os.Build.VERSION_CODES.O; 8 import static android.os.Build.VERSION_CODES.P; 9 import static android.os.Build.VERSION_CODES.Q; 10 import static android.os.Build.VERSION_CODES.R; 11 import static android.os.Build.VERSION_CODES.S; 12 import static android.os.Build.VERSION_CODES.TIRAMISU; 13 import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; 14 import static com.google.common.base.Preconditions.checkNotNull; 15 16 import android.accounts.IAccountManager; 17 import android.app.IAlarmManager; 18 import android.app.ILocaleManager; 19 import android.app.INotificationManager; 20 import android.app.ISearchManager; 21 import android.app.IUiModeManager; 22 import android.app.IWallpaperManager; 23 import android.app.admin.IDevicePolicyManager; 24 import android.app.ambientcontext.IAmbientContextManager; 25 import android.app.job.IJobScheduler; 26 import android.app.role.IRoleManager; 27 import android.app.slice.ISliceManager; 28 import android.app.timedetector.ITimeDetectorService; 29 import android.app.timezonedetector.ITimeZoneDetectorService; 30 import android.app.trust.ITrustManager; 31 import android.app.usage.IStorageStatsManager; 32 import android.app.usage.IUsageStatsManager; 33 import android.app.wearable.IWearableSensingManager; 34 import android.bluetooth.BluetoothAdapter; 35 import android.bluetooth.IBluetooth; 36 import android.bluetooth.IBluetoothManager; 37 import android.companion.ICompanionDeviceManager; 38 import android.companion.virtual.IVirtualDeviceManager; 39 import android.content.Context; 40 import android.content.IClipboard; 41 import android.content.IRestrictionsManager; 42 import android.content.integrity.IAppIntegrityManager; 43 import android.content.pm.ICrossProfileApps; 44 import android.content.pm.IShortcutService; 45 import android.content.rollback.IRollbackManager; 46 import android.hardware.ISensorPrivacyManager; 47 import android.hardware.biometrics.IAuthService; 48 import android.hardware.biometrics.IBiometricService; 49 import android.hardware.fingerprint.IFingerprintService; 50 import android.hardware.input.IInputManager; 51 import android.hardware.location.IContextHubService; 52 import android.hardware.usb.IUsbManager; 53 import android.location.ICountryDetector; 54 import android.location.ILocationManager; 55 import android.media.IAudioService; 56 import android.media.IMediaRouterService; 57 import android.media.session.ISessionManager; 58 import android.net.IConnectivityManager; 59 import android.net.IIpSecService; 60 import android.net.INetworkPolicyManager; 61 import android.net.INetworkScoreService; 62 import android.net.ITetheringConnector; 63 import android.net.IVpnManager; 64 import android.net.nsd.INsdManager; 65 import android.net.vcn.IVcnManagementService; 66 import android.net.wifi.IWifiManager; 67 import android.net.wifi.aware.IWifiAwareManager; 68 import android.net.wifi.p2p.IWifiP2pManager; 69 import android.net.wifi.rtt.IWifiRttManager; 70 import android.nfc.INfcAdapter; 71 import android.os.BatteryStats; 72 import android.os.Binder; 73 import android.os.IBatteryPropertiesRegistrar; 74 import android.os.IBinder; 75 import android.os.IDumpstate; 76 import android.os.IInterface; 77 import android.os.IPowerManager; 78 import android.os.IThermalService; 79 import android.os.IUserManager; 80 import android.os.RemoteException; 81 import android.os.ServiceManager; 82 import android.os.storage.IStorageManager; 83 import android.permission.ILegacyPermissionManager; 84 import android.permission.IPermissionManager; 85 import android.safetycenter.ISafetyCenterManager; 86 import android.security.IFileIntegrityService; 87 import android.speech.IRecognitionServiceManager; 88 import android.uwb.IUwbAdapter; 89 import android.view.IWindowManager; 90 import android.view.contentcapture.IContentCaptureManager; 91 import android.view.translation.ITranslationManager; 92 import com.android.internal.app.IAppOpsService; 93 import com.android.internal.app.IBatteryStats; 94 import com.android.internal.app.ISoundTriggerService; 95 import com.android.internal.app.IVoiceInteractionManagerService; 96 import com.android.internal.appwidget.IAppWidgetService; 97 import com.android.internal.compat.IPlatformCompat; 98 import com.android.internal.os.IDropBoxManagerService; 99 import com.android.internal.statusbar.IStatusBar; 100 import com.android.internal.telephony.ITelephony; 101 import com.android.internal.telephony.ITelephonyRegistry; 102 import com.android.internal.view.IInputMethodManager; 103 import java.util.HashMap; 104 import java.util.HashSet; 105 import java.util.Map; 106 import java.util.Set; 107 import javax.annotation.Nullable; 108 import javax.annotation.concurrent.GuardedBy; 109 import org.robolectric.RuntimeEnvironment; 110 import org.robolectric.annotation.Implementation; 111 import org.robolectric.annotation.Implements; 112 import org.robolectric.annotation.Resetter; 113 import org.robolectric.util.ReflectionHelpers; 114 115 /** Shadow for {@link ServiceManager}. */ 116 @SuppressWarnings("NewApi") 117 @Implements(value = ServiceManager.class, isInAndroidSdk = false) 118 public class ShadowServiceManager { 119 120 // A mutable map that contains a list of binder services. It is mutable so entries can be added by 121 // ShadowServiceManager subclasses. This is useful to support prerelease SDKs. 122 protected static final Map<String, BinderService> binderServices = buildBinderServicesMap(); 123 124 @GuardedBy("ShadowServiceManager.class") 125 private static final Set<String> unavailableServices = new HashSet<>(); 126 127 /** Represents the type of implementation to generate for the Binder interface */ 128 private enum BinderProxyType { 129 /* use ReflectionHelpers.createNullProxy */ 130 NULL, 131 /* use ReflectionHelpers.createDeepProxy */ 132 DEEP, 133 /* use ReflectionHelpers.createDelegatingProxy */ 134 DELEGATING 135 } 136 137 /** 138 * A data class that holds descriptor information about binder services. It also holds the cached 139 * binder object if it is requested by {@link #getService(String)}. 140 */ 141 private static final class BinderService { 142 143 private final Class<? extends IInterface> clazz; 144 private final String className; 145 private final BinderProxyType proxyType; 146 private Binder cachedBinder; 147 private final Object delegate; 148 BinderService( Class<? extends IInterface> clazz, String className, BinderProxyType proxyType, @Nullable Object delegate)149 BinderService( 150 Class<? extends IInterface> clazz, 151 String className, 152 BinderProxyType proxyType, 153 @Nullable Object delegate) { 154 this.clazz = clazz; 155 this.className = className; 156 this.proxyType = proxyType; 157 this.delegate = delegate; 158 if (proxyType == BinderProxyType.DELEGATING) { 159 checkNotNull(delegate); 160 } 161 } 162 163 @GuardedBy("ShadowServiceManager.class") getBinder()164 IBinder getBinder() { 165 if (cachedBinder == null) { 166 cachedBinder = new Binder(); 167 168 cachedBinder.attachInterface(createProxy(), className); 169 } 170 return cachedBinder; 171 } 172 createProxy()173 private IInterface createProxy() { 174 switch (proxyType) { 175 case NULL: 176 return ReflectionHelpers.createNullProxy(clazz); 177 case DEEP: 178 return ReflectionHelpers.createDeepProxy(clazz); 179 case DELEGATING: 180 return ReflectionHelpers.createDelegatingProxy(clazz, delegate); 181 } 182 throw new IllegalStateException("unrecognized proxy type " + proxyType); 183 } 184 } 185 buildBinderServicesMap()186 private static Map<String, BinderService> buildBinderServicesMap() { 187 Map<String, BinderService> binderServices = new HashMap<>(); 188 addBinderService(binderServices, Context.CLIPBOARD_SERVICE, IClipboard.class); 189 addBinderService(binderServices, Context.WIFI_P2P_SERVICE, IWifiP2pManager.class); 190 addBinderService(binderServices, Context.ACCOUNT_SERVICE, IAccountManager.class); 191 addBinderService(binderServices, Context.USB_SERVICE, IUsbManager.class); 192 addBinderService(binderServices, Context.LOCATION_SERVICE, ILocationManager.class); 193 addBinderService(binderServices, Context.INPUT_METHOD_SERVICE, IInputMethodManager.class); 194 addBinderService(binderServices, Context.ALARM_SERVICE, IAlarmManager.class); 195 addBinderService(binderServices, Context.POWER_SERVICE, IPowerManager.class); 196 addBinderService(binderServices, BatteryStats.SERVICE_NAME, IBatteryStats.class); 197 addBinderService(binderServices, Context.DROPBOX_SERVICE, IDropBoxManagerService.class); 198 addBinderService(binderServices, Context.DEVICE_POLICY_SERVICE, IDevicePolicyManager.class); 199 addBinderService(binderServices, Context.TELEPHONY_SERVICE, ITelephony.class); 200 addBinderService(binderServices, Context.CONNECTIVITY_SERVICE, IConnectivityManager.class); 201 addBinderService(binderServices, Context.WIFI_SERVICE, IWifiManager.class); 202 addBinderService(binderServices, Context.SEARCH_SERVICE, ISearchManager.class); 203 addBinderService(binderServices, Context.UI_MODE_SERVICE, IUiModeManager.class); 204 addBinderService(binderServices, Context.NETWORK_POLICY_SERVICE, INetworkPolicyManager.class); 205 addBinderService(binderServices, Context.INPUT_SERVICE, IInputManager.class); 206 addBinderService(binderServices, Context.COUNTRY_DETECTOR, ICountryDetector.class); 207 addBinderService(binderServices, Context.NSD_SERVICE, INsdManager.class); 208 addBinderService(binderServices, Context.AUDIO_SERVICE, IAudioService.class); 209 addBinderService(binderServices, Context.APPWIDGET_SERVICE, IAppWidgetService.class); 210 addBinderService(binderServices, Context.NOTIFICATION_SERVICE, INotificationManager.class); 211 addBinderService(binderServices, Context.WALLPAPER_SERVICE, IWallpaperManager.class); 212 addBinderService(binderServices, Context.BLUETOOTH_SERVICE, IBluetooth.class); 213 addBinderService(binderServices, Context.WINDOW_SERVICE, IWindowManager.class); 214 addBinderService(binderServices, Context.NFC_SERVICE, INfcAdapter.class, BinderProxyType.DEEP); 215 addBinderService(binderServices, Context.USER_SERVICE, IUserManager.class); 216 addBinderService( 217 binderServices, 218 BluetoothAdapter.BLUETOOTH_MANAGER_SERVICE, 219 IBluetoothManager.class, 220 BinderProxyType.DELEGATING, 221 IBluetoothManagerDelegates.createDelegate()); 222 223 addBinderService(binderServices, Context.APP_OPS_SERVICE, IAppOpsService.class); 224 addBinderService(binderServices, "batteryproperties", IBatteryPropertiesRegistrar.class); 225 226 if (RuntimeEnvironment.getApiLevel() >= LOLLIPOP) { 227 addBinderService(binderServices, Context.RESTRICTIONS_SERVICE, IRestrictionsManager.class); 228 addBinderService(binderServices, Context.TRUST_SERVICE, ITrustManager.class); 229 addBinderService(binderServices, Context.JOB_SCHEDULER_SERVICE, IJobScheduler.class); 230 addBinderService(binderServices, Context.NETWORK_SCORE_SERVICE, INetworkScoreService.class); 231 addBinderService(binderServices, Context.USAGE_STATS_SERVICE, IUsageStatsManager.class); 232 addBinderService(binderServices, Context.MEDIA_ROUTER_SERVICE, IMediaRouterService.class); 233 addBinderService( 234 binderServices, 235 Context.MEDIA_SESSION_SERVICE, 236 ISessionManager.class, 237 BinderProxyType.DEEP); 238 addBinderService( 239 binderServices, 240 Context.VOICE_INTERACTION_MANAGER_SERVICE, 241 IVoiceInteractionManagerService.class, 242 BinderProxyType.DEEP); 243 } 244 if (RuntimeEnvironment.getApiLevel() >= M) { 245 addBinderService(binderServices, Context.FINGERPRINT_SERVICE, IFingerprintService.class); 246 } 247 if (RuntimeEnvironment.getApiLevel() >= N) { 248 addBinderService(binderServices, Context.CONTEXTHUB_SERVICE, IContextHubService.class); 249 addBinderService(binderServices, Context.SOUND_TRIGGER_SERVICE, ISoundTriggerService.class); 250 } 251 if (RuntimeEnvironment.getApiLevel() >= N_MR1) { 252 addBinderService(binderServices, Context.SHORTCUT_SERVICE, IShortcutService.class); 253 } 254 if (RuntimeEnvironment.getApiLevel() >= O) { 255 addBinderService(binderServices, "mount", IStorageManager.class); 256 addBinderService(binderServices, Context.WIFI_AWARE_SERVICE, IWifiAwareManager.class); 257 addBinderService(binderServices, Context.STORAGE_STATS_SERVICE, IStorageStatsManager.class); 258 addBinderService( 259 binderServices, Context.COMPANION_DEVICE_SERVICE, ICompanionDeviceManager.class); 260 } else { 261 addBinderService(binderServices, "mount", "android.os.storage.IMountService"); 262 } 263 if (RuntimeEnvironment.getApiLevel() >= P) { 264 addBinderService(binderServices, Context.SLICE_SERVICE, ISliceManager.class); 265 addBinderService(binderServices, Context.CROSS_PROFILE_APPS_SERVICE, ICrossProfileApps.class); 266 addBinderService(binderServices, Context.WIFI_RTT_RANGING_SERVICE, IWifiRttManager.class); 267 addBinderService(binderServices, Context.IPSEC_SERVICE, IIpSecService.class); 268 } 269 if (RuntimeEnvironment.getApiLevel() >= Q) { 270 addBinderService(binderServices, Context.BIOMETRIC_SERVICE, IBiometricService.class); 271 addBinderService( 272 binderServices, Context.CONTENT_CAPTURE_MANAGER_SERVICE, IContentCaptureManager.class); 273 addBinderService(binderServices, Context.ROLE_SERVICE, IRoleManager.class); 274 addBinderService(binderServices, Context.ROLLBACK_SERVICE, IRollbackManager.class); 275 addBinderService(binderServices, Context.THERMAL_SERVICE, IThermalService.class); 276 addBinderService(binderServices, Context.BUGREPORT_SERVICE, IDumpstate.class); 277 } 278 if (RuntimeEnvironment.getApiLevel() >= R) { 279 addBinderService(binderServices, Context.APP_INTEGRITY_SERVICE, IAppIntegrityManager.class); 280 addBinderService(binderServices, Context.AUTH_SERVICE, IAuthService.class); 281 addBinderService(binderServices, Context.TETHERING_SERVICE, ITetheringConnector.class); 282 addBinderService(binderServices, "telephony.registry", ITelephonyRegistry.class); 283 addBinderService(binderServices, Context.PLATFORM_COMPAT_SERVICE, IPlatformCompat.class); 284 addBinderService(binderServices, Context.FILE_INTEGRITY_SERVICE, IFileIntegrityService.class); 285 } 286 if (RuntimeEnvironment.getApiLevel() >= S) { 287 addBinderService(binderServices, "permissionmgr", IPermissionManager.class); 288 addBinderService( 289 binderServices, Context.TIME_ZONE_DETECTOR_SERVICE, ITimeZoneDetectorService.class); 290 addBinderService(binderServices, Context.TIME_DETECTOR_SERVICE, ITimeDetectorService.class); 291 addBinderService( 292 binderServices, Context.SPEECH_RECOGNITION_SERVICE, IRecognitionServiceManager.class); 293 addBinderService( 294 binderServices, Context.LEGACY_PERMISSION_SERVICE, ILegacyPermissionManager.class); 295 addBinderService(binderServices, Context.UWB_SERVICE, IUwbAdapter.class); 296 addBinderService(binderServices, Context.VCN_MANAGEMENT_SERVICE, IVcnManagementService.class); 297 addBinderService( 298 binderServices, Context.TRANSLATION_MANAGER_SERVICE, ITranslationManager.class); 299 addBinderService(binderServices, Context.SENSOR_PRIVACY_SERVICE, ISensorPrivacyManager.class); 300 addBinderService(binderServices, Context.VPN_MANAGEMENT_SERVICE, IVpnManager.class); 301 } 302 if (RuntimeEnvironment.getApiLevel() >= TIRAMISU) { 303 addBinderService( 304 binderServices, Context.AMBIENT_CONTEXT_SERVICE, IAmbientContextManager.class); 305 addBinderService(binderServices, Context.LOCALE_SERVICE, ILocaleManager.class); 306 addBinderService(binderServices, Context.SAFETY_CENTER_SERVICE, ISafetyCenterManager.class); 307 addBinderService(binderServices, Context.STATUS_BAR_SERVICE, IStatusBar.class); 308 } 309 if (RuntimeEnvironment.getApiLevel() >= UPSIDE_DOWN_CAKE) { 310 addBinderService(binderServices, Context.VIRTUAL_DEVICE_SERVICE, IVirtualDeviceManager.class); 311 addBinderService( 312 binderServices, Context.WEARABLE_SENSING_SERVICE, IWearableSensingManager.class); 313 } 314 return binderServices; 315 } 316 addBinderService( Map<String, BinderService> binderServices, String name, Class<? extends IInterface> clazz)317 protected static void addBinderService( 318 Map<String, BinderService> binderServices, String name, Class<? extends IInterface> clazz) { 319 addBinderService( 320 binderServices, name, clazz, clazz.getCanonicalName(), BinderProxyType.NULL, null); 321 } 322 addBinderService( Map<String, BinderService> binderServices, String name, Class<? extends IInterface> clazz, BinderProxyType proxyType)323 private static void addBinderService( 324 Map<String, BinderService> binderServices, 325 String name, 326 Class<? extends IInterface> clazz, 327 BinderProxyType proxyType) { 328 addBinderService(binderServices, name, clazz, clazz.getCanonicalName(), proxyType, null); 329 } 330 addBinderService( Map<String, BinderService> binderServices, String name, String className)331 private static void addBinderService( 332 Map<String, BinderService> binderServices, String name, String className) { 333 Class<? extends IInterface> clazz; 334 try { 335 clazz = Class.forName(className).asSubclass(IInterface.class); 336 } catch (ClassNotFoundException e) { 337 throw new RuntimeException(e); 338 } 339 addBinderService(binderServices, name, clazz, className, BinderProxyType.NULL, null); 340 } 341 addBinderService( Map<String, BinderService> binderServices, String name, Class<? extends IInterface> clazz, BinderProxyType proxyType, @Nullable Object delegate)342 private static void addBinderService( 343 Map<String, BinderService> binderServices, 344 String name, 345 Class<? extends IInterface> clazz, 346 BinderProxyType proxyType, 347 @Nullable Object delegate) { 348 addBinderService(binderServices, name, clazz, clazz.getCanonicalName(), proxyType, delegate); 349 } 350 addBinderService( Map<String, BinderService> binderServices, String name, Class<? extends IInterface> clazz, String className, BinderProxyType proxyType, @Nullable Object delegate)351 private static void addBinderService( 352 Map<String, BinderService> binderServices, 353 String name, 354 Class<? extends IInterface> clazz, 355 String className, 356 BinderProxyType proxyType, 357 @Nullable Object delegate) { 358 binderServices.put(name, new BinderService(clazz, className, proxyType, delegate)); 359 } 360 361 /** 362 * Returns the {@link IBinder} associated with the given system service. If the given service is 363 * set to unavailable in {@link #setServiceAvailability}, {@code null} will be returned. 364 */ 365 @Implementation getService(String name)366 protected static IBinder getService(String name) { 367 synchronized (ShadowServiceManager.class) { 368 if (unavailableServices.contains(name)) { 369 return null; 370 } 371 return getBinderForService(name); 372 } 373 } 374 375 @Implementation addService(String name, IBinder service)376 protected static void addService(String name, IBinder service) {} 377 378 /** 379 * Same as {@link #getService}. 380 * 381 * <p>The real implementation of {@link #checkService} differs from {@link #getService} in that it 382 * is not a blocking call; so it is more likely to return {@code null} in cases where the service 383 * isn't available (whereas {@link #getService} will block until it becomes available, until a 384 * timeout or error happens). 385 */ 386 @Implementation checkService(String name)387 protected static IBinder checkService(String name) { 388 synchronized (ShadowServiceManager.class) { 389 if (unavailableServices.contains(name)) { 390 return null; 391 } 392 return getBinderForService(name); 393 } 394 } 395 396 @Implementation listServices()397 protected static String[] listServices() throws RemoteException { 398 return null; 399 } 400 401 @Implementation initServiceCache(Map<String, IBinder> cache)402 protected static void initServiceCache(Map<String, IBinder> cache) {} 403 404 /** 405 * Sets the availability of the given system service. If the service is set as unavailable, 406 * subsequent calls to {@link Context#getSystemService} for that service will return {@code null}. 407 * 408 * <p>A service is considered available by default. 409 */ setServiceAvailability(String service, boolean available)410 public static synchronized void setServiceAvailability(String service, boolean available) { 411 if (available) { 412 unavailableServices.remove(service); 413 } else { 414 unavailableServices.add(service); 415 } 416 } 417 418 @GuardedBy("ShadowServiceManager.class") 419 @Nullable getBinderForService(String name)420 private static IBinder getBinderForService(String name) { 421 BinderService binderService = binderServices.get(name); 422 if (binderService == null) { 423 return null; 424 } 425 return binderService.getBinder(); 426 } 427 428 @Resetter reset()429 public static synchronized void reset() { 430 unavailableServices.clear(); 431 } 432 } 433