• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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