blob: d758ecae0f83b3e39992d6896cb34b43e8ca93be [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;
62import android.net.wifi.IWifiManager;
63import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070064import android.net.wifi.p2p.IWifiP2pManager;
65import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080066import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.os.Binder;
68import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080069import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080070import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.os.FileUtils;
72import android.os.Handler;
73import android.os.IBinder;
74import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070075import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.PowerManager;
77import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070078import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.ServiceManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070080import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.Vibrator;
San Mehatb1043402010-02-05 08:26:50 -080082import android.os.storage.StorageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080083import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070084import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.util.AndroidRuntimeException;
86import android.util.Log;
87import android.view.ContextThemeWrapper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070089import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +090091import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -070092import android.accounts.AccountManager;
93import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -080094import android.app.admin.DevicePolicyManager;
Dan Egnorf18a01c2009-11-12 11:32:50 -080095import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -070096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import java.io.File;
98import java.io.FileInputStream;
99import java.io.FileNotFoundException;
100import java.io.FileOutputStream;
101import java.io.IOException;
102import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103import java.util.ArrayList;
104import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106class ReceiverRestrictedContext extends ContextWrapper {
107 ReceiverRestrictedContext(Context base) {
108 super(base);
109 }
110
111 @Override
112 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
113 return registerReceiver(receiver, filter, null, null);
114 }
115
116 @Override
117 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
118 String broadcastPermission, Handler scheduler) {
119 throw new ReceiverCallNotAllowedException(
120 "IntentReceiver components are not allowed to register to receive intents");
121 //ex.fillInStackTrace();
122 //Log.e("IntentReceiver", ex.getMessage(), ex);
123 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
124 // scheduler);
125 }
126
127 @Override
128 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
129 throw new ReceiverCallNotAllowedException(
130 "IntentReceiver components are not allowed to bind to services");
131 //ex.fillInStackTrace();
132 //Log.e("IntentReceiver", ex.getMessage(), ex);
133 //return mContext.bindService(service, interfaceName, conn, flags);
134 }
135}
136
137/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800138 * Common implementation of Context API, which provides the base
139 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800141class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700143 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700145 private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
146 new HashMap<String, SharedPreferencesImpl>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700148 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700149 private String mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 private Resources mResources;
151 /*package*/ ActivityThread mMainThread;
152 private Context mOuterContext;
153 private IBinder mActivityToken = null;
154 private ApplicationContentResolver mContentResolver;
155 private int mThemeResource = 0;
156 private Resources.Theme mTheme = null;
157 private PackageManager mPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800158 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700159 private boolean mRestricted;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
161 private final Object mSync = new Object();
162
163 private File mDatabasesDir;
164 private File mPreferencesDir;
165 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 private File mCacheDir;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800167 private File mObbDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800168 private File mExternalFilesDir;
169 private File mExternalCacheDir;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 private static final String[] EMPTY_FILE_LIST = {};
172
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800173 /**
174 * Override this class when the system service constructor needs a
175 * ContextImpl. Else, use StaticServiceFetcher below.
176 */
177 /*package*/ static class ServiceFetcher {
178 int mContextCacheIndex = -1;
179
180 /**
181 * Main entrypoint; only override if you don't need caching.
182 */
183 public Object getService(ContextImpl ctx) {
184 ArrayList<Object> cache = ctx.mServiceCache;
185 Object service;
186 synchronized (cache) {
187 if (cache.size() == 0) {
188 // Initialize the cache vector on first access.
189 // At this point sNextPerContextServiceCacheIndex
190 // is the number of potential services that are
191 // cached per-Context.
192 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
193 cache.add(null);
194 }
195 } else {
196 service = cache.get(mContextCacheIndex);
197 if (service != null) {
198 return service;
199 }
200 }
201 service = createService(ctx);
202 cache.set(mContextCacheIndex, service);
203 return service;
204 }
205 }
206
207 /**
208 * Override this to create a new per-Context instance of the
209 * service. getService() will handle locking and caching.
210 */
211 public Object createService(ContextImpl ctx) {
212 throw new RuntimeException("Not implemented");
213 }
214 }
215
216 /**
217 * Override this class for services to be cached process-wide.
218 */
219 abstract static class StaticServiceFetcher extends ServiceFetcher {
220 private Object mCachedInstance;
221
222 @Override
223 public final Object getService(ContextImpl unused) {
224 synchronized (StaticServiceFetcher.this) {
225 Object service = mCachedInstance;
226 if (service != null) {
227 return service;
228 }
229 return mCachedInstance = createStaticService();
230 }
231 }
232
233 public abstract Object createStaticService();
234 }
235
236 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
237 new HashMap<String, ServiceFetcher>();
238
239 private static int sNextPerContextServiceCacheIndex = 0;
240 private static void registerService(String serviceName, ServiceFetcher fetcher) {
241 if (!(fetcher instanceof StaticServiceFetcher)) {
242 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
243 }
244 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
245 }
246
247 // This one's defined separately and given a variable name so it
248 // can be re-used by getWallpaperManager(), avoiding a HashMap
249 // lookup.
250 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
251 public Object createService(ContextImpl ctx) {
252 return new WallpaperManager(ctx.getOuterContext(),
253 ctx.mMainThread.getHandler());
254 }};
255
256 static {
257 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
258 public Object getService(ContextImpl ctx) {
259 return AccessibilityManager.getInstance(ctx);
260 }});
261
262 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
263 public Object createService(ContextImpl ctx) {
264 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
265 IAccountManager service = IAccountManager.Stub.asInterface(b);
266 return new AccountManager(ctx, service);
267 }});
268
269 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
270 public Object createService(ContextImpl ctx) {
271 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
272 }});
273
274 registerService(ALARM_SERVICE, new StaticServiceFetcher() {
275 public Object createStaticService() {
276 IBinder b = ServiceManager.getService(ALARM_SERVICE);
277 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
278 return new AlarmManager(service);
279 }});
280
281 registerService(AUDIO_SERVICE, new ServiceFetcher() {
282 public Object createService(ContextImpl ctx) {
283 return new AudioManager(ctx);
284 }});
285
286 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
287 public Object createService(ContextImpl ctx) {
288 return new ClipboardManager(ctx.getOuterContext(),
289 ctx.mMainThread.getHandler());
290 }});
291
292 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
293 public Object createStaticService() {
294 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
295 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
296 }});
297
298 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
299 public Object createStaticService() {
300 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
301 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
302 }});
303
304 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
305 public Object createService(ContextImpl ctx) {
306 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
307 }});
308
309 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
310 public Object createService(ContextImpl ctx) {
311 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
312 }});
313
Nick Pellyd2507462010-12-13 12:22:34 -0800314 registerService(NFC_SERVICE, new ServiceFetcher() {
315 public Object createService(ContextImpl ctx) {
316 return new NfcManager(ctx);
317 }});
318
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800319 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
320 public Object createStaticService() {
321 return createDropBoxManager();
322 }});
323
324 registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
325 public Object createService(ContextImpl ctx) {
326 return InputMethodManager.getInstance(ctx);
327 }});
328
satok988323c2011-06-22 16:38:13 +0900329 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
330 public Object createService(ContextImpl ctx) {
331 return TextServicesManager.getInstance();
332 }});
333
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800334 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
335 public Object getService(ContextImpl ctx) {
336 // TODO: why isn't this caching it? It wasn't
337 // before, so I'm preserving the old behavior and
338 // using getService(), instead of createService()
339 // which would do the caching.
340 return new KeyguardManager();
341 }});
342
343 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
344 public Object createService(ContextImpl ctx) {
345 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
346 }});
347
348 registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
349 public Object createStaticService() {
350 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
351 return new LocationManager(ILocationManager.Stub.asInterface(b));
352 }});
353
Jeff Sharkey1a303952011-06-16 13:04:20 -0700354 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
355 @Override
356 public Object createService(ContextImpl ctx) {
357 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
358 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
359 }
360 });
361
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800362 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
363 public Object createService(ContextImpl ctx) {
364 final Context outerContext = ctx.getOuterContext();
365 return new NotificationManager(
366 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800367 Resources.selectSystemTheme(0,
368 outerContext.getApplicationInfo().targetSdkVersion,
369 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700370 com.android.internal.R.style.Theme_Holo_Dialog,
371 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800372 ctx.mMainThread.getHandler());
373 }});
374
375 // Note: this was previously cached in a static variable, but
376 // constructed using mMainThread.getHandler(), so converting
377 // it to be a regular Context-cached service...
378 registerService(POWER_SERVICE, new ServiceFetcher() {
379 public Object createService(ContextImpl ctx) {
380 IBinder b = ServiceManager.getService(POWER_SERVICE);
381 IPowerManager service = IPowerManager.Stub.asInterface(b);
382 return new PowerManager(service, ctx.mMainThread.getHandler());
383 }});
384
385 registerService(SEARCH_SERVICE, new ServiceFetcher() {
386 public Object createService(ContextImpl ctx) {
387 return new SearchManager(ctx.getOuterContext(),
388 ctx.mMainThread.getHandler());
389 }});
390
391 registerService(SENSOR_SERVICE, new ServiceFetcher() {
392 public Object createService(ContextImpl ctx) {
393 return new SensorManager(ctx.mMainThread.getHandler().getLooper());
394 }});
395
396 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
397 public Object createService(ContextImpl ctx) {
398 return new StatusBarManager(ctx.getOuterContext());
399 }});
400
401 registerService(STORAGE_SERVICE, new ServiceFetcher() {
402 public Object createService(ContextImpl ctx) {
403 try {
404 return new StorageManager(ctx.mMainThread.getHandler().getLooper());
405 } catch (RemoteException rex) {
406 Log.e(TAG, "Failed to create StorageManager", rex);
407 return null;
408 }
409 }});
410
411 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
412 public Object createService(ContextImpl ctx) {
413 return new TelephonyManager(ctx.getOuterContext());
414 }});
415
416 registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
417 public Object createStaticService() {
418 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
419 return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
420 }});
421
422 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
423 public Object createService(ContextImpl ctx) {
424 return new UiModeManager();
425 }});
426
Mike Lockwood3a68b832011-03-08 10:08:59 -0500427 registerService(USB_SERVICE, new ServiceFetcher() {
428 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500429 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500430 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500431 }});
432
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -0400433 registerService(SERIAL_SERVICE, new ServiceFetcher() {
434 public Object createService(ContextImpl ctx) {
435 IBinder b = ServiceManager.getService(SERIAL_SERVICE);
436 return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
437 }});
438
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800439 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
440 public Object createService(ContextImpl ctx) {
441 return new Vibrator();
442 }});
443
444 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
445
446 registerService(WIFI_SERVICE, new ServiceFetcher() {
447 public Object createService(ContextImpl ctx) {
448 IBinder b = ServiceManager.getService(WIFI_SERVICE);
449 IWifiManager service = IWifiManager.Stub.asInterface(b);
450 return new WifiManager(service, ctx.mMainThread.getHandler());
451 }});
452
repo sync55bc5f32011-06-24 14:23:07 -0700453 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
454 public Object createService(ContextImpl ctx) {
455 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
456 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
457 return new WifiP2pManager(service);
458 }});
459
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800460 registerService(WINDOW_SERVICE, new ServiceFetcher() {
461 public Object getService(ContextImpl ctx) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700462 return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800463 }});
464 }
465
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700466 static ContextImpl getImpl(Context context) {
467 Context nextContext;
468 while ((context instanceof ContextWrapper) &&
469 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
470 context = nextContext;
471 }
472 return (ContextImpl)context;
473 }
474
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800475 // The system service cache for the system services that are
476 // cached per-ContextImpl. Package-scoped to avoid accessor
477 // methods.
478 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800480 @Override
481 public AssetManager getAssets() {
482 return mResources.getAssets();
483 }
484
485 @Override
486 public Resources getResources() {
487 return mResources;
488 }
489
490 @Override
491 public PackageManager getPackageManager() {
492 if (mPackageManager != null) {
493 return mPackageManager;
494 }
495
496 IPackageManager pm = ActivityThread.getPackageManager();
497 if (pm != null) {
498 // Doesn't matter if we make more than one instance.
499 return (mPackageManager = new ApplicationPackageManager(this, pm));
500 }
501
502 return null;
503 }
504
505 @Override
506 public ContentResolver getContentResolver() {
507 return mContentResolver;
508 }
509
510 @Override
511 public Looper getMainLooper() {
512 return mMainThread.getLooper();
513 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 @Override
516 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700517 return (mPackageInfo != null) ?
518 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800519 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800521 @Override
522 public void setTheme(int resid) {
523 mThemeResource = resid;
524 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800527 public int getThemeResId() {
528 return mThemeResource;
529 }
530
531 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800532 public Resources.Theme getTheme() {
533 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800534 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
535 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800536 mTheme = mResources.newTheme();
537 mTheme.applyStyle(mThemeResource, true);
538 }
539 return mTheme;
540 }
541
542 @Override
543 public ClassLoader getClassLoader() {
544 return mPackageInfo != null ?
545 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
546 }
547
548 @Override
549 public String getPackageName() {
550 if (mPackageInfo != null) {
551 return mPackageInfo.getPackageName();
552 }
553 throw new RuntimeException("Not supported in system context");
554 }
555
556 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700557 public ApplicationInfo getApplicationInfo() {
558 if (mPackageInfo != null) {
559 return mPackageInfo.getApplicationInfo();
560 }
561 throw new RuntimeException("Not supported in system context");
562 }
563
564 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 public String getPackageResourcePath() {
566 if (mPackageInfo != null) {
567 return mPackageInfo.getResDir();
568 }
569 throw new RuntimeException("Not supported in system context");
570 }
571
572 @Override
573 public String getPackageCodePath() {
574 if (mPackageInfo != null) {
575 return mPackageInfo.getAppDir();
576 }
577 throw new RuntimeException("Not supported in system context");
578 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200579
Joe Onorato23ecae32009-06-10 17:07:15 -0700580 public File getSharedPrefsFile(String name) {
581 return makeFilename(getPreferencesDir(), name + ".xml");
582 }
583
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800584 @Override
585 public SharedPreferences getSharedPreferences(String name, int mode) {
586 SharedPreferencesImpl sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 synchronized (sSharedPrefs) {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700588 sp = sSharedPrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700589 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800590 File prefsFile = getSharedPrefsFile(name);
591 sp = new SharedPreferencesImpl(prefsFile, mode);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700592 sSharedPrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700593 return sp;
594 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800596 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
597 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
598 // If somebody else (some other process) changed the prefs
599 // file behind our back, we reload it. This has been the
600 // historical (if undocumented) behavior.
601 sp.startReloadIfChangedUnexpectedly();
602 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700603 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 }
605
606 private File getPreferencesDir() {
607 synchronized (mSync) {
608 if (mPreferencesDir == null) {
609 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
610 }
611 return mPreferencesDir;
612 }
613 }
614
615 @Override
616 public FileInputStream openFileInput(String name)
617 throws FileNotFoundException {
618 File f = makeFilename(getFilesDir(), name);
619 return new FileInputStream(f);
620 }
621
622 @Override
623 public FileOutputStream openFileOutput(String name, int mode)
624 throws FileNotFoundException {
625 final boolean append = (mode&MODE_APPEND) != 0;
626 File f = makeFilename(getFilesDir(), name);
627 try {
628 FileOutputStream fos = new FileOutputStream(f, append);
629 setFilePermissionsFromMode(f.getPath(), mode, 0);
630 return fos;
631 } catch (FileNotFoundException e) {
632 }
633
634 File parent = f.getParentFile();
635 parent.mkdir();
636 FileUtils.setPermissions(
637 parent.getPath(),
638 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
639 -1, -1);
640 FileOutputStream fos = new FileOutputStream(f, append);
641 setFilePermissionsFromMode(f.getPath(), mode, 0);
642 return fos;
643 }
644
645 @Override
646 public boolean deleteFile(String name) {
647 File f = makeFilename(getFilesDir(), name);
648 return f.delete();
649 }
650
651 @Override
652 public File getFilesDir() {
653 synchronized (mSync) {
654 if (mFilesDir == null) {
655 mFilesDir = new File(getDataDirFile(), "files");
656 }
657 if (!mFilesDir.exists()) {
658 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200659 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 return null;
661 }
662 FileUtils.setPermissions(
663 mFilesDir.getPath(),
664 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
665 -1, -1);
666 }
667 return mFilesDir;
668 }
669 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800672 public File getExternalFilesDir(String type) {
673 synchronized (mSync) {
674 if (mExternalFilesDir == null) {
675 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
676 getPackageName());
677 }
678 if (!mExternalFilesDir.exists()) {
679 try {
680 (new File(Environment.getExternalStorageAndroidDataDir(),
681 ".nomedia")).createNewFile();
682 } catch (IOException e) {
683 }
684 if (!mExternalFilesDir.mkdirs()) {
685 Log.w(TAG, "Unable to create external files directory");
686 return null;
687 }
688 }
689 if (type == null) {
690 return mExternalFilesDir;
691 }
692 File dir = new File(mExternalFilesDir, type);
693 if (!dir.exists()) {
694 if (!dir.mkdirs()) {
695 Log.w(TAG, "Unable to create external media directory " + dir);
696 return null;
697 }
698 }
699 return dir;
700 }
701 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200702
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800703 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800704 public File getObbDir() {
705 synchronized (mSync) {
706 if (mObbDir == null) {
707 mObbDir = Environment.getExternalStorageAppObbDirectory(
708 getPackageName());
709 }
710 return mObbDir;
711 }
712 }
713
714 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 public File getCacheDir() {
716 synchronized (mSync) {
717 if (mCacheDir == null) {
718 mCacheDir = new File(getDataDirFile(), "cache");
719 }
720 if (!mCacheDir.exists()) {
721 if(!mCacheDir.mkdirs()) {
722 Log.w(TAG, "Unable to create cache directory");
723 return null;
724 }
725 FileUtils.setPermissions(
726 mCacheDir.getPath(),
727 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
728 -1, -1);
729 }
730 }
731 return mCacheDir;
732 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200733
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800734 @Override
735 public File getExternalCacheDir() {
736 synchronized (mSync) {
737 if (mExternalCacheDir == null) {
738 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
739 getPackageName());
740 }
741 if (!mExternalCacheDir.exists()) {
742 try {
743 (new File(Environment.getExternalStorageAndroidDataDir(),
744 ".nomedia")).createNewFile();
745 } catch (IOException e) {
746 }
747 if (!mExternalCacheDir.mkdirs()) {
748 Log.w(TAG, "Unable to create external cache directory");
749 return null;
750 }
751 }
752 return mExternalCacheDir;
753 }
754 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 @Override
757 public File getFileStreamPath(String name) {
758 return makeFilename(getFilesDir(), name);
759 }
760
761 @Override
762 public String[] fileList() {
763 final String[] list = getFilesDir().list();
764 return (list != null) ? list : EMPTY_FILE_LIST;
765 }
766
767 @Override
768 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Jeff Brown47847f32012-03-22 19:13:11 -0700769 return openOrCreateDatabase(name, mode, factory, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 }
771
772 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700773 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
774 DatabaseErrorHandler errorHandler) {
775 File f = validateFilePath(name, true);
Jeff Brown47847f32012-03-22 19:13:11 -0700776 int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
777 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
778 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
779 }
780 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
Vasu Nori74f170f2010-06-01 18:06:18 -0700781 setFilePermissionsFromMode(f.getPath(), mode, 0);
782 return db;
783 }
784
785 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 public boolean deleteDatabase(String name) {
787 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800788 File f = validateFilePath(name, false);
Jeff Brown79087e42012-03-01 19:52:44 -0800789 return SQLiteDatabase.deleteDatabase(f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790 } catch (Exception e) {
791 }
792 return false;
793 }
794
795 @Override
796 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800797 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 }
799
800 @Override
801 public String[] databaseList() {
802 final String[] list = getDatabasesDir().list();
803 return (list != null) ? list : EMPTY_FILE_LIST;
804 }
805
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 private File getDatabasesDir() {
808 synchronized (mSync) {
809 if (mDatabasesDir == null) {
810 mDatabasesDir = new File(getDataDirFile(), "databases");
811 }
812 if (mDatabasesDir.getPath().equals("databases")) {
813 mDatabasesDir = new File("/data/system");
814 }
815 return mDatabasesDir;
816 }
817 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 @Override
820 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700821 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
824 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700825 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700826 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 }
828
829 @Override
830 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700831 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 }
833
834 @Override
835 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700836 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 }
838
839 @Override
840 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700841 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 }
843
844 @Override
845 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700846 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 }
848
849 @Override
850 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700851 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 }
853
854 @Override
855 public void startActivity(Intent intent) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700856 startActivity(intent, null);
857 }
858
859 @Override
860 public void startActivity(Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
862 throw new AndroidRuntimeException(
863 "Calling startActivity() from outside of an Activity "
864 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
865 + " Is this really what you want?");
866 }
867 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -0700868 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700869 (Activity)null, intent, -1, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870 }
871
872 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800873 public void startActivities(Intent[] intents) {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700874 startActivities(intents, null);
875 }
876
877 @Override
878 public void startActivities(Intent[] intents, Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800879 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
880 throw new AndroidRuntimeException(
881 "Calling startActivities() from outside of an Activity "
882 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
883 + " Is this really what you want?");
884 }
885 mMainThread.getInstrumentation().execStartActivities(
886 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700887 (Activity)null, intents, options);
Dianne Hackborn621e17d2010-11-22 15:59:56 -0800888 }
889
890 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700891 public void startIntentSender(IntentSender intent,
892 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
893 throws IntentSender.SendIntentException {
Dianne Hackborna4972e92012-03-14 10:38:05 -0700894 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
895 }
896
897 @Override
898 public void startIntentSender(IntentSender intent, Intent fillInIntent,
899 int flagsMask, int flagsValues, int extraFlags, Bundle options)
900 throws IntentSender.SendIntentException {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700901 try {
902 String resolvedType = null;
903 if (fillInIntent != null) {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400904 fillInIntent.setAllowFds(false);
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700905 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
906 }
907 int result = ActivityManagerNative.getDefault()
908 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
909 fillInIntent, resolvedType, null, null,
Dianne Hackborna4972e92012-03-14 10:38:05 -0700910 0, flagsMask, flagsValues, options);
911 if (result == ActivityManager.START_CANCELED) {
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700912 throw new IntentSender.SendIntentException();
913 }
914 Instrumentation.checkStartActivityResult(result, null);
915 } catch (RemoteException e) {
916 }
917 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200918
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700919 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 public void sendBroadcast(Intent intent) {
921 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
922 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400923 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 ActivityManagerNative.getDefault().broadcastIntent(
925 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700926 Activity.RESULT_OK, null, null, null, false, false,
927 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 } catch (RemoteException e) {
929 }
930 }
931
Amith Yamasani67cf7d32012-02-16 14:31:23 -0800932 /** @hide */
933 @Override
934 public void sendBroadcast(Intent intent, int userId) {
935 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
936 try {
937 intent.setAllowFds(false);
938 ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
939 intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
940 userId);
941 } catch (RemoteException e) {
942 }
943 }
944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 @Override
946 public void sendBroadcast(Intent intent, String receiverPermission) {
947 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
948 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400949 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 ActivityManagerNative.getDefault().broadcastIntent(
951 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700952 Activity.RESULT_OK, null, null, receiverPermission, false, false,
953 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 } catch (RemoteException e) {
955 }
956 }
957
958 @Override
959 public void sendOrderedBroadcast(Intent intent,
960 String receiverPermission) {
961 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
962 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400963 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 ActivityManagerNative.getDefault().broadcastIntent(
965 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700966 Activity.RESULT_OK, null, null, receiverPermission, true, false,
967 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 } catch (RemoteException e) {
969 }
970 }
971
972 @Override
973 public void sendOrderedBroadcast(Intent intent,
974 String receiverPermission, BroadcastReceiver resultReceiver,
975 Handler scheduler, int initialCode, String initialData,
976 Bundle initialExtras) {
977 IIntentReceiver rd = null;
978 if (resultReceiver != null) {
979 if (mPackageInfo != null) {
980 if (scheduler == null) {
981 scheduler = mMainThread.getHandler();
982 }
983 rd = mPackageInfo.getReceiverDispatcher(
984 resultReceiver, getOuterContext(), scheduler,
985 mMainThread.getInstrumentation(), false);
986 } else {
987 if (scheduler == null) {
988 scheduler = mMainThread.getHandler();
989 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700990 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
992 }
993 }
994 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
995 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -0400996 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800997 ActivityManagerNative.getDefault().broadcastIntent(
998 mMainThread.getApplicationThread(), intent, resolvedType, rd,
999 initialCode, initialData, initialExtras, receiverPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -07001000 true, false, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 } catch (RemoteException e) {
1002 }
1003 }
1004
1005 @Override
1006 public void sendStickyBroadcast(Intent intent) {
1007 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1008 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001009 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 ActivityManagerNative.getDefault().broadcastIntent(
1011 mMainThread.getApplicationThread(), intent, resolvedType, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001012 Activity.RESULT_OK, null, null, null, false, true,
1013 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 } catch (RemoteException e) {
1015 }
1016 }
1017
1018 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001019 public void sendStickyOrderedBroadcast(Intent intent,
1020 BroadcastReceiver resultReceiver,
1021 Handler scheduler, int initialCode, String initialData,
1022 Bundle initialExtras) {
1023 IIntentReceiver rd = null;
1024 if (resultReceiver != null) {
1025 if (mPackageInfo != null) {
1026 if (scheduler == null) {
1027 scheduler = mMainThread.getHandler();
1028 }
1029 rd = mPackageInfo.getReceiverDispatcher(
1030 resultReceiver, getOuterContext(), scheduler,
1031 mMainThread.getInstrumentation(), false);
1032 } else {
1033 if (scheduler == null) {
1034 scheduler = mMainThread.getHandler();
1035 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001036 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001037 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1038 }
1039 }
1040 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1041 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001042 intent.setAllowFds(false);
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001043 ActivityManagerNative.getDefault().broadcastIntent(
1044 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1045 initialCode, initialData, initialExtras, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07001046 true, true, Binder.getOrigCallingUser());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001047 } catch (RemoteException e) {
1048 }
1049 }
1050
1051 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001052 public void removeStickyBroadcast(Intent intent) {
1053 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1054 if (resolvedType != null) {
1055 intent = new Intent(intent);
1056 intent.setDataAndType(intent.getData(), resolvedType);
1057 }
1058 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001059 intent.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001060 ActivityManagerNative.getDefault().unbroadcastIntent(
Amith Yamasani742a6712011-05-04 14:49:28 -07001061 mMainThread.getApplicationThread(), intent, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 } catch (RemoteException e) {
1063 }
1064 }
1065
1066 @Override
1067 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1068 return registerReceiver(receiver, filter, null, null);
1069 }
1070
1071 @Override
1072 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1073 String broadcastPermission, Handler scheduler) {
1074 return registerReceiverInternal(receiver, filter, broadcastPermission,
1075 scheduler, getOuterContext());
1076 }
1077
1078 private Intent registerReceiverInternal(BroadcastReceiver receiver,
1079 IntentFilter filter, String broadcastPermission,
1080 Handler scheduler, Context context) {
1081 IIntentReceiver rd = null;
1082 if (receiver != null) {
1083 if (mPackageInfo != null && context != null) {
1084 if (scheduler == null) {
1085 scheduler = mMainThread.getHandler();
1086 }
1087 rd = mPackageInfo.getReceiverDispatcher(
1088 receiver, context, scheduler,
1089 mMainThread.getInstrumentation(), true);
1090 } else {
1091 if (scheduler == null) {
1092 scheduler = mMainThread.getHandler();
1093 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001094 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001095 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 }
1097 }
1098 try {
1099 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001100 mMainThread.getApplicationThread(), mBasePackageName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101 rd, filter, broadcastPermission);
1102 } catch (RemoteException e) {
1103 return null;
1104 }
1105 }
1106
1107 @Override
1108 public void unregisterReceiver(BroadcastReceiver receiver) {
1109 if (mPackageInfo != null) {
1110 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1111 getOuterContext(), receiver);
1112 try {
1113 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1114 } catch (RemoteException e) {
1115 }
1116 } else {
1117 throw new RuntimeException("Not supported in system context");
1118 }
1119 }
1120
1121 @Override
1122 public ComponentName startService(Intent service) {
1123 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001124 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 ComponentName cn = ActivityManagerNative.getDefault().startService(
1126 mMainThread.getApplicationThread(), service,
1127 service.resolveTypeIfNeeded(getContentResolver()));
1128 if (cn != null && cn.getPackageName().equals("!")) {
1129 throw new SecurityException(
1130 "Not allowed to start service " + service
1131 + " without permission " + cn.getClassName());
1132 }
1133 return cn;
1134 } catch (RemoteException e) {
1135 return null;
1136 }
1137 }
1138
1139 @Override
1140 public boolean stopService(Intent service) {
1141 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001142 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 int res = ActivityManagerNative.getDefault().stopService(
1144 mMainThread.getApplicationThread(), service,
1145 service.resolveTypeIfNeeded(getContentResolver()));
1146 if (res < 0) {
1147 throw new SecurityException(
1148 "Not allowed to stop service " + service);
1149 }
1150 return res != 0;
1151 } catch (RemoteException e) {
1152 return false;
1153 }
1154 }
1155
1156 @Override
1157 public boolean bindService(Intent service, ServiceConnection conn,
1158 int flags) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001159 return bindService(service, conn, flags, UserId.getUserId(Process.myUid()));
1160 }
1161
1162 /** @hide */
1163 @Override
1164 public boolean bindService(Intent service, ServiceConnection conn, int flags, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 IServiceConnection sd;
1166 if (mPackageInfo != null) {
1167 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1168 mMainThread.getHandler(), flags);
1169 } else {
1170 throw new RuntimeException("Not supported in system context");
1171 }
1172 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001173 IBinder token = getActivityToken();
1174 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1175 && mPackageInfo.getApplicationInfo().targetSdkVersion
1176 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1177 flags |= BIND_WAIVE_PRIORITY;
1178 }
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001179 service.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 int res = ActivityManagerNative.getDefault().bindService(
1181 mMainThread.getApplicationThread(), getActivityToken(),
1182 service, service.resolveTypeIfNeeded(getContentResolver()),
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001183 sd, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 if (res < 0) {
1185 throw new SecurityException(
1186 "Not allowed to bind to service " + service);
1187 }
1188 return res != 0;
1189 } catch (RemoteException e) {
1190 return false;
1191 }
1192 }
1193
1194 @Override
1195 public void unbindService(ServiceConnection conn) {
1196 if (mPackageInfo != null) {
1197 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1198 getOuterContext(), conn);
1199 try {
1200 ActivityManagerNative.getDefault().unbindService(sd);
1201 } catch (RemoteException e) {
1202 }
1203 } else {
1204 throw new RuntimeException("Not supported in system context");
1205 }
1206 }
1207
1208 @Override
1209 public boolean startInstrumentation(ComponentName className,
1210 String profileFile, Bundle arguments) {
1211 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001212 if (arguments != null) {
1213 arguments.setAllowFds(false);
1214 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 return ActivityManagerNative.getDefault().startInstrumentation(
1216 className, profileFile, 0, arguments, null);
1217 } catch (RemoteException e) {
1218 // System has crashed, nothing we can do.
1219 }
1220 return false;
1221 }
1222
1223 @Override
1224 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001225 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1226 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 }
1228
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001229 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001230 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231 }
1232
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001233 /* package */ static DropBoxManager createDropBoxManager() {
1234 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1235 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001236 if (service == null) {
1237 // Don't return a DropBoxManager that will NPE upon use.
1238 // This also avoids caching a broken DropBoxManager in
1239 // getDropBoxManager during early boot, before the
1240 // DROPBOX_SERVICE is registered.
1241 return null;
1242 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001243 return new DropBoxManager(service);
1244 }
1245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 @Override
1247 public int checkPermission(String permission, int pid, int uid) {
1248 if (permission == null) {
1249 throw new IllegalArgumentException("permission is null");
1250 }
1251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 try {
1253 return ActivityManagerNative.getDefault().checkPermission(
1254 permission, pid, uid);
1255 } catch (RemoteException e) {
1256 return PackageManager.PERMISSION_DENIED;
1257 }
1258 }
1259
1260 @Override
1261 public int checkCallingPermission(String permission) {
1262 if (permission == null) {
1263 throw new IllegalArgumentException("permission is null");
1264 }
1265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 int pid = Binder.getCallingPid();
1267 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001268 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 }
1270 return PackageManager.PERMISSION_DENIED;
1271 }
1272
1273 @Override
1274 public int checkCallingOrSelfPermission(String permission) {
1275 if (permission == null) {
1276 throw new IllegalArgumentException("permission is null");
1277 }
1278
1279 return checkPermission(permission, Binder.getCallingPid(),
1280 Binder.getCallingUid());
1281 }
1282
1283 private void enforce(
1284 String permission, int resultOfCheck,
1285 boolean selfToo, int uid, String message) {
1286 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1287 throw new SecurityException(
1288 (message != null ? (message + ": ") : "") +
1289 (selfToo
1290 ? "Neither user " + uid + " nor current process has "
1291 : "User " + uid + " does not have ") +
1292 permission +
1293 ".");
1294 }
1295 }
1296
1297 public void enforcePermission(
1298 String permission, int pid, int uid, String message) {
1299 enforce(permission,
1300 checkPermission(permission, pid, uid),
1301 false,
1302 uid,
1303 message);
1304 }
1305
1306 public void enforceCallingPermission(String permission, String message) {
1307 enforce(permission,
1308 checkCallingPermission(permission),
1309 false,
1310 Binder.getCallingUid(),
1311 message);
1312 }
1313
1314 public void enforceCallingOrSelfPermission(
1315 String permission, String message) {
1316 enforce(permission,
1317 checkCallingOrSelfPermission(permission),
1318 true,
1319 Binder.getCallingUid(),
1320 message);
1321 }
1322
1323 @Override
1324 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1325 try {
1326 ActivityManagerNative.getDefault().grantUriPermission(
1327 mMainThread.getApplicationThread(), toPackage, uri,
1328 modeFlags);
1329 } catch (RemoteException e) {
1330 }
1331 }
1332
1333 @Override
1334 public void revokeUriPermission(Uri uri, int modeFlags) {
1335 try {
1336 ActivityManagerNative.getDefault().revokeUriPermission(
1337 mMainThread.getApplicationThread(), uri,
1338 modeFlags);
1339 } catch (RemoteException e) {
1340 }
1341 }
1342
1343 @Override
1344 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001345 try {
1346 return ActivityManagerNative.getDefault().checkUriPermission(
1347 uri, pid, uid, modeFlags);
1348 } catch (RemoteException e) {
1349 return PackageManager.PERMISSION_DENIED;
1350 }
1351 }
1352
1353 @Override
1354 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 int pid = Binder.getCallingPid();
1356 if (pid != Process.myPid()) {
1357 return checkUriPermission(uri, pid,
1358 Binder.getCallingUid(), modeFlags);
1359 }
1360 return PackageManager.PERMISSION_DENIED;
1361 }
1362
1363 @Override
1364 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1365 return checkUriPermission(uri, Binder.getCallingPid(),
1366 Binder.getCallingUid(), modeFlags);
1367 }
1368
1369 @Override
1370 public int checkUriPermission(Uri uri, String readPermission,
1371 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001372 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1374 + readPermission + " writePermission=" + writePermission
1375 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1376 }
1377 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1378 if (readPermission == null
1379 || checkPermission(readPermission, pid, uid)
1380 == PackageManager.PERMISSION_GRANTED) {
1381 return PackageManager.PERMISSION_GRANTED;
1382 }
1383 }
1384 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1385 if (writePermission == null
1386 || checkPermission(writePermission, pid, uid)
1387 == PackageManager.PERMISSION_GRANTED) {
1388 return PackageManager.PERMISSION_GRANTED;
1389 }
1390 }
1391 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1392 : PackageManager.PERMISSION_DENIED;
1393 }
1394
1395 private String uriModeFlagToString(int uriModeFlags) {
1396 switch (uriModeFlags) {
1397 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1398 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1399 return "read and write";
1400 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1401 return "read";
1402 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1403 return "write";
1404 }
1405 throw new IllegalArgumentException(
1406 "Unknown permission mode flags: " + uriModeFlags);
1407 }
1408
1409 private void enforceForUri(
1410 int modeFlags, int resultOfCheck, boolean selfToo,
1411 int uid, Uri uri, String message) {
1412 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1413 throw new SecurityException(
1414 (message != null ? (message + ": ") : "") +
1415 (selfToo
1416 ? "Neither user " + uid + " nor current process has "
1417 : "User " + uid + " does not have ") +
1418 uriModeFlagToString(modeFlags) +
1419 " permission on " +
1420 uri +
1421 ".");
1422 }
1423 }
1424
1425 public void enforceUriPermission(
1426 Uri uri, int pid, int uid, int modeFlags, String message) {
1427 enforceForUri(
1428 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1429 false, uid, uri, message);
1430 }
1431
1432 public void enforceCallingUriPermission(
1433 Uri uri, int modeFlags, String message) {
1434 enforceForUri(
1435 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001436 false,
1437 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 }
1439
1440 public void enforceCallingOrSelfUriPermission(
1441 Uri uri, int modeFlags, String message) {
1442 enforceForUri(
1443 modeFlags,
1444 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1445 Binder.getCallingUid(), uri, message);
1446 }
1447
1448 public void enforceUriPermission(
1449 Uri uri, String readPermission, String writePermission,
1450 int pid, int uid, int modeFlags, String message) {
1451 enforceForUri(modeFlags,
1452 checkUriPermission(
1453 uri, readPermission, writePermission, pid, uid,
1454 modeFlags),
1455 false,
1456 uid,
1457 uri,
1458 message);
1459 }
1460
1461 @Override
1462 public Context createPackageContext(String packageName, int flags)
1463 throws PackageManager.NameNotFoundException {
1464 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001465 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 }
1467
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001468 LoadedApk pi =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001469 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001471 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001472 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001473 c.init(pi, null, mMainThread, mResources, mBasePackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 if (c.mResources != null) {
1475 return c;
1476 }
1477 }
1478
1479 // Should be a better exception.
1480 throw new PackageManager.NameNotFoundException(
1481 "Application package " + packageName + " not found");
1482 }
1483
Romain Guy870e09f2009-07-06 16:35:25 -07001484 @Override
1485 public boolean isRestricted() {
1486 return mRestricted;
1487 }
1488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 private File getDataDirFile() {
1490 if (mPackageInfo != null) {
1491 return mPackageInfo.getDataDirFile();
1492 }
1493 throw new RuntimeException("Not supported in system context");
1494 }
1495
1496 @Override
1497 public File getDir(String name, int mode) {
1498 name = "app_" + name;
1499 File file = makeFilename(getDataDirFile(), name);
1500 if (!file.exists()) {
1501 file.mkdir();
1502 setFilePermissionsFromMode(file.getPath(), mode,
1503 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1504 }
1505 return file;
1506 }
1507
Dianne Hackborn21556372010-02-04 16:34:40 -08001508 static ContextImpl createSystemContext(ActivityThread mainThread) {
1509 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 context.init(Resources.getSystem(), mainThread);
1511 return context;
1512 }
1513
Dianne Hackborn21556372010-02-04 16:34:40 -08001514 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 mOuterContext = this;
1516 }
1517
1518 /**
1519 * Create a new ApplicationContext from an existing one. The new one
1520 * works and operates the same as the one it is copying.
1521 *
1522 * @param context Existing application context.
1523 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001524 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001526 mBasePackageName = context.mBasePackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 mResources = context.mResources;
1528 mMainThread = context.mMainThread;
1529 mContentResolver = context.mContentResolver;
1530 mOuterContext = this;
1531 }
1532
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001533 final void init(LoadedApk packageInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 IBinder activityToken, ActivityThread mainThread) {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001535 init(packageInfo, activityToken, mainThread, null, null);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001536 }
1537
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001538 final void init(LoadedApk packageInfo,
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001539 IBinder activityToken, ActivityThread mainThread,
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001540 Resources container, String basePackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 mPackageInfo = packageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001542 mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001544
Dianne Hackborn559a7872010-04-07 18:19:41 -07001545 if (mResources != null && container != null
1546 && container.getCompatibilityInfo().applicationScale !=
1547 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001548 if (DEBUG) {
1549 Log.d(TAG, "loaded context has different scaling. Using container's" +
1550 " compatiblity info:" + container.getDisplayMetrics());
1551 }
1552 mResources = mainThread.getTopLevelResources(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001553 mPackageInfo.getResDir(), container.getCompatibilityInfo());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001554 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 mMainThread = mainThread;
1556 mContentResolver = new ApplicationContentResolver(this, mainThread);
1557
1558 setActivityToken(activityToken);
1559 }
1560
1561 final void init(Resources resources, ActivityThread mainThread) {
1562 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001563 mBasePackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 mResources = resources;
1565 mMainThread = mainThread;
1566 mContentResolver = new ApplicationContentResolver(this, mainThread);
1567 }
1568
1569 final void scheduleFinalCleanup(String who, String what) {
1570 mMainThread.scheduleContextCleanup(this, who, what);
1571 }
1572
1573 final void performFinalCleanup(String who, String what) {
1574 //Log.i(TAG, "Cleanup up context: " + this);
1575 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1576 }
1577
1578 final Context getReceiverRestrictedContext() {
1579 if (mReceiverRestrictedContext != null) {
1580 return mReceiverRestrictedContext;
1581 }
1582 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1583 }
1584
1585 final void setActivityToken(IBinder token) {
1586 mActivityToken = token;
1587 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 final void setOuterContext(Context context) {
1590 mOuterContext = context;
1591 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 final Context getOuterContext() {
1594 return mOuterContext;
1595 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 final IBinder getActivityToken() {
1598 return mActivityToken;
1599 }
1600
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08001601 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 int extraPermissions) {
1603 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1604 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1605 |extraPermissions;
1606 if ((mode&MODE_WORLD_READABLE) != 0) {
1607 perms |= FileUtils.S_IROTH;
1608 }
1609 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1610 perms |= FileUtils.S_IWOTH;
1611 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001612 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001613 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1614 + ", perms=0x" + Integer.toHexString(perms));
1615 }
1616 FileUtils.setPermissions(name, perms, -1, -1);
1617 }
1618
Oscar Montemayora8529f62009-11-18 10:14:20 -08001619 private File validateFilePath(String name, boolean createDirectory) {
1620 File dir;
1621 File f;
1622
1623 if (name.charAt(0) == File.separatorChar) {
1624 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1625 dir = new File(dirPath);
1626 name = name.substring(name.lastIndexOf(File.separatorChar));
1627 f = new File(dir, name);
1628 } else {
1629 dir = getDatabasesDir();
1630 f = makeFilename(dir, name);
1631 }
1632
1633 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1634 FileUtils.setPermissions(dir.getPath(),
1635 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1636 -1, -1);
1637 }
1638
1639 return f;
1640 }
1641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 private File makeFilename(File base, String name) {
1643 if (name.indexOf(File.separatorChar) < 0) {
1644 return new File(base, name);
1645 }
1646 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001647 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 }
1649
1650 // ----------------------------------------------------------------------
1651 // ----------------------------------------------------------------------
1652 // ----------------------------------------------------------------------
1653
1654 private static final class ApplicationContentResolver extends ContentResolver {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001655 public ApplicationContentResolver(Context context, ActivityThread mainThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 super(context);
1657 mMainThread = mainThread;
1658 }
1659
1660 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001661 protected IContentProvider acquireProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 return mMainThread.acquireProvider(context, name);
1663 }
1664
1665 @Override
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07001666 protected IContentProvider acquireExistingProvider(Context context, String name) {
1667 return mMainThread.acquireExistingProvider(context, name);
1668 }
1669
1670 @Override
1671 public boolean releaseProvider(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001672 return mMainThread.releaseProvider(provider);
1673 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 private final ActivityThread mMainThread;
1676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677}