blob: 2bf1fb712304b61a919b4af1a914c3677c1a4c4c [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.BroadcastReceiver;
22import android.content.ComponentName;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.IContentProvider;
27import android.content.Intent;
28import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070029import android.content.IIntentReceiver;
30import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ReceiverCallNotAllowedException;
32import android.content.ServiceConnection;
33import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.pm.PackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.res.AssetManager;
Dianne Hackborn5be8de32011-05-24 18:11:57 -070038import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070040import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.database.sqlite.SQLiteDatabase;
42import android.database.sqlite.SQLiteDatabase.CursorFactory;
43import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.graphics.drawable.Drawable;
45import android.hardware.SensorManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080046import android.hardware.usb.IUsbManager;
47import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080048import android.location.CountryDetector;
49import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.location.ILocationManager;
51import android.location.LocationManager;
52import android.media.AudioManager;
53import android.net.ConnectivityManager;
54import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070055import android.net.INetworkPolicyManager;
56import android.net.NetworkPolicyManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070057import android.net.ThrottleManager;
58import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.net.Uri;
60import android.net.wifi.IWifiManager;
61import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070062import android.net.wifi.p2p.IWifiP2pManager;
63import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080064import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.os.Binder;
66import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080067import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080068import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.os.FileUtils;
70import android.os.Handler;
71import android.os.IBinder;
72import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070073import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.PowerManager;
75import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070076import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.ServiceManager;
78import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080079import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070081import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.util.AndroidRuntimeException;
83import android.util.Log;
84import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090088import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070089import android.accounts.AccountManager;
90import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080091import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080092import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import java.io.File;
95import java.io.FileInputStream;
96import java.io.FileNotFoundException;
97import java.io.FileOutputStream;
98import java.io.IOException;
99import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import java.util.ArrayList;
101import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103class ReceiverRestrictedContext extends ContextWrapper {
104 ReceiverRestrictedContext(Context base) {
105 super(base);
106 }
107
108 @Override
109 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
110 return registerReceiver(receiver, filter, null, null);
111 }
112
113 @Override
114 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
115 String broadcastPermission, Handler scheduler) {
116 throw new ReceiverCallNotAllowedException(
117 "IntentReceiver components are not allowed to register to receive intents");
118 //ex.fillInStackTrace();
119 //Log.e("IntentReceiver", ex.getMessage(), ex);
120 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
121 // scheduler);
122 }
123
124 @Override
125 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
126 throw new ReceiverCallNotAllowedException(
127 "IntentReceiver components are not allowed to bind to services");
128 //ex.fillInStackTrace();
129 //Log.e("IntentReceiver", ex.getMessage(), ex);
130 //return mContext.bindService(service, interfaceName, conn, flags);
131 }
132}
133
134/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800135 * Common implementation of Context API, which provides the base
136 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800138class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700140 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700142 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
143 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700145 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700146 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private Resources mResources;
148 /*package*/ ActivityThread mMainThread;
149 private Context mOuterContext;
150 private IBinder mActivityToken = null;
151 private ApplicationContentResolver mContentResolver;
152 private int mThemeResource = 0;
153 private Resources.Theme mTheme = null;
154 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700156 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157
158 private final Object mSync = new Object();
159
160 private File mDatabasesDir;
161 private File mPreferencesDir;
162 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800164 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800165 private File mExternalFilesDir;
166 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 private static final String[] EMPTY_FILE_LIST = {};
169
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800170 /**
171 * Override this class when the system service constructor needs a
172 * ContextImpl. Else, use StaticServiceFetcher below.
173 */
174 /*package*/ static class ServiceFetcher {
175 int mContextCacheIndex = -1;
176
177 /**
178 * Main entrypoint; only override if you don't need caching.
179 */
180 public Object getService(ContextImpl ctx) {
181 ArrayList<Object> cache = ctx.mServiceCache;
182 Object service;
183 synchronized (cache) {
184 if (cache.size() == 0) {
185 // Initialize the cache vector on first access.
186 // At this point sNextPerContextServiceCacheIndex
187 // is the number of potential services that are
188 // cached per-Context.
189 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
190 cache.add(null);
191 }
192 } else {
193 service = cache.get(mContextCacheIndex);
194 if (service != null) {
195 return service;
196 }
197 }
198 service = createService(ctx);
199 cache.set(mContextCacheIndex, service);
200 return service;
201 }
202 }
203
204 /**
205 * Override this to create a new per-Context instance of the
206 * service. getService() will handle locking and caching.
207 */
208 public Object createService(ContextImpl ctx) {
209 throw new RuntimeException("Not implemented");
210 }
211 }
212
213 /**
214 * Override this class for services to be cached process-wide.
215 */
216 abstract static class StaticServiceFetcher extends ServiceFetcher {
217 private Object mCachedInstance;
218
219 @Override
220 public final Object getService(ContextImpl unused) {
221 synchronized (StaticServiceFetcher.this) {
222 Object service = mCachedInstance;
223 if (service != null) {
224 return service;
225 }
226 return mCachedInstance = createStaticService();
227 }
228 }
229
230 public abstract Object createStaticService();
231 }
232
233 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
234 new HashMap<String, ServiceFetcher>();
235
236 private static int sNextPerContextServiceCacheIndex = 0;
237 private static void registerService(String serviceName, ServiceFetcher fetcher) {
238 if (!(fetcher instanceof StaticServiceFetcher)) {
239 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
240 }
241 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
242 }
243
244 // This one's defined separately and given a variable name so it
245 // can be re-used by getWallpaperManager(), avoiding a HashMap
246 // lookup.
247 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
248 public Object createService(ContextImpl ctx) {
249 return new WallpaperManager(ctx.getOuterContext(),
250 ctx.mMainThread.getHandler());
251 }};
252
253 static {
254 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
255 public Object getService(ContextImpl ctx) {
256 return AccessibilityManager.getInstance(ctx);
257 }});
258
259 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
260 public Object createService(ContextImpl ctx) {
261 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
262 IAccountManager service = IAccountManager.Stub.asInterface(b);
263 return new AccountManager(ctx, service);
264 }});
265
266 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
267 public Object createService(ContextImpl ctx) {
268 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
269 }});
270
271 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
272 public Object createStaticService() {
273 IBinder b = ServiceManager.getService(ALARM_SERVICE);
274 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
275 return new AlarmManager(service);
276 }});
277
278 registerService(AUDIO_SERVICE, new ServiceFetcher() {
279 public Object createService(ContextImpl ctx) {
280 return new AudioManager(ctx);
281 }});
282
283 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
284 public Object createService(ContextImpl ctx) {
285 return new ClipboardManager(ctx.getOuterContext(),
286 ctx.mMainThread.getHandler());
287 }});
288
289 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
290 public Object createStaticService() {
291 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
292 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
293 }});
294
295 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
296 public Object createStaticService() {
297 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
298 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
299 }});
300
301 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
302 public Object createService(ContextImpl ctx) {
303 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
304 }});
305
306 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
307 public Object createService(ContextImpl ctx) {
308 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
309 }});
310
Nick Pellyd2507462010-12-13 12:22:34 -0800311 registerService(NFC_SERVICE, new ServiceFetcher() {
312 public Object createService(ContextImpl ctx) {
313 return new NfcManager(ctx);
314 }});
315
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800316 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
317 public Object createStaticService() {
318 return createDropBoxManager();
319 }});
320
321 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
322 public Object createService(ContextImpl ctx) {
323 return InputMethodManager.getInstance(ctx);
324 }});
325
satok988323c2011-06-22 16:38:13 +0900326 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
327 public Object createService(ContextImpl ctx) {
328 return TextServicesManager.getInstance();
329 }});
330
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800331 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
332 public Object getService(ContextImpl ctx) {
333 // TODO: why isn't this caching it? It wasn't
334 // before, so I'm preserving the old behavior and
335 // using getService(), instead of createService()
336 // which would do the caching.
337 return new KeyguardManager();
338 }});
339
340 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
341 public Object createService(ContextImpl ctx) {
342 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
343 }});
344
345 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
346 public Object createStaticService() {
347 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
348 return new LocationManager(ILocationManager.Stub.asInterface(b));
349 }});
350
Jeff Sharkey1a303952011-06-16 13:04:20 -0700351 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
352 @Override
353 public Object createService(ContextImpl ctx) {
354 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
355 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
356 }
357 });
358
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800359 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
360 public Object createService(ContextImpl ctx) {
361 final Context outerContext = ctx.getOuterContext();
362 return new NotificationManager(
363 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800364 Resources.selectSystemTheme(0,
365 outerContext.getApplicationInfo().targetSdkVersion,
366 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700367 com.android.internal.R.style.Theme_Holo_Dialog,
368 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800369 ctx.mMainThread.getHandler());
370 }});
371
372 // Note: this was previously cached in a static variable, but
373 // constructed using mMainThread.getHandler(), so converting
374 // it to be a regular Context-cached service...
375 registerService(POWER_SERVICE, new ServiceFetcher() {
376 public Object createService(ContextImpl ctx) {
377 IBinder b = ServiceManager.getService(POWER_SERVICE);
378 IPowerManager service = IPowerManager.Stub.asInterface(b);
379 return new PowerManager(service, ctx.mMainThread.getHandler());
380 }});
381
382 registerService(SEARCH_SERVICE, new ServiceFetcher() {
383 public Object createService(ContextImpl ctx) {
384 return new SearchManager(ctx.getOuterContext(),
385 ctx.mMainThread.getHandler());
386 }});
387
388 registerService(SENSOR_SERVICE, new ServiceFetcher() {
389 public Object createService(ContextImpl ctx) {
390 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
391 }});
392
393 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
394 public Object createService(ContextImpl ctx) {
395 return new StatusBarManager(ctx.getOuterContext());
396 }});
397
398 registerService(STORAGE_SERVICE, new ServiceFetcher() {
399 public Object createService(ContextImpl ctx) {
400 try {
401 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
402 } catch (RemoteException rex) {
403 Log.e(TAG, "Failed to create StorageManager", rex);
404 return null;
405 }
406 }});
407
408 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
409 public Object createService(ContextImpl ctx) {
410 return new TelephonyManager(ctx.getOuterContext());
411 }});
412
413 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
414 public Object createStaticService() {
415 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
416 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
417 }});
418
419 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
420 public Object createService(ContextImpl ctx) {
421 return new UiModeManager();
422 }});
423
Mike Lockwood3a68b832011-03-08 10:08:59 -0500424 registerService(USB_SERVICE, new ServiceFetcher() {
425 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500426 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500427 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500428 }});
429
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800430 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
431 public Object createService(ContextImpl ctx) {
432 return new Vibrator();
433 }});
434
435 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
436
437 registerService(WIFI_SERVICE, new ServiceFetcher() {
438 public Object createService(ContextImpl ctx) {
439 IBinder b = ServiceManager.getService(WIFI_SERVICE);
440 IWifiManager service = IWifiManager.Stub.asInterface(b);
441 return new WifiManager(service, ctx.mMainThread.getHandler());
442 }});
443
repo sync55bc5f32011-06-24 14:23:07 -0700444 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
445 public Object createService(ContextImpl ctx) {
446 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
447 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
448 return new WifiP2pManager(service);
449 }});
450
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800451 registerService(WINDOW_SERVICE, new ServiceFetcher() {
452 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700453 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800454 }});
455 }
456
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700457 static ContextImpl getImpl(Context context) {
458 Context nextContext;
459 while ((context instanceof ContextWrapper) &&
460 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
461 context = nextContext;
462 }
463 return (ContextImpl)context;
464 }
465
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800466 // The system service cache for the system services that are
467 // cached per-ContextImpl. Package-scoped to avoid accessor
468 // methods.
469 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 @Override
472 public AssetManager getAssets() {
473 return mResources.getAssets();
474 }
475
476 @Override
477 public Resources getResources() {
478 return mResources;
479 }
480
481 @Override
482 public PackageManager getPackageManager() {
483 if (mPackageManager != null) {
484 return mPackageManager;
485 }
486
487 IPackageManager pm = ActivityThread.getPackageManager();
488 if (pm != null) {
489 // Doesn't matter if we make more than one instance.
490 return (mPackageManager = new ApplicationPackageManager(this, pm));
491 }
492
493 return null;
494 }
495
496 @Override
497 public ContentResolver getContentResolver() {
498 return mContentResolver;
499 }
500
501 @Override
502 public Looper getMainLooper() {
503 return mMainThread.getLooper();
504 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 @Override
507 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700508 return (mPackageInfo != null) ?
509 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800510 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 @Override
513 public void setTheme(int resid) {
514 mThemeResource = resid;
515 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800518 public int getThemeResId() {
519 return mThemeResource;
520 }
521
522 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800523 public Resources.Theme getTheme() {
524 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800525 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
526 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 mTheme = mResources.newTheme();
528 mTheme.applyStyle(mThemeResource, true);
529 }
530 return mTheme;
531 }
532
533 @Override
534 public ClassLoader getClassLoader() {
535 return mPackageInfo != null ?
536 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
537 }
538
539 @Override
540 public String getPackageName() {
541 if (mPackageInfo != null) {
542 return mPackageInfo.getPackageName();
543 }
544 throw new RuntimeException("Not supported in system context");
545 }
546
547 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700548 public ApplicationInfo getApplicationInfo() {
549 if (mPackageInfo != null) {
550 return mPackageInfo.getApplicationInfo();
551 }
552 throw new RuntimeException("Not supported in system context");
553 }
554
555 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 public String getPackageResourcePath() {
557 if (mPackageInfo != null) {
558 return mPackageInfo.getResDir();
559 }
560 throw new RuntimeException("Not supported in system context");
561 }
562
563 @Override
564 public String getPackageCodePath() {
565 if (mPackageInfo != null) {
566 return mPackageInfo.getAppDir();
567 }
568 throw new RuntimeException("Not supported in system context");
569 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200570
Joe Onorato23ecae32009-06-10 17:07:15 -0700571 public File getSharedPrefsFile(String name) {
572 return makeFilename(getPreferencesDir(), name + ".xml");
573 }
574
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 @Override
576 public SharedPreferences getSharedPreferences(String name, int mode) {
577 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700579 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700580 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800581 File prefsFile = getSharedPrefsFile(name);
582 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700583 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700584 return sp;
585 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800587 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
588 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
589 // If somebody else (some other process) changed the prefs
590 // file behind our back, we reload it. This has been the
591 // historical (if undocumented) behavior.
592 sp.startReloadIfChangedUnexpectedly();
593 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700594 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 }
596
597 private File getPreferencesDir() {
598 synchronized (mSync) {
599 if (mPreferencesDir == null) {
600 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
601 }
602 return mPreferencesDir;
603 }
604 }
605
606 @Override
607 public FileInputStream openFileInput(String name)
608 throws FileNotFoundException {
609 File f = makeFilename(getFilesDir(), name);
610 return new FileInputStream(f);
611 }
612
613 @Override
614 public FileOutputStream openFileOutput(String name, int mode)
615 throws FileNotFoundException {
616 final boolean append = (mode&MODE_APPEND) != 0;
617 File f = makeFilename(getFilesDir(), name);
618 try {
619 FileOutputStream fos = new FileOutputStream(f, append);
620 setFilePermissionsFromMode(f.getPath(), mode, 0);
621 return fos;
622 } catch (FileNotFoundException e) {
623 }
624
625 File parent = f.getParentFile();
626 parent.mkdir();
627 FileUtils.setPermissions(
628 parent.getPath(),
629 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
630 -1, -1);
631 FileOutputStream fos = new FileOutputStream(f, append);
632 setFilePermissionsFromMode(f.getPath(), mode, 0);
633 return fos;
634 }
635
636 @Override
637 public boolean deleteFile(String name) {
638 File f = makeFilename(getFilesDir(), name);
639 return f.delete();
640 }
641
642 @Override
643 public File getFilesDir() {
644 synchronized (mSync) {
645 if (mFilesDir == null) {
646 mFilesDir = new File(getDataDirFile(), "files");
647 }
648 if (!mFilesDir.exists()) {
649 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200650 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 return null;
652 }
653 FileUtils.setPermissions(
654 mFilesDir.getPath(),
655 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
656 -1, -1);
657 }
658 return mFilesDir;
659 }
660 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800663 public File getExternalFilesDir(String type) {
664 synchronized (mSync) {
665 if (mExternalFilesDir == null) {
666 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
667 getPackageName());
668 }
669 if (!mExternalFilesDir.exists()) {
670 try {
671 (new File(Environment.getExternalStorageAndroidDataDir(),
672 ".nomedia")).createNewFile();
673 } catch (IOException e) {
674 }
675 if (!mExternalFilesDir.mkdirs()) {
676 Log.w(TAG, "Unable to create external files directory");
677 return null;
678 }
679 }
680 if (type == null) {
681 return mExternalFilesDir;
682 }
683 File dir = new File(mExternalFilesDir, type);
684 if (!dir.exists()) {
685 if (!dir.mkdirs()) {
686 Log.w(TAG, "Unable to create external media directory " + dir);
687 return null;
688 }
689 }
690 return dir;
691 }
692 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200693
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800694 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800695 public File getObbDir() {
696 synchronized (mSync) {
697 if (mObbDir == null) {
698 mObbDir = Environment.getExternalStorageAppObbDirectory(
699 getPackageName());
700 }
701 return mObbDir;
702 }
703 }
704
705 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800706 public File getCacheDir() {
707 synchronized (mSync) {
708 if (mCacheDir == null) {
709 mCacheDir = new File(getDataDirFile(), "cache");
710 }
711 if (!mCacheDir.exists()) {
712 if(!mCacheDir.mkdirs()) {
713 Log.w(TAG, "Unable to create cache directory");
714 return null;
715 }
716 FileUtils.setPermissions(
717 mCacheDir.getPath(),
718 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
719 -1, -1);
720 }
721 }
722 return mCacheDir;
723 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200724
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800725 @Override
726 public File getExternalCacheDir() {
727 synchronized (mSync) {
728 if (mExternalCacheDir == null) {
729 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
730 getPackageName());
731 }
732 if (!mExternalCacheDir.exists()) {
733 try {
734 (new File(Environment.getExternalStorageAndroidDataDir(),
735 ".nomedia")).createNewFile();
736 } catch (IOException e) {
737 }
738 if (!mExternalCacheDir.mkdirs()) {
739 Log.w(TAG, "Unable to create external cache directory");
740 return null;
741 }
742 }
743 return mExternalCacheDir;
744 }
745 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 @Override
748 public File getFileStreamPath(String name) {
749 return makeFilename(getFilesDir(), name);
750 }
751
752 @Override
753 public String[] fileList() {
754 final String[] list = getFilesDir().list();
755 return (list != null) ? list : EMPTY_FILE_LIST;
756 }
757
758 @Override
759 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800760 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800761 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
762 setFilePermissionsFromMode(f.getPath(), mode, 0);
763 return db;
764 }
765
766 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700767 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
768 DatabaseErrorHandler errorHandler) {
769 File f = validateFilePath(name, true);
770 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
771 setFilePermissionsFromMode(f.getPath(), mode, 0);
772 return db;
773 }
774
775 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 public boolean deleteDatabase(String name) {
777 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800778 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800779 return f.delete();
780 } catch (Exception e) {
781 }
782 return false;
783 }
784
785 @Override
786 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800787 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 }
789
790 @Override
791 public String[] databaseList() {
792 final String[] list = getDatabasesDir().list();
793 return (list != null) ? list : EMPTY_FILE_LIST;
794 }
795
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 private File getDatabasesDir() {
798 synchronized (mSync) {
799 if (mDatabasesDir == null) {
800 mDatabasesDir = new File(getDataDirFile(), "databases");
801 }
802 if (mDatabasesDir.getPath().equals("databases")) {
803 mDatabasesDir = new File("/data/system");
804 }
805 return mDatabasesDir;
806 }
807 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 @Override
810 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700811 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 }
813
814 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700815 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700816 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 }
818
819 @Override
820 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700821 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 @Override
825 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700826 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828
829 @Override
830 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700831 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 }
833
834 @Override
835 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700836 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 }
838
839 @Override
840 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700841 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 }
843
844 @Override
845 public void startActivity(Intent intent) {
846 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
847 throw new AndroidRuntimeException(
848 "Calling startActivity() from outside of an Activity "
849 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
850 + " Is this really what you want?");
851 }
852 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700853 getOuterContext(), mMainThread.getApplicationThread(), null,
854 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 }
856
857 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800858 public void startActivities(Intent[] intents) {
859 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
860 throw new AndroidRuntimeException(
861 "Calling startActivities() from outside of an Activity "
862 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
863 + " Is this really what you want?");
864 }
865 mMainThread.getInstrumentation().execStartActivities(
866 getOuterContext(), mMainThread.getApplicationThread(), null,
867 (Activity)null, intents);
868 }
869
870 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700871 public void startIntentSender(IntentSender intent,
872 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
873 throws IntentSender.SendIntentException {
874 try {
875 String resolvedType = null;
876 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400877 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700878 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
879 }
880 int result = ActivityManagerNative.getDefault()
881 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
882 fillInIntent, resolvedType, null, null,
883 0, flagsMask, flagsValues);
884 if (result == IActivityManager.START_CANCELED) {
885 throw new IntentSender.SendIntentException();
886 }
887 Instrumentation.checkStartActivityResult(result, null);
888 } catch (RemoteException e) {
889 }
890 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200891
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700892 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800893 public void sendBroadcast(Intent intent) {
894 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
895 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400896 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 ActivityManagerNative.getDefault().broadcastIntent(
898 mMainThread.getApplicationThread(), intent, resolvedType, null,
899 Activity.RESULT_OK, null, null, null, false, false);
900 } catch (RemoteException e) {
901 }
902 }
903
904 @Override
905 public void sendBroadcast(Intent intent, String receiverPermission) {
906 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
907 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400908 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 ActivityManagerNative.getDefault().broadcastIntent(
910 mMainThread.getApplicationThread(), intent, resolvedType, null,
911 Activity.RESULT_OK, null, null, receiverPermission, false, false);
912 } catch (RemoteException e) {
913 }
914 }
915
916 @Override
917 public void sendOrderedBroadcast(Intent intent,
918 String receiverPermission) {
919 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
920 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400921 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 ActivityManagerNative.getDefault().broadcastIntent(
923 mMainThread.getApplicationThread(), intent, resolvedType, null,
924 Activity.RESULT_OK, null, null, receiverPermission, true, false);
925 } catch (RemoteException e) {
926 }
927 }
928
929 @Override
930 public void sendOrderedBroadcast(Intent intent,
931 String receiverPermission, BroadcastReceiver resultReceiver,
932 Handler scheduler, int initialCode, String initialData,
933 Bundle initialExtras) {
934 IIntentReceiver rd = null;
935 if (resultReceiver != null) {
936 if (mPackageInfo != null) {
937 if (scheduler == null) {
938 scheduler = mMainThread.getHandler();
939 }
940 rd = mPackageInfo.getReceiverDispatcher(
941 resultReceiver, getOuterContext(), scheduler,
942 mMainThread.getInstrumentation(), false);
943 } else {
944 if (scheduler == null) {
945 scheduler = mMainThread.getHandler();
946 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700947 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
949 }
950 }
951 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
952 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400953 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 ActivityManagerNative.getDefault().broadcastIntent(
955 mMainThread.getApplicationThread(), intent, resolvedType, rd,
956 initialCode, initialData, initialExtras, receiverPermission,
957 true, false);
958 } catch (RemoteException e) {
959 }
960 }
961
962 @Override
963 public void sendStickyBroadcast(Intent intent) {
964 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
965 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400966 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 ActivityManagerNative.getDefault().broadcastIntent(
968 mMainThread.getApplicationThread(), intent, resolvedType, null,
969 Activity.RESULT_OK, null, null, null, false, true);
970 } catch (RemoteException e) {
971 }
972 }
973
974 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700975 public void sendStickyOrderedBroadcast(Intent intent,
976 BroadcastReceiver resultReceiver,
977 Handler scheduler, int initialCode, String initialData,
978 Bundle initialExtras) {
979 IIntentReceiver rd = null;
980 if (resultReceiver != null) {
981 if (mPackageInfo != null) {
982 if (scheduler == null) {
983 scheduler = mMainThread.getHandler();
984 }
985 rd = mPackageInfo.getReceiverDispatcher(
986 resultReceiver, getOuterContext(), scheduler,
987 mMainThread.getInstrumentation(), false);
988 } else {
989 if (scheduler == null) {
990 scheduler = mMainThread.getHandler();
991 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700992 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700993 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
994 }
995 }
996 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
997 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400998 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700999 ActivityManagerNative.getDefault().broadcastIntent(
1000 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1001 initialCode, initialData, initialExtras, null,
1002 true, true);
1003 } catch (RemoteException e) {
1004 }
1005 }
1006
1007 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 public void removeStickyBroadcast(Intent intent) {
1009 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1010 if (resolvedType != null) {
1011 intent = new Intent(intent);
1012 intent.setDataAndType(intent.getData(), resolvedType);
1013 }
1014 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001015 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 ActivityManagerNative.getDefault().unbroadcastIntent(
1017 mMainThread.getApplicationThread(), intent);
1018 } catch (RemoteException e) {
1019 }
1020 }
1021
1022 @Override
1023 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1024 return registerReceiver(receiver, filter, null, null);
1025 }
1026
1027 @Override
1028 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1029 String broadcastPermission, Handler scheduler) {
1030 return registerReceiverInternal(receiver, filter, broadcastPermission,
1031 scheduler, getOuterContext());
1032 }
1033
1034 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1035 IntentFilter filter, String broadcastPermission,
1036 Handler scheduler, Context context) {
1037 IIntentReceiver rd = null;
1038 if (receiver != null) {
1039 if (mPackageInfo != null && context != null) {
1040 if (scheduler == null) {
1041 scheduler = mMainThread.getHandler();
1042 }
1043 rd = mPackageInfo.getReceiverDispatcher(
1044 receiver, context, scheduler,
1045 mMainThread.getInstrumentation(), true);
1046 } else {
1047 if (scheduler == null) {
1048 scheduler = mMainThread.getHandler();
1049 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001050 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001051 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 }
1053 }
1054 try {
1055 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001056 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 rd, filter, broadcastPermission);
1058 } catch (RemoteException e) {
1059 return null;
1060 }
1061 }
1062
1063 @Override
1064 public void unregisterReceiver(BroadcastReceiver receiver) {
1065 if (mPackageInfo != null) {
1066 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1067 getOuterContext(), receiver);
1068 try {
1069 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1070 } catch (RemoteException e) {
1071 }
1072 } else {
1073 throw new RuntimeException("Not supported in system context");
1074 }
1075 }
1076
1077 @Override
1078 public ComponentName startService(Intent service) {
1079 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001080 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 ComponentName cn = ActivityManagerNative.getDefault().startService(
1082 mMainThread.getApplicationThread(), service,
1083 service.resolveTypeIfNeeded(getContentResolver()));
1084 if (cn != null && cn.getPackageName().equals("!")) {
1085 throw new SecurityException(
1086 "Not allowed to start service " + service
1087 + " without permission " + cn.getClassName());
1088 }
1089 return cn;
1090 } catch (RemoteException e) {
1091 return null;
1092 }
1093 }
1094
1095 @Override
1096 public boolean stopService(Intent service) {
1097 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001098 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001099 int res = ActivityManagerNative.getDefault().stopService(
1100 mMainThread.getApplicationThread(), service,
1101 service.resolveTypeIfNeeded(getContentResolver()));
1102 if (res < 0) {
1103 throw new SecurityException(
1104 "Not allowed to stop service " + service);
1105 }
1106 return res != 0;
1107 } catch (RemoteException e) {
1108 return false;
1109 }
1110 }
1111
1112 @Override
1113 public boolean bindService(Intent service, ServiceConnection conn,
1114 int flags) {
1115 IServiceConnection sd;
1116 if (mPackageInfo != null) {
1117 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1118 mMainThread.getHandler(), flags);
1119 } else {
1120 throw new RuntimeException("Not supported in system context");
1121 }
1122 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001123 IBinder token = getActivityToken();
1124 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1125 && mPackageInfo.getApplicationInfo().targetSdkVersion
1126 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1127 flags |= BIND_WAIVE_PRIORITY;
1128 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001129 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 int res = ActivityManagerNative.getDefault().bindService(
1131 mMainThread.getApplicationThread(), getActivityToken(),
1132 service, service.resolveTypeIfNeeded(getContentResolver()),
1133 sd, flags);
1134 if (res < 0) {
1135 throw new SecurityException(
1136 "Not allowed to bind to service " + service);
1137 }
1138 return res != 0;
1139 } catch (RemoteException e) {
1140 return false;
1141 }
1142 }
1143
1144 @Override
1145 public void unbindService(ServiceConnection conn) {
1146 if (mPackageInfo != null) {
1147 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1148 getOuterContext(), conn);
1149 try {
1150 ActivityManagerNative.getDefault().unbindService(sd);
1151 } catch (RemoteException e) {
1152 }
1153 } else {
1154 throw new RuntimeException("Not supported in system context");
1155 }
1156 }
1157
1158 @Override
1159 public boolean startInstrumentation(ComponentName className,
1160 String profileFile, Bundle arguments) {
1161 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001162 if (arguments != null) {
1163 arguments.setAllowFds(false);
1164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 return ActivityManagerNative.getDefault().startInstrumentation(
1166 className, profileFile, 0, arguments, null);
1167 } catch (RemoteException e) {
1168 // System has crashed, nothing we can do.
1169 }
1170 return false;
1171 }
1172
1173 @Override
1174 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001175 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1176 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 }
1178
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001179 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001180 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 }
1182
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001183 /* package */ static DropBoxManager createDropBoxManager() {
1184 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1185 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001186 if (service == null) {
1187 // Don't return a DropBoxManager that will NPE upon use.
1188 // This also avoids caching a broken DropBoxManager in
1189 // getDropBoxManager during early boot, before the
1190 // DROPBOX_SERVICE is registered.
1191 return null;
1192 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001193 return new DropBoxManager(service);
1194 }
1195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 @Override
1197 public int checkPermission(String permission, int pid, int uid) {
1198 if (permission == null) {
1199 throw new IllegalArgumentException("permission is null");
1200 }
1201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 try {
1203 return ActivityManagerNative.getDefault().checkPermission(
1204 permission, pid, uid);
1205 } catch (RemoteException e) {
1206 return PackageManager.PERMISSION_DENIED;
1207 }
1208 }
1209
1210 @Override
1211 public int checkCallingPermission(String permission) {
1212 if (permission == null) {
1213 throw new IllegalArgumentException("permission is null");
1214 }
1215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 int pid = Binder.getCallingPid();
1217 if (pid != Process.myPid()) {
1218 return checkPermission(permission, pid,
1219 Binder.getCallingUid());
1220 }
1221 return PackageManager.PERMISSION_DENIED;
1222 }
1223
1224 @Override
1225 public int checkCallingOrSelfPermission(String permission) {
1226 if (permission == null) {
1227 throw new IllegalArgumentException("permission is null");
1228 }
1229
1230 return checkPermission(permission, Binder.getCallingPid(),
1231 Binder.getCallingUid());
1232 }
1233
1234 private void enforce(
1235 String permission, int resultOfCheck,
1236 boolean selfToo, int uid, String message) {
1237 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1238 throw new SecurityException(
1239 (message != null ? (message + ": ") : "") +
1240 (selfToo
1241 ? "Neither user " + uid + " nor current process has "
1242 : "User " + uid + " does not have ") +
1243 permission +
1244 ".");
1245 }
1246 }
1247
1248 public void enforcePermission(
1249 String permission, int pid, int uid, String message) {
1250 enforce(permission,
1251 checkPermission(permission, pid, uid),
1252 false,
1253 uid,
1254 message);
1255 }
1256
1257 public void enforceCallingPermission(String permission, String message) {
1258 enforce(permission,
1259 checkCallingPermission(permission),
1260 false,
1261 Binder.getCallingUid(),
1262 message);
1263 }
1264
1265 public void enforceCallingOrSelfPermission(
1266 String permission, String message) {
1267 enforce(permission,
1268 checkCallingOrSelfPermission(permission),
1269 true,
1270 Binder.getCallingUid(),
1271 message);
1272 }
1273
1274 @Override
1275 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1276 try {
1277 ActivityManagerNative.getDefault().grantUriPermission(
1278 mMainThread.getApplicationThread(), toPackage, uri,
1279 modeFlags);
1280 } catch (RemoteException e) {
1281 }
1282 }
1283
1284 @Override
1285 public void revokeUriPermission(Uri uri, int modeFlags) {
1286 try {
1287 ActivityManagerNative.getDefault().revokeUriPermission(
1288 mMainThread.getApplicationThread(), uri,
1289 modeFlags);
1290 } catch (RemoteException e) {
1291 }
1292 }
1293
1294 @Override
1295 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 try {
1297 return ActivityManagerNative.getDefault().checkUriPermission(
1298 uri, pid, uid, modeFlags);
1299 } catch (RemoteException e) {
1300 return PackageManager.PERMISSION_DENIED;
1301 }
1302 }
1303
1304 @Override
1305 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 int pid = Binder.getCallingPid();
1307 if (pid != Process.myPid()) {
1308 return checkUriPermission(uri, pid,
1309 Binder.getCallingUid(), modeFlags);
1310 }
1311 return PackageManager.PERMISSION_DENIED;
1312 }
1313
1314 @Override
1315 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1316 return checkUriPermission(uri, Binder.getCallingPid(),
1317 Binder.getCallingUid(), modeFlags);
1318 }
1319
1320 @Override
1321 public int checkUriPermission(Uri uri, String readPermission,
1322 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001323 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1325 + readPermission + " writePermission=" + writePermission
1326 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1327 }
1328 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1329 if (readPermission == null
1330 || checkPermission(readPermission, pid, uid)
1331 == PackageManager.PERMISSION_GRANTED) {
1332 return PackageManager.PERMISSION_GRANTED;
1333 }
1334 }
1335 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1336 if (writePermission == null
1337 || checkPermission(writePermission, pid, uid)
1338 == PackageManager.PERMISSION_GRANTED) {
1339 return PackageManager.PERMISSION_GRANTED;
1340 }
1341 }
1342 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1343 : PackageManager.PERMISSION_DENIED;
1344 }
1345
1346 private String uriModeFlagToString(int uriModeFlags) {
1347 switch (uriModeFlags) {
1348 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1349 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1350 return "read and write";
1351 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1352 return "read";
1353 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1354 return "write";
1355 }
1356 throw new IllegalArgumentException(
1357 "Unknown permission mode flags: " + uriModeFlags);
1358 }
1359
1360 private void enforceForUri(
1361 int modeFlags, int resultOfCheck, boolean selfToo,
1362 int uid, Uri uri, String message) {
1363 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1364 throw new SecurityException(
1365 (message != null ? (message + ": ") : "") +
1366 (selfToo
1367 ? "Neither user " + uid + " nor current process has "
1368 : "User " + uid + " does not have ") +
1369 uriModeFlagToString(modeFlags) +
1370 " permission on " +
1371 uri +
1372 ".");
1373 }
1374 }
1375
1376 public void enforceUriPermission(
1377 Uri uri, int pid, int uid, int modeFlags, String message) {
1378 enforceForUri(
1379 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1380 false, uid, uri, message);
1381 }
1382
1383 public void enforceCallingUriPermission(
1384 Uri uri, int modeFlags, String message) {
1385 enforceForUri(
1386 modeFlags, checkCallingUriPermission(uri, modeFlags),
1387 false, Binder.getCallingUid(), uri, message);
1388 }
1389
1390 public void enforceCallingOrSelfUriPermission(
1391 Uri uri, int modeFlags, String message) {
1392 enforceForUri(
1393 modeFlags,
1394 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1395 Binder.getCallingUid(), uri, message);
1396 }
1397
1398 public void enforceUriPermission(
1399 Uri uri, String readPermission, String writePermission,
1400 int pid, int uid, int modeFlags, String message) {
1401 enforceForUri(modeFlags,
1402 checkUriPermission(
1403 uri, readPermission, writePermission, pid, uid,
1404 modeFlags),
1405 false,
1406 uid,
1407 uri,
1408 message);
1409 }
1410
1411 @Override
1412 public Context createPackageContext(String packageName, int flags)
1413 throws PackageManager.NameNotFoundException {
1414 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001415 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 }
1417
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001418 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001419 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001421 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001422 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001423 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424 if (c.mResources != null) {
1425 return c;
1426 }
1427 }
1428
1429 // Should be a better exception.
1430 throw new PackageManager.NameNotFoundException(
1431 "Application package " + packageName + " not found");
1432 }
1433
Romain Guy870e09f2009-07-06 16:35:25 -07001434 @Override
1435 public boolean isRestricted() {
1436 return mRestricted;
1437 }
1438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 private File getDataDirFile() {
1440 if (mPackageInfo != null) {
1441 return mPackageInfo.getDataDirFile();
1442 }
1443 throw new RuntimeException("Not supported in system context");
1444 }
1445
1446 @Override
1447 public File getDir(String name, int mode) {
1448 name = "app_" + name;
1449 File file = makeFilename(getDataDirFile(), name);
1450 if (!file.exists()) {
1451 file.mkdir();
1452 setFilePermissionsFromMode(file.getPath(), mode,
1453 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1454 }
1455 return file;
1456 }
1457
Dianne Hackborn21556372010-02-04 16:34:40 -08001458 static ContextImpl createSystemContext(ActivityThread mainThread) {
1459 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 context.init(Resources.getSystem(), mainThread);
1461 return context;
1462 }
1463
Dianne Hackborn21556372010-02-04 16:34:40 -08001464 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 mOuterContext = this;
1466 }
1467
1468 /**
1469 * Create a new ApplicationContext from an existing one. The new one
1470 * works and operates the same as the one it is copying.
1471 *
1472 * @param context Existing application context.
1473 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001474 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001476 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 mResources = context.mResources;
1478 mMainThread = context.mMainThread;
1479 mContentResolver = context.mContentResolver;
1480 mOuterContext = this;
1481 }
1482
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001483 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001485 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001486 }
1487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001488 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001489 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001490 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001492 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001494
Dianne Hackborn559a7872010-04-07 18:19:41 -07001495 if (mResources != null && container != null
1496 && container.getCompatibilityInfo().applicationScale !=
1497 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001498 if (DEBUG) {
1499 Log.d(TAG, "loaded context has different scaling. Using container's" +
1500 " compatiblity info:" + container.getDisplayMetrics());
1501 }
1502 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001503 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 mMainThread = mainThread;
1506 mContentResolver = new ApplicationContentResolver(this, mainThread);
1507
1508 setActivityToken(activityToken);
1509 }
1510
1511 final void init(Resources resources, ActivityThread mainThread) {
1512 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001513 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 mResources = resources;
1515 mMainThread = mainThread;
1516 mContentResolver = new ApplicationContentResolver(this, mainThread);
1517 }
1518
1519 final void scheduleFinalCleanup(String who, String what) {
1520 mMainThread.scheduleContextCleanup(this, who, what);
1521 }
1522
1523 final void performFinalCleanup(String who, String what) {
1524 //Log.i(TAG, "Cleanup up context: " + this);
1525 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1526 }
1527
1528 final Context getReceiverRestrictedContext() {
1529 if (mReceiverRestrictedContext != null) {
1530 return mReceiverRestrictedContext;
1531 }
1532 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1533 }
1534
1535 final void setActivityToken(IBinder token) {
1536 mActivityToken = token;
1537 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 final void setOuterContext(Context context) {
1540 mOuterContext = context;
1541 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 final Context getOuterContext() {
1544 return mOuterContext;
1545 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 final IBinder getActivityToken() {
1548 return mActivityToken;
1549 }
1550
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001551 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 int extraPermissions) {
1553 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1554 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1555 |extraPermissions;
1556 if ((mode&MODE_WORLD_READABLE) != 0) {
1557 perms |= FileUtils.S_IROTH;
1558 }
1559 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1560 perms |= FileUtils.S_IWOTH;
1561 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001562 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1564 + ", perms=0x" + Integer.toHexString(perms));
1565 }
1566 FileUtils.setPermissions(name, perms, -1, -1);
1567 }
1568
Oscar Montemayora8529f62009-11-18 10:14:20 -08001569 private File validateFilePath(String name, boolean createDirectory) {
1570 File dir;
1571 File f;
1572
1573 if (name.charAt(0) == File.separatorChar) {
1574 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1575 dir = new File(dirPath);
1576 name = name.substring(name.lastIndexOf(File.separatorChar));
1577 f = new File(dir, name);
1578 } else {
1579 dir = getDatabasesDir();
1580 f = makeFilename(dir, name);
1581 }
1582
1583 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1584 FileUtils.setPermissions(dir.getPath(),
1585 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1586 -1, -1);
1587 }
1588
1589 return f;
1590 }
1591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 private File makeFilename(File base, String name) {
1593 if (name.indexOf(File.separatorChar) < 0) {
1594 return new File(base, name);
1595 }
1596 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001597 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 }
1599
1600 // ----------------------------------------------------------------------
1601 // ----------------------------------------------------------------------
1602 // ----------------------------------------------------------------------
1603
1604 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001605 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 super(context);
1607 mMainThread = mainThread;
1608 }
1609
1610 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001611 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 return mMainThread.acquireProvider(context, name);
1613 }
1614
1615 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001616 protected IContentProvider acquireExistingProvider(Context context, String name) {
1617 return mMainThread.acquireExistingProvider(context, name);
1618 }
1619
1620 @Override
1621 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 return mMainThread.releaseProvider(provider);
1623 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001624
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 private final ActivityThread mMainThread;
1626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627}