blob: 51f1e3d1230708ea2969a0b889141584861338b9 [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 RuntimeException e = new RuntimeException("foo");
429 e.fillInStackTrace();
430 Log.i(TAG, "Getting window manager", e);
431 CompatibilityInfo ci = ctx.mResources.getCompatibilityInfo();
432 return WindowManagerImpl.getDefault(ci);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800433 }});
434 }
435
436 // The system service cache for the system services that are
437 // cached per-ContextImpl. Package-scoped to avoid accessor
438 // methods.
439 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
440
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800441 @Override
442 public AssetManager getAssets() {
443 return mResources.getAssets();
444 }
445
446 @Override
447 public Resources getResources() {
448 return mResources;
449 }
450
451 @Override
452 public PackageManager getPackageManager() {
453 if (mPackageManager != null) {
454 return mPackageManager;
455 }
456
457 IPackageManager pm = ActivityThread.getPackageManager();
458 if (pm != null) {
459 // Doesn't matter if we make more than one instance.
460 return (mPackageManager = new ApplicationPackageManager(this, pm));
461 }
462
463 return null;
464 }
465
466 @Override
467 public ContentResolver getContentResolver() {
468 return mContentResolver;
469 }
470
471 @Override
472 public Looper getMainLooper() {
473 return mMainThread.getLooper();
474 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800476 @Override
477 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700478 return (mPackageInfo != null) ?
479 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 @Override
483 public void setTheme(int resid) {
484 mThemeResource = resid;
485 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800487 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800488 public int getThemeResId() {
489 return mThemeResource;
490 }
491
492 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 public Resources.Theme getTheme() {
494 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800495 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
496 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 mTheme = mResources.newTheme();
498 mTheme.applyStyle(mThemeResource, true);
499 }
500 return mTheme;
501 }
502
503 @Override
504 public ClassLoader getClassLoader() {
505 return mPackageInfo != null ?
506 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
507 }
508
509 @Override
510 public String getPackageName() {
511 if (mPackageInfo != null) {
512 return mPackageInfo.getPackageName();
513 }
514 throw new RuntimeException("Not supported in system context");
515 }
516
517 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700518 public ApplicationInfo getApplicationInfo() {
519 if (mPackageInfo != null) {
520 return mPackageInfo.getApplicationInfo();
521 }
522 throw new RuntimeException("Not supported in system context");
523 }
524
525 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 public String getPackageResourcePath() {
527 if (mPackageInfo != null) {
528 return mPackageInfo.getResDir();
529 }
530 throw new RuntimeException("Not supported in system context");
531 }
532
533 @Override
534 public String getPackageCodePath() {
535 if (mPackageInfo != null) {
536 return mPackageInfo.getAppDir();
537 }
538 throw new RuntimeException("Not supported in system context");
539 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200540
Joe Onorato23ecae32009-06-10 17:07:15 -0700541 public File getSharedPrefsFile(String name) {
542 return makeFilename(getPreferencesDir(), name + ".xml");
543 }
544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 @Override
546 public SharedPreferences getSharedPreferences(String name, int mode) {
547 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700549 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700550 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800551 File prefsFile = getSharedPrefsFile(name);
552 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700553 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700554 return sp;
555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800557 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
558 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
559 // If somebody else (some other process) changed the prefs
560 // file behind our back, we reload it. This has been the
561 // historical (if undocumented) behavior.
562 sp.startReloadIfChangedUnexpectedly();
563 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700564 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 }
566
567 private File getPreferencesDir() {
568 synchronized (mSync) {
569 if (mPreferencesDir == null) {
570 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
571 }
572 return mPreferencesDir;
573 }
574 }
575
576 @Override
577 public FileInputStream openFileInput(String name)
578 throws FileNotFoundException {
579 File f = makeFilename(getFilesDir(), name);
580 return new FileInputStream(f);
581 }
582
583 @Override
584 public FileOutputStream openFileOutput(String name, int mode)
585 throws FileNotFoundException {
586 final boolean append = (mode&MODE_APPEND) != 0;
587 File f = makeFilename(getFilesDir(), name);
588 try {
589 FileOutputStream fos = new FileOutputStream(f, append);
590 setFilePermissionsFromMode(f.getPath(), mode, 0);
591 return fos;
592 } catch (FileNotFoundException e) {
593 }
594
595 File parent = f.getParentFile();
596 parent.mkdir();
597 FileUtils.setPermissions(
598 parent.getPath(),
599 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
600 -1, -1);
601 FileOutputStream fos = new FileOutputStream(f, append);
602 setFilePermissionsFromMode(f.getPath(), mode, 0);
603 return fos;
604 }
605
606 @Override
607 public boolean deleteFile(String name) {
608 File f = makeFilename(getFilesDir(), name);
609 return f.delete();
610 }
611
612 @Override
613 public File getFilesDir() {
614 synchronized (mSync) {
615 if (mFilesDir == null) {
616 mFilesDir = new File(getDataDirFile(), "files");
617 }
618 if (!mFilesDir.exists()) {
619 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200620 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 return null;
622 }
623 FileUtils.setPermissions(
624 mFilesDir.getPath(),
625 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
626 -1, -1);
627 }
628 return mFilesDir;
629 }
630 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800633 public File getExternalFilesDir(String type) {
634 synchronized (mSync) {
635 if (mExternalFilesDir == null) {
636 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
637 getPackageName());
638 }
639 if (!mExternalFilesDir.exists()) {
640 try {
641 (new File(Environment.getExternalStorageAndroidDataDir(),
642 ".nomedia")).createNewFile();
643 } catch (IOException e) {
644 }
645 if (!mExternalFilesDir.mkdirs()) {
646 Log.w(TAG, "Unable to create external files directory");
647 return null;
648 }
649 }
650 if (type == null) {
651 return mExternalFilesDir;
652 }
653 File dir = new File(mExternalFilesDir, type);
654 if (!dir.exists()) {
655 if (!dir.mkdirs()) {
656 Log.w(TAG, "Unable to create external media directory " + dir);
657 return null;
658 }
659 }
660 return dir;
661 }
662 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200663
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800664 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800665 public File getObbDir() {
666 synchronized (mSync) {
667 if (mObbDir == null) {
668 mObbDir = Environment.getExternalStorageAppObbDirectory(
669 getPackageName());
670 }
671 return mObbDir;
672 }
673 }
674
675 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 public File getCacheDir() {
677 synchronized (mSync) {
678 if (mCacheDir == null) {
679 mCacheDir = new File(getDataDirFile(), "cache");
680 }
681 if (!mCacheDir.exists()) {
682 if(!mCacheDir.mkdirs()) {
683 Log.w(TAG, "Unable to create cache directory");
684 return null;
685 }
686 FileUtils.setPermissions(
687 mCacheDir.getPath(),
688 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
689 -1, -1);
690 }
691 }
692 return mCacheDir;
693 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200694
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800695 @Override
696 public File getExternalCacheDir() {
697 synchronized (mSync) {
698 if (mExternalCacheDir == null) {
699 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
700 getPackageName());
701 }
702 if (!mExternalCacheDir.exists()) {
703 try {
704 (new File(Environment.getExternalStorageAndroidDataDir(),
705 ".nomedia")).createNewFile();
706 } catch (IOException e) {
707 }
708 if (!mExternalCacheDir.mkdirs()) {
709 Log.w(TAG, "Unable to create external cache directory");
710 return null;
711 }
712 }
713 return mExternalCacheDir;
714 }
715 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 @Override
718 public File getFileStreamPath(String name) {
719 return makeFilename(getFilesDir(), name);
720 }
721
722 @Override
723 public String[] fileList() {
724 final String[] list = getFilesDir().list();
725 return (list != null) ? list : EMPTY_FILE_LIST;
726 }
727
728 @Override
729 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800730 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
732 setFilePermissionsFromMode(f.getPath(), mode, 0);
733 return db;
734 }
735
736 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700737 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
738 DatabaseErrorHandler errorHandler) {
739 File f = validateFilePath(name, true);
740 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
741 setFilePermissionsFromMode(f.getPath(), mode, 0);
742 return db;
743 }
744
745 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 public boolean deleteDatabase(String name) {
747 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800748 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 return f.delete();
750 } catch (Exception e) {
751 }
752 return false;
753 }
754
755 @Override
756 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800757 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 }
759
760 @Override
761 public String[] databaseList() {
762 final String[] list = getDatabasesDir().list();
763 return (list != null) ? list : EMPTY_FILE_LIST;
764 }
765
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 private File getDatabasesDir() {
768 synchronized (mSync) {
769 if (mDatabasesDir == null) {
770 mDatabasesDir = new File(getDataDirFile(), "databases");
771 }
772 if (mDatabasesDir.getPath().equals("databases")) {
773 mDatabasesDir = new File("/data/system");
774 }
775 return mDatabasesDir;
776 }
777 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200778
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 @Override
780 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700781 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 }
783
784 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700785 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700786 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788
789 @Override
790 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700791 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 }
793
794 @Override
795 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700796 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 }
798
799 @Override
800 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700801 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 }
803
804 @Override
805 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700806 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
808
809 @Override
810 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700811 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 }
813
814 @Override
815 public void startActivity(Intent intent) {
816 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
817 throw new AndroidRuntimeException(
818 "Calling startActivity() from outside of an Activity "
819 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
820 + " Is this really what you want?");
821 }
822 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700823 getOuterContext(), mMainThread.getApplicationThread(), null,
824 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 }
826
827 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800828 public void startActivities(Intent[] intents) {
829 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
830 throw new AndroidRuntimeException(
831 "Calling startActivities() from outside of an Activity "
832 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
833 + " Is this really what you want?");
834 }
835 mMainThread.getInstrumentation().execStartActivities(
836 getOuterContext(), mMainThread.getApplicationThread(), null,
837 (Activity)null, intents);
838 }
839
840 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700841 public void startIntentSender(IntentSender intent,
842 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
843 throws IntentSender.SendIntentException {
844 try {
845 String resolvedType = null;
846 if (fillInIntent != null) {
847 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
848 }
849 int result = ActivityManagerNative.getDefault()
850 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
851 fillInIntent, resolvedType, null, null,
852 0, flagsMask, flagsValues);
853 if (result == IActivityManager.START_CANCELED) {
854 throw new IntentSender.SendIntentException();
855 }
856 Instrumentation.checkStartActivityResult(result, null);
857 } catch (RemoteException e) {
858 }
859 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200860
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700861 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 public void sendBroadcast(Intent intent) {
863 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
864 try {
865 ActivityManagerNative.getDefault().broadcastIntent(
866 mMainThread.getApplicationThread(), intent, resolvedType, null,
867 Activity.RESULT_OK, null, null, null, false, false);
868 } catch (RemoteException e) {
869 }
870 }
871
872 @Override
873 public void sendBroadcast(Intent intent, String receiverPermission) {
874 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
875 try {
876 ActivityManagerNative.getDefault().broadcastIntent(
877 mMainThread.getApplicationThread(), intent, resolvedType, null,
878 Activity.RESULT_OK, null, null, receiverPermission, false, false);
879 } catch (RemoteException e) {
880 }
881 }
882
883 @Override
884 public void sendOrderedBroadcast(Intent intent,
885 String receiverPermission) {
886 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
887 try {
888 ActivityManagerNative.getDefault().broadcastIntent(
889 mMainThread.getApplicationThread(), intent, resolvedType, null,
890 Activity.RESULT_OK, null, null, receiverPermission, true, false);
891 } catch (RemoteException e) {
892 }
893 }
894
895 @Override
896 public void sendOrderedBroadcast(Intent intent,
897 String receiverPermission, BroadcastReceiver resultReceiver,
898 Handler scheduler, int initialCode, String initialData,
899 Bundle initialExtras) {
900 IIntentReceiver rd = null;
901 if (resultReceiver != null) {
902 if (mPackageInfo != null) {
903 if (scheduler == null) {
904 scheduler = mMainThread.getHandler();
905 }
906 rd = mPackageInfo.getReceiverDispatcher(
907 resultReceiver, getOuterContext(), scheduler,
908 mMainThread.getInstrumentation(), false);
909 } else {
910 if (scheduler == null) {
911 scheduler = mMainThread.getHandler();
912 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700913 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
915 }
916 }
917 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
918 try {
919 ActivityManagerNative.getDefault().broadcastIntent(
920 mMainThread.getApplicationThread(), intent, resolvedType, rd,
921 initialCode, initialData, initialExtras, receiverPermission,
922 true, false);
923 } catch (RemoteException e) {
924 }
925 }
926
927 @Override
928 public void sendStickyBroadcast(Intent intent) {
929 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
930 try {
931 ActivityManagerNative.getDefault().broadcastIntent(
932 mMainThread.getApplicationThread(), intent, resolvedType, null,
933 Activity.RESULT_OK, null, null, null, false, true);
934 } catch (RemoteException e) {
935 }
936 }
937
938 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700939 public void sendStickyOrderedBroadcast(Intent intent,
940 BroadcastReceiver resultReceiver,
941 Handler scheduler, int initialCode, String initialData,
942 Bundle initialExtras) {
943 IIntentReceiver rd = null;
944 if (resultReceiver != null) {
945 if (mPackageInfo != null) {
946 if (scheduler == null) {
947 scheduler = mMainThread.getHandler();
948 }
949 rd = mPackageInfo.getReceiverDispatcher(
950 resultReceiver, getOuterContext(), scheduler,
951 mMainThread.getInstrumentation(), false);
952 } else {
953 if (scheduler == null) {
954 scheduler = mMainThread.getHandler();
955 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700956 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700957 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
958 }
959 }
960 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
961 try {
962 ActivityManagerNative.getDefault().broadcastIntent(
963 mMainThread.getApplicationThread(), intent, resolvedType, rd,
964 initialCode, initialData, initialExtras, null,
965 true, true);
966 } catch (RemoteException e) {
967 }
968 }
969
970 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 public void removeStickyBroadcast(Intent intent) {
972 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
973 if (resolvedType != null) {
974 intent = new Intent(intent);
975 intent.setDataAndType(intent.getData(), resolvedType);
976 }
977 try {
978 ActivityManagerNative.getDefault().unbroadcastIntent(
979 mMainThread.getApplicationThread(), intent);
980 } catch (RemoteException e) {
981 }
982 }
983
984 @Override
985 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
986 return registerReceiver(receiver, filter, null, null);
987 }
988
989 @Override
990 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
991 String broadcastPermission, Handler scheduler) {
992 return registerReceiverInternal(receiver, filter, broadcastPermission,
993 scheduler, getOuterContext());
994 }
995
996 private Intent registerReceiverInternal(BroadcastReceiver receiver,
997 IntentFilter filter, String broadcastPermission,
998 Handler scheduler, Context context) {
999 IIntentReceiver rd = null;
1000 if (receiver != null) {
1001 if (mPackageInfo != null && context != null) {
1002 if (scheduler == null) {
1003 scheduler = mMainThread.getHandler();
1004 }
1005 rd = mPackageInfo.getReceiverDispatcher(
1006 receiver, context, scheduler,
1007 mMainThread.getInstrumentation(), true);
1008 } else {
1009 if (scheduler == null) {
1010 scheduler = mMainThread.getHandler();
1011 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001012 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001013 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 }
1015 }
1016 try {
1017 return ActivityManagerNative.getDefault().registerReceiver(
1018 mMainThread.getApplicationThread(),
1019 rd, filter, broadcastPermission);
1020 } catch (RemoteException e) {
1021 return null;
1022 }
1023 }
1024
1025 @Override
1026 public void unregisterReceiver(BroadcastReceiver receiver) {
1027 if (mPackageInfo != null) {
1028 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1029 getOuterContext(), receiver);
1030 try {
1031 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1032 } catch (RemoteException e) {
1033 }
1034 } else {
1035 throw new RuntimeException("Not supported in system context");
1036 }
1037 }
1038
1039 @Override
1040 public ComponentName startService(Intent service) {
1041 try {
1042 ComponentName cn = ActivityManagerNative.getDefault().startService(
1043 mMainThread.getApplicationThread(), service,
1044 service.resolveTypeIfNeeded(getContentResolver()));
1045 if (cn != null && cn.getPackageName().equals("!")) {
1046 throw new SecurityException(
1047 "Not allowed to start service " + service
1048 + " without permission " + cn.getClassName());
1049 }
1050 return cn;
1051 } catch (RemoteException e) {
1052 return null;
1053 }
1054 }
1055
1056 @Override
1057 public boolean stopService(Intent service) {
1058 try {
1059 int res = ActivityManagerNative.getDefault().stopService(
1060 mMainThread.getApplicationThread(), service,
1061 service.resolveTypeIfNeeded(getContentResolver()));
1062 if (res < 0) {
1063 throw new SecurityException(
1064 "Not allowed to stop service " + service);
1065 }
1066 return res != 0;
1067 } catch (RemoteException e) {
1068 return false;
1069 }
1070 }
1071
1072 @Override
1073 public boolean bindService(Intent service, ServiceConnection conn,
1074 int flags) {
1075 IServiceConnection sd;
1076 if (mPackageInfo != null) {
1077 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1078 mMainThread.getHandler(), flags);
1079 } else {
1080 throw new RuntimeException("Not supported in system context");
1081 }
1082 try {
1083 int res = ActivityManagerNative.getDefault().bindService(
1084 mMainThread.getApplicationThread(), getActivityToken(),
1085 service, service.resolveTypeIfNeeded(getContentResolver()),
1086 sd, flags);
1087 if (res < 0) {
1088 throw new SecurityException(
1089 "Not allowed to bind to service " + service);
1090 }
1091 return res != 0;
1092 } catch (RemoteException e) {
1093 return false;
1094 }
1095 }
1096
1097 @Override
1098 public void unbindService(ServiceConnection conn) {
1099 if (mPackageInfo != null) {
1100 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1101 getOuterContext(), conn);
1102 try {
1103 ActivityManagerNative.getDefault().unbindService(sd);
1104 } catch (RemoteException e) {
1105 }
1106 } else {
1107 throw new RuntimeException("Not supported in system context");
1108 }
1109 }
1110
1111 @Override
1112 public boolean startInstrumentation(ComponentName className,
1113 String profileFile, Bundle arguments) {
1114 try {
1115 return ActivityManagerNative.getDefault().startInstrumentation(
1116 className, profileFile, 0, arguments, null);
1117 } catch (RemoteException e) {
1118 // System has crashed, nothing we can do.
1119 }
1120 return false;
1121 }
1122
1123 @Override
1124 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001125 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1126 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 }
1128
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001129 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001130 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 }
1132
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001133 /* package */ static DropBoxManager createDropBoxManager() {
1134 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1135 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001136 if (service == null) {
1137 // Don't return a DropBoxManager that will NPE upon use.
1138 // This also avoids caching a broken DropBoxManager in
1139 // getDropBoxManager during early boot, before the
1140 // DROPBOX_SERVICE is registered.
1141 return null;
1142 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001143 return new DropBoxManager(service);
1144 }
1145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001146 @Override
1147 public int checkPermission(String permission, int pid, int uid) {
1148 if (permission == null) {
1149 throw new IllegalArgumentException("permission is null");
1150 }
1151
1152 if (!Process.supportsProcesses()) {
1153 return PackageManager.PERMISSION_GRANTED;
1154 }
1155 try {
1156 return ActivityManagerNative.getDefault().checkPermission(
1157 permission, pid, uid);
1158 } catch (RemoteException e) {
1159 return PackageManager.PERMISSION_DENIED;
1160 }
1161 }
1162
1163 @Override
1164 public int checkCallingPermission(String permission) {
1165 if (permission == null) {
1166 throw new IllegalArgumentException("permission is null");
1167 }
1168
1169 if (!Process.supportsProcesses()) {
1170 return PackageManager.PERMISSION_GRANTED;
1171 }
1172 int pid = Binder.getCallingPid();
1173 if (pid != Process.myPid()) {
1174 return checkPermission(permission, pid,
1175 Binder.getCallingUid());
1176 }
1177 return PackageManager.PERMISSION_DENIED;
1178 }
1179
1180 @Override
1181 public int checkCallingOrSelfPermission(String permission) {
1182 if (permission == null) {
1183 throw new IllegalArgumentException("permission is null");
1184 }
1185
1186 return checkPermission(permission, Binder.getCallingPid(),
1187 Binder.getCallingUid());
1188 }
1189
1190 private void enforce(
1191 String permission, int resultOfCheck,
1192 boolean selfToo, int uid, String message) {
1193 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1194 throw new SecurityException(
1195 (message != null ? (message + ": ") : "") +
1196 (selfToo
1197 ? "Neither user " + uid + " nor current process has "
1198 : "User " + uid + " does not have ") +
1199 permission +
1200 ".");
1201 }
1202 }
1203
1204 public void enforcePermission(
1205 String permission, int pid, int uid, String message) {
1206 enforce(permission,
1207 checkPermission(permission, pid, uid),
1208 false,
1209 uid,
1210 message);
1211 }
1212
1213 public void enforceCallingPermission(String permission, String message) {
1214 enforce(permission,
1215 checkCallingPermission(permission),
1216 false,
1217 Binder.getCallingUid(),
1218 message);
1219 }
1220
1221 public void enforceCallingOrSelfPermission(
1222 String permission, String message) {
1223 enforce(permission,
1224 checkCallingOrSelfPermission(permission),
1225 true,
1226 Binder.getCallingUid(),
1227 message);
1228 }
1229
1230 @Override
1231 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1232 try {
1233 ActivityManagerNative.getDefault().grantUriPermission(
1234 mMainThread.getApplicationThread(), toPackage, uri,
1235 modeFlags);
1236 } catch (RemoteException e) {
1237 }
1238 }
1239
1240 @Override
1241 public void revokeUriPermission(Uri uri, int modeFlags) {
1242 try {
1243 ActivityManagerNative.getDefault().revokeUriPermission(
1244 mMainThread.getApplicationThread(), uri,
1245 modeFlags);
1246 } catch (RemoteException e) {
1247 }
1248 }
1249
1250 @Override
1251 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1252 if (!Process.supportsProcesses()) {
1253 return PackageManager.PERMISSION_GRANTED;
1254 }
1255 try {
1256 return ActivityManagerNative.getDefault().checkUriPermission(
1257 uri, pid, uid, modeFlags);
1258 } catch (RemoteException e) {
1259 return PackageManager.PERMISSION_DENIED;
1260 }
1261 }
1262
1263 @Override
1264 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1265 if (!Process.supportsProcesses()) {
1266 return PackageManager.PERMISSION_GRANTED;
1267 }
1268 int pid = Binder.getCallingPid();
1269 if (pid != Process.myPid()) {
1270 return checkUriPermission(uri, pid,
1271 Binder.getCallingUid(), modeFlags);
1272 }
1273 return PackageManager.PERMISSION_DENIED;
1274 }
1275
1276 @Override
1277 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1278 return checkUriPermission(uri, Binder.getCallingPid(),
1279 Binder.getCallingUid(), modeFlags);
1280 }
1281
1282 @Override
1283 public int checkUriPermission(Uri uri, String readPermission,
1284 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001285 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1287 + readPermission + " writePermission=" + writePermission
1288 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1289 }
1290 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1291 if (readPermission == null
1292 || checkPermission(readPermission, pid, uid)
1293 == PackageManager.PERMISSION_GRANTED) {
1294 return PackageManager.PERMISSION_GRANTED;
1295 }
1296 }
1297 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1298 if (writePermission == null
1299 || checkPermission(writePermission, pid, uid)
1300 == PackageManager.PERMISSION_GRANTED) {
1301 return PackageManager.PERMISSION_GRANTED;
1302 }
1303 }
1304 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1305 : PackageManager.PERMISSION_DENIED;
1306 }
1307
1308 private String uriModeFlagToString(int uriModeFlags) {
1309 switch (uriModeFlags) {
1310 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1311 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1312 return "read and write";
1313 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1314 return "read";
1315 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1316 return "write";
1317 }
1318 throw new IllegalArgumentException(
1319 "Unknown permission mode flags: " + uriModeFlags);
1320 }
1321
1322 private void enforceForUri(
1323 int modeFlags, int resultOfCheck, boolean selfToo,
1324 int uid, Uri uri, String message) {
1325 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1326 throw new SecurityException(
1327 (message != null ? (message + ": ") : "") +
1328 (selfToo
1329 ? "Neither user " + uid + " nor current process has "
1330 : "User " + uid + " does not have ") +
1331 uriModeFlagToString(modeFlags) +
1332 " permission on " +
1333 uri +
1334 ".");
1335 }
1336 }
1337
1338 public void enforceUriPermission(
1339 Uri uri, int pid, int uid, int modeFlags, String message) {
1340 enforceForUri(
1341 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1342 false, uid, uri, message);
1343 }
1344
1345 public void enforceCallingUriPermission(
1346 Uri uri, int modeFlags, String message) {
1347 enforceForUri(
1348 modeFlags, checkCallingUriPermission(uri, modeFlags),
1349 false, Binder.getCallingUid(), uri, message);
1350 }
1351
1352 public void enforceCallingOrSelfUriPermission(
1353 Uri uri, int modeFlags, String message) {
1354 enforceForUri(
1355 modeFlags,
1356 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1357 Binder.getCallingUid(), uri, message);
1358 }
1359
1360 public void enforceUriPermission(
1361 Uri uri, String readPermission, String writePermission,
1362 int pid, int uid, int modeFlags, String message) {
1363 enforceForUri(modeFlags,
1364 checkUriPermission(
1365 uri, readPermission, writePermission, pid, uid,
1366 modeFlags),
1367 false,
1368 uid,
1369 uri,
1370 message);
1371 }
1372
1373 @Override
1374 public Context createPackageContext(String packageName, int flags)
1375 throws PackageManager.NameNotFoundException {
1376 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001377 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 }
1379
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001380 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001381 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001382 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001383 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001384 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001385 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 if (c.mResources != null) {
1387 return c;
1388 }
1389 }
1390
1391 // Should be a better exception.
1392 throw new PackageManager.NameNotFoundException(
1393 "Application package " + packageName + " not found");
1394 }
1395
Romain Guy870e09f2009-07-06 16:35:25 -07001396 @Override
1397 public boolean isRestricted() {
1398 return mRestricted;
1399 }
1400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 private File getDataDirFile() {
1402 if (mPackageInfo != null) {
1403 return mPackageInfo.getDataDirFile();
1404 }
1405 throw new RuntimeException("Not supported in system context");
1406 }
1407
1408 @Override
1409 public File getDir(String name, int mode) {
1410 name = "app_" + name;
1411 File file = makeFilename(getDataDirFile(), name);
1412 if (!file.exists()) {
1413 file.mkdir();
1414 setFilePermissionsFromMode(file.getPath(), mode,
1415 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1416 }
1417 return file;
1418 }
1419
Dianne Hackborn21556372010-02-04 16:34:40 -08001420 static ContextImpl createSystemContext(ActivityThread mainThread) {
1421 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 context.init(Resources.getSystem(), mainThread);
1423 return context;
1424 }
1425
Dianne Hackborn21556372010-02-04 16:34:40 -08001426 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 mOuterContext = this;
1428 }
1429
1430 /**
1431 * Create a new ApplicationContext from an existing one. The new one
1432 * works and operates the same as the one it is copying.
1433 *
1434 * @param context Existing application context.
1435 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001436 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001437 mPackageInfo = context.mPackageInfo;
1438 mResources = context.mResources;
1439 mMainThread = context.mMainThread;
1440 mContentResolver = context.mContentResolver;
1441 mOuterContext = this;
1442 }
1443
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001444 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001446 init(packageInfo, activityToken, mainThread, null);
1447 }
1448
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001449 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001450 IBinder activityToken, ActivityThread mainThread,
1451 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 mPackageInfo = packageInfo;
1453 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001454
Dianne Hackborn559a7872010-04-07 18:19:41 -07001455 if (mResources != null && container != null
1456 && container.getCompatibilityInfo().applicationScale !=
1457 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001458 if (DEBUG) {
1459 Log.d(TAG, "loaded context has different scaling. Using container's" +
1460 " compatiblity info:" + container.getDisplayMetrics());
1461 }
1462 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001463 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 mMainThread = mainThread;
1466 mContentResolver = new ApplicationContentResolver(this, mainThread);
1467
1468 setActivityToken(activityToken);
1469 }
1470
1471 final void init(Resources resources, ActivityThread mainThread) {
1472 mPackageInfo = null;
1473 mResources = resources;
1474 mMainThread = mainThread;
1475 mContentResolver = new ApplicationContentResolver(this, mainThread);
1476 }
1477
1478 final void scheduleFinalCleanup(String who, String what) {
1479 mMainThread.scheduleContextCleanup(this, who, what);
1480 }
1481
1482 final void performFinalCleanup(String who, String what) {
1483 //Log.i(TAG, "Cleanup up context: " + this);
1484 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1485 }
1486
1487 final Context getReceiverRestrictedContext() {
1488 if (mReceiverRestrictedContext != null) {
1489 return mReceiverRestrictedContext;
1490 }
1491 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1492 }
1493
1494 final void setActivityToken(IBinder token) {
1495 mActivityToken = token;
1496 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001497
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 final void setOuterContext(Context context) {
1499 mOuterContext = context;
1500 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 final Context getOuterContext() {
1503 return mOuterContext;
1504 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 final IBinder getActivityToken() {
1507 return mActivityToken;
1508 }
1509
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001510 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 int extraPermissions) {
1512 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1513 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1514 |extraPermissions;
1515 if ((mode&MODE_WORLD_READABLE) != 0) {
1516 perms |= FileUtils.S_IROTH;
1517 }
1518 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1519 perms |= FileUtils.S_IWOTH;
1520 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001521 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1523 + ", perms=0x" + Integer.toHexString(perms));
1524 }
1525 FileUtils.setPermissions(name, perms, -1, -1);
1526 }
1527
Oscar Montemayora8529f62009-11-18 10:14:20 -08001528 private File validateFilePath(String name, boolean createDirectory) {
1529 File dir;
1530 File f;
1531
1532 if (name.charAt(0) == File.separatorChar) {
1533 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1534 dir = new File(dirPath);
1535 name = name.substring(name.lastIndexOf(File.separatorChar));
1536 f = new File(dir, name);
1537 } else {
1538 dir = getDatabasesDir();
1539 f = makeFilename(dir, name);
1540 }
1541
1542 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1543 FileUtils.setPermissions(dir.getPath(),
1544 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1545 -1, -1);
1546 }
1547
1548 return f;
1549 }
1550
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 private File makeFilename(File base, String name) {
1552 if (name.indexOf(File.separatorChar) < 0) {
1553 return new File(base, name);
1554 }
1555 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001556 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 }
1558
1559 // ----------------------------------------------------------------------
1560 // ----------------------------------------------------------------------
1561 // ----------------------------------------------------------------------
1562
1563 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001564 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 super(context);
1566 mMainThread = mainThread;
1567 }
1568
1569 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001570 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 return mMainThread.acquireProvider(context, name);
1572 }
1573
1574 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001575 protected IContentProvider acquireExistingProvider(Context context, String name) {
1576 return mMainThread.acquireExistingProvider(context, name);
1577 }
1578
1579 @Override
1580 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 return mMainThread.releaseProvider(provider);
1582 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001584 private final ActivityThread mMainThread;
1585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586}