blob: a99cec28bdf60669d07c574278e8abce6040f042 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.content.BroadcastReceiver;
22import android.content.ComponentName;
23import android.content.ContentResolver;
24import android.content.Context;
25import android.content.ContextWrapper;
26import android.content.IContentProvider;
27import android.content.Intent;
28import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070029import android.content.IIntentReceiver;
30import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.content.ReceiverCallNotAllowedException;
32import android.content.ServiceConnection;
33import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.content.pm.PackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.res.AssetManager;
Dianne Hackborn5be8de32011-05-24 18:11:57 -070038import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070040import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.database.sqlite.SQLiteDatabase;
42import android.database.sqlite.SQLiteDatabase.CursorFactory;
43import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.graphics.drawable.Drawable;
45import android.hardware.SensorManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080046import android.hardware.usb.IUsbManager;
47import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080048import android.location.CountryDetector;
49import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.location.ILocationManager;
51import android.location.LocationManager;
52import android.media.AudioManager;
53import android.net.ConnectivityManager;
54import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070055import android.net.INetworkPolicyManager;
56import android.net.NetworkPolicyManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070057import android.net.ThrottleManager;
58import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080059import android.net.Uri;
60import android.net.wifi.IWifiManager;
61import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070062import android.net.wifi.p2p.IWifiP2pManager;
63import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080064import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.os.Binder;
66import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080067import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080068import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.os.FileUtils;
70import android.os.Handler;
71import android.os.IBinder;
72import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070073import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.os.PowerManager;
75import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070076import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.ServiceManager;
78import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080079import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070081import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.util.AndroidRuntimeException;
83import android.util.Log;
84import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090088import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070089import android.accounts.AccountManager;
90import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080091import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080092import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094import java.io.File;
95import java.io.FileInputStream;
96import java.io.FileNotFoundException;
97import java.io.FileOutputStream;
98import java.io.IOException;
99import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import java.util.ArrayList;
101import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103class ReceiverRestrictedContext extends ContextWrapper {
104 ReceiverRestrictedContext(Context base) {
105 super(base);
106 }
107
108 @Override
109 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
110 return registerReceiver(receiver, filter, null, null);
111 }
112
113 @Override
114 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
115 String broadcastPermission, Handler scheduler) {
116 throw new ReceiverCallNotAllowedException(
117 "IntentReceiver components are not allowed to register to receive intents");
118 //ex.fillInStackTrace();
119 //Log.e("IntentReceiver", ex.getMessage(), ex);
120 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
121 // scheduler);
122 }
123
124 @Override
125 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
126 throw new ReceiverCallNotAllowedException(
127 "IntentReceiver components are not allowed to bind to services");
128 //ex.fillInStackTrace();
129 //Log.e("IntentReceiver", ex.getMessage(), ex);
130 //return mContext.bindService(service, interfaceName, conn, flags);
131 }
132}
133
134/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800135 * Common implementation of Context API, which provides the base
136 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800138class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700140 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700142 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
143 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700145 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700146 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private Resources mResources;
148 /*package*/ ActivityThread mMainThread;
149 private Context mOuterContext;
150 private IBinder mActivityToken = null;
151 private ApplicationContentResolver mContentResolver;
152 private int mThemeResource = 0;
153 private Resources.Theme mTheme = null;
154 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700156 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157
158 private final Object mSync = new Object();
159
160 private File mDatabasesDir;
161 private File mPreferencesDir;
162 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800164 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800165 private File mExternalFilesDir;
166 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 private static final String[] EMPTY_FILE_LIST = {};
169
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800170 /**
171 * Override this class when the system service constructor needs a
172 * ContextImpl. Else, use StaticServiceFetcher below.
173 */
174 /*package*/ static class ServiceFetcher {
175 int mContextCacheIndex = -1;
176
177 /**
178 * Main entrypoint; only override if you don't need caching.
179 */
180 public Object getService(ContextImpl ctx) {
181 ArrayList<Object> cache = ctx.mServiceCache;
182 Object service;
183 synchronized (cache) {
184 if (cache.size() == 0) {
185 // Initialize the cache vector on first access.
186 // At this point sNextPerContextServiceCacheIndex
187 // is the number of potential services that are
188 // cached per-Context.
189 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
190 cache.add(null);
191 }
192 } else {
193 service = cache.get(mContextCacheIndex);
194 if (service != null) {
195 return service;
196 }
197 }
198 service = createService(ctx);
199 cache.set(mContextCacheIndex, service);
200 return service;
201 }
202 }
203
204 /**
205 * Override this to create a new per-Context instance of the
206 * service. getService() will handle locking and caching.
207 */
208 public Object createService(ContextImpl ctx) {
209 throw new RuntimeException("Not implemented");
210 }
211 }
212
213 /**
214 * Override this class for services to be cached process-wide.
215 */
216 abstract static class StaticServiceFetcher extends ServiceFetcher {
217 private Object mCachedInstance;
218
219 @Override
220 public final Object getService(ContextImpl unused) {
221 synchronized (StaticServiceFetcher.this) {
222 Object service = mCachedInstance;
223 if (service != null) {
224 return service;
225 }
226 return mCachedInstance = createStaticService();
227 }
228 }
229
230 public abstract Object createStaticService();
231 }
232
233 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
234 new HashMap<String, ServiceFetcher>();
235
236 private static int sNextPerContextServiceCacheIndex = 0;
237 private static void registerService(String serviceName, ServiceFetcher fetcher) {
238 if (!(fetcher instanceof StaticServiceFetcher)) {
239 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
240 }
241 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
242 }
243
244 // This one's defined separately and given a variable name so it
245 // can be re-used by getWallpaperManager(), avoiding a HashMap
246 // lookup.
247 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
248 public Object createService(ContextImpl ctx) {
249 return new WallpaperManager(ctx.getOuterContext(),
250 ctx.mMainThread.getHandler());
251 }};
252
253 static {
254 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
255 public Object getService(ContextImpl ctx) {
256 return AccessibilityManager.getInstance(ctx);
257 }});
258
259 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
260 public Object createService(ContextImpl ctx) {
261 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
262 IAccountManager service = IAccountManager.Stub.asInterface(b);
263 return new AccountManager(ctx, service);
264 }});
265
266 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
267 public Object createService(ContextImpl ctx) {
268 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
269 }});
270
271 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
272 public Object createStaticService() {
273 IBinder b = ServiceManager.getService(ALARM_SERVICE);
274 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
275 return new AlarmManager(service);
276 }});
277
278 registerService(AUDIO_SERVICE, new ServiceFetcher() {
279 public Object createService(ContextImpl ctx) {
280 return new AudioManager(ctx);
281 }});
282
283 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
284 public Object createService(ContextImpl ctx) {
285 return new ClipboardManager(ctx.getOuterContext(),
286 ctx.mMainThread.getHandler());
287 }});
288
289 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
290 public Object createStaticService() {
291 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
292 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
293 }});
294
295 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
296 public Object createStaticService() {
297 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
298 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
299 }});
300
301 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
302 public Object createService(ContextImpl ctx) {
303 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
304 }});
305
306 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
307 public Object createService(ContextImpl ctx) {
308 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
309 }});
310
Nick Pellyd2507462010-12-13 12:22:34 -0800311 registerService(NFC_SERVICE, new ServiceFetcher() {
312 public Object createService(ContextImpl ctx) {
313 return new NfcManager(ctx);
314 }});
315
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800316 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
317 public Object createStaticService() {
318 return createDropBoxManager();
319 }});
320
321 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
322 public Object createService(ContextImpl ctx) {
323 return InputMethodManager.getInstance(ctx);
324 }});
325
satok988323c2011-06-22 16:38:13 +0900326 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
327 public Object createService(ContextImpl ctx) {
328 return TextServicesManager.getInstance();
329 }});
330
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800331 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
332 public Object getService(ContextImpl ctx) {
333 // TODO: why isn't this caching it? It wasn't
334 // before, so I'm preserving the old behavior and
335 // using getService(), instead of createService()
336 // which would do the caching.
337 return new KeyguardManager();
338 }});
339
340 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
341 public Object createService(ContextImpl ctx) {
342 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
343 }});
344
345 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
346 public Object createStaticService() {
347 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
348 return new LocationManager(ILocationManager.Stub.asInterface(b));
349 }});
350
Jeff Sharkey1a303952011-06-16 13:04:20 -0700351 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
352 @Override
353 public Object createService(ContextImpl ctx) {
354 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
355 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
356 }
357 });
358
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800359 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
360 public Object createService(ContextImpl ctx) {
361 final Context outerContext = ctx.getOuterContext();
362 return new NotificationManager(
363 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800364 Resources.selectSystemTheme(0,
365 outerContext.getApplicationInfo().targetSdkVersion,
366 com.android.internal.R.style.Theme_Dialog,
367 com.android.internal.R.style.Theme_Holo_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800368 ctx.mMainThread.getHandler());
369 }});
370
371 // Note: this was previously cached in a static variable, but
372 // constructed using mMainThread.getHandler(), so converting
373 // it to be a regular Context-cached service...
374 registerService(POWER_SERVICE, new ServiceFetcher() {
375 public Object createService(ContextImpl ctx) {
376 IBinder b = ServiceManager.getService(POWER_SERVICE);
377 IPowerManager service = IPowerManager.Stub.asInterface(b);
378 return new PowerManager(service, ctx.mMainThread.getHandler());
379 }});
380
381 registerService(SEARCH_SERVICE, new ServiceFetcher() {
382 public Object createService(ContextImpl ctx) {
383 return new SearchManager(ctx.getOuterContext(),
384 ctx.mMainThread.getHandler());
385 }});
386
387 registerService(SENSOR_SERVICE, new ServiceFetcher() {
388 public Object createService(ContextImpl ctx) {
389 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
390 }});
391
392 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
393 public Object createService(ContextImpl ctx) {
394 return new StatusBarManager(ctx.getOuterContext());
395 }});
396
397 registerService(STORAGE_SERVICE, new ServiceFetcher() {
398 public Object createService(ContextImpl ctx) {
399 try {
400 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
401 } catch (RemoteException rex) {
402 Log.e(TAG, "Failed to create StorageManager", rex);
403 return null;
404 }
405 }});
406
407 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
408 public Object createService(ContextImpl ctx) {
409 return new TelephonyManager(ctx.getOuterContext());
410 }});
411
412 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
413 public Object createStaticService() {
414 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
415 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
416 }});
417
418 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
419 public Object createService(ContextImpl ctx) {
420 return new UiModeManager();
421 }});
422
Mike Lockwood3a68b832011-03-08 10:08:59 -0500423 registerService(USB_SERVICE, new ServiceFetcher() {
424 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500425 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500426 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500427 }});
428
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800429 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
430 public Object createService(ContextImpl ctx) {
431 return new Vibrator();
432 }});
433
434 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
435
436 registerService(WIFI_SERVICE, new ServiceFetcher() {
437 public Object createService(ContextImpl ctx) {
438 IBinder b = ServiceManager.getService(WIFI_SERVICE);
439 IWifiManager service = IWifiManager.Stub.asInterface(b);
440 return new WifiManager(service, ctx.mMainThread.getHandler());
441 }});
442
repo sync55bc5f32011-06-24 14:23:07 -0700443 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
444 public Object createService(ContextImpl ctx) {
445 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
446 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
447 return new WifiP2pManager(service);
448 }});
449
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800450 registerService(WINDOW_SERVICE, new ServiceFetcher() {
451 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700452 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800453 }});
454 }
455
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700456 static ContextImpl getImpl(Context context) {
457 Context nextContext;
458 while ((context instanceof ContextWrapper) &&
459 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
460 context = nextContext;
461 }
462 return (ContextImpl)context;
463 }
464
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800465 // The system service cache for the system services that are
466 // cached per-ContextImpl. Package-scoped to avoid accessor
467 // methods.
468 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
469
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800470 @Override
471 public AssetManager getAssets() {
472 return mResources.getAssets();
473 }
474
475 @Override
476 public Resources getResources() {
477 return mResources;
478 }
479
480 @Override
481 public PackageManager getPackageManager() {
482 if (mPackageManager != null) {
483 return mPackageManager;
484 }
485
486 IPackageManager pm = ActivityThread.getPackageManager();
487 if (pm != null) {
488 // Doesn't matter if we make more than one instance.
489 return (mPackageManager = new ApplicationPackageManager(this, pm));
490 }
491
492 return null;
493 }
494
495 @Override
496 public ContentResolver getContentResolver() {
497 return mContentResolver;
498 }
499
500 @Override
501 public Looper getMainLooper() {
502 return mMainThread.getLooper();
503 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 @Override
506 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700507 return (mPackageInfo != null) ?
508 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200510
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 @Override
512 public void setTheme(int resid) {
513 mThemeResource = resid;
514 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800517 public int getThemeResId() {
518 return mThemeResource;
519 }
520
521 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 public Resources.Theme getTheme() {
523 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800524 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
525 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 mTheme = mResources.newTheme();
527 mTheme.applyStyle(mThemeResource, true);
528 }
529 return mTheme;
530 }
531
532 @Override
533 public ClassLoader getClassLoader() {
534 return mPackageInfo != null ?
535 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
536 }
537
538 @Override
539 public String getPackageName() {
540 if (mPackageInfo != null) {
541 return mPackageInfo.getPackageName();
542 }
543 throw new RuntimeException("Not supported in system context");
544 }
545
546 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700547 public ApplicationInfo getApplicationInfo() {
548 if (mPackageInfo != null) {
549 return mPackageInfo.getApplicationInfo();
550 }
551 throw new RuntimeException("Not supported in system context");
552 }
553
554 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555 public String getPackageResourcePath() {
556 if (mPackageInfo != null) {
557 return mPackageInfo.getResDir();
558 }
559 throw new RuntimeException("Not supported in system context");
560 }
561
562 @Override
563 public String getPackageCodePath() {
564 if (mPackageInfo != null) {
565 return mPackageInfo.getAppDir();
566 }
567 throw new RuntimeException("Not supported in system context");
568 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200569
Joe Onorato23ecae32009-06-10 17:07:15 -0700570 public File getSharedPrefsFile(String name) {
571 return makeFilename(getPreferencesDir(), name + ".xml");
572 }
573
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800574 @Override
575 public SharedPreferences getSharedPreferences(String name, int mode) {
576 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700578 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700579 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800580 File prefsFile = getSharedPrefsFile(name);
581 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700582 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700583 return sp;
584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800586 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
587 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
588 // If somebody else (some other process) changed the prefs
589 // file behind our back, we reload it. This has been the
590 // historical (if undocumented) behavior.
591 sp.startReloadIfChangedUnexpectedly();
592 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700593 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
596 private File getPreferencesDir() {
597 synchronized (mSync) {
598 if (mPreferencesDir == null) {
599 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
600 }
601 return mPreferencesDir;
602 }
603 }
604
605 @Override
606 public FileInputStream openFileInput(String name)
607 throws FileNotFoundException {
608 File f = makeFilename(getFilesDir(), name);
609 return new FileInputStream(f);
610 }
611
612 @Override
613 public FileOutputStream openFileOutput(String name, int mode)
614 throws FileNotFoundException {
615 final boolean append = (mode&MODE_APPEND) != 0;
616 File f = makeFilename(getFilesDir(), name);
617 try {
618 FileOutputStream fos = new FileOutputStream(f, append);
619 setFilePermissionsFromMode(f.getPath(), mode, 0);
620 return fos;
621 } catch (FileNotFoundException e) {
622 }
623
624 File parent = f.getParentFile();
625 parent.mkdir();
626 FileUtils.setPermissions(
627 parent.getPath(),
628 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
629 -1, -1);
630 FileOutputStream fos = new FileOutputStream(f, append);
631 setFilePermissionsFromMode(f.getPath(), mode, 0);
632 return fos;
633 }
634
635 @Override
636 public boolean deleteFile(String name) {
637 File f = makeFilename(getFilesDir(), name);
638 return f.delete();
639 }
640
641 @Override
642 public File getFilesDir() {
643 synchronized (mSync) {
644 if (mFilesDir == null) {
645 mFilesDir = new File(getDataDirFile(), "files");
646 }
647 if (!mFilesDir.exists()) {
648 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200649 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 return null;
651 }
652 FileUtils.setPermissions(
653 mFilesDir.getPath(),
654 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
655 -1, -1);
656 }
657 return mFilesDir;
658 }
659 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200660
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800662 public File getExternalFilesDir(String type) {
663 synchronized (mSync) {
664 if (mExternalFilesDir == null) {
665 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
666 getPackageName());
667 }
668 if (!mExternalFilesDir.exists()) {
669 try {
670 (new File(Environment.getExternalStorageAndroidDataDir(),
671 ".nomedia")).createNewFile();
672 } catch (IOException e) {
673 }
674 if (!mExternalFilesDir.mkdirs()) {
675 Log.w(TAG, "Unable to create external files directory");
676 return null;
677 }
678 }
679 if (type == null) {
680 return mExternalFilesDir;
681 }
682 File dir = new File(mExternalFilesDir, type);
683 if (!dir.exists()) {
684 if (!dir.mkdirs()) {
685 Log.w(TAG, "Unable to create external media directory " + dir);
686 return null;
687 }
688 }
689 return dir;
690 }
691 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200692
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800693 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800694 public File getObbDir() {
695 synchronized (mSync) {
696 if (mObbDir == null) {
697 mObbDir = Environment.getExternalStorageAppObbDirectory(
698 getPackageName());
699 }
700 return mObbDir;
701 }
702 }
703
704 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 public File getCacheDir() {
706 synchronized (mSync) {
707 if (mCacheDir == null) {
708 mCacheDir = new File(getDataDirFile(), "cache");
709 }
710 if (!mCacheDir.exists()) {
711 if(!mCacheDir.mkdirs()) {
712 Log.w(TAG, "Unable to create cache directory");
713 return null;
714 }
715 FileUtils.setPermissions(
716 mCacheDir.getPath(),
717 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
718 -1, -1);
719 }
720 }
721 return mCacheDir;
722 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200723
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800724 @Override
725 public File getExternalCacheDir() {
726 synchronized (mSync) {
727 if (mExternalCacheDir == null) {
728 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
729 getPackageName());
730 }
731 if (!mExternalCacheDir.exists()) {
732 try {
733 (new File(Environment.getExternalStorageAndroidDataDir(),
734 ".nomedia")).createNewFile();
735 } catch (IOException e) {
736 }
737 if (!mExternalCacheDir.mkdirs()) {
738 Log.w(TAG, "Unable to create external cache directory");
739 return null;
740 }
741 }
742 return mExternalCacheDir;
743 }
744 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 @Override
747 public File getFileStreamPath(String name) {
748 return makeFilename(getFilesDir(), name);
749 }
750
751 @Override
752 public String[] fileList() {
753 final String[] list = getFilesDir().list();
754 return (list != null) ? list : EMPTY_FILE_LIST;
755 }
756
757 @Override
758 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800759 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
761 setFilePermissionsFromMode(f.getPath(), mode, 0);
762 return db;
763 }
764
765 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700766 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
767 DatabaseErrorHandler errorHandler) {
768 File f = validateFilePath(name, true);
769 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
770 setFilePermissionsFromMode(f.getPath(), mode, 0);
771 return db;
772 }
773
774 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 public boolean deleteDatabase(String name) {
776 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800777 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 return f.delete();
779 } catch (Exception e) {
780 }
781 return false;
782 }
783
784 @Override
785 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800786 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 }
788
789 @Override
790 public String[] databaseList() {
791 final String[] list = getDatabasesDir().list();
792 return (list != null) ? list : EMPTY_FILE_LIST;
793 }
794
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 private File getDatabasesDir() {
797 synchronized (mSync) {
798 if (mDatabasesDir == null) {
799 mDatabasesDir = new File(getDataDirFile(), "databases");
800 }
801 if (mDatabasesDir.getPath().equals("databases")) {
802 mDatabasesDir = new File("/data/system");
803 }
804 return mDatabasesDir;
805 }
806 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200807
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 @Override
809 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700810 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
812
813 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700814 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700815 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800816 }
817
818 @Override
819 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700820 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 }
822
823 @Override
824 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700825 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 }
827
828 @Override
829 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700830 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 }
832
833 @Override
834 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700835 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800836 }
837
838 @Override
839 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700840 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 }
842
843 @Override
844 public void startActivity(Intent intent) {
845 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
846 throw new AndroidRuntimeException(
847 "Calling startActivity() from outside of an Activity "
848 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
849 + " Is this really what you want?");
850 }
851 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700852 getOuterContext(), mMainThread.getApplicationThread(), null,
853 (Activity)null, intent, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 }
855
856 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800857 public void startActivities(Intent[] intents) {
858 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
859 throw new AndroidRuntimeException(
860 "Calling startActivities() from outside of an Activity "
861 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
862 + " Is this really what you want?");
863 }
864 mMainThread.getInstrumentation().execStartActivities(
865 getOuterContext(), mMainThread.getApplicationThread(), null,
866 (Activity)null, intents);
867 }
868
869 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700870 public void startIntentSender(IntentSender intent,
871 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
872 throws IntentSender.SendIntentException {
873 try {
874 String resolvedType = null;
875 if (fillInIntent != null) {
876 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
877 }
878 int result = ActivityManagerNative.getDefault()
879 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
880 fillInIntent, resolvedType, null, null,
881 0, flagsMask, flagsValues);
882 if (result == IActivityManager.START_CANCELED) {
883 throw new IntentSender.SendIntentException();
884 }
885 Instrumentation.checkStartActivityResult(result, null);
886 } catch (RemoteException e) {
887 }
888 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200889
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700890 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 public void sendBroadcast(Intent intent) {
892 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
893 try {
894 ActivityManagerNative.getDefault().broadcastIntent(
895 mMainThread.getApplicationThread(), intent, resolvedType, null,
896 Activity.RESULT_OK, null, null, null, false, false);
897 } catch (RemoteException e) {
898 }
899 }
900
901 @Override
902 public void sendBroadcast(Intent intent, String receiverPermission) {
903 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
904 try {
905 ActivityManagerNative.getDefault().broadcastIntent(
906 mMainThread.getApplicationThread(), intent, resolvedType, null,
907 Activity.RESULT_OK, null, null, receiverPermission, false, false);
908 } catch (RemoteException e) {
909 }
910 }
911
912 @Override
913 public void sendOrderedBroadcast(Intent intent,
914 String receiverPermission) {
915 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
916 try {
917 ActivityManagerNative.getDefault().broadcastIntent(
918 mMainThread.getApplicationThread(), intent, resolvedType, null,
919 Activity.RESULT_OK, null, null, receiverPermission, true, false);
920 } catch (RemoteException e) {
921 }
922 }
923
924 @Override
925 public void sendOrderedBroadcast(Intent intent,
926 String receiverPermission, BroadcastReceiver resultReceiver,
927 Handler scheduler, int initialCode, String initialData,
928 Bundle initialExtras) {
929 IIntentReceiver rd = null;
930 if (resultReceiver != null) {
931 if (mPackageInfo != null) {
932 if (scheduler == null) {
933 scheduler = mMainThread.getHandler();
934 }
935 rd = mPackageInfo.getReceiverDispatcher(
936 resultReceiver, getOuterContext(), scheduler,
937 mMainThread.getInstrumentation(), false);
938 } else {
939 if (scheduler == null) {
940 scheduler = mMainThread.getHandler();
941 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700942 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800943 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
944 }
945 }
946 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
947 try {
948 ActivityManagerNative.getDefault().broadcastIntent(
949 mMainThread.getApplicationThread(), intent, resolvedType, rd,
950 initialCode, initialData, initialExtras, receiverPermission,
951 true, false);
952 } catch (RemoteException e) {
953 }
954 }
955
956 @Override
957 public void sendStickyBroadcast(Intent intent) {
958 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
959 try {
960 ActivityManagerNative.getDefault().broadcastIntent(
961 mMainThread.getApplicationThread(), intent, resolvedType, null,
962 Activity.RESULT_OK, null, null, null, false, true);
963 } catch (RemoteException e) {
964 }
965 }
966
967 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700968 public void sendStickyOrderedBroadcast(Intent intent,
969 BroadcastReceiver resultReceiver,
970 Handler scheduler, int initialCode, String initialData,
971 Bundle initialExtras) {
972 IIntentReceiver rd = null;
973 if (resultReceiver != null) {
974 if (mPackageInfo != null) {
975 if (scheduler == null) {
976 scheduler = mMainThread.getHandler();
977 }
978 rd = mPackageInfo.getReceiverDispatcher(
979 resultReceiver, getOuterContext(), scheduler,
980 mMainThread.getInstrumentation(), false);
981 } else {
982 if (scheduler == null) {
983 scheduler = mMainThread.getHandler();
984 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700985 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700986 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
987 }
988 }
989 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
990 try {
991 ActivityManagerNative.getDefault().broadcastIntent(
992 mMainThread.getApplicationThread(), intent, resolvedType, rd,
993 initialCode, initialData, initialExtras, null,
994 true, true);
995 } catch (RemoteException e) {
996 }
997 }
998
999 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 public void removeStickyBroadcast(Intent intent) {
1001 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1002 if (resolvedType != null) {
1003 intent = new Intent(intent);
1004 intent.setDataAndType(intent.getData(), resolvedType);
1005 }
1006 try {
1007 ActivityManagerNative.getDefault().unbroadcastIntent(
1008 mMainThread.getApplicationThread(), intent);
1009 } catch (RemoteException e) {
1010 }
1011 }
1012
1013 @Override
1014 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1015 return registerReceiver(receiver, filter, null, null);
1016 }
1017
1018 @Override
1019 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1020 String broadcastPermission, Handler scheduler) {
1021 return registerReceiverInternal(receiver, filter, broadcastPermission,
1022 scheduler, getOuterContext());
1023 }
1024
1025 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1026 IntentFilter filter, String broadcastPermission,
1027 Handler scheduler, Context context) {
1028 IIntentReceiver rd = null;
1029 if (receiver != null) {
1030 if (mPackageInfo != null && context != null) {
1031 if (scheduler == null) {
1032 scheduler = mMainThread.getHandler();
1033 }
1034 rd = mPackageInfo.getReceiverDispatcher(
1035 receiver, context, scheduler,
1036 mMainThread.getInstrumentation(), true);
1037 } else {
1038 if (scheduler == null) {
1039 scheduler = mMainThread.getHandler();
1040 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001041 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001042 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001043 }
1044 }
1045 try {
1046 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001047 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 rd, filter, broadcastPermission);
1049 } catch (RemoteException e) {
1050 return null;
1051 }
1052 }
1053
1054 @Override
1055 public void unregisterReceiver(BroadcastReceiver receiver) {
1056 if (mPackageInfo != null) {
1057 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1058 getOuterContext(), receiver);
1059 try {
1060 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1061 } catch (RemoteException e) {
1062 }
1063 } else {
1064 throw new RuntimeException("Not supported in system context");
1065 }
1066 }
1067
1068 @Override
1069 public ComponentName startService(Intent service) {
1070 try {
1071 ComponentName cn = ActivityManagerNative.getDefault().startService(
1072 mMainThread.getApplicationThread(), service,
1073 service.resolveTypeIfNeeded(getContentResolver()));
1074 if (cn != null && cn.getPackageName().equals("!")) {
1075 throw new SecurityException(
1076 "Not allowed to start service " + service
1077 + " without permission " + cn.getClassName());
1078 }
1079 return cn;
1080 } catch (RemoteException e) {
1081 return null;
1082 }
1083 }
1084
1085 @Override
1086 public boolean stopService(Intent service) {
1087 try {
1088 int res = ActivityManagerNative.getDefault().stopService(
1089 mMainThread.getApplicationThread(), service,
1090 service.resolveTypeIfNeeded(getContentResolver()));
1091 if (res < 0) {
1092 throw new SecurityException(
1093 "Not allowed to stop service " + service);
1094 }
1095 return res != 0;
1096 } catch (RemoteException e) {
1097 return false;
1098 }
1099 }
1100
1101 @Override
1102 public boolean bindService(Intent service, ServiceConnection conn,
1103 int flags) {
1104 IServiceConnection sd;
1105 if (mPackageInfo != null) {
1106 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1107 mMainThread.getHandler(), flags);
1108 } else {
1109 throw new RuntimeException("Not supported in system context");
1110 }
1111 try {
1112 int res = ActivityManagerNative.getDefault().bindService(
1113 mMainThread.getApplicationThread(), getActivityToken(),
1114 service, service.resolveTypeIfNeeded(getContentResolver()),
1115 sd, flags);
1116 if (res < 0) {
1117 throw new SecurityException(
1118 "Not allowed to bind to service " + service);
1119 }
1120 return res != 0;
1121 } catch (RemoteException e) {
1122 return false;
1123 }
1124 }
1125
1126 @Override
1127 public void unbindService(ServiceConnection conn) {
1128 if (mPackageInfo != null) {
1129 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1130 getOuterContext(), conn);
1131 try {
1132 ActivityManagerNative.getDefault().unbindService(sd);
1133 } catch (RemoteException e) {
1134 }
1135 } else {
1136 throw new RuntimeException("Not supported in system context");
1137 }
1138 }
1139
1140 @Override
1141 public boolean startInstrumentation(ComponentName className,
1142 String profileFile, Bundle arguments) {
1143 try {
1144 return ActivityManagerNative.getDefault().startInstrumentation(
1145 className, profileFile, 0, arguments, null);
1146 } catch (RemoteException e) {
1147 // System has crashed, nothing we can do.
1148 }
1149 return false;
1150 }
1151
1152 @Override
1153 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001154 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1155 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 }
1157
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001158 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001159 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 }
1161
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001162 /* package */ static DropBoxManager createDropBoxManager() {
1163 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1164 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001165 if (service == null) {
1166 // Don't return a DropBoxManager that will NPE upon use.
1167 // This also avoids caching a broken DropBoxManager in
1168 // getDropBoxManager during early boot, before the
1169 // DROPBOX_SERVICE is registered.
1170 return null;
1171 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001172 return new DropBoxManager(service);
1173 }
1174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 @Override
1176 public int checkPermission(String permission, int pid, int uid) {
1177 if (permission == null) {
1178 throw new IllegalArgumentException("permission is null");
1179 }
1180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001181 try {
1182 return ActivityManagerNative.getDefault().checkPermission(
1183 permission, pid, uid);
1184 } catch (RemoteException e) {
1185 return PackageManager.PERMISSION_DENIED;
1186 }
1187 }
1188
1189 @Override
1190 public int checkCallingPermission(String permission) {
1191 if (permission == null) {
1192 throw new IllegalArgumentException("permission is null");
1193 }
1194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 int pid = Binder.getCallingPid();
1196 if (pid != Process.myPid()) {
1197 return checkPermission(permission, pid,
1198 Binder.getCallingUid());
1199 }
1200 return PackageManager.PERMISSION_DENIED;
1201 }
1202
1203 @Override
1204 public int checkCallingOrSelfPermission(String permission) {
1205 if (permission == null) {
1206 throw new IllegalArgumentException("permission is null");
1207 }
1208
1209 return checkPermission(permission, Binder.getCallingPid(),
1210 Binder.getCallingUid());
1211 }
1212
1213 private void enforce(
1214 String permission, int resultOfCheck,
1215 boolean selfToo, int uid, String message) {
1216 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1217 throw new SecurityException(
1218 (message != null ? (message + ": ") : "") +
1219 (selfToo
1220 ? "Neither user " + uid + " nor current process has "
1221 : "User " + uid + " does not have ") +
1222 permission +
1223 ".");
1224 }
1225 }
1226
1227 public void enforcePermission(
1228 String permission, int pid, int uid, String message) {
1229 enforce(permission,
1230 checkPermission(permission, pid, uid),
1231 false,
1232 uid,
1233 message);
1234 }
1235
1236 public void enforceCallingPermission(String permission, String message) {
1237 enforce(permission,
1238 checkCallingPermission(permission),
1239 false,
1240 Binder.getCallingUid(),
1241 message);
1242 }
1243
1244 public void enforceCallingOrSelfPermission(
1245 String permission, String message) {
1246 enforce(permission,
1247 checkCallingOrSelfPermission(permission),
1248 true,
1249 Binder.getCallingUid(),
1250 message);
1251 }
1252
1253 @Override
1254 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1255 try {
1256 ActivityManagerNative.getDefault().grantUriPermission(
1257 mMainThread.getApplicationThread(), toPackage, uri,
1258 modeFlags);
1259 } catch (RemoteException e) {
1260 }
1261 }
1262
1263 @Override
1264 public void revokeUriPermission(Uri uri, int modeFlags) {
1265 try {
1266 ActivityManagerNative.getDefault().revokeUriPermission(
1267 mMainThread.getApplicationThread(), uri,
1268 modeFlags);
1269 } catch (RemoteException e) {
1270 }
1271 }
1272
1273 @Override
1274 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 try {
1276 return ActivityManagerNative.getDefault().checkUriPermission(
1277 uri, pid, uid, modeFlags);
1278 } catch (RemoteException e) {
1279 return PackageManager.PERMISSION_DENIED;
1280 }
1281 }
1282
1283 @Override
1284 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 int pid = Binder.getCallingPid();
1286 if (pid != Process.myPid()) {
1287 return checkUriPermission(uri, pid,
1288 Binder.getCallingUid(), modeFlags);
1289 }
1290 return PackageManager.PERMISSION_DENIED;
1291 }
1292
1293 @Override
1294 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1295 return checkUriPermission(uri, Binder.getCallingPid(),
1296 Binder.getCallingUid(), modeFlags);
1297 }
1298
1299 @Override
1300 public int checkUriPermission(Uri uri, String readPermission,
1301 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001302 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1304 + readPermission + " writePermission=" + writePermission
1305 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1306 }
1307 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1308 if (readPermission == null
1309 || checkPermission(readPermission, pid, uid)
1310 == PackageManager.PERMISSION_GRANTED) {
1311 return PackageManager.PERMISSION_GRANTED;
1312 }
1313 }
1314 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1315 if (writePermission == null
1316 || checkPermission(writePermission, pid, uid)
1317 == PackageManager.PERMISSION_GRANTED) {
1318 return PackageManager.PERMISSION_GRANTED;
1319 }
1320 }
1321 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1322 : PackageManager.PERMISSION_DENIED;
1323 }
1324
1325 private String uriModeFlagToString(int uriModeFlags) {
1326 switch (uriModeFlags) {
1327 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1328 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1329 return "read and write";
1330 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1331 return "read";
1332 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1333 return "write";
1334 }
1335 throw new IllegalArgumentException(
1336 "Unknown permission mode flags: " + uriModeFlags);
1337 }
1338
1339 private void enforceForUri(
1340 int modeFlags, int resultOfCheck, boolean selfToo,
1341 int uid, Uri uri, String message) {
1342 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1343 throw new SecurityException(
1344 (message != null ? (message + ": ") : "") +
1345 (selfToo
1346 ? "Neither user " + uid + " nor current process has "
1347 : "User " + uid + " does not have ") +
1348 uriModeFlagToString(modeFlags) +
1349 " permission on " +
1350 uri +
1351 ".");
1352 }
1353 }
1354
1355 public void enforceUriPermission(
1356 Uri uri, int pid, int uid, int modeFlags, String message) {
1357 enforceForUri(
1358 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1359 false, uid, uri, message);
1360 }
1361
1362 public void enforceCallingUriPermission(
1363 Uri uri, int modeFlags, String message) {
1364 enforceForUri(
1365 modeFlags, checkCallingUriPermission(uri, modeFlags),
1366 false, Binder.getCallingUid(), uri, message);
1367 }
1368
1369 public void enforceCallingOrSelfUriPermission(
1370 Uri uri, int modeFlags, String message) {
1371 enforceForUri(
1372 modeFlags,
1373 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1374 Binder.getCallingUid(), uri, message);
1375 }
1376
1377 public void enforceUriPermission(
1378 Uri uri, String readPermission, String writePermission,
1379 int pid, int uid, int modeFlags, String message) {
1380 enforceForUri(modeFlags,
1381 checkUriPermission(
1382 uri, readPermission, writePermission, pid, uid,
1383 modeFlags),
1384 false,
1385 uid,
1386 uri,
1387 message);
1388 }
1389
1390 @Override
1391 public Context createPackageContext(String packageName, int flags)
1392 throws PackageManager.NameNotFoundException {
1393 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001394 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 }
1396
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001397 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001398 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001400 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001401 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001402 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 if (c.mResources != null) {
1404 return c;
1405 }
1406 }
1407
1408 // Should be a better exception.
1409 throw new PackageManager.NameNotFoundException(
1410 "Application package " + packageName + " not found");
1411 }
1412
Romain Guy870e09f2009-07-06 16:35:25 -07001413 @Override
1414 public boolean isRestricted() {
1415 return mRestricted;
1416 }
1417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 private File getDataDirFile() {
1419 if (mPackageInfo != null) {
1420 return mPackageInfo.getDataDirFile();
1421 }
1422 throw new RuntimeException("Not supported in system context");
1423 }
1424
1425 @Override
1426 public File getDir(String name, int mode) {
1427 name = "app_" + name;
1428 File file = makeFilename(getDataDirFile(), name);
1429 if (!file.exists()) {
1430 file.mkdir();
1431 setFilePermissionsFromMode(file.getPath(), mode,
1432 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1433 }
1434 return file;
1435 }
1436
Dianne Hackborn21556372010-02-04 16:34:40 -08001437 static ContextImpl createSystemContext(ActivityThread mainThread) {
1438 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 context.init(Resources.getSystem(), mainThread);
1440 return context;
1441 }
1442
Dianne Hackborn21556372010-02-04 16:34:40 -08001443 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 mOuterContext = this;
1445 }
1446
1447 /**
1448 * Create a new ApplicationContext from an existing one. The new one
1449 * works and operates the same as the one it is copying.
1450 *
1451 * @param context Existing application context.
1452 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001453 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001455 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001456 mResources = context.mResources;
1457 mMainThread = context.mMainThread;
1458 mContentResolver = context.mContentResolver;
1459 mOuterContext = this;
1460 }
1461
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001462 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001464 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001465 }
1466
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001467 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001468 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001469 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001471 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001473
Dianne Hackborn559a7872010-04-07 18:19:41 -07001474 if (mResources != null && container != null
1475 && container.getCompatibilityInfo().applicationScale !=
1476 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001477 if (DEBUG) {
1478 Log.d(TAG, "loaded context has different scaling. Using container's" +
1479 " compatiblity info:" + container.getDisplayMetrics());
1480 }
1481 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001482 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 mMainThread = mainThread;
1485 mContentResolver = new ApplicationContentResolver(this, mainThread);
1486
1487 setActivityToken(activityToken);
1488 }
1489
1490 final void init(Resources resources, ActivityThread mainThread) {
1491 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001492 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 mResources = resources;
1494 mMainThread = mainThread;
1495 mContentResolver = new ApplicationContentResolver(this, mainThread);
1496 }
1497
1498 final void scheduleFinalCleanup(String who, String what) {
1499 mMainThread.scheduleContextCleanup(this, who, what);
1500 }
1501
1502 final void performFinalCleanup(String who, String what) {
1503 //Log.i(TAG, "Cleanup up context: " + this);
1504 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1505 }
1506
1507 final Context getReceiverRestrictedContext() {
1508 if (mReceiverRestrictedContext != null) {
1509 return mReceiverRestrictedContext;
1510 }
1511 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1512 }
1513
1514 final void setActivityToken(IBinder token) {
1515 mActivityToken = token;
1516 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 final void setOuterContext(Context context) {
1519 mOuterContext = context;
1520 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001521
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522 final Context getOuterContext() {
1523 return mOuterContext;
1524 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 final IBinder getActivityToken() {
1527 return mActivityToken;
1528 }
1529
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001530 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 int extraPermissions) {
1532 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1533 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1534 |extraPermissions;
1535 if ((mode&MODE_WORLD_READABLE) != 0) {
1536 perms |= FileUtils.S_IROTH;
1537 }
1538 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1539 perms |= FileUtils.S_IWOTH;
1540 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001541 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001542 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1543 + ", perms=0x" + Integer.toHexString(perms));
1544 }
1545 FileUtils.setPermissions(name, perms, -1, -1);
1546 }
1547
Oscar Montemayora8529f62009-11-18 10:14:20 -08001548 private File validateFilePath(String name, boolean createDirectory) {
1549 File dir;
1550 File f;
1551
1552 if (name.charAt(0) == File.separatorChar) {
1553 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1554 dir = new File(dirPath);
1555 name = name.substring(name.lastIndexOf(File.separatorChar));
1556 f = new File(dir, name);
1557 } else {
1558 dir = getDatabasesDir();
1559 f = makeFilename(dir, name);
1560 }
1561
1562 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1563 FileUtils.setPermissions(dir.getPath(),
1564 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1565 -1, -1);
1566 }
1567
1568 return f;
1569 }
1570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 private File makeFilename(File base, String name) {
1572 if (name.indexOf(File.separatorChar) < 0) {
1573 return new File(base, name);
1574 }
1575 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001576 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 }
1578
1579 // ----------------------------------------------------------------------
1580 // ----------------------------------------------------------------------
1581 // ----------------------------------------------------------------------
1582
1583 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001584 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 super(context);
1586 mMainThread = mainThread;
1587 }
1588
1589 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001590 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 return mMainThread.acquireProvider(context, name);
1592 }
1593
1594 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001595 protected IContentProvider acquireExistingProvider(Context context, String name) {
1596 return mMainThread.acquireExistingProvider(context, name);
1597 }
1598
1599 @Override
1600 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001601 return mMainThread.releaseProvider(provider);
1602 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604 private final ActivityThread mMainThread;
1605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606}