blob: fe8c5066636122492bc6b826e68e5f5b5e63bf70 [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
Dianne Hackbornff32f352013-07-18 17:31:13 -070019import android.os.Build;
svetoslavganov75986cf2009-05-14 22:28:01 -070020import com.android.internal.policy.PolicyManager;
Jeff Sharkey6d515712012-09-20 16:06:08 -070021import com.android.internal.util.Preconditions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Matthew Xieddf7e472013-03-01 18:41:02 -080023import android.bluetooth.BluetoothManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.ContextWrapper;
29import android.content.IContentProvider;
30import android.content.Intent;
31import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070032import android.content.IIntentReceiver;
33import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.ReceiverCallNotAllowedException;
35import android.content.ServiceConnection;
36import android.content.SharedPreferences;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.content.pm.ApplicationInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.content.pm.IPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.pm.PackageManager;
Jeff Sharkey6d515712012-09-20 16:06:08 -070040import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.content.res.AssetManager;
Dianne Hackborn5be8de32011-05-24 18:11:57 -070042import android.content.res.CompatibilityInfo;
Dianne Hackborn756220b2012-08-14 16:45:30 -070043import android.content.res.Configuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.res.Resources;
Vasu Nori74f170f2010-06-01 18:06:18 -070045import android.database.DatabaseErrorHandler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.database.sqlite.SQLiteDatabase;
47import android.database.sqlite.SQLiteDatabase.CursorFactory;
48import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.graphics.drawable.Drawable;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040050import android.hardware.ISerialManager;
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -040051import android.hardware.SerialManager;
Jeff Brown25157e42012-04-16 12:13:05 -070052import android.hardware.SystemSensorManager;
Eino-Ville Talvala2f1a2e42013-07-25 17:12:05 -070053import android.hardware.camera2.CameraManager;
Jeff Brownfa25bf52012-07-23 19:26:30 -070054import android.hardware.display.DisplayManager;
Jeff Brown9df6e7a2012-04-05 11:49:26 -070055import android.hardware.input.InputManager;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080056import android.hardware.usb.IUsbManager;
57import android.hardware.usb.UsbManager;
Bai Taoa58a8752010-07-13 15:32:16 +080058import android.location.CountryDetector;
59import android.location.ICountryDetector;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.location.ILocationManager;
61import android.location.LocationManager;
62import android.media.AudioManager;
Dianne Hackbornb58b8f82012-06-11 15:08:39 -070063import android.media.MediaRouter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.net.ConnectivityManager;
65import android.net.IConnectivityManager;
Jeff Sharkey1a303952011-06-16 13:04:20 -070066import android.net.INetworkPolicyManager;
67import android.net.NetworkPolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.net.Uri;
Irfan Sheriff7d024d32012-03-22 17:01:39 -070069import android.net.nsd.INsdManager;
70import android.net.nsd.NsdManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.net.wifi.IWifiManager;
72import android.net.wifi.WifiManager;
repo sync55bc5f32011-06-24 14:23:07 -070073import android.net.wifi.p2p.IWifiP2pManager;
74import android.net.wifi.p2p.WifiP2pManager;
Nick Pelly50b4d8f2010-12-07 22:40:28 -080075import android.nfc.NfcManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.Binder;
77import android.os.Bundle;
Amith Yamasanicd757062012-10-19 18:23:52 -070078import android.os.Debug;
Dan Egnorf18a01c2009-11-12 11:32:50 -080079import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080080import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.FileUtils;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.IPowerManager;
Amith Yamasani258848d2012-08-10 17:06:33 -070085import android.os.IUserManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.PowerManager;
88import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070089import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.ServiceManager;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070091import android.os.UserHandle;
Jeff Brownc2346132012-04-13 01:55:38 -070092import android.os.SystemVibrator;
Amith Yamasani258848d2012-08-10 17:06:33 -070093import android.os.UserManager;
San Mehatb1043402010-02-05 08:26:50 -080094import android.os.storage.StorageManager;
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -070095import android.print.IPrintManager;
96import android.print.PrintManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import android.telephony.TelephonyManager;
Dianne Hackborn9f531192010-08-04 17:48:03 -070098import android.content.ClipboardManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.util.AndroidRuntimeException;
Jeff Sharkey8e3ddab2013-06-17 18:26:37 -0700100import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.util.Log;
Amith Yamasanicd757062012-10-19 18:23:52 -0700102import android.util.Slog;
Craig Mautner48d0d182013-06-11 07:53:06 -0700103import android.view.DisplayAdjustments;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import android.view.ContextThemeWrapper;
Jeff Brown98365d72012-08-19 20:30:52 -0700105import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -0700107import android.view.accessibility.AccessibilityManager;
Alan Viverette69ce69b2013-08-29 12:23:48 -0700108import android.view.accessibility.CaptioningManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109import android.view.inputmethod.InputMethodManager;
satok988323c2011-06-22 16:38:13 +0900110import android.view.textservice.TextServicesManager;
Fred Quintana60307342009-03-24 22:48:12 -0700111import android.accounts.AccountManager;
112import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800113import android.app.admin.DevicePolicyManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800114
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700115import com.android.internal.annotations.GuardedBy;
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800116import com.android.internal.app.IAppOpsService;
Dan Egnorf18a01c2009-11-12 11:32:50 -0800117import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import java.io.File;
120import java.io.FileInputStream;
121import java.io.FileNotFoundException;
122import java.io.FileOutputStream;
123import java.io.IOException;
124import java.io.InputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import java.util.ArrayList;
126import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128class ReceiverRestrictedContext extends ContextWrapper {
129 ReceiverRestrictedContext(Context base) {
130 super(base);
131 }
132
133 @Override
134 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
135 return registerReceiver(receiver, filter, null, null);
136 }
137
138 @Override
139 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
140 String broadcastPermission, Handler scheduler) {
Jeff Sharkey27bd34d2012-09-16 12:49:00 -0700141 if (receiver == null) {
142 // Allow retrieving current sticky broadcast; this is safe since we
143 // aren't actually registering a receiver.
144 return super.registerReceiver(null, filter, broadcastPermission, scheduler);
145 } else {
146 throw new ReceiverCallNotAllowedException(
147 "BroadcastReceiver components are not allowed to register to receive intents");
148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 }
150
151 @Override
Dianne Hackborn20e80982012-08-31 19:00:44 -0700152 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
153 IntentFilter filter, String broadcastPermission, Handler scheduler) {
Jeff Sharkey27bd34d2012-09-16 12:49:00 -0700154 if (receiver == null) {
155 // Allow retrieving current sticky broadcast; this is safe since we
156 // aren't actually registering a receiver.
157 return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler);
158 } else {
159 throw new ReceiverCallNotAllowedException(
160 "BroadcastReceiver components are not allowed to register to receive intents");
161 }
Dianne Hackborn20e80982012-08-31 19:00:44 -0700162 }
163
164 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
166 throw new ReceiverCallNotAllowedException(
Jeff Sharkey27bd34d2012-09-16 12:49:00 -0700167 "BroadcastReceiver components are not allowed to bind to services");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 }
169}
170
171/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800172 * Common implementation of Context API, which provides the base
173 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800175class ContextImpl extends Context {
Dianne Hackborn40e9f292012-11-27 19:12:23 -0800176 private final static String TAG = "ContextImpl";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700177 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178
Jeff Sharkey8e3ddab2013-06-17 18:26:37 -0700179 /**
180 * Map from package name, to preference name, to cached preferences.
181 */
182 private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700184 /*package*/ LoadedApk mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700185 private String mBasePackageName;
Dianne Hackborn95d78532013-09-11 09:51:14 -0700186 private String mOpPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 private Resources mResources;
188 /*package*/ ActivityThread mMainThread;
189 private Context mOuterContext;
190 private IBinder mActivityToken = null;
191 private ApplicationContentResolver mContentResolver;
192 private int mThemeResource = 0;
193 private Resources.Theme mTheme = null;
194 private PackageManager mPackageManager;
Jeff Browna492c3a2012-08-23 19:48:44 -0700195 private Display mDisplay; // may be null if default display
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 private Context mReceiverRestrictedContext = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700197 private boolean mRestricted;
Jeff Sharkey6d515712012-09-20 16:06:08 -0700198 private UserHandle mUser;
Craig Mautner88c05892013-06-28 09:47:45 -0700199 private ResourcesManager mResourcesManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200
201 private final Object mSync = new Object();
202
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700203 @GuardedBy("mSync")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204 private File mDatabasesDir;
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700205 @GuardedBy("mSync")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 private File mPreferencesDir;
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700207 @GuardedBy("mSync")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 private File mFilesDir;
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700209 @GuardedBy("mSync")
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210 private File mCacheDir;
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700211
212 @GuardedBy("mSync")
213 private File[] mExternalObbDirs;
214 @GuardedBy("mSync")
215 private File[] mExternalFilesDirs;
216 @GuardedBy("mSync")
217 private File[] mExternalCacheDirs;
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219 private static final String[] EMPTY_FILE_LIST = {};
220
Craig Mautner48d0d182013-06-11 07:53:06 -0700221 final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
222
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800223 /**
224 * Override this class when the system service constructor needs a
225 * ContextImpl. Else, use StaticServiceFetcher below.
226 */
227 /*package*/ static class ServiceFetcher {
228 int mContextCacheIndex = -1;
229
230 /**
231 * Main entrypoint; only override if you don't need caching.
232 */
233 public Object getService(ContextImpl ctx) {
234 ArrayList<Object> cache = ctx.mServiceCache;
235 Object service;
236 synchronized (cache) {
237 if (cache.size() == 0) {
238 // Initialize the cache vector on first access.
239 // At this point sNextPerContextServiceCacheIndex
240 // is the number of potential services that are
241 // cached per-Context.
242 for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
243 cache.add(null);
244 }
245 } else {
246 service = cache.get(mContextCacheIndex);
247 if (service != null) {
248 return service;
249 }
250 }
251 service = createService(ctx);
252 cache.set(mContextCacheIndex, service);
253 return service;
254 }
255 }
256
257 /**
258 * Override this to create a new per-Context instance of the
259 * service. getService() will handle locking and caching.
260 */
261 public Object createService(ContextImpl ctx) {
262 throw new RuntimeException("Not implemented");
263 }
264 }
265
266 /**
267 * Override this class for services to be cached process-wide.
268 */
269 abstract static class StaticServiceFetcher extends ServiceFetcher {
270 private Object mCachedInstance;
271
272 @Override
273 public final Object getService(ContextImpl unused) {
274 synchronized (StaticServiceFetcher.this) {
275 Object service = mCachedInstance;
276 if (service != null) {
277 return service;
278 }
279 return mCachedInstance = createStaticService();
280 }
281 }
282
283 public abstract Object createStaticService();
284 }
285
286 private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
287 new HashMap<String, ServiceFetcher>();
288
289 private static int sNextPerContextServiceCacheIndex = 0;
290 private static void registerService(String serviceName, ServiceFetcher fetcher) {
291 if (!(fetcher instanceof StaticServiceFetcher)) {
292 fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
293 }
294 SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
295 }
296
297 // This one's defined separately and given a variable name so it
298 // can be re-used by getWallpaperManager(), avoiding a HashMap
299 // lookup.
300 private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
301 public Object createService(ContextImpl ctx) {
302 return new WallpaperManager(ctx.getOuterContext(),
303 ctx.mMainThread.getHandler());
304 }};
305
306 static {
307 registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
308 public Object getService(ContextImpl ctx) {
309 return AccessibilityManager.getInstance(ctx);
310 }});
311
Alan Viverette69ce69b2013-08-29 12:23:48 -0700312 registerService(CAPTIONING_SERVICE, new ServiceFetcher() {
313 public Object getService(ContextImpl ctx) {
314 return new CaptioningManager(ctx);
315 }});
316
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800317 registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
318 public Object createService(ContextImpl ctx) {
319 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
320 IAccountManager service = IAccountManager.Stub.asInterface(b);
321 return new AccountManager(ctx, service);
322 }});
323
324 registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
325 public Object createService(ContextImpl ctx) {
326 return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
327 }});
328
Christopher Tatee0a22b32013-07-11 14:43:13 -0700329 registerService(ALARM_SERVICE, new ServiceFetcher() {
330 public Object createService(ContextImpl ctx) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800331 IBinder b = ServiceManager.getService(ALARM_SERVICE);
332 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
Christopher Tatee0a22b32013-07-11 14:43:13 -0700333 return new AlarmManager(service, ctx);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800334 }});
335
336 registerService(AUDIO_SERVICE, new ServiceFetcher() {
337 public Object createService(ContextImpl ctx) {
338 return new AudioManager(ctx);
339 }});
340
Dianne Hackbornb58b8f82012-06-11 15:08:39 -0700341 registerService(MEDIA_ROUTER_SERVICE, new ServiceFetcher() {
342 public Object createService(ContextImpl ctx) {
343 return new MediaRouter(ctx);
344 }});
345
Jaikumar Ganesh1abb1cb2012-01-25 16:14:50 -0800346 registerService(BLUETOOTH_SERVICE, new ServiceFetcher() {
347 public Object createService(ContextImpl ctx) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800348 return new BluetoothManager(ctx);
Jaikumar Ganesh1abb1cb2012-01-25 16:14:50 -0800349 }});
350
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800351 registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
352 public Object createService(ContextImpl ctx) {
353 return new ClipboardManager(ctx.getOuterContext(),
354 ctx.mMainThread.getHandler());
355 }});
356
357 registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
358 public Object createStaticService() {
359 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
360 return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
361 }});
362
363 registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
364 public Object createStaticService() {
365 IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
366 return new CountryDetector(ICountryDetector.Stub.asInterface(b));
367 }});
368
369 registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
370 public Object createService(ContextImpl ctx) {
371 return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
372 }});
373
374 registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
375 public Object createService(ContextImpl ctx) {
376 return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
377 }});
378
Nick Pellyd2507462010-12-13 12:22:34 -0800379 registerService(NFC_SERVICE, new ServiceFetcher() {
380 public Object createService(ContextImpl ctx) {
381 return new NfcManager(ctx);
382 }});
383
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800384 registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
385 public Object createStaticService() {
386 return createDropBoxManager();
387 }});
388
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700389 registerService(INPUT_SERVICE, new StaticServiceFetcher() {
390 public Object createStaticService() {
391 return InputManager.getInstance();
Jeff Brownac143512012-04-05 18:57:33 -0700392 }});
Jeff Brown9df6e7a2012-04-05 11:49:26 -0700393
Jeff Brownbd6e1502012-08-28 03:27:37 -0700394 registerService(DISPLAY_SERVICE, new ServiceFetcher() {
395 @Override
396 public Object createService(ContextImpl ctx) {
397 return new DisplayManager(ctx.getOuterContext());
398 }});
Jeff Brownfa25bf52012-07-23 19:26:30 -0700399
Jeff Brownf9e989d2013-04-04 23:04:03 -0700400 registerService(INPUT_METHOD_SERVICE, new StaticServiceFetcher() {
401 public Object createStaticService() {
402 return InputMethodManager.getInstance();
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800403 }});
404
satok988323c2011-06-22 16:38:13 +0900405 registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
406 public Object createService(ContextImpl ctx) {
407 return TextServicesManager.getInstance();
408 }});
409
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800410 registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
411 public Object getService(ContextImpl ctx) {
412 // TODO: why isn't this caching it? It wasn't
413 // before, so I'm preserving the old behavior and
414 // using getService(), instead of createService()
415 // which would do the caching.
416 return new KeyguardManager();
417 }});
418
419 registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
420 public Object createService(ContextImpl ctx) {
421 return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
422 }});
423
Nick Pellye0fd6932012-07-11 10:26:13 -0700424 registerService(LOCATION_SERVICE, new ServiceFetcher() {
425 public Object createService(ContextImpl ctx) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800426 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
Nick Pellye0fd6932012-07-11 10:26:13 -0700427 return new LocationManager(ctx, ILocationManager.Stub.asInterface(b));
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800428 }});
429
Jeff Sharkey1a303952011-06-16 13:04:20 -0700430 registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
431 @Override
432 public Object createService(ContextImpl ctx) {
433 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
434 ServiceManager.getService(NETWORK_POLICY_SERVICE)));
435 }
436 });
437
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800438 registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
439 public Object createService(ContextImpl ctx) {
440 final Context outerContext = ctx.getOuterContext();
441 return new NotificationManager(
442 new ContextThemeWrapper(outerContext,
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800443 Resources.selectSystemTheme(0,
444 outerContext.getApplicationInfo().targetSdkVersion,
445 com.android.internal.R.style.Theme_Dialog,
Adam Powell6e90a362011-08-14 16:48:32 -0700446 com.android.internal.R.style.Theme_Holo_Dialog,
447 com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800448 ctx.mMainThread.getHandler());
449 }});
450
Irfan Sheriff7d024d32012-03-22 17:01:39 -0700451 registerService(NSD_SERVICE, new ServiceFetcher() {
452 @Override
453 public Object createService(ContextImpl ctx) {
454 IBinder b = ServiceManager.getService(NSD_SERVICE);
455 INsdManager service = INsdManager.Stub.asInterface(b);
Irfan Sheriff22af38c2012-05-03 16:44:27 -0700456 return new NsdManager(ctx.getOuterContext(), service);
Irfan Sheriff7d024d32012-03-22 17:01:39 -0700457 }});
458
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800459 // Note: this was previously cached in a static variable, but
460 // constructed using mMainThread.getHandler(), so converting
461 // it to be a regular Context-cached service...
462 registerService(POWER_SERVICE, new ServiceFetcher() {
463 public Object createService(ContextImpl ctx) {
464 IBinder b = ServiceManager.getService(POWER_SERVICE);
465 IPowerManager service = IPowerManager.Stub.asInterface(b);
Jeff Brown96307042012-07-27 15:51:34 -0700466 return new PowerManager(ctx.getOuterContext(),
467 service, ctx.mMainThread.getHandler());
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800468 }});
469
470 registerService(SEARCH_SERVICE, new ServiceFetcher() {
471 public Object createService(ContextImpl ctx) {
472 return new SearchManager(ctx.getOuterContext(),
473 ctx.mMainThread.getHandler());
474 }});
475
476 registerService(SENSOR_SERVICE, new ServiceFetcher() {
477 public Object createService(ContextImpl ctx) {
Jaikumar Ganesh6d0c1d72013-03-27 17:41:33 -0700478 return new SystemSensorManager(ctx.getOuterContext(),
479 ctx.mMainThread.getHandler().getLooper());
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800480 }});
481
482 registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
483 public Object createService(ContextImpl ctx) {
484 return new StatusBarManager(ctx.getOuterContext());
485 }});
486
487 registerService(STORAGE_SERVICE, new ServiceFetcher() {
488 public Object createService(ContextImpl ctx) {
489 try {
Jeff Sharkeybe722152013-02-15 16:56:38 -0800490 return new StorageManager(
491 ctx.getContentResolver(), ctx.mMainThread.getHandler().getLooper());
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800492 } catch (RemoteException rex) {
493 Log.e(TAG, "Failed to create StorageManager", rex);
494 return null;
495 }
496 }});
497
498 registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
499 public Object createService(ContextImpl ctx) {
500 return new TelephonyManager(ctx.getOuterContext());
501 }});
502
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800503 registerService(UI_MODE_SERVICE, new ServiceFetcher() {
504 public Object createService(ContextImpl ctx) {
505 return new UiModeManager();
506 }});
507
Mike Lockwood3a68b832011-03-08 10:08:59 -0500508 registerService(USB_SERVICE, new ServiceFetcher() {
509 public Object createService(ContextImpl ctx) {
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500510 IBinder b = ServiceManager.getService(USB_SERVICE);
Mike Lockwood3a68b832011-03-08 10:08:59 -0500511 return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
Mike Lockwoode7d511e2010-12-30 13:39:37 -0500512 }});
513
Mike Lockwoodb01e8bf2011-08-29 20:11:07 -0400514 registerService(SERIAL_SERVICE, new ServiceFetcher() {
515 public Object createService(ContextImpl ctx) {
516 IBinder b = ServiceManager.getService(SERIAL_SERVICE);
517 return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
518 }});
519
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800520 registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
521 public Object createService(ContextImpl ctx) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800522 return new SystemVibrator(ctx);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800523 }});
524
525 registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
526
527 registerService(WIFI_SERVICE, new ServiceFetcher() {
528 public Object createService(ContextImpl ctx) {
529 IBinder b = ServiceManager.getService(WIFI_SERVICE);
530 IWifiManager service = IWifiManager.Stub.asInterface(b);
Irfan Sheriff88759bb2012-07-02 15:58:28 -0700531 return new WifiManager(ctx.getOuterContext(), service);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800532 }});
533
repo sync55bc5f32011-06-24 14:23:07 -0700534 registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
535 public Object createService(ContextImpl ctx) {
536 IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
537 IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
538 return new WifiP2pManager(service);
539 }});
540
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800541 registerService(WINDOW_SERVICE, new ServiceFetcher() {
Romain Guye50848b2013-06-07 10:57:25 -0700542 Display mDefaultDisplay;
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800543 public Object getService(ContextImpl ctx) {
Jeff Browna492c3a2012-08-23 19:48:44 -0700544 Display display = ctx.mDisplay;
545 if (display == null) {
Romain Guye50848b2013-06-07 10:57:25 -0700546 if (mDefaultDisplay == null) {
547 DisplayManager dm = (DisplayManager)ctx.getOuterContext().
548 getSystemService(Context.DISPLAY_SERVICE);
549 mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
550 }
551 display = mDefaultDisplay;
Jeff Browna492c3a2012-08-23 19:48:44 -0700552 }
553 return new WindowManagerImpl(display);
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800554 }});
Amith Yamasani258848d2012-08-10 17:06:33 -0700555
556 registerService(USER_SERVICE, new ServiceFetcher() {
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800557 public Object createService(ContextImpl ctx) {
Amith Yamasani258848d2012-08-10 17:06:33 -0700558 IBinder b = ServiceManager.getService(USER_SERVICE);
559 IUserManager service = IUserManager.Stub.asInterface(b);
560 return new UserManager(ctx, service);
561 }});
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800562
563 registerService(APP_OPS_SERVICE, new ServiceFetcher() {
564 public Object createService(ContextImpl ctx) {
565 IBinder b = ServiceManager.getService(APP_OPS_SERVICE);
566 IAppOpsService service = IAppOpsService.Stub.asInterface(b);
567 return new AppOpsManager(ctx, service);
568 }});
Eino-Ville Talvalab2675542012-12-12 13:29:45 -0800569
Igor Murashkine363fbb2013-06-25 20:26:06 +0000570 registerService(CAMERA_SERVICE, new ServiceFetcher() {
571 public Object createService(ContextImpl ctx) {
572 return new CameraManager(ctx);
Svetoslav Ganov4b9a4d12013-06-11 15:20:06 -0700573 }
574 });
575
576 registerService(PRINT_SERVICE, new ServiceFetcher() {
577 public Object createService(ContextImpl ctx) {
578 IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
579 IPrintManager service = IPrintManager.Stub.asInterface(iBinder);
580 return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(),
581 UserHandle.getAppId(Process.myUid()));
Eino-Ville Talvalab2675542012-12-12 13:29:45 -0800582 }});
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800583 }
584
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700585 static ContextImpl getImpl(Context context) {
586 Context nextContext;
587 while ((context instanceof ContextWrapper) &&
588 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
589 context = nextContext;
590 }
591 return (ContextImpl)context;
592 }
593
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -0800594 // The system service cache for the system services that are
595 // cached per-ContextImpl. Package-scoped to avoid accessor
596 // methods.
597 final ArrayList<Object> mServiceCache = new ArrayList<Object>();
598
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599 @Override
600 public AssetManager getAssets() {
Dianne Hackborn756220b2012-08-14 16:45:30 -0700601 return getResources().getAssets();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 }
603
604 @Override
605 public Resources getResources() {
606 return mResources;
607 }
608
609 @Override
610 public PackageManager getPackageManager() {
611 if (mPackageManager != null) {
612 return mPackageManager;
613 }
614
615 IPackageManager pm = ActivityThread.getPackageManager();
616 if (pm != null) {
617 // Doesn't matter if we make more than one instance.
618 return (mPackageManager = new ApplicationPackageManager(this, pm));
619 }
620
621 return null;
622 }
623
624 @Override
625 public ContentResolver getContentResolver() {
626 return mContentResolver;
627 }
628
629 @Override
630 public Looper getMainLooper() {
631 return mMainThread.getLooper();
632 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 @Override
635 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700636 return (mPackageInfo != null) ?
637 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 @Override
641 public void setTheme(int resid) {
642 mThemeResource = resid;
643 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 @Override
Dianne Hackborn247fe742011-01-08 17:25:57 -0800646 public int getThemeResId() {
647 return mThemeResource;
648 }
649
650 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 public Resources.Theme getTheme() {
652 if (mTheme == null) {
Dianne Hackbornd922ae02011-01-14 11:43:24 -0800653 mThemeResource = Resources.selectDefaultTheme(mThemeResource,
654 getOuterContext().getApplicationInfo().targetSdkVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 mTheme = mResources.newTheme();
656 mTheme.applyStyle(mThemeResource, true);
657 }
658 return mTheme;
659 }
660
661 @Override
662 public ClassLoader getClassLoader() {
663 return mPackageInfo != null ?
664 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
665 }
666
667 @Override
668 public String getPackageName() {
669 if (mPackageInfo != null) {
670 return mPackageInfo.getPackageName();
671 }
Dianne Hackborn35654b62013-01-14 17:38:02 -0800672 // No mPackageInfo means this is a Context for the system itself,
673 // and this here is its name.
674 return "android";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800675 }
676
Dianne Hackbornd8e1dbb2013-01-17 17:47:37 -0800677 /** @hide */
678 @Override
679 public String getBasePackageName() {
680 return mBasePackageName != null ? mBasePackageName : getPackageName();
681 }
682
Dianne Hackborn95d78532013-09-11 09:51:14 -0700683 /** @hide */
684 @Override
685 public String getOpPackageName() {
686 return mOpPackageName != null ? mOpPackageName : getBasePackageName();
687 }
688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700690 public ApplicationInfo getApplicationInfo() {
691 if (mPackageInfo != null) {
692 return mPackageInfo.getApplicationInfo();
693 }
694 throw new RuntimeException("Not supported in system context");
695 }
696
697 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800698 public String getPackageResourcePath() {
699 if (mPackageInfo != null) {
700 return mPackageInfo.getResDir();
701 }
702 throw new RuntimeException("Not supported in system context");
703 }
704
705 @Override
706 public String getPackageCodePath() {
707 if (mPackageInfo != null) {
708 return mPackageInfo.getAppDir();
709 }
710 throw new RuntimeException("Not supported in system context");
711 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200712
Joe Onorato23ecae32009-06-10 17:07:15 -0700713 public File getSharedPrefsFile(String name) {
714 return makeFilename(getPreferencesDir(), name + ".xml");
715 }
716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 @Override
718 public SharedPreferences getSharedPreferences(String name, int mode) {
719 SharedPreferencesImpl sp;
Dianne Hackbornf6913592013-09-05 13:21:24 -0700720 synchronized (ContextImpl.class) {
Jeff Sharkey8e3ddab2013-06-17 18:26:37 -0700721 if (sSharedPrefs == null) {
722 sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
723 }
724
725 final String packageName = getPackageName();
726 ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
727 if (packagePrefs == null) {
728 packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
729 sSharedPrefs.put(packageName, packagePrefs);
730 }
731
Dianne Hackbornff32f352013-07-18 17:31:13 -0700732 // At least one application in the world actually passes in a null
733 // name. This happened to work because when we generated the file name
734 // we would stringify it to "null.xml". Nice.
735 if (mPackageInfo.getApplicationInfo().targetSdkVersion <
Chet Haasee8222dd2013-09-05 07:44:18 -0700736 Build.VERSION_CODES.KITKAT) {
Dianne Hackbornff32f352013-07-18 17:31:13 -0700737 if (name == null) {
738 name = "null";
739 }
740 }
741
Jeff Sharkey8e3ddab2013-06-17 18:26:37 -0700742 sp = packagePrefs.get(name);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700743 if (sp == null) {
Brad Fitzpatrick4cd50b82010-12-01 17:31:45 -0800744 File prefsFile = getSharedPrefsFile(name);
745 sp = new SharedPreferencesImpl(prefsFile, mode);
Jeff Sharkey8e3ddab2013-06-17 18:26:37 -0700746 packagePrefs.put(name, sp);
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700747 return sp;
748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 }
Brad Fitzpatrick4e920f72010-12-14 11:52:13 -0800750 if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
751 getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
752 // If somebody else (some other process) changed the prefs
753 // file behind our back, we reload it. This has been the
754 // historical (if undocumented) behavior.
755 sp.startReloadIfChangedUnexpectedly();
756 }
Brad Fitzpatrick6194c532010-09-07 18:00:33 -0700757 return sp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800758 }
759
760 private File getPreferencesDir() {
761 synchronized (mSync) {
762 if (mPreferencesDir == null) {
763 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
764 }
765 return mPreferencesDir;
766 }
767 }
768
769 @Override
770 public FileInputStream openFileInput(String name)
771 throws FileNotFoundException {
772 File f = makeFilename(getFilesDir(), name);
773 return new FileInputStream(f);
774 }
775
776 @Override
777 public FileOutputStream openFileOutput(String name, int mode)
778 throws FileNotFoundException {
779 final boolean append = (mode&MODE_APPEND) != 0;
780 File f = makeFilename(getFilesDir(), name);
781 try {
782 FileOutputStream fos = new FileOutputStream(f, append);
783 setFilePermissionsFromMode(f.getPath(), mode, 0);
784 return fos;
785 } catch (FileNotFoundException e) {
786 }
787
788 File parent = f.getParentFile();
789 parent.mkdir();
790 FileUtils.setPermissions(
791 parent.getPath(),
792 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
793 -1, -1);
794 FileOutputStream fos = new FileOutputStream(f, append);
795 setFilePermissionsFromMode(f.getPath(), mode, 0);
796 return fos;
797 }
798
799 @Override
800 public boolean deleteFile(String name) {
801 File f = makeFilename(getFilesDir(), name);
802 return f.delete();
803 }
804
805 @Override
806 public File getFilesDir() {
807 synchronized (mSync) {
808 if (mFilesDir == null) {
809 mFilesDir = new File(getDataDirFile(), "files");
810 }
811 if (!mFilesDir.exists()) {
812 if(!mFilesDir.mkdirs()) {
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200813 Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800814 return null;
815 }
816 FileUtils.setPermissions(
817 mFilesDir.getPath(),
818 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
819 -1, -1);
820 }
821 return mFilesDir;
822 }
823 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200824
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800825 @Override
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800826 public File getExternalFilesDir(String type) {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700827 // Operates on primary external storage
828 return getExternalFilesDirs(type)[0];
829 }
830
831 @Override
832 public File[] getExternalFilesDirs(String type) {
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800833 synchronized (mSync) {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700834 if (mExternalFilesDirs == null) {
835 mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName());
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800836 }
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700837
838 // Splice in requested type, if any
839 File[] dirs = mExternalFilesDirs;
840 if (type != null) {
841 dirs = Environment.buildPaths(dirs, type);
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800842 }
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700843
844 // Create dirs if needed
845 return ensureDirsExistOrFilter(dirs);
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800846 }
847 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200848
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800849 @Override
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800850 public File getObbDir() {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700851 // Operates on primary external storage
852 return getObbDirs()[0];
853 }
854
855 @Override
856 public File[] getObbDirs() {
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800857 synchronized (mSync) {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700858 if (mExternalObbDirs == null) {
859 mExternalObbDirs = Environment.buildExternalStorageAppObbDirs(getPackageName());
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800860 }
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700861 return mExternalObbDirs;
Dianne Hackborn805fd7e2011-01-16 18:30:29 -0800862 }
863 }
864
865 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 public File getCacheDir() {
867 synchronized (mSync) {
868 if (mCacheDir == null) {
869 mCacheDir = new File(getDataDirFile(), "cache");
870 }
871 if (!mCacheDir.exists()) {
872 if(!mCacheDir.mkdirs()) {
Amith Yamasani92d57052012-08-23 10:07:52 -0700873 Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 return null;
875 }
876 FileUtils.setPermissions(
877 mCacheDir.getPath(),
878 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
879 -1, -1);
880 }
881 }
882 return mCacheDir;
883 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200884
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800885 @Override
886 public File getExternalCacheDir() {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700887 // Operates on primary external storage
888 return getExternalCacheDirs()[0];
889 }
890
891 @Override
892 public File[] getExternalCacheDirs() {
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800893 synchronized (mSync) {
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700894 if (mExternalCacheDirs == null) {
895 mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName());
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800896 }
Jeff Sharkey1abdb712013-08-11 16:28:14 -0700897
898 // Create dirs if needed
899 return ensureDirsExistOrFilter(mExternalCacheDirs);
Dianne Hackborne83cefc2010-02-04 17:38:14 -0800900 }
901 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 @Override
904 public File getFileStreamPath(String name) {
905 return makeFilename(getFilesDir(), name);
906 }
907
908 @Override
909 public String[] fileList() {
910 final String[] list = getFilesDir().list();
911 return (list != null) ? list : EMPTY_FILE_LIST;
912 }
913
914 @Override
915 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Jeff Brown47847f32012-03-22 19:13:11 -0700916 return openOrCreateDatabase(name, mode, factory, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 }
918
919 @Override
Vasu Nori74f170f2010-06-01 18:06:18 -0700920 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
921 DatabaseErrorHandler errorHandler) {
922 File f = validateFilePath(name, true);
Jeff Brown47847f32012-03-22 19:13:11 -0700923 int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
924 if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
925 flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
926 }
927 SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
Vasu Nori74f170f2010-06-01 18:06:18 -0700928 setFilePermissionsFromMode(f.getPath(), mode, 0);
929 return db;
930 }
931
932 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 public boolean deleteDatabase(String name) {
934 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800935 File f = validateFilePath(name, false);
Jeff Brown79087e42012-03-01 19:52:44 -0800936 return SQLiteDatabase.deleteDatabase(f);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 } catch (Exception e) {
938 }
939 return false;
940 }
941
942 @Override
943 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800944 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 }
946
947 @Override
948 public String[] databaseList() {
949 final String[] list = getDatabasesDir().list();
950 return (list != null) ? list : EMPTY_FILE_LIST;
951 }
952
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800954 private File getDatabasesDir() {
955 synchronized (mSync) {
956 if (mDatabasesDir == null) {
957 mDatabasesDir = new File(getDataDirFile(), "databases");
958 }
959 if (mDatabasesDir.getPath().equals("databases")) {
960 mDatabasesDir = new File("/data/system");
961 }
962 return mDatabasesDir;
963 }
964 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +0200965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 @Override
967 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700968 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 }
970
971 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700972 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700973 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 }
975
976 @Override
977 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700978 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 }
980
981 @Override
982 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700983 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 }
985
986 @Override
987 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700988 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 }
990
991 @Override
992 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700993 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994 }
995
996 @Override
997 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700998 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 }
1000
1001 @Override
1002 public void startActivity(Intent intent) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001003 warnIfCallingFromSystemProcess();
Dianne Hackborna4972e92012-03-14 10:38:05 -07001004 startActivity(intent, null);
1005 }
1006
Amith Yamasani82644082012-08-03 13:09:11 -07001007 /** @hide */
1008 @Override
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001009 public void startActivityAsUser(Intent intent, UserHandle user) {
Dianne Hackbornf1c26e22012-08-23 13:54:58 -07001010 startActivityAsUser(intent, null, user);
Amith Yamasani82644082012-08-03 13:09:11 -07001011 }
1012
Dianne Hackborna4972e92012-03-14 10:38:05 -07001013 @Override
1014 public void startActivity(Intent intent, Bundle options) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001015 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1017 throw new AndroidRuntimeException(
1018 "Calling startActivity() from outside of an Activity "
1019 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
1020 + " Is this really what you want?");
1021 }
1022 mMainThread.getInstrumentation().execStartActivity(
Dianne Hackborn6e8304e2010-05-14 00:42:53 -07001023 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -07001024 (Activity)null, intent, -1, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 }
1026
Amith Yamasani258848d2012-08-10 17:06:33 -07001027 /** @hide */
1028 @Override
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001029 public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
Amith Yamasani258848d2012-08-10 17:06:33 -07001030 try {
1031 ActivityManagerNative.getDefault().startActivityAsUser(
Dianne Hackbornf265ea92013-01-31 15:00:51 -08001032 mMainThread.getApplicationThread(), getBasePackageName(), intent,
Amith Yamasani258848d2012-08-10 17:06:33 -07001033 intent.resolveTypeIfNeeded(getContentResolver()),
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001034 null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
1035 user.getIdentifier());
Amith Yamasani258848d2012-08-10 17:06:33 -07001036 } catch (RemoteException re) {
1037 }
1038 }
1039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040 @Override
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001041 public void startActivities(Intent[] intents) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001042 warnIfCallingFromSystemProcess();
Dianne Hackborna4972e92012-03-14 10:38:05 -07001043 startActivities(intents, null);
1044 }
1045
Amith Yamasaniea7e9152012-09-24 16:11:18 -07001046 /** @hide */
1047 @Override
1048 public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
1049 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1050 throw new AndroidRuntimeException(
1051 "Calling startActivities() from outside of an Activity "
1052 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1053 + " Is this really what you want?");
1054 }
1055 mMainThread.getInstrumentation().execStartActivitiesAsUser(
1056 getOuterContext(), mMainThread.getApplicationThread(), null,
1057 (Activity)null, intents, options, userHandle.getIdentifier());
1058 }
1059
Dianne Hackborna4972e92012-03-14 10:38:05 -07001060 @Override
1061 public void startActivities(Intent[] intents, Bundle options) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001062 warnIfCallingFromSystemProcess();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001063 if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1064 throw new AndroidRuntimeException(
1065 "Calling startActivities() from outside of an Activity "
1066 + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1067 + " Is this really what you want?");
1068 }
1069 mMainThread.getInstrumentation().execStartActivities(
1070 getOuterContext(), mMainThread.getApplicationThread(), null,
Dianne Hackborna4972e92012-03-14 10:38:05 -07001071 (Activity)null, intents, options);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001072 }
1073
1074 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -07001075 public void startIntentSender(IntentSender intent,
1076 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1077 throws IntentSender.SendIntentException {
Dianne Hackborna4972e92012-03-14 10:38:05 -07001078 startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
1079 }
1080
1081 @Override
1082 public void startIntentSender(IntentSender intent, Intent fillInIntent,
1083 int flagsMask, int flagsValues, int extraFlags, Bundle options)
1084 throws IntentSender.SendIntentException {
Dianne Hackbornfa82f222009-09-17 15:14:12 -07001085 try {
1086 String resolvedType = null;
1087 if (fillInIntent != null) {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001088 fillInIntent.migrateExtraStreamToClipData();
1089 fillInIntent.prepareToLeaveProcess();
Dianne Hackbornfa82f222009-09-17 15:14:12 -07001090 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
1091 }
1092 int result = ActivityManagerNative.getDefault()
1093 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
1094 fillInIntent, resolvedType, null, null,
Dianne Hackborna4972e92012-03-14 10:38:05 -07001095 0, flagsMask, flagsValues, options);
1096 if (result == ActivityManager.START_CANCELED) {
Dianne Hackbornfa82f222009-09-17 15:14:12 -07001097 throw new IntentSender.SendIntentException();
1098 }
1099 Instrumentation.checkStartActivityResult(result, null);
1100 } catch (RemoteException e) {
1101 }
1102 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02001103
Dianne Hackbornfa82f222009-09-17 15:14:12 -07001104 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001105 public void sendBroadcast(Intent intent) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001106 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1108 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001109 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 ActivityManagerNative.getDefault().broadcastIntent(
1111 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001112 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001113 getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 } catch (RemoteException e) {
1115 }
1116 }
1117
Amith Yamasani67cf7d32012-02-16 14:31:23 -08001118 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001119 public void sendBroadcast(Intent intent, String receiverPermission) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001120 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1122 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001123 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 ActivityManagerNative.getDefault().broadcastIntent(
1125 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001126 Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
1127 false, false, getUserId());
1128 } catch (RemoteException e) {
1129 }
1130 }
1131
1132 @Override
1133 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1134 warnIfCallingFromSystemProcess();
1135 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1136 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001137 intent.prepareToLeaveProcess();
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001138 ActivityManagerNative.getDefault().broadcastIntent(
1139 mMainThread.getApplicationThread(), intent, resolvedType, null,
1140 Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001141 getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 } catch (RemoteException e) {
1143 }
1144 }
1145
1146 @Override
1147 public void sendOrderedBroadcast(Intent intent,
1148 String receiverPermission) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001149 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001150 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1151 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001152 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 ActivityManagerNative.getDefault().broadcastIntent(
1154 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001155 Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false,
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001156 getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001157 } catch (RemoteException e) {
1158 }
1159 }
1160
1161 @Override
1162 public void sendOrderedBroadcast(Intent intent,
1163 String receiverPermission, BroadcastReceiver resultReceiver,
1164 Handler scheduler, int initialCode, String initialData,
1165 Bundle initialExtras) {
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001166 sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
1167 resultReceiver, scheduler, initialCode, initialData, initialExtras);
1168 }
1169
1170 @Override
1171 public void sendOrderedBroadcast(Intent intent,
1172 String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1173 Handler scheduler, int initialCode, String initialData,
1174 Bundle initialExtras) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001175 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 IIntentReceiver rd = null;
1177 if (resultReceiver != null) {
1178 if (mPackageInfo != null) {
1179 if (scheduler == null) {
1180 scheduler = mMainThread.getHandler();
1181 }
1182 rd = mPackageInfo.getReceiverDispatcher(
1183 resultReceiver, getOuterContext(), scheduler,
1184 mMainThread.getInstrumentation(), false);
1185 } else {
1186 if (scheduler == null) {
1187 scheduler = mMainThread.getHandler();
1188 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001189 rd = new LoadedApk.ReceiverDispatcher(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1191 }
1192 }
1193 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1194 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001195 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 ActivityManagerNative.getDefault().broadcastIntent(
1197 mMainThread.getApplicationThread(), intent, resolvedType, rd,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001198 initialCode, initialData, initialExtras, receiverPermission, appOp,
1199 true, false, getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 } catch (RemoteException e) {
1201 }
1202 }
1203
1204 @Override
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001205 public void sendBroadcastAsUser(Intent intent, UserHandle user) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001206 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1207 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001208 intent.prepareToLeaveProcess();
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001209 ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001210 intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
1211 AppOpsManager.OP_NONE, false, false, user.getIdentifier());
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001212 } catch (RemoteException e) {
1213 }
1214 }
1215
1216 @Override
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001217 public void sendBroadcastAsUser(Intent intent, UserHandle user,
1218 String receiverPermission) {
1219 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1220 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001221 intent.prepareToLeaveProcess();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001222 ActivityManagerNative.getDefault().broadcastIntent(
1223 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001224 Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, false, false,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001225 user.getIdentifier());
1226 } catch (RemoteException e) {
1227 }
1228 }
1229
1230 @Override
Dianne Hackborn79af1dd2012-08-16 16:42:52 -07001231 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001232 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001233 int initialCode, String initialData, Bundle initialExtras) {
1234 IIntentReceiver rd = null;
1235 if (resultReceiver != null) {
1236 if (mPackageInfo != null) {
1237 if (scheduler == null) {
1238 scheduler = mMainThread.getHandler();
1239 }
1240 rd = mPackageInfo.getReceiverDispatcher(
1241 resultReceiver, getOuterContext(), scheduler,
1242 mMainThread.getInstrumentation(), false);
1243 } else {
1244 if (scheduler == null) {
1245 scheduler = mMainThread.getHandler();
1246 }
1247 rd = new LoadedApk.ReceiverDispatcher(
1248 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1249 }
1250 }
1251 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1252 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001253 intent.prepareToLeaveProcess();
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001254 ActivityManagerNative.getDefault().broadcastIntent(
1255 mMainThread.getApplicationThread(), intent, resolvedType, rd,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001256 initialCode, initialData, initialExtras, receiverPermission,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001257 AppOpsManager.OP_NONE, true, false, user.getIdentifier());
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001258 } catch (RemoteException e) {
1259 }
1260 }
1261
1262 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 public void sendStickyBroadcast(Intent intent) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001264 warnIfCallingFromSystemProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1266 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001267 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 ActivityManagerNative.getDefault().broadcastIntent(
1269 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001270 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true,
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001271 getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001272 } catch (RemoteException e) {
1273 }
1274 }
1275
1276 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001277 public void sendStickyOrderedBroadcast(Intent intent,
1278 BroadcastReceiver resultReceiver,
1279 Handler scheduler, int initialCode, String initialData,
1280 Bundle initialExtras) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001281 warnIfCallingFromSystemProcess();
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001282 IIntentReceiver rd = null;
1283 if (resultReceiver != null) {
1284 if (mPackageInfo != null) {
1285 if (scheduler == null) {
1286 scheduler = mMainThread.getHandler();
1287 }
1288 rd = mPackageInfo.getReceiverDispatcher(
1289 resultReceiver, getOuterContext(), scheduler,
1290 mMainThread.getInstrumentation(), false);
1291 } else {
1292 if (scheduler == null) {
1293 scheduler = mMainThread.getHandler();
1294 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001295 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001296 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1297 }
1298 }
1299 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1300 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001301 intent.prepareToLeaveProcess();
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001302 ActivityManagerNative.getDefault().broadcastIntent(
1303 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1304 initialCode, initialData, initialExtras, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001305 AppOpsManager.OP_NONE, true, true, getUserId());
Dianne Hackbornefa199f2009-09-19 12:03:15 -07001306 } catch (RemoteException e) {
1307 }
1308 }
1309
1310 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 public void removeStickyBroadcast(Intent intent) {
1312 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1313 if (resolvedType != null) {
1314 intent = new Intent(intent);
1315 intent.setDataAndType(intent.getData(), resolvedType);
1316 }
1317 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001318 intent.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 ActivityManagerNative.getDefault().unbroadcastIntent(
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001320 mMainThread.getApplicationThread(), intent, getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 } catch (RemoteException e) {
1322 }
1323 }
1324
1325 @Override
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001326 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1327 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1328 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001329 intent.prepareToLeaveProcess();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001330 ActivityManagerNative.getDefault().broadcastIntent(
1331 mMainThread.getApplicationThread(), intent, resolvedType, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001332 Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier());
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001333 } catch (RemoteException e) {
1334 }
1335 }
1336
1337 @Override
1338 public void sendStickyOrderedBroadcastAsUser(Intent intent,
1339 UserHandle user, BroadcastReceiver resultReceiver,
1340 Handler scheduler, int initialCode, String initialData,
1341 Bundle initialExtras) {
1342 IIntentReceiver rd = null;
1343 if (resultReceiver != null) {
1344 if (mPackageInfo != null) {
1345 if (scheduler == null) {
1346 scheduler = mMainThread.getHandler();
1347 }
1348 rd = mPackageInfo.getReceiverDispatcher(
1349 resultReceiver, getOuterContext(), scheduler,
1350 mMainThread.getInstrumentation(), false);
1351 } else {
1352 if (scheduler == null) {
1353 scheduler = mMainThread.getHandler();
1354 }
1355 rd = new LoadedApk.ReceiverDispatcher(
1356 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1357 }
1358 }
1359 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1360 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001361 intent.prepareToLeaveProcess();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001362 ActivityManagerNative.getDefault().broadcastIntent(
1363 mMainThread.getApplicationThread(), intent, resolvedType, rd,
1364 initialCode, initialData, initialExtras, null,
Dianne Hackbornf51f6122013-02-04 18:23:34 -08001365 AppOpsManager.OP_NONE, true, true, user.getIdentifier());
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001366 } catch (RemoteException e) {
1367 }
1368 }
1369
1370 @Override
1371 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1372 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1373 if (resolvedType != null) {
1374 intent = new Intent(intent);
1375 intent.setDataAndType(intent.getData(), resolvedType);
1376 }
1377 try {
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001378 intent.prepareToLeaveProcess();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001379 ActivityManagerNative.getDefault().unbroadcastIntent(
1380 mMainThread.getApplicationThread(), intent, user.getIdentifier());
1381 } catch (RemoteException e) {
1382 }
1383 }
1384
1385 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1387 return registerReceiver(receiver, filter, null, null);
1388 }
1389
1390 @Override
1391 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1392 String broadcastPermission, Handler scheduler) {
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001393 return registerReceiverInternal(receiver, getUserId(),
Dianne Hackborn20e80982012-08-31 19:00:44 -07001394 filter, broadcastPermission, scheduler, getOuterContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 }
1396
Dianne Hackborn20e80982012-08-31 19:00:44 -07001397 @Override
1398 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1399 IntentFilter filter, String broadcastPermission, Handler scheduler) {
1400 return registerReceiverInternal(receiver, user.getIdentifier(),
1401 filter, broadcastPermission, scheduler, getOuterContext());
1402 }
1403
1404 private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 IntentFilter filter, String broadcastPermission,
1406 Handler scheduler, Context context) {
1407 IIntentReceiver rd = null;
1408 if (receiver != null) {
1409 if (mPackageInfo != null && context != null) {
1410 if (scheduler == null) {
1411 scheduler = mMainThread.getHandler();
1412 }
1413 rd = mPackageInfo.getReceiverDispatcher(
1414 receiver, context, scheduler,
1415 mMainThread.getInstrumentation(), true);
1416 } else {
1417 if (scheduler == null) {
1418 scheduler = mMainThread.getHandler();
1419 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001420 rd = new LoadedApk.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001421 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 }
1424 try {
1425 return ActivityManagerNative.getDefault().registerReceiver(
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001426 mMainThread.getApplicationThread(), mBasePackageName,
Dianne Hackborn20e80982012-08-31 19:00:44 -07001427 rd, filter, broadcastPermission, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 } catch (RemoteException e) {
1429 return null;
1430 }
1431 }
1432
1433 @Override
1434 public void unregisterReceiver(BroadcastReceiver receiver) {
1435 if (mPackageInfo != null) {
1436 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1437 getOuterContext(), receiver);
1438 try {
1439 ActivityManagerNative.getDefault().unregisterReceiver(rd);
1440 } catch (RemoteException e) {
1441 }
1442 } else {
1443 throw new RuntimeException("Not supported in system context");
1444 }
1445 }
1446
1447 @Override
1448 public ComponentName startService(Intent service) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001449 warnIfCallingFromSystemProcess();
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001450 return startServiceAsUser(service, mUser);
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001451 }
1452
1453 @Override
1454 public boolean stopService(Intent service) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001455 warnIfCallingFromSystemProcess();
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001456 return stopServiceAsUser(service, mUser);
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001457 }
1458
1459 @Override
1460 public ComponentName startServiceAsUser(Intent service, UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 try {
Dianne Hackborn221ea892013-08-04 16:50:16 -07001462 if (service.getComponent() == null && service.getPackage() == null) {
Chet Haasee8222dd2013-09-05 07:44:18 -07001463 if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
Dianne Hackborn221ea892013-08-04 16:50:16 -07001464 IllegalArgumentException ex = new IllegalArgumentException(
1465 "Service Intent must be explicit: " + service);
Dianne Hackborn83524872013-08-05 19:07:41 -07001466 Log.e(TAG, "This will become an error", ex);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001467 //throw ex;
1468 }
1469 }
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001470 service.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 ComponentName cn = ActivityManagerNative.getDefault().startService(
1472 mMainThread.getApplicationThread(), service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001473 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001474 if (cn != null) {
1475 if (cn.getPackageName().equals("!")) {
1476 throw new SecurityException(
1477 "Not allowed to start service " + service
1478 + " without permission " + cn.getClassName());
1479 } else if (cn.getPackageName().equals("!!")) {
1480 throw new SecurityException(
1481 "Unable to start service " + service
1482 + ": " + cn.getClassName());
1483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 }
1485 return cn;
1486 } catch (RemoteException e) {
1487 return null;
1488 }
1489 }
1490
1491 @Override
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001492 public boolean stopServiceAsUser(Intent service, UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 try {
Dianne Hackborn221ea892013-08-04 16:50:16 -07001494 if (service.getComponent() == null && service.getPackage() == null) {
Chet Haasee8222dd2013-09-05 07:44:18 -07001495 if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
Dianne Hackborn221ea892013-08-04 16:50:16 -07001496 IllegalArgumentException ex = new IllegalArgumentException(
1497 "Service Intent must be explicit: " + service);
Dianne Hackborn83524872013-08-05 19:07:41 -07001498 Log.e(TAG, "This will become an error", ex);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001499 //throw ex;
1500 }
1501 }
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001502 service.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 int res = ActivityManagerNative.getDefault().stopService(
1504 mMainThread.getApplicationThread(), service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -07001505 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 if (res < 0) {
1507 throw new SecurityException(
1508 "Not allowed to stop service " + service);
1509 }
1510 return res != 0;
1511 } catch (RemoteException e) {
1512 return false;
1513 }
1514 }
1515
1516 @Override
1517 public boolean bindService(Intent service, ServiceConnection conn,
1518 int flags) {
Amith Yamasanicd757062012-10-19 18:23:52 -07001519 warnIfCallingFromSystemProcess();
Amith Yamasani27b89e62013-01-16 12:30:11 -08001520 return bindServiceAsUser(service, conn, flags, Process.myUserHandle());
Amith Yamasani37ce3a82012-02-06 12:04:42 -08001521 }
1522
1523 /** @hide */
1524 @Override
Amith Yamasani27b89e62013-01-16 12:30:11 -08001525 public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1526 UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001527 IServiceConnection sd;
Christopher Tate79b33172012-06-18 14:54:21 -07001528 if (conn == null) {
1529 throw new IllegalArgumentException("connection is null");
1530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 if (mPackageInfo != null) {
1532 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1533 mMainThread.getHandler(), flags);
1534 } else {
1535 throw new RuntimeException("Not supported in system context");
1536 }
Dianne Hackborn221ea892013-08-04 16:50:16 -07001537 if (service.getComponent() == null && service.getPackage() == null) {
Chet Haasee8222dd2013-09-05 07:44:18 -07001538 if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KITKAT) {
Dianne Hackborn221ea892013-08-04 16:50:16 -07001539 IllegalArgumentException ex = new IllegalArgumentException(
1540 "Service Intent must be explicit: " + service);
Dianne Hackborn83524872013-08-05 19:07:41 -07001541 Log.e(TAG, "This will become an error", ex);
Dianne Hackborn221ea892013-08-04 16:50:16 -07001542 //throw ex;
1543 }
1544 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07001546 IBinder token = getActivityToken();
1547 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1548 && mPackageInfo.getApplicationInfo().targetSdkVersion
1549 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1550 flags |= BIND_WAIVE_PRIORITY;
1551 }
Jeff Sharkeya14acd22013-04-02 18:27:45 -07001552 service.prepareToLeaveProcess();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 int res = ActivityManagerNative.getDefault().bindService(
1554 mMainThread.getApplicationThread(), getActivityToken(),
1555 service, service.resolveTypeIfNeeded(getContentResolver()),
Amith Yamasani27b89e62013-01-16 12:30:11 -08001556 sd, flags, user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001557 if (res < 0) {
1558 throw new SecurityException(
1559 "Not allowed to bind to service " + service);
1560 }
1561 return res != 0;
1562 } catch (RemoteException e) {
1563 return false;
1564 }
1565 }
1566
1567 @Override
1568 public void unbindService(ServiceConnection conn) {
Christopher Tate79b33172012-06-18 14:54:21 -07001569 if (conn == null) {
1570 throw new IllegalArgumentException("connection is null");
1571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 if (mPackageInfo != null) {
1573 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1574 getOuterContext(), conn);
1575 try {
1576 ActivityManagerNative.getDefault().unbindService(sd);
1577 } catch (RemoteException e) {
1578 }
1579 } else {
1580 throw new RuntimeException("Not supported in system context");
1581 }
1582 }
1583
1584 @Override
1585 public boolean startInstrumentation(ComponentName className,
1586 String profileFile, Bundle arguments) {
1587 try {
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04001588 if (arguments != null) {
1589 arguments.setAllowFds(false);
1590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 return ActivityManagerNative.getDefault().startInstrumentation(
Svetoslav Ganov80943d82013-01-02 10:25:37 -08001592 className, profileFile, 0, arguments, null, null, getUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 } catch (RemoteException e) {
1594 // System has crashed, nothing we can do.
1595 }
1596 return false;
1597 }
1598
1599 @Override
1600 public Object getSystemService(String name) {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001601 ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1602 return fetcher == null ? null : fetcher.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 }
1604
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001605 private WallpaperManager getWallpaperManager() {
Brad Fitzpatrick224ba0c2010-11-12 12:22:15 -08001606 return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001607 }
1608
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001609 /* package */ static DropBoxManager createDropBoxManager() {
1610 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1611 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001612 if (service == null) {
1613 // Don't return a DropBoxManager that will NPE upon use.
1614 // This also avoids caching a broken DropBoxManager in
1615 // getDropBoxManager during early boot, before the
1616 // DROPBOX_SERVICE is registered.
1617 return null;
1618 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001619 return new DropBoxManager(service);
1620 }
1621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001622 @Override
1623 public int checkPermission(String permission, int pid, int uid) {
1624 if (permission == null) {
1625 throw new IllegalArgumentException("permission is null");
1626 }
1627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001628 try {
1629 return ActivityManagerNative.getDefault().checkPermission(
1630 permission, pid, uid);
1631 } catch (RemoteException e) {
1632 return PackageManager.PERMISSION_DENIED;
1633 }
1634 }
1635
1636 @Override
1637 public int checkCallingPermission(String permission) {
1638 if (permission == null) {
1639 throw new IllegalArgumentException("permission is null");
1640 }
1641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 int pid = Binder.getCallingPid();
1643 if (pid != Process.myPid()) {
Amith Yamasani742a6712011-05-04 14:49:28 -07001644 return checkPermission(permission, pid, Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
1646 return PackageManager.PERMISSION_DENIED;
1647 }
1648
1649 @Override
1650 public int checkCallingOrSelfPermission(String permission) {
1651 if (permission == null) {
1652 throw new IllegalArgumentException("permission is null");
1653 }
1654
1655 return checkPermission(permission, Binder.getCallingPid(),
1656 Binder.getCallingUid());
1657 }
1658
1659 private void enforce(
1660 String permission, int resultOfCheck,
1661 boolean selfToo, int uid, String message) {
1662 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1663 throw new SecurityException(
1664 (message != null ? (message + ": ") : "") +
1665 (selfToo
1666 ? "Neither user " + uid + " nor current process has "
Christopher Tate4dc7a682012-09-11 12:15:49 -07001667 : "uid " + uid + " does not have ") +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001668 permission +
1669 ".");
1670 }
1671 }
1672
1673 public void enforcePermission(
1674 String permission, int pid, int uid, String message) {
1675 enforce(permission,
1676 checkPermission(permission, pid, uid),
1677 false,
1678 uid,
1679 message);
1680 }
1681
1682 public void enforceCallingPermission(String permission, String message) {
1683 enforce(permission,
1684 checkCallingPermission(permission),
1685 false,
1686 Binder.getCallingUid(),
1687 message);
1688 }
1689
1690 public void enforceCallingOrSelfPermission(
1691 String permission, String message) {
1692 enforce(permission,
1693 checkCallingOrSelfPermission(permission),
1694 true,
1695 Binder.getCallingUid(),
1696 message);
1697 }
1698
1699 @Override
1700 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1701 try {
1702 ActivityManagerNative.getDefault().grantUriPermission(
1703 mMainThread.getApplicationThread(), toPackage, uri,
1704 modeFlags);
1705 } catch (RemoteException e) {
1706 }
1707 }
1708
1709 @Override
1710 public void revokeUriPermission(Uri uri, int modeFlags) {
1711 try {
1712 ActivityManagerNative.getDefault().revokeUriPermission(
1713 mMainThread.getApplicationThread(), uri,
1714 modeFlags);
1715 } catch (RemoteException e) {
1716 }
1717 }
1718
1719 @Override
1720 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001721 try {
1722 return ActivityManagerNative.getDefault().checkUriPermission(
1723 uri, pid, uid, modeFlags);
1724 } catch (RemoteException e) {
1725 return PackageManager.PERMISSION_DENIED;
1726 }
1727 }
1728
1729 @Override
1730 public int checkCallingUriPermission(Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001731 int pid = Binder.getCallingPid();
1732 if (pid != Process.myPid()) {
1733 return checkUriPermission(uri, pid,
1734 Binder.getCallingUid(), modeFlags);
1735 }
1736 return PackageManager.PERMISSION_DENIED;
1737 }
1738
1739 @Override
1740 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1741 return checkUriPermission(uri, Binder.getCallingPid(),
1742 Binder.getCallingUid(), modeFlags);
1743 }
1744
1745 @Override
1746 public int checkUriPermission(Uri uri, String readPermission,
1747 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001748 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1750 + readPermission + " writePermission=" + writePermission
1751 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1752 }
1753 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1754 if (readPermission == null
1755 || checkPermission(readPermission, pid, uid)
1756 == PackageManager.PERMISSION_GRANTED) {
1757 return PackageManager.PERMISSION_GRANTED;
1758 }
1759 }
1760 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1761 if (writePermission == null
1762 || checkPermission(writePermission, pid, uid)
1763 == PackageManager.PERMISSION_GRANTED) {
1764 return PackageManager.PERMISSION_GRANTED;
1765 }
1766 }
1767 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1768 : PackageManager.PERMISSION_DENIED;
1769 }
1770
1771 private String uriModeFlagToString(int uriModeFlags) {
1772 switch (uriModeFlags) {
1773 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1774 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1775 return "read and write";
1776 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1777 return "read";
1778 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1779 return "write";
1780 }
1781 throw new IllegalArgumentException(
1782 "Unknown permission mode flags: " + uriModeFlags);
1783 }
1784
1785 private void enforceForUri(
1786 int modeFlags, int resultOfCheck, boolean selfToo,
1787 int uid, Uri uri, String message) {
1788 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1789 throw new SecurityException(
1790 (message != null ? (message + ": ") : "") +
1791 (selfToo
1792 ? "Neither user " + uid + " nor current process has "
1793 : "User " + uid + " does not have ") +
1794 uriModeFlagToString(modeFlags) +
1795 " permission on " +
1796 uri +
1797 ".");
1798 }
1799 }
1800
1801 public void enforceUriPermission(
1802 Uri uri, int pid, int uid, int modeFlags, String message) {
1803 enforceForUri(
1804 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1805 false, uid, uri, message);
1806 }
1807
1808 public void enforceCallingUriPermission(
1809 Uri uri, int modeFlags, String message) {
1810 enforceForUri(
1811 modeFlags, checkCallingUriPermission(uri, modeFlags),
Amith Yamasani742a6712011-05-04 14:49:28 -07001812 false,
1813 Binder.getCallingUid(), uri, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 }
1815
1816 public void enforceCallingOrSelfUriPermission(
1817 Uri uri, int modeFlags, String message) {
1818 enforceForUri(
1819 modeFlags,
1820 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1821 Binder.getCallingUid(), uri, message);
1822 }
1823
1824 public void enforceUriPermission(
1825 Uri uri, String readPermission, String writePermission,
1826 int pid, int uid, int modeFlags, String message) {
1827 enforceForUri(modeFlags,
1828 checkUriPermission(
1829 uri, readPermission, writePermission, pid, uid,
1830 modeFlags),
1831 false,
1832 uid,
1833 uri,
1834 message);
1835 }
1836
Tom O'Neill365632e2013-09-09 09:34:58 -07001837 /**
1838 * Logs a warning if the system process directly called a method such as
1839 * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}.
1840 * The "AsUser" variants allow us to properly enforce the user's restrictions.
1841 */
Amith Yamasanicd757062012-10-19 18:23:52 -07001842 private void warnIfCallingFromSystemProcess() {
1843 if (Process.myUid() == Process.SYSTEM_UID) {
1844 Slog.w(TAG, "Calling a method in the system process without a qualified user: "
Dianne Hackborn40e9f292012-11-27 19:12:23 -08001845 + Debug.getCallers(5));
Amith Yamasanicd757062012-10-19 18:23:52 -07001846 }
1847 }
1848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 @Override
1850 public Context createPackageContext(String packageName, int flags)
Jeff Sharkey6d515712012-09-20 16:06:08 -07001851 throws NameNotFoundException {
Amith Yamasani64442c12012-10-07 08:17:46 -07001852 return createPackageContextAsUser(packageName, flags,
1853 mUser != null ? mUser : Process.myUserHandle());
Jeff Sharkey6d515712012-09-20 16:06:08 -07001854 }
1855
1856 @Override
1857 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
1858 throws NameNotFoundException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001859 if (packageName.equals("system") || packageName.equals("android")) {
Jeff Sharkey816e4f72012-04-22 17:08:52 -07001860 final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
Adam Powell6f2a3d22012-10-05 22:32:04 -07001861 context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1862 context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
Jeff Sharkey816e4f72012-04-22 17:08:52 -07001863 return context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864 }
1865
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001866 LoadedApk pi =
Amith Yamasani98edc952012-09-25 14:09:27 -07001867 mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
1868 user.getIdentifier());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001870 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001871 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Jeff Sharkey6d515712012-09-20 16:06:08 -07001872 c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001873 if (c.mResources != null) {
1874 return c;
1875 }
1876 }
1877
1878 // Should be a better exception.
1879 throw new PackageManager.NameNotFoundException(
1880 "Application package " + packageName + " not found");
1881 }
1882
Romain Guy870e09f2009-07-06 16:35:25 -07001883 @Override
Dianne Hackborn756220b2012-08-14 16:45:30 -07001884 public Context createConfigurationContext(Configuration overrideConfiguration) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001885 if (overrideConfiguration == null) {
1886 throw new IllegalArgumentException("overrideConfiguration must not be null");
1887 }
1888
Dianne Hackborn756220b2012-08-14 16:45:30 -07001889 ContextImpl c = new ContextImpl();
1890 c.init(mPackageInfo, null, mMainThread);
Craig Mautner88c05892013-06-28 09:47:45 -07001891 c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
1892 getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
1893 mActivityToken);
Dianne Hackborn756220b2012-08-14 16:45:30 -07001894 return c;
1895 }
1896
1897 @Override
Jeff Browna492c3a2012-08-23 19:48:44 -07001898 public Context createDisplayContext(Display display) {
1899 if (display == null) {
1900 throw new IllegalArgumentException("display must not be null");
1901 }
1902
1903 int displayId = display.getDisplayId();
Jeff Browna492c3a2012-08-23 19:48:44 -07001904
1905 ContextImpl context = new ContextImpl();
1906 context.init(mPackageInfo, null, mMainThread);
1907 context.mDisplay = display;
Craig Mautner48d0d182013-06-11 07:53:06 -07001908 DisplayAdjustments daj = getDisplayAdjustments(displayId);
Craig Mautner88c05892013-06-28 09:47:45 -07001909 context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
1910 displayId, null, daj.getCompatibilityInfo(), null);
Jeff Browna492c3a2012-08-23 19:48:44 -07001911 return context;
1912 }
1913
1914 private int getDisplayId() {
1915 return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
1916 }
1917
1918 @Override
Romain Guy870e09f2009-07-06 16:35:25 -07001919 public boolean isRestricted() {
1920 return mRestricted;
1921 }
1922
Jeff Brown98365d72012-08-19 20:30:52 -07001923 @Override
Craig Mautner48d0d182013-06-11 07:53:06 -07001924 public DisplayAdjustments getDisplayAdjustments(int displayId) {
1925 return mDisplayAdjustments;
Jeff Brown98365d72012-08-19 20:30:52 -07001926 }
1927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 private File getDataDirFile() {
1929 if (mPackageInfo != null) {
1930 return mPackageInfo.getDataDirFile();
1931 }
1932 throw new RuntimeException("Not supported in system context");
1933 }
1934
1935 @Override
1936 public File getDir(String name, int mode) {
1937 name = "app_" + name;
1938 File file = makeFilename(getDataDirFile(), name);
1939 if (!file.exists()) {
1940 file.mkdir();
1941 setFilePermissionsFromMode(file.getPath(), mode,
1942 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1943 }
1944 return file;
1945 }
1946
Jeff Sharkeyded653b2012-09-27 19:09:24 -07001947 /** {@hide} */
1948 public int getUserId() {
1949 return mUser.getIdentifier();
1950 }
1951
Dianne Hackborn21556372010-02-04 16:34:40 -08001952 static ContextImpl createSystemContext(ActivityThread mainThread) {
Jeff Sharkey6d515712012-09-20 16:06:08 -07001953 final ContextImpl context = new ContextImpl();
1954 context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 return context;
1956 }
1957
Dianne Hackborn21556372010-02-04 16:34:40 -08001958 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 mOuterContext = this;
1960 }
1961
1962 /**
1963 * Create a new ApplicationContext from an existing one. The new one
1964 * works and operates the same as the one it is copying.
1965 *
1966 * @param context Existing application context.
1967 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001968 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 mPackageInfo = context.mPackageInfo;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001970 mBasePackageName = context.mBasePackageName;
Dianne Hackborn95d78532013-09-11 09:51:14 -07001971 mOpPackageName = context.mOpPackageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 mResources = context.mResources;
1973 mMainThread = context.mMainThread;
1974 mContentResolver = context.mContentResolver;
Jeff Sharkey6d515712012-09-20 16:06:08 -07001975 mUser = context.mUser;
Jeff Browna492c3a2012-08-23 19:48:44 -07001976 mDisplay = context.mDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 mOuterContext = this;
Craig Mautner48d0d182013-06-11 07:53:06 -07001978 mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 }
1980
Jeff Sharkey6d515712012-09-20 16:06:08 -07001981 final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
1982 init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001983 }
1984
Jeff Sharkey6d515712012-09-20 16:06:08 -07001985 final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
1986 Resources container, String basePackageName, UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 mPackageInfo = packageInfo;
Dianne Hackborn95d78532013-09-11 09:51:14 -07001988 if (basePackageName != null) {
1989 mBasePackageName = mOpPackageName = basePackageName;
1990 } else {
1991 mBasePackageName = packageInfo.mPackageName;
1992 ApplicationInfo ainfo = packageInfo.getApplicationInfo();
1993 if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) {
1994 // Special case: system components allow themselves to be loaded in to other
1995 // processes. For purposes of app ops, we must then consider the context as
1996 // belonging to the package of this process, not the system itself, otherwise
1997 // the package+uid verifications in app ops will fail.
1998 mOpPackageName = ActivityThread.currentPackageName();
1999 } else {
2000 mOpPackageName = mBasePackageName;
2001 }
2002 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 mResources = mPackageInfo.getResources(mainThread);
Craig Mautner88c05892013-06-28 09:47:45 -07002004 mResourcesManager = ResourcesManager.getInstance();
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07002005
Craig Mautner48d0d182013-06-11 07:53:06 -07002006 CompatibilityInfo compatInfo =
2007 container == null ? null : container.getCompatibilityInfo();
2008 if (mResources != null &&
2009 ((compatInfo != null && compatInfo.applicationScale !=
2010 mResources.getCompatibilityInfo().applicationScale)
2011 || activityToken != null)) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07002012 if (DEBUG) {
2013 Log.d(TAG, "loaded context has different scaling. Using container's" +
2014 " compatiblity info:" + container.getDisplayMetrics());
2015 }
Craig Mautner48d0d182013-06-11 07:53:06 -07002016 if (compatInfo == null) {
Craig Mautnerbd6a6e62013-08-06 14:04:05 -07002017 compatInfo = packageInfo.getCompatibilityInfo();
Craig Mautner48d0d182013-06-11 07:53:06 -07002018 }
2019 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
2020 mDisplayAdjustments.setActivityToken(activityToken);
Craig Mautner88c05892013-06-28 09:47:45 -07002021 mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
Craig Mautner48d0d182013-06-11 07:53:06 -07002022 Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
2023 } else {
2024 mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
2025 mDisplayAdjustments.setActivityToken(activityToken);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07002026 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002027 mMainThread = mainThread;
Dianne Hackborn756220b2012-08-14 16:45:30 -07002028 mActivityToken = activityToken;
Jeff Sharkey6d515712012-09-20 16:06:08 -07002029 mContentResolver = new ApplicationContentResolver(this, mainThread, user);
2030 mUser = user;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031 }
2032
Jeff Sharkey6d515712012-09-20 16:06:08 -07002033 final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 mPackageInfo = null;
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002035 mBasePackageName = null;
Dianne Hackborn95d78532013-09-11 09:51:14 -07002036 mOpPackageName = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002037 mResources = resources;
2038 mMainThread = mainThread;
Jeff Sharkey6d515712012-09-20 16:06:08 -07002039 mContentResolver = new ApplicationContentResolver(this, mainThread, user);
2040 mUser = user;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 }
2042
2043 final void scheduleFinalCleanup(String who, String what) {
2044 mMainThread.scheduleContextCleanup(this, who, what);
2045 }
2046
2047 final void performFinalCleanup(String who, String what) {
2048 //Log.i(TAG, "Cleanup up context: " + this);
2049 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
2050 }
2051
2052 final Context getReceiverRestrictedContext() {
2053 if (mReceiverRestrictedContext != null) {
2054 return mReceiverRestrictedContext;
2055 }
2056 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
2057 }
2058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002059 final void setOuterContext(Context context) {
2060 mOuterContext = context;
2061 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002062
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002063 final Context getOuterContext() {
2064 return mOuterContext;
2065 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002067 final IBinder getActivityToken() {
2068 return mActivityToken;
2069 }
2070
Brad Fitzpatrickd3da4402010-11-10 08:27:11 -08002071 static void setFilePermissionsFromMode(String name, int mode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 int extraPermissions) {
2073 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
2074 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
2075 |extraPermissions;
2076 if ((mode&MODE_WORLD_READABLE) != 0) {
2077 perms |= FileUtils.S_IROTH;
2078 }
2079 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
2080 perms |= FileUtils.S_IWOTH;
2081 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07002082 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
2084 + ", perms=0x" + Integer.toHexString(perms));
2085 }
2086 FileUtils.setPermissions(name, perms, -1, -1);
2087 }
2088
Oscar Montemayora8529f62009-11-18 10:14:20 -08002089 private File validateFilePath(String name, boolean createDirectory) {
2090 File dir;
2091 File f;
2092
2093 if (name.charAt(0) == File.separatorChar) {
2094 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
2095 dir = new File(dirPath);
2096 name = name.substring(name.lastIndexOf(File.separatorChar));
2097 f = new File(dir, name);
2098 } else {
2099 dir = getDatabasesDir();
2100 f = makeFilename(dir, name);
2101 }
2102
2103 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
2104 FileUtils.setPermissions(dir.getPath(),
2105 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2106 -1, -1);
2107 }
2108
2109 return f;
2110 }
2111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 private File makeFilename(File base, String name) {
2113 if (name.indexOf(File.separatorChar) < 0) {
2114 return new File(base, name);
2115 }
2116 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08002117 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 }
2119
Jeff Sharkey1abdb712013-08-11 16:28:14 -07002120 /**
2121 * Ensure that given directories exist, trying to create them if missing. If
2122 * unable to create, they are filtered by replacing with {@code null}.
2123 */
2124 private static File[] ensureDirsExistOrFilter(File[] dirs) {
2125 File[] result = new File[dirs.length];
2126 for (int i = 0; i < dirs.length; i++) {
2127 File dir = dirs[i];
2128 if (!dir.exists()) {
2129 if (!dir.mkdirs()) {
2130 Log.w(TAG, "Failed to ensure directory: " + dir);
2131 dir = null;
2132 }
2133 }
2134 result[i] = dir;
2135 }
2136 return result;
2137 }
2138
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002139 // ----------------------------------------------------------------------
2140 // ----------------------------------------------------------------------
2141 // ----------------------------------------------------------------------
2142
2143 private static final class ApplicationContentResolver extends ContentResolver {
Jeff Sharkey6d515712012-09-20 16:06:08 -07002144 private final ActivityThread mMainThread;
2145 private final UserHandle mUser;
2146
2147 public ApplicationContentResolver(
2148 Context context, ActivityThread mainThread, UserHandle user) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002149 super(context);
Jeff Sharkey6d515712012-09-20 16:06:08 -07002150 mMainThread = Preconditions.checkNotNull(mainThread);
2151 mUser = Preconditions.checkNotNull(user);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 }
2153
2154 @Override
Jeff Sharkey6d515712012-09-20 16:06:08 -07002155 protected IContentProvider acquireProvider(Context context, String auth) {
2156 return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 }
2158
2159 @Override
Jeff Sharkey6d515712012-09-20 16:06:08 -07002160 protected IContentProvider acquireExistingProvider(Context context, String auth) {
2161 return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07002162 }
2163
2164 @Override
2165 public boolean releaseProvider(IContentProvider provider) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07002166 return mMainThread.releaseProvider(provider, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002167 }
Christian Mehlmauer5f5acca2010-06-25 19:06:18 +02002168
Dianne Hackborn652b6d12012-05-09 18:18:40 -07002169 @Override
Jeff Sharkey6d515712012-09-20 16:06:08 -07002170 protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2171 return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
Dianne Hackborn652b6d12012-05-09 18:18:40 -07002172 }
2173
2174 @Override
2175 public boolean releaseUnstableProvider(IContentProvider icp) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07002176 return mMainThread.releaseProvider(icp, false);
2177 }
2178
2179 @Override
2180 public void unstableProviderDied(IContentProvider icp) {
2181 mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
Dianne Hackborn652b6d12012-05-09 18:18:40 -07002182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184}