blob: 6f639906097d2de866c97593fc2cebcfe928c259 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.BroadcastReceiver;
22import android.content.ComponentName;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.IContentProvider;
27import android.content.Intent;
28import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070029import android.content.IIntentReceiver;
30import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ReceiverCallNotAllowedException;
32import android.content.ServiceConnection;
33import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.pm.PackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.res.AssetManager;
38import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070039import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.database.sqlite.SQLiteDatabase;
41import android.database.sqlite.SQLiteDatabase.CursorFactory;
42import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.graphics.drawable.Drawable;
44import android.hardware.SensorManager;
Bai Taoa58a8752010-07-13 15:32:16 +080045import android.location.CountryDetector;
46import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.location.ILocationManager;
48import android.location.LocationManager;
49import android.media.AudioManager;
50import android.net.ConnectivityManager;
51import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070052import android.net.ThrottleManager;
53import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.net.Uri;
55import android.net.wifi.IWifiManager;
56import android.net.wifi.WifiManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080057import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.os.Binder;
Adam Powellc63806d2010-09-23 16:21:30 -070059import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080061import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080062import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.os.FileUtils;
64import android.os.Handler;
65import android.os.IBinder;
66import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070067import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.os.PowerManager;
69import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070070import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.ServiceManager;
72import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080073import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070075import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.util.AndroidRuntimeException;
77import android.util.Log;
78import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070080import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070082import android.accounts.AccountManager;
83import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080084import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080085import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import java.io.File;
88import java.io.FileInputStream;
89import java.io.FileNotFoundException;
90import java.io.FileOutputStream;
91import java.io.IOException;
92import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import java.util.ArrayList;
94import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096class ReceiverRestrictedContext extends ContextWrapper {
97 ReceiverRestrictedContext(Context base) {
98 super(base);
99 }
100
101 @Override
102 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
103 return registerReceiver(receiver, filter, null, null);
104 }
105
106 @Override
107 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
108 String broadcastPermission, Handler scheduler) {
109 throw new ReceiverCallNotAllowedException(
110 "IntentReceiver components are not allowed to register to receive intents");
111 //ex.fillInStackTrace();
112 //Log.e("IntentReceiver", ex.getMessage(), ex);
113 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
114 // scheduler);
115 }
116
117 @Override
118 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
119 throw new ReceiverCallNotAllowedException(
120 "IntentReceiver components are not allowed to bind to services");
121 //ex.fillInStackTrace();
122 //Log.e("IntentReceiver", ex.getMessage(), ex);
123 //return mContext.bindService(service, interfaceName, conn, flags);
124 }
125}
126
127/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800128 * Common implementation of Context API, which provides the base
129 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800131class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700133 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700135 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
136 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700138 /*package*/ LoadedApk mPackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 private Resources mResources;
140 /*package*/ ActivityThread mMainThread;
141 private Context mOuterContext;
142 private IBinder mActivityToken = null;
143 private ApplicationContentResolver mContentResolver;
144 private int mThemeResource = 0;
145 private Resources.Theme mTheme = null;
146 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700148 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
150 private final Object mSync = new Object();
151
152 private File mDatabasesDir;
153 private File mPreferencesDir;
154 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800156 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800157 private File mExternalFilesDir;
158 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private static final String[] EMPTY_FILE_LIST = {};
161
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800162 /**
163 * Override this class when the system service constructor needs a
164 * ContextImpl. Else, use StaticServiceFetcher below.
165 */
166 /*package*/ static class ServiceFetcher {
167 int mContextCacheIndex = -1;
168
169 /**
170 * Main entrypoint; only override if you don't need caching.
171 */
172 public Object getService(ContextImpl ctx) {
173 ArrayList<Object> cache = ctx.mServiceCache;
174 Object service;
175 synchronized (cache) {
176 if (cache.size() == 0) {
177 // Initialize the cache vector on first access.
178 // At this point sNextPerContextServiceCacheIndex
179 // is the number of potential services that are
180 // cached per-Context.
181 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
182 cache.add(null);
183 }
184 } else {
185 service = cache.get(mContextCacheIndex);
186 if (service != null) {
187 return service;
188 }
189 }
190 service = createService(ctx);
191 cache.set(mContextCacheIndex, service);
192 return service;
193 }
194 }
195
196 /**
197 * Override this to create a new per-Context instance of the
198 * service. getService() will handle locking and caching.
199 */
200 public Object createService(ContextImpl ctx) {
201 throw new RuntimeException("Not implemented");
202 }
203 }
204
205 /**
206 * Override this class for services to be cached process-wide.
207 */
208 abstract static class StaticServiceFetcher extends ServiceFetcher {
209 private Object mCachedInstance;
210
211 @Override
212 public final Object getService(ContextImpl unused) {
213 synchronized (StaticServiceFetcher.this) {
214 Object service = mCachedInstance;
215 if (service != null) {
216 return service;
217 }
218 return mCachedInstance = createStaticService();
219 }
220 }
221
222 public abstract Object createStaticService();
223 }
224
225 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
226 new HashMap<String, ServiceFetcher>();
227
228 private static int sNextPerContextServiceCacheIndex = 0;
229 private static void registerService(String serviceName, ServiceFetcher fetcher) {
230 if (!(fetcher instanceof StaticServiceFetcher)) {
231 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
232 }
233 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
234 }
235
236 // This one's defined separately and given a variable name so it
237 // can be re-used by getWallpaperManager(), avoiding a HashMap
238 // lookup.
239 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
240 public Object createService(ContextImpl ctx) {
241 return new WallpaperManager(ctx.getOuterContext(),
242 ctx.mMainThread.getHandler());
243 }};
244
245 static {
246 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
247 public Object getService(ContextImpl ctx) {
248 return AccessibilityManager.getInstance(ctx);
249 }});
250
251 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
252 public Object createService(ContextImpl ctx) {
253 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
254 IAccountManager service = IAccountManager.Stub.asInterface(b);
255 return new AccountManager(ctx, service);
256 }});
257
258 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
259 public Object createService(ContextImpl ctx) {
260 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
261 }});
262
263 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
264 public Object createStaticService() {
265 IBinder b = ServiceManager.getService(ALARM_SERVICE);
266 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
267 return new AlarmManager(service);
268 }});
269
270 registerService(AUDIO_SERVICE, new ServiceFetcher() {
271 public Object createService(ContextImpl ctx) {
272 return new AudioManager(ctx);
273 }});
274
275 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
276 public Object createService(ContextImpl ctx) {
277 return new ClipboardManager(ctx.getOuterContext(),
278 ctx.mMainThread.getHandler());
279 }});
280
281 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
282 public Object createStaticService() {
283 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
284 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
285 }});
286
287 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
288 public Object createStaticService() {
289 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
290 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
291 }});
292
293 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
294 public Object createService(ContextImpl ctx) {
295 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
296 }});
297
298 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
299 public Object createService(ContextImpl ctx) {
300 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
301 }});
302
Nick Pellyd2507462010-12-13 12:22:34 -0800303 registerService(NFC_SERVICE, new ServiceFetcher() {
304 public Object createService(ContextImpl ctx) {
305 return new NfcManager(ctx);
306 }});
307
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800308 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
309 public Object createStaticService() {
310 return createDropBoxManager();
311 }});
312
313 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
314 public Object createService(ContextImpl ctx) {
315 return InputMethodManager.getInstance(ctx);
316 }});
317
318 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
319 public Object getService(ContextImpl ctx) {
320 // TODO: why isn't this caching it? It wasn't
321 // before, so I'm preserving the old behavior and
322 // using getService(), instead of createService()
323 // which would do the caching.
324 return new KeyguardManager();
325 }});
326
327 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
328 public Object createService(ContextImpl ctx) {
329 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
330 }});
331
332 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
333 public Object createStaticService() {
334 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
335 return new LocationManager(ILocationManager.Stub.asInterface(b));
336 }});
337
338 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
339 public Object createService(ContextImpl ctx) {
340 final Context outerContext = ctx.getOuterContext();
341 return new NotificationManager(
342 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800343 Resources.selectSystemTheme(0,
344 outerContext.getApplicationInfo().targetSdkVersion,
345 com.android.internal.R.style.Theme_Dialog,
346 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800347 ctx.mMainThread.getHandler());
348 }});
349
350 // Note: this was previously cached in a static variable, but
351 // constructed using mMainThread.getHandler(), so converting
352 // it to be a regular Context-cached service...
353 registerService(POWER_SERVICE, new ServiceFetcher() {
354 public Object createService(ContextImpl ctx) {
355 IBinder b = ServiceManager.getService(POWER_SERVICE);
356 IPowerManager service = IPowerManager.Stub.asInterface(b);
357 return new PowerManager(service, ctx.mMainThread.getHandler());
358 }});
359
360 registerService(SEARCH_SERVICE, new ServiceFetcher() {
361 public Object createService(ContextImpl ctx) {
362 return new SearchManager(ctx.getOuterContext(),
363 ctx.mMainThread.getHandler());
364 }});
365
366 registerService(SENSOR_SERVICE, new ServiceFetcher() {
367 public Object createService(ContextImpl ctx) {
368 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
369 }});
370
371 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
372 public Object createService(ContextImpl ctx) {
373 return new StatusBarManager(ctx.getOuterContext());
374 }});
375
376 registerService(STORAGE_SERVICE, new ServiceFetcher() {
377 public Object createService(ContextImpl ctx) {
378 try {
379 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
380 } catch (RemoteException rex) {
381 Log.e(TAG, "Failed to create StorageManager", rex);
382 return null;
383 }
384 }});
385
386 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
387 public Object createService(ContextImpl ctx) {
388 return new TelephonyManager(ctx.getOuterContext());
389 }});
390
391 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
392 public Object createStaticService() {
393 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
394 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
395 }});
396
397 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
398 public Object createService(ContextImpl ctx) {
399 return new UiModeManager();
400 }});
401
402 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
403 public Object createService(ContextImpl ctx) {
404 return new Vibrator();
405 }});
406
407 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
408
409 registerService(WIFI_SERVICE, new ServiceFetcher() {
410 public Object createService(ContextImpl ctx) {
411 IBinder b = ServiceManager.getService(WIFI_SERVICE);
412 IWifiManager service = IWifiManager.Stub.asInterface(b);
413 return new WifiManager(service, ctx.mMainThread.getHandler());
414 }});
415
416 registerService(WINDOW_SERVICE, new ServiceFetcher() {
417 public Object getService(ContextImpl ctx) {
418 return WindowManagerImpl.getDefault();
419 }});
420 }
421
422 // The system service cache for the system services that are
423 // cached per-ContextImpl. Package-scoped to avoid accessor
424 // methods.
425 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 @Override
428 public AssetManager getAssets() {
429 return mResources.getAssets();
430 }
431
432 @Override
433 public Resources getResources() {
434 return mResources;
435 }
436
437 @Override
438 public PackageManager getPackageManager() {
439 if (mPackageManager != null) {
440 return mPackageManager;
441 }
442
443 IPackageManager pm = ActivityThread.getPackageManager();
444 if (pm != null) {
445 // Doesn't matter if we make more than one instance.
446 return (mPackageManager = new ApplicationPackageManager(this, pm));
447 }
448
449 return null;
450 }
451
452 @Override
453 public ContentResolver getContentResolver() {
454 return mContentResolver;
455 }
456
457 @Override
458 public Looper getMainLooper() {
459 return mMainThread.getLooper();
460 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200461
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800462 @Override
463 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700464 return (mPackageInfo != null) ?
465 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200467
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468 @Override
469 public void setTheme(int resid) {
470 mThemeResource = resid;
471 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200472
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800474 public int getThemeResId() {
475 return mThemeResource;
476 }
477
478 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 public Resources.Theme getTheme() {
480 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800481 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
482 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800483 mTheme = mResources.newTheme();
484 mTheme.applyStyle(mThemeResource, true);
485 }
486 return mTheme;
487 }
488
489 @Override
490 public ClassLoader getClassLoader() {
491 return mPackageInfo != null ?
492 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
493 }
494
495 @Override
496 public String getPackageName() {
497 if (mPackageInfo != null) {
498 return mPackageInfo.getPackageName();
499 }
500 throw new RuntimeException("Not supported in system context");
501 }
502
503 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700504 public ApplicationInfo getApplicationInfo() {
505 if (mPackageInfo != null) {
506 return mPackageInfo.getApplicationInfo();
507 }
508 throw new RuntimeException("Not supported in system context");
509 }
510
511 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 public String getPackageResourcePath() {
513 if (mPackageInfo != null) {
514 return mPackageInfo.getResDir();
515 }
516 throw new RuntimeException("Not supported in system context");
517 }
518
519 @Override
520 public String getPackageCodePath() {
521 if (mPackageInfo != null) {
522 return mPackageInfo.getAppDir();
523 }
524 throw new RuntimeException("Not supported in system context");
525 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200526
Joe Onorato23ecae32009-06-10 17:07:15 -0700527 public File getSharedPrefsFile(String name) {
528 return makeFilename(getPreferencesDir(), name + ".xml");
529 }
530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 @Override
532 public SharedPreferences getSharedPreferences(String name, int mode) {
533 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700535 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700536 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800537 File prefsFile = getSharedPrefsFile(name);
538 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700539 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700540 return sp;
541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800543 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
544 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
545 // If somebody else (some other process) changed the prefs
546 // file behind our back, we reload it. This has been the
547 // historical (if undocumented) behavior.
548 sp.startReloadIfChangedUnexpectedly();
549 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700550 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800551 }
552
553 private File getPreferencesDir() {
554 synchronized (mSync) {
555 if (mPreferencesDir == null) {
556 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
557 }
558 return mPreferencesDir;
559 }
560 }
561
562 @Override
563 public FileInputStream openFileInput(String name)
564 throws FileNotFoundException {
565 File f = makeFilename(getFilesDir(), name);
566 return new FileInputStream(f);
567 }
568
569 @Override
570 public FileOutputStream openFileOutput(String name, int mode)
571 throws FileNotFoundException {
572 final boolean append = (mode&MODE_APPEND) != 0;
573 File f = makeFilename(getFilesDir(), name);
574 try {
575 FileOutputStream fos = new FileOutputStream(f, append);
576 setFilePermissionsFromMode(f.getPath(), mode, 0);
577 return fos;
578 } catch (FileNotFoundException e) {
579 }
580
581 File parent = f.getParentFile();
582 parent.mkdir();
583 FileUtils.setPermissions(
584 parent.getPath(),
585 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
586 -1, -1);
587 FileOutputStream fos = new FileOutputStream(f, append);
588 setFilePermissionsFromMode(f.getPath(), mode, 0);
589 return fos;
590 }
591
592 @Override
593 public boolean deleteFile(String name) {
594 File f = makeFilename(getFilesDir(), name);
595 return f.delete();
596 }
597
598 @Override
599 public File getFilesDir() {
600 synchronized (mSync) {
601 if (mFilesDir == null) {
602 mFilesDir = new File(getDataDirFile(), "files");
603 }
604 if (!mFilesDir.exists()) {
605 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200606 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 return null;
608 }
609 FileUtils.setPermissions(
610 mFilesDir.getPath(),
611 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
612 -1, -1);
613 }
614 return mFilesDir;
615 }
616 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800619 public File getExternalFilesDir(String type) {
620 synchronized (mSync) {
621 if (mExternalFilesDir == null) {
622 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
623 getPackageName());
624 }
625 if (!mExternalFilesDir.exists()) {
626 try {
627 (new File(Environment.getExternalStorageAndroidDataDir(),
628 ".nomedia")).createNewFile();
629 } catch (IOException e) {
630 }
631 if (!mExternalFilesDir.mkdirs()) {
632 Log.w(TAG, "Unable to create external files directory");
633 return null;
634 }
635 }
636 if (type == null) {
637 return mExternalFilesDir;
638 }
639 File dir = new File(mExternalFilesDir, type);
640 if (!dir.exists()) {
641 if (!dir.mkdirs()) {
642 Log.w(TAG, "Unable to create external media directory " + dir);
643 return null;
644 }
645 }
646 return dir;
647 }
648 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200649
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800650 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800651 public File getObbDir() {
652 synchronized (mSync) {
653 if (mObbDir == null) {
654 mObbDir = Environment.getExternalStorageAppObbDirectory(
655 getPackageName());
656 }
657 return mObbDir;
658 }
659 }
660
661 @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}