blob: 8749d3e17e0e47df9063da305eb2fa72cb81b5ac [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;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080062import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.os.Binder;
64import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080065import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080066import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.os.FileUtils;
68import android.os.Handler;
69import android.os.IBinder;
70import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070071import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.PowerManager;
73import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070074import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.os.ServiceManager;
76import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080077import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070079import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.util.AndroidRuntimeException;
81import android.util.Log;
82import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070084import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070086import android.accounts.AccountManager;
87import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080088import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080089import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import java.io.File;
92import java.io.FileInputStream;
93import java.io.FileNotFoundException;
94import java.io.FileOutputStream;
95import java.io.IOException;
96import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import java.util.ArrayList;
98import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100class ReceiverRestrictedContext extends ContextWrapper {
101 ReceiverRestrictedContext(Context base) {
102 super(base);
103 }
104
105 @Override
106 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
107 return registerReceiver(receiver, filter, null, null);
108 }
109
110 @Override
111 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
112 String broadcastPermission, Handler scheduler) {
113 throw new ReceiverCallNotAllowedException(
114 "IntentReceiver components are not allowed to register to receive intents");
115 //ex.fillInStackTrace();
116 //Log.e("IntentReceiver", ex.getMessage(), ex);
117 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
118 // scheduler);
119 }
120
121 @Override
122 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
123 throw new ReceiverCallNotAllowedException(
124 "IntentReceiver components are not allowed to bind to services");
125 //ex.fillInStackTrace();
126 //Log.e("IntentReceiver", ex.getMessage(), ex);
127 //return mContext.bindService(service, interfaceName, conn, flags);
128 }
129}
130
131/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800132 * Common implementation of Context API, which provides the base
133 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800135class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700137 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800138
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700139 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
140 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700142 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700143 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 private Resources mResources;
145 /*package*/ ActivityThread mMainThread;
146 private Context mOuterContext;
147 private IBinder mActivityToken = null;
148 private ApplicationContentResolver mContentResolver;
149 private int mThemeResource = 0;
150 private Resources.Theme mTheme = null;
151 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700153 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154
155 private final Object mSync = new Object();
156
157 private File mDatabasesDir;
158 private File mPreferencesDir;
159 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800161 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800162 private File mExternalFilesDir;
163 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 private static final String[] EMPTY_FILE_LIST = {};
166
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800167 /**
168 * Override this class when the system service constructor needs a
169 * ContextImpl. Else, use StaticServiceFetcher below.
170 */
171 /*package*/ static class ServiceFetcher {
172 int mContextCacheIndex = -1;
173
174 /**
175 * Main entrypoint; only override if you don't need caching.
176 */
177 public Object getService(ContextImpl ctx) {
178 ArrayList<Object> cache = ctx.mServiceCache;
179 Object service;
180 synchronized (cache) {
181 if (cache.size() == 0) {
182 // Initialize the cache vector on first access.
183 // At this point sNextPerContextServiceCacheIndex
184 // is the number of potential services that are
185 // cached per-Context.
186 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
187 cache.add(null);
188 }
189 } else {
190 service = cache.get(mContextCacheIndex);
191 if (service != null) {
192 return service;
193 }
194 }
195 service = createService(ctx);
196 cache.set(mContextCacheIndex, service);
197 return service;
198 }
199 }
200
201 /**
202 * Override this to create a new per-Context instance of the
203 * service. getService() will handle locking and caching.
204 */
205 public Object createService(ContextImpl ctx) {
206 throw new RuntimeException("Not implemented");
207 }
208 }
209
210 /**
211 * Override this class for services to be cached process-wide.
212 */
213 abstract static class StaticServiceFetcher extends ServiceFetcher {
214 private Object mCachedInstance;
215
216 @Override
217 public final Object getService(ContextImpl unused) {
218 synchronized (StaticServiceFetcher.this) {
219 Object service = mCachedInstance;
220 if (service != null) {
221 return service;
222 }
223 return mCachedInstance = createStaticService();
224 }
225 }
226
227 public abstract Object createStaticService();
228 }
229
230 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
231 new HashMap<String, ServiceFetcher>();
232
233 private static int sNextPerContextServiceCacheIndex = 0;
234 private static void registerService(String serviceName, ServiceFetcher fetcher) {
235 if (!(fetcher instanceof StaticServiceFetcher)) {
236 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
237 }
238 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
239 }
240
241 // This one's defined separately and given a variable name so it
242 // can be re-used by getWallpaperManager(), avoiding a HashMap
243 // lookup.
244 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
245 public Object createService(ContextImpl ctx) {
246 return new WallpaperManager(ctx.getOuterContext(),
247 ctx.mMainThread.getHandler());
248 }};
249
250 static {
251 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
252 public Object getService(ContextImpl ctx) {
253 return AccessibilityManager.getInstance(ctx);
254 }});
255
256 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
257 public Object createService(ContextImpl ctx) {
258 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
259 IAccountManager service = IAccountManager.Stub.asInterface(b);
260 return new AccountManager(ctx, service);
261 }});
262
263 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
264 public Object createService(ContextImpl ctx) {
265 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
266 }});
267
268 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
269 public Object createStaticService() {
270 IBinder b = ServiceManager.getService(ALARM_SERVICE);
271 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
272 return new AlarmManager(service);
273 }});
274
275 registerService(AUDIO_SERVICE, new ServiceFetcher() {
276 public Object createService(ContextImpl ctx) {
277 return new AudioManager(ctx);
278 }});
279
280 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
281 public Object createService(ContextImpl ctx) {
282 return new ClipboardManager(ctx.getOuterContext(),
283 ctx.mMainThread.getHandler());
284 }});
285
286 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
287 public Object createStaticService() {
288 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
289 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
290 }});
291
292 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
293 public Object createStaticService() {
294 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
295 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
296 }});
297
298 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
299 public Object createService(ContextImpl ctx) {
300 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
301 }});
302
303 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
304 public Object createService(ContextImpl ctx) {
305 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
306 }});
307
Nick Pellyd2507462010-12-13 12:22:34 -0800308 registerService(NFC_SERVICE, new ServiceFetcher() {
309 public Object createService(ContextImpl ctx) {
310 return new NfcManager(ctx);
311 }});
312
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800313 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
314 public Object createStaticService() {
315 return createDropBoxManager();
316 }});
317
318 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
319 public Object createService(ContextImpl ctx) {
320 return InputMethodManager.getInstance(ctx);
321 }});
322
323 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
324 public Object getService(ContextImpl ctx) {
325 // TODO: why isn't this caching it? It wasn't
326 // before, so I'm preserving the old behavior and
327 // using getService(), instead of createService()
328 // which would do the caching.
329 return new KeyguardManager();
330 }});
331
332 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
333 public Object createService(ContextImpl ctx) {
334 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
335 }});
336
337 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
338 public Object createStaticService() {
339 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
340 return new LocationManager(ILocationManager.Stub.asInterface(b));
341 }});
342
Jeff Sharkey1a303952011-06-16 13:04:20 -0700343 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
344 @Override
345 public Object createService(ContextImpl ctx) {
346 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
347 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
348 }
349 });
350
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800351 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
352 public Object createService(ContextImpl ctx) {
353 final Context outerContext = ctx.getOuterContext();
354 return new NotificationManager(
355 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800356 Resources.selectSystemTheme(0,
357 outerContext.getApplicationInfo().targetSdkVersion,
358 com.android.internal.R.style.Theme_Dialog,
359 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800360 ctx.mMainThread.getHandler());
361 }});
362
363 // Note: this was previously cached in a static variable, but
364 // constructed using mMainThread.getHandler(), so converting
365 // it to be a regular Context-cached service...
366 registerService(POWER_SERVICE, new ServiceFetcher() {
367 public Object createService(ContextImpl ctx) {
368 IBinder b = ServiceManager.getService(POWER_SERVICE);
369 IPowerManager service = IPowerManager.Stub.asInterface(b);
370 return new PowerManager(service, ctx.mMainThread.getHandler());
371 }});
372
373 registerService(SEARCH_SERVICE, new ServiceFetcher() {
374 public Object createService(ContextImpl ctx) {
375 return new SearchManager(ctx.getOuterContext(),
376 ctx.mMainThread.getHandler());
377 }});
378
379 registerService(SENSOR_SERVICE, new ServiceFetcher() {
380 public Object createService(ContextImpl ctx) {
381 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
382 }});
383
384 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
385 public Object createService(ContextImpl ctx) {
386 return new StatusBarManager(ctx.getOuterContext());
387 }});
388
389 registerService(STORAGE_SERVICE, new ServiceFetcher() {
390 public Object createService(ContextImpl ctx) {
391 try {
392 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
393 } catch (RemoteException rex) {
394 Log.e(TAG, "Failed to create StorageManager", rex);
395 return null;
396 }
397 }});
398
399 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
400 public Object createService(ContextImpl ctx) {
401 return new TelephonyManager(ctx.getOuterContext());
402 }});
403
404 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
405 public Object createStaticService() {
406 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
407 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
408 }});
409
410 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
411 public Object createService(ContextImpl ctx) {
412 return new UiModeManager();
413 }});
414
Mike Lockwood3a68b832011-03-08 10:08:59 -0500415 registerService(USB_SERVICE, new ServiceFetcher() {
416 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500417 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500418 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500419 }});
420
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800421 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
422 public Object createService(ContextImpl ctx) {
423 return new Vibrator();
424 }});
425
426 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
427
428 registerService(WIFI_SERVICE, new ServiceFetcher() {
429 public Object createService(ContextImpl ctx) {
430 IBinder b = ServiceManager.getService(WIFI_SERVICE);
431 IWifiManager service = IWifiManager.Stub.asInterface(b);
432 return new WifiManager(service, ctx.mMainThread.getHandler());
433 }});
434
435 registerService(WINDOW_SERVICE, new ServiceFetcher() {
436 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700437 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800438 }});
439 }
440
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700441 static ContextImpl getImpl(Context context) {
442 Context nextContext;
443 while ((context instanceof ContextWrapper) &&
444 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
445 context = nextContext;
446 }
447 return (ContextImpl)context;
448 }
449
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800450 // The system service cache for the system services that are
451 // cached per-ContextImpl. Package-scoped to avoid accessor
452 // methods.
453 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 @Override
456 public AssetManager getAssets() {
457 return mResources.getAssets();
458 }
459
460 @Override
461 public Resources getResources() {
462 return mResources;
463 }
464
465 @Override
466 public PackageManager getPackageManager() {
467 if (mPackageManager != null) {
468 return mPackageManager;
469 }
470
471 IPackageManager pm = ActivityThread.getPackageManager();
472 if (pm != null) {
473 // Doesn't matter if we make more than one instance.
474 return (mPackageManager = new ApplicationPackageManager(this, pm));
475 }
476
477 return null;
478 }
479
480 @Override
481 public ContentResolver getContentResolver() {
482 return mContentResolver;
483 }
484
485 @Override
486 public Looper getMainLooper() {
487 return mMainThread.getLooper();
488 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 @Override
491 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700492 return (mPackageInfo != null) ?
493 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 @Override
497 public void setTheme(int resid) {
498 mThemeResource = resid;
499 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800502 public int getThemeResId() {
503 return mThemeResource;
504 }
505
506 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 public Resources.Theme getTheme() {
508 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800509 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
510 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 mTheme = mResources.newTheme();
512 mTheme.applyStyle(mThemeResource, true);
513 }
514 return mTheme;
515 }
516
517 @Override
518 public ClassLoader getClassLoader() {
519 return mPackageInfo != null ?
520 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
521 }
522
523 @Override
524 public String getPackageName() {
525 if (mPackageInfo != null) {
526 return mPackageInfo.getPackageName();
527 }
528 throw new RuntimeException("Not supported in system context");
529 }
530
531 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700532 public ApplicationInfo getApplicationInfo() {
533 if (mPackageInfo != null) {
534 return mPackageInfo.getApplicationInfo();
535 }
536 throw new RuntimeException("Not supported in system context");
537 }
538
539 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 public String getPackageResourcePath() {
541 if (mPackageInfo != null) {
542 return mPackageInfo.getResDir();
543 }
544 throw new RuntimeException("Not supported in system context");
545 }
546
547 @Override
548 public String getPackageCodePath() {
549 if (mPackageInfo != null) {
550 return mPackageInfo.getAppDir();
551 }
552 throw new RuntimeException("Not supported in system context");
553 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200554
Joe Onorato23ecae32009-06-10 17:07:15 -0700555 public File getSharedPrefsFile(String name) {
556 return makeFilename(getPreferencesDir(), name + ".xml");
557 }
558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559 @Override
560 public SharedPreferences getSharedPreferences(String name, int mode) {
561 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700563 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700564 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800565 File prefsFile = getSharedPrefsFile(name);
566 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700567 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700568 return sp;
569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800571 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
572 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
573 // If somebody else (some other process) changed the prefs
574 // file behind our back, we reload it. This has been the
575 // historical (if undocumented) behavior.
576 sp.startReloadIfChangedUnexpectedly();
577 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700578 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 }
580
581 private File getPreferencesDir() {
582 synchronized (mSync) {
583 if (mPreferencesDir == null) {
584 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
585 }
586 return mPreferencesDir;
587 }
588 }
589
590 @Override
591 public FileInputStream openFileInput(String name)
592 throws FileNotFoundException {
593 File f = makeFilename(getFilesDir(), name);
594 return new FileInputStream(f);
595 }
596
597 @Override
598 public FileOutputStream openFileOutput(String name, int mode)
599 throws FileNotFoundException {
600 final boolean append = (mode&MODE_APPEND) != 0;
601 File f = makeFilename(getFilesDir(), name);
602 try {
603 FileOutputStream fos = new FileOutputStream(f, append);
604 setFilePermissionsFromMode(f.getPath(), mode, 0);
605 return fos;
606 } catch (FileNotFoundException e) {
607 }
608
609 File parent = f.getParentFile();
610 parent.mkdir();
611 FileUtils.setPermissions(
612 parent.getPath(),
613 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
614 -1, -1);
615 FileOutputStream fos = new FileOutputStream(f, append);
616 setFilePermissionsFromMode(f.getPath(), mode, 0);
617 return fos;
618 }
619
620 @Override
621 public boolean deleteFile(String name) {
622 File f = makeFilename(getFilesDir(), name);
623 return f.delete();
624 }
625
626 @Override
627 public File getFilesDir() {
628 synchronized (mSync) {
629 if (mFilesDir == null) {
630 mFilesDir = new File(getDataDirFile(), "files");
631 }
632 if (!mFilesDir.exists()) {
633 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200634 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 return null;
636 }
637 FileUtils.setPermissions(
638 mFilesDir.getPath(),
639 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
640 -1, -1);
641 }
642 return mFilesDir;
643 }
644 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800647 public File getExternalFilesDir(String type) {
648 synchronized (mSync) {
649 if (mExternalFilesDir == null) {
650 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
651 getPackageName());
652 }
653 if (!mExternalFilesDir.exists()) {
654 try {
655 (new File(Environment.getExternalStorageAndroidDataDir(),
656 ".nomedia")).createNewFile();
657 } catch (IOException e) {
658 }
659 if (!mExternalFilesDir.mkdirs()) {
660 Log.w(TAG, "Unable to create external files directory");
661 return null;
662 }
663 }
664 if (type == null) {
665 return mExternalFilesDir;
666 }
667 File dir = new File(mExternalFilesDir, type);
668 if (!dir.exists()) {
669 if (!dir.mkdirs()) {
670 Log.w(TAG, "Unable to create external media directory " + dir);
671 return null;
672 }
673 }
674 return dir;
675 }
676 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200677
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800678 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800679 public File getObbDir() {
680 synchronized (mSync) {
681 if (mObbDir == null) {
682 mObbDir = Environment.getExternalStorageAppObbDirectory(
683 getPackageName());
684 }
685 return mObbDir;
686 }
687 }
688
689 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800690 public File getCacheDir() {
691 synchronized (mSync) {
692 if (mCacheDir == null) {
693 mCacheDir = new File(getDataDirFile(), "cache");
694 }
695 if (!mCacheDir.exists()) {
696 if(!mCacheDir.mkdirs()) {
697 Log.w(TAG, "Unable to create cache directory");
698 return null;
699 }
700 FileUtils.setPermissions(
701 mCacheDir.getPath(),
702 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
703 -1, -1);
704 }
705 }
706 return mCacheDir;
707 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200708
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800709 @Override
710 public File getExternalCacheDir() {
711 synchronized (mSync) {
712 if (mExternalCacheDir == null) {
713 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
714 getPackageName());
715 }
716 if (!mExternalCacheDir.exists()) {
717 try {
718 (new File(Environment.getExternalStorageAndroidDataDir(),
719 ".nomedia")).createNewFile();
720 } catch (IOException e) {
721 }
722 if (!mExternalCacheDir.mkdirs()) {
723 Log.w(TAG, "Unable to create external cache directory");
724 return null;
725 }
726 }
727 return mExternalCacheDir;
728 }
729 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 @Override
732 public File getFileStreamPath(String name) {
733 return makeFilename(getFilesDir(), name);
734 }
735
736 @Override
737 public String[] fileList() {
738 final String[] list = getFilesDir().list();
739 return (list != null) ? list : EMPTY_FILE_LIST;
740 }
741
742 @Override
743 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800744 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800745 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
746 setFilePermissionsFromMode(f.getPath(), mode, 0);
747 return db;
748 }
749
750 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700751 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
752 DatabaseErrorHandler errorHandler) {
753 File f = validateFilePath(name, true);
754 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
755 setFilePermissionsFromMode(f.getPath(), mode, 0);
756 return db;
757 }
758
759 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 public boolean deleteDatabase(String name) {
761 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800762 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763 return f.delete();
764 } catch (Exception e) {
765 }
766 return false;
767 }
768
769 @Override
770 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800771 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 }
773
774 @Override
775 public String[] databaseList() {
776 final String[] list = getDatabasesDir().list();
777 return (list != null) ? list : EMPTY_FILE_LIST;
778 }
779
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 private File getDatabasesDir() {
782 synchronized (mSync) {
783 if (mDatabasesDir == null) {
784 mDatabasesDir = new File(getDataDirFile(), "databases");
785 }
786 if (mDatabasesDir.getPath().equals("databases")) {
787 mDatabasesDir = new File("/data/system");
788 }
789 return mDatabasesDir;
790 }
791 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800793 @Override
794 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700795 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 }
797
798 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700799 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700800 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 }
802
803 @Override
804 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700805 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 }
807
808 @Override
809 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700810 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
812
813 @Override
814 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700815 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 }
817
818 @Override
819 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700820 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 }
822
823 @Override
824 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700825 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 }
827
828 @Override
829 public void startActivity(Intent intent) {
830 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
831 throw new AndroidRuntimeException(
832 "Calling startActivity() from outside of an Activity "
833 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
834 + " Is this really what you want?");
835 }
836 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700837 getOuterContext(), mMainThread.getApplicationThread(), null,
838 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 }
840
841 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800842 public void startActivities(Intent[] intents) {
843 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
844 throw new AndroidRuntimeException(
845 "Calling startActivities() from outside of an Activity "
846 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
847 + " Is this really what you want?");
848 }
849 mMainThread.getInstrumentation().execStartActivities(
850 getOuterContext(), mMainThread.getApplicationThread(), null,
851 (Activity)null, intents);
852 }
853
854 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700855 public void startIntentSender(IntentSender intent,
856 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
857 throws IntentSender.SendIntentException {
858 try {
859 String resolvedType = null;
860 if (fillInIntent != null) {
861 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
862 }
863 int result = ActivityManagerNative.getDefault()
864 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
865 fillInIntent, resolvedType, null, null,
866 0, flagsMask, flagsValues);
867 if (result == IActivityManager.START_CANCELED) {
868 throw new IntentSender.SendIntentException();
869 }
870 Instrumentation.checkStartActivityResult(result, null);
871 } catch (RemoteException e) {
872 }
873 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200874
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700875 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 public void sendBroadcast(Intent intent) {
877 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
878 try {
879 ActivityManagerNative.getDefault().broadcastIntent(
880 mMainThread.getApplicationThread(), intent, resolvedType, null,
881 Activity.RESULT_OK, null, null, null, false, false);
882 } catch (RemoteException e) {
883 }
884 }
885
886 @Override
887 public void sendBroadcast(Intent intent, String receiverPermission) {
888 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
889 try {
890 ActivityManagerNative.getDefault().broadcastIntent(
891 mMainThread.getApplicationThread(), intent, resolvedType, null,
892 Activity.RESULT_OK, null, null, receiverPermission, false, false);
893 } catch (RemoteException e) {
894 }
895 }
896
897 @Override
898 public void sendOrderedBroadcast(Intent intent,
899 String receiverPermission) {
900 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
901 try {
902 ActivityManagerNative.getDefault().broadcastIntent(
903 mMainThread.getApplicationThread(), intent, resolvedType, null,
904 Activity.RESULT_OK, null, null, receiverPermission, true, false);
905 } catch (RemoteException e) {
906 }
907 }
908
909 @Override
910 public void sendOrderedBroadcast(Intent intent,
911 String receiverPermission, BroadcastReceiver resultReceiver,
912 Handler scheduler, int initialCode, String initialData,
913 Bundle initialExtras) {
914 IIntentReceiver rd = null;
915 if (resultReceiver != null) {
916 if (mPackageInfo != null) {
917 if (scheduler == null) {
918 scheduler = mMainThread.getHandler();
919 }
920 rd = mPackageInfo.getReceiverDispatcher(
921 resultReceiver, getOuterContext(), scheduler,
922 mMainThread.getInstrumentation(), false);
923 } else {
924 if (scheduler == null) {
925 scheduler = mMainThread.getHandler();
926 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700927 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
929 }
930 }
931 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
932 try {
933 ActivityManagerNative.getDefault().broadcastIntent(
934 mMainThread.getApplicationThread(), intent, resolvedType, rd,
935 initialCode, initialData, initialExtras, receiverPermission,
936 true, false);
937 } catch (RemoteException e) {
938 }
939 }
940
941 @Override
942 public void sendStickyBroadcast(Intent intent) {
943 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
944 try {
945 ActivityManagerNative.getDefault().broadcastIntent(
946 mMainThread.getApplicationThread(), intent, resolvedType, null,
947 Activity.RESULT_OK, null, null, null, false, true);
948 } catch (RemoteException e) {
949 }
950 }
951
952 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700953 public void sendStickyOrderedBroadcast(Intent intent,
954 BroadcastReceiver resultReceiver,
955 Handler scheduler, int initialCode, String initialData,
956 Bundle initialExtras) {
957 IIntentReceiver rd = null;
958 if (resultReceiver != null) {
959 if (mPackageInfo != null) {
960 if (scheduler == null) {
961 scheduler = mMainThread.getHandler();
962 }
963 rd = mPackageInfo.getReceiverDispatcher(
964 resultReceiver, getOuterContext(), scheduler,
965 mMainThread.getInstrumentation(), false);
966 } else {
967 if (scheduler == null) {
968 scheduler = mMainThread.getHandler();
969 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700970 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700971 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
972 }
973 }
974 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
975 try {
976 ActivityManagerNative.getDefault().broadcastIntent(
977 mMainThread.getApplicationThread(), intent, resolvedType, rd,
978 initialCode, initialData, initialExtras, null,
979 true, true);
980 } catch (RemoteException e) {
981 }
982 }
983
984 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 public void removeStickyBroadcast(Intent intent) {
986 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
987 if (resolvedType != null) {
988 intent = new Intent(intent);
989 intent.setDataAndType(intent.getData(), resolvedType);
990 }
991 try {
992 ActivityManagerNative.getDefault().unbroadcastIntent(
993 mMainThread.getApplicationThread(), intent);
994 } catch (RemoteException e) {
995 }
996 }
997
998 @Override
999 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1000 return registerReceiver(receiver, filter, null, null);
1001 }
1002
1003 @Override
1004 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1005 String broadcastPermission, Handler scheduler) {
1006 return registerReceiverInternal(receiver, filter, broadcastPermission,
1007 scheduler, getOuterContext());
1008 }
1009
1010 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1011 IntentFilter filter, String broadcastPermission,
1012 Handler scheduler, Context context) {
1013 IIntentReceiver rd = null;
1014 if (receiver != null) {
1015 if (mPackageInfo != null && context != null) {
1016 if (scheduler == null) {
1017 scheduler = mMainThread.getHandler();
1018 }
1019 rd = mPackageInfo.getReceiverDispatcher(
1020 receiver, context, scheduler,
1021 mMainThread.getInstrumentation(), true);
1022 } else {
1023 if (scheduler == null) {
1024 scheduler = mMainThread.getHandler();
1025 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001026 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001027 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 }
1029 }
1030 try {
1031 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001032 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001033 rd, filter, broadcastPermission);
1034 } catch (RemoteException e) {
1035 return null;
1036 }
1037 }
1038
1039 @Override
1040 public void unregisterReceiver(BroadcastReceiver receiver) {
1041 if (mPackageInfo != null) {
1042 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1043 getOuterContext(), receiver);
1044 try {
1045 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1046 } catch (RemoteException e) {
1047 }
1048 } else {
1049 throw new RuntimeException("Not supported in system context");
1050 }
1051 }
1052
1053 @Override
1054 public ComponentName startService(Intent service) {
1055 try {
1056 ComponentName cn = ActivityManagerNative.getDefault().startService(
1057 mMainThread.getApplicationThread(), service,
1058 service.resolveTypeIfNeeded(getContentResolver()));
1059 if (cn != null && cn.getPackageName().equals("!")) {
1060 throw new SecurityException(
1061 "Not allowed to start service " + service
1062 + " without permission " + cn.getClassName());
1063 }
1064 return cn;
1065 } catch (RemoteException e) {
1066 return null;
1067 }
1068 }
1069
1070 @Override
1071 public boolean stopService(Intent service) {
1072 try {
1073 int res = ActivityManagerNative.getDefault().stopService(
1074 mMainThread.getApplicationThread(), service,
1075 service.resolveTypeIfNeeded(getContentResolver()));
1076 if (res < 0) {
1077 throw new SecurityException(
1078 "Not allowed to stop service " + service);
1079 }
1080 return res != 0;
1081 } catch (RemoteException e) {
1082 return false;
1083 }
1084 }
1085
1086 @Override
1087 public boolean bindService(Intent service, ServiceConnection conn,
1088 int flags) {
1089 IServiceConnection sd;
1090 if (mPackageInfo != null) {
1091 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1092 mMainThread.getHandler(), flags);
1093 } else {
1094 throw new RuntimeException("Not supported in system context");
1095 }
1096 try {
1097 int res = ActivityManagerNative.getDefault().bindService(
1098 mMainThread.getApplicationThread(), getActivityToken(),
1099 service, service.resolveTypeIfNeeded(getContentResolver()),
1100 sd, flags);
1101 if (res < 0) {
1102 throw new SecurityException(
1103 "Not allowed to bind to service " + service);
1104 }
1105 return res != 0;
1106 } catch (RemoteException e) {
1107 return false;
1108 }
1109 }
1110
1111 @Override
1112 public void unbindService(ServiceConnection conn) {
1113 if (mPackageInfo != null) {
1114 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1115 getOuterContext(), conn);
1116 try {
1117 ActivityManagerNative.getDefault().unbindService(sd);
1118 } catch (RemoteException e) {
1119 }
1120 } else {
1121 throw new RuntimeException("Not supported in system context");
1122 }
1123 }
1124
1125 @Override
1126 public boolean startInstrumentation(ComponentName className,
1127 String profileFile, Bundle arguments) {
1128 try {
1129 return ActivityManagerNative.getDefault().startInstrumentation(
1130 className, profileFile, 0, arguments, null);
1131 } catch (RemoteException e) {
1132 // System has crashed, nothing we can do.
1133 }
1134 return false;
1135 }
1136
1137 @Override
1138 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001139 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1140 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 }
1142
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001143 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001144 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001145 }
1146
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001147 /* package */ static DropBoxManager createDropBoxManager() {
1148 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1149 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001150 if (service == null) {
1151 // Don't return a DropBoxManager that will NPE upon use.
1152 // This also avoids caching a broken DropBoxManager in
1153 // getDropBoxManager during early boot, before the
1154 // DROPBOX_SERVICE is registered.
1155 return null;
1156 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001157 return new DropBoxManager(service);
1158 }
1159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 @Override
1161 public int checkPermission(String permission, int pid, int uid) {
1162 if (permission == null) {
1163 throw new IllegalArgumentException("permission is null");
1164 }
1165
1166 if (!Process.supportsProcesses()) {
1167 return PackageManager.PERMISSION_GRANTED;
1168 }
1169 try {
1170 return ActivityManagerNative.getDefault().checkPermission(
1171 permission, pid, uid);
1172 } catch (RemoteException e) {
1173 return PackageManager.PERMISSION_DENIED;
1174 }
1175 }
1176
1177 @Override
1178 public int checkCallingPermission(String permission) {
1179 if (permission == null) {
1180 throw new IllegalArgumentException("permission is null");
1181 }
1182
1183 if (!Process.supportsProcesses()) {
1184 return PackageManager.PERMISSION_GRANTED;
1185 }
1186 int pid = Binder.getCallingPid();
1187 if (pid != Process.myPid()) {
1188 return checkPermission(permission, pid,
1189 Binder.getCallingUid());
1190 }
1191 return PackageManager.PERMISSION_DENIED;
1192 }
1193
1194 @Override
1195 public int checkCallingOrSelfPermission(String permission) {
1196 if (permission == null) {
1197 throw new IllegalArgumentException("permission is null");
1198 }
1199
1200 return checkPermission(permission, Binder.getCallingPid(),
1201 Binder.getCallingUid());
1202 }
1203
1204 private void enforce(
1205 String permission, int resultOfCheck,
1206 boolean selfToo, int uid, String message) {
1207 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1208 throw new SecurityException(
1209 (message != null ? (message + ": ") : "") +
1210 (selfToo
1211 ? "Neither user " + uid + " nor current process has "
1212 : "User " + uid + " does not have ") +
1213 permission +
1214 ".");
1215 }
1216 }
1217
1218 public void enforcePermission(
1219 String permission, int pid, int uid, String message) {
1220 enforce(permission,
1221 checkPermission(permission, pid, uid),
1222 false,
1223 uid,
1224 message);
1225 }
1226
1227 public void enforceCallingPermission(String permission, String message) {
1228 enforce(permission,
1229 checkCallingPermission(permission),
1230 false,
1231 Binder.getCallingUid(),
1232 message);
1233 }
1234
1235 public void enforceCallingOrSelfPermission(
1236 String permission, String message) {
1237 enforce(permission,
1238 checkCallingOrSelfPermission(permission),
1239 true,
1240 Binder.getCallingUid(),
1241 message);
1242 }
1243
1244 @Override
1245 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1246 try {
1247 ActivityManagerNative.getDefault().grantUriPermission(
1248 mMainThread.getApplicationThread(), toPackage, uri,
1249 modeFlags);
1250 } catch (RemoteException e) {
1251 }
1252 }
1253
1254 @Override
1255 public void revokeUriPermission(Uri uri, int modeFlags) {
1256 try {
1257 ActivityManagerNative.getDefault().revokeUriPermission(
1258 mMainThread.getApplicationThread(), uri,
1259 modeFlags);
1260 } catch (RemoteException e) {
1261 }
1262 }
1263
1264 @Override
1265 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1266 if (!Process.supportsProcesses()) {
1267 return PackageManager.PERMISSION_GRANTED;
1268 }
1269 try {
1270 return ActivityManagerNative.getDefault().checkUriPermission(
1271 uri, pid, uid, modeFlags);
1272 } catch (RemoteException e) {
1273 return PackageManager.PERMISSION_DENIED;
1274 }
1275 }
1276
1277 @Override
1278 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1279 if (!Process.supportsProcesses()) {
1280 return PackageManager.PERMISSION_GRANTED;
1281 }
1282 int pid = Binder.getCallingPid();
1283 if (pid != Process.myPid()) {
1284 return checkUriPermission(uri, pid,
1285 Binder.getCallingUid(), modeFlags);
1286 }
1287 return PackageManager.PERMISSION_DENIED;
1288 }
1289
1290 @Override
1291 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1292 return checkUriPermission(uri, Binder.getCallingPid(),
1293 Binder.getCallingUid(), modeFlags);
1294 }
1295
1296 @Override
1297 public int checkUriPermission(Uri uri, String readPermission,
1298 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001299 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1301 + readPermission + " writePermission=" + writePermission
1302 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1303 }
1304 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1305 if (readPermission == null
1306 || checkPermission(readPermission, pid, uid)
1307 == PackageManager.PERMISSION_GRANTED) {
1308 return PackageManager.PERMISSION_GRANTED;
1309 }
1310 }
1311 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1312 if (writePermission == null
1313 || checkPermission(writePermission, pid, uid)
1314 == PackageManager.PERMISSION_GRANTED) {
1315 return PackageManager.PERMISSION_GRANTED;
1316 }
1317 }
1318 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1319 : PackageManager.PERMISSION_DENIED;
1320 }
1321
1322 private String uriModeFlagToString(int uriModeFlags) {
1323 switch (uriModeFlags) {
1324 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1325 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1326 return "read and write";
1327 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1328 return "read";
1329 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1330 return "write";
1331 }
1332 throw new IllegalArgumentException(
1333 "Unknown permission mode flags: " + uriModeFlags);
1334 }
1335
1336 private void enforceForUri(
1337 int modeFlags, int resultOfCheck, boolean selfToo,
1338 int uid, Uri uri, String message) {
1339 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1340 throw new SecurityException(
1341 (message != null ? (message + ": ") : "") +
1342 (selfToo
1343 ? "Neither user " + uid + " nor current process has "
1344 : "User " + uid + " does not have ") +
1345 uriModeFlagToString(modeFlags) +
1346 " permission on " +
1347 uri +
1348 ".");
1349 }
1350 }
1351
1352 public void enforceUriPermission(
1353 Uri uri, int pid, int uid, int modeFlags, String message) {
1354 enforceForUri(
1355 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1356 false, uid, uri, message);
1357 }
1358
1359 public void enforceCallingUriPermission(
1360 Uri uri, int modeFlags, String message) {
1361 enforceForUri(
1362 modeFlags, checkCallingUriPermission(uri, modeFlags),
1363 false, Binder.getCallingUid(), uri, message);
1364 }
1365
1366 public void enforceCallingOrSelfUriPermission(
1367 Uri uri, int modeFlags, String message) {
1368 enforceForUri(
1369 modeFlags,
1370 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1371 Binder.getCallingUid(), uri, message);
1372 }
1373
1374 public void enforceUriPermission(
1375 Uri uri, String readPermission, String writePermission,
1376 int pid, int uid, int modeFlags, String message) {
1377 enforceForUri(modeFlags,
1378 checkUriPermission(
1379 uri, readPermission, writePermission, pid, uid,
1380 modeFlags),
1381 false,
1382 uid,
1383 uri,
1384 message);
1385 }
1386
1387 @Override
1388 public Context createPackageContext(String packageName, int flags)
1389 throws PackageManager.NameNotFoundException {
1390 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001391 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 }
1393
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001394 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001395 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001397 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001398 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001399 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001400 if (c.mResources != null) {
1401 return c;
1402 }
1403 }
1404
1405 // Should be a better exception.
1406 throw new PackageManager.NameNotFoundException(
1407 "Application package " + packageName + " not found");
1408 }
1409
Romain Guy870e09f2009-07-06 16:35:25 -07001410 @Override
1411 public boolean isRestricted() {
1412 return mRestricted;
1413 }
1414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001415 private File getDataDirFile() {
1416 if (mPackageInfo != null) {
1417 return mPackageInfo.getDataDirFile();
1418 }
1419 throw new RuntimeException("Not supported in system context");
1420 }
1421
1422 @Override
1423 public File getDir(String name, int mode) {
1424 name = "app_" + name;
1425 File file = makeFilename(getDataDirFile(), name);
1426 if (!file.exists()) {
1427 file.mkdir();
1428 setFilePermissionsFromMode(file.getPath(), mode,
1429 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1430 }
1431 return file;
1432 }
1433
Dianne Hackborn21556372010-02-04 16:34:40 -08001434 static ContextImpl createSystemContext(ActivityThread mainThread) {
1435 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 context.init(Resources.getSystem(), mainThread);
1437 return context;
1438 }
1439
Dianne Hackborn21556372010-02-04 16:34:40 -08001440 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 mOuterContext = this;
1442 }
1443
1444 /**
1445 * Create a new ApplicationContext from an existing one. The new one
1446 * works and operates the same as the one it is copying.
1447 *
1448 * @param context Existing application context.
1449 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001450 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001452 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 mResources = context.mResources;
1454 mMainThread = context.mMainThread;
1455 mContentResolver = context.mContentResolver;
1456 mOuterContext = this;
1457 }
1458
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001459 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001461 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001462 }
1463
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001464 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001465 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001466 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001468 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001470
Dianne Hackborn559a7872010-04-07 18:19:41 -07001471 if (mResources != null && container != null
1472 && container.getCompatibilityInfo().applicationScale !=
1473 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001474 if (DEBUG) {
1475 Log.d(TAG, "loaded context has different scaling. Using container's" +
1476 " compatiblity info:" + container.getDisplayMetrics());
1477 }
1478 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001479 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001480 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001481 mMainThread = mainThread;
1482 mContentResolver = new ApplicationContentResolver(this, mainThread);
1483
1484 setActivityToken(activityToken);
1485 }
1486
1487 final void init(Resources resources, ActivityThread mainThread) {
1488 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001489 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 mResources = resources;
1491 mMainThread = mainThread;
1492 mContentResolver = new ApplicationContentResolver(this, mainThread);
1493 }
1494
1495 final void scheduleFinalCleanup(String who, String what) {
1496 mMainThread.scheduleContextCleanup(this, who, what);
1497 }
1498
1499 final void performFinalCleanup(String who, String what) {
1500 //Log.i(TAG, "Cleanup up context: " + this);
1501 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1502 }
1503
1504 final Context getReceiverRestrictedContext() {
1505 if (mReceiverRestrictedContext != null) {
1506 return mReceiverRestrictedContext;
1507 }
1508 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1509 }
1510
1511 final void setActivityToken(IBinder token) {
1512 mActivityToken = token;
1513 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 final void setOuterContext(Context context) {
1516 mOuterContext = context;
1517 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 final Context getOuterContext() {
1520 return mOuterContext;
1521 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 final IBinder getActivityToken() {
1524 return mActivityToken;
1525 }
1526
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001527 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 int extraPermissions) {
1529 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1530 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1531 |extraPermissions;
1532 if ((mode&MODE_WORLD_READABLE) != 0) {
1533 perms |= FileUtils.S_IROTH;
1534 }
1535 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1536 perms |= FileUtils.S_IWOTH;
1537 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001538 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1540 + ", perms=0x" + Integer.toHexString(perms));
1541 }
1542 FileUtils.setPermissions(name, perms, -1, -1);
1543 }
1544
Oscar Montemayora8529f62009-11-18 10:14:20 -08001545 private File validateFilePath(String name, boolean createDirectory) {
1546 File dir;
1547 File f;
1548
1549 if (name.charAt(0) == File.separatorChar) {
1550 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1551 dir = new File(dirPath);
1552 name = name.substring(name.lastIndexOf(File.separatorChar));
1553 f = new File(dir, name);
1554 } else {
1555 dir = getDatabasesDir();
1556 f = makeFilename(dir, name);
1557 }
1558
1559 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1560 FileUtils.setPermissions(dir.getPath(),
1561 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1562 -1, -1);
1563 }
1564
1565 return f;
1566 }
1567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 private File makeFilename(File base, String name) {
1569 if (name.indexOf(File.separatorChar) < 0) {
1570 return new File(base, name);
1571 }
1572 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001573 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 }
1575
1576 // ----------------------------------------------------------------------
1577 // ----------------------------------------------------------------------
1578 // ----------------------------------------------------------------------
1579
1580 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001581 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 super(context);
1583 mMainThread = mainThread;
1584 }
1585
1586 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001587 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001588 return mMainThread.acquireProvider(context, name);
1589 }
1590
1591 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001592 protected IContentProvider acquireExistingProvider(Context context, String name) {
1593 return mMainThread.acquireExistingProvider(context, name);
1594 }
1595
1596 @Override
1597 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 return mMainThread.releaseProvider(provider);
1599 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001601 private final ActivityThread mMainThread;
1602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603}