blob: 138a88fc857b9ddb50b12c2bb76fca8ef41f4ccf [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.BroadcastReceiver;
22import android.content.ComponentName;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.IContentProvider;
27import android.content.Intent;
28import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070029import android.content.IIntentReceiver;
30import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ReceiverCallNotAllowedException;
32import android.content.ServiceConnection;
33import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.pm.PackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.res.AssetManager;
Dianne Hackborn5be8de32011-05-24 18:11:57 -070038import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070040import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.database.sqlite.SQLiteDatabase;
42import android.database.sqlite.SQLiteDatabase.CursorFactory;
43import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.graphics.drawable.Drawable;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040045import android.hardware.ISerialManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.hardware.SensorManager;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040047import android.hardware.SerialManager;
Jeff Brownac143512012-04-05 18:57:33 -070048import android.hardware.input.IInputManager;
Jeff Brown9df6e7a2012-04-05 11:49:26 -070049import android.hardware.input.InputManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080050import android.hardware.usb.IUsbManager;
51import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080052import android.location.CountryDetector;
53import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.location.ILocationManager;
55import android.location.LocationManager;
56import android.media.AudioManager;
57import android.net.ConnectivityManager;
58import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070059import android.net.INetworkPolicyManager;
60import android.net.NetworkPolicyManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070061import android.net.ThrottleManager;
62import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.net.Uri;
Irfan Sheriff7d024d32012-03-22 17:01:39 -070064import android.net.nsd.INsdManager;
65import android.net.nsd.NsdManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.net.wifi.IWifiManager;
67import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070068import android.net.wifi.p2p.IWifiP2pManager;
69import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080070import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.Binder;
72import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080073import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080074import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.os.FileUtils;
76import android.os.Handler;
77import android.os.IBinder;
78import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070079import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.os.PowerManager;
81import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070082import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.ServiceManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070084import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080086import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070088import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.util.AndroidRuntimeException;
90import android.util.Log;
91import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070093import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090095import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070096import android.accounts.AccountManager;
97import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080098import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080099import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import java.io.File;
102import java.io.FileInputStream;
103import java.io.FileNotFoundException;
104import java.io.FileOutputStream;
105import java.io.IOException;
106import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import java.util.ArrayList;
108import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110class ReceiverRestrictedContext extends ContextWrapper {
111 ReceiverRestrictedContext(Context base) {
112 super(base);
113 }
114
115 @Override
116 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
117 return registerReceiver(receiver, filter, null, null);
118 }
119
120 @Override
121 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
122 String broadcastPermission, Handler scheduler) {
123 throw new ReceiverCallNotAllowedException(
124 "IntentReceiver components are not allowed to register to receive intents");
125 //ex.fillInStackTrace();
126 //Log.e("IntentReceiver", ex.getMessage(), ex);
127 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
128 // scheduler);
129 }
130
131 @Override
132 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
133 throw new ReceiverCallNotAllowedException(
134 "IntentReceiver components are not allowed to bind to services");
135 //ex.fillInStackTrace();
136 //Log.e("IntentReceiver", ex.getMessage(), ex);
137 //return mContext.bindService(service, interfaceName, conn, flags);
138 }
139}
140
141/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800142 * Common implementation of Context API, which provides the base
143 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800145class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700147 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700149 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
150 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700152 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700153 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 private Resources mResources;
155 /*package*/ ActivityThread mMainThread;
156 private Context mOuterContext;
157 private IBinder mActivityToken = null;
158 private ApplicationContentResolver mContentResolver;
159 private int mThemeResource = 0;
160 private Resources.Theme mTheme = null;
161 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700163 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
165 private final Object mSync = new Object();
166
167 private File mDatabasesDir;
168 private File mPreferencesDir;
169 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800171 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800172 private File mExternalFilesDir;
173 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175 private static final String[] EMPTY_FILE_LIST = {};
176
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800177 /**
178 * Override this class when the system service constructor needs a
179 * ContextImpl. Else, use StaticServiceFetcher below.
180 */
181 /*package*/ static class ServiceFetcher {
182 int mContextCacheIndex = -1;
183
184 /**
185 * Main entrypoint; only override if you don't need caching.
186 */
187 public Object getService(ContextImpl ctx) {
188 ArrayList<Object> cache = ctx.mServiceCache;
189 Object service;
190 synchronized (cache) {
191 if (cache.size() == 0) {
192 // Initialize the cache vector on first access.
193 // At this point sNextPerContextServiceCacheIndex
194 // is the number of potential services that are
195 // cached per-Context.
196 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
197 cache.add(null);
198 }
199 } else {
200 service = cache.get(mContextCacheIndex);
201 if (service != null) {
202 return service;
203 }
204 }
205 service = createService(ctx);
206 cache.set(mContextCacheIndex, service);
207 return service;
208 }
209 }
210
211 /**
212 * Override this to create a new per-Context instance of the
213 * service. getService() will handle locking and caching.
214 */
215 public Object createService(ContextImpl ctx) {
216 throw new RuntimeException("Not implemented");
217 }
218 }
219
220 /**
221 * Override this class for services to be cached process-wide.
222 */
223 abstract static class StaticServiceFetcher extends ServiceFetcher {
224 private Object mCachedInstance;
225
226 @Override
227 public final Object getService(ContextImpl unused) {
228 synchronized (StaticServiceFetcher.this) {
229 Object service = mCachedInstance;
230 if (service != null) {
231 return service;
232 }
233 return mCachedInstance = createStaticService();
234 }
235 }
236
237 public abstract Object createStaticService();
238 }
239
240 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
241 new HashMap<String, ServiceFetcher>();
242
243 private static int sNextPerContextServiceCacheIndex = 0;
244 private static void registerService(String serviceName, ServiceFetcher fetcher) {
245 if (!(fetcher instanceof StaticServiceFetcher)) {
246 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
247 }
248 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
249 }
250
251 // This one's defined separately and given a variable name so it
252 // can be re-used by getWallpaperManager(), avoiding a HashMap
253 // lookup.
254 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
255 public Object createService(ContextImpl ctx) {
256 return new WallpaperManager(ctx.getOuterContext(),
257 ctx.mMainThread.getHandler());
258 }};
259
260 static {
261 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
262 public Object getService(ContextImpl ctx) {
263 return AccessibilityManager.getInstance(ctx);
264 }});
265
266 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
267 public Object createService(ContextImpl ctx) {
268 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
269 IAccountManager service = IAccountManager.Stub.asInterface(b);
270 return new AccountManager(ctx, service);
271 }});
272
273 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
274 public Object createService(ContextImpl ctx) {
275 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
276 }});
277
278 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
279 public Object createStaticService() {
280 IBinder b = ServiceManager.getService(ALARM_SERVICE);
281 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
282 return new AlarmManager(service);
283 }});
284
285 registerService(AUDIO_SERVICE, new ServiceFetcher() {
286 public Object createService(ContextImpl ctx) {
287 return new AudioManager(ctx);
288 }});
289
290 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
291 public Object createService(ContextImpl ctx) {
292 return new ClipboardManager(ctx.getOuterContext(),
293 ctx.mMainThread.getHandler());
294 }});
295
296 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
297 public Object createStaticService() {
298 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
299 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
300 }});
301
302 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
303 public Object createStaticService() {
304 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
305 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
306 }});
307
308 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
309 public Object createService(ContextImpl ctx) {
310 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
311 }});
312
313 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
314 public Object createService(ContextImpl ctx) {
315 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
316 }});
317
Nick Pellyd2507462010-12-13 12:22:34 -0800318 registerService(NFC_SERVICE, new ServiceFetcher() {
319 public Object createService(ContextImpl ctx) {
320 return new NfcManager(ctx);
321 }});
322
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800323 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
324 public Object createStaticService() {
325 return createDropBoxManager();
326 }});
327
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700328 registerService(INPUT_SERVICE, new StaticServiceFetcher() {
329 public Object createStaticService() {
330 return InputManager.getInstance();
Jeff Brownac143512012-04-05 18:57:33 -0700331 }});
Jeff Brown9df6e7a2012-04-05 11:49:26 -0700332
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800333 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
334 public Object createService(ContextImpl ctx) {
335 return InputMethodManager.getInstance(ctx);
336 }});
337
satok988323c2011-06-22 16:38:13 +0900338 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
339 public Object createService(ContextImpl ctx) {
340 return TextServicesManager.getInstance();
341 }});
342
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800343 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
344 public Object getService(ContextImpl ctx) {
345 // TODO: why isn't this caching it? It wasn't
346 // before, so I'm preserving the old behavior and
347 // using getService(), instead of createService()
348 // which would do the caching.
349 return new KeyguardManager();
350 }});
351
352 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
353 public Object createService(ContextImpl ctx) {
354 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
355 }});
356
357 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
358 public Object createStaticService() {
359 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
360 return new LocationManager(ILocationManager.Stub.asInterface(b));
361 }});
362
Jeff Sharkey1a303952011-06-16 13:04:20 -0700363 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
364 @Override
365 public Object createService(ContextImpl ctx) {
366 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
367 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
368 }
369 });
370
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800371 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
372 public Object createService(ContextImpl ctx) {
373 final Context outerContext = ctx.getOuterContext();
374 return new NotificationManager(
375 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800376 Resources.selectSystemTheme(0,
377 outerContext.getApplicationInfo().targetSdkVersion,
378 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700379 com.android.internal.R.style.Theme_Holo_Dialog,
380 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800381 ctx.mMainThread.getHandler());
382 }});
383
Irfan Sheriff7d024d32012-03-22 17:01:39 -0700384 registerService(NSD_SERVICE, new ServiceFetcher() {
385 @Override
386 public Object createService(ContextImpl ctx) {
387 IBinder b = ServiceManager.getService(NSD_SERVICE);
388 INsdManager service = INsdManager.Stub.asInterface(b);
389 return new NsdManager(service);
390 }});
391
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800392 // Note: this was previously cached in a static variable, but
393 // constructed using mMainThread.getHandler(), so converting
394 // it to be a regular Context-cached service...
395 registerService(POWER_SERVICE, new ServiceFetcher() {
396 public Object createService(ContextImpl ctx) {
397 IBinder b = ServiceManager.getService(POWER_SERVICE);
398 IPowerManager service = IPowerManager.Stub.asInterface(b);
399 return new PowerManager(service, ctx.mMainThread.getHandler());
400 }});
401
402 registerService(SEARCH_SERVICE, new ServiceFetcher() {
403 public Object createService(ContextImpl ctx) {
404 return new SearchManager(ctx.getOuterContext(),
405 ctx.mMainThread.getHandler());
406 }});
407
408 registerService(SENSOR_SERVICE, new ServiceFetcher() {
409 public Object createService(ContextImpl ctx) {
410 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
411 }});
412
413 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
414 public Object createService(ContextImpl ctx) {
415 return new StatusBarManager(ctx.getOuterContext());
416 }});
417
418 registerService(STORAGE_SERVICE, new ServiceFetcher() {
419 public Object createService(ContextImpl ctx) {
420 try {
421 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
422 } catch (RemoteException rex) {
423 Log.e(TAG, "Failed to create StorageManager", rex);
424 return null;
425 }
426 }});
427
428 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
429 public Object createService(ContextImpl ctx) {
430 return new TelephonyManager(ctx.getOuterContext());
431 }});
432
433 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
434 public Object createStaticService() {
435 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
436 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
437 }});
438
439 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
440 public Object createService(ContextImpl ctx) {
441 return new UiModeManager();
442 }});
443
Mike Lockwood3a68b832011-03-08 10:08:59 -0500444 registerService(USB_SERVICE, new ServiceFetcher() {
445 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500446 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500447 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500448 }});
449
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -0400450 registerService(SERIAL_SERVICE, new ServiceFetcher() {
451 public Object createService(ContextImpl ctx) {
452 IBinder b = ServiceManager.getService(SERIAL_SERVICE);
453 return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
454 }});
455
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800456 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
457 public Object createService(ContextImpl ctx) {
458 return new Vibrator();
459 }});
460
461 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
462
463 registerService(WIFI_SERVICE, new ServiceFetcher() {
464 public Object createService(ContextImpl ctx) {
465 IBinder b = ServiceManager.getService(WIFI_SERVICE);
466 IWifiManager service = IWifiManager.Stub.asInterface(b);
467 return new WifiManager(service, ctx.mMainThread.getHandler());
468 }});
469
repo sync55bc5f32011-06-24 14:23:07 -0700470 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
471 public Object createService(ContextImpl ctx) {
472 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
473 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
474 return new WifiP2pManager(service);
475 }});
476
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800477 registerService(WINDOW_SERVICE, new ServiceFetcher() {
478 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700479 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800480 }});
481 }
482
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700483 static ContextImpl getImpl(Context context) {
484 Context nextContext;
485 while ((context instanceof ContextWrapper) &&
486 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
487 context = nextContext;
488 }
489 return (ContextImpl)context;
490 }
491
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800492 // The system service cache for the system services that are
493 // cached per-ContextImpl. Package-scoped to avoid accessor
494 // methods.
495 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 @Override
498 public AssetManager getAssets() {
499 return mResources.getAssets();
500 }
501
502 @Override
503 public Resources getResources() {
504 return mResources;
505 }
506
507 @Override
508 public PackageManager getPackageManager() {
509 if (mPackageManager != null) {
510 return mPackageManager;
511 }
512
513 IPackageManager pm = ActivityThread.getPackageManager();
514 if (pm != null) {
515 // Doesn't matter if we make more than one instance.
516 return (mPackageManager = new ApplicationPackageManager(this, pm));
517 }
518
519 return null;
520 }
521
522 @Override
523 public ContentResolver getContentResolver() {
524 return mContentResolver;
525 }
526
527 @Override
528 public Looper getMainLooper() {
529 return mMainThread.getLooper();
530 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 @Override
533 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700534 return (mPackageInfo != null) ?
535 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 @Override
539 public void setTheme(int resid) {
540 mThemeResource = resid;
541 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800543 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800544 public int getThemeResId() {
545 return mThemeResource;
546 }
547
548 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 public Resources.Theme getTheme() {
550 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800551 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
552 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 mTheme = mResources.newTheme();
554 mTheme.applyStyle(mThemeResource, true);
555 }
556 return mTheme;
557 }
558
559 @Override
560 public ClassLoader getClassLoader() {
561 return mPackageInfo != null ?
562 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
563 }
564
565 @Override
566 public String getPackageName() {
567 if (mPackageInfo != null) {
568 return mPackageInfo.getPackageName();
569 }
570 throw new RuntimeException("Not supported in system context");
571 }
572
573 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700574 public ApplicationInfo getApplicationInfo() {
575 if (mPackageInfo != null) {
576 return mPackageInfo.getApplicationInfo();
577 }
578 throw new RuntimeException("Not supported in system context");
579 }
580
581 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 public String getPackageResourcePath() {
583 if (mPackageInfo != null) {
584 return mPackageInfo.getResDir();
585 }
586 throw new RuntimeException("Not supported in system context");
587 }
588
589 @Override
590 public String getPackageCodePath() {
591 if (mPackageInfo != null) {
592 return mPackageInfo.getAppDir();
593 }
594 throw new RuntimeException("Not supported in system context");
595 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200596
Joe Onorato23ecae32009-06-10 17:07:15 -0700597 public File getSharedPrefsFile(String name) {
598 return makeFilename(getPreferencesDir(), name + ".xml");
599 }
600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 @Override
602 public SharedPreferences getSharedPreferences(String name, int mode) {
603 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700605 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700606 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800607 File prefsFile = getSharedPrefsFile(name);
608 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700609 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700610 return sp;
611 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800613 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
614 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
615 // If somebody else (some other process) changed the prefs
616 // file behind our back, we reload it. This has been the
617 // historical (if undocumented) behavior.
618 sp.startReloadIfChangedUnexpectedly();
619 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700620 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 }
622
623 private File getPreferencesDir() {
624 synchronized (mSync) {
625 if (mPreferencesDir == null) {
626 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
627 }
628 return mPreferencesDir;
629 }
630 }
631
632 @Override
633 public FileInputStream openFileInput(String name)
634 throws FileNotFoundException {
635 File f = makeFilename(getFilesDir(), name);
636 return new FileInputStream(f);
637 }
638
639 @Override
640 public FileOutputStream openFileOutput(String name, int mode)
641 throws FileNotFoundException {
642 final boolean append = (mode&MODE_APPEND) != 0;
643 File f = makeFilename(getFilesDir(), name);
644 try {
645 FileOutputStream fos = new FileOutputStream(f, append);
646 setFilePermissionsFromMode(f.getPath(), mode, 0);
647 return fos;
648 } catch (FileNotFoundException e) {
649 }
650
651 File parent = f.getParentFile();
652 parent.mkdir();
653 FileUtils.setPermissions(
654 parent.getPath(),
655 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
656 -1, -1);
657 FileOutputStream fos = new FileOutputStream(f, append);
658 setFilePermissionsFromMode(f.getPath(), mode, 0);
659 return fos;
660 }
661
662 @Override
663 public boolean deleteFile(String name) {
664 File f = makeFilename(getFilesDir(), name);
665 return f.delete();
666 }
667
668 @Override
669 public File getFilesDir() {
670 synchronized (mSync) {
671 if (mFilesDir == null) {
672 mFilesDir = new File(getDataDirFile(), "files");
673 }
674 if (!mFilesDir.exists()) {
675 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200676 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 return null;
678 }
679 FileUtils.setPermissions(
680 mFilesDir.getPath(),
681 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
682 -1, -1);
683 }
684 return mFilesDir;
685 }
686 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200687
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800688 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800689 public File getExternalFilesDir(String type) {
690 synchronized (mSync) {
691 if (mExternalFilesDir == null) {
692 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
693 getPackageName());
694 }
695 if (!mExternalFilesDir.exists()) {
696 try {
697 (new File(Environment.getExternalStorageAndroidDataDir(),
698 ".nomedia")).createNewFile();
699 } catch (IOException e) {
700 }
701 if (!mExternalFilesDir.mkdirs()) {
702 Log.w(TAG, "Unable to create external files directory");
703 return null;
704 }
705 }
706 if (type == null) {
707 return mExternalFilesDir;
708 }
709 File dir = new File(mExternalFilesDir, type);
710 if (!dir.exists()) {
711 if (!dir.mkdirs()) {
712 Log.w(TAG, "Unable to create external media directory " + dir);
713 return null;
714 }
715 }
716 return dir;
717 }
718 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200719
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800720 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800721 public File getObbDir() {
722 synchronized (mSync) {
723 if (mObbDir == null) {
724 mObbDir = Environment.getExternalStorageAppObbDirectory(
725 getPackageName());
726 }
727 return mObbDir;
728 }
729 }
730
731 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 public File getCacheDir() {
733 synchronized (mSync) {
734 if (mCacheDir == null) {
735 mCacheDir = new File(getDataDirFile(), "cache");
736 }
737 if (!mCacheDir.exists()) {
738 if(!mCacheDir.mkdirs()) {
739 Log.w(TAG, "Unable to create cache directory");
740 return null;
741 }
742 FileUtils.setPermissions(
743 mCacheDir.getPath(),
744 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
745 -1, -1);
746 }
747 }
748 return mCacheDir;
749 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200750
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800751 @Override
752 public File getExternalCacheDir() {
753 synchronized (mSync) {
754 if (mExternalCacheDir == null) {
755 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
756 getPackageName());
757 }
758 if (!mExternalCacheDir.exists()) {
759 try {
760 (new File(Environment.getExternalStorageAndroidDataDir(),
761 ".nomedia")).createNewFile();
762 } catch (IOException e) {
763 }
764 if (!mExternalCacheDir.mkdirs()) {
765 Log.w(TAG, "Unable to create external cache directory");
766 return null;
767 }
768 }
769 return mExternalCacheDir;
770 }
771 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 @Override
774 public File getFileStreamPath(String name) {
775 return makeFilename(getFilesDir(), name);
776 }
777
778 @Override
779 public String[] fileList() {
780 final String[] list = getFilesDir().list();
781 return (list != null) ? list : EMPTY_FILE_LIST;
782 }
783
784 @Override
785 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Jeff Brown47847f32012-03-22 19:13:11 -0700786 return openOrCreateDatabase(name, mode, factory, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788
789 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700790 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
791 DatabaseErrorHandler errorHandler) {
792 File f = validateFilePath(name, true);
Jeff Brown47847f32012-03-22 19:13:11 -0700793 int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
794 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
795 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
796 }
797 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
Vasu Nori74f170f2010-06-01 18:06:18 -0700798 setFilePermissionsFromMode(f.getPath(), mode, 0);
799 return db;
800 }
801
802 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800803 public boolean deleteDatabase(String name) {
804 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800805 File f = validateFilePath(name, false);
Jeff Brown79087e42012-03-01 19:52:44 -0800806 return SQLiteDatabase.deleteDatabase(f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 } catch (Exception e) {
808 }
809 return false;
810 }
811
812 @Override
813 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800814 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 }
816
817 @Override
818 public String[] databaseList() {
819 final String[] list = getDatabasesDir().list();
820 return (list != null) ? list : EMPTY_FILE_LIST;
821 }
822
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 private File getDatabasesDir() {
825 synchronized (mSync) {
826 if (mDatabasesDir == null) {
827 mDatabasesDir = new File(getDataDirFile(), "databases");
828 }
829 if (mDatabasesDir.getPath().equals("databases")) {
830 mDatabasesDir = new File("/data/system");
831 }
832 return mDatabasesDir;
833 }
834 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200835
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 @Override
837 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700838 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 }
840
841 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700842 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700843 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 }
845
846 @Override
847 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700848 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 }
850
851 @Override
852 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700853 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 }
855
856 @Override
857 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700858 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 }
860
861 @Override
862 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700863 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 }
865
866 @Override
867 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700868 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869 }
870
871 @Override
872 public void startActivity(Intent intent) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700873 startActivity(intent, null);
874 }
875
876 @Override
877 public void startActivity(Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
879 throw new AndroidRuntimeException(
880 "Calling startActivity() from outside of an Activity "
881 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
882 + " Is this really what you want?");
883 }
884 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700885 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700886 (Activity)null, intent, -1, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 }
888
889 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800890 public void startActivities(Intent[] intents) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700891 startActivities(intents, null);
892 }
893
894 @Override
895 public void startActivities(Intent[] intents, Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800896 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
897 throw new AndroidRuntimeException(
898 "Calling startActivities() from outside of an Activity "
899 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
900 + " Is this really what you want?");
901 }
902 mMainThread.getInstrumentation().execStartActivities(
903 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700904 (Activity)null, intents, options);
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800905 }
906
907 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700908 public void startIntentSender(IntentSender intent,
909 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
910 throws IntentSender.SendIntentException {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700911 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
912 }
913
914 @Override
915 public void startIntentSender(IntentSender intent, Intent fillInIntent,
916 int flagsMask, int flagsValues, int extraFlags, Bundle options)
917 throws IntentSender.SendIntentException {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700918 try {
919 String resolvedType = null;
920 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400921 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700922 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
923 }
924 int result = ActivityManagerNative.getDefault()
925 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
926 fillInIntent, resolvedType, null, null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700927 0, flagsMask, flagsValues, options);
928 if (result == ActivityManager.START_CANCELED) {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700929 throw new IntentSender.SendIntentException();
930 }
931 Instrumentation.checkStartActivityResult(result, null);
932 } catch (RemoteException e) {
933 }
934 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200935
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700936 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 public void sendBroadcast(Intent intent) {
938 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
939 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400940 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 ActivityManagerNative.getDefault().broadcastIntent(
942 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700943 Activity.RESULT_OK, null, null, null, false, false,
944 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 } catch (RemoteException e) {
946 }
947 }
948
Amith Yamasani67cf7d32012-02-16 14:31:23 -0800949 /** @hide */
950 @Override
951 public void sendBroadcast(Intent intent, int userId) {
952 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
953 try {
954 intent.setAllowFds(false);
955 ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
956 intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
957 userId);
958 } catch (RemoteException e) {
959 }
960 }
961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 @Override
963 public void sendBroadcast(Intent intent, String receiverPermission) {
964 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
965 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400966 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 ActivityManagerNative.getDefault().broadcastIntent(
968 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700969 Activity.RESULT_OK, null, null, receiverPermission, false, false,
970 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 } catch (RemoteException e) {
972 }
973 }
974
975 @Override
976 public void sendOrderedBroadcast(Intent intent,
977 String receiverPermission) {
978 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
979 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400980 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800981 ActivityManagerNative.getDefault().broadcastIntent(
982 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700983 Activity.RESULT_OK, null, null, receiverPermission, true, false,
984 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 } catch (RemoteException e) {
986 }
987 }
988
989 @Override
990 public void sendOrderedBroadcast(Intent intent,
991 String receiverPermission, BroadcastReceiver resultReceiver,
992 Handler scheduler, int initialCode, String initialData,
993 Bundle initialExtras) {
994 IIntentReceiver rd = null;
995 if (resultReceiver != null) {
996 if (mPackageInfo != null) {
997 if (scheduler == null) {
998 scheduler = mMainThread.getHandler();
999 }
1000 rd = mPackageInfo.getReceiverDispatcher(
1001 resultReceiver, getOuterContext(), scheduler,
1002 mMainThread.getInstrumentation(), false);
1003 } else {
1004 if (scheduler == null) {
1005 scheduler = mMainThread.getHandler();
1006 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001007 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1009 }
1010 }
1011 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1012 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001013 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 ActivityManagerNative.getDefault().broadcastIntent(
1015 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1016 initialCode, initialData, initialExtras, receiverPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -07001017 true, false, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 } catch (RemoteException e) {
1019 }
1020 }
1021
1022 @Override
1023 public void sendStickyBroadcast(Intent intent) {
1024 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1025 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001026 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 ActivityManagerNative.getDefault().broadcastIntent(
1028 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001029 Activity.RESULT_OK, null, null, null, false, true,
1030 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 } catch (RemoteException e) {
1032 }
1033 }
1034
1035 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001036 public void sendStickyOrderedBroadcast(Intent intent,
1037 BroadcastReceiver resultReceiver,
1038 Handler scheduler, int initialCode, String initialData,
1039 Bundle initialExtras) {
1040 IIntentReceiver rd = null;
1041 if (resultReceiver != null) {
1042 if (mPackageInfo != null) {
1043 if (scheduler == null) {
1044 scheduler = mMainThread.getHandler();
1045 }
1046 rd = mPackageInfo.getReceiverDispatcher(
1047 resultReceiver, getOuterContext(), scheduler,
1048 mMainThread.getInstrumentation(), false);
1049 } else {
1050 if (scheduler == null) {
1051 scheduler = mMainThread.getHandler();
1052 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001053 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001054 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1055 }
1056 }
1057 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1058 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001059 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001060 ActivityManagerNative.getDefault().broadcastIntent(
1061 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1062 initialCode, initialData, initialExtras, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001063 true, true, Binder.getOrigCallingUser());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001064 } catch (RemoteException e) {
1065 }
1066 }
1067
1068 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 public void removeStickyBroadcast(Intent intent) {
1070 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1071 if (resolvedType != null) {
1072 intent = new Intent(intent);
1073 intent.setDataAndType(intent.getData(), resolvedType);
1074 }
1075 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001076 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 ActivityManagerNative.getDefault().unbroadcastIntent(
Amith Yamasani742a6712011-05-04 14:49:28 -07001078 mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 } catch (RemoteException e) {
1080 }
1081 }
1082
1083 @Override
1084 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1085 return registerReceiver(receiver, filter, null, null);
1086 }
1087
1088 @Override
1089 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1090 String broadcastPermission, Handler scheduler) {
1091 return registerReceiverInternal(receiver, filter, broadcastPermission,
1092 scheduler, getOuterContext());
1093 }
1094
1095 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1096 IntentFilter filter, String broadcastPermission,
1097 Handler scheduler, Context context) {
1098 IIntentReceiver rd = null;
1099 if (receiver != null) {
1100 if (mPackageInfo != null && context != null) {
1101 if (scheduler == null) {
1102 scheduler = mMainThread.getHandler();
1103 }
1104 rd = mPackageInfo.getReceiverDispatcher(
1105 receiver, context, scheduler,
1106 mMainThread.getInstrumentation(), true);
1107 } else {
1108 if (scheduler == null) {
1109 scheduler = mMainThread.getHandler();
1110 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001111 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001112 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 }
1114 }
1115 try {
1116 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001117 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 rd, filter, broadcastPermission);
1119 } catch (RemoteException e) {
1120 return null;
1121 }
1122 }
1123
1124 @Override
1125 public void unregisterReceiver(BroadcastReceiver receiver) {
1126 if (mPackageInfo != null) {
1127 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1128 getOuterContext(), receiver);
1129 try {
1130 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1131 } catch (RemoteException e) {
1132 }
1133 } else {
1134 throw new RuntimeException("Not supported in system context");
1135 }
1136 }
1137
1138 @Override
1139 public ComponentName startService(Intent service) {
1140 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001141 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 ComponentName cn = ActivityManagerNative.getDefault().startService(
1143 mMainThread.getApplicationThread(), service,
1144 service.resolveTypeIfNeeded(getContentResolver()));
1145 if (cn != null && cn.getPackageName().equals("!")) {
1146 throw new SecurityException(
1147 "Not allowed to start service " + service
1148 + " without permission " + cn.getClassName());
1149 }
1150 return cn;
1151 } catch (RemoteException e) {
1152 return null;
1153 }
1154 }
1155
1156 @Override
1157 public boolean stopService(Intent service) {
1158 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001159 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 int res = ActivityManagerNative.getDefault().stopService(
1161 mMainThread.getApplicationThread(), service,
1162 service.resolveTypeIfNeeded(getContentResolver()));
1163 if (res < 0) {
1164 throw new SecurityException(
1165 "Not allowed to stop service " + service);
1166 }
1167 return res != 0;
1168 } catch (RemoteException e) {
1169 return false;
1170 }
1171 }
1172
1173 @Override
1174 public boolean bindService(Intent service, ServiceConnection conn,
1175 int flags) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001176 return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
1177 }
1178
1179 /** @hide */
1180 @Override
1181 public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 IServiceConnection sd;
1183 if (mPackageInfo != null) {
1184 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1185 mMainThread.getHandler(), flags);
1186 } else {
1187 throw new RuntimeException("Not supported in system context");
1188 }
1189 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001190 IBinder token = getActivityToken();
1191 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1192 && mPackageInfo.getApplicationInfo().targetSdkVersion
1193 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1194 flags |= BIND_WAIVE_PRIORITY;
1195 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001196 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001197 int res = ActivityManagerNative.getDefault().bindService(
1198 mMainThread.getApplicationThread(), getActivityToken(),
1199 service, service.resolveTypeIfNeeded(getContentResolver()),
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001200 sd, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 if (res < 0) {
1202 throw new SecurityException(
1203 "Not allowed to bind to service " + service);
1204 }
1205 return res != 0;
1206 } catch (RemoteException e) {
1207 return false;
1208 }
1209 }
1210
1211 @Override
1212 public void unbindService(ServiceConnection conn) {
1213 if (mPackageInfo != null) {
1214 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1215 getOuterContext(), conn);
1216 try {
1217 ActivityManagerNative.getDefault().unbindService(sd);
1218 } catch (RemoteException e) {
1219 }
1220 } else {
1221 throw new RuntimeException("Not supported in system context");
1222 }
1223 }
1224
1225 @Override
1226 public boolean startInstrumentation(ComponentName className,
1227 String profileFile, Bundle arguments) {
1228 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001229 if (arguments != null) {
1230 arguments.setAllowFds(false);
1231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 return ActivityManagerNative.getDefault().startInstrumentation(
1233 className, profileFile, 0, arguments, null);
1234 } catch (RemoteException e) {
1235 // System has crashed, nothing we can do.
1236 }
1237 return false;
1238 }
1239
1240 @Override
1241 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001242 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1243 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001244 }
1245
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001246 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001247 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 }
1249
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001250 /* package */ static DropBoxManager createDropBoxManager() {
1251 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1252 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001253 if (service == null) {
1254 // Don't return a DropBoxManager that will NPE upon use.
1255 // This also avoids caching a broken DropBoxManager in
1256 // getDropBoxManager during early boot, before the
1257 // DROPBOX_SERVICE is registered.
1258 return null;
1259 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001260 return new DropBoxManager(service);
1261 }
1262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 @Override
1264 public int checkPermission(String permission, int pid, int uid) {
1265 if (permission == null) {
1266 throw new IllegalArgumentException("permission is null");
1267 }
1268
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 try {
1270 return ActivityManagerNative.getDefault().checkPermission(
1271 permission, pid, uid);
1272 } catch (RemoteException e) {
1273 return PackageManager.PERMISSION_DENIED;
1274 }
1275 }
1276
1277 @Override
1278 public int checkCallingPermission(String permission) {
1279 if (permission == null) {
1280 throw new IllegalArgumentException("permission is null");
1281 }
1282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 int pid = Binder.getCallingPid();
1284 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001285 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 }
1287 return PackageManager.PERMISSION_DENIED;
1288 }
1289
1290 @Override
1291 public int checkCallingOrSelfPermission(String permission) {
1292 if (permission == null) {
1293 throw new IllegalArgumentException("permission is null");
1294 }
1295
1296 return checkPermission(permission, Binder.getCallingPid(),
1297 Binder.getCallingUid());
1298 }
1299
1300 private void enforce(
1301 String permission, int resultOfCheck,
1302 boolean selfToo, int uid, String message) {
1303 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1304 throw new SecurityException(
1305 (message != null ? (message + ": ") : "") +
1306 (selfToo
1307 ? "Neither user " + uid + " nor current process has "
1308 : "User " + uid + " does not have ") +
1309 permission +
1310 ".");
1311 }
1312 }
1313
1314 public void enforcePermission(
1315 String permission, int pid, int uid, String message) {
1316 enforce(permission,
1317 checkPermission(permission, pid, uid),
1318 false,
1319 uid,
1320 message);
1321 }
1322
1323 public void enforceCallingPermission(String permission, String message) {
1324 enforce(permission,
1325 checkCallingPermission(permission),
1326 false,
1327 Binder.getCallingUid(),
1328 message);
1329 }
1330
1331 public void enforceCallingOrSelfPermission(
1332 String permission, String message) {
1333 enforce(permission,
1334 checkCallingOrSelfPermission(permission),
1335 true,
1336 Binder.getCallingUid(),
1337 message);
1338 }
1339
1340 @Override
1341 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1342 try {
1343 ActivityManagerNative.getDefault().grantUriPermission(
1344 mMainThread.getApplicationThread(), toPackage, uri,
1345 modeFlags);
1346 } catch (RemoteException e) {
1347 }
1348 }
1349
1350 @Override
1351 public void revokeUriPermission(Uri uri, int modeFlags) {
1352 try {
1353 ActivityManagerNative.getDefault().revokeUriPermission(
1354 mMainThread.getApplicationThread(), uri,
1355 modeFlags);
1356 } catch (RemoteException e) {
1357 }
1358 }
1359
1360 @Override
1361 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 try {
1363 return ActivityManagerNative.getDefault().checkUriPermission(
1364 uri, pid, uid, modeFlags);
1365 } catch (RemoteException e) {
1366 return PackageManager.PERMISSION_DENIED;
1367 }
1368 }
1369
1370 @Override
1371 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 int pid = Binder.getCallingPid();
1373 if (pid != Process.myPid()) {
1374 return checkUriPermission(uri, pid,
1375 Binder.getCallingUid(), modeFlags);
1376 }
1377 return PackageManager.PERMISSION_DENIED;
1378 }
1379
1380 @Override
1381 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1382 return checkUriPermission(uri, Binder.getCallingPid(),
1383 Binder.getCallingUid(), modeFlags);
1384 }
1385
1386 @Override
1387 public int checkUriPermission(Uri uri, String readPermission,
1388 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001389 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1391 + readPermission + " writePermission=" + writePermission
1392 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1393 }
1394 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1395 if (readPermission == null
1396 || checkPermission(readPermission, pid, uid)
1397 == PackageManager.PERMISSION_GRANTED) {
1398 return PackageManager.PERMISSION_GRANTED;
1399 }
1400 }
1401 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1402 if (writePermission == null
1403 || checkPermission(writePermission, pid, uid)
1404 == PackageManager.PERMISSION_GRANTED) {
1405 return PackageManager.PERMISSION_GRANTED;
1406 }
1407 }
1408 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1409 : PackageManager.PERMISSION_DENIED;
1410 }
1411
1412 private String uriModeFlagToString(int uriModeFlags) {
1413 switch (uriModeFlags) {
1414 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1415 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1416 return "read and write";
1417 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1418 return "read";
1419 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1420 return "write";
1421 }
1422 throw new IllegalArgumentException(
1423 "Unknown permission mode flags: " + uriModeFlags);
1424 }
1425
1426 private void enforceForUri(
1427 int modeFlags, int resultOfCheck, boolean selfToo,
1428 int uid, Uri uri, String message) {
1429 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1430 throw new SecurityException(
1431 (message != null ? (message + ": ") : "") +
1432 (selfToo
1433 ? "Neither user " + uid + " nor current process has "
1434 : "User " + uid + " does not have ") +
1435 uriModeFlagToString(modeFlags) +
1436 " permission on " +
1437 uri +
1438 ".");
1439 }
1440 }
1441
1442 public void enforceUriPermission(
1443 Uri uri, int pid, int uid, int modeFlags, String message) {
1444 enforceForUri(
1445 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1446 false, uid, uri, message);
1447 }
1448
1449 public void enforceCallingUriPermission(
1450 Uri uri, int modeFlags, String message) {
1451 enforceForUri(
1452 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001453 false,
1454 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 }
1456
1457 public void enforceCallingOrSelfUriPermission(
1458 Uri uri, int modeFlags, String message) {
1459 enforceForUri(
1460 modeFlags,
1461 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1462 Binder.getCallingUid(), uri, message);
1463 }
1464
1465 public void enforceUriPermission(
1466 Uri uri, String readPermission, String writePermission,
1467 int pid, int uid, int modeFlags, String message) {
1468 enforceForUri(modeFlags,
1469 checkUriPermission(
1470 uri, readPermission, writePermission, pid, uid,
1471 modeFlags),
1472 false,
1473 uid,
1474 uri,
1475 message);
1476 }
1477
1478 @Override
1479 public Context createPackageContext(String packageName, int flags)
1480 throws PackageManager.NameNotFoundException {
1481 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001482 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 }
1484
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001485 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001486 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001488 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001489 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001490 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 if (c.mResources != null) {
1492 return c;
1493 }
1494 }
1495
1496 // Should be a better exception.
1497 throw new PackageManager.NameNotFoundException(
1498 "Application package " + packageName + " not found");
1499 }
1500
Romain Guy870e09f2009-07-06 16:35:25 -07001501 @Override
1502 public boolean isRestricted() {
1503 return mRestricted;
1504 }
1505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 private File getDataDirFile() {
1507 if (mPackageInfo != null) {
1508 return mPackageInfo.getDataDirFile();
1509 }
1510 throw new RuntimeException("Not supported in system context");
1511 }
1512
1513 @Override
1514 public File getDir(String name, int mode) {
1515 name = "app_" + name;
1516 File file = makeFilename(getDataDirFile(), name);
1517 if (!file.exists()) {
1518 file.mkdir();
1519 setFilePermissionsFromMode(file.getPath(), mode,
1520 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1521 }
1522 return file;
1523 }
1524
Dianne Hackborn21556372010-02-04 16:34:40 -08001525 static ContextImpl createSystemContext(ActivityThread mainThread) {
1526 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 context.init(Resources.getSystem(), mainThread);
1528 return context;
1529 }
1530
Dianne Hackborn21556372010-02-04 16:34:40 -08001531 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 mOuterContext = this;
1533 }
1534
1535 /**
1536 * Create a new ApplicationContext from an existing one. The new one
1537 * works and operates the same as the one it is copying.
1538 *
1539 * @param context Existing application context.
1540 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001541 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001543 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 mResources = context.mResources;
1545 mMainThread = context.mMainThread;
1546 mContentResolver = context.mContentResolver;
1547 mOuterContext = this;
1548 }
1549
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001550 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001552 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001553 }
1554
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001555 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001556 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001557 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001559 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001561
Dianne Hackborn559a7872010-04-07 18:19:41 -07001562 if (mResources != null && container != null
1563 && container.getCompatibilityInfo().applicationScale !=
1564 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001565 if (DEBUG) {
1566 Log.d(TAG, "loaded context has different scaling. Using container's" +
1567 " compatiblity info:" + container.getDisplayMetrics());
1568 }
1569 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001570 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 mMainThread = mainThread;
1573 mContentResolver = new ApplicationContentResolver(this, mainThread);
1574
1575 setActivityToken(activityToken);
1576 }
1577
1578 final void init(Resources resources, ActivityThread mainThread) {
1579 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001580 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 mResources = resources;
1582 mMainThread = mainThread;
1583 mContentResolver = new ApplicationContentResolver(this, mainThread);
1584 }
1585
1586 final void scheduleFinalCleanup(String who, String what) {
1587 mMainThread.scheduleContextCleanup(this, who, what);
1588 }
1589
1590 final void performFinalCleanup(String who, String what) {
1591 //Log.i(TAG, "Cleanup up context: " + this);
1592 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1593 }
1594
1595 final Context getReceiverRestrictedContext() {
1596 if (mReceiverRestrictedContext != null) {
1597 return mReceiverRestrictedContext;
1598 }
1599 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1600 }
1601
1602 final void setActivityToken(IBinder token) {
1603 mActivityToken = token;
1604 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 final void setOuterContext(Context context) {
1607 mOuterContext = context;
1608 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 final Context getOuterContext() {
1611 return mOuterContext;
1612 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 final IBinder getActivityToken() {
1615 return mActivityToken;
1616 }
1617
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001618 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001619 int extraPermissions) {
1620 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1621 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1622 |extraPermissions;
1623 if ((mode&MODE_WORLD_READABLE) != 0) {
1624 perms |= FileUtils.S_IROTH;
1625 }
1626 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1627 perms |= FileUtils.S_IWOTH;
1628 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001629 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1631 + ", perms=0x" + Integer.toHexString(perms));
1632 }
1633 FileUtils.setPermissions(name, perms, -1, -1);
1634 }
1635
Oscar Montemayora8529f62009-11-18 10:14:20 -08001636 private File validateFilePath(String name, boolean createDirectory) {
1637 File dir;
1638 File f;
1639
1640 if (name.charAt(0) == File.separatorChar) {
1641 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1642 dir = new File(dirPath);
1643 name = name.substring(name.lastIndexOf(File.separatorChar));
1644 f = new File(dir, name);
1645 } else {
1646 dir = getDatabasesDir();
1647 f = makeFilename(dir, name);
1648 }
1649
1650 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1651 FileUtils.setPermissions(dir.getPath(),
1652 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1653 -1, -1);
1654 }
1655
1656 return f;
1657 }
1658
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 private File makeFilename(File base, String name) {
1660 if (name.indexOf(File.separatorChar) < 0) {
1661 return new File(base, name);
1662 }
1663 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001664 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 }
1666
1667 // ----------------------------------------------------------------------
1668 // ----------------------------------------------------------------------
1669 // ----------------------------------------------------------------------
1670
1671 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001672 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 super(context);
1674 mMainThread = mainThread;
1675 }
1676
1677 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001678 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001679 return mMainThread.acquireProvider(context, name);
1680 }
1681
1682 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001683 protected IContentProvider acquireExistingProvider(Context context, String name) {
1684 return mMainThread.acquireExistingProvider(context, name);
1685 }
1686
1687 @Override
1688 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001689 return mMainThread.releaseProvider(provider);
1690 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692 private final ActivityThread mMainThread;
1693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694}