blob: 73170bb490216780183ed52ed039e0c3669b218b [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;
45import android.hardware.SensorManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080046import android.hardware.usb.IUsbManager;
47import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080048import android.location.CountryDetector;
49import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.location.ILocationManager;
51import android.location.LocationManager;
52import android.media.AudioManager;
53import android.net.ConnectivityManager;
54import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070055import android.net.ThrottleManager;
56import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.net.Uri;
58import android.net.wifi.IWifiManager;
59import android.net.wifi.WifiManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080060import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.os.Binder;
Adam Powellc63806d2010-09-23 16:21:30 -070062import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080064import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080065import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.os.FileUtils;
67import android.os.Handler;
68import android.os.IBinder;
69import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070070import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.PowerManager;
72import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070073import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.ServiceManager;
75import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080076import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070078import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.util.AndroidRuntimeException;
80import android.util.Log;
81import android.view.ContextThemeWrapper;
Dianne Hackborn5be8de32011-05-24 18:11:57 -070082import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070084import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070086import android.accounts.AccountManager;
87import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080088import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080089import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import java.io.File;
92import java.io.FileInputStream;
93import java.io.FileNotFoundException;
94import java.io.FileOutputStream;
95import java.io.IOException;
96import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import java.util.ArrayList;
98import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100class ReceiverRestrictedContext extends ContextWrapper {
101 ReceiverRestrictedContext(Context base) {
102 super(base);
103 }
104
105 @Override
106 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
107 return registerReceiver(receiver, filter, null, null);
108 }
109
110 @Override
111 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
112 String broadcastPermission, Handler scheduler) {
113 throw new ReceiverCallNotAllowedException(
114 "IntentReceiver components are not allowed to register to receive intents");
115 //ex.fillInStackTrace();
116 //Log.e("IntentReceiver", ex.getMessage(), ex);
117 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
118 // scheduler);
119 }
120
121 @Override
122 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
123 throw new ReceiverCallNotAllowedException(
124 "IntentReceiver components are not allowed to bind to services");
125 //ex.fillInStackTrace();
126 //Log.e("IntentReceiver", ex.getMessage(), ex);
127 //return mContext.bindService(service, interfaceName, conn, flags);
128 }
129}
130
131/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800132 * Common implementation of Context API, which provides the base
133 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800135class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700137 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700139 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
140 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700142 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 private Resources mResources;
144 /*package*/ ActivityThread mMainThread;
145 private Context mOuterContext;
146 private IBinder mActivityToken = null;
147 private ApplicationContentResolver mContentResolver;
148 private int mThemeResource = 0;
149 private Resources.Theme mTheme = null;
150 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700152 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153
154 private final Object mSync = new Object();
155
156 private File mDatabasesDir;
157 private File mPreferencesDir;
158 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800160 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800161 private File mExternalFilesDir;
162 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 private static final String[] EMPTY_FILE_LIST = {};
165
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800166 /**
167 * Override this class when the system service constructor needs a
168 * ContextImpl. Else, use StaticServiceFetcher below.
169 */
170 /*package*/ static class ServiceFetcher {
171 int mContextCacheIndex = -1;
172
173 /**
174 * Main entrypoint; only override if you don't need caching.
175 */
176 public Object getService(ContextImpl ctx) {
177 ArrayList<Object> cache = ctx.mServiceCache;
178 Object service;
179 synchronized (cache) {
180 if (cache.size() == 0) {
181 // Initialize the cache vector on first access.
182 // At this point sNextPerContextServiceCacheIndex
183 // is the number of potential services that are
184 // cached per-Context.
185 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
186 cache.add(null);
187 }
188 } else {
189 service = cache.get(mContextCacheIndex);
190 if (service != null) {
191 return service;
192 }
193 }
194 service = createService(ctx);
195 cache.set(mContextCacheIndex, service);
196 return service;
197 }
198 }
199
200 /**
201 * Override this to create a new per-Context instance of the
202 * service. getService() will handle locking and caching.
203 */
204 public Object createService(ContextImpl ctx) {
205 throw new RuntimeException("Not implemented");
206 }
207 }
208
209 /**
210 * Override this class for services to be cached process-wide.
211 */
212 abstract static class StaticServiceFetcher extends ServiceFetcher {
213 private Object mCachedInstance;
214
215 @Override
216 public final Object getService(ContextImpl unused) {
217 synchronized (StaticServiceFetcher.this) {
218 Object service = mCachedInstance;
219 if (service != null) {
220 return service;
221 }
222 return mCachedInstance = createStaticService();
223 }
224 }
225
226 public abstract Object createStaticService();
227 }
228
229 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
230 new HashMap<String, ServiceFetcher>();
231
232 private static int sNextPerContextServiceCacheIndex = 0;
233 private static void registerService(String serviceName, ServiceFetcher fetcher) {
234 if (!(fetcher instanceof StaticServiceFetcher)) {
235 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
236 }
237 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
238 }
239
240 // This one's defined separately and given a variable name so it
241 // can be re-used by getWallpaperManager(), avoiding a HashMap
242 // lookup.
243 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
244 public Object createService(ContextImpl ctx) {
245 return new WallpaperManager(ctx.getOuterContext(),
246 ctx.mMainThread.getHandler());
247 }};
248
249 static {
250 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
251 public Object getService(ContextImpl ctx) {
252 return AccessibilityManager.getInstance(ctx);
253 }});
254
255 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
256 public Object createService(ContextImpl ctx) {
257 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
258 IAccountManager service = IAccountManager.Stub.asInterface(b);
259 return new AccountManager(ctx, service);
260 }});
261
262 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
263 public Object createService(ContextImpl ctx) {
264 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
265 }});
266
267 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
268 public Object createStaticService() {
269 IBinder b = ServiceManager.getService(ALARM_SERVICE);
270 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
271 return new AlarmManager(service);
272 }});
273
274 registerService(AUDIO_SERVICE, new ServiceFetcher() {
275 public Object createService(ContextImpl ctx) {
276 return new AudioManager(ctx);
277 }});
278
279 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
280 public Object createService(ContextImpl ctx) {
281 return new ClipboardManager(ctx.getOuterContext(),
282 ctx.mMainThread.getHandler());
283 }});
284
285 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
286 public Object createStaticService() {
287 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
288 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
289 }});
290
291 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
292 public Object createStaticService() {
293 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
294 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
295 }});
296
297 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
298 public Object createService(ContextImpl ctx) {
299 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
300 }});
301
302 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
303 public Object createService(ContextImpl ctx) {
304 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
305 }});
306
Nick Pellyd2507462010-12-13 12:22:34 -0800307 registerService(NFC_SERVICE, new ServiceFetcher() {
308 public Object createService(ContextImpl ctx) {
309 return new NfcManager(ctx);
310 }});
311
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800312 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
313 public Object createStaticService() {
314 return createDropBoxManager();
315 }});
316
317 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
318 public Object createService(ContextImpl ctx) {
319 return InputMethodManager.getInstance(ctx);
320 }});
321
322 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
323 public Object getService(ContextImpl ctx) {
324 // TODO: why isn't this caching it? It wasn't
325 // before, so I'm preserving the old behavior and
326 // using getService(), instead of createService()
327 // which would do the caching.
328 return new KeyguardManager();
329 }});
330
331 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
332 public Object createService(ContextImpl ctx) {
333 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
334 }});
335
336 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
337 public Object createStaticService() {
338 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
339 return new LocationManager(ILocationManager.Stub.asInterface(b));
340 }});
341
342 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
343 public Object createService(ContextImpl ctx) {
344 final Context outerContext = ctx.getOuterContext();
345 return new NotificationManager(
346 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800347 Resources.selectSystemTheme(0,
348 outerContext.getApplicationInfo().targetSdkVersion,
349 com.android.internal.R.style.Theme_Dialog,
350 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800351 ctx.mMainThread.getHandler());
352 }});
353
354 // Note: this was previously cached in a static variable, but
355 // constructed using mMainThread.getHandler(), so converting
356 // it to be a regular Context-cached service...
357 registerService(POWER_SERVICE, new ServiceFetcher() {
358 public Object createService(ContextImpl ctx) {
359 IBinder b = ServiceManager.getService(POWER_SERVICE);
360 IPowerManager service = IPowerManager.Stub.asInterface(b);
361 return new PowerManager(service, ctx.mMainThread.getHandler());
362 }});
363
364 registerService(SEARCH_SERVICE, new ServiceFetcher() {
365 public Object createService(ContextImpl ctx) {
366 return new SearchManager(ctx.getOuterContext(),
367 ctx.mMainThread.getHandler());
368 }});
369
370 registerService(SENSOR_SERVICE, new ServiceFetcher() {
371 public Object createService(ContextImpl ctx) {
372 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
373 }});
374
375 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
376 public Object createService(ContextImpl ctx) {
377 return new StatusBarManager(ctx.getOuterContext());
378 }});
379
380 registerService(STORAGE_SERVICE, new ServiceFetcher() {
381 public Object createService(ContextImpl ctx) {
382 try {
383 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
384 } catch (RemoteException rex) {
385 Log.e(TAG, "Failed to create StorageManager", rex);
386 return null;
387 }
388 }});
389
390 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
391 public Object createService(ContextImpl ctx) {
392 return new TelephonyManager(ctx.getOuterContext());
393 }});
394
395 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
396 public Object createStaticService() {
397 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
398 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
399 }});
400
401 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
402 public Object createService(ContextImpl ctx) {
403 return new UiModeManager();
404 }});
405
Mike Lockwood3a68b832011-03-08 10:08:59 -0500406 registerService(USB_SERVICE, new ServiceFetcher() {
407 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500408 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500409 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500410 }});
411
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800412 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
413 public Object createService(ContextImpl ctx) {
414 return new Vibrator();
415 }});
416
417 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
418
419 registerService(WIFI_SERVICE, new ServiceFetcher() {
420 public Object createService(ContextImpl ctx) {
421 IBinder b = ServiceManager.getService(WIFI_SERVICE);
422 IWifiManager service = IWifiManager.Stub.asInterface(b);
423 return new WifiManager(service, ctx.mMainThread.getHandler());
424 }});
425
426 registerService(WINDOW_SERVICE, new ServiceFetcher() {
427 public Object getService(ContextImpl ctx) {
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700428 CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo();
429 return WindowManagerImpl.getDefault(ci);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800430 }});
431 }
432
433 // The system service cache for the system services that are
434 // cached per-ContextImpl. Package-scoped to avoid accessor
435 // methods.
436 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 @Override
439 public AssetManager getAssets() {
440 return mResources.getAssets();
441 }
442
443 @Override
444 public Resources getResources() {
445 return mResources;
446 }
447
448 @Override
449 public PackageManager getPackageManager() {
450 if (mPackageManager != null) {
451 return mPackageManager;
452 }
453
454 IPackageManager pm = ActivityThread.getPackageManager();
455 if (pm != null) {
456 // Doesn't matter if we make more than one instance.
457 return (mPackageManager = new ApplicationPackageManager(this, pm));
458 }
459
460 return null;
461 }
462
463 @Override
464 public ContentResolver getContentResolver() {
465 return mContentResolver;
466 }
467
468 @Override
469 public Looper getMainLooper() {
470 return mMainThread.getLooper();
471 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 @Override
474 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700475 return (mPackageInfo != null) ?
476 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 @Override
480 public void setTheme(int resid) {
481 mThemeResource = resid;
482 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800484 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800485 public int getThemeResId() {
486 return mThemeResource;
487 }
488
489 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 public Resources.Theme getTheme() {
491 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800492 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
493 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 mTheme = mResources.newTheme();
495 mTheme.applyStyle(mThemeResource, true);
496 }
497 return mTheme;
498 }
499
500 @Override
501 public ClassLoader getClassLoader() {
502 return mPackageInfo != null ?
503 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
504 }
505
506 @Override
507 public String getPackageName() {
508 if (mPackageInfo != null) {
509 return mPackageInfo.getPackageName();
510 }
511 throw new RuntimeException("Not supported in system context");
512 }
513
514 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700515 public ApplicationInfo getApplicationInfo() {
516 if (mPackageInfo != null) {
517 return mPackageInfo.getApplicationInfo();
518 }
519 throw new RuntimeException("Not supported in system context");
520 }
521
522 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 public String getPackageResourcePath() {
524 if (mPackageInfo != null) {
525 return mPackageInfo.getResDir();
526 }
527 throw new RuntimeException("Not supported in system context");
528 }
529
530 @Override
531 public String getPackageCodePath() {
532 if (mPackageInfo != null) {
533 return mPackageInfo.getAppDir();
534 }
535 throw new RuntimeException("Not supported in system context");
536 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200537
Joe Onorato23ecae32009-06-10 17:07:15 -0700538 public File getSharedPrefsFile(String name) {
539 return makeFilename(getPreferencesDir(), name + ".xml");
540 }
541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 @Override
543 public SharedPreferences getSharedPreferences(String name, int mode) {
544 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700546 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700547 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800548 File prefsFile = getSharedPrefsFile(name);
549 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700550 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700551 return sp;
552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800553 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800554 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
555 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
556 // If somebody else (some other process) changed the prefs
557 // file behind our back, we reload it. This has been the
558 // historical (if undocumented) behavior.
559 sp.startReloadIfChangedUnexpectedly();
560 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700561 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 }
563
564 private File getPreferencesDir() {
565 synchronized (mSync) {
566 if (mPreferencesDir == null) {
567 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
568 }
569 return mPreferencesDir;
570 }
571 }
572
573 @Override
574 public FileInputStream openFileInput(String name)
575 throws FileNotFoundException {
576 File f = makeFilename(getFilesDir(), name);
577 return new FileInputStream(f);
578 }
579
580 @Override
581 public FileOutputStream openFileOutput(String name, int mode)
582 throws FileNotFoundException {
583 final boolean append = (mode&MODE_APPEND) != 0;
584 File f = makeFilename(getFilesDir(), name);
585 try {
586 FileOutputStream fos = new FileOutputStream(f, append);
587 setFilePermissionsFromMode(f.getPath(), mode, 0);
588 return fos;
589 } catch (FileNotFoundException e) {
590 }
591
592 File parent = f.getParentFile();
593 parent.mkdir();
594 FileUtils.setPermissions(
595 parent.getPath(),
596 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
597 -1, -1);
598 FileOutputStream fos = new FileOutputStream(f, append);
599 setFilePermissionsFromMode(f.getPath(), mode, 0);
600 return fos;
601 }
602
603 @Override
604 public boolean deleteFile(String name) {
605 File f = makeFilename(getFilesDir(), name);
606 return f.delete();
607 }
608
609 @Override
610 public File getFilesDir() {
611 synchronized (mSync) {
612 if (mFilesDir == null) {
613 mFilesDir = new File(getDataDirFile(), "files");
614 }
615 if (!mFilesDir.exists()) {
616 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200617 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 return null;
619 }
620 FileUtils.setPermissions(
621 mFilesDir.getPath(),
622 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
623 -1, -1);
624 }
625 return mFilesDir;
626 }
627 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800630 public File getExternalFilesDir(String type) {
631 synchronized (mSync) {
632 if (mExternalFilesDir == null) {
633 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
634 getPackageName());
635 }
636 if (!mExternalFilesDir.exists()) {
637 try {
638 (new File(Environment.getExternalStorageAndroidDataDir(),
639 ".nomedia")).createNewFile();
640 } catch (IOException e) {
641 }
642 if (!mExternalFilesDir.mkdirs()) {
643 Log.w(TAG, "Unable to create external files directory");
644 return null;
645 }
646 }
647 if (type == null) {
648 return mExternalFilesDir;
649 }
650 File dir = new File(mExternalFilesDir, type);
651 if (!dir.exists()) {
652 if (!dir.mkdirs()) {
653 Log.w(TAG, "Unable to create external media directory " + dir);
654 return null;
655 }
656 }
657 return dir;
658 }
659 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200660
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800661 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800662 public File getObbDir() {
663 synchronized (mSync) {
664 if (mObbDir == null) {
665 mObbDir = Environment.getExternalStorageAppObbDirectory(
666 getPackageName());
667 }
668 return mObbDir;
669 }
670 }
671
672 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673 public File getCacheDir() {
674 synchronized (mSync) {
675 if (mCacheDir == null) {
676 mCacheDir = new File(getDataDirFile(), "cache");
677 }
678 if (!mCacheDir.exists()) {
679 if(!mCacheDir.mkdirs()) {
680 Log.w(TAG, "Unable to create cache directory");
681 return null;
682 }
683 FileUtils.setPermissions(
684 mCacheDir.getPath(),
685 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
686 -1, -1);
687 }
688 }
689 return mCacheDir;
690 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200691
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800692 @Override
693 public File getExternalCacheDir() {
694 synchronized (mSync) {
695 if (mExternalCacheDir == null) {
696 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
697 getPackageName());
698 }
699 if (!mExternalCacheDir.exists()) {
700 try {
701 (new File(Environment.getExternalStorageAndroidDataDir(),
702 ".nomedia")).createNewFile();
703 } catch (IOException e) {
704 }
705 if (!mExternalCacheDir.mkdirs()) {
706 Log.w(TAG, "Unable to create external cache directory");
707 return null;
708 }
709 }
710 return mExternalCacheDir;
711 }
712 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800714 @Override
715 public File getFileStreamPath(String name) {
716 return makeFilename(getFilesDir(), name);
717 }
718
719 @Override
720 public String[] fileList() {
721 final String[] list = getFilesDir().list();
722 return (list != null) ? list : EMPTY_FILE_LIST;
723 }
724
725 @Override
726 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800727 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800728 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
729 setFilePermissionsFromMode(f.getPath(), mode, 0);
730 return db;
731 }
732
733 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700734 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
735 DatabaseErrorHandler errorHandler) {
736 File f = validateFilePath(name, true);
737 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
738 setFilePermissionsFromMode(f.getPath(), mode, 0);
739 return db;
740 }
741
742 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 public boolean deleteDatabase(String name) {
744 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800745 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 return f.delete();
747 } catch (Exception e) {
748 }
749 return false;
750 }
751
752 @Override
753 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800754 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800755 }
756
757 @Override
758 public String[] databaseList() {
759 final String[] list = getDatabasesDir().list();
760 return (list != null) ? list : EMPTY_FILE_LIST;
761 }
762
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 private File getDatabasesDir() {
765 synchronized (mSync) {
766 if (mDatabasesDir == null) {
767 mDatabasesDir = new File(getDataDirFile(), "databases");
768 }
769 if (mDatabasesDir.getPath().equals("databases")) {
770 mDatabasesDir = new File("/data/system");
771 }
772 return mDatabasesDir;
773 }
774 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 @Override
777 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700778 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 }
780
781 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700782 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700783 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 }
785
786 @Override
787 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700788 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
790
791 @Override
792 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700793 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 }
795
796 @Override
797 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700798 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800
801 @Override
802 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700803 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 }
805
806 @Override
807 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700808 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 }
810
811 @Override
812 public void startActivity(Intent intent) {
813 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
814 throw new AndroidRuntimeException(
815 "Calling startActivity() from outside of an Activity "
816 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
817 + " Is this really what you want?");
818 }
819 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700820 getOuterContext(), mMainThread.getApplicationThread(), null,
821 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800825 public void startActivities(Intent[] intents) {
826 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
827 throw new AndroidRuntimeException(
828 "Calling startActivities() from outside of an Activity "
829 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
830 + " Is this really what you want?");
831 }
832 mMainThread.getInstrumentation().execStartActivities(
833 getOuterContext(), mMainThread.getApplicationThread(), null,
834 (Activity)null, intents);
835 }
836
837 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700838 public void startIntentSender(IntentSender intent,
839 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
840 throws IntentSender.SendIntentException {
841 try {
842 String resolvedType = null;
843 if (fillInIntent != null) {
844 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
845 }
846 int result = ActivityManagerNative.getDefault()
847 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
848 fillInIntent, resolvedType, null, null,
849 0, flagsMask, flagsValues);
850 if (result == IActivityManager.START_CANCELED) {
851 throw new IntentSender.SendIntentException();
852 }
853 Instrumentation.checkStartActivityResult(result, null);
854 } catch (RemoteException e) {
855 }
856 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200857
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700858 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 public void sendBroadcast(Intent intent) {
860 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
861 try {
862 ActivityManagerNative.getDefault().broadcastIntent(
863 mMainThread.getApplicationThread(), intent, resolvedType, null,
864 Activity.RESULT_OK, null, null, null, false, false);
865 } catch (RemoteException e) {
866 }
867 }
868
869 @Override
870 public void sendBroadcast(Intent intent, String receiverPermission) {
871 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
872 try {
873 ActivityManagerNative.getDefault().broadcastIntent(
874 mMainThread.getApplicationThread(), intent, resolvedType, null,
875 Activity.RESULT_OK, null, null, receiverPermission, false, false);
876 } catch (RemoteException e) {
877 }
878 }
879
880 @Override
881 public void sendOrderedBroadcast(Intent intent,
882 String receiverPermission) {
883 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
884 try {
885 ActivityManagerNative.getDefault().broadcastIntent(
886 mMainThread.getApplicationThread(), intent, resolvedType, null,
887 Activity.RESULT_OK, null, null, receiverPermission, true, false);
888 } catch (RemoteException e) {
889 }
890 }
891
892 @Override
893 public void sendOrderedBroadcast(Intent intent,
894 String receiverPermission, BroadcastReceiver resultReceiver,
895 Handler scheduler, int initialCode, String initialData,
896 Bundle initialExtras) {
897 IIntentReceiver rd = null;
898 if (resultReceiver != null) {
899 if (mPackageInfo != null) {
900 if (scheduler == null) {
901 scheduler = mMainThread.getHandler();
902 }
903 rd = mPackageInfo.getReceiverDispatcher(
904 resultReceiver, getOuterContext(), scheduler,
905 mMainThread.getInstrumentation(), false);
906 } else {
907 if (scheduler == null) {
908 scheduler = mMainThread.getHandler();
909 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700910 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
912 }
913 }
914 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
915 try {
916 ActivityManagerNative.getDefault().broadcastIntent(
917 mMainThread.getApplicationThread(), intent, resolvedType, rd,
918 initialCode, initialData, initialExtras, receiverPermission,
919 true, false);
920 } catch (RemoteException e) {
921 }
922 }
923
924 @Override
925 public void sendStickyBroadcast(Intent intent) {
926 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
927 try {
928 ActivityManagerNative.getDefault().broadcastIntent(
929 mMainThread.getApplicationThread(), intent, resolvedType, null,
930 Activity.RESULT_OK, null, null, null, false, true);
931 } catch (RemoteException e) {
932 }
933 }
934
935 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700936 public void sendStickyOrderedBroadcast(Intent intent,
937 BroadcastReceiver resultReceiver,
938 Handler scheduler, int initialCode, String initialData,
939 Bundle initialExtras) {
940 IIntentReceiver rd = null;
941 if (resultReceiver != null) {
942 if (mPackageInfo != null) {
943 if (scheduler == null) {
944 scheduler = mMainThread.getHandler();
945 }
946 rd = mPackageInfo.getReceiverDispatcher(
947 resultReceiver, getOuterContext(), scheduler,
948 mMainThread.getInstrumentation(), false);
949 } else {
950 if (scheduler == null) {
951 scheduler = mMainThread.getHandler();
952 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700953 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700954 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
955 }
956 }
957 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
958 try {
959 ActivityManagerNative.getDefault().broadcastIntent(
960 mMainThread.getApplicationThread(), intent, resolvedType, rd,
961 initialCode, initialData, initialExtras, null,
962 true, true);
963 } catch (RemoteException e) {
964 }
965 }
966
967 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 public void removeStickyBroadcast(Intent intent) {
969 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
970 if (resolvedType != null) {
971 intent = new Intent(intent);
972 intent.setDataAndType(intent.getData(), resolvedType);
973 }
974 try {
975 ActivityManagerNative.getDefault().unbroadcastIntent(
976 mMainThread.getApplicationThread(), intent);
977 } catch (RemoteException e) {
978 }
979 }
980
981 @Override
982 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
983 return registerReceiver(receiver, filter, null, null);
984 }
985
986 @Override
987 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
988 String broadcastPermission, Handler scheduler) {
989 return registerReceiverInternal(receiver, filter, broadcastPermission,
990 scheduler, getOuterContext());
991 }
992
993 private Intent registerReceiverInternal(BroadcastReceiver receiver,
994 IntentFilter filter, String broadcastPermission,
995 Handler scheduler, Context context) {
996 IIntentReceiver rd = null;
997 if (receiver != null) {
998 if (mPackageInfo != null && context != null) {
999 if (scheduler == null) {
1000 scheduler = mMainThread.getHandler();
1001 }
1002 rd = mPackageInfo.getReceiverDispatcher(
1003 receiver, context, scheduler,
1004 mMainThread.getInstrumentation(), true);
1005 } else {
1006 if (scheduler == null) {
1007 scheduler = mMainThread.getHandler();
1008 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001009 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001010 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 }
1012 }
1013 try {
1014 return ActivityManagerNative.getDefault().registerReceiver(
1015 mMainThread.getApplicationThread(),
1016 rd, filter, broadcastPermission);
1017 } catch (RemoteException e) {
1018 return null;
1019 }
1020 }
1021
1022 @Override
1023 public void unregisterReceiver(BroadcastReceiver receiver) {
1024 if (mPackageInfo != null) {
1025 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1026 getOuterContext(), receiver);
1027 try {
1028 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1029 } catch (RemoteException e) {
1030 }
1031 } else {
1032 throw new RuntimeException("Not supported in system context");
1033 }
1034 }
1035
1036 @Override
1037 public ComponentName startService(Intent service) {
1038 try {
1039 ComponentName cn = ActivityManagerNative.getDefault().startService(
1040 mMainThread.getApplicationThread(), service,
1041 service.resolveTypeIfNeeded(getContentResolver()));
1042 if (cn != null && cn.getPackageName().equals("!")) {
1043 throw new SecurityException(
1044 "Not allowed to start service " + service
1045 + " without permission " + cn.getClassName());
1046 }
1047 return cn;
1048 } catch (RemoteException e) {
1049 return null;
1050 }
1051 }
1052
1053 @Override
1054 public boolean stopService(Intent service) {
1055 try {
1056 int res = ActivityManagerNative.getDefault().stopService(
1057 mMainThread.getApplicationThread(), service,
1058 service.resolveTypeIfNeeded(getContentResolver()));
1059 if (res < 0) {
1060 throw new SecurityException(
1061 "Not allowed to stop service " + service);
1062 }
1063 return res != 0;
1064 } catch (RemoteException e) {
1065 return false;
1066 }
1067 }
1068
1069 @Override
1070 public boolean bindService(Intent service, ServiceConnection conn,
1071 int flags) {
1072 IServiceConnection sd;
1073 if (mPackageInfo != null) {
1074 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1075 mMainThread.getHandler(), flags);
1076 } else {
1077 throw new RuntimeException("Not supported in system context");
1078 }
1079 try {
1080 int res = ActivityManagerNative.getDefault().bindService(
1081 mMainThread.getApplicationThread(), getActivityToken(),
1082 service, service.resolveTypeIfNeeded(getContentResolver()),
1083 sd, flags);
1084 if (res < 0) {
1085 throw new SecurityException(
1086 "Not allowed to bind to service " + service);
1087 }
1088 return res != 0;
1089 } catch (RemoteException e) {
1090 return false;
1091 }
1092 }
1093
1094 @Override
1095 public void unbindService(ServiceConnection conn) {
1096 if (mPackageInfo != null) {
1097 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1098 getOuterContext(), conn);
1099 try {
1100 ActivityManagerNative.getDefault().unbindService(sd);
1101 } catch (RemoteException e) {
1102 }
1103 } else {
1104 throw new RuntimeException("Not supported in system context");
1105 }
1106 }
1107
1108 @Override
1109 public boolean startInstrumentation(ComponentName className,
1110 String profileFile, Bundle arguments) {
1111 try {
1112 return ActivityManagerNative.getDefault().startInstrumentation(
1113 className, profileFile, 0, arguments, null);
1114 } catch (RemoteException e) {
1115 // System has crashed, nothing we can do.
1116 }
1117 return false;
1118 }
1119
1120 @Override
1121 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001122 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1123 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 }
1125
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001126 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001127 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 }
1129
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001130 /* package */ static DropBoxManager createDropBoxManager() {
1131 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1132 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001133 if (service == null) {
1134 // Don't return a DropBoxManager that will NPE upon use.
1135 // This also avoids caching a broken DropBoxManager in
1136 // getDropBoxManager during early boot, before the
1137 // DROPBOX_SERVICE is registered.
1138 return null;
1139 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001140 return new DropBoxManager(service);
1141 }
1142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 @Override
1144 public int checkPermission(String permission, int pid, int uid) {
1145 if (permission == null) {
1146 throw new IllegalArgumentException("permission is null");
1147 }
1148
1149 if (!Process.supportsProcesses()) {
1150 return PackageManager.PERMISSION_GRANTED;
1151 }
1152 try {
1153 return ActivityManagerNative.getDefault().checkPermission(
1154 permission, pid, uid);
1155 } catch (RemoteException e) {
1156 return PackageManager.PERMISSION_DENIED;
1157 }
1158 }
1159
1160 @Override
1161 public int checkCallingPermission(String permission) {
1162 if (permission == null) {
1163 throw new IllegalArgumentException("permission is null");
1164 }
1165
1166 if (!Process.supportsProcesses()) {
1167 return PackageManager.PERMISSION_GRANTED;
1168 }
1169 int pid = Binder.getCallingPid();
1170 if (pid != Process.myPid()) {
1171 return checkPermission(permission, pid,
1172 Binder.getCallingUid());
1173 }
1174 return PackageManager.PERMISSION_DENIED;
1175 }
1176
1177 @Override
1178 public int checkCallingOrSelfPermission(String permission) {
1179 if (permission == null) {
1180 throw new IllegalArgumentException("permission is null");
1181 }
1182
1183 return checkPermission(permission, Binder.getCallingPid(),
1184 Binder.getCallingUid());
1185 }
1186
1187 private void enforce(
1188 String permission, int resultOfCheck,
1189 boolean selfToo, int uid, String message) {
1190 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1191 throw new SecurityException(
1192 (message != null ? (message + ": ") : "") +
1193 (selfToo
1194 ? "Neither user " + uid + " nor current process has "
1195 : "User " + uid + " does not have ") +
1196 permission +
1197 ".");
1198 }
1199 }
1200
1201 public void enforcePermission(
1202 String permission, int pid, int uid, String message) {
1203 enforce(permission,
1204 checkPermission(permission, pid, uid),
1205 false,
1206 uid,
1207 message);
1208 }
1209
1210 public void enforceCallingPermission(String permission, String message) {
1211 enforce(permission,
1212 checkCallingPermission(permission),
1213 false,
1214 Binder.getCallingUid(),
1215 message);
1216 }
1217
1218 public void enforceCallingOrSelfPermission(
1219 String permission, String message) {
1220 enforce(permission,
1221 checkCallingOrSelfPermission(permission),
1222 true,
1223 Binder.getCallingUid(),
1224 message);
1225 }
1226
1227 @Override
1228 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1229 try {
1230 ActivityManagerNative.getDefault().grantUriPermission(
1231 mMainThread.getApplicationThread(), toPackage, uri,
1232 modeFlags);
1233 } catch (RemoteException e) {
1234 }
1235 }
1236
1237 @Override
1238 public void revokeUriPermission(Uri uri, int modeFlags) {
1239 try {
1240 ActivityManagerNative.getDefault().revokeUriPermission(
1241 mMainThread.getApplicationThread(), uri,
1242 modeFlags);
1243 } catch (RemoteException e) {
1244 }
1245 }
1246
1247 @Override
1248 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1249 if (!Process.supportsProcesses()) {
1250 return PackageManager.PERMISSION_GRANTED;
1251 }
1252 try {
1253 return ActivityManagerNative.getDefault().checkUriPermission(
1254 uri, pid, uid, modeFlags);
1255 } catch (RemoteException e) {
1256 return PackageManager.PERMISSION_DENIED;
1257 }
1258 }
1259
1260 @Override
1261 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1262 if (!Process.supportsProcesses()) {
1263 return PackageManager.PERMISSION_GRANTED;
1264 }
1265 int pid = Binder.getCallingPid();
1266 if (pid != Process.myPid()) {
1267 return checkUriPermission(uri, pid,
1268 Binder.getCallingUid(), modeFlags);
1269 }
1270 return PackageManager.PERMISSION_DENIED;
1271 }
1272
1273 @Override
1274 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1275 return checkUriPermission(uri, Binder.getCallingPid(),
1276 Binder.getCallingUid(), modeFlags);
1277 }
1278
1279 @Override
1280 public int checkUriPermission(Uri uri, String readPermission,
1281 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001282 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1284 + readPermission + " writePermission=" + writePermission
1285 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1286 }
1287 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1288 if (readPermission == null
1289 || checkPermission(readPermission, pid, uid)
1290 == PackageManager.PERMISSION_GRANTED) {
1291 return PackageManager.PERMISSION_GRANTED;
1292 }
1293 }
1294 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1295 if (writePermission == null
1296 || checkPermission(writePermission, pid, uid)
1297 == PackageManager.PERMISSION_GRANTED) {
1298 return PackageManager.PERMISSION_GRANTED;
1299 }
1300 }
1301 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1302 : PackageManager.PERMISSION_DENIED;
1303 }
1304
1305 private String uriModeFlagToString(int uriModeFlags) {
1306 switch (uriModeFlags) {
1307 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1308 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1309 return "read and write";
1310 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1311 return "read";
1312 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1313 return "write";
1314 }
1315 throw new IllegalArgumentException(
1316 "Unknown permission mode flags: " + uriModeFlags);
1317 }
1318
1319 private void enforceForUri(
1320 int modeFlags, int resultOfCheck, boolean selfToo,
1321 int uid, Uri uri, String message) {
1322 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1323 throw new SecurityException(
1324 (message != null ? (message + ": ") : "") +
1325 (selfToo
1326 ? "Neither user " + uid + " nor current process has "
1327 : "User " + uid + " does not have ") +
1328 uriModeFlagToString(modeFlags) +
1329 " permission on " +
1330 uri +
1331 ".");
1332 }
1333 }
1334
1335 public void enforceUriPermission(
1336 Uri uri, int pid, int uid, int modeFlags, String message) {
1337 enforceForUri(
1338 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1339 false, uid, uri, message);
1340 }
1341
1342 public void enforceCallingUriPermission(
1343 Uri uri, int modeFlags, String message) {
1344 enforceForUri(
1345 modeFlags, checkCallingUriPermission(uri, modeFlags),
1346 false, Binder.getCallingUid(), uri, message);
1347 }
1348
1349 public void enforceCallingOrSelfUriPermission(
1350 Uri uri, int modeFlags, String message) {
1351 enforceForUri(
1352 modeFlags,
1353 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1354 Binder.getCallingUid(), uri, message);
1355 }
1356
1357 public void enforceUriPermission(
1358 Uri uri, String readPermission, String writePermission,
1359 int pid, int uid, int modeFlags, String message) {
1360 enforceForUri(modeFlags,
1361 checkUriPermission(
1362 uri, readPermission, writePermission, pid, uid,
1363 modeFlags),
1364 false,
1365 uid,
1366 uri,
1367 message);
1368 }
1369
1370 @Override
1371 public Context createPackageContext(String packageName, int flags)
1372 throws PackageManager.NameNotFoundException {
1373 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001374 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 }
1376
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001377 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001378 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001380 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001381 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001382 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 if (c.mResources != null) {
1384 return c;
1385 }
1386 }
1387
1388 // Should be a better exception.
1389 throw new PackageManager.NameNotFoundException(
1390 "Application package " + packageName + " not found");
1391 }
1392
Romain Guy870e09f2009-07-06 16:35:25 -07001393 @Override
1394 public boolean isRestricted() {
1395 return mRestricted;
1396 }
1397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 private File getDataDirFile() {
1399 if (mPackageInfo != null) {
1400 return mPackageInfo.getDataDirFile();
1401 }
1402 throw new RuntimeException("Not supported in system context");
1403 }
1404
1405 @Override
1406 public File getDir(String name, int mode) {
1407 name = "app_" + name;
1408 File file = makeFilename(getDataDirFile(), name);
1409 if (!file.exists()) {
1410 file.mkdir();
1411 setFilePermissionsFromMode(file.getPath(), mode,
1412 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1413 }
1414 return file;
1415 }
1416
Dianne Hackborn21556372010-02-04 16:34:40 -08001417 static ContextImpl createSystemContext(ActivityThread mainThread) {
1418 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 context.init(Resources.getSystem(), mainThread);
1420 return context;
1421 }
1422
Dianne Hackborn21556372010-02-04 16:34:40 -08001423 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 mOuterContext = this;
1425 }
1426
1427 /**
1428 * Create a new ApplicationContext from an existing one. The new one
1429 * works and operates the same as the one it is copying.
1430 *
1431 * @param context Existing application context.
1432 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001433 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 mPackageInfo = context.mPackageInfo;
1435 mResources = context.mResources;
1436 mMainThread = context.mMainThread;
1437 mContentResolver = context.mContentResolver;
1438 mOuterContext = this;
1439 }
1440
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001441 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001443 init(packageInfo, activityToken, mainThread, null);
1444 }
1445
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001446 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001447 IBinder activityToken, ActivityThread mainThread,
1448 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 mPackageInfo = packageInfo;
1450 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001451
Dianne Hackborn559a7872010-04-07 18:19:41 -07001452 if (mResources != null && container != null
1453 && container.getCompatibilityInfo().applicationScale !=
1454 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001455 if (DEBUG) {
1456 Log.d(TAG, "loaded context has different scaling. Using container's" +
1457 " compatiblity info:" + container.getDisplayMetrics());
1458 }
1459 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001460 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 mMainThread = mainThread;
1463 mContentResolver = new ApplicationContentResolver(this, mainThread);
1464
1465 setActivityToken(activityToken);
1466 }
1467
1468 final void init(Resources resources, ActivityThread mainThread) {
1469 mPackageInfo = null;
1470 mResources = resources;
1471 mMainThread = mainThread;
1472 mContentResolver = new ApplicationContentResolver(this, mainThread);
1473 }
1474
1475 final void scheduleFinalCleanup(String who, String what) {
1476 mMainThread.scheduleContextCleanup(this, who, what);
1477 }
1478
1479 final void performFinalCleanup(String who, String what) {
1480 //Log.i(TAG, "Cleanup up context: " + this);
1481 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1482 }
1483
1484 final Context getReceiverRestrictedContext() {
1485 if (mReceiverRestrictedContext != null) {
1486 return mReceiverRestrictedContext;
1487 }
1488 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1489 }
1490
1491 final void setActivityToken(IBinder token) {
1492 mActivityToken = token;
1493 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 final void setOuterContext(Context context) {
1496 mOuterContext = context;
1497 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 final Context getOuterContext() {
1500 return mOuterContext;
1501 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 final IBinder getActivityToken() {
1504 return mActivityToken;
1505 }
1506
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001507 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 int extraPermissions) {
1509 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1510 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1511 |extraPermissions;
1512 if ((mode&MODE_WORLD_READABLE) != 0) {
1513 perms |= FileUtils.S_IROTH;
1514 }
1515 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1516 perms |= FileUtils.S_IWOTH;
1517 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001518 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1520 + ", perms=0x" + Integer.toHexString(perms));
1521 }
1522 FileUtils.setPermissions(name, perms, -1, -1);
1523 }
1524
Oscar Montemayora8529f62009-11-18 10:14:20 -08001525 private File validateFilePath(String name, boolean createDirectory) {
1526 File dir;
1527 File f;
1528
1529 if (name.charAt(0) == File.separatorChar) {
1530 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1531 dir = new File(dirPath);
1532 name = name.substring(name.lastIndexOf(File.separatorChar));
1533 f = new File(dir, name);
1534 } else {
1535 dir = getDatabasesDir();
1536 f = makeFilename(dir, name);
1537 }
1538
1539 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1540 FileUtils.setPermissions(dir.getPath(),
1541 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1542 -1, -1);
1543 }
1544
1545 return f;
1546 }
1547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 private File makeFilename(File base, String name) {
1549 if (name.indexOf(File.separatorChar) < 0) {
1550 return new File(base, name);
1551 }
1552 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001553 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 }
1555
1556 // ----------------------------------------------------------------------
1557 // ----------------------------------------------------------------------
1558 // ----------------------------------------------------------------------
1559
1560 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001561 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 super(context);
1563 mMainThread = mainThread;
1564 }
1565
1566 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001567 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 return mMainThread.acquireProvider(context, name);
1569 }
1570
1571 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001572 protected IContentProvider acquireExistingProvider(Context context, String name) {
1573 return mMainThread.acquireExistingProvider(context, name);
1574 }
1575
1576 @Override
1577 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578 return mMainThread.releaseProvider(provider);
1579 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 private final ActivityThread mMainThread;
1582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001583}