blob: 414ba792bd93a999c5182c645e52e9b8746f121a [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;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040045import android.hardware.ISerialManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.hardware.SensorManager;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040047import android.hardware.SerialManager;
Jeff Brown9df6e7a2012-04-05 11:49:26 -070048import android.hardware.input.InputManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080049import android.hardware.usb.IUsbManager;
50import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080051import android.location.CountryDetector;
52import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.location.ILocationManager;
54import android.location.LocationManager;
55import android.media.AudioManager;
56import android.net.ConnectivityManager;
57import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070058import android.net.INetworkPolicyManager;
59import android.net.NetworkPolicyManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070060import android.net.ThrottleManager;
61import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.net.Uri;
63import android.net.wifi.IWifiManager;
64import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070065import android.net.wifi.p2p.IWifiP2pManager;
66import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080067import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.os.Binder;
69import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080070import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080071import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.os.FileUtils;
73import android.os.Handler;
74import android.os.IBinder;
75import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070076import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077import android.os.PowerManager;
78import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070079import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.os.ServiceManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070081import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080083import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070085import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.util.AndroidRuntimeException;
87import android.util.Log;
88import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070090import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090092import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070093import android.accounts.AccountManager;
94import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080095import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080096import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import java.io.File;
99import java.io.FileInputStream;
100import java.io.FileNotFoundException;
101import java.io.FileOutputStream;
102import java.io.IOException;
103import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import java.util.ArrayList;
105import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107class ReceiverRestrictedContext extends ContextWrapper {
108 ReceiverRestrictedContext(Context base) {
109 super(base);
110 }
111
112 @Override
113 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
114 return registerReceiver(receiver, filter, null, null);
115 }
116
117 @Override
118 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
119 String broadcastPermission, Handler scheduler) {
120 throw new ReceiverCallNotAllowedException(
121 "IntentReceiver components are not allowed to register to receive intents");
122 //ex.fillInStackTrace();
123 //Log.e("IntentReceiver", ex.getMessage(), ex);
124 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
125 // scheduler);
126 }
127
128 @Override
129 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
130 throw new ReceiverCallNotAllowedException(
131 "IntentReceiver components are not allowed to bind to services");
132 //ex.fillInStackTrace();
133 //Log.e("IntentReceiver", ex.getMessage(), ex);
134 //return mContext.bindService(service, interfaceName, conn, flags);
135 }
136}
137
138/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800139 * Common implementation of Context API, which provides the base
140 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800142class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700144 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700146 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
147 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700149 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700150 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800151 private Resources mResources;
152 /*package*/ ActivityThread mMainThread;
153 private Context mOuterContext;
154 private IBinder mActivityToken = null;
155 private ApplicationContentResolver mContentResolver;
156 private int mThemeResource = 0;
157 private Resources.Theme mTheme = null;
158 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700160 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161
162 private final Object mSync = new Object();
163
164 private File mDatabasesDir;
165 private File mPreferencesDir;
166 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800168 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800169 private File mExternalFilesDir;
170 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 private static final String[] EMPTY_FILE_LIST = {};
173
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800174 /**
175 * Override this class when the system service constructor needs a
176 * ContextImpl. Else, use StaticServiceFetcher below.
177 */
178 /*package*/ static class ServiceFetcher {
179 int mContextCacheIndex = -1;
180
181 /**
182 * Main entrypoint; only override if you don't need caching.
183 */
184 public Object getService(ContextImpl ctx) {
185 ArrayList<Object> cache = ctx.mServiceCache;
186 Object service;
187 synchronized (cache) {
188 if (cache.size() == 0) {
189 // Initialize the cache vector on first access.
190 // At this point sNextPerContextServiceCacheIndex
191 // is the number of potential services that are
192 // cached per-Context.
193 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
194 cache.add(null);
195 }
196 } else {
197 service = cache.get(mContextCacheIndex);
198 if (service != null) {
199 return service;
200 }
201 }
202 service = createService(ctx);
203 cache.set(mContextCacheIndex, service);
204 return service;
205 }
206 }
207
208 /**
209 * Override this to create a new per-Context instance of the
210 * service. getService() will handle locking and caching.
211 */
212 public Object createService(ContextImpl ctx) {
213 throw new RuntimeException("Not implemented");
214 }
215 }
216
217 /**
218 * Override this class for services to be cached process-wide.
219 */
220 abstract static class StaticServiceFetcher extends ServiceFetcher {
221 private Object mCachedInstance;
222
223 @Override
224 public final Object getService(ContextImpl unused) {
225 synchronized (StaticServiceFetcher.this) {
226 Object service = mCachedInstance;
227 if (service != null) {
228 return service;
229 }
230 return mCachedInstance = createStaticService();
231 }
232 }
233
234 public abstract Object createStaticService();
235 }
236
237 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
238 new HashMap<String, ServiceFetcher>();
239
240 private static int sNextPerContextServiceCacheIndex = 0;
241 private static void registerService(String serviceName, ServiceFetcher fetcher) {
242 if (!(fetcher instanceof StaticServiceFetcher)) {
243 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
244 }
245 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
246 }
247
248 // This one's defined separately and given a variable name so it
249 // can be re-used by getWallpaperManager(), avoiding a HashMap
250 // lookup.
251 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
252 public Object createService(ContextImpl ctx) {
253 return new WallpaperManager(ctx.getOuterContext(),
254 ctx.mMainThread.getHandler());
255 }};
256
257 static {
258 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
259 public Object getService(ContextImpl ctx) {
260 return AccessibilityManager.getInstance(ctx);
261 }});
262
263 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
264 public Object createService(ContextImpl ctx) {
265 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
266 IAccountManager service = IAccountManager.Stub.asInterface(b);
267 return new AccountManager(ctx, service);
268 }});
269
270 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
271 public Object createService(ContextImpl ctx) {
272 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
273 }});
274
275 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
276 public Object createStaticService() {
277 IBinder b = ServiceManager.getService(ALARM_SERVICE);
278 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
279 return new AlarmManager(service);
280 }});
281
282 registerService(AUDIO_SERVICE, new ServiceFetcher() {
283 public Object createService(ContextImpl ctx) {
284 return new AudioManager(ctx);
285 }});
286
287 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
288 public Object createService(ContextImpl ctx) {
289 return new ClipboardManager(ctx.getOuterContext(),
290 ctx.mMainThread.getHandler());
291 }});
292
293 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
294 public Object createStaticService() {
295 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
296 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
297 }});
298
299 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
300 public Object createStaticService() {
301 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
302 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
303 }});
304
305 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
306 public Object createService(ContextImpl ctx) {
307 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
308 }});
309
310 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
311 public Object createService(ContextImpl ctx) {
312 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
313 }});
314
Nick Pellyd2507462010-12-13 12:22:34 -0800315 registerService(NFC_SERVICE, new ServiceFetcher() {
316 public Object createService(ContextImpl ctx) {
317 return new NfcManager(ctx);
318 }});
319
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800320 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
321 public Object createStaticService() {
322 return createDropBoxManager();
323 }});
324
Jeff Brown9df6e7a2012-04-05 11:49:26 -0700325 registerService(INPUT_SERVICE, new ServiceFetcher() {
326 public Object createService(ContextImpl ctx) {
327 return new InputManager(ctx);
328 }});
329
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800330 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
331 public Object createService(ContextImpl ctx) {
332 return InputMethodManager.getInstance(ctx);
333 }});
334
satok988323c2011-06-22 16:38:13 +0900335 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
336 public Object createService(ContextImpl ctx) {
337 return TextServicesManager.getInstance();
338 }});
339
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800340 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
341 public Object getService(ContextImpl ctx) {
342 // TODO: why isn't this caching it? It wasn't
343 // before, so I'm preserving the old behavior and
344 // using getService(), instead of createService()
345 // which would do the caching.
346 return new KeyguardManager();
347 }});
348
349 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
350 public Object createService(ContextImpl ctx) {
351 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
352 }});
353
354 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
355 public Object createStaticService() {
356 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
357 return new LocationManager(ILocationManager.Stub.asInterface(b));
358 }});
359
Jeff Sharkey1a303952011-06-16 13:04:20 -0700360 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
361 @Override
362 public Object createService(ContextImpl ctx) {
363 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
364 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
365 }
366 });
367
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800368 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
369 public Object createService(ContextImpl ctx) {
370 final Context outerContext = ctx.getOuterContext();
371 return new NotificationManager(
372 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800373 Resources.selectSystemTheme(0,
374 outerContext.getApplicationInfo().targetSdkVersion,
375 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700376 com.android.internal.R.style.Theme_Holo_Dialog,
377 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800378 ctx.mMainThread.getHandler());
379 }});
380
381 // Note: this was previously cached in a static variable, but
382 // constructed using mMainThread.getHandler(), so converting
383 // it to be a regular Context-cached service...
384 registerService(POWER_SERVICE, new ServiceFetcher() {
385 public Object createService(ContextImpl ctx) {
386 IBinder b = ServiceManager.getService(POWER_SERVICE);
387 IPowerManager service = IPowerManager.Stub.asInterface(b);
388 return new PowerManager(service, ctx.mMainThread.getHandler());
389 }});
390
391 registerService(SEARCH_SERVICE, new ServiceFetcher() {
392 public Object createService(ContextImpl ctx) {
393 return new SearchManager(ctx.getOuterContext(),
394 ctx.mMainThread.getHandler());
395 }});
396
397 registerService(SENSOR_SERVICE, new ServiceFetcher() {
398 public Object createService(ContextImpl ctx) {
399 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
400 }});
401
402 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
403 public Object createService(ContextImpl ctx) {
404 return new StatusBarManager(ctx.getOuterContext());
405 }});
406
407 registerService(STORAGE_SERVICE, new ServiceFetcher() {
408 public Object createService(ContextImpl ctx) {
409 try {
410 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
411 } catch (RemoteException rex) {
412 Log.e(TAG, "Failed to create StorageManager", rex);
413 return null;
414 }
415 }});
416
417 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
418 public Object createService(ContextImpl ctx) {
419 return new TelephonyManager(ctx.getOuterContext());
420 }});
421
422 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
423 public Object createStaticService() {
424 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
425 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
426 }});
427
428 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
429 public Object createService(ContextImpl ctx) {
430 return new UiModeManager();
431 }});
432
Mike Lockwood3a68b832011-03-08 10:08:59 -0500433 registerService(USB_SERVICE, new ServiceFetcher() {
434 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500435 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500436 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500437 }});
438
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -0400439 registerService(SERIAL_SERVICE, new ServiceFetcher() {
440 public Object createService(ContextImpl ctx) {
441 IBinder b = ServiceManager.getService(SERIAL_SERVICE);
442 return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
443 }});
444
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800445 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
446 public Object createService(ContextImpl ctx) {
447 return new Vibrator();
448 }});
449
450 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
451
452 registerService(WIFI_SERVICE, new ServiceFetcher() {
453 public Object createService(ContextImpl ctx) {
454 IBinder b = ServiceManager.getService(WIFI_SERVICE);
455 IWifiManager service = IWifiManager.Stub.asInterface(b);
456 return new WifiManager(service, ctx.mMainThread.getHandler());
457 }});
458
repo sync55bc5f32011-06-24 14:23:07 -0700459 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
460 public Object createService(ContextImpl ctx) {
461 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
462 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
463 return new WifiP2pManager(service);
464 }});
465
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800466 registerService(WINDOW_SERVICE, new ServiceFetcher() {
467 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700468 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800469 }});
470 }
471
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700472 static ContextImpl getImpl(Context context) {
473 Context nextContext;
474 while ((context instanceof ContextWrapper) &&
475 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
476 context = nextContext;
477 }
478 return (ContextImpl)context;
479 }
480
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800481 // The system service cache for the system services that are
482 // cached per-ContextImpl. Package-scoped to avoid accessor
483 // methods.
484 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 @Override
487 public AssetManager getAssets() {
488 return mResources.getAssets();
489 }
490
491 @Override
492 public Resources getResources() {
493 return mResources;
494 }
495
496 @Override
497 public PackageManager getPackageManager() {
498 if (mPackageManager != null) {
499 return mPackageManager;
500 }
501
502 IPackageManager pm = ActivityThread.getPackageManager();
503 if (pm != null) {
504 // Doesn't matter if we make more than one instance.
505 return (mPackageManager = new ApplicationPackageManager(this, pm));
506 }
507
508 return null;
509 }
510
511 @Override
512 public ContentResolver getContentResolver() {
513 return mContentResolver;
514 }
515
516 @Override
517 public Looper getMainLooper() {
518 return mMainThread.getLooper();
519 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 @Override
522 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700523 return (mPackageInfo != null) ?
524 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527 @Override
528 public void setTheme(int resid) {
529 mThemeResource = resid;
530 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800533 public int getThemeResId() {
534 return mThemeResource;
535 }
536
537 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538 public Resources.Theme getTheme() {
539 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800540 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
541 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 mTheme = mResources.newTheme();
543 mTheme.applyStyle(mThemeResource, true);
544 }
545 return mTheme;
546 }
547
548 @Override
549 public ClassLoader getClassLoader() {
550 return mPackageInfo != null ?
551 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
552 }
553
554 @Override
555 public String getPackageName() {
556 if (mPackageInfo != null) {
557 return mPackageInfo.getPackageName();
558 }
559 throw new RuntimeException("Not supported in system context");
560 }
561
562 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700563 public ApplicationInfo getApplicationInfo() {
564 if (mPackageInfo != null) {
565 return mPackageInfo.getApplicationInfo();
566 }
567 throw new RuntimeException("Not supported in system context");
568 }
569
570 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800571 public String getPackageResourcePath() {
572 if (mPackageInfo != null) {
573 return mPackageInfo.getResDir();
574 }
575 throw new RuntimeException("Not supported in system context");
576 }
577
578 @Override
579 public String getPackageCodePath() {
580 if (mPackageInfo != null) {
581 return mPackageInfo.getAppDir();
582 }
583 throw new RuntimeException("Not supported in system context");
584 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200585
Joe Onorato23ecae32009-06-10 17:07:15 -0700586 public File getSharedPrefsFile(String name) {
587 return makeFilename(getPreferencesDir(), name + ".xml");
588 }
589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 @Override
591 public SharedPreferences getSharedPreferences(String name, int mode) {
592 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800593 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700594 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700595 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800596 File prefsFile = getSharedPrefsFile(name);
597 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700598 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700599 return sp;
600 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800602 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
603 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
604 // If somebody else (some other process) changed the prefs
605 // file behind our back, we reload it. This has been the
606 // historical (if undocumented) behavior.
607 sp.startReloadIfChangedUnexpectedly();
608 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700609 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800610 }
611
612 private File getPreferencesDir() {
613 synchronized (mSync) {
614 if (mPreferencesDir == null) {
615 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
616 }
617 return mPreferencesDir;
618 }
619 }
620
621 @Override
622 public FileInputStream openFileInput(String name)
623 throws FileNotFoundException {
624 File f = makeFilename(getFilesDir(), name);
625 return new FileInputStream(f);
626 }
627
628 @Override
629 public FileOutputStream openFileOutput(String name, int mode)
630 throws FileNotFoundException {
631 final boolean append = (mode&MODE_APPEND) != 0;
632 File f = makeFilename(getFilesDir(), name);
633 try {
634 FileOutputStream fos = new FileOutputStream(f, append);
635 setFilePermissionsFromMode(f.getPath(), mode, 0);
636 return fos;
637 } catch (FileNotFoundException e) {
638 }
639
640 File parent = f.getParentFile();
641 parent.mkdir();
642 FileUtils.setPermissions(
643 parent.getPath(),
644 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
645 -1, -1);
646 FileOutputStream fos = new FileOutputStream(f, append);
647 setFilePermissionsFromMode(f.getPath(), mode, 0);
648 return fos;
649 }
650
651 @Override
652 public boolean deleteFile(String name) {
653 File f = makeFilename(getFilesDir(), name);
654 return f.delete();
655 }
656
657 @Override
658 public File getFilesDir() {
659 synchronized (mSync) {
660 if (mFilesDir == null) {
661 mFilesDir = new File(getDataDirFile(), "files");
662 }
663 if (!mFilesDir.exists()) {
664 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200665 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 return null;
667 }
668 FileUtils.setPermissions(
669 mFilesDir.getPath(),
670 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
671 -1, -1);
672 }
673 return mFilesDir;
674 }
675 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800678 public File getExternalFilesDir(String type) {
679 synchronized (mSync) {
680 if (mExternalFilesDir == null) {
681 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
682 getPackageName());
683 }
684 if (!mExternalFilesDir.exists()) {
685 try {
686 (new File(Environment.getExternalStorageAndroidDataDir(),
687 ".nomedia")).createNewFile();
688 } catch (IOException e) {
689 }
690 if (!mExternalFilesDir.mkdirs()) {
691 Log.w(TAG, "Unable to create external files directory");
692 return null;
693 }
694 }
695 if (type == null) {
696 return mExternalFilesDir;
697 }
698 File dir = new File(mExternalFilesDir, type);
699 if (!dir.exists()) {
700 if (!dir.mkdirs()) {
701 Log.w(TAG, "Unable to create external media directory " + dir);
702 return null;
703 }
704 }
705 return dir;
706 }
707 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200708
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800709 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800710 public File getObbDir() {
711 synchronized (mSync) {
712 if (mObbDir == null) {
713 mObbDir = Environment.getExternalStorageAppObbDirectory(
714 getPackageName());
715 }
716 return mObbDir;
717 }
718 }
719
720 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721 public File getCacheDir() {
722 synchronized (mSync) {
723 if (mCacheDir == null) {
724 mCacheDir = new File(getDataDirFile(), "cache");
725 }
726 if (!mCacheDir.exists()) {
727 if(!mCacheDir.mkdirs()) {
728 Log.w(TAG, "Unable to create cache directory");
729 return null;
730 }
731 FileUtils.setPermissions(
732 mCacheDir.getPath(),
733 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
734 -1, -1);
735 }
736 }
737 return mCacheDir;
738 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200739
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800740 @Override
741 public File getExternalCacheDir() {
742 synchronized (mSync) {
743 if (mExternalCacheDir == null) {
744 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
745 getPackageName());
746 }
747 if (!mExternalCacheDir.exists()) {
748 try {
749 (new File(Environment.getExternalStorageAndroidDataDir(),
750 ".nomedia")).createNewFile();
751 } catch (IOException e) {
752 }
753 if (!mExternalCacheDir.mkdirs()) {
754 Log.w(TAG, "Unable to create external cache directory");
755 return null;
756 }
757 }
758 return mExternalCacheDir;
759 }
760 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 @Override
763 public File getFileStreamPath(String name) {
764 return makeFilename(getFilesDir(), name);
765 }
766
767 @Override
768 public String[] fileList() {
769 final String[] list = getFilesDir().list();
770 return (list != null) ? list : EMPTY_FILE_LIST;
771 }
772
773 @Override
774 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Jeff Brown47847f32012-03-22 19:13:11 -0700775 return openOrCreateDatabase(name, mode, factory, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 }
777
778 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700779 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
780 DatabaseErrorHandler errorHandler) {
781 File f = validateFilePath(name, true);
Jeff Brown47847f32012-03-22 19:13:11 -0700782 int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
783 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
784 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
785 }
786 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
Vasu Nori74f170f2010-06-01 18:06:18 -0700787 setFilePermissionsFromMode(f.getPath(), mode, 0);
788 return db;
789 }
790
791 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800792 public boolean deleteDatabase(String name) {
793 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800794 File f = validateFilePath(name, false);
Jeff Brown79087e42012-03-01 19:52:44 -0800795 return SQLiteDatabase.deleteDatabase(f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 } catch (Exception e) {
797 }
798 return false;
799 }
800
801 @Override
802 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800803 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 }
805
806 @Override
807 public String[] databaseList() {
808 final String[] list = getDatabasesDir().list();
809 return (list != null) ? list : EMPTY_FILE_LIST;
810 }
811
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 private File getDatabasesDir() {
814 synchronized (mSync) {
815 if (mDatabasesDir == null) {
816 mDatabasesDir = new File(getDataDirFile(), "databases");
817 }
818 if (mDatabasesDir.getPath().equals("databases")) {
819 mDatabasesDir = new File("/data/system");
820 }
821 return mDatabasesDir;
822 }
823 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 @Override
826 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700827 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 }
829
830 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700831 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700832 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 }
834
835 @Override
836 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700837 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 }
839
840 @Override
841 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700842 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843 }
844
845 @Override
846 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700847 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 }
849
850 @Override
851 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700852 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 }
854
855 @Override
856 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700857 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800858 }
859
860 @Override
861 public void startActivity(Intent intent) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700862 startActivity(intent, null);
863 }
864
865 @Override
866 public void startActivity(Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
868 throw new AndroidRuntimeException(
869 "Calling startActivity() from outside of an Activity "
870 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
871 + " Is this really what you want?");
872 }
873 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700874 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700875 (Activity)null, intent, -1, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 }
877
878 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800879 public void startActivities(Intent[] intents) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700880 startActivities(intents, null);
881 }
882
883 @Override
884 public void startActivities(Intent[] intents, Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800885 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
886 throw new AndroidRuntimeException(
887 "Calling startActivities() from outside of an Activity "
888 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
889 + " Is this really what you want?");
890 }
891 mMainThread.getInstrumentation().execStartActivities(
892 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700893 (Activity)null, intents, options);
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800894 }
895
896 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700897 public void startIntentSender(IntentSender intent,
898 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
899 throws IntentSender.SendIntentException {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700900 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
901 }
902
903 @Override
904 public void startIntentSender(IntentSender intent, Intent fillInIntent,
905 int flagsMask, int flagsValues, int extraFlags, Bundle options)
906 throws IntentSender.SendIntentException {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700907 try {
908 String resolvedType = null;
909 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400910 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700911 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
912 }
913 int result = ActivityManagerNative.getDefault()
914 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
915 fillInIntent, resolvedType, null, null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700916 0, flagsMask, flagsValues, options);
917 if (result == ActivityManager.START_CANCELED) {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700918 throw new IntentSender.SendIntentException();
919 }
920 Instrumentation.checkStartActivityResult(result, null);
921 } catch (RemoteException e) {
922 }
923 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200924
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700925 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 public void sendBroadcast(Intent intent) {
927 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
928 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400929 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 ActivityManagerNative.getDefault().broadcastIntent(
931 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700932 Activity.RESULT_OK, null, null, null, false, false,
933 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 } catch (RemoteException e) {
935 }
936 }
937
Amith Yamasani67cf7d32012-02-16 14:31:23 -0800938 /** @hide */
939 @Override
940 public void sendBroadcast(Intent intent, int userId) {
941 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
942 try {
943 intent.setAllowFds(false);
944 ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
945 intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
946 userId);
947 } catch (RemoteException e) {
948 }
949 }
950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 @Override
952 public void sendBroadcast(Intent intent, String receiverPermission) {
953 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
954 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400955 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 ActivityManagerNative.getDefault().broadcastIntent(
957 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700958 Activity.RESULT_OK, null, null, receiverPermission, false, false,
959 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 } catch (RemoteException e) {
961 }
962 }
963
964 @Override
965 public void sendOrderedBroadcast(Intent intent,
966 String receiverPermission) {
967 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
968 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400969 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 ActivityManagerNative.getDefault().broadcastIntent(
971 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700972 Activity.RESULT_OK, null, null, receiverPermission, true, false,
973 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 } catch (RemoteException e) {
975 }
976 }
977
978 @Override
979 public void sendOrderedBroadcast(Intent intent,
980 String receiverPermission, BroadcastReceiver resultReceiver,
981 Handler scheduler, int initialCode, String initialData,
982 Bundle initialExtras) {
983 IIntentReceiver rd = null;
984 if (resultReceiver != null) {
985 if (mPackageInfo != null) {
986 if (scheduler == null) {
987 scheduler = mMainThread.getHandler();
988 }
989 rd = mPackageInfo.getReceiverDispatcher(
990 resultReceiver, getOuterContext(), scheduler,
991 mMainThread.getInstrumentation(), false);
992 } else {
993 if (scheduler == null) {
994 scheduler = mMainThread.getHandler();
995 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700996 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
998 }
999 }
1000 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1001 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001002 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001003 ActivityManagerNative.getDefault().broadcastIntent(
1004 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1005 initialCode, initialData, initialExtras, receiverPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -07001006 true, false, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 } catch (RemoteException e) {
1008 }
1009 }
1010
1011 @Override
1012 public void sendStickyBroadcast(Intent intent) {
1013 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1014 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001015 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 ActivityManagerNative.getDefault().broadcastIntent(
1017 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001018 Activity.RESULT_OK, null, null, null, false, true,
1019 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 } catch (RemoteException e) {
1021 }
1022 }
1023
1024 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001025 public void sendStickyOrderedBroadcast(Intent intent,
1026 BroadcastReceiver resultReceiver,
1027 Handler scheduler, int initialCode, String initialData,
1028 Bundle initialExtras) {
1029 IIntentReceiver rd = null;
1030 if (resultReceiver != null) {
1031 if (mPackageInfo != null) {
1032 if (scheduler == null) {
1033 scheduler = mMainThread.getHandler();
1034 }
1035 rd = mPackageInfo.getReceiverDispatcher(
1036 resultReceiver, getOuterContext(), scheduler,
1037 mMainThread.getInstrumentation(), false);
1038 } else {
1039 if (scheduler == null) {
1040 scheduler = mMainThread.getHandler();
1041 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001042 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001043 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1044 }
1045 }
1046 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1047 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001048 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001049 ActivityManagerNative.getDefault().broadcastIntent(
1050 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1051 initialCode, initialData, initialExtras, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001052 true, true, Binder.getOrigCallingUser());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001053 } catch (RemoteException e) {
1054 }
1055 }
1056
1057 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 public void removeStickyBroadcast(Intent intent) {
1059 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1060 if (resolvedType != null) {
1061 intent = new Intent(intent);
1062 intent.setDataAndType(intent.getData(), resolvedType);
1063 }
1064 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001065 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001066 ActivityManagerNative.getDefault().unbroadcastIntent(
Amith Yamasani742a6712011-05-04 14:49:28 -07001067 mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001068 } catch (RemoteException e) {
1069 }
1070 }
1071
1072 @Override
1073 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1074 return registerReceiver(receiver, filter, null, null);
1075 }
1076
1077 @Override
1078 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1079 String broadcastPermission, Handler scheduler) {
1080 return registerReceiverInternal(receiver, filter, broadcastPermission,
1081 scheduler, getOuterContext());
1082 }
1083
1084 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1085 IntentFilter filter, String broadcastPermission,
1086 Handler scheduler, Context context) {
1087 IIntentReceiver rd = null;
1088 if (receiver != null) {
1089 if (mPackageInfo != null && context != null) {
1090 if (scheduler == null) {
1091 scheduler = mMainThread.getHandler();
1092 }
1093 rd = mPackageInfo.getReceiverDispatcher(
1094 receiver, context, scheduler,
1095 mMainThread.getInstrumentation(), true);
1096 } else {
1097 if (scheduler == null) {
1098 scheduler = mMainThread.getHandler();
1099 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001100 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001101 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 }
1103 }
1104 try {
1105 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001106 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 rd, filter, broadcastPermission);
1108 } catch (RemoteException e) {
1109 return null;
1110 }
1111 }
1112
1113 @Override
1114 public void unregisterReceiver(BroadcastReceiver receiver) {
1115 if (mPackageInfo != null) {
1116 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1117 getOuterContext(), receiver);
1118 try {
1119 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1120 } catch (RemoteException e) {
1121 }
1122 } else {
1123 throw new RuntimeException("Not supported in system context");
1124 }
1125 }
1126
1127 @Override
1128 public ComponentName startService(Intent service) {
1129 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001130 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 ComponentName cn = ActivityManagerNative.getDefault().startService(
1132 mMainThread.getApplicationThread(), service,
1133 service.resolveTypeIfNeeded(getContentResolver()));
1134 if (cn != null && cn.getPackageName().equals("!")) {
1135 throw new SecurityException(
1136 "Not allowed to start service " + service
1137 + " without permission " + cn.getClassName());
1138 }
1139 return cn;
1140 } catch (RemoteException e) {
1141 return null;
1142 }
1143 }
1144
1145 @Override
1146 public boolean stopService(Intent service) {
1147 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001148 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 int res = ActivityManagerNative.getDefault().stopService(
1150 mMainThread.getApplicationThread(), service,
1151 service.resolveTypeIfNeeded(getContentResolver()));
1152 if (res < 0) {
1153 throw new SecurityException(
1154 "Not allowed to stop service " + service);
1155 }
1156 return res != 0;
1157 } catch (RemoteException e) {
1158 return false;
1159 }
1160 }
1161
1162 @Override
1163 public boolean bindService(Intent service, ServiceConnection conn,
1164 int flags) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001165 return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
1166 }
1167
1168 /** @hide */
1169 @Override
1170 public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 IServiceConnection sd;
1172 if (mPackageInfo != null) {
1173 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1174 mMainThread.getHandler(), flags);
1175 } else {
1176 throw new RuntimeException("Not supported in system context");
1177 }
1178 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001179 IBinder token = getActivityToken();
1180 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1181 && mPackageInfo.getApplicationInfo().targetSdkVersion
1182 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1183 flags |= BIND_WAIVE_PRIORITY;
1184 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001185 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001186 int res = ActivityManagerNative.getDefault().bindService(
1187 mMainThread.getApplicationThread(), getActivityToken(),
1188 service, service.resolveTypeIfNeeded(getContentResolver()),
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001189 sd, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 if (res < 0) {
1191 throw new SecurityException(
1192 "Not allowed to bind to service " + service);
1193 }
1194 return res != 0;
1195 } catch (RemoteException e) {
1196 return false;
1197 }
1198 }
1199
1200 @Override
1201 public void unbindService(ServiceConnection conn) {
1202 if (mPackageInfo != null) {
1203 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1204 getOuterContext(), conn);
1205 try {
1206 ActivityManagerNative.getDefault().unbindService(sd);
1207 } catch (RemoteException e) {
1208 }
1209 } else {
1210 throw new RuntimeException("Not supported in system context");
1211 }
1212 }
1213
1214 @Override
1215 public boolean startInstrumentation(ComponentName className,
1216 String profileFile, Bundle arguments) {
1217 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001218 if (arguments != null) {
1219 arguments.setAllowFds(false);
1220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 return ActivityManagerNative.getDefault().startInstrumentation(
1222 className, profileFile, 0, arguments, null);
1223 } catch (RemoteException e) {
1224 // System has crashed, nothing we can do.
1225 }
1226 return false;
1227 }
1228
1229 @Override
1230 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001231 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1232 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 }
1234
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001235 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001236 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 }
1238
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001239 /* package */ static DropBoxManager createDropBoxManager() {
1240 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1241 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001242 if (service == null) {
1243 // Don't return a DropBoxManager that will NPE upon use.
1244 // This also avoids caching a broken DropBoxManager in
1245 // getDropBoxManager during early boot, before the
1246 // DROPBOX_SERVICE is registered.
1247 return null;
1248 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001249 return new DropBoxManager(service);
1250 }
1251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 @Override
1253 public int checkPermission(String permission, int pid, int uid) {
1254 if (permission == null) {
1255 throw new IllegalArgumentException("permission is null");
1256 }
1257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 try {
1259 return ActivityManagerNative.getDefault().checkPermission(
1260 permission, pid, uid);
1261 } catch (RemoteException e) {
1262 return PackageManager.PERMISSION_DENIED;
1263 }
1264 }
1265
1266 @Override
1267 public int checkCallingPermission(String permission) {
1268 if (permission == null) {
1269 throw new IllegalArgumentException("permission is null");
1270 }
1271
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 int pid = Binder.getCallingPid();
1273 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001274 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275 }
1276 return PackageManager.PERMISSION_DENIED;
1277 }
1278
1279 @Override
1280 public int checkCallingOrSelfPermission(String permission) {
1281 if (permission == null) {
1282 throw new IllegalArgumentException("permission is null");
1283 }
1284
1285 return checkPermission(permission, Binder.getCallingPid(),
1286 Binder.getCallingUid());
1287 }
1288
1289 private void enforce(
1290 String permission, int resultOfCheck,
1291 boolean selfToo, int uid, String message) {
1292 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1293 throw new SecurityException(
1294 (message != null ? (message + ": ") : "") +
1295 (selfToo
1296 ? "Neither user " + uid + " nor current process has "
1297 : "User " + uid + " does not have ") +
1298 permission +
1299 ".");
1300 }
1301 }
1302
1303 public void enforcePermission(
1304 String permission, int pid, int uid, String message) {
1305 enforce(permission,
1306 checkPermission(permission, pid, uid),
1307 false,
1308 uid,
1309 message);
1310 }
1311
1312 public void enforceCallingPermission(String permission, String message) {
1313 enforce(permission,
1314 checkCallingPermission(permission),
1315 false,
1316 Binder.getCallingUid(),
1317 message);
1318 }
1319
1320 public void enforceCallingOrSelfPermission(
1321 String permission, String message) {
1322 enforce(permission,
1323 checkCallingOrSelfPermission(permission),
1324 true,
1325 Binder.getCallingUid(),
1326 message);
1327 }
1328
1329 @Override
1330 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1331 try {
1332 ActivityManagerNative.getDefault().grantUriPermission(
1333 mMainThread.getApplicationThread(), toPackage, uri,
1334 modeFlags);
1335 } catch (RemoteException e) {
1336 }
1337 }
1338
1339 @Override
1340 public void revokeUriPermission(Uri uri, int modeFlags) {
1341 try {
1342 ActivityManagerNative.getDefault().revokeUriPermission(
1343 mMainThread.getApplicationThread(), uri,
1344 modeFlags);
1345 } catch (RemoteException e) {
1346 }
1347 }
1348
1349 @Override
1350 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 try {
1352 return ActivityManagerNative.getDefault().checkUriPermission(
1353 uri, pid, uid, modeFlags);
1354 } catch (RemoteException e) {
1355 return PackageManager.PERMISSION_DENIED;
1356 }
1357 }
1358
1359 @Override
1360 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 int pid = Binder.getCallingPid();
1362 if (pid != Process.myPid()) {
1363 return checkUriPermission(uri, pid,
1364 Binder.getCallingUid(), modeFlags);
1365 }
1366 return PackageManager.PERMISSION_DENIED;
1367 }
1368
1369 @Override
1370 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1371 return checkUriPermission(uri, Binder.getCallingPid(),
1372 Binder.getCallingUid(), modeFlags);
1373 }
1374
1375 @Override
1376 public int checkUriPermission(Uri uri, String readPermission,
1377 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001378 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1380 + readPermission + " writePermission=" + writePermission
1381 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1382 }
1383 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1384 if (readPermission == null
1385 || checkPermission(readPermission, pid, uid)
1386 == PackageManager.PERMISSION_GRANTED) {
1387 return PackageManager.PERMISSION_GRANTED;
1388 }
1389 }
1390 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1391 if (writePermission == null
1392 || checkPermission(writePermission, pid, uid)
1393 == PackageManager.PERMISSION_GRANTED) {
1394 return PackageManager.PERMISSION_GRANTED;
1395 }
1396 }
1397 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1398 : PackageManager.PERMISSION_DENIED;
1399 }
1400
1401 private String uriModeFlagToString(int uriModeFlags) {
1402 switch (uriModeFlags) {
1403 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1404 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1405 return "read and write";
1406 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1407 return "read";
1408 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1409 return "write";
1410 }
1411 throw new IllegalArgumentException(
1412 "Unknown permission mode flags: " + uriModeFlags);
1413 }
1414
1415 private void enforceForUri(
1416 int modeFlags, int resultOfCheck, boolean selfToo,
1417 int uid, Uri uri, String message) {
1418 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1419 throw new SecurityException(
1420 (message != null ? (message + ": ") : "") +
1421 (selfToo
1422 ? "Neither user " + uid + " nor current process has "
1423 : "User " + uid + " does not have ") +
1424 uriModeFlagToString(modeFlags) +
1425 " permission on " +
1426 uri +
1427 ".");
1428 }
1429 }
1430
1431 public void enforceUriPermission(
1432 Uri uri, int pid, int uid, int modeFlags, String message) {
1433 enforceForUri(
1434 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1435 false, uid, uri, message);
1436 }
1437
1438 public void enforceCallingUriPermission(
1439 Uri uri, int modeFlags, String message) {
1440 enforceForUri(
1441 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001442 false,
1443 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 }
1445
1446 public void enforceCallingOrSelfUriPermission(
1447 Uri uri, int modeFlags, String message) {
1448 enforceForUri(
1449 modeFlags,
1450 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1451 Binder.getCallingUid(), uri, message);
1452 }
1453
1454 public void enforceUriPermission(
1455 Uri uri, String readPermission, String writePermission,
1456 int pid, int uid, int modeFlags, String message) {
1457 enforceForUri(modeFlags,
1458 checkUriPermission(
1459 uri, readPermission, writePermission, pid, uid,
1460 modeFlags),
1461 false,
1462 uid,
1463 uri,
1464 message);
1465 }
1466
1467 @Override
1468 public Context createPackageContext(String packageName, int flags)
1469 throws PackageManager.NameNotFoundException {
1470 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001471 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 }
1473
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001474 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001475 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001477 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001478 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001479 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if (c.mResources != null) {
1481 return c;
1482 }
1483 }
1484
1485 // Should be a better exception.
1486 throw new PackageManager.NameNotFoundException(
1487 "Application package " + packageName + " not found");
1488 }
1489
Romain Guy870e09f2009-07-06 16:35:25 -07001490 @Override
1491 public boolean isRestricted() {
1492 return mRestricted;
1493 }
1494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 private File getDataDirFile() {
1496 if (mPackageInfo != null) {
1497 return mPackageInfo.getDataDirFile();
1498 }
1499 throw new RuntimeException("Not supported in system context");
1500 }
1501
1502 @Override
1503 public File getDir(String name, int mode) {
1504 name = "app_" + name;
1505 File file = makeFilename(getDataDirFile(), name);
1506 if (!file.exists()) {
1507 file.mkdir();
1508 setFilePermissionsFromMode(file.getPath(), mode,
1509 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1510 }
1511 return file;
1512 }
1513
Dianne Hackborn21556372010-02-04 16:34:40 -08001514 static ContextImpl createSystemContext(ActivityThread mainThread) {
1515 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 context.init(Resources.getSystem(), mainThread);
1517 return context;
1518 }
1519
Dianne Hackborn21556372010-02-04 16:34:40 -08001520 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 mOuterContext = this;
1522 }
1523
1524 /**
1525 * Create a new ApplicationContext from an existing one. The new one
1526 * works and operates the same as the one it is copying.
1527 *
1528 * @param context Existing application context.
1529 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001530 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001532 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 mResources = context.mResources;
1534 mMainThread = context.mMainThread;
1535 mContentResolver = context.mContentResolver;
1536 mOuterContext = this;
1537 }
1538
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001539 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001541 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001542 }
1543
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001544 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001545 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001546 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001547 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001548 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001550
Dianne Hackborn559a7872010-04-07 18:19:41 -07001551 if (mResources != null && container != null
1552 && container.getCompatibilityInfo().applicationScale !=
1553 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001554 if (DEBUG) {
1555 Log.d(TAG, "loaded context has different scaling. Using container's" +
1556 " compatiblity info:" + container.getDisplayMetrics());
1557 }
1558 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001559 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001560 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 mMainThread = mainThread;
1562 mContentResolver = new ApplicationContentResolver(this, mainThread);
1563
1564 setActivityToken(activityToken);
1565 }
1566
1567 final void init(Resources resources, ActivityThread mainThread) {
1568 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001569 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 mResources = resources;
1571 mMainThread = mainThread;
1572 mContentResolver = new ApplicationContentResolver(this, mainThread);
1573 }
1574
1575 final void scheduleFinalCleanup(String who, String what) {
1576 mMainThread.scheduleContextCleanup(this, who, what);
1577 }
1578
1579 final void performFinalCleanup(String who, String what) {
1580 //Log.i(TAG, "Cleanup up context: " + this);
1581 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1582 }
1583
1584 final Context getReceiverRestrictedContext() {
1585 if (mReceiverRestrictedContext != null) {
1586 return mReceiverRestrictedContext;
1587 }
1588 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1589 }
1590
1591 final void setActivityToken(IBinder token) {
1592 mActivityToken = token;
1593 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 final void setOuterContext(Context context) {
1596 mOuterContext = context;
1597 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 final Context getOuterContext() {
1600 return mOuterContext;
1601 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 final IBinder getActivityToken() {
1604 return mActivityToken;
1605 }
1606
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001607 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 int extraPermissions) {
1609 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1610 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1611 |extraPermissions;
1612 if ((mode&MODE_WORLD_READABLE) != 0) {
1613 perms |= FileUtils.S_IROTH;
1614 }
1615 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1616 perms |= FileUtils.S_IWOTH;
1617 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001618 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001619 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1620 + ", perms=0x" + Integer.toHexString(perms));
1621 }
1622 FileUtils.setPermissions(name, perms, -1, -1);
1623 }
1624
Oscar Montemayora8529f62009-11-18 10:14:20 -08001625 private File validateFilePath(String name, boolean createDirectory) {
1626 File dir;
1627 File f;
1628
1629 if (name.charAt(0) == File.separatorChar) {
1630 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1631 dir = new File(dirPath);
1632 name = name.substring(name.lastIndexOf(File.separatorChar));
1633 f = new File(dir, name);
1634 } else {
1635 dir = getDatabasesDir();
1636 f = makeFilename(dir, name);
1637 }
1638
1639 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1640 FileUtils.setPermissions(dir.getPath(),
1641 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1642 -1, -1);
1643 }
1644
1645 return f;
1646 }
1647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 private File makeFilename(File base, String name) {
1649 if (name.indexOf(File.separatorChar) < 0) {
1650 return new File(base, name);
1651 }
1652 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001653 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 }
1655
1656 // ----------------------------------------------------------------------
1657 // ----------------------------------------------------------------------
1658 // ----------------------------------------------------------------------
1659
1660 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001661 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 super(context);
1663 mMainThread = mainThread;
1664 }
1665
1666 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001667 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 return mMainThread.acquireProvider(context, name);
1669 }
1670
1671 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001672 protected IContentProvider acquireExistingProvider(Context context, String name) {
1673 return mMainThread.acquireExistingProvider(context, name);
1674 }
1675
1676 @Override
1677 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 return mMainThread.releaseProvider(provider);
1679 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001681 private final ActivityThread mMainThread;
1682 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683}