• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static org.robolectric.annotation.LooperMode.Mode.LEGACY;
4 import static org.robolectric.shadows.ShadowLooper.assertLooperMode;
5 
6 import android.app.ActivityThread;
7 import android.app.AlertDialog;
8 import android.app.Application;
9 import android.app.Dialog;
10 import android.appwidget.AppWidgetManager;
11 import android.bluetooth.BluetoothAdapter;
12 import android.content.BroadcastReceiver;
13 import android.content.ComponentName;
14 import android.content.Context;
15 import android.content.ContextWrapper;
16 import android.content.Intent;
17 import android.content.IntentFilter;
18 import android.content.ServiceConnection;
19 import android.os.Handler;
20 import android.os.IBinder;
21 import android.os.PowerManager;
22 import android.widget.ListPopupWindow;
23 import android.widget.PopupWindow;
24 import android.widget.Toast;
25 import com.google.common.collect.ImmutableList;
26 import java.util.ArrayList;
27 import java.util.HashMap;
28 import java.util.List;
29 import java.util.Map;
30 import org.robolectric.RuntimeEnvironment;
31 import org.robolectric.annotation.Implements;
32 import org.robolectric.annotation.RealObject;
33 import org.robolectric.shadow.api.Shadow;
34 import org.robolectric.shadows.ShadowActivityThread._ActivityThread_;
35 import org.robolectric.shadows.ShadowActivityThread._AppBindData_;
36 import org.robolectric.shadows.ShadowUserManager.UserManagerState;
37 import org.robolectric.util.ReflectionHelpers;
38 import org.robolectric.util.Scheduler;
39 import org.robolectric.util.reflector.Reflector;
40 
41 @Implements(Application.class)
42 public class ShadowApplication extends ShadowContextWrapper {
43   @RealObject private Application realApplication;
44 
45   private List<android.widget.Toast> shownToasts = new ArrayList<>();
46   private ShadowPopupMenu latestPopupMenu;
47   private PopupWindow latestPopupWindow;
48   private ListPopupWindow latestListPopupWindow;
49   private UserManagerState userManagerState;
50 
51   /**
52    * @deprecated Use {@code shadowOf({@link ApplicationProvider#getApplicationContext()})} instead.
53    */
54   @Deprecated
getInstance()55   public static ShadowApplication getInstance() {
56     return Shadow.extract(RuntimeEnvironment.getApplication());
57   }
58 
59   /**
60    * Runs any background tasks previously queued by {@link android.os.AsyncTask#execute(Object[])}.
61    *
62    * <p>Note: calling this method does not pause or un-pause the scheduler.
63    */
runBackgroundTasks()64   public static void runBackgroundTasks() {
65     getInstance().getBackgroundThreadScheduler().advanceBy(0);
66   }
67 
68   /** Configures the value to be returned by {@link Application#getProcessName()}. */
setProcessName(String processName)69   public static void setProcessName(String processName) {
70     // No need for a @Resetter because the whole ActivityThread is reset before each test.
71     _ActivityThread_ activityThread =
72         Reflector.reflector(_ActivityThread_.class, ShadowActivityThread.currentActivityThread());
73     Reflector.reflector(_AppBindData_.class, activityThread.getBoundApplication())
74         .setProcessName(processName);
75   }
76 
77   /**
78    * Attaches an application to a base context.
79    *
80    * @param context The context with which to initialize the application, whose base context will be
81    *     attached to the application
82    */
callAttach(Context context)83   public void callAttach(Context context) {
84     ReflectionHelpers.callInstanceMethod(
85         Application.class,
86         realApplication,
87         "attach",
88         ReflectionHelpers.ClassParameter.from(Context.class, context));
89   }
90 
getShownToasts()91   public List<Toast> getShownToasts() {
92     return shownToasts;
93   }
94 
95   /**
96    * Return the foreground scheduler.
97    *
98    * @return Foreground scheduler.
99    * @deprecated use {@link org.robolectric.Robolectric#getForegroundThreadScheduler()}
100    */
101   @Deprecated
getForegroundThreadScheduler()102   public Scheduler getForegroundThreadScheduler() {
103     return RuntimeEnvironment.getMasterScheduler();
104   }
105 
106   /**
107    * Return the background scheduler.
108    *
109    * @return Background scheduler.
110    * @deprecated use {@link org.robolectric.Robolectric#getBackgroundThreadScheduler()}
111    */
112   @Deprecated
getBackgroundThreadScheduler()113   public Scheduler getBackgroundThreadScheduler() {
114     assertLooperMode(LEGACY);
115     return ShadowLegacyLooper.getBackgroundThreadScheduler();
116   }
117 
118   /**
119    * Sets whether or not calls to unbindService should call onServiceDisconnected().
120    *
121    * <p>The default for this is currently {@code true} because that is the historical behavior.
122    * However, this does not correctly mirror Android's actual behavior. This value will eventually
123    * default to {@code false} once users have had a chance to migrate, and eventually the option
124    * will be removed altogether.
125    */
setUnbindServiceCallsOnServiceDisconnected(boolean flag)126   public void setUnbindServiceCallsOnServiceDisconnected(boolean flag) {
127     getShadowInstrumentation().setUnbindServiceCallsOnServiceDisconnected(flag);
128   }
129 
setComponentNameAndServiceForBindService(ComponentName name, IBinder service)130   public void setComponentNameAndServiceForBindService(ComponentName name, IBinder service) {
131     getShadowInstrumentation().setComponentNameAndServiceForBindService(name, service);
132   }
133 
setComponentNameAndServiceForBindServiceForIntent( Intent intent, ComponentName name, IBinder service)134   public void setComponentNameAndServiceForBindServiceForIntent(
135       Intent intent, ComponentName name, IBinder service) {
136     getShadowInstrumentation()
137         .setComponentNameAndServiceForBindServiceForIntent(intent, name, service);
138   }
139 
assertNoBroadcastListenersOfActionRegistered(ContextWrapper context, String action)140   public void assertNoBroadcastListenersOfActionRegistered(ContextWrapper context, String action) {
141     getShadowInstrumentation().assertNoBroadcastListenersOfActionRegistered(context, action);
142   }
143 
getBoundServiceConnections()144   public List<ServiceConnection> getBoundServiceConnections() {
145     return getShadowInstrumentation().getBoundServiceConnections();
146   }
147 
setUnbindServiceShouldThrowIllegalArgument(boolean flag)148   public void setUnbindServiceShouldThrowIllegalArgument(boolean flag) {
149     getShadowInstrumentation().setUnbindServiceShouldThrowIllegalArgument(flag);
150   }
151 
152   /**
153    * Configures the ShadowApplication so that calls to bindService will throw the given
154    * SecurityException.
155    */
setThrowInBindService(SecurityException e)156   public void setThrowInBindService(SecurityException e) {
157     getShadowInstrumentation().setThrowInBindService(e);
158   }
159 
160   /**
161    * Configures the ShadowApplication so that calls to bindService will call
162    * ServiceConnection#onServiceConnected before returning.
163    */
setBindServiceCallsOnServiceConnectedDirectly(boolean callDirectly)164   public void setBindServiceCallsOnServiceConnectedDirectly(boolean callDirectly) {
165     getShadowInstrumentation().setBindServiceCallsOnServiceConnectedDirectly(callDirectly);
166   }
167 
getUnboundServiceConnections()168   public List<ServiceConnection> getUnboundServiceConnections() {
169     return getShadowInstrumentation().getUnboundServiceConnections();
170   }
171 
172   /**
173    * @deprecated use PackageManager.queryBroadcastReceivers instead
174    */
175   @Deprecated
hasReceiverForIntent(Intent intent)176   public boolean hasReceiverForIntent(Intent intent) {
177     return getShadowInstrumentation().hasReceiverForIntent(intent);
178   }
179 
180   /**
181    * @deprecated use PackageManager.queryBroadcastReceivers instead
182    */
183   @Deprecated
getReceiversForIntent(Intent intent)184   public List<BroadcastReceiver> getReceiversForIntent(Intent intent) {
185     return getShadowInstrumentation().getReceiversForIntent(intent);
186   }
187 
188   /**
189    * @return list of {@link Wrapper}s for registered receivers
190    */
getRegisteredReceivers()191   public ImmutableList<Wrapper> getRegisteredReceivers() {
192     return getShadowInstrumentation().getRegisteredReceivers();
193   }
194 
195   /** Clears the list of {@link Wrapper}s for registered receivers */
clearRegisteredReceivers()196   public void clearRegisteredReceivers() {
197     getShadowInstrumentation().clearRegisteredReceivers();
198   }
199 
200   /**
201    * @deprecated Please use {@link Context#getSystemService(Context.APPWIDGET_SERVICE)} intstead.
202    */
203   @Deprecated
getAppWidgetManager()204   public AppWidgetManager getAppWidgetManager() {
205     return (AppWidgetManager) realApplication.getSystemService(Context.APPWIDGET_SERVICE);
206   }
207 
208   /**
209    * @deprecated Use {@link ShadowAlertDialog#getLatestAlertDialog()} instead.
210    */
211   @Deprecated
getLatestAlertDialog()212   public ShadowAlertDialog getLatestAlertDialog() {
213     AlertDialog dialog = ShadowAlertDialog.getLatestAlertDialog();
214     return dialog == null ? null : Shadow.extract(dialog);
215   }
216 
217   /**
218    * @deprecated Use {@link ShadowDialog#getLatestDialog()} instead.
219    */
220   @Deprecated
getLatestDialog()221   public ShadowDialog getLatestDialog() {
222     Dialog dialog = ShadowDialog.getLatestDialog();
223     return dialog == null ? null : Shadow.extract(dialog);
224   }
225 
226   /**
227    * @deprecated Use {@link BluetoothAdapter#getDefaultAdapter()} ()} instead.
228    */
229   @Deprecated
getBluetoothAdapter()230   public final BluetoothAdapter getBluetoothAdapter() {
231     return BluetoothAdapter.getDefaultAdapter();
232   }
233 
declareActionUnbindable(String action)234   public void declareActionUnbindable(String action) {
235     getShadowInstrumentation().declareActionUnbindable(action);
236   }
237 
238   /**
239    * Configures the ShadowApplication so that bindService calls for the given ComponentName return
240    * false and do not call onServiceConnected.
241    */
declareComponentUnbindable(ComponentName component)242   public void declareComponentUnbindable(ComponentName component) {
243     getShadowInstrumentation().declareComponentUnbindable(component);
244   }
245 
246   /**
247    * @deprecated use ShadowPowerManager.getLatestWakeLock
248    */
249   @Deprecated
getLatestWakeLock()250   public PowerManager.WakeLock getLatestWakeLock() {
251     return ShadowPowerManager.getLatestWakeLock();
252   }
253 
254   /**
255    * @deprecated use PowerManager APIs instead
256    */
257   @Deprecated
addWakeLock(PowerManager.WakeLock wl)258   public void addWakeLock(PowerManager.WakeLock wl) {
259     ShadowPowerManager.addWakeLock(wl);
260   }
261 
262   /**
263    * @deprecated use ShadowPowerManager.clearWakeLocks
264    */
265   @Deprecated
clearWakeLocks()266   public void clearWakeLocks() {
267     ShadowPowerManager.clearWakeLocks();
268   }
269 
270   private final Map<String, Object> singletons = new HashMap<>();
271 
getSingleton(Class<T> clazz, Provider<T> provider)272   public <T> T getSingleton(Class<T> clazz, Provider<T> provider) {
273     synchronized (singletons) {
274       //noinspection unchecked
275       T item = (T) singletons.get(clazz.getName());
276       if (item == null) {
277         singletons.put(clazz.getName(), item = provider.get());
278       }
279       return item;
280     }
281   }
282 
283   /**
284    * Set to true if you'd like Robolectric to strictly simulate the real Android behavior when
285    * calling {@link Context#startActivity(android.content.Intent)}. Real Android throws a {@link
286    * android.content.ActivityNotFoundException} if given an {@link Intent} that is not known to the
287    * {@link android.content.pm.PackageManager}
288    *
289    * <p>By default, this behavior is off (false).
290    *
291    * @param checkActivities True to validate activities.
292    */
checkActivities(boolean checkActivities)293   public void checkActivities(boolean checkActivities) {
294     ActivityThread activityThread = (ActivityThread) RuntimeEnvironment.getActivityThread();
295     ShadowInstrumentation shadowInstrumentation =
296         Shadow.extract(activityThread.getInstrumentation());
297     shadowInstrumentation.checkActivities(checkActivities);
298   }
299 
300   /**
301    * @deprecated Use {@link ShadowPopupMenu#getLatestPopupMenu()} instead.
302    */
303   @Deprecated
getLatestPopupMenu()304   public ShadowPopupMenu getLatestPopupMenu() {
305     return latestPopupMenu;
306   }
307 
setLatestPopupMenu(ShadowPopupMenu latestPopupMenu)308   protected void setLatestPopupMenu(ShadowPopupMenu latestPopupMenu) {
309     this.latestPopupMenu = latestPopupMenu;
310   }
311 
getLatestPopupWindow()312   public PopupWindow getLatestPopupWindow() {
313     return latestPopupWindow;
314   }
315 
setLatestPopupWindow(PopupWindow latestPopupWindow)316   protected void setLatestPopupWindow(PopupWindow latestPopupWindow) {
317     this.latestPopupWindow = latestPopupWindow;
318   }
319 
getLatestListPopupWindow()320   public ListPopupWindow getLatestListPopupWindow() {
321     return latestListPopupWindow;
322   }
323 
setLatestListPopupWindow(ListPopupWindow latestListPopupWindow)324   protected void setLatestListPopupWindow(ListPopupWindow latestListPopupWindow) {
325     this.latestListPopupWindow = latestListPopupWindow;
326   }
327 
getUserManagerState()328   UserManagerState getUserManagerState() {
329     if (userManagerState == null) {
330       userManagerState = new UserManagerState();
331     }
332 
333     return userManagerState;
334   }
335 
336   public static final class Wrapper {
337     public BroadcastReceiver broadcastReceiver;
338     public IntentFilter intentFilter;
339     public Context context;
340     public Throwable exception;
341     public String broadcastPermission;
342     public Handler scheduler;
343     public int flags;
344 
Wrapper( BroadcastReceiver broadcastReceiver, IntentFilter intentFilter, Context context, String broadcastPermission, Handler scheduler, int flags)345     public Wrapper(
346         BroadcastReceiver broadcastReceiver,
347         IntentFilter intentFilter,
348         Context context,
349         String broadcastPermission,
350         Handler scheduler,
351         int flags) {
352       this.broadcastReceiver = broadcastReceiver;
353       this.intentFilter = intentFilter;
354       this.context = context;
355       this.broadcastPermission = broadcastPermission;
356       this.scheduler = scheduler;
357       this.flags = flags;
358       exception = new Throwable();
359     }
360 
getBroadcastReceiver()361     public BroadcastReceiver getBroadcastReceiver() {
362       return broadcastReceiver;
363     }
364 
getIntentFilter()365     public IntentFilter getIntentFilter() {
366       return intentFilter;
367     }
368 
getContext()369     public Context getContext() {
370       return context;
371     }
372 
373     @Override
toString()374     public String toString() {
375       return "Wrapper[receiver=["
376           + broadcastReceiver
377           + "], context=["
378           + context
379           + "], intentFilter=["
380           + intentFilter
381           + "]]";
382     }
383   }
384 
385   /**
386    * @deprecated Do not depend on this method to override services as it will be removed in a future
387    *     update. The preferered method is use the shadow of the corresponding service.
388    */
389   @Deprecated
setSystemService(String key, Object service)390   public void setSystemService(String key, Object service) {
391     ShadowContextImpl shadowContext = Shadow.extract(realApplication.getBaseContext());
392     shadowContext.setSystemService(key, service);
393   }
394 }
395