blob: e133ea02e29f30af7e8b9f6cec0a72eadd03dae4 [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 Hackborne83cefce2010-02-04 17:38:14 -0800156 private File mExternalFilesDir;
157 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private static final String[] EMPTY_FILE_LIST = {};
160
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800161 /**
162 * Override this class when the system service constructor needs a
163 * ContextImpl. Else, use StaticServiceFetcher below.
164 */
165 /*package*/ static class ServiceFetcher {
166 int mContextCacheIndex = -1;
167
168 /**
169 * Main entrypoint; only override if you don't need caching.
170 */
171 public Object getService(ContextImpl ctx) {
172 ArrayList<Object> cache = ctx.mServiceCache;
173 Object service;
174 synchronized (cache) {
175 if (cache.size() == 0) {
176 // Initialize the cache vector on first access.
177 // At this point sNextPerContextServiceCacheIndex
178 // is the number of potential services that are
179 // cached per-Context.
180 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
181 cache.add(null);
182 }
183 } else {
184 service = cache.get(mContextCacheIndex);
185 if (service != null) {
186 return service;
187 }
188 }
189 service = createService(ctx);
190 cache.set(mContextCacheIndex, service);
191 return service;
192 }
193 }
194
195 /**
196 * Override this to create a new per-Context instance of the
197 * service. getService() will handle locking and caching.
198 */
199 public Object createService(ContextImpl ctx) {
200 throw new RuntimeException("Not implemented");
201 }
202 }
203
204 /**
205 * Override this class for services to be cached process-wide.
206 */
207 abstract static class StaticServiceFetcher extends ServiceFetcher {
208 private Object mCachedInstance;
209
210 @Override
211 public final Object getService(ContextImpl unused) {
212 synchronized (StaticServiceFetcher.this) {
213 Object service = mCachedInstance;
214 if (service != null) {
215 return service;
216 }
217 return mCachedInstance = createStaticService();
218 }
219 }
220
221 public abstract Object createStaticService();
222 }
223
224 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
225 new HashMap<String, ServiceFetcher>();
226
227 private static int sNextPerContextServiceCacheIndex = 0;
228 private static void registerService(String serviceName, ServiceFetcher fetcher) {
229 if (!(fetcher instanceof StaticServiceFetcher)) {
230 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
231 }
232 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
233 }
234
235 // This one's defined separately and given a variable name so it
236 // can be re-used by getWallpaperManager(), avoiding a HashMap
237 // lookup.
238 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
239 public Object createService(ContextImpl ctx) {
240 return new WallpaperManager(ctx.getOuterContext(),
241 ctx.mMainThread.getHandler());
242 }};
243
244 static {
245 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
246 public Object getService(ContextImpl ctx) {
247 return AccessibilityManager.getInstance(ctx);
248 }});
249
250 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
251 public Object createService(ContextImpl ctx) {
252 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
253 IAccountManager service = IAccountManager.Stub.asInterface(b);
254 return new AccountManager(ctx, service);
255 }});
256
257 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
258 public Object createService(ContextImpl ctx) {
259 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
260 }});
261
262 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
263 public Object createStaticService() {
264 IBinder b = ServiceManager.getService(ALARM_SERVICE);
265 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
266 return new AlarmManager(service);
267 }});
268
269 registerService(AUDIO_SERVICE, new ServiceFetcher() {
270 public Object createService(ContextImpl ctx) {
271 return new AudioManager(ctx);
272 }});
273
274 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
275 public Object createService(ContextImpl ctx) {
276 return new ClipboardManager(ctx.getOuterContext(),
277 ctx.mMainThread.getHandler());
278 }});
279
280 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
281 public Object createStaticService() {
282 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
283 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
284 }});
285
286 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
287 public Object createStaticService() {
288 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
289 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
290 }});
291
292 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
293 public Object createService(ContextImpl ctx) {
294 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
295 }});
296
297 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
298 public Object createService(ContextImpl ctx) {
299 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
300 }});
301
Nick Pellyd2507462010-12-13 12:22:34 -0800302 registerService(NFC_SERVICE, new ServiceFetcher() {
303 public Object createService(ContextImpl ctx) {
304 return new NfcManager(ctx);
305 }});
306
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800307 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
308 public Object createStaticService() {
309 return createDropBoxManager();
310 }});
311
312 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
313 public Object createService(ContextImpl ctx) {
314 return InputMethodManager.getInstance(ctx);
315 }});
316
317 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
318 public Object getService(ContextImpl ctx) {
319 // TODO: why isn't this caching it? It wasn't
320 // before, so I'm preserving the old behavior and
321 // using getService(), instead of createService()
322 // which would do the caching.
323 return new KeyguardManager();
324 }});
325
326 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
327 public Object createService(ContextImpl ctx) {
328 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
329 }});
330
331 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
332 public Object createStaticService() {
333 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
334 return new LocationManager(ILocationManager.Stub.asInterface(b));
335 }});
336
337 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
338 public Object createService(ContextImpl ctx) {
339 final Context outerContext = ctx.getOuterContext();
340 return new NotificationManager(
341 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800342 Resources.selectSystemTheme(0,
343 outerContext.getApplicationInfo().targetSdkVersion,
344 com.android.internal.R.style.Theme_Dialog,
345 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800346 ctx.mMainThread.getHandler());
347 }});
348
349 // Note: this was previously cached in a static variable, but
350 // constructed using mMainThread.getHandler(), so converting
351 // it to be a regular Context-cached service...
352 registerService(POWER_SERVICE, new ServiceFetcher() {
353 public Object createService(ContextImpl ctx) {
354 IBinder b = ServiceManager.getService(POWER_SERVICE);
355 IPowerManager service = IPowerManager.Stub.asInterface(b);
356 return new PowerManager(service, ctx.mMainThread.getHandler());
357 }});
358
359 registerService(SEARCH_SERVICE, new ServiceFetcher() {
360 public Object createService(ContextImpl ctx) {
361 return new SearchManager(ctx.getOuterContext(),
362 ctx.mMainThread.getHandler());
363 }});
364
365 registerService(SENSOR_SERVICE, new ServiceFetcher() {
366 public Object createService(ContextImpl ctx) {
367 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
368 }});
369
370 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
371 public Object createService(ContextImpl ctx) {
372 return new StatusBarManager(ctx.getOuterContext());
373 }});
374
375 registerService(STORAGE_SERVICE, new ServiceFetcher() {
376 public Object createService(ContextImpl ctx) {
377 try {
378 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
379 } catch (RemoteException rex) {
380 Log.e(TAG, "Failed to create StorageManager", rex);
381 return null;
382 }
383 }});
384
385 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
386 public Object createService(ContextImpl ctx) {
387 return new TelephonyManager(ctx.getOuterContext());
388 }});
389
390 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
391 public Object createStaticService() {
392 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
393 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
394 }});
395
396 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
397 public Object createService(ContextImpl ctx) {
398 return new UiModeManager();
399 }});
400
401 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
402 public Object createService(ContextImpl ctx) {
403 return new Vibrator();
404 }});
405
406 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
407
408 registerService(WIFI_SERVICE, new ServiceFetcher() {
409 public Object createService(ContextImpl ctx) {
410 IBinder b = ServiceManager.getService(WIFI_SERVICE);
411 IWifiManager service = IWifiManager.Stub.asInterface(b);
412 return new WifiManager(service, ctx.mMainThread.getHandler());
413 }});
414
415 registerService(WINDOW_SERVICE, new ServiceFetcher() {
416 public Object getService(ContextImpl ctx) {
417 return WindowManagerImpl.getDefault();
418 }});
419 }
420
421 // The system service cache for the system services that are
422 // cached per-ContextImpl. Package-scoped to avoid accessor
423 // methods.
424 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
425
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 @Override
427 public AssetManager getAssets() {
428 return mResources.getAssets();
429 }
430
431 @Override
432 public Resources getResources() {
433 return mResources;
434 }
435
436 @Override
437 public PackageManager getPackageManager() {
438 if (mPackageManager != null) {
439 return mPackageManager;
440 }
441
442 IPackageManager pm = ActivityThread.getPackageManager();
443 if (pm != null) {
444 // Doesn't matter if we make more than one instance.
445 return (mPackageManager = new ApplicationPackageManager(this, pm));
446 }
447
448 return null;
449 }
450
451 @Override
452 public ContentResolver getContentResolver() {
453 return mContentResolver;
454 }
455
456 @Override
457 public Looper getMainLooper() {
458 return mMainThread.getLooper();
459 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 @Override
462 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700463 return (mPackageInfo != null) ?
464 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800467 @Override
468 public void setTheme(int resid) {
469 mThemeResource = resid;
470 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800473 public int getThemeResId() {
474 return mThemeResource;
475 }
476
477 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 public Resources.Theme getTheme() {
479 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800480 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
481 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 mTheme = mResources.newTheme();
483 mTheme.applyStyle(mThemeResource, true);
484 }
485 return mTheme;
486 }
487
488 @Override
489 public ClassLoader getClassLoader() {
490 return mPackageInfo != null ?
491 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
492 }
493
494 @Override
495 public String getPackageName() {
496 if (mPackageInfo != null) {
497 return mPackageInfo.getPackageName();
498 }
499 throw new RuntimeException("Not supported in system context");
500 }
501
502 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700503 public ApplicationInfo getApplicationInfo() {
504 if (mPackageInfo != null) {
505 return mPackageInfo.getApplicationInfo();
506 }
507 throw new RuntimeException("Not supported in system context");
508 }
509
510 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 public String getPackageResourcePath() {
512 if (mPackageInfo != null) {
513 return mPackageInfo.getResDir();
514 }
515 throw new RuntimeException("Not supported in system context");
516 }
517
518 @Override
519 public String getPackageCodePath() {
520 if (mPackageInfo != null) {
521 return mPackageInfo.getAppDir();
522 }
523 throw new RuntimeException("Not supported in system context");
524 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200525
Joe Onorato23ecae32009-06-10 17:07:15 -0700526 public File getSharedPrefsFile(String name) {
527 return makeFilename(getPreferencesDir(), name + ".xml");
528 }
529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 @Override
531 public SharedPreferences getSharedPreferences(String name, int mode) {
532 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800533 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700534 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700535 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800536 File prefsFile = getSharedPrefsFile(name);
537 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700538 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700539 return sp;
540 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800542 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
543 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
544 // If somebody else (some other process) changed the prefs
545 // file behind our back, we reload it. This has been the
546 // historical (if undocumented) behavior.
547 sp.startReloadIfChangedUnexpectedly();
548 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700549 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800550 }
551
552 private File getPreferencesDir() {
553 synchronized (mSync) {
554 if (mPreferencesDir == null) {
555 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
556 }
557 return mPreferencesDir;
558 }
559 }
560
561 @Override
562 public FileInputStream openFileInput(String name)
563 throws FileNotFoundException {
564 File f = makeFilename(getFilesDir(), name);
565 return new FileInputStream(f);
566 }
567
568 @Override
569 public FileOutputStream openFileOutput(String name, int mode)
570 throws FileNotFoundException {
571 final boolean append = (mode&MODE_APPEND) != 0;
572 File f = makeFilename(getFilesDir(), name);
573 try {
574 FileOutputStream fos = new FileOutputStream(f, append);
575 setFilePermissionsFromMode(f.getPath(), mode, 0);
576 return fos;
577 } catch (FileNotFoundException e) {
578 }
579
580 File parent = f.getParentFile();
581 parent.mkdir();
582 FileUtils.setPermissions(
583 parent.getPath(),
584 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
585 -1, -1);
586 FileOutputStream fos = new FileOutputStream(f, append);
587 setFilePermissionsFromMode(f.getPath(), mode, 0);
588 return fos;
589 }
590
591 @Override
592 public boolean deleteFile(String name) {
593 File f = makeFilename(getFilesDir(), name);
594 return f.delete();
595 }
596
597 @Override
598 public File getFilesDir() {
599 synchronized (mSync) {
600 if (mFilesDir == null) {
601 mFilesDir = new File(getDataDirFile(), "files");
602 }
603 if (!mFilesDir.exists()) {
604 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200605 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 return null;
607 }
608 FileUtils.setPermissions(
609 mFilesDir.getPath(),
610 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
611 -1, -1);
612 }
613 return mFilesDir;
614 }
615 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800618 public File getExternalFilesDir(String type) {
619 synchronized (mSync) {
620 if (mExternalFilesDir == null) {
621 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
622 getPackageName());
623 }
624 if (!mExternalFilesDir.exists()) {
625 try {
626 (new File(Environment.getExternalStorageAndroidDataDir(),
627 ".nomedia")).createNewFile();
628 } catch (IOException e) {
629 }
630 if (!mExternalFilesDir.mkdirs()) {
631 Log.w(TAG, "Unable to create external files directory");
632 return null;
633 }
634 }
635 if (type == null) {
636 return mExternalFilesDir;
637 }
638 File dir = new File(mExternalFilesDir, type);
639 if (!dir.exists()) {
640 if (!dir.mkdirs()) {
641 Log.w(TAG, "Unable to create external media directory " + dir);
642 return null;
643 }
644 }
645 return dir;
646 }
647 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200648
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800649 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 public File getCacheDir() {
651 synchronized (mSync) {
652 if (mCacheDir == null) {
653 mCacheDir = new File(getDataDirFile(), "cache");
654 }
655 if (!mCacheDir.exists()) {
656 if(!mCacheDir.mkdirs()) {
657 Log.w(TAG, "Unable to create cache directory");
658 return null;
659 }
660 FileUtils.setPermissions(
661 mCacheDir.getPath(),
662 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
663 -1, -1);
664 }
665 }
666 return mCacheDir;
667 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200668
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800669 @Override
670 public File getExternalCacheDir() {
671 synchronized (mSync) {
672 if (mExternalCacheDir == null) {
673 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
674 getPackageName());
675 }
676 if (!mExternalCacheDir.exists()) {
677 try {
678 (new File(Environment.getExternalStorageAndroidDataDir(),
679 ".nomedia")).createNewFile();
680 } catch (IOException e) {
681 }
682 if (!mExternalCacheDir.mkdirs()) {
683 Log.w(TAG, "Unable to create external cache directory");
684 return null;
685 }
686 }
687 return mExternalCacheDir;
688 }
689 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 @Override
692 public File getFileStreamPath(String name) {
693 return makeFilename(getFilesDir(), name);
694 }
695
696 @Override
697 public String[] fileList() {
698 final String[] list = getFilesDir().list();
699 return (list != null) ? list : EMPTY_FILE_LIST;
700 }
701
702 @Override
703 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800704 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
706 setFilePermissionsFromMode(f.getPath(), mode, 0);
707 return db;
708 }
709
710 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700711 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
712 DatabaseErrorHandler errorHandler) {
713 File f = validateFilePath(name, true);
714 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
715 setFilePermissionsFromMode(f.getPath(), mode, 0);
716 return db;
717 }
718
719 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800720 public boolean deleteDatabase(String name) {
721 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800722 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 return f.delete();
724 } catch (Exception e) {
725 }
726 return false;
727 }
728
729 @Override
730 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800731 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 }
733
734 @Override
735 public String[] databaseList() {
736 final String[] list = getDatabasesDir().list();
737 return (list != null) ? list : EMPTY_FILE_LIST;
738 }
739
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741 private File getDatabasesDir() {
742 synchronized (mSync) {
743 if (mDatabasesDir == null) {
744 mDatabasesDir = new File(getDataDirFile(), "databases");
745 }
746 if (mDatabasesDir.getPath().equals("databases")) {
747 mDatabasesDir = new File("/data/system");
748 }
749 return mDatabasesDir;
750 }
751 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 @Override
754 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700755 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 }
757
758 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700759 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700760 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 }
762
763 @Override
764 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700765 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 }
767
768 @Override
769 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700770 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800771 }
772
773 @Override
774 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700775 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
778 @Override
779 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700780 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 }
782
783 @Override
784 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700785 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 }
787
788 @Override
789 public void startActivity(Intent intent) {
790 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
791 throw new AndroidRuntimeException(
792 "Calling startActivity() from outside of an Activity "
793 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
794 + " Is this really what you want?");
795 }
796 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700797 getOuterContext(), mMainThread.getApplicationThread(), null,
798 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 }
800
801 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800802 public void startActivities(Intent[] intents) {
803 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
804 throw new AndroidRuntimeException(
805 "Calling startActivities() from outside of an Activity "
806 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
807 + " Is this really what you want?");
808 }
809 mMainThread.getInstrumentation().execStartActivities(
810 getOuterContext(), mMainThread.getApplicationThread(), null,
811 (Activity)null, intents);
812 }
813
814 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700815 public void startIntentSender(IntentSender intent,
816 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
817 throws IntentSender.SendIntentException {
818 try {
819 String resolvedType = null;
820 if (fillInIntent != null) {
821 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
822 }
823 int result = ActivityManagerNative.getDefault()
824 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
825 fillInIntent, resolvedType, null, null,
826 0, flagsMask, flagsValues);
827 if (result == IActivityManager.START_CANCELED) {
828 throw new IntentSender.SendIntentException();
829 }
830 Instrumentation.checkStartActivityResult(result, null);
831 } catch (RemoteException e) {
832 }
833 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200834
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700835 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 public void sendBroadcast(Intent intent) {
837 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
838 try {
839 ActivityManagerNative.getDefault().broadcastIntent(
840 mMainThread.getApplicationThread(), intent, resolvedType, null,
841 Activity.RESULT_OK, null, null, null, false, false);
842 } catch (RemoteException e) {
843 }
844 }
845
846 @Override
847 public void sendBroadcast(Intent intent, String receiverPermission) {
848 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
849 try {
850 ActivityManagerNative.getDefault().broadcastIntent(
851 mMainThread.getApplicationThread(), intent, resolvedType, null,
852 Activity.RESULT_OK, null, null, receiverPermission, false, false);
853 } catch (RemoteException e) {
854 }
855 }
856
857 @Override
858 public void sendOrderedBroadcast(Intent intent,
859 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, true, false);
865 } catch (RemoteException e) {
866 }
867 }
868
869 @Override
870 public void sendOrderedBroadcast(Intent intent,
871 String receiverPermission, BroadcastReceiver resultReceiver,
872 Handler scheduler, int initialCode, String initialData,
873 Bundle initialExtras) {
874 IIntentReceiver rd = null;
875 if (resultReceiver != null) {
876 if (mPackageInfo != null) {
877 if (scheduler == null) {
878 scheduler = mMainThread.getHandler();
879 }
880 rd = mPackageInfo.getReceiverDispatcher(
881 resultReceiver, getOuterContext(), scheduler,
882 mMainThread.getInstrumentation(), false);
883 } else {
884 if (scheduler == null) {
885 scheduler = mMainThread.getHandler();
886 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700887 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
889 }
890 }
891 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
892 try {
893 ActivityManagerNative.getDefault().broadcastIntent(
894 mMainThread.getApplicationThread(), intent, resolvedType, rd,
895 initialCode, initialData, initialExtras, receiverPermission,
896 true, false);
897 } catch (RemoteException e) {
898 }
899 }
900
901 @Override
902 public void sendStickyBroadcast(Intent intent) {
903 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
904 try {
905 ActivityManagerNative.getDefault().broadcastIntent(
906 mMainThread.getApplicationThread(), intent, resolvedType, null,
907 Activity.RESULT_OK, null, null, null, false, true);
908 } catch (RemoteException e) {
909 }
910 }
911
912 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700913 public void sendStickyOrderedBroadcast(Intent intent,
914 BroadcastReceiver resultReceiver,
915 Handler scheduler, int initialCode, String initialData,
916 Bundle initialExtras) {
917 IIntentReceiver rd = null;
918 if (resultReceiver != null) {
919 if (mPackageInfo != null) {
920 if (scheduler == null) {
921 scheduler = mMainThread.getHandler();
922 }
923 rd = mPackageInfo.getReceiverDispatcher(
924 resultReceiver, getOuterContext(), scheduler,
925 mMainThread.getInstrumentation(), false);
926 } else {
927 if (scheduler == null) {
928 scheduler = mMainThread.getHandler();
929 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700930 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700931 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
932 }
933 }
934 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
935 try {
936 ActivityManagerNative.getDefault().broadcastIntent(
937 mMainThread.getApplicationThread(), intent, resolvedType, rd,
938 initialCode, initialData, initialExtras, null,
939 true, true);
940 } catch (RemoteException e) {
941 }
942 }
943
944 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 public void removeStickyBroadcast(Intent intent) {
946 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
947 if (resolvedType != null) {
948 intent = new Intent(intent);
949 intent.setDataAndType(intent.getData(), resolvedType);
950 }
951 try {
952 ActivityManagerNative.getDefault().unbroadcastIntent(
953 mMainThread.getApplicationThread(), intent);
954 } catch (RemoteException e) {
955 }
956 }
957
958 @Override
959 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
960 return registerReceiver(receiver, filter, null, null);
961 }
962
963 @Override
964 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
965 String broadcastPermission, Handler scheduler) {
966 return registerReceiverInternal(receiver, filter, broadcastPermission,
967 scheduler, getOuterContext());
968 }
969
970 private Intent registerReceiverInternal(BroadcastReceiver receiver,
971 IntentFilter filter, String broadcastPermission,
972 Handler scheduler, Context context) {
973 IIntentReceiver rd = null;
974 if (receiver != null) {
975 if (mPackageInfo != null && context != null) {
976 if (scheduler == null) {
977 scheduler = mMainThread.getHandler();
978 }
979 rd = mPackageInfo.getReceiverDispatcher(
980 receiver, context, scheduler,
981 mMainThread.getInstrumentation(), true);
982 } else {
983 if (scheduler == null) {
984 scheduler = mMainThread.getHandler();
985 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700986 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700987 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 }
989 }
990 try {
991 return ActivityManagerNative.getDefault().registerReceiver(
992 mMainThread.getApplicationThread(),
993 rd, filter, broadcastPermission);
994 } catch (RemoteException e) {
995 return null;
996 }
997 }
998
999 @Override
1000 public void unregisterReceiver(BroadcastReceiver receiver) {
1001 if (mPackageInfo != null) {
1002 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1003 getOuterContext(), receiver);
1004 try {
1005 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1006 } catch (RemoteException e) {
1007 }
1008 } else {
1009 throw new RuntimeException("Not supported in system context");
1010 }
1011 }
1012
1013 @Override
1014 public ComponentName startService(Intent service) {
1015 try {
1016 ComponentName cn = ActivityManagerNative.getDefault().startService(
1017 mMainThread.getApplicationThread(), service,
1018 service.resolveTypeIfNeeded(getContentResolver()));
1019 if (cn != null && cn.getPackageName().equals("!")) {
1020 throw new SecurityException(
1021 "Not allowed to start service " + service
1022 + " without permission " + cn.getClassName());
1023 }
1024 return cn;
1025 } catch (RemoteException e) {
1026 return null;
1027 }
1028 }
1029
1030 @Override
1031 public boolean stopService(Intent service) {
1032 try {
1033 int res = ActivityManagerNative.getDefault().stopService(
1034 mMainThread.getApplicationThread(), service,
1035 service.resolveTypeIfNeeded(getContentResolver()));
1036 if (res < 0) {
1037 throw new SecurityException(
1038 "Not allowed to stop service " + service);
1039 }
1040 return res != 0;
1041 } catch (RemoteException e) {
1042 return false;
1043 }
1044 }
1045
1046 @Override
1047 public boolean bindService(Intent service, ServiceConnection conn,
1048 int flags) {
1049 IServiceConnection sd;
1050 if (mPackageInfo != null) {
1051 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1052 mMainThread.getHandler(), flags);
1053 } else {
1054 throw new RuntimeException("Not supported in system context");
1055 }
1056 try {
1057 int res = ActivityManagerNative.getDefault().bindService(
1058 mMainThread.getApplicationThread(), getActivityToken(),
1059 service, service.resolveTypeIfNeeded(getContentResolver()),
1060 sd, flags);
1061 if (res < 0) {
1062 throw new SecurityException(
1063 "Not allowed to bind to service " + service);
1064 }
1065 return res != 0;
1066 } catch (RemoteException e) {
1067 return false;
1068 }
1069 }
1070
1071 @Override
1072 public void unbindService(ServiceConnection conn) {
1073 if (mPackageInfo != null) {
1074 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1075 getOuterContext(), conn);
1076 try {
1077 ActivityManagerNative.getDefault().unbindService(sd);
1078 } catch (RemoteException e) {
1079 }
1080 } else {
1081 throw new RuntimeException("Not supported in system context");
1082 }
1083 }
1084
1085 @Override
1086 public boolean startInstrumentation(ComponentName className,
1087 String profileFile, Bundle arguments) {
1088 try {
1089 return ActivityManagerNative.getDefault().startInstrumentation(
1090 className, profileFile, 0, arguments, null);
1091 } catch (RemoteException e) {
1092 // System has crashed, nothing we can do.
1093 }
1094 return false;
1095 }
1096
1097 @Override
1098 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001099 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1100 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 }
1102
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001103 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001104 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 }
1106
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001107 /* package */ static DropBoxManager createDropBoxManager() {
1108 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1109 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001110 if (service == null) {
1111 // Don't return a DropBoxManager that will NPE upon use.
1112 // This also avoids caching a broken DropBoxManager in
1113 // getDropBoxManager during early boot, before the
1114 // DROPBOX_SERVICE is registered.
1115 return null;
1116 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001117 return new DropBoxManager(service);
1118 }
1119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 @Override
1121 public int checkPermission(String permission, int pid, int uid) {
1122 if (permission == null) {
1123 throw new IllegalArgumentException("permission is null");
1124 }
1125
1126 if (!Process.supportsProcesses()) {
1127 return PackageManager.PERMISSION_GRANTED;
1128 }
1129 try {
1130 return ActivityManagerNative.getDefault().checkPermission(
1131 permission, pid, uid);
1132 } catch (RemoteException e) {
1133 return PackageManager.PERMISSION_DENIED;
1134 }
1135 }
1136
1137 @Override
1138 public int checkCallingPermission(String permission) {
1139 if (permission == null) {
1140 throw new IllegalArgumentException("permission is null");
1141 }
1142
1143 if (!Process.supportsProcesses()) {
1144 return PackageManager.PERMISSION_GRANTED;
1145 }
1146 int pid = Binder.getCallingPid();
1147 if (pid != Process.myPid()) {
1148 return checkPermission(permission, pid,
1149 Binder.getCallingUid());
1150 }
1151 return PackageManager.PERMISSION_DENIED;
1152 }
1153
1154 @Override
1155 public int checkCallingOrSelfPermission(String permission) {
1156 if (permission == null) {
1157 throw new IllegalArgumentException("permission is null");
1158 }
1159
1160 return checkPermission(permission, Binder.getCallingPid(),
1161 Binder.getCallingUid());
1162 }
1163
1164 private void enforce(
1165 String permission, int resultOfCheck,
1166 boolean selfToo, int uid, String message) {
1167 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1168 throw new SecurityException(
1169 (message != null ? (message + ": ") : "") +
1170 (selfToo
1171 ? "Neither user " + uid + " nor current process has "
1172 : "User " + uid + " does not have ") +
1173 permission +
1174 ".");
1175 }
1176 }
1177
1178 public void enforcePermission(
1179 String permission, int pid, int uid, String message) {
1180 enforce(permission,
1181 checkPermission(permission, pid, uid),
1182 false,
1183 uid,
1184 message);
1185 }
1186
1187 public void enforceCallingPermission(String permission, String message) {
1188 enforce(permission,
1189 checkCallingPermission(permission),
1190 false,
1191 Binder.getCallingUid(),
1192 message);
1193 }
1194
1195 public void enforceCallingOrSelfPermission(
1196 String permission, String message) {
1197 enforce(permission,
1198 checkCallingOrSelfPermission(permission),
1199 true,
1200 Binder.getCallingUid(),
1201 message);
1202 }
1203
1204 @Override
1205 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1206 try {
1207 ActivityManagerNative.getDefault().grantUriPermission(
1208 mMainThread.getApplicationThread(), toPackage, uri,
1209 modeFlags);
1210 } catch (RemoteException e) {
1211 }
1212 }
1213
1214 @Override
1215 public void revokeUriPermission(Uri uri, int modeFlags) {
1216 try {
1217 ActivityManagerNative.getDefault().revokeUriPermission(
1218 mMainThread.getApplicationThread(), uri,
1219 modeFlags);
1220 } catch (RemoteException e) {
1221 }
1222 }
1223
1224 @Override
1225 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1226 if (!Process.supportsProcesses()) {
1227 return PackageManager.PERMISSION_GRANTED;
1228 }
1229 try {
1230 return ActivityManagerNative.getDefault().checkUriPermission(
1231 uri, pid, uid, modeFlags);
1232 } catch (RemoteException e) {
1233 return PackageManager.PERMISSION_DENIED;
1234 }
1235 }
1236
1237 @Override
1238 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1239 if (!Process.supportsProcesses()) {
1240 return PackageManager.PERMISSION_GRANTED;
1241 }
1242 int pid = Binder.getCallingPid();
1243 if (pid != Process.myPid()) {
1244 return checkUriPermission(uri, pid,
1245 Binder.getCallingUid(), modeFlags);
1246 }
1247 return PackageManager.PERMISSION_DENIED;
1248 }
1249
1250 @Override
1251 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1252 return checkUriPermission(uri, Binder.getCallingPid(),
1253 Binder.getCallingUid(), modeFlags);
1254 }
1255
1256 @Override
1257 public int checkUriPermission(Uri uri, String readPermission,
1258 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001259 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1261 + readPermission + " writePermission=" + writePermission
1262 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1263 }
1264 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1265 if (readPermission == null
1266 || checkPermission(readPermission, pid, uid)
1267 == PackageManager.PERMISSION_GRANTED) {
1268 return PackageManager.PERMISSION_GRANTED;
1269 }
1270 }
1271 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1272 if (writePermission == null
1273 || checkPermission(writePermission, pid, uid)
1274 == PackageManager.PERMISSION_GRANTED) {
1275 return PackageManager.PERMISSION_GRANTED;
1276 }
1277 }
1278 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1279 : PackageManager.PERMISSION_DENIED;
1280 }
1281
1282 private String uriModeFlagToString(int uriModeFlags) {
1283 switch (uriModeFlags) {
1284 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1285 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1286 return "read and write";
1287 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1288 return "read";
1289 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1290 return "write";
1291 }
1292 throw new IllegalArgumentException(
1293 "Unknown permission mode flags: " + uriModeFlags);
1294 }
1295
1296 private void enforceForUri(
1297 int modeFlags, int resultOfCheck, boolean selfToo,
1298 int uid, Uri uri, String message) {
1299 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1300 throw new SecurityException(
1301 (message != null ? (message + ": ") : "") +
1302 (selfToo
1303 ? "Neither user " + uid + " nor current process has "
1304 : "User " + uid + " does not have ") +
1305 uriModeFlagToString(modeFlags) +
1306 " permission on " +
1307 uri +
1308 ".");
1309 }
1310 }
1311
1312 public void enforceUriPermission(
1313 Uri uri, int pid, int uid, int modeFlags, String message) {
1314 enforceForUri(
1315 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1316 false, uid, uri, message);
1317 }
1318
1319 public void enforceCallingUriPermission(
1320 Uri uri, int modeFlags, String message) {
1321 enforceForUri(
1322 modeFlags, checkCallingUriPermission(uri, modeFlags),
1323 false, Binder.getCallingUid(), uri, message);
1324 }
1325
1326 public void enforceCallingOrSelfUriPermission(
1327 Uri uri, int modeFlags, String message) {
1328 enforceForUri(
1329 modeFlags,
1330 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1331 Binder.getCallingUid(), uri, message);
1332 }
1333
1334 public void enforceUriPermission(
1335 Uri uri, String readPermission, String writePermission,
1336 int pid, int uid, int modeFlags, String message) {
1337 enforceForUri(modeFlags,
1338 checkUriPermission(
1339 uri, readPermission, writePermission, pid, uid,
1340 modeFlags),
1341 false,
1342 uid,
1343 uri,
1344 message);
1345 }
1346
1347 @Override
1348 public Context createPackageContext(String packageName, int flags)
1349 throws PackageManager.NameNotFoundException {
1350 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001351 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 }
1353
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001354 LoadedApk pi =
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 mMainThread.getPackageInfo(packageName, flags);
1356 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001357 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001358 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001359 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 if (c.mResources != null) {
1361 return c;
1362 }
1363 }
1364
1365 // Should be a better exception.
1366 throw new PackageManager.NameNotFoundException(
1367 "Application package " + packageName + " not found");
1368 }
1369
Romain Guy870e09f2009-07-06 16:35:25 -07001370 @Override
1371 public boolean isRestricted() {
1372 return mRestricted;
1373 }
1374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 private File getDataDirFile() {
1376 if (mPackageInfo != null) {
1377 return mPackageInfo.getDataDirFile();
1378 }
1379 throw new RuntimeException("Not supported in system context");
1380 }
1381
1382 @Override
1383 public File getDir(String name, int mode) {
1384 name = "app_" + name;
1385 File file = makeFilename(getDataDirFile(), name);
1386 if (!file.exists()) {
1387 file.mkdir();
1388 setFilePermissionsFromMode(file.getPath(), mode,
1389 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1390 }
1391 return file;
1392 }
1393
Dianne Hackborn21556372010-02-04 16:34:40 -08001394 static ContextImpl createSystemContext(ActivityThread mainThread) {
1395 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 context.init(Resources.getSystem(), mainThread);
1397 return context;
1398 }
1399
Dianne Hackborn21556372010-02-04 16:34:40 -08001400 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001401 mOuterContext = this;
1402 }
1403
1404 /**
1405 * Create a new ApplicationContext from an existing one. The new one
1406 * works and operates the same as the one it is copying.
1407 *
1408 * @param context Existing application context.
1409 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001410 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001411 mPackageInfo = context.mPackageInfo;
1412 mResources = context.mResources;
1413 mMainThread = context.mMainThread;
1414 mContentResolver = context.mContentResolver;
1415 mOuterContext = this;
1416 }
1417
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001418 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001420 init(packageInfo, activityToken, mainThread, null);
1421 }
1422
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001423 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001424 IBinder activityToken, ActivityThread mainThread,
1425 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 mPackageInfo = packageInfo;
1427 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001428
Dianne Hackborn559a7872010-04-07 18:19:41 -07001429 if (mResources != null && container != null
1430 && container.getCompatibilityInfo().applicationScale !=
1431 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001432 if (DEBUG) {
1433 Log.d(TAG, "loaded context has different scaling. Using container's" +
1434 " compatiblity info:" + container.getDisplayMetrics());
1435 }
1436 mResources = mainThread.getTopLevelResources(
1437 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1438 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 mMainThread = mainThread;
1440 mContentResolver = new ApplicationContentResolver(this, mainThread);
1441
1442 setActivityToken(activityToken);
1443 }
1444
1445 final void init(Resources resources, ActivityThread mainThread) {
1446 mPackageInfo = null;
1447 mResources = resources;
1448 mMainThread = mainThread;
1449 mContentResolver = new ApplicationContentResolver(this, mainThread);
1450 }
1451
1452 final void scheduleFinalCleanup(String who, String what) {
1453 mMainThread.scheduleContextCleanup(this, who, what);
1454 }
1455
1456 final void performFinalCleanup(String who, String what) {
1457 //Log.i(TAG, "Cleanup up context: " + this);
1458 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1459 }
1460
1461 final Context getReceiverRestrictedContext() {
1462 if (mReceiverRestrictedContext != null) {
1463 return mReceiverRestrictedContext;
1464 }
1465 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1466 }
1467
1468 final void setActivityToken(IBinder token) {
1469 mActivityToken = token;
1470 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 final void setOuterContext(Context context) {
1473 mOuterContext = context;
1474 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 final Context getOuterContext() {
1477 return mOuterContext;
1478 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 final IBinder getActivityToken() {
1481 return mActivityToken;
1482 }
1483
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001484 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 int extraPermissions) {
1486 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1487 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1488 |extraPermissions;
1489 if ((mode&MODE_WORLD_READABLE) != 0) {
1490 perms |= FileUtils.S_IROTH;
1491 }
1492 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1493 perms |= FileUtils.S_IWOTH;
1494 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001495 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1497 + ", perms=0x" + Integer.toHexString(perms));
1498 }
1499 FileUtils.setPermissions(name, perms, -1, -1);
1500 }
1501
Oscar Montemayora8529f62009-11-18 10:14:20 -08001502 private File validateFilePath(String name, boolean createDirectory) {
1503 File dir;
1504 File f;
1505
1506 if (name.charAt(0) == File.separatorChar) {
1507 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1508 dir = new File(dirPath);
1509 name = name.substring(name.lastIndexOf(File.separatorChar));
1510 f = new File(dir, name);
1511 } else {
1512 dir = getDatabasesDir();
1513 f = makeFilename(dir, name);
1514 }
1515
1516 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1517 FileUtils.setPermissions(dir.getPath(),
1518 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1519 -1, -1);
1520 }
1521
1522 return f;
1523 }
1524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 private File makeFilename(File base, String name) {
1526 if (name.indexOf(File.separatorChar) < 0) {
1527 return new File(base, name);
1528 }
1529 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001530 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 }
1532
1533 // ----------------------------------------------------------------------
1534 // ----------------------------------------------------------------------
1535 // ----------------------------------------------------------------------
1536
1537 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001538 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 super(context);
1540 mMainThread = mainThread;
1541 }
1542
1543 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001544 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 return mMainThread.acquireProvider(context, name);
1546 }
1547
1548 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001549 protected IContentProvider acquireExistingProvider(Context context, String name) {
1550 return mMainThread.acquireExistingProvider(context, name);
1551 }
1552
1553 @Override
1554 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 return mMainThread.releaseProvider(provider);
1556 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001557
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 private final ActivityThread mMainThread;
1559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560}