blob: 36b9d72de45dd6c0a325afdf1c3c376bcb3f8e10 [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;
38import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070039import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.database.sqlite.SQLiteDatabase;
41import android.database.sqlite.SQLiteDatabase.CursorFactory;
42import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.graphics.drawable.Drawable;
44import android.hardware.SensorManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080045import android.hardware.usb.IUsbManager;
46import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080047import android.location.CountryDetector;
48import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.location.ILocationManager;
50import android.location.LocationManager;
51import android.media.AudioManager;
52import android.net.ConnectivityManager;
53import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070054import android.net.ThrottleManager;
55import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.net.Uri;
57import android.net.wifi.IWifiManager;
58import android.net.wifi.WifiManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080059import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.os.Binder;
Adam Powellc63806d2010-09-23 16:21:30 -070061import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080063import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080064import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.os.FileUtils;
66import android.os.Handler;
67import android.os.IBinder;
68import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070069import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.os.PowerManager;
71import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070072import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.ServiceManager;
74import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080075import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070077import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.util.AndroidRuntimeException;
79import android.util.Log;
80import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070082import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070084import android.accounts.AccountManager;
85import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080086import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080087import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import java.io.File;
90import java.io.FileInputStream;
91import java.io.FileNotFoundException;
92import java.io.FileOutputStream;
93import java.io.IOException;
94import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import java.util.ArrayList;
96import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098class ReceiverRestrictedContext extends ContextWrapper {
99 ReceiverRestrictedContext(Context base) {
100 super(base);
101 }
102
103 @Override
104 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
105 return registerReceiver(receiver, filter, null, null);
106 }
107
108 @Override
109 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
110 String broadcastPermission, Handler scheduler) {
111 throw new ReceiverCallNotAllowedException(
112 "IntentReceiver components are not allowed to register to receive intents");
113 //ex.fillInStackTrace();
114 //Log.e("IntentReceiver", ex.getMessage(), ex);
115 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
116 // scheduler);
117 }
118
119 @Override
120 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
121 throw new ReceiverCallNotAllowedException(
122 "IntentReceiver components are not allowed to bind to services");
123 //ex.fillInStackTrace();
124 //Log.e("IntentReceiver", ex.getMessage(), ex);
125 //return mContext.bindService(service, interfaceName, conn, flags);
126 }
127}
128
129/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800130 * Common implementation of Context API, which provides the base
131 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800133class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700135 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700137 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
138 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700140 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 private Resources mResources;
142 /*package*/ ActivityThread mMainThread;
143 private Context mOuterContext;
144 private IBinder mActivityToken = null;
145 private ApplicationContentResolver mContentResolver;
146 private int mThemeResource = 0;
147 private Resources.Theme mTheme = null;
148 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700150 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151
152 private final Object mSync = new Object();
153
154 private File mDatabasesDir;
155 private File mPreferencesDir;
156 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800158 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800159 private File mExternalFilesDir;
160 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200161
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 private static final String[] EMPTY_FILE_LIST = {};
163
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800164 /**
165 * Override this class when the system service constructor needs a
166 * ContextImpl. Else, use StaticServiceFetcher below.
167 */
168 /*package*/ static class ServiceFetcher {
169 int mContextCacheIndex = -1;
170
171 /**
172 * Main entrypoint; only override if you don't need caching.
173 */
174 public Object getService(ContextImpl ctx) {
175 ArrayList<Object> cache = ctx.mServiceCache;
176 Object service;
177 synchronized (cache) {
178 if (cache.size() == 0) {
179 // Initialize the cache vector on first access.
180 // At this point sNextPerContextServiceCacheIndex
181 // is the number of potential services that are
182 // cached per-Context.
183 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
184 cache.add(null);
185 }
186 } else {
187 service = cache.get(mContextCacheIndex);
188 if (service != null) {
189 return service;
190 }
191 }
192 service = createService(ctx);
193 cache.set(mContextCacheIndex, service);
194 return service;
195 }
196 }
197
198 /**
199 * Override this to create a new per-Context instance of the
200 * service. getService() will handle locking and caching.
201 */
202 public Object createService(ContextImpl ctx) {
203 throw new RuntimeException("Not implemented");
204 }
205 }
206
207 /**
208 * Override this class for services to be cached process-wide.
209 */
210 abstract static class StaticServiceFetcher extends ServiceFetcher {
211 private Object mCachedInstance;
212
213 @Override
214 public final Object getService(ContextImpl unused) {
215 synchronized (StaticServiceFetcher.this) {
216 Object service = mCachedInstance;
217 if (service != null) {
218 return service;
219 }
220 return mCachedInstance = createStaticService();
221 }
222 }
223
224 public abstract Object createStaticService();
225 }
226
227 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
228 new HashMap<String, ServiceFetcher>();
229
230 private static int sNextPerContextServiceCacheIndex = 0;
231 private static void registerService(String serviceName, ServiceFetcher fetcher) {
232 if (!(fetcher instanceof StaticServiceFetcher)) {
233 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
234 }
235 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
236 }
237
238 // This one's defined separately and given a variable name so it
239 // can be re-used by getWallpaperManager(), avoiding a HashMap
240 // lookup.
241 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
242 public Object createService(ContextImpl ctx) {
243 return new WallpaperManager(ctx.getOuterContext(),
244 ctx.mMainThread.getHandler());
245 }};
246
247 static {
248 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
249 public Object getService(ContextImpl ctx) {
250 return AccessibilityManager.getInstance(ctx);
251 }});
252
253 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
254 public Object createService(ContextImpl ctx) {
255 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
256 IAccountManager service = IAccountManager.Stub.asInterface(b);
257 return new AccountManager(ctx, service);
258 }});
259
260 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
261 public Object createService(ContextImpl ctx) {
262 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
263 }});
264
265 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
266 public Object createStaticService() {
267 IBinder b = ServiceManager.getService(ALARM_SERVICE);
268 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
269 return new AlarmManager(service);
270 }});
271
272 registerService(AUDIO_SERVICE, new ServiceFetcher() {
273 public Object createService(ContextImpl ctx) {
274 return new AudioManager(ctx);
275 }});
276
277 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
278 public Object createService(ContextImpl ctx) {
279 return new ClipboardManager(ctx.getOuterContext(),
280 ctx.mMainThread.getHandler());
281 }});
282
283 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
284 public Object createStaticService() {
285 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
286 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
287 }});
288
289 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
290 public Object createStaticService() {
291 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
292 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
293 }});
294
295 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
296 public Object createService(ContextImpl ctx) {
297 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
298 }});
299
300 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
301 public Object createService(ContextImpl ctx) {
302 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
303 }});
304
Nick Pellyd2507462010-12-13 12:22:34 -0800305 registerService(NFC_SERVICE, new ServiceFetcher() {
306 public Object createService(ContextImpl ctx) {
307 return new NfcManager(ctx);
308 }});
309
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800310 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
311 public Object createStaticService() {
312 return createDropBoxManager();
313 }});
314
315 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
316 public Object createService(ContextImpl ctx) {
317 return InputMethodManager.getInstance(ctx);
318 }});
319
320 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
321 public Object getService(ContextImpl ctx) {
322 // TODO: why isn't this caching it? It wasn't
323 // before, so I'm preserving the old behavior and
324 // using getService(), instead of createService()
325 // which would do the caching.
326 return new KeyguardManager();
327 }});
328
329 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
330 public Object createService(ContextImpl ctx) {
331 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
332 }});
333
334 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
335 public Object createStaticService() {
336 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
337 return new LocationManager(ILocationManager.Stub.asInterface(b));
338 }});
339
340 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
341 public Object createService(ContextImpl ctx) {
342 final Context outerContext = ctx.getOuterContext();
343 return new NotificationManager(
344 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800345 Resources.selectSystemTheme(0,
346 outerContext.getApplicationInfo().targetSdkVersion,
347 com.android.internal.R.style.Theme_Dialog,
348 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800349 ctx.mMainThread.getHandler());
350 }});
351
352 // Note: this was previously cached in a static variable, but
353 // constructed using mMainThread.getHandler(), so converting
354 // it to be a regular Context-cached service...
355 registerService(POWER_SERVICE, new ServiceFetcher() {
356 public Object createService(ContextImpl ctx) {
357 IBinder b = ServiceManager.getService(POWER_SERVICE);
358 IPowerManager service = IPowerManager.Stub.asInterface(b);
359 return new PowerManager(service, ctx.mMainThread.getHandler());
360 }});
361
362 registerService(SEARCH_SERVICE, new ServiceFetcher() {
363 public Object createService(ContextImpl ctx) {
364 return new SearchManager(ctx.getOuterContext(),
365 ctx.mMainThread.getHandler());
366 }});
367
368 registerService(SENSOR_SERVICE, new ServiceFetcher() {
369 public Object createService(ContextImpl ctx) {
370 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
371 }});
372
373 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
374 public Object createService(ContextImpl ctx) {
375 return new StatusBarManager(ctx.getOuterContext());
376 }});
377
378 registerService(STORAGE_SERVICE, new ServiceFetcher() {
379 public Object createService(ContextImpl ctx) {
380 try {
381 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
382 } catch (RemoteException rex) {
383 Log.e(TAG, "Failed to create StorageManager", rex);
384 return null;
385 }
386 }});
387
388 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
389 public Object createService(ContextImpl ctx) {
390 return new TelephonyManager(ctx.getOuterContext());
391 }});
392
393 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
394 public Object createStaticService() {
395 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
396 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
397 }});
398
399 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
400 public Object createService(ContextImpl ctx) {
401 return new UiModeManager();
402 }});
403
Mike Lockwood3a68b832011-03-08 10:08:59 -0500404 registerService(USB_SERVICE, new ServiceFetcher() {
405 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500406 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500407 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500408 }});
409
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800410 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
411 public Object createService(ContextImpl ctx) {
412 return new Vibrator();
413 }});
414
415 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
416
417 registerService(WIFI_SERVICE, new ServiceFetcher() {
418 public Object createService(ContextImpl ctx) {
419 IBinder b = ServiceManager.getService(WIFI_SERVICE);
420 IWifiManager service = IWifiManager.Stub.asInterface(b);
421 return new WifiManager(service, ctx.mMainThread.getHandler());
422 }});
423
424 registerService(WINDOW_SERVICE, new ServiceFetcher() {
425 public Object getService(ContextImpl ctx) {
426 return WindowManagerImpl.getDefault();
427 }});
428 }
429
430 // The system service cache for the system services that are
431 // cached per-ContextImpl. Package-scoped to avoid accessor
432 // methods.
433 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 @Override
436 public AssetManager getAssets() {
437 return mResources.getAssets();
438 }
439
440 @Override
441 public Resources getResources() {
442 return mResources;
443 }
444
445 @Override
446 public PackageManager getPackageManager() {
447 if (mPackageManager != null) {
448 return mPackageManager;
449 }
450
451 IPackageManager pm = ActivityThread.getPackageManager();
452 if (pm != null) {
453 // Doesn't matter if we make more than one instance.
454 return (mPackageManager = new ApplicationPackageManager(this, pm));
455 }
456
457 return null;
458 }
459
460 @Override
461 public ContentResolver getContentResolver() {
462 return mContentResolver;
463 }
464
465 @Override
466 public Looper getMainLooper() {
467 return mMainThread.getLooper();
468 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 @Override
471 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700472 return (mPackageInfo != null) ?
473 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 @Override
477 public void setTheme(int resid) {
478 mThemeResource = resid;
479 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800481 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800482 public int getThemeResId() {
483 return mThemeResource;
484 }
485
486 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 public Resources.Theme getTheme() {
488 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800489 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
490 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 mTheme = mResources.newTheme();
492 mTheme.applyStyle(mThemeResource, true);
493 }
494 return mTheme;
495 }
496
497 @Override
498 public ClassLoader getClassLoader() {
499 return mPackageInfo != null ?
500 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
501 }
502
503 @Override
504 public String getPackageName() {
505 if (mPackageInfo != null) {
506 return mPackageInfo.getPackageName();
507 }
508 throw new RuntimeException("Not supported in system context");
509 }
510
511 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700512 public ApplicationInfo getApplicationInfo() {
513 if (mPackageInfo != null) {
514 return mPackageInfo.getApplicationInfo();
515 }
516 throw new RuntimeException("Not supported in system context");
517 }
518
519 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 public String getPackageResourcePath() {
521 if (mPackageInfo != null) {
522 return mPackageInfo.getResDir();
523 }
524 throw new RuntimeException("Not supported in system context");
525 }
526
527 @Override
528 public String getPackageCodePath() {
529 if (mPackageInfo != null) {
530 return mPackageInfo.getAppDir();
531 }
532 throw new RuntimeException("Not supported in system context");
533 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200534
Joe Onorato23ecae32009-06-10 17:07:15 -0700535 public File getSharedPrefsFile(String name) {
536 return makeFilename(getPreferencesDir(), name + ".xml");
537 }
538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 @Override
540 public SharedPreferences getSharedPreferences(String name, int mode) {
541 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700543 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700544 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800545 File prefsFile = getSharedPrefsFile(name);
546 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700547 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700548 return sp;
549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800551 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
552 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
553 // If somebody else (some other process) changed the prefs
554 // file behind our back, we reload it. This has been the
555 // historical (if undocumented) behavior.
556 sp.startReloadIfChangedUnexpectedly();
557 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700558 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 }
560
561 private File getPreferencesDir() {
562 synchronized (mSync) {
563 if (mPreferencesDir == null) {
564 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
565 }
566 return mPreferencesDir;
567 }
568 }
569
570 @Override
571 public FileInputStream openFileInput(String name)
572 throws FileNotFoundException {
573 File f = makeFilename(getFilesDir(), name);
574 return new FileInputStream(f);
575 }
576
577 @Override
578 public FileOutputStream openFileOutput(String name, int mode)
579 throws FileNotFoundException {
580 final boolean append = (mode&MODE_APPEND) != 0;
581 File f = makeFilename(getFilesDir(), name);
582 try {
583 FileOutputStream fos = new FileOutputStream(f, append);
584 setFilePermissionsFromMode(f.getPath(), mode, 0);
585 return fos;
586 } catch (FileNotFoundException e) {
587 }
588
589 File parent = f.getParentFile();
590 parent.mkdir();
591 FileUtils.setPermissions(
592 parent.getPath(),
593 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
594 -1, -1);
595 FileOutputStream fos = new FileOutputStream(f, append);
596 setFilePermissionsFromMode(f.getPath(), mode, 0);
597 return fos;
598 }
599
600 @Override
601 public boolean deleteFile(String name) {
602 File f = makeFilename(getFilesDir(), name);
603 return f.delete();
604 }
605
606 @Override
607 public File getFilesDir() {
608 synchronized (mSync) {
609 if (mFilesDir == null) {
610 mFilesDir = new File(getDataDirFile(), "files");
611 }
612 if (!mFilesDir.exists()) {
613 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200614 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 return null;
616 }
617 FileUtils.setPermissions(
618 mFilesDir.getPath(),
619 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
620 -1, -1);
621 }
622 return mFilesDir;
623 }
624 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800627 public File getExternalFilesDir(String type) {
628 synchronized (mSync) {
629 if (mExternalFilesDir == null) {
630 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
631 getPackageName());
632 }
633 if (!mExternalFilesDir.exists()) {
634 try {
635 (new File(Environment.getExternalStorageAndroidDataDir(),
636 ".nomedia")).createNewFile();
637 } catch (IOException e) {
638 }
639 if (!mExternalFilesDir.mkdirs()) {
640 Log.w(TAG, "Unable to create external files directory");
641 return null;
642 }
643 }
644 if (type == null) {
645 return mExternalFilesDir;
646 }
647 File dir = new File(mExternalFilesDir, type);
648 if (!dir.exists()) {
649 if (!dir.mkdirs()) {
650 Log.w(TAG, "Unable to create external media directory " + dir);
651 return null;
652 }
653 }
654 return dir;
655 }
656 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200657
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800658 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800659 public File getObbDir() {
660 synchronized (mSync) {
661 if (mObbDir == null) {
662 mObbDir = Environment.getExternalStorageAppObbDirectory(
663 getPackageName());
664 }
665 return mObbDir;
666 }
667 }
668
669 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 public File getCacheDir() {
671 synchronized (mSync) {
672 if (mCacheDir == null) {
673 mCacheDir = new File(getDataDirFile(), "cache");
674 }
675 if (!mCacheDir.exists()) {
676 if(!mCacheDir.mkdirs()) {
677 Log.w(TAG, "Unable to create cache directory");
678 return null;
679 }
680 FileUtils.setPermissions(
681 mCacheDir.getPath(),
682 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
683 -1, -1);
684 }
685 }
686 return mCacheDir;
687 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200688
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800689 @Override
690 public File getExternalCacheDir() {
691 synchronized (mSync) {
692 if (mExternalCacheDir == null) {
693 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
694 getPackageName());
695 }
696 if (!mExternalCacheDir.exists()) {
697 try {
698 (new File(Environment.getExternalStorageAndroidDataDir(),
699 ".nomedia")).createNewFile();
700 } catch (IOException e) {
701 }
702 if (!mExternalCacheDir.mkdirs()) {
703 Log.w(TAG, "Unable to create external cache directory");
704 return null;
705 }
706 }
707 return mExternalCacheDir;
708 }
709 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 @Override
712 public File getFileStreamPath(String name) {
713 return makeFilename(getFilesDir(), name);
714 }
715
716 @Override
717 public String[] fileList() {
718 final String[] list = getFilesDir().list();
719 return (list != null) ? list : EMPTY_FILE_LIST;
720 }
721
722 @Override
723 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800724 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
726 setFilePermissionsFromMode(f.getPath(), mode, 0);
727 return db;
728 }
729
730 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700731 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
732 DatabaseErrorHandler errorHandler) {
733 File f = validateFilePath(name, true);
734 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
735 setFilePermissionsFromMode(f.getPath(), mode, 0);
736 return db;
737 }
738
739 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 public boolean deleteDatabase(String name) {
741 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800742 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 return f.delete();
744 } catch (Exception e) {
745 }
746 return false;
747 }
748
749 @Override
750 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800751 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800752 }
753
754 @Override
755 public String[] databaseList() {
756 final String[] list = getDatabasesDir().list();
757 return (list != null) ? list : EMPTY_FILE_LIST;
758 }
759
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 private File getDatabasesDir() {
762 synchronized (mSync) {
763 if (mDatabasesDir == null) {
764 mDatabasesDir = new File(getDataDirFile(), "databases");
765 }
766 if (mDatabasesDir.getPath().equals("databases")) {
767 mDatabasesDir = new File("/data/system");
768 }
769 return mDatabasesDir;
770 }
771 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200772
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 @Override
774 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700775 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
778 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700779 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700780 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 }
782
783 @Override
784 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700785 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 }
787
788 @Override
789 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700790 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 }
792
793 @Override
794 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700795 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
797
798 @Override
799 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700800 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802
803 @Override
804 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700805 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 }
807
808 @Override
809 public void startActivity(Intent intent) {
810 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
811 throw new AndroidRuntimeException(
812 "Calling startActivity() from outside of an Activity "
813 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
814 + " Is this really what you want?");
815 }
816 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700817 getOuterContext(), mMainThread.getApplicationThread(), null,
818 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 }
820
821 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800822 public void startActivities(Intent[] intents) {
823 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
824 throw new AndroidRuntimeException(
825 "Calling startActivities() from outside of an Activity "
826 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
827 + " Is this really what you want?");
828 }
829 mMainThread.getInstrumentation().execStartActivities(
830 getOuterContext(), mMainThread.getApplicationThread(), null,
831 (Activity)null, intents);
832 }
833
834 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700835 public void startIntentSender(IntentSender intent,
836 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
837 throws IntentSender.SendIntentException {
838 try {
839 String resolvedType = null;
840 if (fillInIntent != null) {
841 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
842 }
843 int result = ActivityManagerNative.getDefault()
844 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
845 fillInIntent, resolvedType, null, null,
846 0, flagsMask, flagsValues);
847 if (result == IActivityManager.START_CANCELED) {
848 throw new IntentSender.SendIntentException();
849 }
850 Instrumentation.checkStartActivityResult(result, null);
851 } catch (RemoteException e) {
852 }
853 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200854
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700855 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 public void sendBroadcast(Intent intent) {
857 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
858 try {
859 ActivityManagerNative.getDefault().broadcastIntent(
860 mMainThread.getApplicationThread(), intent, resolvedType, null,
861 Activity.RESULT_OK, null, null, null, false, false);
862 } catch (RemoteException e) {
863 }
864 }
865
866 @Override
867 public void sendBroadcast(Intent intent, String receiverPermission) {
868 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
869 try {
870 ActivityManagerNative.getDefault().broadcastIntent(
871 mMainThread.getApplicationThread(), intent, resolvedType, null,
872 Activity.RESULT_OK, null, null, receiverPermission, false, false);
873 } catch (RemoteException e) {
874 }
875 }
876
877 @Override
878 public void sendOrderedBroadcast(Intent intent,
879 String receiverPermission) {
880 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
881 try {
882 ActivityManagerNative.getDefault().broadcastIntent(
883 mMainThread.getApplicationThread(), intent, resolvedType, null,
884 Activity.RESULT_OK, null, null, receiverPermission, true, false);
885 } catch (RemoteException e) {
886 }
887 }
888
889 @Override
890 public void sendOrderedBroadcast(Intent intent,
891 String receiverPermission, BroadcastReceiver resultReceiver,
892 Handler scheduler, int initialCode, String initialData,
893 Bundle initialExtras) {
894 IIntentReceiver rd = null;
895 if (resultReceiver != null) {
896 if (mPackageInfo != null) {
897 if (scheduler == null) {
898 scheduler = mMainThread.getHandler();
899 }
900 rd = mPackageInfo.getReceiverDispatcher(
901 resultReceiver, getOuterContext(), scheduler,
902 mMainThread.getInstrumentation(), false);
903 } else {
904 if (scheduler == null) {
905 scheduler = mMainThread.getHandler();
906 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700907 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
909 }
910 }
911 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
912 try {
913 ActivityManagerNative.getDefault().broadcastIntent(
914 mMainThread.getApplicationThread(), intent, resolvedType, rd,
915 initialCode, initialData, initialExtras, receiverPermission,
916 true, false);
917 } catch (RemoteException e) {
918 }
919 }
920
921 @Override
922 public void sendStickyBroadcast(Intent intent) {
923 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
924 try {
925 ActivityManagerNative.getDefault().broadcastIntent(
926 mMainThread.getApplicationThread(), intent, resolvedType, null,
927 Activity.RESULT_OK, null, null, null, false, true);
928 } catch (RemoteException e) {
929 }
930 }
931
932 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700933 public void sendStickyOrderedBroadcast(Intent intent,
934 BroadcastReceiver resultReceiver,
935 Handler scheduler, int initialCode, String initialData,
936 Bundle initialExtras) {
937 IIntentReceiver rd = null;
938 if (resultReceiver != null) {
939 if (mPackageInfo != null) {
940 if (scheduler == null) {
941 scheduler = mMainThread.getHandler();
942 }
943 rd = mPackageInfo.getReceiverDispatcher(
944 resultReceiver, getOuterContext(), scheduler,
945 mMainThread.getInstrumentation(), false);
946 } else {
947 if (scheduler == null) {
948 scheduler = mMainThread.getHandler();
949 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700950 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700951 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
952 }
953 }
954 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
955 try {
956 ActivityManagerNative.getDefault().broadcastIntent(
957 mMainThread.getApplicationThread(), intent, resolvedType, rd,
958 initialCode, initialData, initialExtras, null,
959 true, true);
960 } catch (RemoteException e) {
961 }
962 }
963
964 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 public void removeStickyBroadcast(Intent intent) {
966 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
967 if (resolvedType != null) {
968 intent = new Intent(intent);
969 intent.setDataAndType(intent.getData(), resolvedType);
970 }
971 try {
972 ActivityManagerNative.getDefault().unbroadcastIntent(
973 mMainThread.getApplicationThread(), intent);
974 } catch (RemoteException e) {
975 }
976 }
977
978 @Override
979 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
980 return registerReceiver(receiver, filter, null, null);
981 }
982
983 @Override
984 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
985 String broadcastPermission, Handler scheduler) {
986 return registerReceiverInternal(receiver, filter, broadcastPermission,
987 scheduler, getOuterContext());
988 }
989
990 private Intent registerReceiverInternal(BroadcastReceiver receiver,
991 IntentFilter filter, String broadcastPermission,
992 Handler scheduler, Context context) {
993 IIntentReceiver rd = null;
994 if (receiver != null) {
995 if (mPackageInfo != null && context != null) {
996 if (scheduler == null) {
997 scheduler = mMainThread.getHandler();
998 }
999 rd = mPackageInfo.getReceiverDispatcher(
1000 receiver, context, scheduler,
1001 mMainThread.getInstrumentation(), true);
1002 } else {
1003 if (scheduler == null) {
1004 scheduler = mMainThread.getHandler();
1005 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001006 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001007 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 }
1009 }
1010 try {
1011 return ActivityManagerNative.getDefault().registerReceiver(
1012 mMainThread.getApplicationThread(),
1013 rd, filter, broadcastPermission);
1014 } catch (RemoteException e) {
1015 return null;
1016 }
1017 }
1018
1019 @Override
1020 public void unregisterReceiver(BroadcastReceiver receiver) {
1021 if (mPackageInfo != null) {
1022 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1023 getOuterContext(), receiver);
1024 try {
1025 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1026 } catch (RemoteException e) {
1027 }
1028 } else {
1029 throw new RuntimeException("Not supported in system context");
1030 }
1031 }
1032
1033 @Override
1034 public ComponentName startService(Intent service) {
1035 try {
1036 ComponentName cn = ActivityManagerNative.getDefault().startService(
1037 mMainThread.getApplicationThread(), service,
1038 service.resolveTypeIfNeeded(getContentResolver()));
1039 if (cn != null && cn.getPackageName().equals("!")) {
1040 throw new SecurityException(
1041 "Not allowed to start service " + service
1042 + " without permission " + cn.getClassName());
1043 }
1044 return cn;
1045 } catch (RemoteException e) {
1046 return null;
1047 }
1048 }
1049
1050 @Override
1051 public boolean stopService(Intent service) {
1052 try {
1053 int res = ActivityManagerNative.getDefault().stopService(
1054 mMainThread.getApplicationThread(), service,
1055 service.resolveTypeIfNeeded(getContentResolver()));
1056 if (res < 0) {
1057 throw new SecurityException(
1058 "Not allowed to stop service " + service);
1059 }
1060 return res != 0;
1061 } catch (RemoteException e) {
1062 return false;
1063 }
1064 }
1065
1066 @Override
1067 public boolean bindService(Intent service, ServiceConnection conn,
1068 int flags) {
1069 IServiceConnection sd;
1070 if (mPackageInfo != null) {
1071 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1072 mMainThread.getHandler(), flags);
1073 } else {
1074 throw new RuntimeException("Not supported in system context");
1075 }
1076 try {
1077 int res = ActivityManagerNative.getDefault().bindService(
1078 mMainThread.getApplicationThread(), getActivityToken(),
1079 service, service.resolveTypeIfNeeded(getContentResolver()),
1080 sd, flags);
1081 if (res < 0) {
1082 throw new SecurityException(
1083 "Not allowed to bind to service " + service);
1084 }
1085 return res != 0;
1086 } catch (RemoteException e) {
1087 return false;
1088 }
1089 }
1090
1091 @Override
1092 public void unbindService(ServiceConnection conn) {
1093 if (mPackageInfo != null) {
1094 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1095 getOuterContext(), conn);
1096 try {
1097 ActivityManagerNative.getDefault().unbindService(sd);
1098 } catch (RemoteException e) {
1099 }
1100 } else {
1101 throw new RuntimeException("Not supported in system context");
1102 }
1103 }
1104
1105 @Override
1106 public boolean startInstrumentation(ComponentName className,
1107 String profileFile, Bundle arguments) {
1108 try {
1109 return ActivityManagerNative.getDefault().startInstrumentation(
1110 className, profileFile, 0, arguments, null);
1111 } catch (RemoteException e) {
1112 // System has crashed, nothing we can do.
1113 }
1114 return false;
1115 }
1116
1117 @Override
1118 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001119 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1120 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 }
1122
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001123 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001124 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 }
1126
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001127 /* package */ static DropBoxManager createDropBoxManager() {
1128 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1129 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001130 if (service == null) {
1131 // Don't return a DropBoxManager that will NPE upon use.
1132 // This also avoids caching a broken DropBoxManager in
1133 // getDropBoxManager during early boot, before the
1134 // DROPBOX_SERVICE is registered.
1135 return null;
1136 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001137 return new DropBoxManager(service);
1138 }
1139
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 @Override
1141 public int checkPermission(String permission, int pid, int uid) {
1142 if (permission == null) {
1143 throw new IllegalArgumentException("permission is null");
1144 }
1145
1146 if (!Process.supportsProcesses()) {
1147 return PackageManager.PERMISSION_GRANTED;
1148 }
1149 try {
1150 return ActivityManagerNative.getDefault().checkPermission(
1151 permission, pid, uid);
1152 } catch (RemoteException e) {
1153 return PackageManager.PERMISSION_DENIED;
1154 }
1155 }
1156
1157 @Override
1158 public int checkCallingPermission(String permission) {
1159 if (permission == null) {
1160 throw new IllegalArgumentException("permission is null");
1161 }
1162
1163 if (!Process.supportsProcesses()) {
1164 return PackageManager.PERMISSION_GRANTED;
1165 }
1166 int pid = Binder.getCallingPid();
1167 if (pid != Process.myPid()) {
1168 return checkPermission(permission, pid,
1169 Binder.getCallingUid());
1170 }
1171 return PackageManager.PERMISSION_DENIED;
1172 }
1173
1174 @Override
1175 public int checkCallingOrSelfPermission(String permission) {
1176 if (permission == null) {
1177 throw new IllegalArgumentException("permission is null");
1178 }
1179
1180 return checkPermission(permission, Binder.getCallingPid(),
1181 Binder.getCallingUid());
1182 }
1183
1184 private void enforce(
1185 String permission, int resultOfCheck,
1186 boolean selfToo, int uid, String message) {
1187 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1188 throw new SecurityException(
1189 (message != null ? (message + ": ") : "") +
1190 (selfToo
1191 ? "Neither user " + uid + " nor current process has "
1192 : "User " + uid + " does not have ") +
1193 permission +
1194 ".");
1195 }
1196 }
1197
1198 public void enforcePermission(
1199 String permission, int pid, int uid, String message) {
1200 enforce(permission,
1201 checkPermission(permission, pid, uid),
1202 false,
1203 uid,
1204 message);
1205 }
1206
1207 public void enforceCallingPermission(String permission, String message) {
1208 enforce(permission,
1209 checkCallingPermission(permission),
1210 false,
1211 Binder.getCallingUid(),
1212 message);
1213 }
1214
1215 public void enforceCallingOrSelfPermission(
1216 String permission, String message) {
1217 enforce(permission,
1218 checkCallingOrSelfPermission(permission),
1219 true,
1220 Binder.getCallingUid(),
1221 message);
1222 }
1223
1224 @Override
1225 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1226 try {
1227 ActivityManagerNative.getDefault().grantUriPermission(
1228 mMainThread.getApplicationThread(), toPackage, uri,
1229 modeFlags);
1230 } catch (RemoteException e) {
1231 }
1232 }
1233
1234 @Override
1235 public void revokeUriPermission(Uri uri, int modeFlags) {
1236 try {
1237 ActivityManagerNative.getDefault().revokeUriPermission(
1238 mMainThread.getApplicationThread(), uri,
1239 modeFlags);
1240 } catch (RemoteException e) {
1241 }
1242 }
1243
1244 @Override
1245 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1246 if (!Process.supportsProcesses()) {
1247 return PackageManager.PERMISSION_GRANTED;
1248 }
1249 try {
1250 return ActivityManagerNative.getDefault().checkUriPermission(
1251 uri, pid, uid, modeFlags);
1252 } catch (RemoteException e) {
1253 return PackageManager.PERMISSION_DENIED;
1254 }
1255 }
1256
1257 @Override
1258 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1259 if (!Process.supportsProcesses()) {
1260 return PackageManager.PERMISSION_GRANTED;
1261 }
1262 int pid = Binder.getCallingPid();
1263 if (pid != Process.myPid()) {
1264 return checkUriPermission(uri, pid,
1265 Binder.getCallingUid(), modeFlags);
1266 }
1267 return PackageManager.PERMISSION_DENIED;
1268 }
1269
1270 @Override
1271 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1272 return checkUriPermission(uri, Binder.getCallingPid(),
1273 Binder.getCallingUid(), modeFlags);
1274 }
1275
1276 @Override
1277 public int checkUriPermission(Uri uri, String readPermission,
1278 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001279 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1281 + readPermission + " writePermission=" + writePermission
1282 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1283 }
1284 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1285 if (readPermission == null
1286 || checkPermission(readPermission, pid, uid)
1287 == PackageManager.PERMISSION_GRANTED) {
1288 return PackageManager.PERMISSION_GRANTED;
1289 }
1290 }
1291 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1292 if (writePermission == null
1293 || checkPermission(writePermission, pid, uid)
1294 == PackageManager.PERMISSION_GRANTED) {
1295 return PackageManager.PERMISSION_GRANTED;
1296 }
1297 }
1298 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1299 : PackageManager.PERMISSION_DENIED;
1300 }
1301
1302 private String uriModeFlagToString(int uriModeFlags) {
1303 switch (uriModeFlags) {
1304 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1305 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1306 return "read and write";
1307 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1308 return "read";
1309 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1310 return "write";
1311 }
1312 throw new IllegalArgumentException(
1313 "Unknown permission mode flags: " + uriModeFlags);
1314 }
1315
1316 private void enforceForUri(
1317 int modeFlags, int resultOfCheck, boolean selfToo,
1318 int uid, Uri uri, String message) {
1319 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1320 throw new SecurityException(
1321 (message != null ? (message + ": ") : "") +
1322 (selfToo
1323 ? "Neither user " + uid + " nor current process has "
1324 : "User " + uid + " does not have ") +
1325 uriModeFlagToString(modeFlags) +
1326 " permission on " +
1327 uri +
1328 ".");
1329 }
1330 }
1331
1332 public void enforceUriPermission(
1333 Uri uri, int pid, int uid, int modeFlags, String message) {
1334 enforceForUri(
1335 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1336 false, uid, uri, message);
1337 }
1338
1339 public void enforceCallingUriPermission(
1340 Uri uri, int modeFlags, String message) {
1341 enforceForUri(
1342 modeFlags, checkCallingUriPermission(uri, modeFlags),
1343 false, Binder.getCallingUid(), uri, message);
1344 }
1345
1346 public void enforceCallingOrSelfUriPermission(
1347 Uri uri, int modeFlags, String message) {
1348 enforceForUri(
1349 modeFlags,
1350 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1351 Binder.getCallingUid(), uri, message);
1352 }
1353
1354 public void enforceUriPermission(
1355 Uri uri, String readPermission, String writePermission,
1356 int pid, int uid, int modeFlags, String message) {
1357 enforceForUri(modeFlags,
1358 checkUriPermission(
1359 uri, readPermission, writePermission, pid, uid,
1360 modeFlags),
1361 false,
1362 uid,
1363 uri,
1364 message);
1365 }
1366
1367 @Override
1368 public Context createPackageContext(String packageName, int flags)
1369 throws PackageManager.NameNotFoundException {
1370 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001371 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 }
1373
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001374 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001375 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001377 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001378 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001379 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001380 if (c.mResources != null) {
1381 return c;
1382 }
1383 }
1384
1385 // Should be a better exception.
1386 throw new PackageManager.NameNotFoundException(
1387 "Application package " + packageName + " not found");
1388 }
1389
Romain Guy870e09f2009-07-06 16:35:25 -07001390 @Override
1391 public boolean isRestricted() {
1392 return mRestricted;
1393 }
1394
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 private File getDataDirFile() {
1396 if (mPackageInfo != null) {
1397 return mPackageInfo.getDataDirFile();
1398 }
1399 throw new RuntimeException("Not supported in system context");
1400 }
1401
1402 @Override
1403 public File getDir(String name, int mode) {
1404 name = "app_" + name;
1405 File file = makeFilename(getDataDirFile(), name);
1406 if (!file.exists()) {
1407 file.mkdir();
1408 setFilePermissionsFromMode(file.getPath(), mode,
1409 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1410 }
1411 return file;
1412 }
1413
Dianne Hackborn21556372010-02-04 16:34:40 -08001414 static ContextImpl createSystemContext(ActivityThread mainThread) {
1415 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 context.init(Resources.getSystem(), mainThread);
1417 return context;
1418 }
1419
Dianne Hackborn21556372010-02-04 16:34:40 -08001420 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 mOuterContext = this;
1422 }
1423
1424 /**
1425 * Create a new ApplicationContext from an existing one. The new one
1426 * works and operates the same as the one it is copying.
1427 *
1428 * @param context Existing application context.
1429 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001430 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 mPackageInfo = context.mPackageInfo;
1432 mResources = context.mResources;
1433 mMainThread = context.mMainThread;
1434 mContentResolver = context.mContentResolver;
1435 mOuterContext = this;
1436 }
1437
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001438 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001440 init(packageInfo, activityToken, mainThread, null);
1441 }
1442
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001443 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001444 IBinder activityToken, ActivityThread mainThread,
1445 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 mPackageInfo = packageInfo;
1447 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001448
Dianne Hackborn559a7872010-04-07 18:19:41 -07001449 if (mResources != null && container != null
1450 && container.getCompatibilityInfo().applicationScale !=
1451 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001452 if (DEBUG) {
1453 Log.d(TAG, "loaded context has different scaling. Using container's" +
1454 " compatiblity info:" + container.getDisplayMetrics());
1455 }
1456 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001457 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 mMainThread = mainThread;
1460 mContentResolver = new ApplicationContentResolver(this, mainThread);
1461
1462 setActivityToken(activityToken);
1463 }
1464
1465 final void init(Resources resources, ActivityThread mainThread) {
1466 mPackageInfo = null;
1467 mResources = resources;
1468 mMainThread = mainThread;
1469 mContentResolver = new ApplicationContentResolver(this, mainThread);
1470 }
1471
1472 final void scheduleFinalCleanup(String who, String what) {
1473 mMainThread.scheduleContextCleanup(this, who, what);
1474 }
1475
1476 final void performFinalCleanup(String who, String what) {
1477 //Log.i(TAG, "Cleanup up context: " + this);
1478 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1479 }
1480
1481 final Context getReceiverRestrictedContext() {
1482 if (mReceiverRestrictedContext != null) {
1483 return mReceiverRestrictedContext;
1484 }
1485 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1486 }
1487
1488 final void setActivityToken(IBinder token) {
1489 mActivityToken = token;
1490 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 final void setOuterContext(Context context) {
1493 mOuterContext = context;
1494 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 final Context getOuterContext() {
1497 return mOuterContext;
1498 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 final IBinder getActivityToken() {
1501 return mActivityToken;
1502 }
1503
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001504 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 int extraPermissions) {
1506 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1507 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1508 |extraPermissions;
1509 if ((mode&MODE_WORLD_READABLE) != 0) {
1510 perms |= FileUtils.S_IROTH;
1511 }
1512 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1513 perms |= FileUtils.S_IWOTH;
1514 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001515 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1517 + ", perms=0x" + Integer.toHexString(perms));
1518 }
1519 FileUtils.setPermissions(name, perms, -1, -1);
1520 }
1521
Oscar Montemayora8529f62009-11-18 10:14:20 -08001522 private File validateFilePath(String name, boolean createDirectory) {
1523 File dir;
1524 File f;
1525
1526 if (name.charAt(0) == File.separatorChar) {
1527 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1528 dir = new File(dirPath);
1529 name = name.substring(name.lastIndexOf(File.separatorChar));
1530 f = new File(dir, name);
1531 } else {
1532 dir = getDatabasesDir();
1533 f = makeFilename(dir, name);
1534 }
1535
1536 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1537 FileUtils.setPermissions(dir.getPath(),
1538 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1539 -1, -1);
1540 }
1541
1542 return f;
1543 }
1544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 private File makeFilename(File base, String name) {
1546 if (name.indexOf(File.separatorChar) < 0) {
1547 return new File(base, name);
1548 }
1549 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001550 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 }
1552
1553 // ----------------------------------------------------------------------
1554 // ----------------------------------------------------------------------
1555 // ----------------------------------------------------------------------
1556
1557 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001558 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 super(context);
1560 mMainThread = mainThread;
1561 }
1562
1563 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001564 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 return mMainThread.acquireProvider(context, name);
1566 }
1567
1568 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001569 protected IContentProvider acquireExistingProvider(Context context, String name) {
1570 return mMainThread.acquireExistingProvider(context, name);
1571 }
1572
1573 @Override
1574 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 return mMainThread.releaseProvider(provider);
1576 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001577
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 private final ActivityThread mMainThread;
1579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580}