blob: 5ffceb3f74e67b781ed31187319187dc9476ce0d [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;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080048import android.hardware.usb.IUsbManager;
49import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080050import android.location.CountryDetector;
51import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.location.ILocationManager;
53import android.location.LocationManager;
54import android.media.AudioManager;
55import android.net.ConnectivityManager;
56import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070057import android.net.INetworkPolicyManager;
58import android.net.NetworkPolicyManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070059import android.net.ThrottleManager;
60import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.net.Uri;
Irfan Sheriff7d024d32012-03-22 17:01:39 -070062import android.net.nsd.INsdManager;
63import android.net.nsd.NsdManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.net.wifi.IWifiManager;
65import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070066import android.net.wifi.p2p.IWifiP2pManager;
67import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080068import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.os.Binder;
70import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080071import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080072import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.os.FileUtils;
74import android.os.Handler;
75import android.os.IBinder;
76import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070077import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.os.PowerManager;
79import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070080import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.ServiceManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070082import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080084import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070086import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.util.AndroidRuntimeException;
88import android.util.Log;
89import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070091import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090093import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070094import android.accounts.AccountManager;
95import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080096import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080097import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import java.io.File;
100import java.io.FileInputStream;
101import java.io.FileNotFoundException;
102import java.io.FileOutputStream;
103import java.io.IOException;
104import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import java.util.ArrayList;
106import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108class ReceiverRestrictedContext extends ContextWrapper {
109 ReceiverRestrictedContext(Context base) {
110 super(base);
111 }
112
113 @Override
114 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
115 return registerReceiver(receiver, filter, null, null);
116 }
117
118 @Override
119 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
120 String broadcastPermission, Handler scheduler) {
121 throw new ReceiverCallNotAllowedException(
122 "IntentReceiver components are not allowed to register to receive intents");
123 //ex.fillInStackTrace();
124 //Log.e("IntentReceiver", ex.getMessage(), ex);
125 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
126 // scheduler);
127 }
128
129 @Override
130 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
131 throw new ReceiverCallNotAllowedException(
132 "IntentReceiver components are not allowed to bind to services");
133 //ex.fillInStackTrace();
134 //Log.e("IntentReceiver", ex.getMessage(), ex);
135 //return mContext.bindService(service, interfaceName, conn, flags);
136 }
137}
138
139/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800140 * Common implementation of Context API, which provides the base
141 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800143class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700145 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700147 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
148 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700150 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700151 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 private Resources mResources;
153 /*package*/ ActivityThread mMainThread;
154 private Context mOuterContext;
155 private IBinder mActivityToken = null;
156 private ApplicationContentResolver mContentResolver;
157 private int mThemeResource = 0;
158 private Resources.Theme mTheme = null;
159 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700161 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
163 private final Object mSync = new Object();
164
165 private File mDatabasesDir;
166 private File mPreferencesDir;
167 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800169 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800170 private File mExternalFilesDir;
171 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 private static final String[] EMPTY_FILE_LIST = {};
174
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800175 /**
176 * Override this class when the system service constructor needs a
177 * ContextImpl. Else, use StaticServiceFetcher below.
178 */
179 /*package*/ static class ServiceFetcher {
180 int mContextCacheIndex = -1;
181
182 /**
183 * Main entrypoint; only override if you don't need caching.
184 */
185 public Object getService(ContextImpl ctx) {
186 ArrayList<Object> cache = ctx.mServiceCache;
187 Object service;
188 synchronized (cache) {
189 if (cache.size() == 0) {
190 // Initialize the cache vector on first access.
191 // At this point sNextPerContextServiceCacheIndex
192 // is the number of potential services that are
193 // cached per-Context.
194 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
195 cache.add(null);
196 }
197 } else {
198 service = cache.get(mContextCacheIndex);
199 if (service != null) {
200 return service;
201 }
202 }
203 service = createService(ctx);
204 cache.set(mContextCacheIndex, service);
205 return service;
206 }
207 }
208
209 /**
210 * Override this to create a new per-Context instance of the
211 * service. getService() will handle locking and caching.
212 */
213 public Object createService(ContextImpl ctx) {
214 throw new RuntimeException("Not implemented");
215 }
216 }
217
218 /**
219 * Override this class for services to be cached process-wide.
220 */
221 abstract static class StaticServiceFetcher extends ServiceFetcher {
222 private Object mCachedInstance;
223
224 @Override
225 public final Object getService(ContextImpl unused) {
226 synchronized (StaticServiceFetcher.this) {
227 Object service = mCachedInstance;
228 if (service != null) {
229 return service;
230 }
231 return mCachedInstance = createStaticService();
232 }
233 }
234
235 public abstract Object createStaticService();
236 }
237
238 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
239 new HashMap<String, ServiceFetcher>();
240
241 private static int sNextPerContextServiceCacheIndex = 0;
242 private static void registerService(String serviceName, ServiceFetcher fetcher) {
243 if (!(fetcher instanceof StaticServiceFetcher)) {
244 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
245 }
246 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
247 }
248
249 // This one's defined separately and given a variable name so it
250 // can be re-used by getWallpaperManager(), avoiding a HashMap
251 // lookup.
252 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
253 public Object createService(ContextImpl ctx) {
254 return new WallpaperManager(ctx.getOuterContext(),
255 ctx.mMainThread.getHandler());
256 }};
257
258 static {
259 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
260 public Object getService(ContextImpl ctx) {
261 return AccessibilityManager.getInstance(ctx);
262 }});
263
264 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
265 public Object createService(ContextImpl ctx) {
266 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
267 IAccountManager service = IAccountManager.Stub.asInterface(b);
268 return new AccountManager(ctx, service);
269 }});
270
271 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
272 public Object createService(ContextImpl ctx) {
273 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
274 }});
275
276 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
277 public Object createStaticService() {
278 IBinder b = ServiceManager.getService(ALARM_SERVICE);
279 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
280 return new AlarmManager(service);
281 }});
282
283 registerService(AUDIO_SERVICE, new ServiceFetcher() {
284 public Object createService(ContextImpl ctx) {
285 return new AudioManager(ctx);
286 }});
287
288 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
289 public Object createService(ContextImpl ctx) {
290 return new ClipboardManager(ctx.getOuterContext(),
291 ctx.mMainThread.getHandler());
292 }});
293
294 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
295 public Object createStaticService() {
296 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
297 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
298 }});
299
300 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
301 public Object createStaticService() {
302 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
303 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
304 }});
305
306 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
307 public Object createService(ContextImpl ctx) {
308 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
309 }});
310
311 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
312 public Object createService(ContextImpl ctx) {
313 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
314 }});
315
Nick Pellyd2507462010-12-13 12:22:34 -0800316 registerService(NFC_SERVICE, new ServiceFetcher() {
317 public Object createService(ContextImpl ctx) {
318 return new NfcManager(ctx);
319 }});
320
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800321 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
322 public Object createStaticService() {
323 return createDropBoxManager();
324 }});
325
326 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
327 public Object createService(ContextImpl ctx) {
328 return InputMethodManager.getInstance(ctx);
329 }});
330
satok988323c2011-06-22 16:38:13 +0900331 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
332 public Object createService(ContextImpl ctx) {
333 return TextServicesManager.getInstance();
334 }});
335
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800336 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
337 public Object getService(ContextImpl ctx) {
338 // TODO: why isn't this caching it? It wasn't
339 // before, so I'm preserving the old behavior and
340 // using getService(), instead of createService()
341 // which would do the caching.
342 return new KeyguardManager();
343 }});
344
345 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
346 public Object createService(ContextImpl ctx) {
347 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
348 }});
349
350 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
351 public Object createStaticService() {
352 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
353 return new LocationManager(ILocationManager.Stub.asInterface(b));
354 }});
355
Jeff Sharkey1a303952011-06-16 13:04:20 -0700356 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
357 @Override
358 public Object createService(ContextImpl ctx) {
359 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
360 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
361 }
362 });
363
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800364 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
365 public Object createService(ContextImpl ctx) {
366 final Context outerContext = ctx.getOuterContext();
367 return new NotificationManager(
368 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800369 Resources.selectSystemTheme(0,
370 outerContext.getApplicationInfo().targetSdkVersion,
371 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700372 com.android.internal.R.style.Theme_Holo_Dialog,
373 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800374 ctx.mMainThread.getHandler());
375 }});
376
Irfan Sheriff7d024d32012-03-22 17:01:39 -0700377 registerService(NSD_SERVICE, new ServiceFetcher() {
378 @Override
379 public Object createService(ContextImpl ctx) {
380 IBinder b = ServiceManager.getService(NSD_SERVICE);
381 INsdManager service = INsdManager.Stub.asInterface(b);
382 return new NsdManager(service);
383 }});
384
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800385 // Note: this was previously cached in a static variable, but
386 // constructed using mMainThread.getHandler(), so converting
387 // it to be a regular Context-cached service...
388 registerService(POWER_SERVICE, new ServiceFetcher() {
389 public Object createService(ContextImpl ctx) {
390 IBinder b = ServiceManager.getService(POWER_SERVICE);
391 IPowerManager service = IPowerManager.Stub.asInterface(b);
392 return new PowerManager(service, ctx.mMainThread.getHandler());
393 }});
394
395 registerService(SEARCH_SERVICE, new ServiceFetcher() {
396 public Object createService(ContextImpl ctx) {
397 return new SearchManager(ctx.getOuterContext(),
398 ctx.mMainThread.getHandler());
399 }});
400
401 registerService(SENSOR_SERVICE, new ServiceFetcher() {
402 public Object createService(ContextImpl ctx) {
403 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
404 }});
405
406 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
407 public Object createService(ContextImpl ctx) {
408 return new StatusBarManager(ctx.getOuterContext());
409 }});
410
411 registerService(STORAGE_SERVICE, new ServiceFetcher() {
412 public Object createService(ContextImpl ctx) {
413 try {
414 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
415 } catch (RemoteException rex) {
416 Log.e(TAG, "Failed to create StorageManager", rex);
417 return null;
418 }
419 }});
420
421 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
422 public Object createService(ContextImpl ctx) {
423 return new TelephonyManager(ctx.getOuterContext());
424 }});
425
426 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
427 public Object createStaticService() {
428 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
429 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
430 }});
431
432 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
433 public Object createService(ContextImpl ctx) {
434 return new UiModeManager();
435 }});
436
Mike Lockwood3a68b832011-03-08 10:08:59 -0500437 registerService(USB_SERVICE, new ServiceFetcher() {
438 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500439 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500440 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500441 }});
442
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -0400443 registerService(SERIAL_SERVICE, new ServiceFetcher() {
444 public Object createService(ContextImpl ctx) {
445 IBinder b = ServiceManager.getService(SERIAL_SERVICE);
446 return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
447 }});
448
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800449 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
450 public Object createService(ContextImpl ctx) {
451 return new Vibrator();
452 }});
453
454 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
455
456 registerService(WIFI_SERVICE, new ServiceFetcher() {
457 public Object createService(ContextImpl ctx) {
458 IBinder b = ServiceManager.getService(WIFI_SERVICE);
459 IWifiManager service = IWifiManager.Stub.asInterface(b);
460 return new WifiManager(service, ctx.mMainThread.getHandler());
461 }});
462
repo sync55bc5f32011-06-24 14:23:07 -0700463 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
464 public Object createService(ContextImpl ctx) {
465 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
466 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
467 return new WifiP2pManager(service);
468 }});
469
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800470 registerService(WINDOW_SERVICE, new ServiceFetcher() {
471 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700472 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800473 }});
474 }
475
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700476 static ContextImpl getImpl(Context context) {
477 Context nextContext;
478 while ((context instanceof ContextWrapper) &&
479 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
480 context = nextContext;
481 }
482 return (ContextImpl)context;
483 }
484
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800485 // The system service cache for the system services that are
486 // cached per-ContextImpl. Package-scoped to avoid accessor
487 // methods.
488 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 @Override
491 public AssetManager getAssets() {
492 return mResources.getAssets();
493 }
494
495 @Override
496 public Resources getResources() {
497 return mResources;
498 }
499
500 @Override
501 public PackageManager getPackageManager() {
502 if (mPackageManager != null) {
503 return mPackageManager;
504 }
505
506 IPackageManager pm = ActivityThread.getPackageManager();
507 if (pm != null) {
508 // Doesn't matter if we make more than one instance.
509 return (mPackageManager = new ApplicationPackageManager(this, pm));
510 }
511
512 return null;
513 }
514
515 @Override
516 public ContentResolver getContentResolver() {
517 return mContentResolver;
518 }
519
520 @Override
521 public Looper getMainLooper() {
522 return mMainThread.getLooper();
523 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525 @Override
526 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700527 return (mPackageInfo != null) ?
528 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200530
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531 @Override
532 public void setTheme(int resid) {
533 mThemeResource = resid;
534 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800537 public int getThemeResId() {
538 return mThemeResource;
539 }
540
541 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 public Resources.Theme getTheme() {
543 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800544 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
545 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 mTheme = mResources.newTheme();
547 mTheme.applyStyle(mThemeResource, true);
548 }
549 return mTheme;
550 }
551
552 @Override
553 public ClassLoader getClassLoader() {
554 return mPackageInfo != null ?
555 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
556 }
557
558 @Override
559 public String getPackageName() {
560 if (mPackageInfo != null) {
561 return mPackageInfo.getPackageName();
562 }
563 throw new RuntimeException("Not supported in system context");
564 }
565
566 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700567 public ApplicationInfo getApplicationInfo() {
568 if (mPackageInfo != null) {
569 return mPackageInfo.getApplicationInfo();
570 }
571 throw new RuntimeException("Not supported in system context");
572 }
573
574 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 public String getPackageResourcePath() {
576 if (mPackageInfo != null) {
577 return mPackageInfo.getResDir();
578 }
579 throw new RuntimeException("Not supported in system context");
580 }
581
582 @Override
583 public String getPackageCodePath() {
584 if (mPackageInfo != null) {
585 return mPackageInfo.getAppDir();
586 }
587 throw new RuntimeException("Not supported in system context");
588 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200589
Joe Onorato23ecae32009-06-10 17:07:15 -0700590 public File getSharedPrefsFile(String name) {
591 return makeFilename(getPreferencesDir(), name + ".xml");
592 }
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 @Override
595 public SharedPreferences getSharedPreferences(String name, int mode) {
596 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700598 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700599 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800600 File prefsFile = getSharedPrefsFile(name);
601 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700602 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700603 return sp;
604 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800606 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
607 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
608 // If somebody else (some other process) changed the prefs
609 // file behind our back, we reload it. This has been the
610 // historical (if undocumented) behavior.
611 sp.startReloadIfChangedUnexpectedly();
612 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700613 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800614 }
615
616 private File getPreferencesDir() {
617 synchronized (mSync) {
618 if (mPreferencesDir == null) {
619 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
620 }
621 return mPreferencesDir;
622 }
623 }
624
625 @Override
626 public FileInputStream openFileInput(String name)
627 throws FileNotFoundException {
628 File f = makeFilename(getFilesDir(), name);
629 return new FileInputStream(f);
630 }
631
632 @Override
633 public FileOutputStream openFileOutput(String name, int mode)
634 throws FileNotFoundException {
635 final boolean append = (mode&MODE_APPEND) != 0;
636 File f = makeFilename(getFilesDir(), name);
637 try {
638 FileOutputStream fos = new FileOutputStream(f, append);
639 setFilePermissionsFromMode(f.getPath(), mode, 0);
640 return fos;
641 } catch (FileNotFoundException e) {
642 }
643
644 File parent = f.getParentFile();
645 parent.mkdir();
646 FileUtils.setPermissions(
647 parent.getPath(),
648 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
649 -1, -1);
650 FileOutputStream fos = new FileOutputStream(f, append);
651 setFilePermissionsFromMode(f.getPath(), mode, 0);
652 return fos;
653 }
654
655 @Override
656 public boolean deleteFile(String name) {
657 File f = makeFilename(getFilesDir(), name);
658 return f.delete();
659 }
660
661 @Override
662 public File getFilesDir() {
663 synchronized (mSync) {
664 if (mFilesDir == null) {
665 mFilesDir = new File(getDataDirFile(), "files");
666 }
667 if (!mFilesDir.exists()) {
668 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200669 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 return null;
671 }
672 FileUtils.setPermissions(
673 mFilesDir.getPath(),
674 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
675 -1, -1);
676 }
677 return mFilesDir;
678 }
679 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800682 public File getExternalFilesDir(String type) {
683 synchronized (mSync) {
684 if (mExternalFilesDir == null) {
685 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
686 getPackageName());
687 }
688 if (!mExternalFilesDir.exists()) {
689 try {
690 (new File(Environment.getExternalStorageAndroidDataDir(),
691 ".nomedia")).createNewFile();
692 } catch (IOException e) {
693 }
694 if (!mExternalFilesDir.mkdirs()) {
695 Log.w(TAG, "Unable to create external files directory");
696 return null;
697 }
698 }
699 if (type == null) {
700 return mExternalFilesDir;
701 }
702 File dir = new File(mExternalFilesDir, type);
703 if (!dir.exists()) {
704 if (!dir.mkdirs()) {
705 Log.w(TAG, "Unable to create external media directory " + dir);
706 return null;
707 }
708 }
709 return dir;
710 }
711 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200712
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800713 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800714 public File getObbDir() {
715 synchronized (mSync) {
716 if (mObbDir == null) {
717 mObbDir = Environment.getExternalStorageAppObbDirectory(
718 getPackageName());
719 }
720 return mObbDir;
721 }
722 }
723
724 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 public File getCacheDir() {
726 synchronized (mSync) {
727 if (mCacheDir == null) {
728 mCacheDir = new File(getDataDirFile(), "cache");
729 }
730 if (!mCacheDir.exists()) {
731 if(!mCacheDir.mkdirs()) {
732 Log.w(TAG, "Unable to create cache directory");
733 return null;
734 }
735 FileUtils.setPermissions(
736 mCacheDir.getPath(),
737 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
738 -1, -1);
739 }
740 }
741 return mCacheDir;
742 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200743
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800744 @Override
745 public File getExternalCacheDir() {
746 synchronized (mSync) {
747 if (mExternalCacheDir == null) {
748 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
749 getPackageName());
750 }
751 if (!mExternalCacheDir.exists()) {
752 try {
753 (new File(Environment.getExternalStorageAndroidDataDir(),
754 ".nomedia")).createNewFile();
755 } catch (IOException e) {
756 }
757 if (!mExternalCacheDir.mkdirs()) {
758 Log.w(TAG, "Unable to create external cache directory");
759 return null;
760 }
761 }
762 return mExternalCacheDir;
763 }
764 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 @Override
767 public File getFileStreamPath(String name) {
768 return makeFilename(getFilesDir(), name);
769 }
770
771 @Override
772 public String[] fileList() {
773 final String[] list = getFilesDir().list();
774 return (list != null) ? list : EMPTY_FILE_LIST;
775 }
776
777 @Override
778 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Jeff Brown47847f32012-03-22 19:13:11 -0700779 return openOrCreateDatabase(name, mode, factory, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 }
781
782 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700783 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
784 DatabaseErrorHandler errorHandler) {
785 File f = validateFilePath(name, true);
Jeff Brown47847f32012-03-22 19:13:11 -0700786 int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
787 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
788 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
789 }
790 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
Vasu Nori74f170f2010-06-01 18:06:18 -0700791 setFilePermissionsFromMode(f.getPath(), mode, 0);
792 return db;
793 }
794
795 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800796 public boolean deleteDatabase(String name) {
797 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800798 File f = validateFilePath(name, false);
Jeff Brown79087e42012-03-01 19:52:44 -0800799 return SQLiteDatabase.deleteDatabase(f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 } catch (Exception e) {
801 }
802 return false;
803 }
804
805 @Override
806 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800807 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800808 }
809
810 @Override
811 public String[] databaseList() {
812 final String[] list = getDatabasesDir().list();
813 return (list != null) ? list : EMPTY_FILE_LIST;
814 }
815
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 private File getDatabasesDir() {
818 synchronized (mSync) {
819 if (mDatabasesDir == null) {
820 mDatabasesDir = new File(getDataDirFile(), "databases");
821 }
822 if (mDatabasesDir.getPath().equals("databases")) {
823 mDatabasesDir = new File("/data/system");
824 }
825 return mDatabasesDir;
826 }
827 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 @Override
830 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700831 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 }
833
834 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700835 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700836 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 }
838
839 @Override
840 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700841 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 }
843
844 @Override
845 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700846 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 }
848
849 @Override
850 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700851 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 }
853
854 @Override
855 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700856 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 }
858
859 @Override
860 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700861 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 }
863
864 @Override
865 public void startActivity(Intent intent) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700866 startActivity(intent, null);
867 }
868
869 @Override
870 public void startActivity(Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
872 throw new AndroidRuntimeException(
873 "Calling startActivity() from outside of an Activity "
874 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
875 + " Is this really what you want?");
876 }
877 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700878 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700879 (Activity)null, intent, -1, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 }
881
882 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800883 public void startActivities(Intent[] intents) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700884 startActivities(intents, null);
885 }
886
887 @Override
888 public void startActivities(Intent[] intents, Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800889 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
890 throw new AndroidRuntimeException(
891 "Calling startActivities() from outside of an Activity "
892 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
893 + " Is this really what you want?");
894 }
895 mMainThread.getInstrumentation().execStartActivities(
896 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700897 (Activity)null, intents, options);
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800898 }
899
900 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700901 public void startIntentSender(IntentSender intent,
902 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
903 throws IntentSender.SendIntentException {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700904 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
905 }
906
907 @Override
908 public void startIntentSender(IntentSender intent, Intent fillInIntent,
909 int flagsMask, int flagsValues, int extraFlags, Bundle options)
910 throws IntentSender.SendIntentException {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700911 try {
912 String resolvedType = null;
913 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400914 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700915 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
916 }
917 int result = ActivityManagerNative.getDefault()
918 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
919 fillInIntent, resolvedType, null, null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700920 0, flagsMask, flagsValues, options);
921 if (result == ActivityManager.START_CANCELED) {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700922 throw new IntentSender.SendIntentException();
923 }
924 Instrumentation.checkStartActivityResult(result, null);
925 } catch (RemoteException e) {
926 }
927 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200928
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700929 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 public void sendBroadcast(Intent intent) {
931 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
932 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400933 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 ActivityManagerNative.getDefault().broadcastIntent(
935 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700936 Activity.RESULT_OK, null, null, null, false, false,
937 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 } catch (RemoteException e) {
939 }
940 }
941
Amith Yamasani67cf7d32012-02-16 14:31:23 -0800942 /** @hide */
943 @Override
944 public void sendBroadcast(Intent intent, int userId) {
945 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
946 try {
947 intent.setAllowFds(false);
948 ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
949 intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
950 userId);
951 } catch (RemoteException e) {
952 }
953 }
954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 @Override
956 public void sendBroadcast(Intent intent, String receiverPermission) {
957 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
958 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400959 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 ActivityManagerNative.getDefault().broadcastIntent(
961 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700962 Activity.RESULT_OK, null, null, receiverPermission, false, false,
963 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 } catch (RemoteException e) {
965 }
966 }
967
968 @Override
969 public void sendOrderedBroadcast(Intent intent,
970 String receiverPermission) {
971 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
972 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400973 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 ActivityManagerNative.getDefault().broadcastIntent(
975 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700976 Activity.RESULT_OK, null, null, receiverPermission, true, false,
977 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 } catch (RemoteException e) {
979 }
980 }
981
982 @Override
983 public void sendOrderedBroadcast(Intent intent,
984 String receiverPermission, BroadcastReceiver resultReceiver,
985 Handler scheduler, int initialCode, String initialData,
986 Bundle initialExtras) {
987 IIntentReceiver rd = null;
988 if (resultReceiver != null) {
989 if (mPackageInfo != null) {
990 if (scheduler == null) {
991 scheduler = mMainThread.getHandler();
992 }
993 rd = mPackageInfo.getReceiverDispatcher(
994 resultReceiver, getOuterContext(), scheduler,
995 mMainThread.getInstrumentation(), false);
996 } else {
997 if (scheduler == null) {
998 scheduler = mMainThread.getHandler();
999 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001000 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1002 }
1003 }
1004 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1005 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001006 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 ActivityManagerNative.getDefault().broadcastIntent(
1008 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1009 initialCode, initialData, initialExtras, receiverPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -07001010 true, false, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 } catch (RemoteException e) {
1012 }
1013 }
1014
1015 @Override
1016 public void sendStickyBroadcast(Intent intent) {
1017 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1018 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001019 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 ActivityManagerNative.getDefault().broadcastIntent(
1021 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001022 Activity.RESULT_OK, null, null, null, false, true,
1023 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024 } catch (RemoteException e) {
1025 }
1026 }
1027
1028 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001029 public void sendStickyOrderedBroadcast(Intent intent,
1030 BroadcastReceiver resultReceiver,
1031 Handler scheduler, int initialCode, String initialData,
1032 Bundle initialExtras) {
1033 IIntentReceiver rd = null;
1034 if (resultReceiver != null) {
1035 if (mPackageInfo != null) {
1036 if (scheduler == null) {
1037 scheduler = mMainThread.getHandler();
1038 }
1039 rd = mPackageInfo.getReceiverDispatcher(
1040 resultReceiver, getOuterContext(), scheduler,
1041 mMainThread.getInstrumentation(), false);
1042 } else {
1043 if (scheduler == null) {
1044 scheduler = mMainThread.getHandler();
1045 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001046 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001047 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1048 }
1049 }
1050 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1051 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001052 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001053 ActivityManagerNative.getDefault().broadcastIntent(
1054 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1055 initialCode, initialData, initialExtras, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001056 true, true, Binder.getOrigCallingUser());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001057 } catch (RemoteException e) {
1058 }
1059 }
1060
1061 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 public void removeStickyBroadcast(Intent intent) {
1063 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1064 if (resolvedType != null) {
1065 intent = new Intent(intent);
1066 intent.setDataAndType(intent.getData(), resolvedType);
1067 }
1068 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001069 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 ActivityManagerNative.getDefault().unbroadcastIntent(
Amith Yamasani742a6712011-05-04 14:49:28 -07001071 mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 } catch (RemoteException e) {
1073 }
1074 }
1075
1076 @Override
1077 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1078 return registerReceiver(receiver, filter, null, null);
1079 }
1080
1081 @Override
1082 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1083 String broadcastPermission, Handler scheduler) {
1084 return registerReceiverInternal(receiver, filter, broadcastPermission,
1085 scheduler, getOuterContext());
1086 }
1087
1088 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1089 IntentFilter filter, String broadcastPermission,
1090 Handler scheduler, Context context) {
1091 IIntentReceiver rd = null;
1092 if (receiver != null) {
1093 if (mPackageInfo != null && context != null) {
1094 if (scheduler == null) {
1095 scheduler = mMainThread.getHandler();
1096 }
1097 rd = mPackageInfo.getReceiverDispatcher(
1098 receiver, context, scheduler,
1099 mMainThread.getInstrumentation(), true);
1100 } else {
1101 if (scheduler == null) {
1102 scheduler = mMainThread.getHandler();
1103 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001104 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001105 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 }
1107 }
1108 try {
1109 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001110 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 rd, filter, broadcastPermission);
1112 } catch (RemoteException e) {
1113 return null;
1114 }
1115 }
1116
1117 @Override
1118 public void unregisterReceiver(BroadcastReceiver receiver) {
1119 if (mPackageInfo != null) {
1120 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1121 getOuterContext(), receiver);
1122 try {
1123 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1124 } catch (RemoteException e) {
1125 }
1126 } else {
1127 throw new RuntimeException("Not supported in system context");
1128 }
1129 }
1130
1131 @Override
1132 public ComponentName startService(Intent service) {
1133 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001134 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 ComponentName cn = ActivityManagerNative.getDefault().startService(
1136 mMainThread.getApplicationThread(), service,
1137 service.resolveTypeIfNeeded(getContentResolver()));
1138 if (cn != null && cn.getPackageName().equals("!")) {
1139 throw new SecurityException(
1140 "Not allowed to start service " + service
1141 + " without permission " + cn.getClassName());
1142 }
1143 return cn;
1144 } catch (RemoteException e) {
1145 return null;
1146 }
1147 }
1148
1149 @Override
1150 public boolean stopService(Intent service) {
1151 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001152 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 int res = ActivityManagerNative.getDefault().stopService(
1154 mMainThread.getApplicationThread(), service,
1155 service.resolveTypeIfNeeded(getContentResolver()));
1156 if (res < 0) {
1157 throw new SecurityException(
1158 "Not allowed to stop service " + service);
1159 }
1160 return res != 0;
1161 } catch (RemoteException e) {
1162 return false;
1163 }
1164 }
1165
1166 @Override
1167 public boolean bindService(Intent service, ServiceConnection conn,
1168 int flags) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001169 return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
1170 }
1171
1172 /** @hide */
1173 @Override
1174 public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 IServiceConnection sd;
1176 if (mPackageInfo != null) {
1177 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1178 mMainThread.getHandler(), flags);
1179 } else {
1180 throw new RuntimeException("Not supported in system context");
1181 }
1182 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001183 IBinder token = getActivityToken();
1184 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1185 && mPackageInfo.getApplicationInfo().targetSdkVersion
1186 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1187 flags |= BIND_WAIVE_PRIORITY;
1188 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001189 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 int res = ActivityManagerNative.getDefault().bindService(
1191 mMainThread.getApplicationThread(), getActivityToken(),
1192 service, service.resolveTypeIfNeeded(getContentResolver()),
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001193 sd, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 if (res < 0) {
1195 throw new SecurityException(
1196 "Not allowed to bind to service " + service);
1197 }
1198 return res != 0;
1199 } catch (RemoteException e) {
1200 return false;
1201 }
1202 }
1203
1204 @Override
1205 public void unbindService(ServiceConnection conn) {
1206 if (mPackageInfo != null) {
1207 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1208 getOuterContext(), conn);
1209 try {
1210 ActivityManagerNative.getDefault().unbindService(sd);
1211 } catch (RemoteException e) {
1212 }
1213 } else {
1214 throw new RuntimeException("Not supported in system context");
1215 }
1216 }
1217
1218 @Override
1219 public boolean startInstrumentation(ComponentName className,
1220 String profileFile, Bundle arguments) {
1221 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001222 if (arguments != null) {
1223 arguments.setAllowFds(false);
1224 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 return ActivityManagerNative.getDefault().startInstrumentation(
1226 className, profileFile, 0, arguments, null);
1227 } catch (RemoteException e) {
1228 // System has crashed, nothing we can do.
1229 }
1230 return false;
1231 }
1232
1233 @Override
1234 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001235 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1236 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 }
1238
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001239 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001240 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 }
1242
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001243 /* package */ static DropBoxManager createDropBoxManager() {
1244 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1245 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001246 if (service == null) {
1247 // Don't return a DropBoxManager that will NPE upon use.
1248 // This also avoids caching a broken DropBoxManager in
1249 // getDropBoxManager during early boot, before the
1250 // DROPBOX_SERVICE is registered.
1251 return null;
1252 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001253 return new DropBoxManager(service);
1254 }
1255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 @Override
1257 public int checkPermission(String permission, int pid, int uid) {
1258 if (permission == null) {
1259 throw new IllegalArgumentException("permission is null");
1260 }
1261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 try {
1263 return ActivityManagerNative.getDefault().checkPermission(
1264 permission, pid, uid);
1265 } catch (RemoteException e) {
1266 return PackageManager.PERMISSION_DENIED;
1267 }
1268 }
1269
1270 @Override
1271 public int checkCallingPermission(String permission) {
1272 if (permission == null) {
1273 throw new IllegalArgumentException("permission is null");
1274 }
1275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 int pid = Binder.getCallingPid();
1277 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001278 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 }
1280 return PackageManager.PERMISSION_DENIED;
1281 }
1282
1283 @Override
1284 public int checkCallingOrSelfPermission(String permission) {
1285 if (permission == null) {
1286 throw new IllegalArgumentException("permission is null");
1287 }
1288
1289 return checkPermission(permission, Binder.getCallingPid(),
1290 Binder.getCallingUid());
1291 }
1292
1293 private void enforce(
1294 String permission, int resultOfCheck,
1295 boolean selfToo, int uid, String message) {
1296 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1297 throw new SecurityException(
1298 (message != null ? (message + ": ") : "") +
1299 (selfToo
1300 ? "Neither user " + uid + " nor current process has "
1301 : "User " + uid + " does not have ") +
1302 permission +
1303 ".");
1304 }
1305 }
1306
1307 public void enforcePermission(
1308 String permission, int pid, int uid, String message) {
1309 enforce(permission,
1310 checkPermission(permission, pid, uid),
1311 false,
1312 uid,
1313 message);
1314 }
1315
1316 public void enforceCallingPermission(String permission, String message) {
1317 enforce(permission,
1318 checkCallingPermission(permission),
1319 false,
1320 Binder.getCallingUid(),
1321 message);
1322 }
1323
1324 public void enforceCallingOrSelfPermission(
1325 String permission, String message) {
1326 enforce(permission,
1327 checkCallingOrSelfPermission(permission),
1328 true,
1329 Binder.getCallingUid(),
1330 message);
1331 }
1332
1333 @Override
1334 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1335 try {
1336 ActivityManagerNative.getDefault().grantUriPermission(
1337 mMainThread.getApplicationThread(), toPackage, uri,
1338 modeFlags);
1339 } catch (RemoteException e) {
1340 }
1341 }
1342
1343 @Override
1344 public void revokeUriPermission(Uri uri, int modeFlags) {
1345 try {
1346 ActivityManagerNative.getDefault().revokeUriPermission(
1347 mMainThread.getApplicationThread(), uri,
1348 modeFlags);
1349 } catch (RemoteException e) {
1350 }
1351 }
1352
1353 @Override
1354 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 try {
1356 return ActivityManagerNative.getDefault().checkUriPermission(
1357 uri, pid, uid, modeFlags);
1358 } catch (RemoteException e) {
1359 return PackageManager.PERMISSION_DENIED;
1360 }
1361 }
1362
1363 @Override
1364 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 int pid = Binder.getCallingPid();
1366 if (pid != Process.myPid()) {
1367 return checkUriPermission(uri, pid,
1368 Binder.getCallingUid(), modeFlags);
1369 }
1370 return PackageManager.PERMISSION_DENIED;
1371 }
1372
1373 @Override
1374 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1375 return checkUriPermission(uri, Binder.getCallingPid(),
1376 Binder.getCallingUid(), modeFlags);
1377 }
1378
1379 @Override
1380 public int checkUriPermission(Uri uri, String readPermission,
1381 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001382 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1384 + readPermission + " writePermission=" + writePermission
1385 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1386 }
1387 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1388 if (readPermission == null
1389 || checkPermission(readPermission, pid, uid)
1390 == PackageManager.PERMISSION_GRANTED) {
1391 return PackageManager.PERMISSION_GRANTED;
1392 }
1393 }
1394 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1395 if (writePermission == null
1396 || checkPermission(writePermission, pid, uid)
1397 == PackageManager.PERMISSION_GRANTED) {
1398 return PackageManager.PERMISSION_GRANTED;
1399 }
1400 }
1401 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1402 : PackageManager.PERMISSION_DENIED;
1403 }
1404
1405 private String uriModeFlagToString(int uriModeFlags) {
1406 switch (uriModeFlags) {
1407 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1408 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1409 return "read and write";
1410 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1411 return "read";
1412 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1413 return "write";
1414 }
1415 throw new IllegalArgumentException(
1416 "Unknown permission mode flags: " + uriModeFlags);
1417 }
1418
1419 private void enforceForUri(
1420 int modeFlags, int resultOfCheck, boolean selfToo,
1421 int uid, Uri uri, String message) {
1422 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1423 throw new SecurityException(
1424 (message != null ? (message + ": ") : "") +
1425 (selfToo
1426 ? "Neither user " + uid + " nor current process has "
1427 : "User " + uid + " does not have ") +
1428 uriModeFlagToString(modeFlags) +
1429 " permission on " +
1430 uri +
1431 ".");
1432 }
1433 }
1434
1435 public void enforceUriPermission(
1436 Uri uri, int pid, int uid, int modeFlags, String message) {
1437 enforceForUri(
1438 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1439 false, uid, uri, message);
1440 }
1441
1442 public void enforceCallingUriPermission(
1443 Uri uri, int modeFlags, String message) {
1444 enforceForUri(
1445 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001446 false,
1447 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 }
1449
1450 public void enforceCallingOrSelfUriPermission(
1451 Uri uri, int modeFlags, String message) {
1452 enforceForUri(
1453 modeFlags,
1454 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1455 Binder.getCallingUid(), uri, message);
1456 }
1457
1458 public void enforceUriPermission(
1459 Uri uri, String readPermission, String writePermission,
1460 int pid, int uid, int modeFlags, String message) {
1461 enforceForUri(modeFlags,
1462 checkUriPermission(
1463 uri, readPermission, writePermission, pid, uid,
1464 modeFlags),
1465 false,
1466 uid,
1467 uri,
1468 message);
1469 }
1470
1471 @Override
1472 public Context createPackageContext(String packageName, int flags)
1473 throws PackageManager.NameNotFoundException {
1474 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001475 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001476 }
1477
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001478 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001479 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001481 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001482 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001483 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 if (c.mResources != null) {
1485 return c;
1486 }
1487 }
1488
1489 // Should be a better exception.
1490 throw new PackageManager.NameNotFoundException(
1491 "Application package " + packageName + " not found");
1492 }
1493
Romain Guy870e09f2009-07-06 16:35:25 -07001494 @Override
1495 public boolean isRestricted() {
1496 return mRestricted;
1497 }
1498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001499 private File getDataDirFile() {
1500 if (mPackageInfo != null) {
1501 return mPackageInfo.getDataDirFile();
1502 }
1503 throw new RuntimeException("Not supported in system context");
1504 }
1505
1506 @Override
1507 public File getDir(String name, int mode) {
1508 name = "app_" + name;
1509 File file = makeFilename(getDataDirFile(), name);
1510 if (!file.exists()) {
1511 file.mkdir();
1512 setFilePermissionsFromMode(file.getPath(), mode,
1513 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1514 }
1515 return file;
1516 }
1517
Dianne Hackborn21556372010-02-04 16:34:40 -08001518 static ContextImpl createSystemContext(ActivityThread mainThread) {
1519 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 context.init(Resources.getSystem(), mainThread);
1521 return context;
1522 }
1523
Dianne Hackborn21556372010-02-04 16:34:40 -08001524 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 mOuterContext = this;
1526 }
1527
1528 /**
1529 * Create a new ApplicationContext from an existing one. The new one
1530 * works and operates the same as the one it is copying.
1531 *
1532 * @param context Existing application context.
1533 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001534 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001535 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001536 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 mResources = context.mResources;
1538 mMainThread = context.mMainThread;
1539 mContentResolver = context.mContentResolver;
1540 mOuterContext = this;
1541 }
1542
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001543 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001544 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001545 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001546 }
1547
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001548 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001549 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001550 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001552 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001554
Dianne Hackborn559a7872010-04-07 18:19:41 -07001555 if (mResources != null && container != null
1556 && container.getCompatibilityInfo().applicationScale !=
1557 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001558 if (DEBUG) {
1559 Log.d(TAG, "loaded context has different scaling. Using container's" +
1560 " compatiblity info:" + container.getDisplayMetrics());
1561 }
1562 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001563 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 mMainThread = mainThread;
1566 mContentResolver = new ApplicationContentResolver(this, mainThread);
1567
1568 setActivityToken(activityToken);
1569 }
1570
1571 final void init(Resources resources, ActivityThread mainThread) {
1572 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001573 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 mResources = resources;
1575 mMainThread = mainThread;
1576 mContentResolver = new ApplicationContentResolver(this, mainThread);
1577 }
1578
1579 final void scheduleFinalCleanup(String who, String what) {
1580 mMainThread.scheduleContextCleanup(this, who, what);
1581 }
1582
1583 final void performFinalCleanup(String who, String what) {
1584 //Log.i(TAG, "Cleanup up context: " + this);
1585 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1586 }
1587
1588 final Context getReceiverRestrictedContext() {
1589 if (mReceiverRestrictedContext != null) {
1590 return mReceiverRestrictedContext;
1591 }
1592 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1593 }
1594
1595 final void setActivityToken(IBinder token) {
1596 mActivityToken = token;
1597 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 final void setOuterContext(Context context) {
1600 mOuterContext = context;
1601 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 final Context getOuterContext() {
1604 return mOuterContext;
1605 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 final IBinder getActivityToken() {
1608 return mActivityToken;
1609 }
1610
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001611 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001612 int extraPermissions) {
1613 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1614 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1615 |extraPermissions;
1616 if ((mode&MODE_WORLD_READABLE) != 0) {
1617 perms |= FileUtils.S_IROTH;
1618 }
1619 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1620 perms |= FileUtils.S_IWOTH;
1621 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001622 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001623 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1624 + ", perms=0x" + Integer.toHexString(perms));
1625 }
1626 FileUtils.setPermissions(name, perms, -1, -1);
1627 }
1628
Oscar Montemayora8529f62009-11-18 10:14:20 -08001629 private File validateFilePath(String name, boolean createDirectory) {
1630 File dir;
1631 File f;
1632
1633 if (name.charAt(0) == File.separatorChar) {
1634 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1635 dir = new File(dirPath);
1636 name = name.substring(name.lastIndexOf(File.separatorChar));
1637 f = new File(dir, name);
1638 } else {
1639 dir = getDatabasesDir();
1640 f = makeFilename(dir, name);
1641 }
1642
1643 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1644 FileUtils.setPermissions(dir.getPath(),
1645 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1646 -1, -1);
1647 }
1648
1649 return f;
1650 }
1651
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 private File makeFilename(File base, String name) {
1653 if (name.indexOf(File.separatorChar) < 0) {
1654 return new File(base, name);
1655 }
1656 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001657 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001658 }
1659
1660 // ----------------------------------------------------------------------
1661 // ----------------------------------------------------------------------
1662 // ----------------------------------------------------------------------
1663
1664 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001665 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 super(context);
1667 mMainThread = mainThread;
1668 }
1669
1670 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001671 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 return mMainThread.acquireProvider(context, name);
1673 }
1674
1675 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001676 protected IContentProvider acquireExistingProvider(Context context, String name) {
1677 return mMainThread.acquireExistingProvider(context, name);
1678 }
1679
1680 @Override
1681 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 return mMainThread.releaseProvider(provider);
1683 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001684
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001685 private final ActivityThread mMainThread;
1686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687}