blob: bcdfe59e2861d6fdc532f017adffccc15a08e3ad [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
svetoslavganov75986cf2009-05-14 22:28:01 -070019import com.android.internal.policy.PolicyManager;
Dianne Hackborn2269d1572010-02-24 19:54:22 -080020import com.android.internal.util.XmlUtils;
svetoslavganov75986cf2009-05-14 22:28:01 -070021import com.google.android.collect.Maps;
22
23import org.xmlpull.v1.XmlPullParserException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.content.BroadcastReceiver;
26import android.content.ComponentName;
27import android.content.ContentResolver;
28import android.content.Context;
29import android.content.ContextWrapper;
30import android.content.IContentProvider;
31import android.content.Intent;
32import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070033import android.content.IIntentReceiver;
34import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.ReceiverCallNotAllowedException;
36import android.content.ServiceConnection;
37import android.content.SharedPreferences;
38import android.content.pm.ActivityInfo;
39import android.content.pm.ApplicationInfo;
40import android.content.pm.ComponentInfo;
Dianne Hackborn49237342009-08-27 20:08:01 -070041import android.content.pm.FeatureInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.content.pm.IPackageDataObserver;
43import android.content.pm.IPackageDeleteObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.content.pm.IPackageInstallObserver;
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -080045import android.content.pm.IPackageMoveObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070047import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.content.pm.InstrumentationInfo;
49import android.content.pm.PackageInfo;
50import android.content.pm.PackageManager;
51import android.content.pm.PermissionGroupInfo;
52import android.content.pm.PermissionInfo;
53import android.content.pm.ProviderInfo;
54import android.content.pm.ResolveInfo;
55import android.content.pm.ServiceInfo;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080056import android.content.pm.PackageParser.Package;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.res.AssetManager;
58import android.content.res.Resources;
59import android.content.res.XmlResourceParser;
60import android.database.sqlite.SQLiteDatabase;
61import android.database.sqlite.SQLiteDatabase.CursorFactory;
62import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.graphics.drawable.Drawable;
64import android.hardware.SensorManager;
65import android.location.ILocationManager;
66import android.location.LocationManager;
67import android.media.AudioManager;
68import android.net.ConnectivityManager;
69import android.net.IConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -070070import android.net.ThrottleManager;
71import android.net.IThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.net.Uri;
73import android.net.wifi.IWifiManager;
74import android.net.wifi.WifiManager;
75import android.os.Binder;
76import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080077import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080078import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.os.FileUtils;
80import android.os.Handler;
81import android.os.IBinder;
82import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070083import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.os.PowerManager;
85import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070086import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import android.os.ServiceManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080088import android.os.StatFs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.os.Vibrator;
90import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080091import android.os.storage.StorageManager;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080092import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.telephony.TelephonyManager;
94import android.text.ClipboardManager;
95import android.util.AndroidRuntimeException;
96import android.util.Log;
97import android.view.ContextThemeWrapper;
98import android.view.LayoutInflater;
99import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -0700100import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -0700102import android.accounts.AccountManager;
103import android.accounts.IAccountManager;
Dianne Hackborn87bba1e2010-02-26 17:25:54 -0800104import android.app.admin.DevicePolicyManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
Dan Egnorf18a01c2009-11-12 11:32:50 -0800106import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import java.io.File;
109import java.io.FileInputStream;
110import java.io.FileNotFoundException;
111import java.io.FileOutputStream;
112import java.io.IOException;
113import java.io.InputStream;
114import java.lang.ref.WeakReference;
115import java.util.ArrayList;
116import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700117import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import java.util.Iterator;
119import java.util.List;
120import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700121import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700122import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import java.util.Map.Entry;
124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125class ReceiverRestrictedContext extends ContextWrapper {
126 ReceiverRestrictedContext(Context base) {
127 super(base);
128 }
129
130 @Override
131 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
132 return registerReceiver(receiver, filter, null, null);
133 }
134
135 @Override
136 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
137 String broadcastPermission, Handler scheduler) {
138 throw new ReceiverCallNotAllowedException(
139 "IntentReceiver components are not allowed to register to receive intents");
140 //ex.fillInStackTrace();
141 //Log.e("IntentReceiver", ex.getMessage(), ex);
142 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
143 // scheduler);
144 }
145
146 @Override
147 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
148 throw new ReceiverCallNotAllowedException(
149 "IntentReceiver components are not allowed to bind to services");
150 //ex.fillInStackTrace();
151 //Log.e("IntentReceiver", ex.getMessage(), ex);
152 //return mContext.bindService(service, interfaceName, conn, flags);
153 }
154}
155
156/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800157 * Common implementation of Context API, which provides the base
158 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800160class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700162 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163 private final static boolean DEBUG_ICONS = false;
164
165 private static final Object sSync = new Object();
166 private static AlarmManager sAlarmManager;
167 private static PowerManager sPowerManager;
168 private static ConnectivityManager sConnectivityManager;
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700169 private static ThrottleManager sThrottleManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170 private static WifiManager sWifiManager;
171 private static LocationManager sLocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
173 new HashMap<File, SharedPreferencesImpl>();
174
175 private AudioManager mAudioManager;
176 /*package*/ ActivityThread.PackageInfo mPackageInfo;
177 private Resources mResources;
178 /*package*/ ActivityThread mMainThread;
179 private Context mOuterContext;
180 private IBinder mActivityToken = null;
181 private ApplicationContentResolver mContentResolver;
182 private int mThemeResource = 0;
183 private Resources.Theme mTheme = null;
184 private PackageManager mPackageManager;
185 private NotificationManager mNotificationManager = null;
186 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700187 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 private Context mReceiverRestrictedContext = null;
189 private SearchManager mSearchManager = null;
190 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800191 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192 private Vibrator mVibrator = null;
193 private LayoutInflater mLayoutInflater = null;
194 private StatusBarManager mStatusBarManager = null;
195 private TelephonyManager mTelephonyManager = null;
196 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700197 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700198 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800199 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800200 private DevicePolicyManager mDevicePolicyManager = null;
Tobias Haamel53332882010-02-18 16:15:43 -0800201 private UiModeManager mUiModeManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202
203 private final Object mSync = new Object();
204
205 private File mDatabasesDir;
206 private File mPreferencesDir;
207 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800208 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800209 private File mExternalFilesDir;
210 private File mExternalCacheDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 private static long sInstanceCount = 0;
213
214 private static final String[] EMPTY_FILE_LIST = {};
215
Carl Shapiro82fe5642010-02-24 00:14:23 -0800216 // For debug only
217 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218 @Override
219 protected void finalize() throws Throwable {
220 super.finalize();
221 --sInstanceCount;
222 }
Carl Shapiro82fe5642010-02-24 00:14:23 -0800223 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224
225 public static long getInstanceCount() {
226 return sInstanceCount;
227 }
228
229 @Override
230 public AssetManager getAssets() {
231 return mResources.getAssets();
232 }
233
234 @Override
235 public Resources getResources() {
236 return mResources;
237 }
238
239 @Override
240 public PackageManager getPackageManager() {
241 if (mPackageManager != null) {
242 return mPackageManager;
243 }
244
245 IPackageManager pm = ActivityThread.getPackageManager();
246 if (pm != null) {
247 // Doesn't matter if we make more than one instance.
248 return (mPackageManager = new ApplicationPackageManager(this, pm));
249 }
250
251 return null;
252 }
253
254 @Override
255 public ContentResolver getContentResolver() {
256 return mContentResolver;
257 }
258
259 @Override
260 public Looper getMainLooper() {
261 return mMainThread.getLooper();
262 }
263
264 @Override
265 public Context getApplicationContext() {
Christopher Tateeb9e9ec2010-03-23 17:14:36 -0700266 return (mPackageInfo != null) ?
267 mPackageInfo.getApplication() : mMainThread.getApplication();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800268 }
269
270 @Override
271 public void setTheme(int resid) {
272 mThemeResource = resid;
273 }
274
275 @Override
276 public Resources.Theme getTheme() {
277 if (mTheme == null) {
278 if (mThemeResource == 0) {
279 mThemeResource = com.android.internal.R.style.Theme;
280 }
281 mTheme = mResources.newTheme();
282 mTheme.applyStyle(mThemeResource, true);
283 }
284 return mTheme;
285 }
286
287 @Override
288 public ClassLoader getClassLoader() {
289 return mPackageInfo != null ?
290 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
291 }
292
293 @Override
294 public String getPackageName() {
295 if (mPackageInfo != null) {
296 return mPackageInfo.getPackageName();
297 }
298 throw new RuntimeException("Not supported in system context");
299 }
300
301 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700302 public ApplicationInfo getApplicationInfo() {
303 if (mPackageInfo != null) {
304 return mPackageInfo.getApplicationInfo();
305 }
306 throw new RuntimeException("Not supported in system context");
307 }
308
309 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 public String getPackageResourcePath() {
311 if (mPackageInfo != null) {
312 return mPackageInfo.getResDir();
313 }
314 throw new RuntimeException("Not supported in system context");
315 }
316
317 @Override
318 public String getPackageCodePath() {
319 if (mPackageInfo != null) {
320 return mPackageInfo.getAppDir();
321 }
322 throw new RuntimeException("Not supported in system context");
323 }
324
325 private static File makeBackupFile(File prefsFile) {
326 return new File(prefsFile.getPath() + ".bak");
327 }
328
Joe Onorato23ecae32009-06-10 17:07:15 -0700329 public File getSharedPrefsFile(String name) {
330 return makeFilename(getPreferencesDir(), name + ".xml");
331 }
332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 @Override
334 public SharedPreferences getSharedPreferences(String name, int mode) {
335 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700336 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 synchronized (sSharedPrefs) {
338 sp = sSharedPrefs.get(f);
339 if (sp != null && !sp.hasFileChanged()) {
340 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
341 return sp;
342 }
343 }
344
345 FileInputStream str = null;
346 File backup = makeBackupFile(f);
347 if (backup.exists()) {
348 f.delete();
349 backup.renameTo(f);
350 }
351
352 // Debugging
353 if (f.exists() && !f.canRead()) {
354 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
355 }
356
357 Map map = null;
358 if (f.exists() && f.canRead()) {
359 try {
360 str = new FileInputStream(f);
361 map = XmlUtils.readMapXml(str);
362 str.close();
363 } catch (org.xmlpull.v1.XmlPullParserException e) {
364 Log.w(TAG, "getSharedPreferences", e);
365 } catch (FileNotFoundException e) {
366 Log.w(TAG, "getSharedPreferences", e);
367 } catch (IOException e) {
368 Log.w(TAG, "getSharedPreferences", e);
369 }
370 }
371
372 synchronized (sSharedPrefs) {
373 if (sp != null) {
374 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
375 sp.replace(map);
376 } else {
377 sp = sSharedPrefs.get(f);
378 if (sp == null) {
379 sp = new SharedPreferencesImpl(f, mode, map);
380 sSharedPrefs.put(f, sp);
381 }
382 }
383 return sp;
384 }
385 }
386
387 private File getPreferencesDir() {
388 synchronized (mSync) {
389 if (mPreferencesDir == null) {
390 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
391 }
392 return mPreferencesDir;
393 }
394 }
395
396 @Override
397 public FileInputStream openFileInput(String name)
398 throws FileNotFoundException {
399 File f = makeFilename(getFilesDir(), name);
400 return new FileInputStream(f);
401 }
402
403 @Override
404 public FileOutputStream openFileOutput(String name, int mode)
405 throws FileNotFoundException {
406 final boolean append = (mode&MODE_APPEND) != 0;
407 File f = makeFilename(getFilesDir(), name);
408 try {
409 FileOutputStream fos = new FileOutputStream(f, append);
410 setFilePermissionsFromMode(f.getPath(), mode, 0);
411 return fos;
412 } catch (FileNotFoundException e) {
413 }
414
415 File parent = f.getParentFile();
416 parent.mkdir();
417 FileUtils.setPermissions(
418 parent.getPath(),
419 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
420 -1, -1);
421 FileOutputStream fos = new FileOutputStream(f, append);
422 setFilePermissionsFromMode(f.getPath(), mode, 0);
423 return fos;
424 }
425
426 @Override
427 public boolean deleteFile(String name) {
428 File f = makeFilename(getFilesDir(), name);
429 return f.delete();
430 }
431
432 @Override
433 public File getFilesDir() {
434 synchronized (mSync) {
435 if (mFilesDir == null) {
436 mFilesDir = new File(getDataDirFile(), "files");
437 }
438 if (!mFilesDir.exists()) {
439 if(!mFilesDir.mkdirs()) {
440 Log.w(TAG, "Unable to create files directory");
441 return null;
442 }
443 FileUtils.setPermissions(
444 mFilesDir.getPath(),
445 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
446 -1, -1);
447 }
448 return mFilesDir;
449 }
450 }
451
452 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800453 public File getExternalFilesDir(String type) {
454 synchronized (mSync) {
455 if (mExternalFilesDir == null) {
456 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
457 getPackageName());
458 }
459 if (!mExternalFilesDir.exists()) {
460 try {
461 (new File(Environment.getExternalStorageAndroidDataDir(),
462 ".nomedia")).createNewFile();
463 } catch (IOException e) {
464 }
465 if (!mExternalFilesDir.mkdirs()) {
466 Log.w(TAG, "Unable to create external files directory");
467 return null;
468 }
469 }
470 if (type == null) {
471 return mExternalFilesDir;
472 }
473 File dir = new File(mExternalFilesDir, type);
474 if (!dir.exists()) {
475 if (!dir.mkdirs()) {
476 Log.w(TAG, "Unable to create external media directory " + dir);
477 return null;
478 }
479 }
480 return dir;
481 }
482 }
483
484 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800485 public File getCacheDir() {
486 synchronized (mSync) {
487 if (mCacheDir == null) {
488 mCacheDir = new File(getDataDirFile(), "cache");
489 }
490 if (!mCacheDir.exists()) {
491 if(!mCacheDir.mkdirs()) {
492 Log.w(TAG, "Unable to create cache directory");
493 return null;
494 }
495 FileUtils.setPermissions(
496 mCacheDir.getPath(),
497 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
498 -1, -1);
499 }
500 }
501 return mCacheDir;
502 }
503
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800504 @Override
505 public File getExternalCacheDir() {
506 synchronized (mSync) {
507 if (mExternalCacheDir == null) {
508 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
509 getPackageName());
510 }
511 if (!mExternalCacheDir.exists()) {
512 try {
513 (new File(Environment.getExternalStorageAndroidDataDir(),
514 ".nomedia")).createNewFile();
515 } catch (IOException e) {
516 }
517 if (!mExternalCacheDir.mkdirs()) {
518 Log.w(TAG, "Unable to create external cache directory");
519 return null;
520 }
521 }
522 return mExternalCacheDir;
523 }
524 }
525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 @Override
527 public File getFileStreamPath(String name) {
528 return makeFilename(getFilesDir(), name);
529 }
530
531 @Override
532 public String[] fileList() {
533 final String[] list = getFilesDir().list();
534 return (list != null) ? list : EMPTY_FILE_LIST;
535 }
536
537 @Override
538 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800539 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800540 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
541 setFilePermissionsFromMode(f.getPath(), mode, 0);
542 return db;
543 }
544
545 @Override
546 public boolean deleteDatabase(String name) {
547 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800548 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 return f.delete();
550 } catch (Exception e) {
551 }
552 return false;
553 }
554
555 @Override
556 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800557 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 }
559
560 @Override
561 public String[] databaseList() {
562 final String[] list = getDatabasesDir().list();
563 return (list != null) ? list : EMPTY_FILE_LIST;
564 }
565
566
567 private File getDatabasesDir() {
568 synchronized (mSync) {
569 if (mDatabasesDir == null) {
570 mDatabasesDir = new File(getDataDirFile(), "databases");
571 }
572 if (mDatabasesDir.getPath().equals("databases")) {
573 mDatabasesDir = new File("/data/system");
574 }
575 return mDatabasesDir;
576 }
577 }
578
579 @Override
580 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700581 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
583
584 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700585 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700586 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
588
589 @Override
590 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700591 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 }
593
594 @Override
595 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700596 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
598
599 @Override
600 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700601 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 }
603
604 @Override
605 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700606 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 }
608
609 @Override
610 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700611 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 }
613
614 @Override
615 public void startActivity(Intent intent) {
616 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
617 throw new AndroidRuntimeException(
618 "Calling startActivity() from outside of an Activity "
619 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
620 + " Is this really what you want?");
621 }
622 mMainThread.getInstrumentation().execStartActivity(
623 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
624 }
625
626 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700627 public void startIntentSender(IntentSender intent,
628 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
629 throws IntentSender.SendIntentException {
630 try {
631 String resolvedType = null;
632 if (fillInIntent != null) {
633 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
634 }
635 int result = ActivityManagerNative.getDefault()
636 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
637 fillInIntent, resolvedType, null, null,
638 0, flagsMask, flagsValues);
639 if (result == IActivityManager.START_CANCELED) {
640 throw new IntentSender.SendIntentException();
641 }
642 Instrumentation.checkStartActivityResult(result, null);
643 } catch (RemoteException e) {
644 }
645 }
646
647 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 public void sendBroadcast(Intent intent) {
649 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
650 try {
651 ActivityManagerNative.getDefault().broadcastIntent(
652 mMainThread.getApplicationThread(), intent, resolvedType, null,
653 Activity.RESULT_OK, null, null, null, false, false);
654 } catch (RemoteException e) {
655 }
656 }
657
658 @Override
659 public void sendBroadcast(Intent intent, String receiverPermission) {
660 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
661 try {
662 ActivityManagerNative.getDefault().broadcastIntent(
663 mMainThread.getApplicationThread(), intent, resolvedType, null,
664 Activity.RESULT_OK, null, null, receiverPermission, false, false);
665 } catch (RemoteException e) {
666 }
667 }
668
669 @Override
670 public void sendOrderedBroadcast(Intent intent,
671 String receiverPermission) {
672 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
673 try {
674 ActivityManagerNative.getDefault().broadcastIntent(
675 mMainThread.getApplicationThread(), intent, resolvedType, null,
676 Activity.RESULT_OK, null, null, receiverPermission, true, false);
677 } catch (RemoteException e) {
678 }
679 }
680
681 @Override
682 public void sendOrderedBroadcast(Intent intent,
683 String receiverPermission, BroadcastReceiver resultReceiver,
684 Handler scheduler, int initialCode, String initialData,
685 Bundle initialExtras) {
686 IIntentReceiver rd = null;
687 if (resultReceiver != null) {
688 if (mPackageInfo != null) {
689 if (scheduler == null) {
690 scheduler = mMainThread.getHandler();
691 }
692 rd = mPackageInfo.getReceiverDispatcher(
693 resultReceiver, getOuterContext(), scheduler,
694 mMainThread.getInstrumentation(), false);
695 } else {
696 if (scheduler == null) {
697 scheduler = mMainThread.getHandler();
698 }
699 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
700 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
701 }
702 }
703 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
704 try {
705 ActivityManagerNative.getDefault().broadcastIntent(
706 mMainThread.getApplicationThread(), intent, resolvedType, rd,
707 initialCode, initialData, initialExtras, receiverPermission,
708 true, false);
709 } catch (RemoteException e) {
710 }
711 }
712
713 @Override
714 public void sendStickyBroadcast(Intent intent) {
715 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
716 try {
717 ActivityManagerNative.getDefault().broadcastIntent(
718 mMainThread.getApplicationThread(), intent, resolvedType, null,
719 Activity.RESULT_OK, null, null, null, false, true);
720 } catch (RemoteException e) {
721 }
722 }
723
724 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700725 public void sendStickyOrderedBroadcast(Intent intent,
726 BroadcastReceiver resultReceiver,
727 Handler scheduler, int initialCode, String initialData,
728 Bundle initialExtras) {
729 IIntentReceiver rd = null;
730 if (resultReceiver != null) {
731 if (mPackageInfo != null) {
732 if (scheduler == null) {
733 scheduler = mMainThread.getHandler();
734 }
735 rd = mPackageInfo.getReceiverDispatcher(
736 resultReceiver, getOuterContext(), scheduler,
737 mMainThread.getInstrumentation(), false);
738 } else {
739 if (scheduler == null) {
740 scheduler = mMainThread.getHandler();
741 }
742 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
743 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
744 }
745 }
746 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
747 try {
748 ActivityManagerNative.getDefault().broadcastIntent(
749 mMainThread.getApplicationThread(), intent, resolvedType, rd,
750 initialCode, initialData, initialExtras, null,
751 true, true);
752 } catch (RemoteException e) {
753 }
754 }
755
756 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 public void removeStickyBroadcast(Intent intent) {
758 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
759 if (resolvedType != null) {
760 intent = new Intent(intent);
761 intent.setDataAndType(intent.getData(), resolvedType);
762 }
763 try {
764 ActivityManagerNative.getDefault().unbroadcastIntent(
765 mMainThread.getApplicationThread(), intent);
766 } catch (RemoteException e) {
767 }
768 }
769
770 @Override
771 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
772 return registerReceiver(receiver, filter, null, null);
773 }
774
775 @Override
776 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
777 String broadcastPermission, Handler scheduler) {
778 return registerReceiverInternal(receiver, filter, broadcastPermission,
779 scheduler, getOuterContext());
780 }
781
782 private Intent registerReceiverInternal(BroadcastReceiver receiver,
783 IntentFilter filter, String broadcastPermission,
784 Handler scheduler, Context context) {
785 IIntentReceiver rd = null;
786 if (receiver != null) {
787 if (mPackageInfo != null && context != null) {
788 if (scheduler == null) {
789 scheduler = mMainThread.getHandler();
790 }
791 rd = mPackageInfo.getReceiverDispatcher(
792 receiver, context, scheduler,
793 mMainThread.getInstrumentation(), true);
794 } else {
795 if (scheduler == null) {
796 scheduler = mMainThread.getHandler();
797 }
798 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
Dianne Hackborn399cccb2010-04-13 22:57:49 -0700799 receiver, context, scheduler, null, true).getIIntentReceiver();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 }
801 }
802 try {
803 return ActivityManagerNative.getDefault().registerReceiver(
804 mMainThread.getApplicationThread(),
805 rd, filter, broadcastPermission);
806 } catch (RemoteException e) {
807 return null;
808 }
809 }
810
811 @Override
812 public void unregisterReceiver(BroadcastReceiver receiver) {
813 if (mPackageInfo != null) {
814 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
815 getOuterContext(), receiver);
816 try {
817 ActivityManagerNative.getDefault().unregisterReceiver(rd);
818 } catch (RemoteException e) {
819 }
820 } else {
821 throw new RuntimeException("Not supported in system context");
822 }
823 }
824
825 @Override
826 public ComponentName startService(Intent service) {
827 try {
828 ComponentName cn = ActivityManagerNative.getDefault().startService(
829 mMainThread.getApplicationThread(), service,
830 service.resolveTypeIfNeeded(getContentResolver()));
831 if (cn != null && cn.getPackageName().equals("!")) {
832 throw new SecurityException(
833 "Not allowed to start service " + service
834 + " without permission " + cn.getClassName());
835 }
836 return cn;
837 } catch (RemoteException e) {
838 return null;
839 }
840 }
841
842 @Override
843 public boolean stopService(Intent service) {
844 try {
845 int res = ActivityManagerNative.getDefault().stopService(
846 mMainThread.getApplicationThread(), service,
847 service.resolveTypeIfNeeded(getContentResolver()));
848 if (res < 0) {
849 throw new SecurityException(
850 "Not allowed to stop service " + service);
851 }
852 return res != 0;
853 } catch (RemoteException e) {
854 return false;
855 }
856 }
857
858 @Override
859 public boolean bindService(Intent service, ServiceConnection conn,
860 int flags) {
861 IServiceConnection sd;
862 if (mPackageInfo != null) {
863 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
864 mMainThread.getHandler(), flags);
865 } else {
866 throw new RuntimeException("Not supported in system context");
867 }
868 try {
869 int res = ActivityManagerNative.getDefault().bindService(
870 mMainThread.getApplicationThread(), getActivityToken(),
871 service, service.resolveTypeIfNeeded(getContentResolver()),
872 sd, flags);
873 if (res < 0) {
874 throw new SecurityException(
875 "Not allowed to bind to service " + service);
876 }
877 return res != 0;
878 } catch (RemoteException e) {
879 return false;
880 }
881 }
882
883 @Override
884 public void unbindService(ServiceConnection conn) {
885 if (mPackageInfo != null) {
886 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
887 getOuterContext(), conn);
888 try {
889 ActivityManagerNative.getDefault().unbindService(sd);
890 } catch (RemoteException e) {
891 }
892 } else {
893 throw new RuntimeException("Not supported in system context");
894 }
895 }
896
897 @Override
898 public boolean startInstrumentation(ComponentName className,
899 String profileFile, Bundle arguments) {
900 try {
901 return ActivityManagerNative.getDefault().startInstrumentation(
902 className, profileFile, 0, arguments, null);
903 } catch (RemoteException e) {
904 // System has crashed, nothing we can do.
905 }
906 return false;
907 }
908
909 @Override
910 public Object getSystemService(String name) {
911 if (WINDOW_SERVICE.equals(name)) {
912 return WindowManagerImpl.getDefault();
913 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
914 synchronized (mSync) {
915 LayoutInflater inflater = mLayoutInflater;
916 if (inflater != null) {
917 return inflater;
918 }
919 mLayoutInflater = inflater =
920 PolicyManager.makeNewLayoutInflater(getOuterContext());
921 return inflater;
922 }
923 } else if (ACTIVITY_SERVICE.equals(name)) {
924 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700925 } else if (INPUT_METHOD_SERVICE.equals(name)) {
926 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 } else if (ALARM_SERVICE.equals(name)) {
928 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700929 } else if (ACCOUNT_SERVICE.equals(name)) {
930 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 } else if (POWER_SERVICE.equals(name)) {
932 return getPowerManager();
933 } else if (CONNECTIVITY_SERVICE.equals(name)) {
934 return getConnectivityManager();
Irfan Sheriffc9b68512010-04-08 14:12:33 -0700935 } else if (THROTTLE_SERVICE.equals(name)) {
936 return getThrottleManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 } else if (WIFI_SERVICE.equals(name)) {
938 return getWifiManager();
939 } else if (NOTIFICATION_SERVICE.equals(name)) {
940 return getNotificationManager();
941 } else if (KEYGUARD_SERVICE.equals(name)) {
942 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700943 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
944 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 } else if (LOCATION_SERVICE.equals(name)) {
946 return getLocationManager();
947 } else if (SEARCH_SERVICE.equals(name)) {
948 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700949 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800951 } else if (STORAGE_SERVICE.equals(name)) {
952 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 } else if (VIBRATOR_SERVICE.equals(name)) {
954 return getVibrator();
955 } else if (STATUS_BAR_SERVICE.equals(name)) {
956 synchronized (mSync) {
957 if (mStatusBarManager == null) {
958 mStatusBarManager = new StatusBarManager(getOuterContext());
959 }
960 return mStatusBarManager;
961 }
962 } else if (AUDIO_SERVICE.equals(name)) {
963 return getAudioManager();
964 } else if (TELEPHONY_SERVICE.equals(name)) {
965 return getTelephonyManager();
966 } else if (CLIPBOARD_SERVICE.equals(name)) {
967 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700968 } else if (WALLPAPER_SERVICE.equals(name)) {
969 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700970 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800971 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800972 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
973 return getDevicePolicyManager();
Tobias Haamel69fb5742010-02-22 21:54:05 +0100974 } else if (UI_MODE_SERVICE.equals(name)) {
Tobias Haamel53332882010-02-18 16:15:43 -0800975 return getUiModeManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
977
978 return null;
979 }
980
Fred Quintana60307342009-03-24 22:48:12 -0700981 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700982 synchronized (mSync) {
983 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700984 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
985 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700986 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700987 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700988 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700989 }
Fred Quintana60307342009-03-24 22:48:12 -0700990 }
991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 private ActivityManager getActivityManager() {
993 synchronized (mSync) {
994 if (mActivityManager == null) {
995 mActivityManager = new ActivityManager(getOuterContext(),
996 mMainThread.getHandler());
997 }
998 }
999 return mActivityManager;
1000 }
1001
1002 private AlarmManager getAlarmManager() {
1003 synchronized (sSync) {
1004 if (sAlarmManager == null) {
1005 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1006 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1007 sAlarmManager = new AlarmManager(service);
1008 }
1009 }
1010 return sAlarmManager;
1011 }
1012
1013 private PowerManager getPowerManager() {
1014 synchronized (sSync) {
1015 if (sPowerManager == null) {
1016 IBinder b = ServiceManager.getService(POWER_SERVICE);
1017 IPowerManager service = IPowerManager.Stub.asInterface(b);
1018 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1019 }
1020 }
1021 return sPowerManager;
1022 }
1023
1024 private ConnectivityManager getConnectivityManager()
1025 {
1026 synchronized (sSync) {
1027 if (sConnectivityManager == null) {
1028 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1029 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1030 sConnectivityManager = new ConnectivityManager(service);
1031 }
1032 }
1033 return sConnectivityManager;
1034 }
1035
Irfan Sheriffc9b68512010-04-08 14:12:33 -07001036 private ThrottleManager getThrottleManager()
1037 {
1038 synchronized (sSync) {
1039 if (sThrottleManager == null) {
1040 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1041 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1042 sThrottleManager = new ThrottleManager(service);
1043 }
1044 }
1045 return sThrottleManager;
1046 }
1047
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 private WifiManager getWifiManager()
1049 {
1050 synchronized (sSync) {
1051 if (sWifiManager == null) {
1052 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1053 IWifiManager service = IWifiManager.Stub.asInterface(b);
1054 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1055 }
1056 }
1057 return sWifiManager;
1058 }
1059
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001060 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 synchronized (mSync) {
1062 if (mNotificationManager == null) {
1063 mNotificationManager = new NotificationManager(
1064 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1065 mMainThread.getHandler());
1066 }
1067 }
1068 return mNotificationManager;
1069 }
1070
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001071 private WallpaperManager getWallpaperManager() {
1072 synchronized (mSync) {
1073 if (mWallpaperManager == null) {
1074 mWallpaperManager = new WallpaperManager(getOuterContext(),
1075 mMainThread.getHandler());
1076 }
1077 }
1078 return mWallpaperManager;
1079 }
1080
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 private TelephonyManager getTelephonyManager() {
1082 synchronized (mSync) {
1083 if (mTelephonyManager == null) {
1084 mTelephonyManager = new TelephonyManager(getOuterContext());
1085 }
1086 }
1087 return mTelephonyManager;
1088 }
1089
1090 private ClipboardManager getClipboardManager() {
1091 synchronized (mSync) {
1092 if (mClipboardManager == null) {
1093 mClipboardManager = new ClipboardManager(getOuterContext(),
1094 mMainThread.getHandler());
1095 }
1096 }
1097 return mClipboardManager;
1098 }
1099
1100 private LocationManager getLocationManager() {
1101 synchronized (sSync) {
1102 if (sLocationManager == null) {
1103 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1104 ILocationManager service = ILocationManager.Stub.asInterface(b);
1105 sLocationManager = new LocationManager(service);
1106 }
1107 }
1108 return sLocationManager;
1109 }
1110
1111 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 synchronized (mSync) {
1113 if (mSearchManager == null) {
1114 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1115 }
1116 }
1117 return mSearchManager;
1118 }
1119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001120 private SensorManager getSensorManager() {
1121 synchronized (mSync) {
1122 if (mSensorManager == null) {
1123 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1124 }
1125 }
1126 return mSensorManager;
1127 }
1128
San Mehatc9d81752010-02-01 10:23:27 -08001129 private StorageManager getStorageManager() {
1130 synchronized (mSync) {
1131 if (mStorageManager == null) {
1132 try {
1133 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1134 } catch (RemoteException rex) {
1135 Log.e(TAG, "Failed to create StorageManager", rex);
1136 mStorageManager = null;
1137 }
1138 }
1139 }
1140 return mStorageManager;
1141 }
1142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 private Vibrator getVibrator() {
1144 synchronized (mSync) {
1145 if (mVibrator == null) {
1146 mVibrator = new Vibrator();
1147 }
1148 }
1149 return mVibrator;
1150 }
Dan Egnor95240272009-10-27 18:23:39 -07001151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 private AudioManager getAudioManager()
1153 {
1154 if (mAudioManager == null) {
1155 mAudioManager = new AudioManager(this);
1156 }
1157 return mAudioManager;
1158 }
1159
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001160 /* package */ static DropBoxManager createDropBoxManager() {
1161 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1162 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1163 return new DropBoxManager(service);
1164 }
1165
Dan Egnorf18a01c2009-11-12 11:32:50 -08001166 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001167 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001168 if (mDropBoxManager == null) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001169 mDropBoxManager = createDropBoxManager();
Dan Egnor95240272009-10-27 18:23:39 -07001170 }
1171 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001172 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001173 }
1174
Dianne Hackbornd6847842010-01-12 18:14:19 -08001175 private DevicePolicyManager getDevicePolicyManager() {
1176 synchronized (mSync) {
1177 if (mDevicePolicyManager == null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001178 mDevicePolicyManager = DevicePolicyManager.create(this,
Dianne Hackbornd6847842010-01-12 18:14:19 -08001179 mMainThread.getHandler());
1180 }
1181 }
1182 return mDevicePolicyManager;
1183 }
1184
Tobias Haamel53332882010-02-18 16:15:43 -08001185 private UiModeManager getUiModeManager() {
1186 synchronized (mSync) {
1187 if (mUiModeManager == null) {
1188 mUiModeManager = new UiModeManager();
1189 }
1190 }
1191 return mUiModeManager;
1192 }
1193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 @Override
1195 public int checkPermission(String permission, int pid, int uid) {
1196 if (permission == null) {
1197 throw new IllegalArgumentException("permission is null");
1198 }
1199
1200 if (!Process.supportsProcesses()) {
1201 return PackageManager.PERMISSION_GRANTED;
1202 }
1203 try {
1204 return ActivityManagerNative.getDefault().checkPermission(
1205 permission, pid, uid);
1206 } catch (RemoteException e) {
1207 return PackageManager.PERMISSION_DENIED;
1208 }
1209 }
1210
1211 @Override
1212 public int checkCallingPermission(String permission) {
1213 if (permission == null) {
1214 throw new IllegalArgumentException("permission is null");
1215 }
1216
1217 if (!Process.supportsProcesses()) {
1218 return PackageManager.PERMISSION_GRANTED;
1219 }
1220 int pid = Binder.getCallingPid();
1221 if (pid != Process.myPid()) {
1222 return checkPermission(permission, pid,
1223 Binder.getCallingUid());
1224 }
1225 return PackageManager.PERMISSION_DENIED;
1226 }
1227
1228 @Override
1229 public int checkCallingOrSelfPermission(String permission) {
1230 if (permission == null) {
1231 throw new IllegalArgumentException("permission is null");
1232 }
1233
1234 return checkPermission(permission, Binder.getCallingPid(),
1235 Binder.getCallingUid());
1236 }
1237
1238 private void enforce(
1239 String permission, int resultOfCheck,
1240 boolean selfToo, int uid, String message) {
1241 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1242 throw new SecurityException(
1243 (message != null ? (message + ": ") : "") +
1244 (selfToo
1245 ? "Neither user " + uid + " nor current process has "
1246 : "User " + uid + " does not have ") +
1247 permission +
1248 ".");
1249 }
1250 }
1251
1252 public void enforcePermission(
1253 String permission, int pid, int uid, String message) {
1254 enforce(permission,
1255 checkPermission(permission, pid, uid),
1256 false,
1257 uid,
1258 message);
1259 }
1260
1261 public void enforceCallingPermission(String permission, String message) {
1262 enforce(permission,
1263 checkCallingPermission(permission),
1264 false,
1265 Binder.getCallingUid(),
1266 message);
1267 }
1268
1269 public void enforceCallingOrSelfPermission(
1270 String permission, String message) {
1271 enforce(permission,
1272 checkCallingOrSelfPermission(permission),
1273 true,
1274 Binder.getCallingUid(),
1275 message);
1276 }
1277
1278 @Override
1279 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1280 try {
1281 ActivityManagerNative.getDefault().grantUriPermission(
1282 mMainThread.getApplicationThread(), toPackage, uri,
1283 modeFlags);
1284 } catch (RemoteException e) {
1285 }
1286 }
1287
1288 @Override
1289 public void revokeUriPermission(Uri uri, int modeFlags) {
1290 try {
1291 ActivityManagerNative.getDefault().revokeUriPermission(
1292 mMainThread.getApplicationThread(), uri,
1293 modeFlags);
1294 } catch (RemoteException e) {
1295 }
1296 }
1297
1298 @Override
1299 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1300 if (!Process.supportsProcesses()) {
1301 return PackageManager.PERMISSION_GRANTED;
1302 }
1303 try {
1304 return ActivityManagerNative.getDefault().checkUriPermission(
1305 uri, pid, uid, modeFlags);
1306 } catch (RemoteException e) {
1307 return PackageManager.PERMISSION_DENIED;
1308 }
1309 }
1310
1311 @Override
1312 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1313 if (!Process.supportsProcesses()) {
1314 return PackageManager.PERMISSION_GRANTED;
1315 }
1316 int pid = Binder.getCallingPid();
1317 if (pid != Process.myPid()) {
1318 return checkUriPermission(uri, pid,
1319 Binder.getCallingUid(), modeFlags);
1320 }
1321 return PackageManager.PERMISSION_DENIED;
1322 }
1323
1324 @Override
1325 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1326 return checkUriPermission(uri, Binder.getCallingPid(),
1327 Binder.getCallingUid(), modeFlags);
1328 }
1329
1330 @Override
1331 public int checkUriPermission(Uri uri, String readPermission,
1332 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001333 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1335 + readPermission + " writePermission=" + writePermission
1336 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1337 }
1338 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1339 if (readPermission == null
1340 || checkPermission(readPermission, pid, uid)
1341 == PackageManager.PERMISSION_GRANTED) {
1342 return PackageManager.PERMISSION_GRANTED;
1343 }
1344 }
1345 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1346 if (writePermission == null
1347 || checkPermission(writePermission, pid, uid)
1348 == PackageManager.PERMISSION_GRANTED) {
1349 return PackageManager.PERMISSION_GRANTED;
1350 }
1351 }
1352 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1353 : PackageManager.PERMISSION_DENIED;
1354 }
1355
1356 private String uriModeFlagToString(int uriModeFlags) {
1357 switch (uriModeFlags) {
1358 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1359 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1360 return "read and write";
1361 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1362 return "read";
1363 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1364 return "write";
1365 }
1366 throw new IllegalArgumentException(
1367 "Unknown permission mode flags: " + uriModeFlags);
1368 }
1369
1370 private void enforceForUri(
1371 int modeFlags, int resultOfCheck, boolean selfToo,
1372 int uid, Uri uri, String message) {
1373 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1374 throw new SecurityException(
1375 (message != null ? (message + ": ") : "") +
1376 (selfToo
1377 ? "Neither user " + uid + " nor current process has "
1378 : "User " + uid + " does not have ") +
1379 uriModeFlagToString(modeFlags) +
1380 " permission on " +
1381 uri +
1382 ".");
1383 }
1384 }
1385
1386 public void enforceUriPermission(
1387 Uri uri, int pid, int uid, int modeFlags, String message) {
1388 enforceForUri(
1389 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1390 false, uid, uri, message);
1391 }
1392
1393 public void enforceCallingUriPermission(
1394 Uri uri, int modeFlags, String message) {
1395 enforceForUri(
1396 modeFlags, checkCallingUriPermission(uri, modeFlags),
1397 false, Binder.getCallingUid(), uri, message);
1398 }
1399
1400 public void enforceCallingOrSelfUriPermission(
1401 Uri uri, int modeFlags, String message) {
1402 enforceForUri(
1403 modeFlags,
1404 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1405 Binder.getCallingUid(), uri, message);
1406 }
1407
1408 public void enforceUriPermission(
1409 Uri uri, String readPermission, String writePermission,
1410 int pid, int uid, int modeFlags, String message) {
1411 enforceForUri(modeFlags,
1412 checkUriPermission(
1413 uri, readPermission, writePermission, pid, uid,
1414 modeFlags),
1415 false,
1416 uid,
1417 uri,
1418 message);
1419 }
1420
1421 @Override
1422 public Context createPackageContext(String packageName, int flags)
1423 throws PackageManager.NameNotFoundException {
1424 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001425 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001426 }
1427
1428 ActivityThread.PackageInfo pi =
1429 mMainThread.getPackageInfo(packageName, flags);
1430 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001431 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001432 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001433 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 if (c.mResources != null) {
1435 return c;
1436 }
1437 }
1438
1439 // Should be a better exception.
1440 throw new PackageManager.NameNotFoundException(
1441 "Application package " + packageName + " not found");
1442 }
1443
Romain Guy870e09f2009-07-06 16:35:25 -07001444 @Override
1445 public boolean isRestricted() {
1446 return mRestricted;
1447 }
1448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 private File getDataDirFile() {
1450 if (mPackageInfo != null) {
1451 return mPackageInfo.getDataDirFile();
1452 }
1453 throw new RuntimeException("Not supported in system context");
1454 }
1455
1456 @Override
1457 public File getDir(String name, int mode) {
1458 name = "app_" + name;
1459 File file = makeFilename(getDataDirFile(), name);
1460 if (!file.exists()) {
1461 file.mkdir();
1462 setFilePermissionsFromMode(file.getPath(), mode,
1463 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1464 }
1465 return file;
1466 }
1467
Dianne Hackborn21556372010-02-04 16:34:40 -08001468 static ContextImpl createSystemContext(ActivityThread mainThread) {
1469 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 context.init(Resources.getSystem(), mainThread);
1471 return context;
1472 }
1473
Dianne Hackborn21556372010-02-04 16:34:40 -08001474 ContextImpl() {
Carl Shapiro82fe5642010-02-24 00:14:23 -08001475 // For debug only
1476 //++sInstanceCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 mOuterContext = this;
1478 }
1479
1480 /**
1481 * Create a new ApplicationContext from an existing one. The new one
1482 * works and operates the same as the one it is copying.
1483 *
1484 * @param context Existing application context.
1485 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001486 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001487 ++sInstanceCount;
1488 mPackageInfo = context.mPackageInfo;
1489 mResources = context.mResources;
1490 mMainThread = context.mMainThread;
1491 mContentResolver = context.mContentResolver;
1492 mOuterContext = this;
1493 }
1494
1495 final void init(ActivityThread.PackageInfo packageInfo,
1496 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001497 init(packageInfo, activityToken, mainThread, null);
1498 }
1499
1500 final void init(ActivityThread.PackageInfo packageInfo,
1501 IBinder activityToken, ActivityThread mainThread,
1502 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001503 mPackageInfo = packageInfo;
1504 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001505
Dianne Hackborn559a7872010-04-07 18:19:41 -07001506 if (mResources != null && container != null
1507 && container.getCompatibilityInfo().applicationScale !=
1508 mResources.getCompatibilityInfo().applicationScale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001509 if (DEBUG) {
1510 Log.d(TAG, "loaded context has different scaling. Using container's" +
1511 " compatiblity info:" + container.getDisplayMetrics());
1512 }
1513 mResources = mainThread.getTopLevelResources(
1514 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1515 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 mMainThread = mainThread;
1517 mContentResolver = new ApplicationContentResolver(this, mainThread);
1518
1519 setActivityToken(activityToken);
1520 }
1521
1522 final void init(Resources resources, ActivityThread mainThread) {
1523 mPackageInfo = null;
1524 mResources = resources;
1525 mMainThread = mainThread;
1526 mContentResolver = new ApplicationContentResolver(this, mainThread);
1527 }
1528
1529 final void scheduleFinalCleanup(String who, String what) {
1530 mMainThread.scheduleContextCleanup(this, who, what);
1531 }
1532
1533 final void performFinalCleanup(String who, String what) {
1534 //Log.i(TAG, "Cleanup up context: " + this);
1535 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1536 }
1537
1538 final Context getReceiverRestrictedContext() {
1539 if (mReceiverRestrictedContext != null) {
1540 return mReceiverRestrictedContext;
1541 }
1542 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1543 }
1544
1545 final void setActivityToken(IBinder token) {
1546 mActivityToken = token;
1547 }
1548
1549 final void setOuterContext(Context context) {
1550 mOuterContext = context;
1551 }
1552
1553 final Context getOuterContext() {
1554 return mOuterContext;
1555 }
1556
1557 final IBinder getActivityToken() {
1558 return mActivityToken;
1559 }
1560
1561 private static void setFilePermissionsFromMode(String name, int mode,
1562 int extraPermissions) {
1563 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1564 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1565 |extraPermissions;
1566 if ((mode&MODE_WORLD_READABLE) != 0) {
1567 perms |= FileUtils.S_IROTH;
1568 }
1569 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1570 perms |= FileUtils.S_IWOTH;
1571 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001572 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1574 + ", perms=0x" + Integer.toHexString(perms));
1575 }
1576 FileUtils.setPermissions(name, perms, -1, -1);
1577 }
1578
Oscar Montemayora8529f62009-11-18 10:14:20 -08001579 private File validateFilePath(String name, boolean createDirectory) {
1580 File dir;
1581 File f;
1582
1583 if (name.charAt(0) == File.separatorChar) {
1584 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1585 dir = new File(dirPath);
1586 name = name.substring(name.lastIndexOf(File.separatorChar));
1587 f = new File(dir, name);
1588 } else {
1589 dir = getDatabasesDir();
1590 f = makeFilename(dir, name);
1591 }
1592
1593 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1594 FileUtils.setPermissions(dir.getPath(),
1595 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1596 -1, -1);
1597 }
1598
1599 return f;
1600 }
1601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 private File makeFilename(File base, String name) {
1603 if (name.indexOf(File.separatorChar) < 0) {
1604 return new File(base, name);
1605 }
1606 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001607 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001608 }
1609
1610 // ----------------------------------------------------------------------
1611 // ----------------------------------------------------------------------
1612 // ----------------------------------------------------------------------
1613
1614 private static final class ApplicationContentResolver extends ContentResolver {
1615 public ApplicationContentResolver(Context context,
1616 ActivityThread mainThread)
1617 {
1618 super(context);
1619 mMainThread = mainThread;
1620 }
1621
1622 @Override
1623 protected IContentProvider acquireProvider(Context context, String name)
1624 {
1625 return mMainThread.acquireProvider(context, name);
1626 }
1627
1628 @Override
1629 public boolean releaseProvider(IContentProvider provider)
1630 {
1631 return mMainThread.releaseProvider(provider);
1632 }
1633
1634 private final ActivityThread mMainThread;
1635 }
1636
1637 // ----------------------------------------------------------------------
1638 // ----------------------------------------------------------------------
1639 // ----------------------------------------------------------------------
1640
1641 /*package*/
1642 static final class ApplicationPackageManager extends PackageManager {
1643 @Override
1644 public PackageInfo getPackageInfo(String packageName, int flags)
1645 throws NameNotFoundException {
1646 try {
1647 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1648 if (pi != null) {
1649 return pi;
1650 }
1651 } catch (RemoteException e) {
1652 throw new RuntimeException("Package manager has died", e);
1653 }
1654
1655 throw new NameNotFoundException(packageName);
1656 }
1657
Mihai Predaeae850c2009-05-13 10:13:48 +02001658 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001659 public String[] currentToCanonicalPackageNames(String[] names) {
1660 try {
1661 return mPM.currentToCanonicalPackageNames(names);
1662 } catch (RemoteException e) {
1663 throw new RuntimeException("Package manager has died", e);
1664 }
1665 }
1666
1667 @Override
1668 public String[] canonicalToCurrentPackageNames(String[] names) {
1669 try {
1670 return mPM.canonicalToCurrentPackageNames(names);
1671 } catch (RemoteException e) {
1672 throw new RuntimeException("Package manager has died", e);
1673 }
1674 }
1675
1676 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001677 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 // First see if the package has an INFO activity; the existence of
1679 // such an activity is implied to be the desired front-door for the
1680 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001681 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1682 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001683 intentToResolve.setPackage(packageName);
1684 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001687 if (resolveInfo == null) {
1688 // reuse the intent instance
1689 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1690 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001691 intentToResolve.setPackage(packageName);
1692 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001694 if (resolveInfo == null) {
1695 return null;
1696 }
1697 Intent intent = new Intent(Intent.ACTION_MAIN);
1698 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1699 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1700 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703 @Override
1704 public int[] getPackageGids(String packageName)
1705 throws NameNotFoundException {
1706 try {
1707 int[] gids = mPM.getPackageGids(packageName);
1708 if (gids == null || gids.length > 0) {
1709 return gids;
1710 }
1711 } catch (RemoteException e) {
1712 throw new RuntimeException("Package manager has died", e);
1713 }
1714
1715 throw new NameNotFoundException(packageName);
1716 }
1717
1718 @Override
1719 public PermissionInfo getPermissionInfo(String name, int flags)
1720 throws NameNotFoundException {
1721 try {
1722 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1723 if (pi != null) {
1724 return pi;
1725 }
1726 } catch (RemoteException e) {
1727 throw new RuntimeException("Package manager has died", e);
1728 }
1729
1730 throw new NameNotFoundException(name);
1731 }
1732
1733 @Override
1734 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1735 throws NameNotFoundException {
1736 try {
1737 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1738 if (pi != null) {
1739 return pi;
1740 }
1741 } catch (RemoteException e) {
1742 throw new RuntimeException("Package manager has died", e);
1743 }
1744
1745 throw new NameNotFoundException(group);
1746 }
1747
1748 @Override
1749 public PermissionGroupInfo getPermissionGroupInfo(String name,
1750 int flags) throws NameNotFoundException {
1751 try {
1752 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1753 if (pgi != null) {
1754 return pgi;
1755 }
1756 } catch (RemoteException e) {
1757 throw new RuntimeException("Package manager has died", e);
1758 }
1759
1760 throw new NameNotFoundException(name);
1761 }
1762
1763 @Override
1764 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1765 try {
1766 return mPM.getAllPermissionGroups(flags);
1767 } catch (RemoteException e) {
1768 throw new RuntimeException("Package manager has died", e);
1769 }
1770 }
1771
1772 @Override
1773 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1774 throws NameNotFoundException {
1775 try {
1776 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1777 if (ai != null) {
1778 return ai;
1779 }
1780 } catch (RemoteException e) {
1781 throw new RuntimeException("Package manager has died", e);
1782 }
1783
1784 throw new NameNotFoundException(packageName);
1785 }
1786
1787 @Override
1788 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1789 throws NameNotFoundException {
1790 try {
1791 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1792 if (ai != null) {
1793 return ai;
1794 }
1795 } catch (RemoteException e) {
1796 throw new RuntimeException("Package manager has died", e);
1797 }
1798
1799 throw new NameNotFoundException(className.toString());
1800 }
1801
1802 @Override
1803 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1804 throws NameNotFoundException {
1805 try {
1806 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1807 if (ai != null) {
1808 return ai;
1809 }
1810 } catch (RemoteException e) {
1811 throw new RuntimeException("Package manager has died", e);
1812 }
1813
1814 throw new NameNotFoundException(className.toString());
1815 }
1816
1817 @Override
1818 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1819 throws NameNotFoundException {
1820 try {
1821 ServiceInfo si = mPM.getServiceInfo(className, flags);
1822 if (si != null) {
1823 return si;
1824 }
1825 } catch (RemoteException e) {
1826 throw new RuntimeException("Package manager has died", e);
1827 }
1828
1829 throw new NameNotFoundException(className.toString());
1830 }
1831
1832 @Override
1833 public String[] getSystemSharedLibraryNames() {
1834 try {
1835 return mPM.getSystemSharedLibraryNames();
1836 } catch (RemoteException e) {
1837 throw new RuntimeException("Package manager has died", e);
1838 }
1839 }
1840
1841 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001842 public FeatureInfo[] getSystemAvailableFeatures() {
1843 try {
1844 return mPM.getSystemAvailableFeatures();
1845 } catch (RemoteException e) {
1846 throw new RuntimeException("Package manager has died", e);
1847 }
1848 }
1849
1850 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001851 public boolean hasSystemFeature(String name) {
1852 try {
1853 return mPM.hasSystemFeature(name);
1854 } catch (RemoteException e) {
1855 throw new RuntimeException("Package manager has died", e);
1856 }
1857 }
1858
1859 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 public int checkPermission(String permName, String pkgName) {
1861 try {
1862 return mPM.checkPermission(permName, pkgName);
1863 } catch (RemoteException e) {
1864 throw new RuntimeException("Package manager has died", e);
1865 }
1866 }
1867
1868 @Override
1869 public boolean addPermission(PermissionInfo info) {
1870 try {
1871 return mPM.addPermission(info);
1872 } catch (RemoteException e) {
1873 throw new RuntimeException("Package manager has died", e);
1874 }
1875 }
1876
1877 @Override
Dianne Hackbornd7c09682010-03-30 10:42:20 -07001878 public boolean addPermissionAsync(PermissionInfo info) {
1879 try {
1880 return mPM.addPermissionAsync(info);
1881 } catch (RemoteException e) {
1882 throw new RuntimeException("Package manager has died", e);
1883 }
1884 }
1885
1886 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 public void removePermission(String name) {
1888 try {
1889 mPM.removePermission(name);
1890 } catch (RemoteException e) {
1891 throw new RuntimeException("Package manager has died", e);
1892 }
1893 }
1894
1895 @Override
1896 public int checkSignatures(String pkg1, String pkg2) {
1897 try {
1898 return mPM.checkSignatures(pkg1, pkg2);
1899 } catch (RemoteException e) {
1900 throw new RuntimeException("Package manager has died", e);
1901 }
1902 }
1903
1904 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001905 public int checkSignatures(int uid1, int uid2) {
1906 try {
1907 return mPM.checkUidSignatures(uid1, uid2);
1908 } catch (RemoteException e) {
1909 throw new RuntimeException("Package manager has died", e);
1910 }
1911 }
1912
1913 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001914 public String[] getPackagesForUid(int uid) {
1915 try {
1916 return mPM.getPackagesForUid(uid);
1917 } catch (RemoteException e) {
1918 throw new RuntimeException("Package manager has died", e);
1919 }
1920 }
1921
1922 @Override
1923 public String getNameForUid(int uid) {
1924 try {
1925 return mPM.getNameForUid(uid);
1926 } catch (RemoteException e) {
1927 throw new RuntimeException("Package manager has died", e);
1928 }
1929 }
1930
1931 @Override
1932 public int getUidForSharedUser(String sharedUserName)
1933 throws NameNotFoundException {
1934 try {
1935 int uid = mPM.getUidForSharedUser(sharedUserName);
1936 if(uid != -1) {
1937 return uid;
1938 }
1939 } catch (RemoteException e) {
1940 throw new RuntimeException("Package manager has died", e);
1941 }
1942 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1943 }
1944
1945 @Override
1946 public List<PackageInfo> getInstalledPackages(int flags) {
1947 try {
1948 return mPM.getInstalledPackages(flags);
1949 } catch (RemoteException e) {
1950 throw new RuntimeException("Package manager has died", e);
1951 }
1952 }
1953
1954 @Override
1955 public List<ApplicationInfo> getInstalledApplications(int flags) {
1956 try {
1957 return mPM.getInstalledApplications(flags);
1958 } catch (RemoteException e) {
1959 throw new RuntimeException("Package manager has died", e);
1960 }
1961 }
1962
1963 @Override
1964 public ResolveInfo resolveActivity(Intent intent, int flags) {
1965 try {
1966 return mPM.resolveIntent(
1967 intent,
1968 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1969 flags);
1970 } catch (RemoteException e) {
1971 throw new RuntimeException("Package manager has died", e);
1972 }
1973 }
1974
1975 @Override
1976 public List<ResolveInfo> queryIntentActivities(Intent intent,
1977 int flags) {
1978 try {
1979 return mPM.queryIntentActivities(
1980 intent,
1981 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1982 flags);
1983 } catch (RemoteException e) {
1984 throw new RuntimeException("Package manager has died", e);
1985 }
1986 }
1987
1988 @Override
1989 public List<ResolveInfo> queryIntentActivityOptions(
1990 ComponentName caller, Intent[] specifics, Intent intent,
1991 int flags) {
1992 final ContentResolver resolver = mContext.getContentResolver();
1993
1994 String[] specificTypes = null;
1995 if (specifics != null) {
1996 final int N = specifics.length;
1997 for (int i=0; i<N; i++) {
1998 Intent sp = specifics[i];
1999 if (sp != null) {
2000 String t = sp.resolveTypeIfNeeded(resolver);
2001 if (t != null) {
2002 if (specificTypes == null) {
2003 specificTypes = new String[N];
2004 }
2005 specificTypes[i] = t;
2006 }
2007 }
2008 }
2009 }
2010
2011 try {
2012 return mPM.queryIntentActivityOptions(caller, specifics,
2013 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2014 flags);
2015 } catch (RemoteException e) {
2016 throw new RuntimeException("Package manager has died", e);
2017 }
2018 }
2019
2020 @Override
2021 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2022 try {
2023 return mPM.queryIntentReceivers(
2024 intent,
2025 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2026 flags);
2027 } catch (RemoteException e) {
2028 throw new RuntimeException("Package manager has died", e);
2029 }
2030 }
2031
2032 @Override
2033 public ResolveInfo resolveService(Intent intent, int flags) {
2034 try {
2035 return mPM.resolveService(
2036 intent,
2037 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2038 flags);
2039 } catch (RemoteException e) {
2040 throw new RuntimeException("Package manager has died", e);
2041 }
2042 }
2043
2044 @Override
2045 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2046 try {
2047 return mPM.queryIntentServices(
2048 intent,
2049 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2050 flags);
2051 } catch (RemoteException e) {
2052 throw new RuntimeException("Package manager has died", e);
2053 }
2054 }
2055
2056 @Override
2057 public ProviderInfo resolveContentProvider(String name,
2058 int flags) {
2059 try {
2060 return mPM.resolveContentProvider(name, flags);
2061 } catch (RemoteException e) {
2062 throw new RuntimeException("Package manager has died", e);
2063 }
2064 }
2065
2066 @Override
2067 public List<ProviderInfo> queryContentProviders(String processName,
2068 int uid, int flags) {
2069 try {
2070 return mPM.queryContentProviders(processName, uid, flags);
2071 } catch (RemoteException e) {
2072 throw new RuntimeException("Package manager has died", e);
2073 }
2074 }
2075
2076 @Override
2077 public InstrumentationInfo getInstrumentationInfo(
2078 ComponentName className, int flags)
2079 throws NameNotFoundException {
2080 try {
2081 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2082 className, flags);
2083 if (ii != null) {
2084 return ii;
2085 }
2086 } catch (RemoteException e) {
2087 throw new RuntimeException("Package manager has died", e);
2088 }
2089
2090 throw new NameNotFoundException(className.toString());
2091 }
2092
2093 @Override
2094 public List<InstrumentationInfo> queryInstrumentation(
2095 String targetPackage, int flags) {
2096 try {
2097 return mPM.queryInstrumentation(targetPackage, flags);
2098 } catch (RemoteException e) {
2099 throw new RuntimeException("Package manager has died", e);
2100 }
2101 }
2102
2103 @Override public Drawable getDrawable(String packageName, int resid,
2104 ApplicationInfo appInfo) {
2105 ResourceName name = new ResourceName(packageName, resid);
2106 Drawable dr = getCachedIcon(name);
2107 if (dr != null) {
2108 return dr;
2109 }
2110 if (appInfo == null) {
2111 try {
2112 appInfo = getApplicationInfo(packageName, 0);
2113 } catch (NameNotFoundException e) {
2114 return null;
2115 }
2116 }
2117 try {
2118 Resources r = getResourcesForApplication(appInfo);
2119 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002120 if (false) {
2121 RuntimeException e = new RuntimeException("here");
2122 e.fillInStackTrace();
2123 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2124 + " from package " + packageName
2125 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2126 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2127 e);
2128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2130 + Integer.toHexString(resid) + " from " + r
2131 + ": " + dr);
2132 putCachedIcon(name, dr);
2133 return dr;
2134 } catch (NameNotFoundException e) {
2135 Log.w("PackageManager", "Failure retrieving resources for"
2136 + appInfo.packageName);
2137 } catch (RuntimeException e) {
2138 // If an exception was thrown, fall through to return
2139 // default icon.
2140 Log.w("PackageManager", "Failure retrieving icon 0x"
2141 + Integer.toHexString(resid) + " in package "
2142 + packageName, e);
2143 }
2144 return null;
2145 }
2146
2147 @Override public Drawable getActivityIcon(ComponentName activityName)
2148 throws NameNotFoundException {
2149 return getActivityInfo(activityName, 0).loadIcon(this);
2150 }
2151
2152 @Override public Drawable getActivityIcon(Intent intent)
2153 throws NameNotFoundException {
2154 if (intent.getComponent() != null) {
2155 return getActivityIcon(intent.getComponent());
2156 }
2157
2158 ResolveInfo info = resolveActivity(
2159 intent, PackageManager.MATCH_DEFAULT_ONLY);
2160 if (info != null) {
2161 return info.activityInfo.loadIcon(this);
2162 }
2163
2164 throw new NameNotFoundException(intent.toURI());
2165 }
2166
2167 @Override public Drawable getDefaultActivityIcon() {
2168 return Resources.getSystem().getDrawable(
2169 com.android.internal.R.drawable.sym_def_app_icon);
2170 }
2171
2172 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002173 return info.loadIcon(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002174 }
2175
2176 @Override public Drawable getApplicationIcon(String packageName)
2177 throws NameNotFoundException {
2178 return getApplicationIcon(getApplicationInfo(packageName, 0));
2179 }
Adam Powell81cd2e92010-04-21 16:35:18 -07002180
2181 @Override
2182 public Drawable getActivityLogo(ComponentName activityName)
2183 throws NameNotFoundException {
2184 return getActivityInfo(activityName, 0).loadLogo(this);
2185 }
2186
2187 @Override
2188 public Drawable getActivityLogo(Intent intent)
2189 throws NameNotFoundException {
2190 if (intent.getComponent() != null) {
2191 return getActivityLogo(intent.getComponent());
2192 }
2193
2194 ResolveInfo info = resolveActivity(
2195 intent, PackageManager.MATCH_DEFAULT_ONLY);
2196 if (info != null) {
2197 return info.activityInfo.loadLogo(this);
2198 }
2199
2200 throw new NameNotFoundException(intent.toUri(0));
2201 }
2202
2203 @Override
2204 public Drawable getApplicationLogo(ApplicationInfo info) {
2205 return info.loadLogo(this);
2206 }
2207
2208 @Override
2209 public Drawable getApplicationLogo(String packageName)
2210 throws NameNotFoundException {
2211 return getApplicationLogo(getApplicationInfo(packageName, 0));
2212 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002213
2214 @Override public Resources getResourcesForActivity(
2215 ComponentName activityName) throws NameNotFoundException {
2216 return getResourcesForApplication(
2217 getActivityInfo(activityName, 0).applicationInfo);
2218 }
2219
2220 @Override public Resources getResourcesForApplication(
2221 ApplicationInfo app) throws NameNotFoundException {
2222 if (app.packageName.equals("system")) {
2223 return mContext.mMainThread.getSystemContext().getResources();
2224 }
2225 Resources r = mContext.mMainThread.getTopLevelResources(
2226 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002227 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 if (r != null) {
2229 return r;
2230 }
2231 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2232 }
2233
2234 @Override public Resources getResourcesForApplication(
2235 String appPackageName) throws NameNotFoundException {
2236 return getResourcesForApplication(
2237 getApplicationInfo(appPackageName, 0));
2238 }
2239
2240 int mCachedSafeMode = -1;
2241 @Override public boolean isSafeMode() {
2242 try {
2243 if (mCachedSafeMode < 0) {
2244 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2245 }
2246 return mCachedSafeMode != 0;
2247 } catch (RemoteException e) {
2248 throw new RuntimeException("Package manager has died", e);
2249 }
2250 }
2251
2252 static void configurationChanged() {
2253 synchronized (sSync) {
2254 sIconCache.clear();
2255 sStringCache.clear();
2256 }
2257 }
2258
Dianne Hackborn21556372010-02-04 16:34:40 -08002259 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002260 IPackageManager pm) {
2261 mContext = context;
2262 mPM = pm;
2263 }
2264
2265 private Drawable getCachedIcon(ResourceName name) {
2266 synchronized (sSync) {
2267 WeakReference<Drawable> wr = sIconCache.get(name);
2268 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2269 + name + ": " + wr);
2270 if (wr != null) { // we have the activity
2271 Drawable dr = wr.get();
2272 if (dr != null) {
2273 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2274 + name + ": " + dr);
2275 return dr;
2276 }
2277 // our entry has been purged
2278 sIconCache.remove(name);
2279 }
2280 }
2281 return null;
2282 }
2283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 private void putCachedIcon(ResourceName name, Drawable dr) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 synchronized (sSync) {
2286 sIconCache.put(name, new WeakReference<Drawable>(dr));
2287 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2288 + name + ": " + dr);
2289 }
2290 }
2291
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002292 static final void handlePackageBroadcast(int cmd, String[] pkgList,
2293 boolean hasPkgInfo) {
2294 boolean immediateGc = false;
2295 if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2296 immediateGc = true;
2297 }
2298 if (pkgList != null && (pkgList.length > 0)) {
2299 boolean needCleanup = false;
2300 for (String ssp : pkgList) {
2301 synchronized (sSync) {
2302 if (sIconCache.size() > 0) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002303 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2304 while (it.hasNext()) {
2305 ResourceName nm = it.next();
2306 if (nm.packageName.equals(ssp)) {
2307 //Log.i(TAG, "Removing cached drawable for " + nm);
2308 it.remove();
2309 needCleanup = true;
2310 }
2311 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002312 }
2313 if (sStringCache.size() > 0) {
2314 Iterator<ResourceName> it = sStringCache.keySet().iterator();
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002315 while (it.hasNext()) {
2316 ResourceName nm = it.next();
2317 if (nm.packageName.equals(ssp)) {
2318 //Log.i(TAG, "Removing cached string for " + nm);
2319 it.remove();
2320 needCleanup = true;
2321 }
2322 }
2323 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002324 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002325 }
2326 if (needCleanup || hasPkgInfo) {
2327 if (immediateGc) {
2328 // Schedule an immediate gc.
2329 Runtime.getRuntime().gc();
2330 } else {
2331 ActivityThread.currentActivityThread().scheduleGcIdler();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 }
2333 }
2334 }
2335 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07002336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002337 private static final class ResourceName {
2338 final String packageName;
2339 final int iconId;
2340
2341 ResourceName(String _packageName, int _iconId) {
2342 packageName = _packageName;
2343 iconId = _iconId;
2344 }
2345
2346 ResourceName(ApplicationInfo aInfo, int _iconId) {
2347 this(aInfo.packageName, _iconId);
2348 }
2349
2350 ResourceName(ComponentInfo cInfo, int _iconId) {
2351 this(cInfo.applicationInfo.packageName, _iconId);
2352 }
2353
2354 ResourceName(ResolveInfo rInfo, int _iconId) {
2355 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2356 }
2357
2358 @Override
2359 public boolean equals(Object o) {
2360 if (this == o) return true;
2361 if (o == null || getClass() != o.getClass()) return false;
2362
2363 ResourceName that = (ResourceName) o;
2364
2365 if (iconId != that.iconId) return false;
2366 return !(packageName != null ?
2367 !packageName.equals(that.packageName) : that.packageName != null);
2368
2369 }
2370
2371 @Override
2372 public int hashCode() {
2373 int result;
2374 result = packageName.hashCode();
2375 result = 31 * result + iconId;
2376 return result;
2377 }
2378
2379 @Override
2380 public String toString() {
2381 return "{ResourceName " + packageName + " / " + iconId + "}";
2382 }
2383 }
2384
2385 private CharSequence getCachedString(ResourceName name) {
2386 synchronized (sSync) {
2387 WeakReference<CharSequence> wr = sStringCache.get(name);
2388 if (wr != null) { // we have the activity
2389 CharSequence cs = wr.get();
2390 if (cs != null) {
2391 return cs;
2392 }
2393 // our entry has been purged
2394 sStringCache.remove(name);
2395 }
2396 }
2397 return null;
2398 }
2399
2400 private void putCachedString(ResourceName name, CharSequence cs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002401 synchronized (sSync) {
2402 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2403 }
2404 }
2405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002406 @Override
2407 public CharSequence getText(String packageName, int resid,
2408 ApplicationInfo appInfo) {
2409 ResourceName name = new ResourceName(packageName, resid);
2410 CharSequence text = getCachedString(name);
2411 if (text != null) {
2412 return text;
2413 }
2414 if (appInfo == null) {
2415 try {
2416 appInfo = getApplicationInfo(packageName, 0);
2417 } catch (NameNotFoundException e) {
2418 return null;
2419 }
2420 }
2421 try {
2422 Resources r = getResourcesForApplication(appInfo);
2423 text = r.getText(resid);
2424 putCachedString(name, text);
2425 return text;
2426 } catch (NameNotFoundException e) {
2427 Log.w("PackageManager", "Failure retrieving resources for"
2428 + appInfo.packageName);
2429 } catch (RuntimeException e) {
2430 // If an exception was thrown, fall through to return
2431 // default icon.
2432 Log.w("PackageManager", "Failure retrieving text 0x"
2433 + Integer.toHexString(resid) + " in package "
2434 + packageName, e);
2435 }
2436 return null;
2437 }
2438
2439 @Override
2440 public XmlResourceParser getXml(String packageName, int resid,
2441 ApplicationInfo appInfo) {
2442 if (appInfo == null) {
2443 try {
2444 appInfo = getApplicationInfo(packageName, 0);
2445 } catch (NameNotFoundException e) {
2446 return null;
2447 }
2448 }
2449 try {
2450 Resources r = getResourcesForApplication(appInfo);
2451 return r.getXml(resid);
2452 } catch (RuntimeException e) {
2453 // If an exception was thrown, fall through to return
2454 // default icon.
2455 Log.w("PackageManager", "Failure retrieving xml 0x"
2456 + Integer.toHexString(resid) + " in package "
2457 + packageName, e);
2458 } catch (NameNotFoundException e) {
2459 Log.w("PackageManager", "Failure retrieving resources for"
2460 + appInfo.packageName);
2461 }
2462 return null;
2463 }
2464
2465 @Override
2466 public CharSequence getApplicationLabel(ApplicationInfo info) {
Jeff Brown07330792010-03-30 19:57:08 -07002467 return info.loadLabel(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469
2470 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002471 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2472 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002474 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 } catch (RemoteException e) {
2476 // Should never happen!
2477 }
2478 }
2479
2480 @Override
Suchi Amalapurapu8946dd32010-02-19 09:19:34 -08002481 public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2482 try {
2483 mPM.movePackage(packageName, observer, flags);
2484 } catch (RemoteException e) {
2485 // Should never happen!
2486 }
2487 }
2488
2489 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002490 public String getInstallerPackageName(String packageName) {
2491 try {
2492 return mPM.getInstallerPackageName(packageName);
2493 } catch (RemoteException e) {
2494 // Should never happen!
2495 }
2496 return null;
2497 }
2498
2499 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002500 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2501 try {
2502 mPM.deletePackage(packageName, observer, flags);
2503 } catch (RemoteException e) {
2504 // Should never happen!
2505 }
2506 }
2507 @Override
2508 public void clearApplicationUserData(String packageName,
2509 IPackageDataObserver observer) {
2510 try {
2511 mPM.clearApplicationUserData(packageName, observer);
2512 } catch (RemoteException e) {
2513 // Should never happen!
2514 }
2515 }
2516 @Override
2517 public void deleteApplicationCacheFiles(String packageName,
2518 IPackageDataObserver observer) {
2519 try {
2520 mPM.deleteApplicationCacheFiles(packageName, observer);
2521 } catch (RemoteException e) {
2522 // Should never happen!
2523 }
2524 }
2525 @Override
2526 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2527 try {
2528 mPM.freeStorageAndNotify(idealStorageSize, observer);
2529 } catch (RemoteException e) {
2530 // Should never happen!
2531 }
2532 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002535 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002537 mPM.freeStorage(freeStorageSize, pi);
2538 } catch (RemoteException e) {
2539 // Should never happen!
2540 }
2541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542
2543 @Override
2544 public void getPackageSizeInfo(String packageName,
2545 IPackageStatsObserver observer) {
2546 try {
2547 mPM.getPackageSizeInfo(packageName, observer);
2548 } catch (RemoteException e) {
2549 // Should never happen!
2550 }
2551 }
2552 @Override
2553 public void addPackageToPreferred(String packageName) {
2554 try {
2555 mPM.addPackageToPreferred(packageName);
2556 } catch (RemoteException e) {
2557 // Should never happen!
2558 }
2559 }
2560
2561 @Override
2562 public void removePackageFromPreferred(String packageName) {
2563 try {
2564 mPM.removePackageFromPreferred(packageName);
2565 } catch (RemoteException e) {
2566 // Should never happen!
2567 }
2568 }
2569
2570 @Override
2571 public List<PackageInfo> getPreferredPackages(int flags) {
2572 try {
2573 return mPM.getPreferredPackages(flags);
2574 } catch (RemoteException e) {
2575 // Should never happen!
2576 }
2577 return new ArrayList<PackageInfo>();
2578 }
2579
2580 @Override
2581 public void addPreferredActivity(IntentFilter filter,
2582 int match, ComponentName[] set, ComponentName activity) {
2583 try {
2584 mPM.addPreferredActivity(filter, match, set, activity);
2585 } catch (RemoteException e) {
2586 // Should never happen!
2587 }
2588 }
2589
2590 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002591 public void replacePreferredActivity(IntentFilter filter,
2592 int match, ComponentName[] set, ComponentName activity) {
2593 try {
2594 mPM.replacePreferredActivity(filter, match, set, activity);
2595 } catch (RemoteException e) {
2596 // Should never happen!
2597 }
2598 }
2599
2600 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 public void clearPackagePreferredActivities(String packageName) {
2602 try {
2603 mPM.clearPackagePreferredActivities(packageName);
2604 } catch (RemoteException e) {
2605 // Should never happen!
2606 }
2607 }
2608
2609 @Override
2610 public int getPreferredActivities(List<IntentFilter> outFilters,
2611 List<ComponentName> outActivities, String packageName) {
2612 try {
2613 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2614 } catch (RemoteException e) {
2615 // Should never happen!
2616 }
2617 return 0;
2618 }
2619
2620 @Override
2621 public void setComponentEnabledSetting(ComponentName componentName,
2622 int newState, int flags) {
2623 try {
2624 mPM.setComponentEnabledSetting(componentName, newState, flags);
2625 } catch (RemoteException e) {
2626 // Should never happen!
2627 }
2628 }
2629
2630 @Override
2631 public int getComponentEnabledSetting(ComponentName componentName) {
2632 try {
2633 return mPM.getComponentEnabledSetting(componentName);
2634 } catch (RemoteException e) {
2635 // Should never happen!
2636 }
2637 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2638 }
2639
2640 @Override
2641 public void setApplicationEnabledSetting(String packageName,
2642 int newState, int flags) {
2643 try {
2644 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2645 } catch (RemoteException e) {
2646 // Should never happen!
2647 }
2648 }
2649
2650 @Override
2651 public int getApplicationEnabledSetting(String packageName) {
2652 try {
2653 return mPM.getApplicationEnabledSetting(packageName);
2654 } catch (RemoteException e) {
2655 // Should never happen!
2656 }
2657 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2658 }
2659
Dianne Hackborn21556372010-02-04 16:34:40 -08002660 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 private final IPackageManager mPM;
2662
2663 private static final Object sSync = new Object();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2665 = new HashMap<ResourceName, WeakReference<Drawable> >();
2666 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2667 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2668 }
2669
2670 // ----------------------------------------------------------------------
2671 // ----------------------------------------------------------------------
2672 // ----------------------------------------------------------------------
2673
2674 private static final class SharedPreferencesImpl implements SharedPreferences {
2675
2676 private final File mFile;
2677 private final File mBackupFile;
2678 private final int mMode;
2679 private Map mMap;
2680 private final FileStatus mFileStatus = new FileStatus();
2681 private long mTimestamp;
2682
The Android Open Source Project10592532009-03-18 17:39:46 -07002683 private static final Object mContent = new Object();
2684 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685
2686 SharedPreferencesImpl(
2687 File file, int mode, Map initialContents) {
2688 mFile = file;
2689 mBackupFile = makeBackupFile(file);
2690 mMode = mode;
2691 mMap = initialContents != null ? initialContents : new HashMap();
2692 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2693 mTimestamp = mFileStatus.mtime;
2694 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002695 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 }
2697
2698 public boolean hasFileChanged() {
2699 synchronized (this) {
2700 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2701 return true;
2702 }
2703 return mTimestamp != mFileStatus.mtime;
2704 }
2705 }
2706
2707 public void replace(Map newContents) {
2708 if (newContents != null) {
2709 synchronized (this) {
2710 mMap = newContents;
2711 }
2712 }
2713 }
2714
2715 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2716 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002717 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002718 }
2719 }
2720
2721 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2722 synchronized(this) {
2723 mListeners.remove(listener);
2724 }
2725 }
2726
2727 public Map<String, ?> getAll() {
2728 synchronized(this) {
2729 //noinspection unchecked
2730 return new HashMap(mMap);
2731 }
2732 }
2733
2734 public String getString(String key, String defValue) {
2735 synchronized (this) {
2736 String v = (String)mMap.get(key);
2737 return v != null ? v : defValue;
2738 }
2739 }
2740
2741 public int getInt(String key, int defValue) {
2742 synchronized (this) {
2743 Integer v = (Integer)mMap.get(key);
2744 return v != null ? v : defValue;
2745 }
2746 }
2747 public long getLong(String key, long defValue) {
2748 synchronized (this) {
2749 Long v = (Long) mMap.get(key);
2750 return v != null ? v : defValue;
2751 }
2752 }
2753 public float getFloat(String key, float defValue) {
2754 synchronized (this) {
2755 Float v = (Float)mMap.get(key);
2756 return v != null ? v : defValue;
2757 }
2758 }
2759 public boolean getBoolean(String key, boolean defValue) {
2760 synchronized (this) {
2761 Boolean v = (Boolean)mMap.get(key);
2762 return v != null ? v : defValue;
2763 }
2764 }
2765
2766 public boolean contains(String key) {
2767 synchronized (this) {
2768 return mMap.containsKey(key);
2769 }
2770 }
2771
2772 public final class EditorImpl implements Editor {
2773 private final Map<String, Object> mModified = Maps.newHashMap();
2774 private boolean mClear = false;
2775
2776 public Editor putString(String key, String value) {
2777 synchronized (this) {
2778 mModified.put(key, value);
2779 return this;
2780 }
2781 }
2782 public Editor putInt(String key, int value) {
2783 synchronized (this) {
2784 mModified.put(key, value);
2785 return this;
2786 }
2787 }
2788 public Editor putLong(String key, long value) {
2789 synchronized (this) {
2790 mModified.put(key, value);
2791 return this;
2792 }
2793 }
2794 public Editor putFloat(String key, float value) {
2795 synchronized (this) {
2796 mModified.put(key, value);
2797 return this;
2798 }
2799 }
2800 public Editor putBoolean(String key, boolean value) {
2801 synchronized (this) {
2802 mModified.put(key, value);
2803 return this;
2804 }
2805 }
2806
2807 public Editor remove(String key) {
2808 synchronized (this) {
2809 mModified.put(key, this);
2810 return this;
2811 }
2812 }
2813
2814 public Editor clear() {
2815 synchronized (this) {
2816 mClear = true;
2817 return this;
2818 }
2819 }
2820
2821 public boolean commit() {
2822 boolean returnValue;
2823
2824 boolean hasListeners;
2825 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002826 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827
2828 synchronized (SharedPreferencesImpl.this) {
2829 hasListeners = mListeners.size() > 0;
2830 if (hasListeners) {
2831 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002832 listeners =
2833 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 }
2835
2836 synchronized (this) {
2837 if (mClear) {
2838 mMap.clear();
2839 mClear = false;
2840 }
2841
The Android Open Source Project10592532009-03-18 17:39:46 -07002842 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843 String k = e.getKey();
2844 Object v = e.getValue();
2845 if (v == this) {
2846 mMap.remove(k);
2847 } else {
2848 mMap.put(k, v);
2849 }
2850
2851 if (hasListeners) {
2852 keysModified.add(k);
2853 }
2854 }
2855
2856 mModified.clear();
2857 }
2858
2859 returnValue = writeFileLocked();
2860 }
2861
2862 if (hasListeners) {
2863 for (int i = keysModified.size() - 1; i >= 0; i--) {
2864 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002865 for (OnSharedPreferenceChangeListener listener : listeners) {
2866 if (listener != null) {
2867 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2868 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 }
2870 }
2871 }
2872
2873 return returnValue;
2874 }
2875 }
2876
2877 public Editor edit() {
2878 return new EditorImpl();
2879 }
2880
2881 private FileOutputStream createFileOutputStream(File file) {
2882 FileOutputStream str = null;
2883 try {
2884 str = new FileOutputStream(file);
2885 } catch (FileNotFoundException e) {
2886 File parent = file.getParentFile();
2887 if (!parent.mkdir()) {
2888 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2889 return null;
2890 }
2891 FileUtils.setPermissions(
2892 parent.getPath(),
2893 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2894 -1, -1);
2895 try {
2896 str = new FileOutputStream(file);
2897 } catch (FileNotFoundException e2) {
2898 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2899 }
2900 }
2901 return str;
2902 }
2903
2904 private boolean writeFileLocked() {
2905 // Rename the current file so it may be used as a backup during the next read
2906 if (mFile.exists()) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07002907 if (!mBackupFile.exists()) {
2908 if (!mFile.renameTo(mBackupFile)) {
2909 Log.e(TAG, "Couldn't rename file " + mFile
2910 + " to backup file " + mBackupFile);
2911 return false;
2912 }
2913 } else {
2914 mFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915 }
2916 }
2917
2918 // Attempt to write the file, delete the backup and return true as atomically as
2919 // possible. If any exception occurs, delete the new file; next time we will restore
2920 // from the backup.
2921 try {
2922 FileOutputStream str = createFileOutputStream(mFile);
2923 if (str == null) {
2924 return false;
2925 }
2926 XmlUtils.writeMapXml(mMap, str);
2927 str.close();
2928 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2929 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2930 mTimestamp = mFileStatus.mtime;
2931 }
2932
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002933 // Writing was successful, delete the backup file if there is one.
2934 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 return true;
2936 } catch (XmlPullParserException e) {
2937 Log.w(TAG, "writeFileLocked: Got exception:", e);
2938 } catch (IOException e) {
2939 Log.w(TAG, "writeFileLocked: Got exception:", e);
2940 }
2941 // Clean up an unsuccessfully written file
2942 if (mFile.exists()) {
2943 if (!mFile.delete()) {
2944 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2945 }
2946 }
2947 return false;
2948 }
2949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950}