blob: db5113ec905b06cf1c367099a2093ffb8c449238 [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;
Amith Yamasani742a6712011-05-04 14:49:28 -070078import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080080import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070082import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.util.AndroidRuntimeException;
84import android.util.Log;
85import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070087import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090089import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070090import android.accounts.AccountManager;
91import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080092import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080093import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import java.io.File;
96import java.io.FileInputStream;
97import java.io.FileNotFoundException;
98import java.io.FileOutputStream;
99import java.io.IOException;
100import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import java.util.ArrayList;
102import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104class ReceiverRestrictedContext extends ContextWrapper {
105 ReceiverRestrictedContext(Context base) {
106 super(base);
107 }
108
109 @Override
110 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
111 return registerReceiver(receiver, filter, null, null);
112 }
113
114 @Override
115 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
116 String broadcastPermission, Handler scheduler) {
117 throw new ReceiverCallNotAllowedException(
118 "IntentReceiver components are not allowed to register to receive intents");
119 //ex.fillInStackTrace();
120 //Log.e("IntentReceiver", ex.getMessage(), ex);
121 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
122 // scheduler);
123 }
124
125 @Override
126 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
127 throw new ReceiverCallNotAllowedException(
128 "IntentReceiver components are not allowed to bind to services");
129 //ex.fillInStackTrace();
130 //Log.e("IntentReceiver", ex.getMessage(), ex);
131 //return mContext.bindService(service, interfaceName, conn, flags);
132 }
133}
134
135/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800136 * Common implementation of Context API, which provides the base
137 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800139class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700141 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700143 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
144 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700146 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700147 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 private Resources mResources;
149 /*package*/ ActivityThread mMainThread;
150 private Context mOuterContext;
151 private IBinder mActivityToken = null;
152 private ApplicationContentResolver mContentResolver;
153 private int mThemeResource = 0;
154 private Resources.Theme mTheme = null;
155 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800156 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700157 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158
159 private final Object mSync = new Object();
160
161 private File mDatabasesDir;
162 private File mPreferencesDir;
163 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800165 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800166 private File mExternalFilesDir;
167 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200168
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 private static final String[] EMPTY_FILE_LIST = {};
170
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800171 /**
172 * Override this class when the system service constructor needs a
173 * ContextImpl. Else, use StaticServiceFetcher below.
174 */
175 /*package*/ static class ServiceFetcher {
176 int mContextCacheIndex = -1;
177
178 /**
179 * Main entrypoint; only override if you don't need caching.
180 */
181 public Object getService(ContextImpl ctx) {
182 ArrayList<Object> cache = ctx.mServiceCache;
183 Object service;
184 synchronized (cache) {
185 if (cache.size() == 0) {
186 // Initialize the cache vector on first access.
187 // At this point sNextPerContextServiceCacheIndex
188 // is the number of potential services that are
189 // cached per-Context.
190 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
191 cache.add(null);
192 }
193 } else {
194 service = cache.get(mContextCacheIndex);
195 if (service != null) {
196 return service;
197 }
198 }
199 service = createService(ctx);
200 cache.set(mContextCacheIndex, service);
201 return service;
202 }
203 }
204
205 /**
206 * Override this to create a new per-Context instance of the
207 * service. getService() will handle locking and caching.
208 */
209 public Object createService(ContextImpl ctx) {
210 throw new RuntimeException("Not implemented");
211 }
212 }
213
214 /**
215 * Override this class for services to be cached process-wide.
216 */
217 abstract static class StaticServiceFetcher extends ServiceFetcher {
218 private Object mCachedInstance;
219
220 @Override
221 public final Object getService(ContextImpl unused) {
222 synchronized (StaticServiceFetcher.this) {
223 Object service = mCachedInstance;
224 if (service != null) {
225 return service;
226 }
227 return mCachedInstance = createStaticService();
228 }
229 }
230
231 public abstract Object createStaticService();
232 }
233
234 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
235 new HashMap<String, ServiceFetcher>();
236
237 private static int sNextPerContextServiceCacheIndex = 0;
238 private static void registerService(String serviceName, ServiceFetcher fetcher) {
239 if (!(fetcher instanceof StaticServiceFetcher)) {
240 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
241 }
242 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
243 }
244
245 // This one's defined separately and given a variable name so it
246 // can be re-used by getWallpaperManager(), avoiding a HashMap
247 // lookup.
248 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
249 public Object createService(ContextImpl ctx) {
250 return new WallpaperManager(ctx.getOuterContext(),
251 ctx.mMainThread.getHandler());
252 }};
253
254 static {
255 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
256 public Object getService(ContextImpl ctx) {
257 return AccessibilityManager.getInstance(ctx);
258 }});
259
260 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
261 public Object createService(ContextImpl ctx) {
262 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
263 IAccountManager service = IAccountManager.Stub.asInterface(b);
264 return new AccountManager(ctx, service);
265 }});
266
267 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
268 public Object createService(ContextImpl ctx) {
269 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
270 }});
271
272 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
273 public Object createStaticService() {
274 IBinder b = ServiceManager.getService(ALARM_SERVICE);
275 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
276 return new AlarmManager(service);
277 }});
278
279 registerService(AUDIO_SERVICE, new ServiceFetcher() {
280 public Object createService(ContextImpl ctx) {
281 return new AudioManager(ctx);
282 }});
283
284 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
285 public Object createService(ContextImpl ctx) {
286 return new ClipboardManager(ctx.getOuterContext(),
287 ctx.mMainThread.getHandler());
288 }});
289
290 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
291 public Object createStaticService() {
292 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
293 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
294 }});
295
296 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
297 public Object createStaticService() {
298 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
299 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
300 }});
301
302 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
303 public Object createService(ContextImpl ctx) {
304 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
305 }});
306
307 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
308 public Object createService(ContextImpl ctx) {
309 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
310 }});
311
Nick Pellyd2507462010-12-13 12:22:34 -0800312 registerService(NFC_SERVICE, new ServiceFetcher() {
313 public Object createService(ContextImpl ctx) {
314 return new NfcManager(ctx);
315 }});
316
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800317 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
318 public Object createStaticService() {
319 return createDropBoxManager();
320 }});
321
322 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
323 public Object createService(ContextImpl ctx) {
324 return InputMethodManager.getInstance(ctx);
325 }});
326
satok988323c2011-06-22 16:38:13 +0900327 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
328 public Object createService(ContextImpl ctx) {
329 return TextServicesManager.getInstance();
330 }});
331
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800332 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
333 public Object getService(ContextImpl ctx) {
334 // TODO: why isn't this caching it? It wasn't
335 // before, so I'm preserving the old behavior and
336 // using getService(), instead of createService()
337 // which would do the caching.
338 return new KeyguardManager();
339 }});
340
341 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
342 public Object createService(ContextImpl ctx) {
343 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
344 }});
345
346 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
347 public Object createStaticService() {
348 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
349 return new LocationManager(ILocationManager.Stub.asInterface(b));
350 }});
351
Jeff Sharkey1a303952011-06-16 13:04:20 -0700352 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
353 @Override
354 public Object createService(ContextImpl ctx) {
355 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
356 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
357 }
358 });
359
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800360 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
361 public Object createService(ContextImpl ctx) {
362 final Context outerContext = ctx.getOuterContext();
363 return new NotificationManager(
364 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800365 Resources.selectSystemTheme(0,
366 outerContext.getApplicationInfo().targetSdkVersion,
367 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700368 com.android.internal.R.style.Theme_Holo_Dialog,
369 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800370 ctx.mMainThread.getHandler());
371 }});
372
373 // Note: this was previously cached in a static variable, but
374 // constructed using mMainThread.getHandler(), so converting
375 // it to be a regular Context-cached service...
376 registerService(POWER_SERVICE, new ServiceFetcher() {
377 public Object createService(ContextImpl ctx) {
378 IBinder b = ServiceManager.getService(POWER_SERVICE);
379 IPowerManager service = IPowerManager.Stub.asInterface(b);
380 return new PowerManager(service, ctx.mMainThread.getHandler());
381 }});
382
383 registerService(SEARCH_SERVICE, new ServiceFetcher() {
384 public Object createService(ContextImpl ctx) {
385 return new SearchManager(ctx.getOuterContext(),
386 ctx.mMainThread.getHandler());
387 }});
388
389 registerService(SENSOR_SERVICE, new ServiceFetcher() {
390 public Object createService(ContextImpl ctx) {
391 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
392 }});
393
394 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
395 public Object createService(ContextImpl ctx) {
396 return new StatusBarManager(ctx.getOuterContext());
397 }});
398
399 registerService(STORAGE_SERVICE, new ServiceFetcher() {
400 public Object createService(ContextImpl ctx) {
401 try {
402 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
403 } catch (RemoteException rex) {
404 Log.e(TAG, "Failed to create StorageManager", rex);
405 return null;
406 }
407 }});
408
409 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
410 public Object createService(ContextImpl ctx) {
411 return new TelephonyManager(ctx.getOuterContext());
412 }});
413
414 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
415 public Object createStaticService() {
416 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
417 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
418 }});
419
420 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
421 public Object createService(ContextImpl ctx) {
422 return new UiModeManager();
423 }});
424
Mike Lockwood3a68b832011-03-08 10:08:59 -0500425 registerService(USB_SERVICE, new ServiceFetcher() {
426 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500427 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500428 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500429 }});
430
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800431 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
432 public Object createService(ContextImpl ctx) {
433 return new Vibrator();
434 }});
435
436 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
437
438 registerService(WIFI_SERVICE, new ServiceFetcher() {
439 public Object createService(ContextImpl ctx) {
440 IBinder b = ServiceManager.getService(WIFI_SERVICE);
441 IWifiManager service = IWifiManager.Stub.asInterface(b);
442 return new WifiManager(service, ctx.mMainThread.getHandler());
443 }});
444
repo sync55bc5f32011-06-24 14:23:07 -0700445 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
446 public Object createService(ContextImpl ctx) {
447 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
448 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
449 return new WifiP2pManager(service);
450 }});
451
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800452 registerService(WINDOW_SERVICE, new ServiceFetcher() {
453 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700454 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800455 }});
456 }
457
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700458 static ContextImpl getImpl(Context context) {
459 Context nextContext;
460 while ((context instanceof ContextWrapper) &&
461 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
462 context = nextContext;
463 }
464 return (ContextImpl)context;
465 }
466
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800467 // The system service cache for the system services that are
468 // cached per-ContextImpl. Package-scoped to avoid accessor
469 // methods.
470 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 @Override
473 public AssetManager getAssets() {
474 return mResources.getAssets();
475 }
476
477 @Override
478 public Resources getResources() {
479 return mResources;
480 }
481
482 @Override
483 public PackageManager getPackageManager() {
484 if (mPackageManager != null) {
485 return mPackageManager;
486 }
487
488 IPackageManager pm = ActivityThread.getPackageManager();
489 if (pm != null) {
490 // Doesn't matter if we make more than one instance.
491 return (mPackageManager = new ApplicationPackageManager(this, pm));
492 }
493
494 return null;
495 }
496
497 @Override
498 public ContentResolver getContentResolver() {
499 return mContentResolver;
500 }
501
502 @Override
503 public Looper getMainLooper() {
504 return mMainThread.getLooper();
505 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 @Override
508 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700509 return (mPackageInfo != null) ?
510 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 @Override
514 public void setTheme(int resid) {
515 mThemeResource = resid;
516 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800519 public int getThemeResId() {
520 return mThemeResource;
521 }
522
523 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800524 public Resources.Theme getTheme() {
525 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800526 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
527 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800528 mTheme = mResources.newTheme();
529 mTheme.applyStyle(mThemeResource, true);
530 }
531 return mTheme;
532 }
533
534 @Override
535 public ClassLoader getClassLoader() {
536 return mPackageInfo != null ?
537 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
538 }
539
540 @Override
541 public String getPackageName() {
542 if (mPackageInfo != null) {
543 return mPackageInfo.getPackageName();
544 }
545 throw new RuntimeException("Not supported in system context");
546 }
547
548 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700549 public ApplicationInfo getApplicationInfo() {
550 if (mPackageInfo != null) {
551 return mPackageInfo.getApplicationInfo();
552 }
553 throw new RuntimeException("Not supported in system context");
554 }
555
556 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800557 public String getPackageResourcePath() {
558 if (mPackageInfo != null) {
559 return mPackageInfo.getResDir();
560 }
561 throw new RuntimeException("Not supported in system context");
562 }
563
564 @Override
565 public String getPackageCodePath() {
566 if (mPackageInfo != null) {
567 return mPackageInfo.getAppDir();
568 }
569 throw new RuntimeException("Not supported in system context");
570 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200571
Joe Onorato23ecae32009-06-10 17:07:15 -0700572 public File getSharedPrefsFile(String name) {
573 return makeFilename(getPreferencesDir(), name + ".xml");
574 }
575
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 @Override
577 public SharedPreferences getSharedPreferences(String name, int mode) {
578 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700580 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700581 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800582 File prefsFile = getSharedPrefsFile(name);
583 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700584 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700585 return sp;
586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800588 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
589 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
590 // If somebody else (some other process) changed the prefs
591 // file behind our back, we reload it. This has been the
592 // historical (if undocumented) behavior.
593 sp.startReloadIfChangedUnexpectedly();
594 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700595 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
597
598 private File getPreferencesDir() {
599 synchronized (mSync) {
600 if (mPreferencesDir == null) {
601 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
602 }
603 return mPreferencesDir;
604 }
605 }
606
607 @Override
608 public FileInputStream openFileInput(String name)
609 throws FileNotFoundException {
610 File f = makeFilename(getFilesDir(), name);
611 return new FileInputStream(f);
612 }
613
614 @Override
615 public FileOutputStream openFileOutput(String name, int mode)
616 throws FileNotFoundException {
617 final boolean append = (mode&MODE_APPEND) != 0;
618 File f = makeFilename(getFilesDir(), name);
619 try {
620 FileOutputStream fos = new FileOutputStream(f, append);
621 setFilePermissionsFromMode(f.getPath(), mode, 0);
622 return fos;
623 } catch (FileNotFoundException e) {
624 }
625
626 File parent = f.getParentFile();
627 parent.mkdir();
628 FileUtils.setPermissions(
629 parent.getPath(),
630 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
631 -1, -1);
632 FileOutputStream fos = new FileOutputStream(f, append);
633 setFilePermissionsFromMode(f.getPath(), mode, 0);
634 return fos;
635 }
636
637 @Override
638 public boolean deleteFile(String name) {
639 File f = makeFilename(getFilesDir(), name);
640 return f.delete();
641 }
642
643 @Override
644 public File getFilesDir() {
645 synchronized (mSync) {
646 if (mFilesDir == null) {
647 mFilesDir = new File(getDataDirFile(), "files");
648 }
649 if (!mFilesDir.exists()) {
650 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200651 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 return null;
653 }
654 FileUtils.setPermissions(
655 mFilesDir.getPath(),
656 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
657 -1, -1);
658 }
659 return mFilesDir;
660 }
661 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800664 public File getExternalFilesDir(String type) {
665 synchronized (mSync) {
666 if (mExternalFilesDir == null) {
667 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
668 getPackageName());
669 }
670 if (!mExternalFilesDir.exists()) {
671 try {
672 (new File(Environment.getExternalStorageAndroidDataDir(),
673 ".nomedia")).createNewFile();
674 } catch (IOException e) {
675 }
676 if (!mExternalFilesDir.mkdirs()) {
677 Log.w(TAG, "Unable to create external files directory");
678 return null;
679 }
680 }
681 if (type == null) {
682 return mExternalFilesDir;
683 }
684 File dir = new File(mExternalFilesDir, type);
685 if (!dir.exists()) {
686 if (!dir.mkdirs()) {
687 Log.w(TAG, "Unable to create external media directory " + dir);
688 return null;
689 }
690 }
691 return dir;
692 }
693 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200694
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800695 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800696 public File getObbDir() {
697 synchronized (mSync) {
698 if (mObbDir == null) {
699 mObbDir = Environment.getExternalStorageAppObbDirectory(
700 getPackageName());
701 }
702 return mObbDir;
703 }
704 }
705
706 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 public File getCacheDir() {
708 synchronized (mSync) {
709 if (mCacheDir == null) {
710 mCacheDir = new File(getDataDirFile(), "cache");
711 }
712 if (!mCacheDir.exists()) {
713 if(!mCacheDir.mkdirs()) {
714 Log.w(TAG, "Unable to create cache directory");
715 return null;
716 }
717 FileUtils.setPermissions(
718 mCacheDir.getPath(),
719 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
720 -1, -1);
721 }
722 }
723 return mCacheDir;
724 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200725
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800726 @Override
727 public File getExternalCacheDir() {
728 synchronized (mSync) {
729 if (mExternalCacheDir == null) {
730 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
731 getPackageName());
732 }
733 if (!mExternalCacheDir.exists()) {
734 try {
735 (new File(Environment.getExternalStorageAndroidDataDir(),
736 ".nomedia")).createNewFile();
737 } catch (IOException e) {
738 }
739 if (!mExternalCacheDir.mkdirs()) {
740 Log.w(TAG, "Unable to create external cache directory");
741 return null;
742 }
743 }
744 return mExternalCacheDir;
745 }
746 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 @Override
749 public File getFileStreamPath(String name) {
750 return makeFilename(getFilesDir(), name);
751 }
752
753 @Override
754 public String[] fileList() {
755 final String[] list = getFilesDir().list();
756 return (list != null) ? list : EMPTY_FILE_LIST;
757 }
758
759 @Override
760 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800761 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
763 setFilePermissionsFromMode(f.getPath(), mode, 0);
764 return db;
765 }
766
767 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700768 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
769 DatabaseErrorHandler errorHandler) {
770 File f = validateFilePath(name, true);
771 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
772 setFilePermissionsFromMode(f.getPath(), mode, 0);
773 return db;
774 }
775
776 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 public boolean deleteDatabase(String name) {
778 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800779 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 return f.delete();
781 } catch (Exception e) {
782 }
783 return false;
784 }
785
786 @Override
787 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800788 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 }
790
791 @Override
792 public String[] databaseList() {
793 final String[] list = getDatabasesDir().list();
794 return (list != null) ? list : EMPTY_FILE_LIST;
795 }
796
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 private File getDatabasesDir() {
799 synchronized (mSync) {
800 if (mDatabasesDir == null) {
801 mDatabasesDir = new File(getDataDirFile(), "databases");
802 }
803 if (mDatabasesDir.getPath().equals("databases")) {
804 mDatabasesDir = new File("/data/system");
805 }
806 return mDatabasesDir;
807 }
808 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200809
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800810 @Override
811 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700812 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 }
814
815 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700816 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700817 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800818 }
819
820 @Override
821 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700822 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 }
824
825 @Override
826 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700827 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 }
829
830 @Override
831 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700832 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 }
834
835 @Override
836 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700837 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 }
839
840 @Override
841 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700842 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 }
844
845 @Override
846 public void startActivity(Intent intent) {
847 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
848 throw new AndroidRuntimeException(
849 "Calling startActivity() from outside of an Activity "
850 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
851 + " Is this really what you want?");
852 }
853 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700854 getOuterContext(), mMainThread.getApplicationThread(), null,
855 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800856 }
857
858 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800859 public void startActivities(Intent[] intents) {
860 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
861 throw new AndroidRuntimeException(
862 "Calling startActivities() from outside of an Activity "
863 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
864 + " Is this really what you want?");
865 }
866 mMainThread.getInstrumentation().execStartActivities(
867 getOuterContext(), mMainThread.getApplicationThread(), null,
868 (Activity)null, intents);
869 }
870
871 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700872 public void startIntentSender(IntentSender intent,
873 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
874 throws IntentSender.SendIntentException {
875 try {
876 String resolvedType = null;
877 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400878 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700879 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
880 }
881 int result = ActivityManagerNative.getDefault()
882 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
883 fillInIntent, resolvedType, null, null,
884 0, flagsMask, flagsValues);
885 if (result == IActivityManager.START_CANCELED) {
886 throw new IntentSender.SendIntentException();
887 }
888 Instrumentation.checkStartActivityResult(result, null);
889 } catch (RemoteException e) {
890 }
891 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200892
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700893 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 public void sendBroadcast(Intent intent) {
895 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
896 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400897 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 ActivityManagerNative.getDefault().broadcastIntent(
899 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700900 Activity.RESULT_OK, null, null, null, false, false,
901 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 } catch (RemoteException e) {
903 }
904 }
905
906 @Override
907 public void sendBroadcast(Intent intent, String receiverPermission) {
908 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
909 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400910 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 ActivityManagerNative.getDefault().broadcastIntent(
912 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700913 Activity.RESULT_OK, null, null, receiverPermission, false, false,
914 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915 } catch (RemoteException e) {
916 }
917 }
918
919 @Override
920 public void sendOrderedBroadcast(Intent intent,
921 String receiverPermission) {
922 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
923 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400924 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 ActivityManagerNative.getDefault().broadcastIntent(
926 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700927 Activity.RESULT_OK, null, null, receiverPermission, true, false,
928 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 } catch (RemoteException e) {
930 }
931 }
932
933 @Override
934 public void sendOrderedBroadcast(Intent intent,
935 String receiverPermission, BroadcastReceiver resultReceiver,
936 Handler scheduler, int initialCode, String initialData,
937 Bundle initialExtras) {
938 IIntentReceiver rd = null;
939 if (resultReceiver != null) {
940 if (mPackageInfo != null) {
941 if (scheduler == null) {
942 scheduler = mMainThread.getHandler();
943 }
944 rd = mPackageInfo.getReceiverDispatcher(
945 resultReceiver, getOuterContext(), scheduler,
946 mMainThread.getInstrumentation(), false);
947 } else {
948 if (scheduler == null) {
949 scheduler = mMainThread.getHandler();
950 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700951 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
953 }
954 }
955 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
956 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400957 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 ActivityManagerNative.getDefault().broadcastIntent(
959 mMainThread.getApplicationThread(), intent, resolvedType, rd,
960 initialCode, initialData, initialExtras, receiverPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -0700961 true, false, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 } catch (RemoteException e) {
963 }
964 }
965
966 @Override
967 public void sendStickyBroadcast(Intent intent) {
968 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
969 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400970 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 ActivityManagerNative.getDefault().broadcastIntent(
972 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700973 Activity.RESULT_OK, null, null, null, false, true,
974 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800975 } catch (RemoteException e) {
976 }
977 }
978
979 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700980 public void sendStickyOrderedBroadcast(Intent intent,
981 BroadcastReceiver resultReceiver,
982 Handler scheduler, int initialCode, String initialData,
983 Bundle initialExtras) {
984 IIntentReceiver rd = null;
985 if (resultReceiver != null) {
986 if (mPackageInfo != null) {
987 if (scheduler == null) {
988 scheduler = mMainThread.getHandler();
989 }
990 rd = mPackageInfo.getReceiverDispatcher(
991 resultReceiver, getOuterContext(), scheduler,
992 mMainThread.getInstrumentation(), false);
993 } else {
994 if (scheduler == null) {
995 scheduler = mMainThread.getHandler();
996 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700997 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700998 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
999 }
1000 }
1001 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1002 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001003 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001004 ActivityManagerNative.getDefault().broadcastIntent(
1005 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1006 initialCode, initialData, initialExtras, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001007 true, true, Binder.getOrigCallingUser());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001008 } catch (RemoteException e) {
1009 }
1010 }
1011
1012 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013 public void removeStickyBroadcast(Intent intent) {
1014 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1015 if (resolvedType != null) {
1016 intent = new Intent(intent);
1017 intent.setDataAndType(intent.getData(), resolvedType);
1018 }
1019 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001020 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 ActivityManagerNative.getDefault().unbroadcastIntent(
Amith Yamasani742a6712011-05-04 14:49:28 -07001022 mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 } catch (RemoteException e) {
1024 }
1025 }
1026
1027 @Override
1028 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1029 return registerReceiver(receiver, filter, null, null);
1030 }
1031
1032 @Override
1033 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1034 String broadcastPermission, Handler scheduler) {
1035 return registerReceiverInternal(receiver, filter, broadcastPermission,
1036 scheduler, getOuterContext());
1037 }
1038
1039 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1040 IntentFilter filter, String broadcastPermission,
1041 Handler scheduler, Context context) {
1042 IIntentReceiver rd = null;
1043 if (receiver != null) {
1044 if (mPackageInfo != null && context != null) {
1045 if (scheduler == null) {
1046 scheduler = mMainThread.getHandler();
1047 }
1048 rd = mPackageInfo.getReceiverDispatcher(
1049 receiver, context, scheduler,
1050 mMainThread.getInstrumentation(), true);
1051 } else {
1052 if (scheduler == null) {
1053 scheduler = mMainThread.getHandler();
1054 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001055 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001056 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057 }
1058 }
1059 try {
1060 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001061 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 rd, filter, broadcastPermission);
1063 } catch (RemoteException e) {
1064 return null;
1065 }
1066 }
1067
1068 @Override
1069 public void unregisterReceiver(BroadcastReceiver receiver) {
1070 if (mPackageInfo != null) {
1071 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1072 getOuterContext(), receiver);
1073 try {
1074 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1075 } catch (RemoteException e) {
1076 }
1077 } else {
1078 throw new RuntimeException("Not supported in system context");
1079 }
1080 }
1081
1082 @Override
1083 public ComponentName startService(Intent service) {
1084 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001085 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 ComponentName cn = ActivityManagerNative.getDefault().startService(
1087 mMainThread.getApplicationThread(), service,
1088 service.resolveTypeIfNeeded(getContentResolver()));
1089 if (cn != null && cn.getPackageName().equals("!")) {
1090 throw new SecurityException(
1091 "Not allowed to start service " + service
1092 + " without permission " + cn.getClassName());
1093 }
1094 return cn;
1095 } catch (RemoteException e) {
1096 return null;
1097 }
1098 }
1099
1100 @Override
1101 public boolean stopService(Intent service) {
1102 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001103 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001104 int res = ActivityManagerNative.getDefault().stopService(
1105 mMainThread.getApplicationThread(), service,
1106 service.resolveTypeIfNeeded(getContentResolver()));
1107 if (res < 0) {
1108 throw new SecurityException(
1109 "Not allowed to stop service " + service);
1110 }
1111 return res != 0;
1112 } catch (RemoteException e) {
1113 return false;
1114 }
1115 }
1116
1117 @Override
1118 public boolean bindService(Intent service, ServiceConnection conn,
1119 int flags) {
1120 IServiceConnection sd;
1121 if (mPackageInfo != null) {
1122 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1123 mMainThread.getHandler(), flags);
1124 } else {
1125 throw new RuntimeException("Not supported in system context");
1126 }
1127 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001128 IBinder token = getActivityToken();
1129 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1130 && mPackageInfo.getApplicationInfo().targetSdkVersion
1131 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1132 flags |= BIND_WAIVE_PRIORITY;
1133 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001134 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 int res = ActivityManagerNative.getDefault().bindService(
1136 mMainThread.getApplicationThread(), getActivityToken(),
1137 service, service.resolveTypeIfNeeded(getContentResolver()),
1138 sd, flags);
1139 if (res < 0) {
1140 throw new SecurityException(
1141 "Not allowed to bind to service " + service);
1142 }
1143 return res != 0;
1144 } catch (RemoteException e) {
1145 return false;
1146 }
1147 }
1148
1149 @Override
1150 public void unbindService(ServiceConnection conn) {
1151 if (mPackageInfo != null) {
1152 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1153 getOuterContext(), conn);
1154 try {
1155 ActivityManagerNative.getDefault().unbindService(sd);
1156 } catch (RemoteException e) {
1157 }
1158 } else {
1159 throw new RuntimeException("Not supported in system context");
1160 }
1161 }
1162
1163 @Override
1164 public boolean startInstrumentation(ComponentName className,
1165 String profileFile, Bundle arguments) {
1166 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001167 if (arguments != null) {
1168 arguments.setAllowFds(false);
1169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 return ActivityManagerNative.getDefault().startInstrumentation(
1171 className, profileFile, 0, arguments, null);
1172 } catch (RemoteException e) {
1173 // System has crashed, nothing we can do.
1174 }
1175 return false;
1176 }
1177
1178 @Override
1179 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001180 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1181 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 }
1183
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001184 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001185 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 }
1187
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001188 /* package */ static DropBoxManager createDropBoxManager() {
1189 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1190 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001191 if (service == null) {
1192 // Don't return a DropBoxManager that will NPE upon use.
1193 // This also avoids caching a broken DropBoxManager in
1194 // getDropBoxManager during early boot, before the
1195 // DROPBOX_SERVICE is registered.
1196 return null;
1197 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001198 return new DropBoxManager(service);
1199 }
1200
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 @Override
1202 public int checkPermission(String permission, int pid, int uid) {
1203 if (permission == null) {
1204 throw new IllegalArgumentException("permission is null");
1205 }
1206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001207 try {
1208 return ActivityManagerNative.getDefault().checkPermission(
1209 permission, pid, uid);
1210 } catch (RemoteException e) {
1211 return PackageManager.PERMISSION_DENIED;
1212 }
1213 }
1214
1215 @Override
1216 public int checkCallingPermission(String permission) {
1217 if (permission == null) {
1218 throw new IllegalArgumentException("permission is null");
1219 }
1220
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 int pid = Binder.getCallingPid();
1222 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001223 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 }
1225 return PackageManager.PERMISSION_DENIED;
1226 }
1227
1228 @Override
1229 public int checkCallingOrSelfPermission(String permission) {
1230 if (permission == null) {
1231 throw new IllegalArgumentException("permission is null");
1232 }
1233
1234 return checkPermission(permission, Binder.getCallingPid(),
1235 Binder.getCallingUid());
1236 }
1237
1238 private void enforce(
1239 String permission, int resultOfCheck,
1240 boolean selfToo, int uid, String message) {
1241 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1242 throw new SecurityException(
1243 (message != null ? (message + ": ") : "") +
1244 (selfToo
1245 ? "Neither user " + uid + " nor current process has "
1246 : "User " + uid + " does not have ") +
1247 permission +
1248 ".");
1249 }
1250 }
1251
1252 public void enforcePermission(
1253 String permission, int pid, int uid, String message) {
1254 enforce(permission,
1255 checkPermission(permission, pid, uid),
1256 false,
1257 uid,
1258 message);
1259 }
1260
1261 public void enforceCallingPermission(String permission, String message) {
1262 enforce(permission,
1263 checkCallingPermission(permission),
1264 false,
1265 Binder.getCallingUid(),
1266 message);
1267 }
1268
1269 public void enforceCallingOrSelfPermission(
1270 String permission, String message) {
1271 enforce(permission,
1272 checkCallingOrSelfPermission(permission),
1273 true,
1274 Binder.getCallingUid(),
1275 message);
1276 }
1277
1278 @Override
1279 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1280 try {
1281 ActivityManagerNative.getDefault().grantUriPermission(
1282 mMainThread.getApplicationThread(), toPackage, uri,
1283 modeFlags);
1284 } catch (RemoteException e) {
1285 }
1286 }
1287
1288 @Override
1289 public void revokeUriPermission(Uri uri, int modeFlags) {
1290 try {
1291 ActivityManagerNative.getDefault().revokeUriPermission(
1292 mMainThread.getApplicationThread(), uri,
1293 modeFlags);
1294 } catch (RemoteException e) {
1295 }
1296 }
1297
1298 @Override
1299 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 try {
1301 return ActivityManagerNative.getDefault().checkUriPermission(
1302 uri, pid, uid, modeFlags);
1303 } catch (RemoteException e) {
1304 return PackageManager.PERMISSION_DENIED;
1305 }
1306 }
1307
1308 @Override
1309 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 int pid = Binder.getCallingPid();
1311 if (pid != Process.myPid()) {
1312 return checkUriPermission(uri, pid,
1313 Binder.getCallingUid(), modeFlags);
1314 }
1315 return PackageManager.PERMISSION_DENIED;
1316 }
1317
1318 @Override
1319 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1320 return checkUriPermission(uri, Binder.getCallingPid(),
1321 Binder.getCallingUid(), modeFlags);
1322 }
1323
1324 @Override
1325 public int checkUriPermission(Uri uri, String readPermission,
1326 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001327 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1329 + readPermission + " writePermission=" + writePermission
1330 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1331 }
1332 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1333 if (readPermission == null
1334 || checkPermission(readPermission, pid, uid)
1335 == PackageManager.PERMISSION_GRANTED) {
1336 return PackageManager.PERMISSION_GRANTED;
1337 }
1338 }
1339 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1340 if (writePermission == null
1341 || checkPermission(writePermission, pid, uid)
1342 == PackageManager.PERMISSION_GRANTED) {
1343 return PackageManager.PERMISSION_GRANTED;
1344 }
1345 }
1346 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1347 : PackageManager.PERMISSION_DENIED;
1348 }
1349
1350 private String uriModeFlagToString(int uriModeFlags) {
1351 switch (uriModeFlags) {
1352 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1353 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1354 return "read and write";
1355 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1356 return "read";
1357 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1358 return "write";
1359 }
1360 throw new IllegalArgumentException(
1361 "Unknown permission mode flags: " + uriModeFlags);
1362 }
1363
1364 private void enforceForUri(
1365 int modeFlags, int resultOfCheck, boolean selfToo,
1366 int uid, Uri uri, String message) {
1367 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1368 throw new SecurityException(
1369 (message != null ? (message + ": ") : "") +
1370 (selfToo
1371 ? "Neither user " + uid + " nor current process has "
1372 : "User " + uid + " does not have ") +
1373 uriModeFlagToString(modeFlags) +
1374 " permission on " +
1375 uri +
1376 ".");
1377 }
1378 }
1379
1380 public void enforceUriPermission(
1381 Uri uri, int pid, int uid, int modeFlags, String message) {
1382 enforceForUri(
1383 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1384 false, uid, uri, message);
1385 }
1386
1387 public void enforceCallingUriPermission(
1388 Uri uri, int modeFlags, String message) {
1389 enforceForUri(
1390 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001391 false,
1392 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001393 }
1394
1395 public void enforceCallingOrSelfUriPermission(
1396 Uri uri, int modeFlags, String message) {
1397 enforceForUri(
1398 modeFlags,
1399 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1400 Binder.getCallingUid(), uri, message);
1401 }
1402
1403 public void enforceUriPermission(
1404 Uri uri, String readPermission, String writePermission,
1405 int pid, int uid, int modeFlags, String message) {
1406 enforceForUri(modeFlags,
1407 checkUriPermission(
1408 uri, readPermission, writePermission, pid, uid,
1409 modeFlags),
1410 false,
1411 uid,
1412 uri,
1413 message);
1414 }
1415
1416 @Override
1417 public Context createPackageContext(String packageName, int flags)
1418 throws PackageManager.NameNotFoundException {
1419 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001420 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 }
1422
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001423 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001424 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001426 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001427 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001428 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 if (c.mResources != null) {
1430 return c;
1431 }
1432 }
1433
1434 // Should be a better exception.
1435 throw new PackageManager.NameNotFoundException(
1436 "Application package " + packageName + " not found");
1437 }
1438
Romain Guy870e09f2009-07-06 16:35:25 -07001439 @Override
1440 public boolean isRestricted() {
1441 return mRestricted;
1442 }
1443
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 private File getDataDirFile() {
1445 if (mPackageInfo != null) {
1446 return mPackageInfo.getDataDirFile();
1447 }
1448 throw new RuntimeException("Not supported in system context");
1449 }
1450
1451 @Override
1452 public File getDir(String name, int mode) {
1453 name = "app_" + name;
1454 File file = makeFilename(getDataDirFile(), name);
1455 if (!file.exists()) {
1456 file.mkdir();
1457 setFilePermissionsFromMode(file.getPath(), mode,
1458 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1459 }
1460 return file;
1461 }
1462
Dianne Hackborn21556372010-02-04 16:34:40 -08001463 static ContextImpl createSystemContext(ActivityThread mainThread) {
1464 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 context.init(Resources.getSystem(), mainThread);
1466 return context;
1467 }
1468
Dianne Hackborn21556372010-02-04 16:34:40 -08001469 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 mOuterContext = this;
1471 }
1472
1473 /**
1474 * Create a new ApplicationContext from an existing one. The new one
1475 * works and operates the same as the one it is copying.
1476 *
1477 * @param context Existing application context.
1478 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001479 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001481 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 mResources = context.mResources;
1483 mMainThread = context.mMainThread;
1484 mContentResolver = context.mContentResolver;
1485 mOuterContext = this;
1486 }
1487
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001488 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001490 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001491 }
1492
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001493 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001494 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001495 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001497 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001499
Dianne Hackborn559a7872010-04-07 18:19:41 -07001500 if (mResources != null && container != null
1501 && container.getCompatibilityInfo().applicationScale !=
1502 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001503 if (DEBUG) {
1504 Log.d(TAG, "loaded context has different scaling. Using container's" +
1505 " compatiblity info:" + container.getDisplayMetrics());
1506 }
1507 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001508 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 mMainThread = mainThread;
1511 mContentResolver = new ApplicationContentResolver(this, mainThread);
1512
1513 setActivityToken(activityToken);
1514 }
1515
1516 final void init(Resources resources, ActivityThread mainThread) {
1517 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001518 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 mResources = resources;
1520 mMainThread = mainThread;
1521 mContentResolver = new ApplicationContentResolver(this, mainThread);
1522 }
1523
1524 final void scheduleFinalCleanup(String who, String what) {
1525 mMainThread.scheduleContextCleanup(this, who, what);
1526 }
1527
1528 final void performFinalCleanup(String who, String what) {
1529 //Log.i(TAG, "Cleanup up context: " + this);
1530 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1531 }
1532
1533 final Context getReceiverRestrictedContext() {
1534 if (mReceiverRestrictedContext != null) {
1535 return mReceiverRestrictedContext;
1536 }
1537 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1538 }
1539
1540 final void setActivityToken(IBinder token) {
1541 mActivityToken = token;
1542 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 final void setOuterContext(Context context) {
1545 mOuterContext = context;
1546 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 final Context getOuterContext() {
1549 return mOuterContext;
1550 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 final IBinder getActivityToken() {
1553 return mActivityToken;
1554 }
1555
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001556 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 int extraPermissions) {
1558 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1559 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1560 |extraPermissions;
1561 if ((mode&MODE_WORLD_READABLE) != 0) {
1562 perms |= FileUtils.S_IROTH;
1563 }
1564 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1565 perms |= FileUtils.S_IWOTH;
1566 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001567 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1569 + ", perms=0x" + Integer.toHexString(perms));
1570 }
1571 FileUtils.setPermissions(name, perms, -1, -1);
1572 }
1573
Oscar Montemayora8529f62009-11-18 10:14:20 -08001574 private File validateFilePath(String name, boolean createDirectory) {
1575 File dir;
1576 File f;
1577
1578 if (name.charAt(0) == File.separatorChar) {
1579 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1580 dir = new File(dirPath);
1581 name = name.substring(name.lastIndexOf(File.separatorChar));
1582 f = new File(dir, name);
1583 } else {
1584 dir = getDatabasesDir();
1585 f = makeFilename(dir, name);
1586 }
1587
1588 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1589 FileUtils.setPermissions(dir.getPath(),
1590 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1591 -1, -1);
1592 }
1593
1594 return f;
1595 }
1596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 private File makeFilename(File base, String name) {
1598 if (name.indexOf(File.separatorChar) < 0) {
1599 return new File(base, name);
1600 }
1601 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001602 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 }
1604
1605 // ----------------------------------------------------------------------
1606 // ----------------------------------------------------------------------
1607 // ----------------------------------------------------------------------
1608
1609 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001610 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 super(context);
1612 mMainThread = mainThread;
1613 }
1614
1615 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001616 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001617 return mMainThread.acquireProvider(context, name);
1618 }
1619
1620 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001621 protected IContentProvider acquireExistingProvider(Context context, String name) {
1622 return mMainThread.acquireExistingProvider(context, name);
1623 }
1624
1625 @Override
1626 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 return mMainThread.releaseProvider(provider);
1628 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 private final ActivityThread mMainThread;
1631 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632}