blob: 083612e1d4cfe4386cc2abdfb2ff3010df0b0d25 [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;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080020import com.android.internal.util.XmlUtils;
svetoslavganov75986cf2009-05-14 22:28:01 -070021
22import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.ContextWrapper;
29import android.content.IContentProvider;
30import android.content.Intent;
31import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070032import android.content.IIntentReceiver;
33import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.ReceiverCallNotAllowedException;
35import android.content.ServiceConnection;
36import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.pm.ApplicationInfo;
38import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070039import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.content.pm.IPackageDataObserver;
41import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080043import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070045import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.PackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.content.res.AssetManager;
48import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070049import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.database.sqlite.SQLiteDatabase;
51import android.database.sqlite.SQLiteDatabase.CursorFactory;
52import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.graphics.drawable.Drawable;
54import android.hardware.SensorManager;
Bai Taoa58a8752010-07-13 15:32:16 +080055import android.location.CountryDetector;
56import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.location.ILocationManager;
58import android.location.LocationManager;
59import android.media.AudioManager;
60import android.net.ConnectivityManager;
61import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070062import android.net.ThrottleManager;
63import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.net.Uri;
65import android.net.wifi.IWifiManager;
66import android.net.wifi.WifiManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080067import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.os.Binder;
Adam Powellc63806d2010-09-23 16:21:30 -070069import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080071import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080072import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.FileUtils;
74import android.os.Handler;
75import android.os.IBinder;
76import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070077import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.os.PowerManager;
79import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070080import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.ServiceManager;
82import android.os.Vibrator;
83import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080084import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070086import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.util.AndroidRuntimeException;
88import android.util.Log;
89import android.view.ContextThemeWrapper;
90import android.view.LayoutInflater;
91import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070092import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070094import android.accounts.AccountManager;
95import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080096import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080097import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import java.io.File;
100import java.io.FileInputStream;
101import java.io.FileNotFoundException;
102import java.io.FileOutputStream;
103import java.io.IOException;
104import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import java.util.ArrayList;
106import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import java.util.List;
108import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700109import java.util.Set;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111class ReceiverRestrictedContext extends ContextWrapper {
112 ReceiverRestrictedContext(Context base) {
113 super(base);
114 }
115
116 @Override
117 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
118 return registerReceiver(receiver, filter, null, null);
119 }
120
121 @Override
122 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
123 String broadcastPermission, Handler scheduler) {
124 throw new ReceiverCallNotAllowedException(
125 "IntentReceiver components are not allowed to register to receive intents");
126 //ex.fillInStackTrace();
127 //Log.e("IntentReceiver", ex.getMessage(), ex);
128 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
129 // scheduler);
130 }
131
132 @Override
133 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
134 throw new ReceiverCallNotAllowedException(
135 "IntentReceiver components are not allowed to bind to services");
136 //ex.fillInStackTrace();
137 //Log.e("IntentReceiver", ex.getMessage(), ex);
138 //return mContext.bindService(service, interfaceName, conn, flags);
139 }
140}
141
142/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800143 * Common implementation of Context API, which provides the base
144 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800146class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700148 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700150 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
151 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700153 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154 private Resources mResources;
155 /*package*/ ActivityThread mMainThread;
156 private Context mOuterContext;
157 private IBinder mActivityToken = null;
158 private ApplicationContentResolver mContentResolver;
159 private int mThemeResource = 0;
160 private Resources.Theme mTheme = null;
161 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700163 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
165 private final Object mSync = new Object();
166
167 private File mDatabasesDir;
168 private File mPreferencesDir;
169 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800171 private File mExternalFilesDir;
172 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200173
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 private static final String[] EMPTY_FILE_LIST = {};
175
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800176 /**
177 * Override this class when the system service constructor needs a
178 * ContextImpl. Else, use StaticServiceFetcher below.
179 */
180 /*package*/ static class ServiceFetcher {
181 int mContextCacheIndex = -1;
182
183 /**
184 * Main entrypoint; only override if you don't need caching.
185 */
186 public Object getService(ContextImpl ctx) {
187 ArrayList<Object> cache = ctx.mServiceCache;
188 Object service;
189 synchronized (cache) {
190 if (cache.size() == 0) {
191 // Initialize the cache vector on first access.
192 // At this point sNextPerContextServiceCacheIndex
193 // is the number of potential services that are
194 // cached per-Context.
195 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
196 cache.add(null);
197 }
198 } else {
199 service = cache.get(mContextCacheIndex);
200 if (service != null) {
201 return service;
202 }
203 }
204 service = createService(ctx);
205 cache.set(mContextCacheIndex, service);
206 return service;
207 }
208 }
209
210 /**
211 * Override this to create a new per-Context instance of the
212 * service. getService() will handle locking and caching.
213 */
214 public Object createService(ContextImpl ctx) {
215 throw new RuntimeException("Not implemented");
216 }
217 }
218
219 /**
220 * Override this class for services to be cached process-wide.
221 */
222 abstract static class StaticServiceFetcher extends ServiceFetcher {
223 private Object mCachedInstance;
224
225 @Override
226 public final Object getService(ContextImpl unused) {
227 synchronized (StaticServiceFetcher.this) {
228 Object service = mCachedInstance;
229 if (service != null) {
230 return service;
231 }
232 return mCachedInstance = createStaticService();
233 }
234 }
235
236 public abstract Object createStaticService();
237 }
238
239 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
240 new HashMap<String, ServiceFetcher>();
241
242 private static int sNextPerContextServiceCacheIndex = 0;
243 private static void registerService(String serviceName, ServiceFetcher fetcher) {
244 if (!(fetcher instanceof StaticServiceFetcher)) {
245 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
246 }
247 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
248 }
249
250 // This one's defined separately and given a variable name so it
251 // can be re-used by getWallpaperManager(), avoiding a HashMap
252 // lookup.
253 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
254 public Object createService(ContextImpl ctx) {
255 return new WallpaperManager(ctx.getOuterContext(),
256 ctx.mMainThread.getHandler());
257 }};
258
259 static {
260 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
261 public Object getService(ContextImpl ctx) {
262 return AccessibilityManager.getInstance(ctx);
263 }});
264
265 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
266 public Object createService(ContextImpl ctx) {
267 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
268 IAccountManager service = IAccountManager.Stub.asInterface(b);
269 return new AccountManager(ctx, service);
270 }});
271
272 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
273 public Object createService(ContextImpl ctx) {
274 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
275 }});
276
277 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
278 public Object createStaticService() {
279 IBinder b = ServiceManager.getService(ALARM_SERVICE);
280 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
281 return new AlarmManager(service);
282 }});
283
284 registerService(AUDIO_SERVICE, new ServiceFetcher() {
285 public Object createService(ContextImpl ctx) {
286 return new AudioManager(ctx);
287 }});
288
289 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
290 public Object createService(ContextImpl ctx) {
291 return new ClipboardManager(ctx.getOuterContext(),
292 ctx.mMainThread.getHandler());
293 }});
294
295 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
296 public Object createStaticService() {
297 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
298 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
299 }});
300
301 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
302 public Object createStaticService() {
303 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
304 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
305 }});
306
307 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
308 public Object createService(ContextImpl ctx) {
309 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
310 }});
311
312 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
313 public Object createService(ContextImpl ctx) {
314 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
315 }});
316
Nick Pellyd2507462010-12-13 12:22:34 -0800317 registerService(NFC_SERVICE, new ServiceFetcher() {
318 public Object createService(ContextImpl ctx) {
319 return new NfcManager(ctx);
320 }});
321
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800322 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
323 public Object createStaticService() {
324 return createDropBoxManager();
325 }});
326
327 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
328 public Object createService(ContextImpl ctx) {
329 return InputMethodManager.getInstance(ctx);
330 }});
331
332 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
333 public Object getService(ContextImpl ctx) {
334 // TODO: why isn't this caching it? It wasn't
335 // before, so I'm preserving the old behavior and
336 // using getService(), instead of createService()
337 // which would do the caching.
338 return new KeyguardManager();
339 }});
340
341 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
342 public Object createService(ContextImpl ctx) {
343 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
344 }});
345
346 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
347 public Object createStaticService() {
348 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
349 return new LocationManager(ILocationManager.Stub.asInterface(b));
350 }});
351
352 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
353 public Object createService(ContextImpl ctx) {
354 final Context outerContext = ctx.getOuterContext();
355 return new NotificationManager(
356 new ContextThemeWrapper(outerContext,
357 outerContext.getApplicationInfo().targetSdkVersion >=
358 Build.VERSION_CODES.HONEYCOMB
359 ? com.android.internal.R.style.Theme_Holo_Dialog
360 : com.android.internal.R.style.Theme_Dialog),
361 ctx.mMainThread.getHandler());
362 }});
363
364 // Note: this was previously cached in a static variable, but
365 // constructed using mMainThread.getHandler(), so converting
366 // it to be a regular Context-cached service...
367 registerService(POWER_SERVICE, new ServiceFetcher() {
368 public Object createService(ContextImpl ctx) {
369 IBinder b = ServiceManager.getService(POWER_SERVICE);
370 IPowerManager service = IPowerManager.Stub.asInterface(b);
371 return new PowerManager(service, ctx.mMainThread.getHandler());
372 }});
373
374 registerService(SEARCH_SERVICE, new ServiceFetcher() {
375 public Object createService(ContextImpl ctx) {
376 return new SearchManager(ctx.getOuterContext(),
377 ctx.mMainThread.getHandler());
378 }});
379
380 registerService(SENSOR_SERVICE, new ServiceFetcher() {
381 public Object createService(ContextImpl ctx) {
382 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
383 }});
384
385 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
386 public Object createService(ContextImpl ctx) {
387 return new StatusBarManager(ctx.getOuterContext());
388 }});
389
390 registerService(STORAGE_SERVICE, new ServiceFetcher() {
391 public Object createService(ContextImpl ctx) {
392 try {
393 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
394 } catch (RemoteException rex) {
395 Log.e(TAG, "Failed to create StorageManager", rex);
396 return null;
397 }
398 }});
399
400 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
401 public Object createService(ContextImpl ctx) {
402 return new TelephonyManager(ctx.getOuterContext());
403 }});
404
405 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
406 public Object createStaticService() {
407 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
408 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
409 }});
410
411 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
412 public Object createService(ContextImpl ctx) {
413 return new UiModeManager();
414 }});
415
416 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
417 public Object createService(ContextImpl ctx) {
418 return new Vibrator();
419 }});
420
421 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
422
423 registerService(WIFI_SERVICE, new ServiceFetcher() {
424 public Object createService(ContextImpl ctx) {
425 IBinder b = ServiceManager.getService(WIFI_SERVICE);
426 IWifiManager service = IWifiManager.Stub.asInterface(b);
427 return new WifiManager(service, ctx.mMainThread.getHandler());
428 }});
429
430 registerService(WINDOW_SERVICE, new ServiceFetcher() {
431 public Object getService(ContextImpl ctx) {
432 return WindowManagerImpl.getDefault();
433 }});
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
488 public Resources.Theme getTheme() {
489 if (mTheme == null) {
490 if (mThemeResource == 0) {
Joe Onorato170e5482010-10-29 13:26:11 -0700491 final Context outerContext = getOuterContext();
492 mThemeResource = (outerContext.getApplicationInfo().targetSdkVersion
493 >= Build.VERSION_CODES.HONEYCOMB)
494 ? com.android.internal.R.style.Theme_Holo
495 : com.android.internal.R.style.Theme;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 }
497 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 Fitzpatrick4cd50b82010-12-01 17:31:45 -0800557 // If somebody else (some other process) changed the prefs
558 // file behind our back, we reload it. This has been the
559 // historical (if undocumented) behavior.
560 sp.startReloadIfChangedUnexpectedly();
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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 public File getCacheDir() {
663 synchronized (mSync) {
664 if (mCacheDir == null) {
665 mCacheDir = new File(getDataDirFile(), "cache");
666 }
667 if (!mCacheDir.exists()) {
668 if(!mCacheDir.mkdirs()) {
669 Log.w(TAG, "Unable to create cache directory");
670 return null;
671 }
672 FileUtils.setPermissions(
673 mCacheDir.getPath(),
674 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
675 -1, -1);
676 }
677 }
678 return mCacheDir;
679 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200680
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800681 @Override
682 public File getExternalCacheDir() {
683 synchronized (mSync) {
684 if (mExternalCacheDir == null) {
685 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
686 getPackageName());
687 }
688 if (!mExternalCacheDir.exists()) {
689 try {
690 (new File(Environment.getExternalStorageAndroidDataDir(),
691 ".nomedia")).createNewFile();
692 } catch (IOException e) {
693 }
694 if (!mExternalCacheDir.mkdirs()) {
695 Log.w(TAG, "Unable to create external cache directory");
696 return null;
697 }
698 }
699 return mExternalCacheDir;
700 }
701 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 @Override
704 public File getFileStreamPath(String name) {
705 return makeFilename(getFilesDir(), name);
706 }
707
708 @Override
709 public String[] fileList() {
710 final String[] list = getFilesDir().list();
711 return (list != null) ? list : EMPTY_FILE_LIST;
712 }
713
714 @Override
715 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800716 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
718 setFilePermissionsFromMode(f.getPath(), mode, 0);
719 return db;
720 }
721
722 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700723 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
724 DatabaseErrorHandler errorHandler) {
725 File f = validateFilePath(name, true);
726 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
727 setFilePermissionsFromMode(f.getPath(), mode, 0);
728 return db;
729 }
730
731 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 public boolean deleteDatabase(String name) {
733 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800734 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 return f.delete();
736 } catch (Exception e) {
737 }
738 return false;
739 }
740
741 @Override
742 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800743 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 }
745
746 @Override
747 public String[] databaseList() {
748 final String[] list = getDatabasesDir().list();
749 return (list != null) ? list : EMPTY_FILE_LIST;
750 }
751
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 private File getDatabasesDir() {
754 synchronized (mSync) {
755 if (mDatabasesDir == null) {
756 mDatabasesDir = new File(getDataDirFile(), "databases");
757 }
758 if (mDatabasesDir.getPath().equals("databases")) {
759 mDatabasesDir = new File("/data/system");
760 }
761 return mDatabasesDir;
762 }
763 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 @Override
766 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700767 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 }
769
770 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700771 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700772 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800773 }
774
775 @Override
776 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700777 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
780 @Override
781 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700782 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 }
784
785 @Override
786 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700787 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 }
789
790 @Override
791 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700792 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 }
794
795 @Override
796 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700797 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 }
799
800 @Override
801 public void startActivity(Intent intent) {
802 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
803 throw new AndroidRuntimeException(
804 "Calling startActivity() from outside of an Activity "
805 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
806 + " Is this really what you want?");
807 }
808 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700809 getOuterContext(), mMainThread.getApplicationThread(), null,
810 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
812
813 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800814 public void startActivities(Intent[] intents) {
815 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
816 throw new AndroidRuntimeException(
817 "Calling startActivities() from outside of an Activity "
818 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
819 + " Is this really what you want?");
820 }
821 mMainThread.getInstrumentation().execStartActivities(
822 getOuterContext(), mMainThread.getApplicationThread(), null,
823 (Activity)null, intents);
824 }
825
826 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700827 public void startIntentSender(IntentSender intent,
828 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
829 throws IntentSender.SendIntentException {
830 try {
831 String resolvedType = null;
832 if (fillInIntent != null) {
833 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
834 }
835 int result = ActivityManagerNative.getDefault()
836 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
837 fillInIntent, resolvedType, null, null,
838 0, flagsMask, flagsValues);
839 if (result == IActivityManager.START_CANCELED) {
840 throw new IntentSender.SendIntentException();
841 }
842 Instrumentation.checkStartActivityResult(result, null);
843 } catch (RemoteException e) {
844 }
845 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200846
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700847 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 public void sendBroadcast(Intent intent) {
849 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
850 try {
851 ActivityManagerNative.getDefault().broadcastIntent(
852 mMainThread.getApplicationThread(), intent, resolvedType, null,
853 Activity.RESULT_OK, null, null, null, false, false);
854 } catch (RemoteException e) {
855 }
856 }
857
858 @Override
859 public void sendBroadcast(Intent intent, String receiverPermission) {
860 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
861 try {
862 ActivityManagerNative.getDefault().broadcastIntent(
863 mMainThread.getApplicationThread(), intent, resolvedType, null,
864 Activity.RESULT_OK, null, null, receiverPermission, false, false);
865 } catch (RemoteException e) {
866 }
867 }
868
869 @Override
870 public void sendOrderedBroadcast(Intent intent,
871 String receiverPermission) {
872 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
873 try {
874 ActivityManagerNative.getDefault().broadcastIntent(
875 mMainThread.getApplicationThread(), intent, resolvedType, null,
876 Activity.RESULT_OK, null, null, receiverPermission, true, false);
877 } catch (RemoteException e) {
878 }
879 }
880
881 @Override
882 public void sendOrderedBroadcast(Intent intent,
883 String receiverPermission, BroadcastReceiver resultReceiver,
884 Handler scheduler, int initialCode, String initialData,
885 Bundle initialExtras) {
886 IIntentReceiver rd = null;
887 if (resultReceiver != null) {
888 if (mPackageInfo != null) {
889 if (scheduler == null) {
890 scheduler = mMainThread.getHandler();
891 }
892 rd = mPackageInfo.getReceiverDispatcher(
893 resultReceiver, getOuterContext(), scheduler,
894 mMainThread.getInstrumentation(), false);
895 } else {
896 if (scheduler == null) {
897 scheduler = mMainThread.getHandler();
898 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700899 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
901 }
902 }
903 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
904 try {
905 ActivityManagerNative.getDefault().broadcastIntent(
906 mMainThread.getApplicationThread(), intent, resolvedType, rd,
907 initialCode, initialData, initialExtras, receiverPermission,
908 true, false);
909 } catch (RemoteException e) {
910 }
911 }
912
913 @Override
914 public void sendStickyBroadcast(Intent intent) {
915 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
916 try {
917 ActivityManagerNative.getDefault().broadcastIntent(
918 mMainThread.getApplicationThread(), intent, resolvedType, null,
919 Activity.RESULT_OK, null, null, null, false, true);
920 } catch (RemoteException e) {
921 }
922 }
923
924 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700925 public void sendStickyOrderedBroadcast(Intent intent,
926 BroadcastReceiver resultReceiver,
927 Handler scheduler, int initialCode, String initialData,
928 Bundle initialExtras) {
929 IIntentReceiver rd = null;
930 if (resultReceiver != null) {
931 if (mPackageInfo != null) {
932 if (scheduler == null) {
933 scheduler = mMainThread.getHandler();
934 }
935 rd = mPackageInfo.getReceiverDispatcher(
936 resultReceiver, getOuterContext(), scheduler,
937 mMainThread.getInstrumentation(), false);
938 } else {
939 if (scheduler == null) {
940 scheduler = mMainThread.getHandler();
941 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700942 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700943 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
944 }
945 }
946 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
947 try {
948 ActivityManagerNative.getDefault().broadcastIntent(
949 mMainThread.getApplicationThread(), intent, resolvedType, rd,
950 initialCode, initialData, initialExtras, null,
951 true, true);
952 } catch (RemoteException e) {
953 }
954 }
955
956 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 public void removeStickyBroadcast(Intent intent) {
958 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
959 if (resolvedType != null) {
960 intent = new Intent(intent);
961 intent.setDataAndType(intent.getData(), resolvedType);
962 }
963 try {
964 ActivityManagerNative.getDefault().unbroadcastIntent(
965 mMainThread.getApplicationThread(), intent);
966 } catch (RemoteException e) {
967 }
968 }
969
970 @Override
971 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
972 return registerReceiver(receiver, filter, null, null);
973 }
974
975 @Override
976 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
977 String broadcastPermission, Handler scheduler) {
978 return registerReceiverInternal(receiver, filter, broadcastPermission,
979 scheduler, getOuterContext());
980 }
981
982 private Intent registerReceiverInternal(BroadcastReceiver receiver,
983 IntentFilter filter, String broadcastPermission,
984 Handler scheduler, Context context) {
985 IIntentReceiver rd = null;
986 if (receiver != null) {
987 if (mPackageInfo != null && context != null) {
988 if (scheduler == null) {
989 scheduler = mMainThread.getHandler();
990 }
991 rd = mPackageInfo.getReceiverDispatcher(
992 receiver, context, scheduler,
993 mMainThread.getInstrumentation(), true);
994 } else {
995 if (scheduler == null) {
996 scheduler = mMainThread.getHandler();
997 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700998 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700999 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 }
1001 }
1002 try {
1003 return ActivityManagerNative.getDefault().registerReceiver(
1004 mMainThread.getApplicationThread(),
1005 rd, filter, broadcastPermission);
1006 } catch (RemoteException e) {
1007 return null;
1008 }
1009 }
1010
1011 @Override
1012 public void unregisterReceiver(BroadcastReceiver receiver) {
1013 if (mPackageInfo != null) {
1014 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1015 getOuterContext(), receiver);
1016 try {
1017 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1018 } catch (RemoteException e) {
1019 }
1020 } else {
1021 throw new RuntimeException("Not supported in system context");
1022 }
1023 }
1024
1025 @Override
1026 public ComponentName startService(Intent service) {
1027 try {
1028 ComponentName cn = ActivityManagerNative.getDefault().startService(
1029 mMainThread.getApplicationThread(), service,
1030 service.resolveTypeIfNeeded(getContentResolver()));
1031 if (cn != null && cn.getPackageName().equals("!")) {
1032 throw new SecurityException(
1033 "Not allowed to start service " + service
1034 + " without permission " + cn.getClassName());
1035 }
1036 return cn;
1037 } catch (RemoteException e) {
1038 return null;
1039 }
1040 }
1041
1042 @Override
1043 public boolean stopService(Intent service) {
1044 try {
1045 int res = ActivityManagerNative.getDefault().stopService(
1046 mMainThread.getApplicationThread(), service,
1047 service.resolveTypeIfNeeded(getContentResolver()));
1048 if (res < 0) {
1049 throw new SecurityException(
1050 "Not allowed to stop service " + service);
1051 }
1052 return res != 0;
1053 } catch (RemoteException e) {
1054 return false;
1055 }
1056 }
1057
1058 @Override
1059 public boolean bindService(Intent service, ServiceConnection conn,
1060 int flags) {
1061 IServiceConnection sd;
1062 if (mPackageInfo != null) {
1063 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1064 mMainThread.getHandler(), flags);
1065 } else {
1066 throw new RuntimeException("Not supported in system context");
1067 }
1068 try {
1069 int res = ActivityManagerNative.getDefault().bindService(
1070 mMainThread.getApplicationThread(), getActivityToken(),
1071 service, service.resolveTypeIfNeeded(getContentResolver()),
1072 sd, flags);
1073 if (res < 0) {
1074 throw new SecurityException(
1075 "Not allowed to bind to service " + service);
1076 }
1077 return res != 0;
1078 } catch (RemoteException e) {
1079 return false;
1080 }
1081 }
1082
1083 @Override
1084 public void unbindService(ServiceConnection conn) {
1085 if (mPackageInfo != null) {
1086 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1087 getOuterContext(), conn);
1088 try {
1089 ActivityManagerNative.getDefault().unbindService(sd);
1090 } catch (RemoteException e) {
1091 }
1092 } else {
1093 throw new RuntimeException("Not supported in system context");
1094 }
1095 }
1096
1097 @Override
1098 public boolean startInstrumentation(ComponentName className,
1099 String profileFile, Bundle arguments) {
1100 try {
1101 return ActivityManagerNative.getDefault().startInstrumentation(
1102 className, profileFile, 0, arguments, null);
1103 } catch (RemoteException e) {
1104 // System has crashed, nothing we can do.
1105 }
1106 return false;
1107 }
1108
1109 @Override
1110 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001111 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1112 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001113 }
1114
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001115 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001116 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
1118
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001119 /* package */ static DropBoxManager createDropBoxManager() {
1120 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1121 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001122 if (service == null) {
1123 // Don't return a DropBoxManager that will NPE upon use.
1124 // This also avoids caching a broken DropBoxManager in
1125 // getDropBoxManager during early boot, before the
1126 // DROPBOX_SERVICE is registered.
1127 return null;
1128 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001129 return new DropBoxManager(service);
1130 }
1131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 @Override
1133 public int checkPermission(String permission, int pid, int uid) {
1134 if (permission == null) {
1135 throw new IllegalArgumentException("permission is null");
1136 }
1137
1138 if (!Process.supportsProcesses()) {
1139 return PackageManager.PERMISSION_GRANTED;
1140 }
1141 try {
1142 return ActivityManagerNative.getDefault().checkPermission(
1143 permission, pid, uid);
1144 } catch (RemoteException e) {
1145 return PackageManager.PERMISSION_DENIED;
1146 }
1147 }
1148
1149 @Override
1150 public int checkCallingPermission(String permission) {
1151 if (permission == null) {
1152 throw new IllegalArgumentException("permission is null");
1153 }
1154
1155 if (!Process.supportsProcesses()) {
1156 return PackageManager.PERMISSION_GRANTED;
1157 }
1158 int pid = Binder.getCallingPid();
1159 if (pid != Process.myPid()) {
1160 return checkPermission(permission, pid,
1161 Binder.getCallingUid());
1162 }
1163 return PackageManager.PERMISSION_DENIED;
1164 }
1165
1166 @Override
1167 public int checkCallingOrSelfPermission(String permission) {
1168 if (permission == null) {
1169 throw new IllegalArgumentException("permission is null");
1170 }
1171
1172 return checkPermission(permission, Binder.getCallingPid(),
1173 Binder.getCallingUid());
1174 }
1175
1176 private void enforce(
1177 String permission, int resultOfCheck,
1178 boolean selfToo, int uid, String message) {
1179 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1180 throw new SecurityException(
1181 (message != null ? (message + ": ") : "") +
1182 (selfToo
1183 ? "Neither user " + uid + " nor current process has "
1184 : "User " + uid + " does not have ") +
1185 permission +
1186 ".");
1187 }
1188 }
1189
1190 public void enforcePermission(
1191 String permission, int pid, int uid, String message) {
1192 enforce(permission,
1193 checkPermission(permission, pid, uid),
1194 false,
1195 uid,
1196 message);
1197 }
1198
1199 public void enforceCallingPermission(String permission, String message) {
1200 enforce(permission,
1201 checkCallingPermission(permission),
1202 false,
1203 Binder.getCallingUid(),
1204 message);
1205 }
1206
1207 public void enforceCallingOrSelfPermission(
1208 String permission, String message) {
1209 enforce(permission,
1210 checkCallingOrSelfPermission(permission),
1211 true,
1212 Binder.getCallingUid(),
1213 message);
1214 }
1215
1216 @Override
1217 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1218 try {
1219 ActivityManagerNative.getDefault().grantUriPermission(
1220 mMainThread.getApplicationThread(), toPackage, uri,
1221 modeFlags);
1222 } catch (RemoteException e) {
1223 }
1224 }
1225
1226 @Override
1227 public void revokeUriPermission(Uri uri, int modeFlags) {
1228 try {
1229 ActivityManagerNative.getDefault().revokeUriPermission(
1230 mMainThread.getApplicationThread(), uri,
1231 modeFlags);
1232 } catch (RemoteException e) {
1233 }
1234 }
1235
1236 @Override
1237 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1238 if (!Process.supportsProcesses()) {
1239 return PackageManager.PERMISSION_GRANTED;
1240 }
1241 try {
1242 return ActivityManagerNative.getDefault().checkUriPermission(
1243 uri, pid, uid, modeFlags);
1244 } catch (RemoteException e) {
1245 return PackageManager.PERMISSION_DENIED;
1246 }
1247 }
1248
1249 @Override
1250 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1251 if (!Process.supportsProcesses()) {
1252 return PackageManager.PERMISSION_GRANTED;
1253 }
1254 int pid = Binder.getCallingPid();
1255 if (pid != Process.myPid()) {
1256 return checkUriPermission(uri, pid,
1257 Binder.getCallingUid(), modeFlags);
1258 }
1259 return PackageManager.PERMISSION_DENIED;
1260 }
1261
1262 @Override
1263 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1264 return checkUriPermission(uri, Binder.getCallingPid(),
1265 Binder.getCallingUid(), modeFlags);
1266 }
1267
1268 @Override
1269 public int checkUriPermission(Uri uri, String readPermission,
1270 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001271 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1273 + readPermission + " writePermission=" + writePermission
1274 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1275 }
1276 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1277 if (readPermission == null
1278 || checkPermission(readPermission, pid, uid)
1279 == PackageManager.PERMISSION_GRANTED) {
1280 return PackageManager.PERMISSION_GRANTED;
1281 }
1282 }
1283 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1284 if (writePermission == null
1285 || checkPermission(writePermission, pid, uid)
1286 == PackageManager.PERMISSION_GRANTED) {
1287 return PackageManager.PERMISSION_GRANTED;
1288 }
1289 }
1290 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1291 : PackageManager.PERMISSION_DENIED;
1292 }
1293
1294 private String uriModeFlagToString(int uriModeFlags) {
1295 switch (uriModeFlags) {
1296 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1297 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1298 return "read and write";
1299 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1300 return "read";
1301 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1302 return "write";
1303 }
1304 throw new IllegalArgumentException(
1305 "Unknown permission mode flags: " + uriModeFlags);
1306 }
1307
1308 private void enforceForUri(
1309 int modeFlags, int resultOfCheck, boolean selfToo,
1310 int uid, Uri uri, String message) {
1311 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1312 throw new SecurityException(
1313 (message != null ? (message + ": ") : "") +
1314 (selfToo
1315 ? "Neither user " + uid + " nor current process has "
1316 : "User " + uid + " does not have ") +
1317 uriModeFlagToString(modeFlags) +
1318 " permission on " +
1319 uri +
1320 ".");
1321 }
1322 }
1323
1324 public void enforceUriPermission(
1325 Uri uri, int pid, int uid, int modeFlags, String message) {
1326 enforceForUri(
1327 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1328 false, uid, uri, message);
1329 }
1330
1331 public void enforceCallingUriPermission(
1332 Uri uri, int modeFlags, String message) {
1333 enforceForUri(
1334 modeFlags, checkCallingUriPermission(uri, modeFlags),
1335 false, Binder.getCallingUid(), uri, message);
1336 }
1337
1338 public void enforceCallingOrSelfUriPermission(
1339 Uri uri, int modeFlags, String message) {
1340 enforceForUri(
1341 modeFlags,
1342 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1343 Binder.getCallingUid(), uri, message);
1344 }
1345
1346 public void enforceUriPermission(
1347 Uri uri, String readPermission, String writePermission,
1348 int pid, int uid, int modeFlags, String message) {
1349 enforceForUri(modeFlags,
1350 checkUriPermission(
1351 uri, readPermission, writePermission, pid, uid,
1352 modeFlags),
1353 false,
1354 uid,
1355 uri,
1356 message);
1357 }
1358
1359 @Override
1360 public Context createPackageContext(String packageName, int flags)
1361 throws PackageManager.NameNotFoundException {
1362 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001363 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 }
1365
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001366 LoadedApk pi =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 mMainThread.getPackageInfo(packageName, flags);
1368 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001369 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001370 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001371 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 if (c.mResources != null) {
1373 return c;
1374 }
1375 }
1376
1377 // Should be a better exception.
1378 throw new PackageManager.NameNotFoundException(
1379 "Application package " + packageName + " not found");
1380 }
1381
Romain Guy870e09f2009-07-06 16:35:25 -07001382 @Override
1383 public boolean isRestricted() {
1384 return mRestricted;
1385 }
1386
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 private File getDataDirFile() {
1388 if (mPackageInfo != null) {
1389 return mPackageInfo.getDataDirFile();
1390 }
1391 throw new RuntimeException("Not supported in system context");
1392 }
1393
1394 @Override
1395 public File getDir(String name, int mode) {
1396 name = "app_" + name;
1397 File file = makeFilename(getDataDirFile(), name);
1398 if (!file.exists()) {
1399 file.mkdir();
1400 setFilePermissionsFromMode(file.getPath(), mode,
1401 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1402 }
1403 return file;
1404 }
1405
Dianne Hackborn21556372010-02-04 16:34:40 -08001406 static ContextImpl createSystemContext(ActivityThread mainThread) {
1407 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 context.init(Resources.getSystem(), mainThread);
1409 return context;
1410 }
1411
Dianne Hackborn21556372010-02-04 16:34:40 -08001412 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 mOuterContext = this;
1414 }
1415
1416 /**
1417 * Create a new ApplicationContext from an existing one. The new one
1418 * works and operates the same as the one it is copying.
1419 *
1420 * @param context Existing application context.
1421 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001422 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 mPackageInfo = context.mPackageInfo;
1424 mResources = context.mResources;
1425 mMainThread = context.mMainThread;
1426 mContentResolver = context.mContentResolver;
1427 mOuterContext = this;
1428 }
1429
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001430 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001432 init(packageInfo, activityToken, mainThread, null);
1433 }
1434
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001435 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001436 IBinder activityToken, ActivityThread mainThread,
1437 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 mPackageInfo = packageInfo;
1439 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001440
Dianne Hackborn559a7872010-04-07 18:19:41 -07001441 if (mResources != null && container != null
1442 && container.getCompatibilityInfo().applicationScale !=
1443 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001444 if (DEBUG) {
1445 Log.d(TAG, "loaded context has different scaling. Using container's" +
1446 " compatiblity info:" + container.getDisplayMetrics());
1447 }
1448 mResources = mainThread.getTopLevelResources(
1449 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 mMainThread = mainThread;
1452 mContentResolver = new ApplicationContentResolver(this, mainThread);
1453
1454 setActivityToken(activityToken);
1455 }
1456
1457 final void init(Resources resources, ActivityThread mainThread) {
1458 mPackageInfo = null;
1459 mResources = resources;
1460 mMainThread = mainThread;
1461 mContentResolver = new ApplicationContentResolver(this, mainThread);
1462 }
1463
1464 final void scheduleFinalCleanup(String who, String what) {
1465 mMainThread.scheduleContextCleanup(this, who, what);
1466 }
1467
1468 final void performFinalCleanup(String who, String what) {
1469 //Log.i(TAG, "Cleanup up context: " + this);
1470 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1471 }
1472
1473 final Context getReceiverRestrictedContext() {
1474 if (mReceiverRestrictedContext != null) {
1475 return mReceiverRestrictedContext;
1476 }
1477 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1478 }
1479
1480 final void setActivityToken(IBinder token) {
1481 mActivityToken = token;
1482 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001483
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 final void setOuterContext(Context context) {
1485 mOuterContext = context;
1486 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001487
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 final Context getOuterContext() {
1489 return mOuterContext;
1490 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 final IBinder getActivityToken() {
1493 return mActivityToken;
1494 }
1495
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001496 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 int extraPermissions) {
1498 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1499 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1500 |extraPermissions;
1501 if ((mode&MODE_WORLD_READABLE) != 0) {
1502 perms |= FileUtils.S_IROTH;
1503 }
1504 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1505 perms |= FileUtils.S_IWOTH;
1506 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001507 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1509 + ", perms=0x" + Integer.toHexString(perms));
1510 }
1511 FileUtils.setPermissions(name, perms, -1, -1);
1512 }
1513
Oscar Montemayora8529f62009-11-18 10:14:20 -08001514 private File validateFilePath(String name, boolean createDirectory) {
1515 File dir;
1516 File f;
1517
1518 if (name.charAt(0) == File.separatorChar) {
1519 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1520 dir = new File(dirPath);
1521 name = name.substring(name.lastIndexOf(File.separatorChar));
1522 f = new File(dir, name);
1523 } else {
1524 dir = getDatabasesDir();
1525 f = makeFilename(dir, name);
1526 }
1527
1528 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1529 FileUtils.setPermissions(dir.getPath(),
1530 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1531 -1, -1);
1532 }
1533
1534 return f;
1535 }
1536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 private File makeFilename(File base, String name) {
1538 if (name.indexOf(File.separatorChar) < 0) {
1539 return new File(base, name);
1540 }
1541 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001542 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 }
1544
1545 // ----------------------------------------------------------------------
1546 // ----------------------------------------------------------------------
1547 // ----------------------------------------------------------------------
1548
1549 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001550 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 super(context);
1552 mMainThread = mainThread;
1553 }
1554
1555 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001556 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 return mMainThread.acquireProvider(context, name);
1558 }
1559
1560 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001561 protected IContentProvider acquireExistingProvider(Context context, String name) {
1562 return mMainThread.acquireExistingProvider(context, name);
1563 }
1564
1565 @Override
1566 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 return mMainThread.releaseProvider(provider);
1568 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 private final ActivityThread mMainThread;
1571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572}