blob: 6289730cb56e669c6ec0594397ed6e4ed9956ca7 [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;
satok988323c2011-06-22 16:38:13 +090086import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070087import android.accounts.AccountManager;
88import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080089import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080090import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import java.io.File;
93import java.io.FileInputStream;
94import java.io.FileNotFoundException;
95import java.io.FileOutputStream;
96import java.io.IOException;
97import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import java.util.ArrayList;
99import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101class ReceiverRestrictedContext extends ContextWrapper {
102 ReceiverRestrictedContext(Context base) {
103 super(base);
104 }
105
106 @Override
107 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
108 return registerReceiver(receiver, filter, null, null);
109 }
110
111 @Override
112 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
113 String broadcastPermission, Handler scheduler) {
114 throw new ReceiverCallNotAllowedException(
115 "IntentReceiver components are not allowed to register to receive intents");
116 //ex.fillInStackTrace();
117 //Log.e("IntentReceiver", ex.getMessage(), ex);
118 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
119 // scheduler);
120 }
121
122 @Override
123 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
124 throw new ReceiverCallNotAllowedException(
125 "IntentReceiver components are not allowed to bind to services");
126 //ex.fillInStackTrace();
127 //Log.e("IntentReceiver", ex.getMessage(), ex);
128 //return mContext.bindService(service, interfaceName, conn, flags);
129 }
130}
131
132/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800133 * Common implementation of Context API, which provides the base
134 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800136class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700138 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700140 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
141 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700143 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700144 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 private Resources mResources;
146 /*package*/ ActivityThread mMainThread;
147 private Context mOuterContext;
148 private IBinder mActivityToken = null;
149 private ApplicationContentResolver mContentResolver;
150 private int mThemeResource = 0;
151 private Resources.Theme mTheme = null;
152 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700154 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155
156 private final Object mSync = new Object();
157
158 private File mDatabasesDir;
159 private File mPreferencesDir;
160 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800162 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800163 private File mExternalFilesDir;
164 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 private static final String[] EMPTY_FILE_LIST = {};
167
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800168 /**
169 * Override this class when the system service constructor needs a
170 * ContextImpl. Else, use StaticServiceFetcher below.
171 */
172 /*package*/ static class ServiceFetcher {
173 int mContextCacheIndex = -1;
174
175 /**
176 * Main entrypoint; only override if you don't need caching.
177 */
178 public Object getService(ContextImpl ctx) {
179 ArrayList<Object> cache = ctx.mServiceCache;
180 Object service;
181 synchronized (cache) {
182 if (cache.size() == 0) {
183 // Initialize the cache vector on first access.
184 // At this point sNextPerContextServiceCacheIndex
185 // is the number of potential services that are
186 // cached per-Context.
187 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
188 cache.add(null);
189 }
190 } else {
191 service = cache.get(mContextCacheIndex);
192 if (service != null) {
193 return service;
194 }
195 }
196 service = createService(ctx);
197 cache.set(mContextCacheIndex, service);
198 return service;
199 }
200 }
201
202 /**
203 * Override this to create a new per-Context instance of the
204 * service. getService() will handle locking and caching.
205 */
206 public Object createService(ContextImpl ctx) {
207 throw new RuntimeException("Not implemented");
208 }
209 }
210
211 /**
212 * Override this class for services to be cached process-wide.
213 */
214 abstract static class StaticServiceFetcher extends ServiceFetcher {
215 private Object mCachedInstance;
216
217 @Override
218 public final Object getService(ContextImpl unused) {
219 synchronized (StaticServiceFetcher.this) {
220 Object service = mCachedInstance;
221 if (service != null) {
222 return service;
223 }
224 return mCachedInstance = createStaticService();
225 }
226 }
227
228 public abstract Object createStaticService();
229 }
230
231 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
232 new HashMap<String, ServiceFetcher>();
233
234 private static int sNextPerContextServiceCacheIndex = 0;
235 private static void registerService(String serviceName, ServiceFetcher fetcher) {
236 if (!(fetcher instanceof StaticServiceFetcher)) {
237 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
238 }
239 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
240 }
241
242 // This one's defined separately and given a variable name so it
243 // can be re-used by getWallpaperManager(), avoiding a HashMap
244 // lookup.
245 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
246 public Object createService(ContextImpl ctx) {
247 return new WallpaperManager(ctx.getOuterContext(),
248 ctx.mMainThread.getHandler());
249 }};
250
251 static {
252 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
253 public Object getService(ContextImpl ctx) {
254 return AccessibilityManager.getInstance(ctx);
255 }});
256
257 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
258 public Object createService(ContextImpl ctx) {
259 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
260 IAccountManager service = IAccountManager.Stub.asInterface(b);
261 return new AccountManager(ctx, service);
262 }});
263
264 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
265 public Object createService(ContextImpl ctx) {
266 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
267 }});
268
269 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
270 public Object createStaticService() {
271 IBinder b = ServiceManager.getService(ALARM_SERVICE);
272 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
273 return new AlarmManager(service);
274 }});
275
276 registerService(AUDIO_SERVICE, new ServiceFetcher() {
277 public Object createService(ContextImpl ctx) {
278 return new AudioManager(ctx);
279 }});
280
281 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
282 public Object createService(ContextImpl ctx) {
283 return new ClipboardManager(ctx.getOuterContext(),
284 ctx.mMainThread.getHandler());
285 }});
286
287 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
288 public Object createStaticService() {
289 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
290 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
291 }});
292
293 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
294 public Object createStaticService() {
295 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
296 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
297 }});
298
299 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
300 public Object createService(ContextImpl ctx) {
301 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
302 }});
303
304 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
305 public Object createService(ContextImpl ctx) {
306 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
307 }});
308
Nick Pellyd2507462010-12-13 12:22:34 -0800309 registerService(NFC_SERVICE, new ServiceFetcher() {
310 public Object createService(ContextImpl ctx) {
311 return new NfcManager(ctx);
312 }});
313
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800314 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
315 public Object createStaticService() {
316 return createDropBoxManager();
317 }});
318
319 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
320 public Object createService(ContextImpl ctx) {
321 return InputMethodManager.getInstance(ctx);
322 }});
323
satok988323c2011-06-22 16:38:13 +0900324 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
325 public Object createService(ContextImpl ctx) {
326 return TextServicesManager.getInstance();
327 }});
328
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800329 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
330 public Object getService(ContextImpl ctx) {
331 // TODO: why isn't this caching it? It wasn't
332 // before, so I'm preserving the old behavior and
333 // using getService(), instead of createService()
334 // which would do the caching.
335 return new KeyguardManager();
336 }});
337
338 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
339 public Object createService(ContextImpl ctx) {
340 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
341 }});
342
343 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
344 public Object createStaticService() {
345 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
346 return new LocationManager(ILocationManager.Stub.asInterface(b));
347 }});
348
Jeff Sharkey1a303952011-06-16 13:04:20 -0700349 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
350 @Override
351 public Object createService(ContextImpl ctx) {
352 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
353 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
354 }
355 });
356
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800357 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
358 public Object createService(ContextImpl ctx) {
359 final Context outerContext = ctx.getOuterContext();
360 return new NotificationManager(
361 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800362 Resources.selectSystemTheme(0,
363 outerContext.getApplicationInfo().targetSdkVersion,
364 com.android.internal.R.style.Theme_Dialog,
365 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800366 ctx.mMainThread.getHandler());
367 }});
368
369 // Note: this was previously cached in a static variable, but
370 // constructed using mMainThread.getHandler(), so converting
371 // it to be a regular Context-cached service...
372 registerService(POWER_SERVICE, new ServiceFetcher() {
373 public Object createService(ContextImpl ctx) {
374 IBinder b = ServiceManager.getService(POWER_SERVICE);
375 IPowerManager service = IPowerManager.Stub.asInterface(b);
376 return new PowerManager(service, ctx.mMainThread.getHandler());
377 }});
378
379 registerService(SEARCH_SERVICE, new ServiceFetcher() {
380 public Object createService(ContextImpl ctx) {
381 return new SearchManager(ctx.getOuterContext(),
382 ctx.mMainThread.getHandler());
383 }});
384
385 registerService(SENSOR_SERVICE, new ServiceFetcher() {
386 public Object createService(ContextImpl ctx) {
387 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
388 }});
389
390 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
391 public Object createService(ContextImpl ctx) {
392 return new StatusBarManager(ctx.getOuterContext());
393 }});
394
395 registerService(STORAGE_SERVICE, new ServiceFetcher() {
396 public Object createService(ContextImpl ctx) {
397 try {
398 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
399 } catch (RemoteException rex) {
400 Log.e(TAG, "Failed to create StorageManager", rex);
401 return null;
402 }
403 }});
404
405 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
406 public Object createService(ContextImpl ctx) {
407 return new TelephonyManager(ctx.getOuterContext());
408 }});
409
410 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
411 public Object createStaticService() {
412 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
413 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
414 }});
415
416 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
417 public Object createService(ContextImpl ctx) {
418 return new UiModeManager();
419 }});
420
Mike Lockwood3a68b832011-03-08 10:08:59 -0500421 registerService(USB_SERVICE, new ServiceFetcher() {
422 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500423 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500424 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500425 }});
426
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800427 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
428 public Object createService(ContextImpl ctx) {
429 return new Vibrator();
430 }});
431
432 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
433
434 registerService(WIFI_SERVICE, new ServiceFetcher() {
435 public Object createService(ContextImpl ctx) {
436 IBinder b = ServiceManager.getService(WIFI_SERVICE);
437 IWifiManager service = IWifiManager.Stub.asInterface(b);
438 return new WifiManager(service, ctx.mMainThread.getHandler());
439 }});
440
441 registerService(WINDOW_SERVICE, new ServiceFetcher() {
442 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700443 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800444 }});
445 }
446
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700447 static ContextImpl getImpl(Context context) {
448 Context nextContext;
449 while ((context instanceof ContextWrapper) &&
450 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
451 context = nextContext;
452 }
453 return (ContextImpl)context;
454 }
455
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800456 // The system service cache for the system services that are
457 // cached per-ContextImpl. Package-scoped to avoid accessor
458 // methods.
459 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800461 @Override
462 public AssetManager getAssets() {
463 return mResources.getAssets();
464 }
465
466 @Override
467 public Resources getResources() {
468 return mResources;
469 }
470
471 @Override
472 public PackageManager getPackageManager() {
473 if (mPackageManager != null) {
474 return mPackageManager;
475 }
476
477 IPackageManager pm = ActivityThread.getPackageManager();
478 if (pm != null) {
479 // Doesn't matter if we make more than one instance.
480 return (mPackageManager = new ApplicationPackageManager(this, pm));
481 }
482
483 return null;
484 }
485
486 @Override
487 public ContentResolver getContentResolver() {
488 return mContentResolver;
489 }
490
491 @Override
492 public Looper getMainLooper() {
493 return mMainThread.getLooper();
494 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 @Override
497 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700498 return (mPackageInfo != null) ?
499 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800500 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 @Override
503 public void setTheme(int resid) {
504 mThemeResource = resid;
505 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200506
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800508 public int getThemeResId() {
509 return mThemeResource;
510 }
511
512 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 public Resources.Theme getTheme() {
514 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800515 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
516 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 mTheme = mResources.newTheme();
518 mTheme.applyStyle(mThemeResource, true);
519 }
520 return mTheme;
521 }
522
523 @Override
524 public ClassLoader getClassLoader() {
525 return mPackageInfo != null ?
526 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
527 }
528
529 @Override
530 public String getPackageName() {
531 if (mPackageInfo != null) {
532 return mPackageInfo.getPackageName();
533 }
534 throw new RuntimeException("Not supported in system context");
535 }
536
537 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700538 public ApplicationInfo getApplicationInfo() {
539 if (mPackageInfo != null) {
540 return mPackageInfo.getApplicationInfo();
541 }
542 throw new RuntimeException("Not supported in system context");
543 }
544
545 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 public String getPackageResourcePath() {
547 if (mPackageInfo != null) {
548 return mPackageInfo.getResDir();
549 }
550 throw new RuntimeException("Not supported in system context");
551 }
552
553 @Override
554 public String getPackageCodePath() {
555 if (mPackageInfo != null) {
556 return mPackageInfo.getAppDir();
557 }
558 throw new RuntimeException("Not supported in system context");
559 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200560
Joe Onorato23ecae32009-06-10 17:07:15 -0700561 public File getSharedPrefsFile(String name) {
562 return makeFilename(getPreferencesDir(), name + ".xml");
563 }
564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 @Override
566 public SharedPreferences getSharedPreferences(String name, int mode) {
567 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700569 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700570 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800571 File prefsFile = getSharedPrefsFile(name);
572 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700573 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700574 return sp;
575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800576 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800577 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
578 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
579 // If somebody else (some other process) changed the prefs
580 // file behind our back, we reload it. This has been the
581 // historical (if undocumented) behavior.
582 sp.startReloadIfChangedUnexpectedly();
583 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700584 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586
587 private File getPreferencesDir() {
588 synchronized (mSync) {
589 if (mPreferencesDir == null) {
590 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
591 }
592 return mPreferencesDir;
593 }
594 }
595
596 @Override
597 public FileInputStream openFileInput(String name)
598 throws FileNotFoundException {
599 File f = makeFilename(getFilesDir(), name);
600 return new FileInputStream(f);
601 }
602
603 @Override
604 public FileOutputStream openFileOutput(String name, int mode)
605 throws FileNotFoundException {
606 final boolean append = (mode&MODE_APPEND) != 0;
607 File f = makeFilename(getFilesDir(), name);
608 try {
609 FileOutputStream fos = new FileOutputStream(f, append);
610 setFilePermissionsFromMode(f.getPath(), mode, 0);
611 return fos;
612 } catch (FileNotFoundException e) {
613 }
614
615 File parent = f.getParentFile();
616 parent.mkdir();
617 FileUtils.setPermissions(
618 parent.getPath(),
619 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
620 -1, -1);
621 FileOutputStream fos = new FileOutputStream(f, append);
622 setFilePermissionsFromMode(f.getPath(), mode, 0);
623 return fos;
624 }
625
626 @Override
627 public boolean deleteFile(String name) {
628 File f = makeFilename(getFilesDir(), name);
629 return f.delete();
630 }
631
632 @Override
633 public File getFilesDir() {
634 synchronized (mSync) {
635 if (mFilesDir == null) {
636 mFilesDir = new File(getDataDirFile(), "files");
637 }
638 if (!mFilesDir.exists()) {
639 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200640 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 return null;
642 }
643 FileUtils.setPermissions(
644 mFilesDir.getPath(),
645 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
646 -1, -1);
647 }
648 return mFilesDir;
649 }
650 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800653 public File getExternalFilesDir(String type) {
654 synchronized (mSync) {
655 if (mExternalFilesDir == null) {
656 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
657 getPackageName());
658 }
659 if (!mExternalFilesDir.exists()) {
660 try {
661 (new File(Environment.getExternalStorageAndroidDataDir(),
662 ".nomedia")).createNewFile();
663 } catch (IOException e) {
664 }
665 if (!mExternalFilesDir.mkdirs()) {
666 Log.w(TAG, "Unable to create external files directory");
667 return null;
668 }
669 }
670 if (type == null) {
671 return mExternalFilesDir;
672 }
673 File dir = new File(mExternalFilesDir, type);
674 if (!dir.exists()) {
675 if (!dir.mkdirs()) {
676 Log.w(TAG, "Unable to create external media directory " + dir);
677 return null;
678 }
679 }
680 return dir;
681 }
682 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200683
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800684 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800685 public File getObbDir() {
686 synchronized (mSync) {
687 if (mObbDir == null) {
688 mObbDir = Environment.getExternalStorageAppObbDirectory(
689 getPackageName());
690 }
691 return mObbDir;
692 }
693 }
694
695 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800696 public File getCacheDir() {
697 synchronized (mSync) {
698 if (mCacheDir == null) {
699 mCacheDir = new File(getDataDirFile(), "cache");
700 }
701 if (!mCacheDir.exists()) {
702 if(!mCacheDir.mkdirs()) {
703 Log.w(TAG, "Unable to create cache directory");
704 return null;
705 }
706 FileUtils.setPermissions(
707 mCacheDir.getPath(),
708 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
709 -1, -1);
710 }
711 }
712 return mCacheDir;
713 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200714
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800715 @Override
716 public File getExternalCacheDir() {
717 synchronized (mSync) {
718 if (mExternalCacheDir == null) {
719 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
720 getPackageName());
721 }
722 if (!mExternalCacheDir.exists()) {
723 try {
724 (new File(Environment.getExternalStorageAndroidDataDir(),
725 ".nomedia")).createNewFile();
726 } catch (IOException e) {
727 }
728 if (!mExternalCacheDir.mkdirs()) {
729 Log.w(TAG, "Unable to create external cache directory");
730 return null;
731 }
732 }
733 return mExternalCacheDir;
734 }
735 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 @Override
738 public File getFileStreamPath(String name) {
739 return makeFilename(getFilesDir(), name);
740 }
741
742 @Override
743 public String[] fileList() {
744 final String[] list = getFilesDir().list();
745 return (list != null) ? list : EMPTY_FILE_LIST;
746 }
747
748 @Override
749 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800750 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
752 setFilePermissionsFromMode(f.getPath(), mode, 0);
753 return db;
754 }
755
756 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700757 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
758 DatabaseErrorHandler errorHandler) {
759 File f = validateFilePath(name, true);
760 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
761 setFilePermissionsFromMode(f.getPath(), mode, 0);
762 return db;
763 }
764
765 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 public boolean deleteDatabase(String name) {
767 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800768 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800769 return f.delete();
770 } catch (Exception e) {
771 }
772 return false;
773 }
774
775 @Override
776 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800777 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 }
779
780 @Override
781 public String[] databaseList() {
782 final String[] list = getDatabasesDir().list();
783 return (list != null) ? list : EMPTY_FILE_LIST;
784 }
785
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 private File getDatabasesDir() {
788 synchronized (mSync) {
789 if (mDatabasesDir == null) {
790 mDatabasesDir = new File(getDataDirFile(), "databases");
791 }
792 if (mDatabasesDir.getPath().equals("databases")) {
793 mDatabasesDir = new File("/data/system");
794 }
795 return mDatabasesDir;
796 }
797 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200798
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 @Override
800 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700801 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 }
803
804 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700805 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700806 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 }
808
809 @Override
810 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700811 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 }
813
814 @Override
815 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700816 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 }
818
819 @Override
820 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700821 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 @Override
825 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700826 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828
829 @Override
830 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700831 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 }
833
834 @Override
835 public void startActivity(Intent intent) {
836 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
837 throw new AndroidRuntimeException(
838 "Calling startActivity() from outside of an Activity "
839 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
840 + " Is this really what you want?");
841 }
842 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700843 getOuterContext(), mMainThread.getApplicationThread(), null,
844 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 }
846
847 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800848 public void startActivities(Intent[] intents) {
849 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
850 throw new AndroidRuntimeException(
851 "Calling startActivities() from outside of an Activity "
852 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
853 + " Is this really what you want?");
854 }
855 mMainThread.getInstrumentation().execStartActivities(
856 getOuterContext(), mMainThread.getApplicationThread(), null,
857 (Activity)null, intents);
858 }
859
860 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700861 public void startIntentSender(IntentSender intent,
862 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
863 throws IntentSender.SendIntentException {
864 try {
865 String resolvedType = null;
866 if (fillInIntent != null) {
867 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
868 }
869 int result = ActivityManagerNative.getDefault()
870 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
871 fillInIntent, resolvedType, null, null,
872 0, flagsMask, flagsValues);
873 if (result == IActivityManager.START_CANCELED) {
874 throw new IntentSender.SendIntentException();
875 }
876 Instrumentation.checkStartActivityResult(result, null);
877 } catch (RemoteException e) {
878 }
879 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200880
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700881 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800882 public void sendBroadcast(Intent intent) {
883 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
884 try {
885 ActivityManagerNative.getDefault().broadcastIntent(
886 mMainThread.getApplicationThread(), intent, resolvedType, null,
887 Activity.RESULT_OK, null, null, null, false, false);
888 } catch (RemoteException e) {
889 }
890 }
891
892 @Override
893 public void sendBroadcast(Intent intent, String receiverPermission) {
894 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
895 try {
896 ActivityManagerNative.getDefault().broadcastIntent(
897 mMainThread.getApplicationThread(), intent, resolvedType, null,
898 Activity.RESULT_OK, null, null, receiverPermission, false, false);
899 } catch (RemoteException e) {
900 }
901 }
902
903 @Override
904 public void sendOrderedBroadcast(Intent intent,
905 String receiverPermission) {
906 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
907 try {
908 ActivityManagerNative.getDefault().broadcastIntent(
909 mMainThread.getApplicationThread(), intent, resolvedType, null,
910 Activity.RESULT_OK, null, null, receiverPermission, true, false);
911 } catch (RemoteException e) {
912 }
913 }
914
915 @Override
916 public void sendOrderedBroadcast(Intent intent,
917 String receiverPermission, BroadcastReceiver resultReceiver,
918 Handler scheduler, int initialCode, String initialData,
919 Bundle initialExtras) {
920 IIntentReceiver rd = null;
921 if (resultReceiver != null) {
922 if (mPackageInfo != null) {
923 if (scheduler == null) {
924 scheduler = mMainThread.getHandler();
925 }
926 rd = mPackageInfo.getReceiverDispatcher(
927 resultReceiver, getOuterContext(), scheduler,
928 mMainThread.getInstrumentation(), false);
929 } else {
930 if (scheduler == null) {
931 scheduler = mMainThread.getHandler();
932 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700933 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
935 }
936 }
937 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
938 try {
939 ActivityManagerNative.getDefault().broadcastIntent(
940 mMainThread.getApplicationThread(), intent, resolvedType, rd,
941 initialCode, initialData, initialExtras, receiverPermission,
942 true, false);
943 } catch (RemoteException e) {
944 }
945 }
946
947 @Override
948 public void sendStickyBroadcast(Intent intent) {
949 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
950 try {
951 ActivityManagerNative.getDefault().broadcastIntent(
952 mMainThread.getApplicationThread(), intent, resolvedType, null,
953 Activity.RESULT_OK, null, null, null, false, true);
954 } catch (RemoteException e) {
955 }
956 }
957
958 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700959 public void sendStickyOrderedBroadcast(Intent intent,
960 BroadcastReceiver resultReceiver,
961 Handler scheduler, int initialCode, String initialData,
962 Bundle initialExtras) {
963 IIntentReceiver rd = null;
964 if (resultReceiver != null) {
965 if (mPackageInfo != null) {
966 if (scheduler == null) {
967 scheduler = mMainThread.getHandler();
968 }
969 rd = mPackageInfo.getReceiverDispatcher(
970 resultReceiver, getOuterContext(), scheduler,
971 mMainThread.getInstrumentation(), false);
972 } else {
973 if (scheduler == null) {
974 scheduler = mMainThread.getHandler();
975 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700976 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700977 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
978 }
979 }
980 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
981 try {
982 ActivityManagerNative.getDefault().broadcastIntent(
983 mMainThread.getApplicationThread(), intent, resolvedType, rd,
984 initialCode, initialData, initialExtras, null,
985 true, true);
986 } catch (RemoteException e) {
987 }
988 }
989
990 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 public void removeStickyBroadcast(Intent intent) {
992 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
993 if (resolvedType != null) {
994 intent = new Intent(intent);
995 intent.setDataAndType(intent.getData(), resolvedType);
996 }
997 try {
998 ActivityManagerNative.getDefault().unbroadcastIntent(
999 mMainThread.getApplicationThread(), intent);
1000 } catch (RemoteException e) {
1001 }
1002 }
1003
1004 @Override
1005 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1006 return registerReceiver(receiver, filter, null, null);
1007 }
1008
1009 @Override
1010 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1011 String broadcastPermission, Handler scheduler) {
1012 return registerReceiverInternal(receiver, filter, broadcastPermission,
1013 scheduler, getOuterContext());
1014 }
1015
1016 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1017 IntentFilter filter, String broadcastPermission,
1018 Handler scheduler, Context context) {
1019 IIntentReceiver rd = null;
1020 if (receiver != null) {
1021 if (mPackageInfo != null && context != null) {
1022 if (scheduler == null) {
1023 scheduler = mMainThread.getHandler();
1024 }
1025 rd = mPackageInfo.getReceiverDispatcher(
1026 receiver, context, scheduler,
1027 mMainThread.getInstrumentation(), true);
1028 } else {
1029 if (scheduler == null) {
1030 scheduler = mMainThread.getHandler();
1031 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001032 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001033 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034 }
1035 }
1036 try {
1037 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001038 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001039 rd, filter, broadcastPermission);
1040 } catch (RemoteException e) {
1041 return null;
1042 }
1043 }
1044
1045 @Override
1046 public void unregisterReceiver(BroadcastReceiver receiver) {
1047 if (mPackageInfo != null) {
1048 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1049 getOuterContext(), receiver);
1050 try {
1051 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1052 } catch (RemoteException e) {
1053 }
1054 } else {
1055 throw new RuntimeException("Not supported in system context");
1056 }
1057 }
1058
1059 @Override
1060 public ComponentName startService(Intent service) {
1061 try {
1062 ComponentName cn = ActivityManagerNative.getDefault().startService(
1063 mMainThread.getApplicationThread(), service,
1064 service.resolveTypeIfNeeded(getContentResolver()));
1065 if (cn != null && cn.getPackageName().equals("!")) {
1066 throw new SecurityException(
1067 "Not allowed to start service " + service
1068 + " without permission " + cn.getClassName());
1069 }
1070 return cn;
1071 } catch (RemoteException e) {
1072 return null;
1073 }
1074 }
1075
1076 @Override
1077 public boolean stopService(Intent service) {
1078 try {
1079 int res = ActivityManagerNative.getDefault().stopService(
1080 mMainThread.getApplicationThread(), service,
1081 service.resolveTypeIfNeeded(getContentResolver()));
1082 if (res < 0) {
1083 throw new SecurityException(
1084 "Not allowed to stop service " + service);
1085 }
1086 return res != 0;
1087 } catch (RemoteException e) {
1088 return false;
1089 }
1090 }
1091
1092 @Override
1093 public boolean bindService(Intent service, ServiceConnection conn,
1094 int flags) {
1095 IServiceConnection sd;
1096 if (mPackageInfo != null) {
1097 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1098 mMainThread.getHandler(), flags);
1099 } else {
1100 throw new RuntimeException("Not supported in system context");
1101 }
1102 try {
1103 int res = ActivityManagerNative.getDefault().bindService(
1104 mMainThread.getApplicationThread(), getActivityToken(),
1105 service, service.resolveTypeIfNeeded(getContentResolver()),
1106 sd, flags);
1107 if (res < 0) {
1108 throw new SecurityException(
1109 "Not allowed to bind to service " + service);
1110 }
1111 return res != 0;
1112 } catch (RemoteException e) {
1113 return false;
1114 }
1115 }
1116
1117 @Override
1118 public void unbindService(ServiceConnection conn) {
1119 if (mPackageInfo != null) {
1120 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1121 getOuterContext(), conn);
1122 try {
1123 ActivityManagerNative.getDefault().unbindService(sd);
1124 } catch (RemoteException e) {
1125 }
1126 } else {
1127 throw new RuntimeException("Not supported in system context");
1128 }
1129 }
1130
1131 @Override
1132 public boolean startInstrumentation(ComponentName className,
1133 String profileFile, Bundle arguments) {
1134 try {
1135 return ActivityManagerNative.getDefault().startInstrumentation(
1136 className, profileFile, 0, arguments, null);
1137 } catch (RemoteException e) {
1138 // System has crashed, nothing we can do.
1139 }
1140 return false;
1141 }
1142
1143 @Override
1144 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001145 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1146 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001147 }
1148
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001149 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001150 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 }
1152
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001153 /* package */ static DropBoxManager createDropBoxManager() {
1154 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1155 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001156 if (service == null) {
1157 // Don't return a DropBoxManager that will NPE upon use.
1158 // This also avoids caching a broken DropBoxManager in
1159 // getDropBoxManager during early boot, before the
1160 // DROPBOX_SERVICE is registered.
1161 return null;
1162 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001163 return new DropBoxManager(service);
1164 }
1165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001166 @Override
1167 public int checkPermission(String permission, int pid, int uid) {
1168 if (permission == null) {
1169 throw new IllegalArgumentException("permission is null");
1170 }
1171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001172 try {
1173 return ActivityManagerNative.getDefault().checkPermission(
1174 permission, pid, uid);
1175 } catch (RemoteException e) {
1176 return PackageManager.PERMISSION_DENIED;
1177 }
1178 }
1179
1180 @Override
1181 public int checkCallingPermission(String permission) {
1182 if (permission == null) {
1183 throw new IllegalArgumentException("permission is null");
1184 }
1185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 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) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 try {
1267 return ActivityManagerNative.getDefault().checkUriPermission(
1268 uri, pid, uid, modeFlags);
1269 } catch (RemoteException e) {
1270 return PackageManager.PERMISSION_DENIED;
1271 }
1272 }
1273
1274 @Override
1275 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 int pid = Binder.getCallingPid();
1277 if (pid != Process.myPid()) {
1278 return checkUriPermission(uri, pid,
1279 Binder.getCallingUid(), modeFlags);
1280 }
1281 return PackageManager.PERMISSION_DENIED;
1282 }
1283
1284 @Override
1285 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1286 return checkUriPermission(uri, Binder.getCallingPid(),
1287 Binder.getCallingUid(), modeFlags);
1288 }
1289
1290 @Override
1291 public int checkUriPermission(Uri uri, String readPermission,
1292 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001293 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1295 + readPermission + " writePermission=" + writePermission
1296 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1297 }
1298 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1299 if (readPermission == null
1300 || checkPermission(readPermission, pid, uid)
1301 == PackageManager.PERMISSION_GRANTED) {
1302 return PackageManager.PERMISSION_GRANTED;
1303 }
1304 }
1305 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1306 if (writePermission == null
1307 || checkPermission(writePermission, pid, uid)
1308 == PackageManager.PERMISSION_GRANTED) {
1309 return PackageManager.PERMISSION_GRANTED;
1310 }
1311 }
1312 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1313 : PackageManager.PERMISSION_DENIED;
1314 }
1315
1316 private String uriModeFlagToString(int uriModeFlags) {
1317 switch (uriModeFlags) {
1318 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1319 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1320 return "read and write";
1321 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1322 return "read";
1323 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1324 return "write";
1325 }
1326 throw new IllegalArgumentException(
1327 "Unknown permission mode flags: " + uriModeFlags);
1328 }
1329
1330 private void enforceForUri(
1331 int modeFlags, int resultOfCheck, boolean selfToo,
1332 int uid, Uri uri, String message) {
1333 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1334 throw new SecurityException(
1335 (message != null ? (message + ": ") : "") +
1336 (selfToo
1337 ? "Neither user " + uid + " nor current process has "
1338 : "User " + uid + " does not have ") +
1339 uriModeFlagToString(modeFlags) +
1340 " permission on " +
1341 uri +
1342 ".");
1343 }
1344 }
1345
1346 public void enforceUriPermission(
1347 Uri uri, int pid, int uid, int modeFlags, String message) {
1348 enforceForUri(
1349 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1350 false, uid, uri, message);
1351 }
1352
1353 public void enforceCallingUriPermission(
1354 Uri uri, int modeFlags, String message) {
1355 enforceForUri(
1356 modeFlags, checkCallingUriPermission(uri, modeFlags),
1357 false, Binder.getCallingUid(), uri, message);
1358 }
1359
1360 public void enforceCallingOrSelfUriPermission(
1361 Uri uri, int modeFlags, String message) {
1362 enforceForUri(
1363 modeFlags,
1364 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1365 Binder.getCallingUid(), uri, message);
1366 }
1367
1368 public void enforceUriPermission(
1369 Uri uri, String readPermission, String writePermission,
1370 int pid, int uid, int modeFlags, String message) {
1371 enforceForUri(modeFlags,
1372 checkUriPermission(
1373 uri, readPermission, writePermission, pid, uid,
1374 modeFlags),
1375 false,
1376 uid,
1377 uri,
1378 message);
1379 }
1380
1381 @Override
1382 public Context createPackageContext(String packageName, int flags)
1383 throws PackageManager.NameNotFoundException {
1384 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001385 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001388 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001389 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001391 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001392 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001393 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394 if (c.mResources != null) {
1395 return c;
1396 }
1397 }
1398
1399 // Should be a better exception.
1400 throw new PackageManager.NameNotFoundException(
1401 "Application package " + packageName + " not found");
1402 }
1403
Romain Guy870e09f2009-07-06 16:35:25 -07001404 @Override
1405 public boolean isRestricted() {
1406 return mRestricted;
1407 }
1408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 private File getDataDirFile() {
1410 if (mPackageInfo != null) {
1411 return mPackageInfo.getDataDirFile();
1412 }
1413 throw new RuntimeException("Not supported in system context");
1414 }
1415
1416 @Override
1417 public File getDir(String name, int mode) {
1418 name = "app_" + name;
1419 File file = makeFilename(getDataDirFile(), name);
1420 if (!file.exists()) {
1421 file.mkdir();
1422 setFilePermissionsFromMode(file.getPath(), mode,
1423 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1424 }
1425 return file;
1426 }
1427
Dianne Hackborn21556372010-02-04 16:34:40 -08001428 static ContextImpl createSystemContext(ActivityThread mainThread) {
1429 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 context.init(Resources.getSystem(), mainThread);
1431 return context;
1432 }
1433
Dianne Hackborn21556372010-02-04 16:34:40 -08001434 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 mOuterContext = this;
1436 }
1437
1438 /**
1439 * Create a new ApplicationContext from an existing one. The new one
1440 * works and operates the same as the one it is copying.
1441 *
1442 * @param context Existing application context.
1443 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001444 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001446 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 mResources = context.mResources;
1448 mMainThread = context.mMainThread;
1449 mContentResolver = context.mContentResolver;
1450 mOuterContext = this;
1451 }
1452
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001453 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001455 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001456 }
1457
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001458 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001459 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001460 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001462 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001464
Dianne Hackborn559a7872010-04-07 18:19:41 -07001465 if (mResources != null && container != null
1466 && container.getCompatibilityInfo().applicationScale !=
1467 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001468 if (DEBUG) {
1469 Log.d(TAG, "loaded context has different scaling. Using container's" +
1470 " compatiblity info:" + container.getDisplayMetrics());
1471 }
1472 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001473 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 mMainThread = mainThread;
1476 mContentResolver = new ApplicationContentResolver(this, mainThread);
1477
1478 setActivityToken(activityToken);
1479 }
1480
1481 final void init(Resources resources, ActivityThread mainThread) {
1482 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001483 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 mResources = resources;
1485 mMainThread = mainThread;
1486 mContentResolver = new ApplicationContentResolver(this, mainThread);
1487 }
1488
1489 final void scheduleFinalCleanup(String who, String what) {
1490 mMainThread.scheduleContextCleanup(this, who, what);
1491 }
1492
1493 final void performFinalCleanup(String who, String what) {
1494 //Log.i(TAG, "Cleanup up context: " + this);
1495 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1496 }
1497
1498 final Context getReceiverRestrictedContext() {
1499 if (mReceiverRestrictedContext != null) {
1500 return mReceiverRestrictedContext;
1501 }
1502 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1503 }
1504
1505 final void setActivityToken(IBinder token) {
1506 mActivityToken = token;
1507 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 final void setOuterContext(Context context) {
1510 mOuterContext = context;
1511 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 final Context getOuterContext() {
1514 return mOuterContext;
1515 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001516
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001517 final IBinder getActivityToken() {
1518 return mActivityToken;
1519 }
1520
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001521 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 int extraPermissions) {
1523 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1524 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1525 |extraPermissions;
1526 if ((mode&MODE_WORLD_READABLE) != 0) {
1527 perms |= FileUtils.S_IROTH;
1528 }
1529 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1530 perms |= FileUtils.S_IWOTH;
1531 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001532 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1534 + ", perms=0x" + Integer.toHexString(perms));
1535 }
1536 FileUtils.setPermissions(name, perms, -1, -1);
1537 }
1538
Oscar Montemayora8529f62009-11-18 10:14:20 -08001539 private File validateFilePath(String name, boolean createDirectory) {
1540 File dir;
1541 File f;
1542
1543 if (name.charAt(0) == File.separatorChar) {
1544 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1545 dir = new File(dirPath);
1546 name = name.substring(name.lastIndexOf(File.separatorChar));
1547 f = new File(dir, name);
1548 } else {
1549 dir = getDatabasesDir();
1550 f = makeFilename(dir, name);
1551 }
1552
1553 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1554 FileUtils.setPermissions(dir.getPath(),
1555 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1556 -1, -1);
1557 }
1558
1559 return f;
1560 }
1561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 private File makeFilename(File base, String name) {
1563 if (name.indexOf(File.separatorChar) < 0) {
1564 return new File(base, name);
1565 }
1566 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001567 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 }
1569
1570 // ----------------------------------------------------------------------
1571 // ----------------------------------------------------------------------
1572 // ----------------------------------------------------------------------
1573
1574 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001575 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 super(context);
1577 mMainThread = mainThread;
1578 }
1579
1580 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001581 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 return mMainThread.acquireProvider(context, name);
1583 }
1584
1585 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001586 protected IContentProvider acquireExistingProvider(Context context, String name) {
1587 return mMainThread.acquireExistingProvider(context, name);
1588 }
1589
1590 @Override
1591 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 return mMainThread.releaseProvider(provider);
1593 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 private final ActivityThread mMainThread;
1596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597}