1package com.xtremelabs.robolectric.shadows;
2
3import android.content.BroadcastReceiver;
4import android.content.ComponentName;
5import android.content.ContentResolver;
6import android.content.Context;
7import android.content.ContextWrapper;
8import android.content.Intent;
9import android.content.IntentFilter;
10import android.content.ServiceConnection;
11import android.content.SharedPreferences;
12import android.content.pm.ApplicationInfo;
13import android.content.pm.PackageManager;
14import android.content.res.AssetManager;
15import android.content.res.Resources;
16import android.os.Looper;
17import com.xtremelabs.robolectric.internal.Implementation;
18import com.xtremelabs.robolectric.internal.Implements;
19import com.xtremelabs.robolectric.internal.RealObject;
20import com.xtremelabs.robolectric.tester.android.content.TestSharedPreferences;
21
22import java.util.HashSet;
23import java.util.List;
24import java.util.Set;
25
26import static android.content.pm.PackageManager.PERMISSION_DENIED;
27import static android.content.pm.PackageManager.PERMISSION_GRANTED;
28import static com.xtremelabs.robolectric.Robolectric.shadowOf;
29
30@SuppressWarnings({"UnusedDeclaration"})
31@Implements(ContextWrapper.class)
32public class ShadowContextWrapper extends ShadowContext {
33    @RealObject private ContextWrapper realContextWrapper;
34    protected Context baseContext;
35
36    private PackageManager packageManager;
37
38    private String appName;
39    private String packageName;
40    private Set<String> grantedPermissions = new HashSet<String>();
41
42    public void __constructor__(Context baseContext) {
43        this.baseContext = baseContext;
44    }
45
46    @Implementation
47    public Context getApplicationContext() {
48        return baseContext.getApplicationContext();
49    }
50
51    @Implementation
52    public Resources.Theme getTheme() {
53        return getResources().newTheme();
54    }
55
56    @Implementation
57    public Resources getResources() {
58        return getApplicationContext().getResources();
59    }
60
61    @Implementation
62    public ContentResolver getContentResolver() {
63        return getApplicationContext().getContentResolver();
64    }
65
66    @Implementation
67    public Object getSystemService(String name) {
68        return getApplicationContext().getSystemService(name);
69    }
70
71    @Implementation
72    public void sendBroadcast(Intent intent) {
73        getApplicationContext().sendBroadcast(intent);
74    }
75
76    public List<Intent> getBroadcastIntents() {
77        return ((ShadowApplication) shadowOf(getApplicationContext())).getBroadcastIntents();
78    }
79
80    @Implementation
81    public int checkPermission(java.lang.String permission, int pid, int uid) {
82        return grantedPermissions.contains(permission) ? PERMISSION_GRANTED : PERMISSION_DENIED;
83    }
84
85    @Implementation
86    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
87        return ((ShadowApplication) shadowOf(getApplicationContext())).registerReceiverWithContext(receiver, filter, realContextWrapper);
88    }
89
90    @Implementation
91    public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
92        getApplicationContext().unregisterReceiver(broadcastReceiver);
93    }
94
95    @Implementation
96    public String getPackageName() {
97        return realContextWrapper == getApplicationContext() ? packageName : getApplicationContext().getPackageName();
98    }
99
100    @Implementation
101    public ApplicationInfo getApplicationInfo() {
102        ApplicationInfo appInfo = new ApplicationInfo();
103        appInfo.name = appName;
104        appInfo.packageName = packageName;
105        appInfo.processName = packageName;
106        return appInfo;
107    }
108
109    /**
110     * Non-Android accessor to set the application name.
111     *
112     * @param name
113     */
114    public void setApplicationName(String name) {
115        appName = name;
116    }
117
118    /**
119     * Implements Android's {@code PackageManager}.
120     *
121     * @return a {@code RobolectricPackageManager}
122     */
123    @Implementation
124    public PackageManager getPackageManager() {
125        return realContextWrapper == getApplicationContext() ? packageManager : getApplicationContext().getPackageManager();
126    }
127
128    @Implementation
129    public ComponentName startService(Intent service) {
130        return getApplicationContext().startService(service);
131    }
132
133    @Implementation
134    public boolean stopService(Intent name) {
135        return getApplicationContext().stopService(name);
136    }
137
138    @Implementation
139    public void startActivity(Intent intent) {
140        getApplicationContext().startActivity(intent);
141    }
142
143    @Implementation
144    public SharedPreferences getSharedPreferences(String name, int mode) {
145        return new TestSharedPreferences(getShadowApplication().getSharedPreferenceMap(), name, mode);
146    }
147
148    @Implementation
149    public AssetManager getAssets() {
150        return getResources().getAssets();
151    }
152
153    /**
154     * Non-Android accessor that delegates to the application to consume and return the next {@code Intent} on the
155     * started activities stack.
156     *
157     * @return the next started {@code Intent} for an activity
158     */
159    public Intent getNextStartedActivity() {
160        return getShadowApplication().getNextStartedActivity();
161    }
162
163    /**
164     * Non-Android accessor that delegates to the application to return (without consuming) the next {@code Intent} on
165     * the started activities stack.
166     *
167     * @return the next started {@code Intent} for an activity
168     */
169    public Intent peekNextStartedActivity() {
170        return getShadowApplication().peekNextStartedActivity();
171    }
172
173    /**
174     * Non-Android accessor that delegates to the application to consume and return the next {@code Intent} on the
175     * started services stack.
176     *
177     * @return the next started {@code Intent} for a service
178     */
179    public Intent getNextStartedService() {
180        return getShadowApplication().getNextStartedService();
181    }
182
183    /**
184     * Non-android accessor that delefates to the application to clear the stack of started
185     * service intents.
186     */
187    public void clearStartedServices() {
188        getShadowApplication().clearStartedServices();
189    }
190
191    /**
192     * Return (without consuming) the next {@code Intent} on the started services stack.
193     *
194     * @return the next started {@code Intent} for a service
195     */
196    public Intent peekNextStartedService() {
197        return getShadowApplication().peekNextStartedService();
198    }
199
200    /**
201     * Non-Android accessor that delegates to the application to return the next {@code Intent} to stop
202     * a service (irrespective of if the service was running)
203     *
204     * @return {@code Intent} for the next service requested to be stopped
205     */
206    public Intent getNextStoppedService() {
207        return getShadowApplication().getNextStoppedService();
208    }
209
210    /**
211     * Non-Android accessor that is used at start-up to set the package name
212     *
213     * @param packageName the package name
214     */
215    public void setPackageName(String packageName) {
216        this.packageName = packageName;
217    }
218
219    /**
220     * Non-Android accessor that is used at start-up to set the packageManager =
221     *
222     * @param packageManager the package manager
223     */
224    public void setPackageManager(PackageManager packageManager) {
225        this.packageManager = packageManager;
226    }
227
228
229    @Implementation
230    public Looper getMainLooper() {
231        return getShadowApplication().getMainLooper();
232    }
233
234    @Implementation
235    public Context getBaseContext() {
236        return baseContext;
237    }
238
239    @Implementation
240    public void attachBaseContext(Context context) {
241        baseContext = context;
242    }
243
244    private ShadowApplication getShadowApplication() {
245        return ((ShadowApplication) shadowOf(getApplicationContext()));
246    }
247
248    @Implementation
249    public boolean bindService(Intent intent, final ServiceConnection serviceConnection, int i) {
250        return getShadowApplication().bindService(intent, serviceConnection, i);
251    }
252
253    /**
254     * Non-Android accessor that is used to grant permissions checked via
255     * {@link android.content.ContextWrapper#checkPermission(String, int, int)}
256     *
257     * @param permissionNames permission names that should be granted
258     */
259    public void grantPermissions(String... permissionNames) {
260        for (String permissionName : permissionNames) {
261            grantedPermissions.add(permissionName);
262        }
263    }
264}
265