blob: 72f7286d96feb26113813e1348528a5fac32349f [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 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 public File getCacheDir() {
666 synchronized (mSync) {
667 if (mCacheDir == null) {
668 mCacheDir = new File(getDataDirFile(), "cache");
669 }
670 if (!mCacheDir.exists()) {
671 if(!mCacheDir.mkdirs()) {
672 Log.w(TAG, "Unable to create cache directory");
673 return null;
674 }
675 FileUtils.setPermissions(
676 mCacheDir.getPath(),
677 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
678 -1, -1);
679 }
680 }
681 return mCacheDir;
682 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200683
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800684 @Override
685 public File getExternalCacheDir() {
686 synchronized (mSync) {
687 if (mExternalCacheDir == null) {
688 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
689 getPackageName());
690 }
691 if (!mExternalCacheDir.exists()) {
692 try {
693 (new File(Environment.getExternalStorageAndroidDataDir(),
694 ".nomedia")).createNewFile();
695 } catch (IOException e) {
696 }
697 if (!mExternalCacheDir.mkdirs()) {
698 Log.w(TAG, "Unable to create external cache directory");
699 return null;
700 }
701 }
702 return mExternalCacheDir;
703 }
704 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 @Override
707 public File getFileStreamPath(String name) {
708 return makeFilename(getFilesDir(), name);
709 }
710
711 @Override
712 public String[] fileList() {
713 final String[] list = getFilesDir().list();
714 return (list != null) ? list : EMPTY_FILE_LIST;
715 }
716
717 @Override
718 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800719 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
721 setFilePermissionsFromMode(f.getPath(), mode, 0);
722 return db;
723 }
724
725 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700726 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
727 DatabaseErrorHandler errorHandler) {
728 File f = validateFilePath(name, true);
729 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
730 setFilePermissionsFromMode(f.getPath(), mode, 0);
731 return db;
732 }
733
734 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 public boolean deleteDatabase(String name) {
736 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800737 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 return f.delete();
739 } catch (Exception e) {
740 }
741 return false;
742 }
743
744 @Override
745 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800746 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 }
748
749 @Override
750 public String[] databaseList() {
751 final String[] list = getDatabasesDir().list();
752 return (list != null) ? list : EMPTY_FILE_LIST;
753 }
754
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 private File getDatabasesDir() {
757 synchronized (mSync) {
758 if (mDatabasesDir == null) {
759 mDatabasesDir = new File(getDataDirFile(), "databases");
760 }
761 if (mDatabasesDir.getPath().equals("databases")) {
762 mDatabasesDir = new File("/data/system");
763 }
764 return mDatabasesDir;
765 }
766 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 @Override
769 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700770 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 }
772
773 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700774 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700775 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
778 @Override
779 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700780 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 }
782
783 @Override
784 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700785 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 }
787
788 @Override
789 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700790 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 }
792
793 @Override
794 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700795 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
797
798 @Override
799 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700800 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802
803 @Override
804 public void startActivity(Intent intent) {
805 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
806 throw new AndroidRuntimeException(
807 "Calling startActivity() from outside of an Activity "
808 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
809 + " Is this really what you want?");
810 }
811 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700812 getOuterContext(), mMainThread.getApplicationThread(), null,
813 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 }
815
816 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800817 public void startActivities(Intent[] intents) {
818 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
819 throw new AndroidRuntimeException(
820 "Calling startActivities() from outside of an Activity "
821 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
822 + " Is this really what you want?");
823 }
824 mMainThread.getInstrumentation().execStartActivities(
825 getOuterContext(), mMainThread.getApplicationThread(), null,
826 (Activity)null, intents);
827 }
828
829 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700830 public void startIntentSender(IntentSender intent,
831 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
832 throws IntentSender.SendIntentException {
833 try {
834 String resolvedType = null;
835 if (fillInIntent != null) {
836 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
837 }
838 int result = ActivityManagerNative.getDefault()
839 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
840 fillInIntent, resolvedType, null, null,
841 0, flagsMask, flagsValues);
842 if (result == IActivityManager.START_CANCELED) {
843 throw new IntentSender.SendIntentException();
844 }
845 Instrumentation.checkStartActivityResult(result, null);
846 } catch (RemoteException e) {
847 }
848 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200849
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700850 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800851 public void sendBroadcast(Intent intent) {
852 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
853 try {
854 ActivityManagerNative.getDefault().broadcastIntent(
855 mMainThread.getApplicationThread(), intent, resolvedType, null,
856 Activity.RESULT_OK, null, null, null, false, false);
857 } catch (RemoteException e) {
858 }
859 }
860
861 @Override
862 public void sendBroadcast(Intent intent, String receiverPermission) {
863 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
864 try {
865 ActivityManagerNative.getDefault().broadcastIntent(
866 mMainThread.getApplicationThread(), intent, resolvedType, null,
867 Activity.RESULT_OK, null, null, receiverPermission, false, false);
868 } catch (RemoteException e) {
869 }
870 }
871
872 @Override
873 public void sendOrderedBroadcast(Intent intent,
874 String receiverPermission) {
875 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
876 try {
877 ActivityManagerNative.getDefault().broadcastIntent(
878 mMainThread.getApplicationThread(), intent, resolvedType, null,
879 Activity.RESULT_OK, null, null, receiverPermission, true, false);
880 } catch (RemoteException e) {
881 }
882 }
883
884 @Override
885 public void sendOrderedBroadcast(Intent intent,
886 String receiverPermission, BroadcastReceiver resultReceiver,
887 Handler scheduler, int initialCode, String initialData,
888 Bundle initialExtras) {
889 IIntentReceiver rd = null;
890 if (resultReceiver != null) {
891 if (mPackageInfo != null) {
892 if (scheduler == null) {
893 scheduler = mMainThread.getHandler();
894 }
895 rd = mPackageInfo.getReceiverDispatcher(
896 resultReceiver, getOuterContext(), scheduler,
897 mMainThread.getInstrumentation(), false);
898 } else {
899 if (scheduler == null) {
900 scheduler = mMainThread.getHandler();
901 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700902 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
904 }
905 }
906 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
907 try {
908 ActivityManagerNative.getDefault().broadcastIntent(
909 mMainThread.getApplicationThread(), intent, resolvedType, rd,
910 initialCode, initialData, initialExtras, receiverPermission,
911 true, false);
912 } catch (RemoteException e) {
913 }
914 }
915
916 @Override
917 public void sendStickyBroadcast(Intent intent) {
918 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
919 try {
920 ActivityManagerNative.getDefault().broadcastIntent(
921 mMainThread.getApplicationThread(), intent, resolvedType, null,
922 Activity.RESULT_OK, null, null, null, false, true);
923 } catch (RemoteException e) {
924 }
925 }
926
927 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700928 public void sendStickyOrderedBroadcast(Intent intent,
929 BroadcastReceiver resultReceiver,
930 Handler scheduler, int initialCode, String initialData,
931 Bundle initialExtras) {
932 IIntentReceiver rd = null;
933 if (resultReceiver != null) {
934 if (mPackageInfo != null) {
935 if (scheduler == null) {
936 scheduler = mMainThread.getHandler();
937 }
938 rd = mPackageInfo.getReceiverDispatcher(
939 resultReceiver, getOuterContext(), scheduler,
940 mMainThread.getInstrumentation(), false);
941 } else {
942 if (scheduler == null) {
943 scheduler = mMainThread.getHandler();
944 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700945 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700946 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
947 }
948 }
949 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
950 try {
951 ActivityManagerNative.getDefault().broadcastIntent(
952 mMainThread.getApplicationThread(), intent, resolvedType, rd,
953 initialCode, initialData, initialExtras, null,
954 true, true);
955 } catch (RemoteException e) {
956 }
957 }
958
959 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 public void removeStickyBroadcast(Intent intent) {
961 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
962 if (resolvedType != null) {
963 intent = new Intent(intent);
964 intent.setDataAndType(intent.getData(), resolvedType);
965 }
966 try {
967 ActivityManagerNative.getDefault().unbroadcastIntent(
968 mMainThread.getApplicationThread(), intent);
969 } catch (RemoteException e) {
970 }
971 }
972
973 @Override
974 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
975 return registerReceiver(receiver, filter, null, null);
976 }
977
978 @Override
979 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
980 String broadcastPermission, Handler scheduler) {
981 return registerReceiverInternal(receiver, filter, broadcastPermission,
982 scheduler, getOuterContext());
983 }
984
985 private Intent registerReceiverInternal(BroadcastReceiver receiver,
986 IntentFilter filter, String broadcastPermission,
987 Handler scheduler, Context context) {
988 IIntentReceiver rd = null;
989 if (receiver != null) {
990 if (mPackageInfo != null && context != null) {
991 if (scheduler == null) {
992 scheduler = mMainThread.getHandler();
993 }
994 rd = mPackageInfo.getReceiverDispatcher(
995 receiver, context, scheduler,
996 mMainThread.getInstrumentation(), true);
997 } else {
998 if (scheduler == null) {
999 scheduler = mMainThread.getHandler();
1000 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001001 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001002 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 }
1004 }
1005 try {
1006 return ActivityManagerNative.getDefault().registerReceiver(
1007 mMainThread.getApplicationThread(),
1008 rd, filter, broadcastPermission);
1009 } catch (RemoteException e) {
1010 return null;
1011 }
1012 }
1013
1014 @Override
1015 public void unregisterReceiver(BroadcastReceiver receiver) {
1016 if (mPackageInfo != null) {
1017 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1018 getOuterContext(), receiver);
1019 try {
1020 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1021 } catch (RemoteException e) {
1022 }
1023 } else {
1024 throw new RuntimeException("Not supported in system context");
1025 }
1026 }
1027
1028 @Override
1029 public ComponentName startService(Intent service) {
1030 try {
1031 ComponentName cn = ActivityManagerNative.getDefault().startService(
1032 mMainThread.getApplicationThread(), service,
1033 service.resolveTypeIfNeeded(getContentResolver()));
1034 if (cn != null && cn.getPackageName().equals("!")) {
1035 throw new SecurityException(
1036 "Not allowed to start service " + service
1037 + " without permission " + cn.getClassName());
1038 }
1039 return cn;
1040 } catch (RemoteException e) {
1041 return null;
1042 }
1043 }
1044
1045 @Override
1046 public boolean stopService(Intent service) {
1047 try {
1048 int res = ActivityManagerNative.getDefault().stopService(
1049 mMainThread.getApplicationThread(), service,
1050 service.resolveTypeIfNeeded(getContentResolver()));
1051 if (res < 0) {
1052 throw new SecurityException(
1053 "Not allowed to stop service " + service);
1054 }
1055 return res != 0;
1056 } catch (RemoteException e) {
1057 return false;
1058 }
1059 }
1060
1061 @Override
1062 public boolean bindService(Intent service, ServiceConnection conn,
1063 int flags) {
1064 IServiceConnection sd;
1065 if (mPackageInfo != null) {
1066 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1067 mMainThread.getHandler(), flags);
1068 } else {
1069 throw new RuntimeException("Not supported in system context");
1070 }
1071 try {
1072 int res = ActivityManagerNative.getDefault().bindService(
1073 mMainThread.getApplicationThread(), getActivityToken(),
1074 service, service.resolveTypeIfNeeded(getContentResolver()),
1075 sd, flags);
1076 if (res < 0) {
1077 throw new SecurityException(
1078 "Not allowed to bind to service " + service);
1079 }
1080 return res != 0;
1081 } catch (RemoteException e) {
1082 return false;
1083 }
1084 }
1085
1086 @Override
1087 public void unbindService(ServiceConnection conn) {
1088 if (mPackageInfo != null) {
1089 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1090 getOuterContext(), conn);
1091 try {
1092 ActivityManagerNative.getDefault().unbindService(sd);
1093 } catch (RemoteException e) {
1094 }
1095 } else {
1096 throw new RuntimeException("Not supported in system context");
1097 }
1098 }
1099
1100 @Override
1101 public boolean startInstrumentation(ComponentName className,
1102 String profileFile, Bundle arguments) {
1103 try {
1104 return ActivityManagerNative.getDefault().startInstrumentation(
1105 className, profileFile, 0, arguments, null);
1106 } catch (RemoteException e) {
1107 // System has crashed, nothing we can do.
1108 }
1109 return false;
1110 }
1111
1112 @Override
1113 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001114 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1115 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 }
1117
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001118 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001119 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 }
1121
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001122 /* package */ static DropBoxManager createDropBoxManager() {
1123 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1124 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001125 if (service == null) {
1126 // Don't return a DropBoxManager that will NPE upon use.
1127 // This also avoids caching a broken DropBoxManager in
1128 // getDropBoxManager during early boot, before the
1129 // DROPBOX_SERVICE is registered.
1130 return null;
1131 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001132 return new DropBoxManager(service);
1133 }
1134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 @Override
1136 public int checkPermission(String permission, int pid, int uid) {
1137 if (permission == null) {
1138 throw new IllegalArgumentException("permission is null");
1139 }
1140
1141 if (!Process.supportsProcesses()) {
1142 return PackageManager.PERMISSION_GRANTED;
1143 }
1144 try {
1145 return ActivityManagerNative.getDefault().checkPermission(
1146 permission, pid, uid);
1147 } catch (RemoteException e) {
1148 return PackageManager.PERMISSION_DENIED;
1149 }
1150 }
1151
1152 @Override
1153 public int checkCallingPermission(String permission) {
1154 if (permission == null) {
1155 throw new IllegalArgumentException("permission is null");
1156 }
1157
1158 if (!Process.supportsProcesses()) {
1159 return PackageManager.PERMISSION_GRANTED;
1160 }
1161 int pid = Binder.getCallingPid();
1162 if (pid != Process.myPid()) {
1163 return checkPermission(permission, pid,
1164 Binder.getCallingUid());
1165 }
1166 return PackageManager.PERMISSION_DENIED;
1167 }
1168
1169 @Override
1170 public int checkCallingOrSelfPermission(String permission) {
1171 if (permission == null) {
1172 throw new IllegalArgumentException("permission is null");
1173 }
1174
1175 return checkPermission(permission, Binder.getCallingPid(),
1176 Binder.getCallingUid());
1177 }
1178
1179 private void enforce(
1180 String permission, int resultOfCheck,
1181 boolean selfToo, int uid, String message) {
1182 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1183 throw new SecurityException(
1184 (message != null ? (message + ": ") : "") +
1185 (selfToo
1186 ? "Neither user " + uid + " nor current process has "
1187 : "User " + uid + " does not have ") +
1188 permission +
1189 ".");
1190 }
1191 }
1192
1193 public void enforcePermission(
1194 String permission, int pid, int uid, String message) {
1195 enforce(permission,
1196 checkPermission(permission, pid, uid),
1197 false,
1198 uid,
1199 message);
1200 }
1201
1202 public void enforceCallingPermission(String permission, String message) {
1203 enforce(permission,
1204 checkCallingPermission(permission),
1205 false,
1206 Binder.getCallingUid(),
1207 message);
1208 }
1209
1210 public void enforceCallingOrSelfPermission(
1211 String permission, String message) {
1212 enforce(permission,
1213 checkCallingOrSelfPermission(permission),
1214 true,
1215 Binder.getCallingUid(),
1216 message);
1217 }
1218
1219 @Override
1220 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1221 try {
1222 ActivityManagerNative.getDefault().grantUriPermission(
1223 mMainThread.getApplicationThread(), toPackage, uri,
1224 modeFlags);
1225 } catch (RemoteException e) {
1226 }
1227 }
1228
1229 @Override
1230 public void revokeUriPermission(Uri uri, int modeFlags) {
1231 try {
1232 ActivityManagerNative.getDefault().revokeUriPermission(
1233 mMainThread.getApplicationThread(), uri,
1234 modeFlags);
1235 } catch (RemoteException e) {
1236 }
1237 }
1238
1239 @Override
1240 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1241 if (!Process.supportsProcesses()) {
1242 return PackageManager.PERMISSION_GRANTED;
1243 }
1244 try {
1245 return ActivityManagerNative.getDefault().checkUriPermission(
1246 uri, pid, uid, modeFlags);
1247 } catch (RemoteException e) {
1248 return PackageManager.PERMISSION_DENIED;
1249 }
1250 }
1251
1252 @Override
1253 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1254 if (!Process.supportsProcesses()) {
1255 return PackageManager.PERMISSION_GRANTED;
1256 }
1257 int pid = Binder.getCallingPid();
1258 if (pid != Process.myPid()) {
1259 return checkUriPermission(uri, pid,
1260 Binder.getCallingUid(), modeFlags);
1261 }
1262 return PackageManager.PERMISSION_DENIED;
1263 }
1264
1265 @Override
1266 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1267 return checkUriPermission(uri, Binder.getCallingPid(),
1268 Binder.getCallingUid(), modeFlags);
1269 }
1270
1271 @Override
1272 public int checkUriPermission(Uri uri, String readPermission,
1273 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001274 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1276 + readPermission + " writePermission=" + writePermission
1277 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1278 }
1279 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1280 if (readPermission == null
1281 || checkPermission(readPermission, pid, uid)
1282 == PackageManager.PERMISSION_GRANTED) {
1283 return PackageManager.PERMISSION_GRANTED;
1284 }
1285 }
1286 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1287 if (writePermission == null
1288 || checkPermission(writePermission, pid, uid)
1289 == PackageManager.PERMISSION_GRANTED) {
1290 return PackageManager.PERMISSION_GRANTED;
1291 }
1292 }
1293 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1294 : PackageManager.PERMISSION_DENIED;
1295 }
1296
1297 private String uriModeFlagToString(int uriModeFlags) {
1298 switch (uriModeFlags) {
1299 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1300 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1301 return "read and write";
1302 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1303 return "read";
1304 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1305 return "write";
1306 }
1307 throw new IllegalArgumentException(
1308 "Unknown permission mode flags: " + uriModeFlags);
1309 }
1310
1311 private void enforceForUri(
1312 int modeFlags, int resultOfCheck, boolean selfToo,
1313 int uid, Uri uri, String message) {
1314 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1315 throw new SecurityException(
1316 (message != null ? (message + ": ") : "") +
1317 (selfToo
1318 ? "Neither user " + uid + " nor current process has "
1319 : "User " + uid + " does not have ") +
1320 uriModeFlagToString(modeFlags) +
1321 " permission on " +
1322 uri +
1323 ".");
1324 }
1325 }
1326
1327 public void enforceUriPermission(
1328 Uri uri, int pid, int uid, int modeFlags, String message) {
1329 enforceForUri(
1330 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1331 false, uid, uri, message);
1332 }
1333
1334 public void enforceCallingUriPermission(
1335 Uri uri, int modeFlags, String message) {
1336 enforceForUri(
1337 modeFlags, checkCallingUriPermission(uri, modeFlags),
1338 false, Binder.getCallingUid(), uri, message);
1339 }
1340
1341 public void enforceCallingOrSelfUriPermission(
1342 Uri uri, int modeFlags, String message) {
1343 enforceForUri(
1344 modeFlags,
1345 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1346 Binder.getCallingUid(), uri, message);
1347 }
1348
1349 public void enforceUriPermission(
1350 Uri uri, String readPermission, String writePermission,
1351 int pid, int uid, int modeFlags, String message) {
1352 enforceForUri(modeFlags,
1353 checkUriPermission(
1354 uri, readPermission, writePermission, pid, uid,
1355 modeFlags),
1356 false,
1357 uid,
1358 uri,
1359 message);
1360 }
1361
1362 @Override
1363 public Context createPackageContext(String packageName, int flags)
1364 throws PackageManager.NameNotFoundException {
1365 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001366 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001367 }
1368
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001369 LoadedApk pi =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 mMainThread.getPackageInfo(packageName, flags);
1371 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001372 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001373 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001374 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 if (c.mResources != null) {
1376 return c;
1377 }
1378 }
1379
1380 // Should be a better exception.
1381 throw new PackageManager.NameNotFoundException(
1382 "Application package " + packageName + " not found");
1383 }
1384
Romain Guy870e09f2009-07-06 16:35:25 -07001385 @Override
1386 public boolean isRestricted() {
1387 return mRestricted;
1388 }
1389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 private File getDataDirFile() {
1391 if (mPackageInfo != null) {
1392 return mPackageInfo.getDataDirFile();
1393 }
1394 throw new RuntimeException("Not supported in system context");
1395 }
1396
1397 @Override
1398 public File getDir(String name, int mode) {
1399 name = "app_" + name;
1400 File file = makeFilename(getDataDirFile(), name);
1401 if (!file.exists()) {
1402 file.mkdir();
1403 setFilePermissionsFromMode(file.getPath(), mode,
1404 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1405 }
1406 return file;
1407 }
1408
Dianne Hackborn21556372010-02-04 16:34:40 -08001409 static ContextImpl createSystemContext(ActivityThread mainThread) {
1410 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 context.init(Resources.getSystem(), mainThread);
1412 return context;
1413 }
1414
Dianne Hackborn21556372010-02-04 16:34:40 -08001415 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 mOuterContext = this;
1417 }
1418
1419 /**
1420 * Create a new ApplicationContext from an existing one. The new one
1421 * works and operates the same as the one it is copying.
1422 *
1423 * @param context Existing application context.
1424 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001425 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 mPackageInfo = context.mPackageInfo;
1427 mResources = context.mResources;
1428 mMainThread = context.mMainThread;
1429 mContentResolver = context.mContentResolver;
1430 mOuterContext = this;
1431 }
1432
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001433 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001435 init(packageInfo, activityToken, mainThread, null);
1436 }
1437
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001438 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001439 IBinder activityToken, ActivityThread mainThread,
1440 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 mPackageInfo = packageInfo;
1442 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001443
Dianne Hackborn559a7872010-04-07 18:19:41 -07001444 if (mResources != null && container != null
1445 && container.getCompatibilityInfo().applicationScale !=
1446 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001447 if (DEBUG) {
1448 Log.d(TAG, "loaded context has different scaling. Using container's" +
1449 " compatiblity info:" + container.getDisplayMetrics());
1450 }
1451 mResources = mainThread.getTopLevelResources(
1452 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 mMainThread = mainThread;
1455 mContentResolver = new ApplicationContentResolver(this, mainThread);
1456
1457 setActivityToken(activityToken);
1458 }
1459
1460 final void init(Resources resources, ActivityThread mainThread) {
1461 mPackageInfo = null;
1462 mResources = resources;
1463 mMainThread = mainThread;
1464 mContentResolver = new ApplicationContentResolver(this, mainThread);
1465 }
1466
1467 final void scheduleFinalCleanup(String who, String what) {
1468 mMainThread.scheduleContextCleanup(this, who, what);
1469 }
1470
1471 final void performFinalCleanup(String who, String what) {
1472 //Log.i(TAG, "Cleanup up context: " + this);
1473 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1474 }
1475
1476 final Context getReceiverRestrictedContext() {
1477 if (mReceiverRestrictedContext != null) {
1478 return mReceiverRestrictedContext;
1479 }
1480 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1481 }
1482
1483 final void setActivityToken(IBinder token) {
1484 mActivityToken = token;
1485 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 final void setOuterContext(Context context) {
1488 mOuterContext = context;
1489 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001490
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 final Context getOuterContext() {
1492 return mOuterContext;
1493 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 final IBinder getActivityToken() {
1496 return mActivityToken;
1497 }
1498
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001499 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 int extraPermissions) {
1501 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1502 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1503 |extraPermissions;
1504 if ((mode&MODE_WORLD_READABLE) != 0) {
1505 perms |= FileUtils.S_IROTH;
1506 }
1507 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1508 perms |= FileUtils.S_IWOTH;
1509 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001510 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1512 + ", perms=0x" + Integer.toHexString(perms));
1513 }
1514 FileUtils.setPermissions(name, perms, -1, -1);
1515 }
1516
Oscar Montemayora8529f62009-11-18 10:14:20 -08001517 private File validateFilePath(String name, boolean createDirectory) {
1518 File dir;
1519 File f;
1520
1521 if (name.charAt(0) == File.separatorChar) {
1522 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1523 dir = new File(dirPath);
1524 name = name.substring(name.lastIndexOf(File.separatorChar));
1525 f = new File(dir, name);
1526 } else {
1527 dir = getDatabasesDir();
1528 f = makeFilename(dir, name);
1529 }
1530
1531 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1532 FileUtils.setPermissions(dir.getPath(),
1533 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1534 -1, -1);
1535 }
1536
1537 return f;
1538 }
1539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 private File makeFilename(File base, String name) {
1541 if (name.indexOf(File.separatorChar) < 0) {
1542 return new File(base, name);
1543 }
1544 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001545 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547
1548 // ----------------------------------------------------------------------
1549 // ----------------------------------------------------------------------
1550 // ----------------------------------------------------------------------
1551
1552 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001553 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554 super(context);
1555 mMainThread = mainThread;
1556 }
1557
1558 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001559 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 return mMainThread.acquireProvider(context, name);
1561 }
1562
1563 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001564 protected IContentProvider acquireExistingProvider(Context context, String name) {
1565 return mMainThread.acquireExistingProvider(context, name);
1566 }
1567
1568 @Override
1569 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 return mMainThread.releaseProvider(provider);
1571 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 private final ActivityThread mMainThread;
1574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575}