• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2;
5 import static android.os.Build.VERSION_CODES.KITKAT;
6 import static android.os.Build.VERSION_CODES.LOLLIPOP;
7 import static android.os.Build.VERSION_CODES.M;
8 import static android.os.Build.VERSION_CODES.N_MR1;
9 import static android.os.Build.VERSION_CODES.O;
10 import static android.os.Build.VERSION_CODES.P;
11 import static android.os.Build.VERSION_CODES.Q;
12 
13 import android.accounts.IAccountManager;
14 import android.app.IAlarmManager;
15 import android.app.INotificationManager;
16 import android.app.ISearchManager;
17 import android.app.admin.IDevicePolicyManager;
18 import android.app.job.IJobScheduler;
19 import android.app.role.IRoleManager;
20 import android.app.slice.ISliceManager;
21 import android.app.trust.ITrustManager;
22 import android.app.usage.IUsageStatsManager;
23 import android.content.Context;
24 import android.content.IClipboard;
25 import android.content.IRestrictionsManager;
26 import android.content.pm.IShortcutService;
27 import android.hardware.display.IColorDisplayManager;
28 import android.hardware.fingerprint.IFingerprintService;
29 import android.hardware.input.IInputManager;
30 import android.hardware.usb.IUsbManager;
31 import android.location.ICountryDetector;
32 import android.location.ILocationManager;
33 import android.media.IAudioService;
34 import android.media.IMediaRouterService;
35 import android.media.session.ISessionManager;
36 import android.net.IConnectivityManager;
37 import android.net.INetworkScoreService;
38 import android.net.nsd.INsdManager;
39 import android.net.wifi.IWifiManager;
40 import android.net.wifi.p2p.IWifiP2pManager;
41 import android.os.BatteryStats;
42 import android.os.Binder;
43 import android.os.IBatteryPropertiesRegistrar;
44 import android.os.IBinder;
45 import android.os.IInterface;
46 import android.os.IPowerManager;
47 import android.os.IUserManager;
48 import android.os.RemoteException;
49 import android.os.ServiceManager;
50 import android.os.storage.IStorageManager;
51 import com.android.internal.app.IAppOpsService;
52 import com.android.internal.app.IBatteryStats;
53 import com.android.internal.appwidget.IAppWidgetService;
54 import com.android.internal.os.IDropBoxManagerService;
55 import com.android.internal.view.IInputMethodManager;
56 import java.util.Collections;
57 import java.util.HashMap;
58 import java.util.HashSet;
59 import java.util.Map;
60 import java.util.Set;
61 import org.robolectric.RuntimeEnvironment;
62 import org.robolectric.annotation.Implementation;
63 import org.robolectric.annotation.Implements;
64 import org.robolectric.annotation.Resetter;
65 import org.robolectric.util.ReflectionHelpers;
66 
67 @SuppressWarnings("NewApi")
68 @Implements(value = ServiceManager.class, isInAndroidSdk = false)
69 public class ShadowServiceManager {
70 
71   private static final Map<String, IBinder> SERVICES;
72 
73   private static final Set<String> unavailableServices = new HashSet<>();
74 
75   static {
76     Map<String, IBinder> map = new HashMap<>();
map.put( Context.CLIPBOARD_SERVICE, createBinder(IClipboard.class, "android.content.IClipboard"))77     map.put(
78         Context.CLIPBOARD_SERVICE, createBinder(IClipboard.class, "android.content.IClipboard"));
map.put( Context.WIFI_P2P_SERVICE, createBinder(IWifiP2pManager.class, "android.net.wifi.p2p.IWifiP2pManager"))79     map.put(
80         Context.WIFI_P2P_SERVICE,
81         createBinder(IWifiP2pManager.class, "android.net.wifi.p2p.IWifiP2pManager"));
map.put( Context.ACCOUNT_SERVICE, createBinder(IAccountManager.class, "android.accounts.IAccountManager"))82     map.put(
83         Context.ACCOUNT_SERVICE,
84         createBinder(IAccountManager.class, "android.accounts.IAccountManager"));
map.put( Context.USB_SERVICE, createBinder(IUsbManager.class, "android.hardware.usb.IUsbManager"))85     map.put(
86         Context.USB_SERVICE, createBinder(IUsbManager.class, "android.hardware.usb.IUsbManager"));
map.put( Context.LOCATION_SERVICE, createBinder(ILocationManager.class, "android.location.ILocationManager"))87     map.put(
88         Context.LOCATION_SERVICE,
89         createBinder(ILocationManager.class, "android.location.ILocationManager"));
map.put( Context.INPUT_METHOD_SERVICE, createBinder(IInputMethodManager.class, "com.android.internal.view.IInputMethodManager"))90     map.put(
91         Context.INPUT_METHOD_SERVICE,
92         createBinder(IInputMethodManager.class, "com.android.internal.view.IInputMethodManager"));
map.put(Context.ALARM_SERVICE, createBinder(IAlarmManager.class, "android.app.IAlarmManager"))93     map.put(Context.ALARM_SERVICE, createBinder(IAlarmManager.class, "android.app.IAlarmManager"));
map.put(Context.POWER_SERVICE, createBinder(IPowerManager.class, "android.os.IPowerManager"))94     map.put(Context.POWER_SERVICE, createBinder(IPowerManager.class, "android.os.IPowerManager"));
map.put( BatteryStats.SERVICE_NAME, createBinder(IBatteryStats.class, "com.android.internal.app.IBatteryStats"))95     map.put(
96         BatteryStats.SERVICE_NAME,
97         createBinder(IBatteryStats.class, "com.android.internal.app.IBatteryStats"));
map.put( Context.DROPBOX_SERVICE, createBinder( IDropBoxManagerService.class, "com.android.internal.os.IDropBoxManagerService"))98     map.put(
99         Context.DROPBOX_SERVICE,
100         createBinder(
101             IDropBoxManagerService.class, "com.android.internal.os.IDropBoxManagerService"));
map.put( Context.DEVICE_POLICY_SERVICE, createBinder(IDevicePolicyManager.class, "android.app.admin.IDevicePolicyManager"))102     map.put(
103         Context.DEVICE_POLICY_SERVICE,
104         createBinder(IDevicePolicyManager.class, "android.app.admin.IDevicePolicyManager"));
map.put( Context.CONNECTIVITY_SERVICE, createBinder(IConnectivityManager.class, "android.net.IConnectivityManager"))105     map.put(
106         Context.CONNECTIVITY_SERVICE,
107         createBinder(IConnectivityManager.class, "android.net.IConnectivityManager"));
map.put( Context.WIFI_SERVICE, createBinder(IWifiManager.class, "android.net.wifi.IWifiManager"))108     map.put(
109         Context.WIFI_SERVICE, createBinder(IWifiManager.class, "android.net.wifi.IWifiManager"));
map.put( Context.SEARCH_SERVICE, createBinder(ISearchManager.class, "android.app.ISearchManager"))110     map.put(
111         Context.SEARCH_SERVICE, createBinder(ISearchManager.class, "android.app.ISearchManager"));
map.put( Context.UI_MODE_SERVICE, createBinder(ISearchManager.class, "android.app.IUiModeManager"))112     map.put(
113         Context.UI_MODE_SERVICE, createBinder(ISearchManager.class, "android.app.IUiModeManager"));
map.put( Context.NETWORK_POLICY_SERVICE, createBinder(ISearchManager.class, "android.net.INetworkPolicyManager"))114     map.put(
115         Context.NETWORK_POLICY_SERVICE,
116         createBinder(ISearchManager.class, "android.net.INetworkPolicyManager"));
map.put(Context.INPUT_SERVICE, createBinder(IInputManager.class, "android.net.IInputManager"))117     map.put(Context.INPUT_SERVICE, createBinder(IInputManager.class, "android.net.IInputManager"));
map.put( Context.COUNTRY_DETECTOR, createBinder(ICountryDetector.class, "android.location.ICountryDetector"))118     map.put(
119         Context.COUNTRY_DETECTOR,
120         createBinder(ICountryDetector.class, "android.location.ICountryDetector"));
map.put( Context.NSD_SERVICE, createBinder(INsdManager.class, "android.net.nsd.INsdManagerandroi"))121     map.put(
122         Context.NSD_SERVICE, createBinder(INsdManager.class, "android.net.nsd.INsdManagerandroi"));
map.put( Context.AUDIO_SERVICE, createBinder(IAudioService.class, "android.media.IAudioService"))123     map.put(
124         Context.AUDIO_SERVICE, createBinder(IAudioService.class, "android.media.IAudioService"));
map.put( Context.APPWIDGET_SERVICE, createBinder(IAppWidgetService.class, "com.android.internal.appwidget.IAppWidgetService"))125     map.put(
126         Context.APPWIDGET_SERVICE,
127         createBinder(IAppWidgetService.class, "com.android.internal.appwidget.IAppWidgetService"));
128 
129     if (RuntimeEnvironment.getApiLevel() >= JELLY_BEAN_MR1) {
map.put(Context.USER_SERVICE, createBinder(IUserManager.class, "android.os.IUserManager"))130       map.put(Context.USER_SERVICE, createBinder(IUserManager.class, "android.os.IUserManager"));
131     }
132     if (RuntimeEnvironment.getApiLevel() >= JELLY_BEAN_MR2) {
map.put( Context.APP_OPS_SERVICE, createBinder(IAppOpsService.class, "com.android.internal.app.IAppOpsService"))133       map.put(
134           Context.APP_OPS_SERVICE,
135           createBinder(IAppOpsService.class, "com.android.internal.app.IAppOpsService"));
136     }
137     if (RuntimeEnvironment.getApiLevel() >= KITKAT) {
138       map.put(
139           "batteryproperties",
140           createBinder(
141               IBatteryPropertiesRegistrar.class, "android.os.IBatteryPropertiesRegistrar"));
142     }
143     if (RuntimeEnvironment.getApiLevel() >= LOLLIPOP) {
map.put( Context.RESTRICTIONS_SERVICE, createBinder(IRestrictionsManager.class, "android.content.IRestrictionsManager"))144       map.put(
145           Context.RESTRICTIONS_SERVICE,
146           createBinder(IRestrictionsManager.class, "android.content.IRestrictionsManager"));
map.put( Context.TRUST_SERVICE, createBinder(ITrustManager.class, "android.app.trust.ITrustManager"))147       map.put(
148           Context.TRUST_SERVICE,
149           createBinder(ITrustManager.class, "android.app.trust.ITrustManager"));
map.put( Context.JOB_SCHEDULER_SERVICE, createBinder(IJobScheduler.class, "android.app.job.IJobScheduler"))150       map.put(
151           Context.JOB_SCHEDULER_SERVICE,
152           createBinder(IJobScheduler.class, "android.app.job.IJobScheduler"));
map.put( Context.NETWORK_SCORE_SERVICE, createBinder(INetworkScoreService.class, "android.net.INetworkScoreService"))153       map.put(
154           Context.NETWORK_SCORE_SERVICE,
155           createBinder(INetworkScoreService.class, "android.net.INetworkScoreService"));
map.put( Context.USAGE_STATS_SERVICE, createBinder(IUsageStatsManager.class, "android.app.usage.IUsageStatsManager"))156       map.put(
157           Context.USAGE_STATS_SERVICE,
158           createBinder(IUsageStatsManager.class, "android.app.usage.IUsageStatsManager"));
map.put( Context.MEDIA_ROUTER_SERVICE, createBinder(IMediaRouterService.class, "android.media.IMediaRouterService"))159       map.put(
160           Context.MEDIA_ROUTER_SERVICE,
161           createBinder(IMediaRouterService.class, "android.media.IMediaRouterService"));
map.put( Context.MEDIA_SESSION_SERVICE, createDeepBinder(ISessionManager.class, "android.media.session.ISessionManager"))162       map.put(
163           Context.MEDIA_SESSION_SERVICE,
164           createDeepBinder(ISessionManager.class, "android.media.session.ISessionManager"));
165     }
166     if (RuntimeEnvironment.getApiLevel() >= M) {
map.put( Context.FINGERPRINT_SERVICE, createBinder( IFingerprintService.class, "android.hardware.fingerprint.IFingerprintService"))167       map.put(
168           Context.FINGERPRINT_SERVICE,
169           createBinder(
170               IFingerprintService.class, "android.hardware.fingerprint.IFingerprintService"));
171     }
172     if (RuntimeEnvironment.getApiLevel() >= N_MR1) {
map.put( Context.SHORTCUT_SERVICE, createBinder(IShortcutService.class, "android.content.pm.IShortcutService"))173       map.put(
174           Context.SHORTCUT_SERVICE,
175           createBinder(IShortcutService.class, "android.content.pm.IShortcutService"));
176     }
177     if (RuntimeEnvironment.getApiLevel() >= O) {
178       map.put("mount", createBinder(IStorageManager.class, "android.os.storage.IStorageManager"));
179     } else {
180       map.put(
181           "mount",
182           createBinder("android.os.storage.IMountService", "android.os.storage.IMountService"));
183     }
184     if (RuntimeEnvironment.getApiLevel() >= P) {
map.put( Context.SLICE_SERVICE, createBinder(ISliceManager.class, "android.app.slice.SliceManager"))185       map.put(
186           Context.SLICE_SERVICE,
187           createBinder(ISliceManager.class, "android.app.slice.SliceManager"));
188     }
189     // BEGIN-INTERNAL
190     if (RuntimeEnvironment.getApiLevel() >= Q) {
map.put(Context.NOTIFICATION_SERVICE, createBinder(INotificationManager.class, "android.app.INotificationManager"))191       map.put(Context.NOTIFICATION_SERVICE,
192           createBinder(INotificationManager.class, "android.app.INotificationManager"));
map.put(Context.COLOR_DISPLAY_SERVICE, createBinder(IColorDisplayManager.class, "android.hardware.display.ColorDisplayManager"))193       map.put(Context.COLOR_DISPLAY_SERVICE, createBinder(IColorDisplayManager.class,
194           "android.hardware.display.ColorDisplayManager"));
map.put(Context.ROLE_SERVICE, createBinder(IRoleManager.class, "android.app.role.IRoleManager"))195       map.put(Context.ROLE_SERVICE,
196               createBinder(IRoleManager.class, "android.app.role.IRoleManager"));
197     }
198     // END-INTERNAL
199     SERVICES = Collections.unmodifiableMap(map);
200   }
201 
202   /**
203    * Returns the binder associated with the given system service. If the given service is set to
204    * unavailable in {@link #setServiceAvailability}, {@code null} will be returned.
205    */
206   @Implementation
getService(String name)207   protected static IBinder getService(String name) {
208     if (unavailableServices.contains(name)) {
209       return null;
210     }
211     return SERVICES.get(name);
212   }
213 
createBinder(String className, String descriptor)214   private static Binder createBinder(String className, String descriptor) {
215     Class<IInterface> clazz;
216     try {
217       clazz = (Class<IInterface>) Class.forName(className);
218     } catch (ClassNotFoundException e) {
219       throw new RuntimeException(e);
220     }
221     Binder binder = new Binder();
222     binder.attachInterface(ReflectionHelpers.createNullProxy(clazz), descriptor);
223     return binder;
224   }
225 
createBinder(Class<? extends IInterface> clazz, String descriptor)226   private static Binder createBinder(Class<? extends IInterface> clazz, String descriptor) {
227     Binder binder = new Binder();
228     binder.attachInterface(ReflectionHelpers.createNullProxy(clazz), descriptor);
229     return binder;
230   }
231 
createDeepBinder(Class<? extends IInterface> clazz, String descriptor)232   private static Binder createDeepBinder(Class<? extends IInterface> clazz, String descriptor) {
233     Binder binder = new Binder();
234     binder.attachInterface(ReflectionHelpers.createDeepProxy(clazz), descriptor);
235     return binder;
236   }
237 
238   @Implementation
addService(String name, IBinder service)239   protected static void addService(String name, IBinder service) {}
240 
241   @Implementation
checkService(String name)242   protected static IBinder checkService(String name) {
243     return null;
244   }
245 
246   @Implementation
listServices()247   protected static String[] listServices() throws RemoteException {
248     return null;
249   }
250 
251   @Implementation
initServiceCache(Map<String, IBinder> cache)252   protected static void initServiceCache(Map<String, IBinder> cache) {}
253 
254   /**
255    * Sets the availability of the given system service. If the service is set as unavailable,
256    * subsequent calls to {@link Context#getSystemService} for that service will return {@code null}.
257    */
setServiceAvailability(String service, boolean available)258   public static void setServiceAvailability(String service, boolean available) {
259     if (available) {
260       unavailableServices.remove(service);
261     } else {
262       unavailableServices.add(service);
263     }
264   }
265 
266   @Resetter
reset()267   public static void reset() {
268     unavailableServices.clear();
269   }
270 }
271