blob: db6a4bf1405e062745a526b454ccc7943e97a4bd [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;
Tom Taylord4a47292009-12-21 13:59:18 -080020import com.android.common.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;
45import android.content.pm.IPackageManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070046import android.content.pm.IPackageStatsObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047import android.content.pm.InstrumentationInfo;
48import android.content.pm.PackageInfo;
49import android.content.pm.PackageManager;
50import android.content.pm.PermissionGroupInfo;
51import android.content.pm.PermissionInfo;
52import android.content.pm.ProviderInfo;
53import android.content.pm.ResolveInfo;
54import android.content.pm.ServiceInfo;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080055import android.content.pm.PackageParser.Package;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.content.res.AssetManager;
57import android.content.res.Resources;
58import android.content.res.XmlResourceParser;
59import android.database.sqlite.SQLiteDatabase;
60import android.database.sqlite.SQLiteDatabase.CursorFactory;
61import android.graphics.Bitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.graphics.drawable.Drawable;
63import android.hardware.SensorManager;
64import android.location.ILocationManager;
65import android.location.LocationManager;
66import android.media.AudioManager;
67import android.net.ConnectivityManager;
68import android.net.IConnectivityManager;
69import android.net.Uri;
70import android.net.wifi.IWifiManager;
71import android.net.wifi.WifiManager;
72import android.os.Binder;
73import android.os.Bundle;
Dan Egnorf18a01c2009-11-12 11:32:50 -080074import android.os.DropBoxManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080075import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import android.os.FileUtils;
77import android.os.Handler;
78import android.os.IBinder;
79import android.os.IPowerManager;
svetoslavganov75986cf2009-05-14 22:28:01 -070080import android.os.Looper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.os.PowerManager;
82import android.os.Process;
svetoslavganov75986cf2009-05-14 22:28:01 -070083import android.os.RemoteException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.os.ServiceManager;
Oscar Montemayor539d3c42010-01-29 15:27:00 -080085import android.os.StatFs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.os.Vibrator;
87import android.os.FileUtils.FileStatus;
San Mehatb1043402010-02-05 08:26:50 -080088import android.os.storage.StorageManager;
Suchi Amalapurapu117818e2010-02-09 03:45:40 -080089import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.telephony.TelephonyManager;
91import android.text.ClipboardManager;
92import android.util.AndroidRuntimeException;
93import android.util.Log;
94import android.view.ContextThemeWrapper;
95import android.view.LayoutInflater;
96import android.view.WindowManagerImpl;
svetoslavganov75986cf2009-05-14 22:28:01 -070097import android.view.accessibility.AccessibilityManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.view.inputmethod.InputMethodManager;
Fred Quintana60307342009-03-24 22:48:12 -070099import android.accounts.AccountManager;
100import android.accounts.IAccountManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
Dan Egnorf18a01c2009-11-12 11:32:50 -0800102import com.android.internal.os.IDropBoxManagerService;
Dan Egnor95240272009-10-27 18:23:39 -0700103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import java.io.File;
105import java.io.FileInputStream;
106import java.io.FileNotFoundException;
107import java.io.FileOutputStream;
108import java.io.IOException;
109import java.io.InputStream;
110import java.lang.ref.WeakReference;
111import java.util.ArrayList;
112import java.util.HashMap;
svetoslavganov75986cf2009-05-14 22:28:01 -0700113import java.util.HashSet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import java.util.Iterator;
115import java.util.List;
116import java.util.Map;
The Android Open Source Project10592532009-03-18 17:39:46 -0700117import java.util.Set;
svetoslavganov75986cf2009-05-14 22:28:01 -0700118import java.util.WeakHashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119import java.util.Map.Entry;
120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121class ReceiverRestrictedContext extends ContextWrapper {
122 ReceiverRestrictedContext(Context base) {
123 super(base);
124 }
125
126 @Override
127 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
128 return registerReceiver(receiver, filter, null, null);
129 }
130
131 @Override
132 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
133 String broadcastPermission, Handler scheduler) {
134 throw new ReceiverCallNotAllowedException(
135 "IntentReceiver components are not allowed to register to receive intents");
136 //ex.fillInStackTrace();
137 //Log.e("IntentReceiver", ex.getMessage(), ex);
138 //return mContext.registerReceiver(receiver, filter, broadcastPermission,
139 // scheduler);
140 }
141
142 @Override
143 public boolean bindService(Intent service, ServiceConnection conn, int flags) {
144 throw new ReceiverCallNotAllowedException(
145 "IntentReceiver components are not allowed to bind to services");
146 //ex.fillInStackTrace();
147 //Log.e("IntentReceiver", ex.getMessage(), ex);
148 //return mContext.bindService(service, interfaceName, conn, flags);
149 }
150}
151
152/**
Dianne Hackborn21556372010-02-04 16:34:40 -0800153 * Common implementation of Context API, which provides the base
154 * context object for Activity and other application components.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 */
Dianne Hackborn21556372010-02-04 16:34:40 -0800156class ContextImpl extends Context {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 private final static String TAG = "ApplicationContext";
Mitsuru Oshima569076c2009-07-02 20:06:08 -0700158 private final static boolean DEBUG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private final static boolean DEBUG_ICONS = false;
160
161 private static final Object sSync = new Object();
162 private static AlarmManager sAlarmManager;
163 private static PowerManager sPowerManager;
164 private static ConnectivityManager sConnectivityManager;
165 private static WifiManager sWifiManager;
166 private static LocationManager sLocationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 private static final HashMap<File, SharedPreferencesImpl> sSharedPrefs =
168 new HashMap<File, SharedPreferencesImpl>();
169
170 private AudioManager mAudioManager;
171 /*package*/ ActivityThread.PackageInfo mPackageInfo;
172 private Resources mResources;
173 /*package*/ ActivityThread mMainThread;
174 private Context mOuterContext;
175 private IBinder mActivityToken = null;
176 private ApplicationContentResolver mContentResolver;
177 private int mThemeResource = 0;
178 private Resources.Theme mTheme = null;
179 private PackageManager mPackageManager;
180 private NotificationManager mNotificationManager = null;
181 private ActivityManager mActivityManager = null;
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700182 private WallpaperManager mWallpaperManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 private Context mReceiverRestrictedContext = null;
184 private SearchManager mSearchManager = null;
185 private SensorManager mSensorManager = null;
San Mehatc9d81752010-02-01 10:23:27 -0800186 private StorageManager mStorageManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187 private Vibrator mVibrator = null;
188 private LayoutInflater mLayoutInflater = null;
189 private StatusBarManager mStatusBarManager = null;
190 private TelephonyManager mTelephonyManager = null;
191 private ClipboardManager mClipboardManager = null;
Romain Guy870e09f2009-07-06 16:35:25 -0700192 private boolean mRestricted;
Fred Quintanae00a3112009-09-22 15:13:30 -0700193 private AccountManager mAccountManager; // protected by mSync
Dan Egnorf18a01c2009-11-12 11:32:50 -0800194 private DropBoxManager mDropBoxManager = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -0800195 private DevicePolicyManager mDevicePolicyManager = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196
197 private final Object mSync = new Object();
198
199 private File mDatabasesDir;
200 private File mPreferencesDir;
201 private File mFilesDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 private File mCacheDir;
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800203 private File mExternalFilesDir;
204 private File mExternalCacheDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 private static long sInstanceCount = 0;
207
208 private static final String[] EMPTY_FILE_LIST = {};
209
210 @Override
211 protected void finalize() throws Throwable {
212 super.finalize();
213 --sInstanceCount;
214 }
215
216 public static long getInstanceCount() {
217 return sInstanceCount;
218 }
219
220 @Override
221 public AssetManager getAssets() {
222 return mResources.getAssets();
223 }
224
225 @Override
226 public Resources getResources() {
227 return mResources;
228 }
229
230 @Override
231 public PackageManager getPackageManager() {
232 if (mPackageManager != null) {
233 return mPackageManager;
234 }
235
236 IPackageManager pm = ActivityThread.getPackageManager();
237 if (pm != null) {
238 // Doesn't matter if we make more than one instance.
239 return (mPackageManager = new ApplicationPackageManager(this, pm));
240 }
241
242 return null;
243 }
244
245 @Override
246 public ContentResolver getContentResolver() {
247 return mContentResolver;
248 }
249
250 @Override
251 public Looper getMainLooper() {
252 return mMainThread.getLooper();
253 }
254
255 @Override
256 public Context getApplicationContext() {
257 return mMainThread.getApplication();
258 }
259
260 @Override
261 public void setTheme(int resid) {
262 mThemeResource = resid;
263 }
264
265 @Override
266 public Resources.Theme getTheme() {
267 if (mTheme == null) {
268 if (mThemeResource == 0) {
269 mThemeResource = com.android.internal.R.style.Theme;
270 }
271 mTheme = mResources.newTheme();
272 mTheme.applyStyle(mThemeResource, true);
273 }
274 return mTheme;
275 }
276
277 @Override
278 public ClassLoader getClassLoader() {
279 return mPackageInfo != null ?
280 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
281 }
282
283 @Override
284 public String getPackageName() {
285 if (mPackageInfo != null) {
286 return mPackageInfo.getPackageName();
287 }
288 throw new RuntimeException("Not supported in system context");
289 }
290
291 @Override
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700292 public ApplicationInfo getApplicationInfo() {
293 if (mPackageInfo != null) {
294 return mPackageInfo.getApplicationInfo();
295 }
296 throw new RuntimeException("Not supported in system context");
297 }
298
299 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 public String getPackageResourcePath() {
301 if (mPackageInfo != null) {
302 return mPackageInfo.getResDir();
303 }
304 throw new RuntimeException("Not supported in system context");
305 }
306
307 @Override
308 public String getPackageCodePath() {
309 if (mPackageInfo != null) {
310 return mPackageInfo.getAppDir();
311 }
312 throw new RuntimeException("Not supported in system context");
313 }
314
315 private static File makeBackupFile(File prefsFile) {
316 return new File(prefsFile.getPath() + ".bak");
317 }
318
Joe Onorato23ecae32009-06-10 17:07:15 -0700319 public File getSharedPrefsFile(String name) {
320 return makeFilename(getPreferencesDir(), name + ".xml");
321 }
322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 @Override
324 public SharedPreferences getSharedPreferences(String name, int mode) {
325 SharedPreferencesImpl sp;
Joe Onorato23ecae32009-06-10 17:07:15 -0700326 File f = getSharedPrefsFile(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 synchronized (sSharedPrefs) {
328 sp = sSharedPrefs.get(f);
329 if (sp != null && !sp.hasFileChanged()) {
330 //Log.i(TAG, "Returning existing prefs " + name + ": " + sp);
331 return sp;
332 }
333 }
334
335 FileInputStream str = null;
336 File backup = makeBackupFile(f);
337 if (backup.exists()) {
338 f.delete();
339 backup.renameTo(f);
340 }
341
342 // Debugging
343 if (f.exists() && !f.canRead()) {
344 Log.w(TAG, "Attempt to read preferences file " + f + " without permission");
345 }
346
347 Map map = null;
348 if (f.exists() && f.canRead()) {
349 try {
350 str = new FileInputStream(f);
351 map = XmlUtils.readMapXml(str);
352 str.close();
353 } catch (org.xmlpull.v1.XmlPullParserException e) {
354 Log.w(TAG, "getSharedPreferences", e);
355 } catch (FileNotFoundException e) {
356 Log.w(TAG, "getSharedPreferences", e);
357 } catch (IOException e) {
358 Log.w(TAG, "getSharedPreferences", e);
359 }
360 }
361
362 synchronized (sSharedPrefs) {
363 if (sp != null) {
364 //Log.i(TAG, "Updating existing prefs " + name + " " + sp + ": " + map);
365 sp.replace(map);
366 } else {
367 sp = sSharedPrefs.get(f);
368 if (sp == null) {
369 sp = new SharedPreferencesImpl(f, mode, map);
370 sSharedPrefs.put(f, sp);
371 }
372 }
373 return sp;
374 }
375 }
376
377 private File getPreferencesDir() {
378 synchronized (mSync) {
379 if (mPreferencesDir == null) {
380 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
381 }
382 return mPreferencesDir;
383 }
384 }
385
386 @Override
387 public FileInputStream openFileInput(String name)
388 throws FileNotFoundException {
389 File f = makeFilename(getFilesDir(), name);
390 return new FileInputStream(f);
391 }
392
393 @Override
394 public FileOutputStream openFileOutput(String name, int mode)
395 throws FileNotFoundException {
396 final boolean append = (mode&MODE_APPEND) != 0;
397 File f = makeFilename(getFilesDir(), name);
398 try {
399 FileOutputStream fos = new FileOutputStream(f, append);
400 setFilePermissionsFromMode(f.getPath(), mode, 0);
401 return fos;
402 } catch (FileNotFoundException e) {
403 }
404
405 File parent = f.getParentFile();
406 parent.mkdir();
407 FileUtils.setPermissions(
408 parent.getPath(),
409 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
410 -1, -1);
411 FileOutputStream fos = new FileOutputStream(f, append);
412 setFilePermissionsFromMode(f.getPath(), mode, 0);
413 return fos;
414 }
415
416 @Override
417 public boolean deleteFile(String name) {
418 File f = makeFilename(getFilesDir(), name);
419 return f.delete();
420 }
421
422 @Override
423 public File getFilesDir() {
424 synchronized (mSync) {
425 if (mFilesDir == null) {
426 mFilesDir = new File(getDataDirFile(), "files");
427 }
428 if (!mFilesDir.exists()) {
429 if(!mFilesDir.mkdirs()) {
430 Log.w(TAG, "Unable to create files directory");
431 return null;
432 }
433 FileUtils.setPermissions(
434 mFilesDir.getPath(),
435 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
436 -1, -1);
437 }
438 return mFilesDir;
439 }
440 }
441
442 @Override
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800443 public File getExternalFilesDir(String type) {
444 synchronized (mSync) {
445 if (mExternalFilesDir == null) {
446 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
447 getPackageName());
448 }
449 if (!mExternalFilesDir.exists()) {
450 try {
451 (new File(Environment.getExternalStorageAndroidDataDir(),
452 ".nomedia")).createNewFile();
453 } catch (IOException e) {
454 }
455 if (!mExternalFilesDir.mkdirs()) {
456 Log.w(TAG, "Unable to create external files directory");
457 return null;
458 }
459 }
460 if (type == null) {
461 return mExternalFilesDir;
462 }
463 File dir = new File(mExternalFilesDir, type);
464 if (!dir.exists()) {
465 if (!dir.mkdirs()) {
466 Log.w(TAG, "Unable to create external media directory " + dir);
467 return null;
468 }
469 }
470 return dir;
471 }
472 }
473
474 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800475 public File getCacheDir() {
476 synchronized (mSync) {
477 if (mCacheDir == null) {
478 mCacheDir = new File(getDataDirFile(), "cache");
479 }
480 if (!mCacheDir.exists()) {
481 if(!mCacheDir.mkdirs()) {
482 Log.w(TAG, "Unable to create cache directory");
483 return null;
484 }
485 FileUtils.setPermissions(
486 mCacheDir.getPath(),
487 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
488 -1, -1);
489 }
490 }
491 return mCacheDir;
492 }
493
Dianne Hackborne83cefce2010-02-04 17:38:14 -0800494 @Override
495 public File getExternalCacheDir() {
496 synchronized (mSync) {
497 if (mExternalCacheDir == null) {
498 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
499 getPackageName());
500 }
501 if (!mExternalCacheDir.exists()) {
502 try {
503 (new File(Environment.getExternalStorageAndroidDataDir(),
504 ".nomedia")).createNewFile();
505 } catch (IOException e) {
506 }
507 if (!mExternalCacheDir.mkdirs()) {
508 Log.w(TAG, "Unable to create external cache directory");
509 return null;
510 }
511 }
512 return mExternalCacheDir;
513 }
514 }
515
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800516 @Override
517 public File getFileStreamPath(String name) {
518 return makeFilename(getFilesDir(), name);
519 }
520
521 @Override
522 public String[] fileList() {
523 final String[] list = getFilesDir().list();
524 return (list != null) ? list : EMPTY_FILE_LIST;
525 }
526
527 @Override
528 public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800529 File f = validateFilePath(name, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
531 setFilePermissionsFromMode(f.getPath(), mode, 0);
532 return db;
533 }
534
535 @Override
536 public boolean deleteDatabase(String name) {
537 try {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800538 File f = validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800539 return f.delete();
540 } catch (Exception e) {
541 }
542 return false;
543 }
544
545 @Override
546 public File getDatabasePath(String name) {
Oscar Montemayora8529f62009-11-18 10:14:20 -0800547 return validateFilePath(name, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 }
549
550 @Override
551 public String[] databaseList() {
552 final String[] list = getDatabasesDir().list();
553 return (list != null) ? list : EMPTY_FILE_LIST;
554 }
555
556
557 private File getDatabasesDir() {
558 synchronized (mSync) {
559 if (mDatabasesDir == null) {
560 mDatabasesDir = new File(getDataDirFile(), "databases");
561 }
562 if (mDatabasesDir.getPath().equals("databases")) {
563 mDatabasesDir = new File("/data/system");
564 }
565 return mDatabasesDir;
566 }
567 }
568
569 @Override
570 public Drawable getWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700571 return getWallpaperManager().getDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800572 }
573
574 @Override
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700575 public Drawable peekWallpaper() {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700576 return getWallpaperManager().peekDrawable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577 }
578
579 @Override
580 public int getWallpaperDesiredMinimumWidth() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700581 return getWallpaperManager().getDesiredMinimumWidth();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 }
583
584 @Override
585 public int getWallpaperDesiredMinimumHeight() {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700586 return getWallpaperManager().getDesiredMinimumHeight();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
588
589 @Override
590 public void setWallpaper(Bitmap bitmap) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700591 getWallpaperManager().setBitmap(bitmap);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 }
593
594 @Override
595 public void setWallpaper(InputStream data) throws IOException {
Dianne Hackborn4c62fc02009-08-08 20:40:27 -0700596 getWallpaperManager().setStream(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800597 }
598
599 @Override
600 public void clearWallpaper() throws IOException {
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700601 getWallpaperManager().clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 }
603
604 @Override
605 public void startActivity(Intent intent) {
606 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
607 throw new AndroidRuntimeException(
608 "Calling startActivity() from outside of an Activity "
609 + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
610 + " Is this really what you want?");
611 }
612 mMainThread.getInstrumentation().execStartActivity(
613 getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
614 }
615
616 @Override
Dianne Hackbornfa82f222009-09-17 15:14:12 -0700617 public void startIntentSender(IntentSender intent,
618 Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
619 throws IntentSender.SendIntentException {
620 try {
621 String resolvedType = null;
622 if (fillInIntent != null) {
623 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
624 }
625 int result = ActivityManagerNative.getDefault()
626 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
627 fillInIntent, resolvedType, null, null,
628 0, flagsMask, flagsValues);
629 if (result == IActivityManager.START_CANCELED) {
630 throw new IntentSender.SendIntentException();
631 }
632 Instrumentation.checkStartActivityResult(result, null);
633 } catch (RemoteException e) {
634 }
635 }
636
637 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800638 public void sendBroadcast(Intent intent) {
639 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
640 try {
641 ActivityManagerNative.getDefault().broadcastIntent(
642 mMainThread.getApplicationThread(), intent, resolvedType, null,
643 Activity.RESULT_OK, null, null, null, false, false);
644 } catch (RemoteException e) {
645 }
646 }
647
648 @Override
649 public void sendBroadcast(Intent intent, String receiverPermission) {
650 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
651 try {
652 ActivityManagerNative.getDefault().broadcastIntent(
653 mMainThread.getApplicationThread(), intent, resolvedType, null,
654 Activity.RESULT_OK, null, null, receiverPermission, false, false);
655 } catch (RemoteException e) {
656 }
657 }
658
659 @Override
660 public void sendOrderedBroadcast(Intent intent,
661 String receiverPermission) {
662 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
663 try {
664 ActivityManagerNative.getDefault().broadcastIntent(
665 mMainThread.getApplicationThread(), intent, resolvedType, null,
666 Activity.RESULT_OK, null, null, receiverPermission, true, false);
667 } catch (RemoteException e) {
668 }
669 }
670
671 @Override
672 public void sendOrderedBroadcast(Intent intent,
673 String receiverPermission, BroadcastReceiver resultReceiver,
674 Handler scheduler, int initialCode, String initialData,
675 Bundle initialExtras) {
676 IIntentReceiver rd = null;
677 if (resultReceiver != null) {
678 if (mPackageInfo != null) {
679 if (scheduler == null) {
680 scheduler = mMainThread.getHandler();
681 }
682 rd = mPackageInfo.getReceiverDispatcher(
683 resultReceiver, getOuterContext(), scheduler,
684 mMainThread.getInstrumentation(), false);
685 } else {
686 if (scheduler == null) {
687 scheduler = mMainThread.getHandler();
688 }
689 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
690 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
691 }
692 }
693 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
694 try {
695 ActivityManagerNative.getDefault().broadcastIntent(
696 mMainThread.getApplicationThread(), intent, resolvedType, rd,
697 initialCode, initialData, initialExtras, receiverPermission,
698 true, false);
699 } catch (RemoteException e) {
700 }
701 }
702
703 @Override
704 public void sendStickyBroadcast(Intent intent) {
705 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
706 try {
707 ActivityManagerNative.getDefault().broadcastIntent(
708 mMainThread.getApplicationThread(), intent, resolvedType, null,
709 Activity.RESULT_OK, null, null, null, false, true);
710 } catch (RemoteException e) {
711 }
712 }
713
714 @Override
Dianne Hackbornefa199f2009-09-19 12:03:15 -0700715 public void sendStickyOrderedBroadcast(Intent intent,
716 BroadcastReceiver resultReceiver,
717 Handler scheduler, int initialCode, String initialData,
718 Bundle initialExtras) {
719 IIntentReceiver rd = null;
720 if (resultReceiver != null) {
721 if (mPackageInfo != null) {
722 if (scheduler == null) {
723 scheduler = mMainThread.getHandler();
724 }
725 rd = mPackageInfo.getReceiverDispatcher(
726 resultReceiver, getOuterContext(), scheduler,
727 mMainThread.getInstrumentation(), false);
728 } else {
729 if (scheduler == null) {
730 scheduler = mMainThread.getHandler();
731 }
732 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
733 resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
734 }
735 }
736 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
737 try {
738 ActivityManagerNative.getDefault().broadcastIntent(
739 mMainThread.getApplicationThread(), intent, resolvedType, rd,
740 initialCode, initialData, initialExtras, null,
741 true, true);
742 } catch (RemoteException e) {
743 }
744 }
745
746 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747 public void removeStickyBroadcast(Intent intent) {
748 String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
749 if (resolvedType != null) {
750 intent = new Intent(intent);
751 intent.setDataAndType(intent.getData(), resolvedType);
752 }
753 try {
754 ActivityManagerNative.getDefault().unbroadcastIntent(
755 mMainThread.getApplicationThread(), intent);
756 } catch (RemoteException e) {
757 }
758 }
759
760 @Override
761 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
762 return registerReceiver(receiver, filter, null, null);
763 }
764
765 @Override
766 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
767 String broadcastPermission, Handler scheduler) {
768 return registerReceiverInternal(receiver, filter, broadcastPermission,
769 scheduler, getOuterContext());
770 }
771
772 private Intent registerReceiverInternal(BroadcastReceiver receiver,
773 IntentFilter filter, String broadcastPermission,
774 Handler scheduler, Context context) {
775 IIntentReceiver rd = null;
776 if (receiver != null) {
777 if (mPackageInfo != null && context != null) {
778 if (scheduler == null) {
779 scheduler = mMainThread.getHandler();
780 }
781 rd = mPackageInfo.getReceiverDispatcher(
782 receiver, context, scheduler,
783 mMainThread.getInstrumentation(), true);
784 } else {
785 if (scheduler == null) {
786 scheduler = mMainThread.getHandler();
787 }
788 rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
789 receiver, context, scheduler, null, false).getIIntentReceiver();
790 }
791 }
792 try {
793 return ActivityManagerNative.getDefault().registerReceiver(
794 mMainThread.getApplicationThread(),
795 rd, filter, broadcastPermission);
796 } catch (RemoteException e) {
797 return null;
798 }
799 }
800
801 @Override
802 public void unregisterReceiver(BroadcastReceiver receiver) {
803 if (mPackageInfo != null) {
804 IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
805 getOuterContext(), receiver);
806 try {
807 ActivityManagerNative.getDefault().unregisterReceiver(rd);
808 } catch (RemoteException e) {
809 }
810 } else {
811 throw new RuntimeException("Not supported in system context");
812 }
813 }
814
815 @Override
816 public ComponentName startService(Intent service) {
817 try {
818 ComponentName cn = ActivityManagerNative.getDefault().startService(
819 mMainThread.getApplicationThread(), service,
820 service.resolveTypeIfNeeded(getContentResolver()));
821 if (cn != null && cn.getPackageName().equals("!")) {
822 throw new SecurityException(
823 "Not allowed to start service " + service
824 + " without permission " + cn.getClassName());
825 }
826 return cn;
827 } catch (RemoteException e) {
828 return null;
829 }
830 }
831
832 @Override
833 public boolean stopService(Intent service) {
834 try {
835 int res = ActivityManagerNative.getDefault().stopService(
836 mMainThread.getApplicationThread(), service,
837 service.resolveTypeIfNeeded(getContentResolver()));
838 if (res < 0) {
839 throw new SecurityException(
840 "Not allowed to stop service " + service);
841 }
842 return res != 0;
843 } catch (RemoteException e) {
844 return false;
845 }
846 }
847
848 @Override
849 public boolean bindService(Intent service, ServiceConnection conn,
850 int flags) {
851 IServiceConnection sd;
852 if (mPackageInfo != null) {
853 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
854 mMainThread.getHandler(), flags);
855 } else {
856 throw new RuntimeException("Not supported in system context");
857 }
858 try {
859 int res = ActivityManagerNative.getDefault().bindService(
860 mMainThread.getApplicationThread(), getActivityToken(),
861 service, service.resolveTypeIfNeeded(getContentResolver()),
862 sd, flags);
863 if (res < 0) {
864 throw new SecurityException(
865 "Not allowed to bind to service " + service);
866 }
867 return res != 0;
868 } catch (RemoteException e) {
869 return false;
870 }
871 }
872
873 @Override
874 public void unbindService(ServiceConnection conn) {
875 if (mPackageInfo != null) {
876 IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
877 getOuterContext(), conn);
878 try {
879 ActivityManagerNative.getDefault().unbindService(sd);
880 } catch (RemoteException e) {
881 }
882 } else {
883 throw new RuntimeException("Not supported in system context");
884 }
885 }
886
887 @Override
888 public boolean startInstrumentation(ComponentName className,
889 String profileFile, Bundle arguments) {
890 try {
891 return ActivityManagerNative.getDefault().startInstrumentation(
892 className, profileFile, 0, arguments, null);
893 } catch (RemoteException e) {
894 // System has crashed, nothing we can do.
895 }
896 return false;
897 }
898
899 @Override
900 public Object getSystemService(String name) {
901 if (WINDOW_SERVICE.equals(name)) {
902 return WindowManagerImpl.getDefault();
903 } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
904 synchronized (mSync) {
905 LayoutInflater inflater = mLayoutInflater;
906 if (inflater != null) {
907 return inflater;
908 }
909 mLayoutInflater = inflater =
910 PolicyManager.makeNewLayoutInflater(getOuterContext());
911 return inflater;
912 }
913 } else if (ACTIVITY_SERVICE.equals(name)) {
914 return getActivityManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700915 } else if (INPUT_METHOD_SERVICE.equals(name)) {
916 return InputMethodManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 } else if (ALARM_SERVICE.equals(name)) {
918 return getAlarmManager();
Fred Quintana60307342009-03-24 22:48:12 -0700919 } else if (ACCOUNT_SERVICE.equals(name)) {
920 return getAccountManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 } else if (POWER_SERVICE.equals(name)) {
922 return getPowerManager();
923 } else if (CONNECTIVITY_SERVICE.equals(name)) {
924 return getConnectivityManager();
925 } else if (WIFI_SERVICE.equals(name)) {
926 return getWifiManager();
927 } else if (NOTIFICATION_SERVICE.equals(name)) {
928 return getNotificationManager();
929 } else if (KEYGUARD_SERVICE.equals(name)) {
930 return new KeyguardManager();
svetoslavganov75986cf2009-05-14 22:28:01 -0700931 } else if (ACCESSIBILITY_SERVICE.equals(name)) {
932 return AccessibilityManager.getInstance(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 } else if (LOCATION_SERVICE.equals(name)) {
934 return getLocationManager();
935 } else if (SEARCH_SERVICE.equals(name)) {
936 return getSearchManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700937 } else if (SENSOR_SERVICE.equals(name)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 return getSensorManager();
San Mehatc9d81752010-02-01 10:23:27 -0800939 } else if (STORAGE_SERVICE.equals(name)) {
940 return getStorageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800941 } else if (VIBRATOR_SERVICE.equals(name)) {
942 return getVibrator();
943 } else if (STATUS_BAR_SERVICE.equals(name)) {
944 synchronized (mSync) {
945 if (mStatusBarManager == null) {
946 mStatusBarManager = new StatusBarManager(getOuterContext());
947 }
948 return mStatusBarManager;
949 }
950 } else if (AUDIO_SERVICE.equals(name)) {
951 return getAudioManager();
952 } else if (TELEPHONY_SERVICE.equals(name)) {
953 return getTelephonyManager();
954 } else if (CLIPBOARD_SERVICE.equals(name)) {
955 return getClipboardManager();
Dianne Hackborn8cc6a502009-08-05 21:29:42 -0700956 } else if (WALLPAPER_SERVICE.equals(name)) {
957 return getWallpaperManager();
Dan Egnor95240272009-10-27 18:23:39 -0700958 } else if (DROPBOX_SERVICE.equals(name)) {
Dan Egnorf18a01c2009-11-12 11:32:50 -0800959 return getDropBoxManager();
Dianne Hackbornd6847842010-01-12 18:14:19 -0800960 } else if (DEVICE_POLICY_SERVICE.equals(name)) {
961 return getDevicePolicyManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 }
963
964 return null;
965 }
966
Fred Quintana60307342009-03-24 22:48:12 -0700967 private AccountManager getAccountManager() {
Fred Quintanae00a3112009-09-22 15:13:30 -0700968 synchronized (mSync) {
969 if (mAccountManager == null) {
Fred Quintana60307342009-03-24 22:48:12 -0700970 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
971 IAccountManager service = IAccountManager.Stub.asInterface(b);
Fred Quintanae00a3112009-09-22 15:13:30 -0700972 mAccountManager = new AccountManager(this, service);
Fred Quintana60307342009-03-24 22:48:12 -0700973 }
Fred Quintanae00a3112009-09-22 15:13:30 -0700974 return mAccountManager;
Fred Quintana60307342009-03-24 22:48:12 -0700975 }
Fred Quintana60307342009-03-24 22:48:12 -0700976 }
977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 private ActivityManager getActivityManager() {
979 synchronized (mSync) {
980 if (mActivityManager == null) {
981 mActivityManager = new ActivityManager(getOuterContext(),
982 mMainThread.getHandler());
983 }
984 }
985 return mActivityManager;
986 }
987
988 private AlarmManager getAlarmManager() {
989 synchronized (sSync) {
990 if (sAlarmManager == null) {
991 IBinder b = ServiceManager.getService(ALARM_SERVICE);
992 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
993 sAlarmManager = new AlarmManager(service);
994 }
995 }
996 return sAlarmManager;
997 }
998
999 private PowerManager getPowerManager() {
1000 synchronized (sSync) {
1001 if (sPowerManager == null) {
1002 IBinder b = ServiceManager.getService(POWER_SERVICE);
1003 IPowerManager service = IPowerManager.Stub.asInterface(b);
1004 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1005 }
1006 }
1007 return sPowerManager;
1008 }
1009
1010 private ConnectivityManager getConnectivityManager()
1011 {
1012 synchronized (sSync) {
1013 if (sConnectivityManager == null) {
1014 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1015 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1016 sConnectivityManager = new ConnectivityManager(service);
1017 }
1018 }
1019 return sConnectivityManager;
1020 }
1021
1022 private WifiManager getWifiManager()
1023 {
1024 synchronized (sSync) {
1025 if (sWifiManager == null) {
1026 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1027 IWifiManager service = IWifiManager.Stub.asInterface(b);
1028 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1029 }
1030 }
1031 return sWifiManager;
1032 }
1033
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001034 private NotificationManager getNotificationManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 synchronized (mSync) {
1036 if (mNotificationManager == null) {
1037 mNotificationManager = new NotificationManager(
1038 new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1039 mMainThread.getHandler());
1040 }
1041 }
1042 return mNotificationManager;
1043 }
1044
Dianne Hackborn8cc6a502009-08-05 21:29:42 -07001045 private WallpaperManager getWallpaperManager() {
1046 synchronized (mSync) {
1047 if (mWallpaperManager == null) {
1048 mWallpaperManager = new WallpaperManager(getOuterContext(),
1049 mMainThread.getHandler());
1050 }
1051 }
1052 return mWallpaperManager;
1053 }
1054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 private TelephonyManager getTelephonyManager() {
1056 synchronized (mSync) {
1057 if (mTelephonyManager == null) {
1058 mTelephonyManager = new TelephonyManager(getOuterContext());
1059 }
1060 }
1061 return mTelephonyManager;
1062 }
1063
1064 private ClipboardManager getClipboardManager() {
1065 synchronized (mSync) {
1066 if (mClipboardManager == null) {
1067 mClipboardManager = new ClipboardManager(getOuterContext(),
1068 mMainThread.getHandler());
1069 }
1070 }
1071 return mClipboardManager;
1072 }
1073
1074 private LocationManager getLocationManager() {
1075 synchronized (sSync) {
1076 if (sLocationManager == null) {
1077 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1078 ILocationManager service = ILocationManager.Stub.asInterface(b);
1079 sLocationManager = new LocationManager(service);
1080 }
1081 }
1082 return sLocationManager;
1083 }
1084
1085 private SearchManager getSearchManager() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001086 synchronized (mSync) {
1087 if (mSearchManager == null) {
1088 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1089 }
1090 }
1091 return mSearchManager;
1092 }
1093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 private SensorManager getSensorManager() {
1095 synchronized (mSync) {
1096 if (mSensorManager == null) {
1097 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1098 }
1099 }
1100 return mSensorManager;
1101 }
1102
San Mehatc9d81752010-02-01 10:23:27 -08001103 private StorageManager getStorageManager() {
1104 synchronized (mSync) {
1105 if (mStorageManager == null) {
1106 try {
1107 mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1108 } catch (RemoteException rex) {
1109 Log.e(TAG, "Failed to create StorageManager", rex);
1110 mStorageManager = null;
1111 }
1112 }
1113 }
1114 return mStorageManager;
1115 }
1116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 private Vibrator getVibrator() {
1118 synchronized (mSync) {
1119 if (mVibrator == null) {
1120 mVibrator = new Vibrator();
1121 }
1122 }
1123 return mVibrator;
1124 }
Dan Egnor95240272009-10-27 18:23:39 -07001125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 private AudioManager getAudioManager()
1127 {
1128 if (mAudioManager == null) {
1129 mAudioManager = new AudioManager(this);
1130 }
1131 return mAudioManager;
1132 }
1133
Dan Egnorf18a01c2009-11-12 11:32:50 -08001134 private DropBoxManager getDropBoxManager() {
Dan Egnor95240272009-10-27 18:23:39 -07001135 synchronized (mSync) {
Dan Egnorf18a01c2009-11-12 11:32:50 -08001136 if (mDropBoxManager == null) {
Dan Egnor95240272009-10-27 18:23:39 -07001137 IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
Dan Egnorf18a01c2009-11-12 11:32:50 -08001138 IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1139 mDropBoxManager = new DropBoxManager(service);
Dan Egnor95240272009-10-27 18:23:39 -07001140 }
1141 }
Dan Egnorf18a01c2009-11-12 11:32:50 -08001142 return mDropBoxManager;
Dan Egnor95240272009-10-27 18:23:39 -07001143 }
1144
Dianne Hackbornd6847842010-01-12 18:14:19 -08001145 private DevicePolicyManager getDevicePolicyManager() {
1146 synchronized (mSync) {
1147 if (mDevicePolicyManager == null) {
1148 mDevicePolicyManager = new DevicePolicyManager(this,
1149 mMainThread.getHandler());
1150 }
1151 }
1152 return mDevicePolicyManager;
1153 }
1154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001155 @Override
1156 public int checkPermission(String permission, int pid, int uid) {
1157 if (permission == null) {
1158 throw new IllegalArgumentException("permission is null");
1159 }
1160
1161 if (!Process.supportsProcesses()) {
1162 return PackageManager.PERMISSION_GRANTED;
1163 }
1164 try {
1165 return ActivityManagerNative.getDefault().checkPermission(
1166 permission, pid, uid);
1167 } catch (RemoteException e) {
1168 return PackageManager.PERMISSION_DENIED;
1169 }
1170 }
1171
1172 @Override
1173 public int checkCallingPermission(String permission) {
1174 if (permission == null) {
1175 throw new IllegalArgumentException("permission is null");
1176 }
1177
1178 if (!Process.supportsProcesses()) {
1179 return PackageManager.PERMISSION_GRANTED;
1180 }
1181 int pid = Binder.getCallingPid();
1182 if (pid != Process.myPid()) {
1183 return checkPermission(permission, pid,
1184 Binder.getCallingUid());
1185 }
1186 return PackageManager.PERMISSION_DENIED;
1187 }
1188
1189 @Override
1190 public int checkCallingOrSelfPermission(String permission) {
1191 if (permission == null) {
1192 throw new IllegalArgumentException("permission is null");
1193 }
1194
1195 return checkPermission(permission, Binder.getCallingPid(),
1196 Binder.getCallingUid());
1197 }
1198
1199 private void enforce(
1200 String permission, int resultOfCheck,
1201 boolean selfToo, int uid, String message) {
1202 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1203 throw new SecurityException(
1204 (message != null ? (message + ": ") : "") +
1205 (selfToo
1206 ? "Neither user " + uid + " nor current process has "
1207 : "User " + uid + " does not have ") +
1208 permission +
1209 ".");
1210 }
1211 }
1212
1213 public void enforcePermission(
1214 String permission, int pid, int uid, String message) {
1215 enforce(permission,
1216 checkPermission(permission, pid, uid),
1217 false,
1218 uid,
1219 message);
1220 }
1221
1222 public void enforceCallingPermission(String permission, String message) {
1223 enforce(permission,
1224 checkCallingPermission(permission),
1225 false,
1226 Binder.getCallingUid(),
1227 message);
1228 }
1229
1230 public void enforceCallingOrSelfPermission(
1231 String permission, String message) {
1232 enforce(permission,
1233 checkCallingOrSelfPermission(permission),
1234 true,
1235 Binder.getCallingUid(),
1236 message);
1237 }
1238
1239 @Override
1240 public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1241 try {
1242 ActivityManagerNative.getDefault().grantUriPermission(
1243 mMainThread.getApplicationThread(), toPackage, uri,
1244 modeFlags);
1245 } catch (RemoteException e) {
1246 }
1247 }
1248
1249 @Override
1250 public void revokeUriPermission(Uri uri, int modeFlags) {
1251 try {
1252 ActivityManagerNative.getDefault().revokeUriPermission(
1253 mMainThread.getApplicationThread(), uri,
1254 modeFlags);
1255 } catch (RemoteException e) {
1256 }
1257 }
1258
1259 @Override
1260 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1261 if (!Process.supportsProcesses()) {
1262 return PackageManager.PERMISSION_GRANTED;
1263 }
1264 try {
1265 return ActivityManagerNative.getDefault().checkUriPermission(
1266 uri, pid, uid, modeFlags);
1267 } catch (RemoteException e) {
1268 return PackageManager.PERMISSION_DENIED;
1269 }
1270 }
1271
1272 @Override
1273 public int checkCallingUriPermission(Uri uri, int modeFlags) {
1274 if (!Process.supportsProcesses()) {
1275 return PackageManager.PERMISSION_GRANTED;
1276 }
1277 int pid = Binder.getCallingPid();
1278 if (pid != Process.myPid()) {
1279 return checkUriPermission(uri, pid,
1280 Binder.getCallingUid(), modeFlags);
1281 }
1282 return PackageManager.PERMISSION_DENIED;
1283 }
1284
1285 @Override
1286 public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1287 return checkUriPermission(uri, Binder.getCallingPid(),
1288 Binder.getCallingUid(), modeFlags);
1289 }
1290
1291 @Override
1292 public int checkUriPermission(Uri uri, String readPermission,
1293 String writePermission, int pid, int uid, int modeFlags) {
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001294 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1296 + readPermission + " writePermission=" + writePermission
1297 + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1298 }
1299 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1300 if (readPermission == null
1301 || checkPermission(readPermission, pid, uid)
1302 == PackageManager.PERMISSION_GRANTED) {
1303 return PackageManager.PERMISSION_GRANTED;
1304 }
1305 }
1306 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1307 if (writePermission == null
1308 || checkPermission(writePermission, pid, uid)
1309 == PackageManager.PERMISSION_GRANTED) {
1310 return PackageManager.PERMISSION_GRANTED;
1311 }
1312 }
1313 return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1314 : PackageManager.PERMISSION_DENIED;
1315 }
1316
1317 private String uriModeFlagToString(int uriModeFlags) {
1318 switch (uriModeFlags) {
1319 case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1320 Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1321 return "read and write";
1322 case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1323 return "read";
1324 case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1325 return "write";
1326 }
1327 throw new IllegalArgumentException(
1328 "Unknown permission mode flags: " + uriModeFlags);
1329 }
1330
1331 private void enforceForUri(
1332 int modeFlags, int resultOfCheck, boolean selfToo,
1333 int uid, Uri uri, String message) {
1334 if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1335 throw new SecurityException(
1336 (message != null ? (message + ": ") : "") +
1337 (selfToo
1338 ? "Neither user " + uid + " nor current process has "
1339 : "User " + uid + " does not have ") +
1340 uriModeFlagToString(modeFlags) +
1341 " permission on " +
1342 uri +
1343 ".");
1344 }
1345 }
1346
1347 public void enforceUriPermission(
1348 Uri uri, int pid, int uid, int modeFlags, String message) {
1349 enforceForUri(
1350 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1351 false, uid, uri, message);
1352 }
1353
1354 public void enforceCallingUriPermission(
1355 Uri uri, int modeFlags, String message) {
1356 enforceForUri(
1357 modeFlags, checkCallingUriPermission(uri, modeFlags),
1358 false, Binder.getCallingUid(), uri, message);
1359 }
1360
1361 public void enforceCallingOrSelfUriPermission(
1362 Uri uri, int modeFlags, String message) {
1363 enforceForUri(
1364 modeFlags,
1365 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1366 Binder.getCallingUid(), uri, message);
1367 }
1368
1369 public void enforceUriPermission(
1370 Uri uri, String readPermission, String writePermission,
1371 int pid, int uid, int modeFlags, String message) {
1372 enforceForUri(modeFlags,
1373 checkUriPermission(
1374 uri, readPermission, writePermission, pid, uid,
1375 modeFlags),
1376 false,
1377 uid,
1378 uri,
1379 message);
1380 }
1381
1382 @Override
1383 public Context createPackageContext(String packageName, int flags)
1384 throws PackageManager.NameNotFoundException {
1385 if (packageName.equals("system") || packageName.equals("android")) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001386 return new ContextImpl(mMainThread.getSystemContext());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 }
1388
1389 ActivityThread.PackageInfo pi =
1390 mMainThread.getPackageInfo(packageName, flags);
1391 if (pi != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001392 ContextImpl c = new ContextImpl();
Romain Guy870e09f2009-07-06 16:35:25 -07001393 c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001394 c.init(pi, null, mMainThread, mResources);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 if (c.mResources != null) {
1396 return c;
1397 }
1398 }
1399
1400 // Should be a better exception.
1401 throw new PackageManager.NameNotFoundException(
1402 "Application package " + packageName + " not found");
1403 }
1404
Romain Guy870e09f2009-07-06 16:35:25 -07001405 @Override
1406 public boolean isRestricted() {
1407 return mRestricted;
1408 }
1409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 private File getDataDirFile() {
1411 if (mPackageInfo != null) {
1412 return mPackageInfo.getDataDirFile();
1413 }
1414 throw new RuntimeException("Not supported in system context");
1415 }
1416
1417 @Override
1418 public File getDir(String name, int mode) {
1419 name = "app_" + name;
1420 File file = makeFilename(getDataDirFile(), name);
1421 if (!file.exists()) {
1422 file.mkdir();
1423 setFilePermissionsFromMode(file.getPath(), mode,
1424 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1425 }
1426 return file;
1427 }
1428
Dianne Hackborn21556372010-02-04 16:34:40 -08001429 static ContextImpl createSystemContext(ActivityThread mainThread) {
1430 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 context.init(Resources.getSystem(), mainThread);
1432 return context;
1433 }
1434
Dianne Hackborn21556372010-02-04 16:34:40 -08001435 ContextImpl() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 ++sInstanceCount;
1437 mOuterContext = this;
1438 }
1439
1440 /**
1441 * Create a new ApplicationContext from an existing one. The new one
1442 * works and operates the same as the one it is copying.
1443 *
1444 * @param context Existing application context.
1445 */
Dianne Hackborn21556372010-02-04 16:34:40 -08001446 public ContextImpl(ContextImpl context) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 ++sInstanceCount;
1448 mPackageInfo = context.mPackageInfo;
1449 mResources = context.mResources;
1450 mMainThread = context.mMainThread;
1451 mContentResolver = context.mContentResolver;
1452 mOuterContext = this;
1453 }
1454
1455 final void init(ActivityThread.PackageInfo packageInfo,
1456 IBinder activityToken, ActivityThread mainThread) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001457 init(packageInfo, activityToken, mainThread, null);
1458 }
1459
1460 final void init(ActivityThread.PackageInfo packageInfo,
1461 IBinder activityToken, ActivityThread mainThread,
1462 Resources container) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001463 mPackageInfo = packageInfo;
1464 mResources = mPackageInfo.getResources(mainThread);
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001465
1466 if (container != null && container.getCompatibilityInfo().applicationScale !=
1467 mResources.getCompatibilityInfo().applicationScale) {
1468 if (DEBUG) {
1469 Log.d(TAG, "loaded context has different scaling. Using container's" +
1470 " compatiblity info:" + container.getDisplayMetrics());
1471 }
1472 mResources = mainThread.getTopLevelResources(
1473 mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 mMainThread = mainThread;
1476 mContentResolver = new ApplicationContentResolver(this, mainThread);
1477
1478 setActivityToken(activityToken);
1479 }
1480
1481 final void init(Resources resources, ActivityThread mainThread) {
1482 mPackageInfo = null;
1483 mResources = resources;
1484 mMainThread = mainThread;
1485 mContentResolver = new ApplicationContentResolver(this, mainThread);
1486 }
1487
1488 final void scheduleFinalCleanup(String who, String what) {
1489 mMainThread.scheduleContextCleanup(this, who, what);
1490 }
1491
1492 final void performFinalCleanup(String who, String what) {
1493 //Log.i(TAG, "Cleanup up context: " + this);
1494 mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1495 }
1496
1497 final Context getReceiverRestrictedContext() {
1498 if (mReceiverRestrictedContext != null) {
1499 return mReceiverRestrictedContext;
1500 }
1501 return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1502 }
1503
1504 final void setActivityToken(IBinder token) {
1505 mActivityToken = token;
1506 }
1507
1508 final void setOuterContext(Context context) {
1509 mOuterContext = context;
1510 }
1511
1512 final Context getOuterContext() {
1513 return mOuterContext;
1514 }
1515
1516 final IBinder getActivityToken() {
1517 return mActivityToken;
1518 }
1519
1520 private static void setFilePermissionsFromMode(String name, int mode,
1521 int extraPermissions) {
1522 int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1523 |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1524 |extraPermissions;
1525 if ((mode&MODE_WORLD_READABLE) != 0) {
1526 perms |= FileUtils.S_IROTH;
1527 }
1528 if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1529 perms |= FileUtils.S_IWOTH;
1530 }
Mitsuru Oshima569076c2009-07-02 20:06:08 -07001531 if (DEBUG) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001532 Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1533 + ", perms=0x" + Integer.toHexString(perms));
1534 }
1535 FileUtils.setPermissions(name, perms, -1, -1);
1536 }
1537
Oscar Montemayora8529f62009-11-18 10:14:20 -08001538 private File validateFilePath(String name, boolean createDirectory) {
1539 File dir;
1540 File f;
1541
1542 if (name.charAt(0) == File.separatorChar) {
1543 String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1544 dir = new File(dirPath);
1545 name = name.substring(name.lastIndexOf(File.separatorChar));
1546 f = new File(dir, name);
1547 } else {
1548 dir = getDatabasesDir();
1549 f = makeFilename(dir, name);
1550 }
1551
1552 if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1553 FileUtils.setPermissions(dir.getPath(),
1554 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1555 -1, -1);
1556 }
1557
1558 return f;
1559 }
1560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561 private File makeFilename(File base, String name) {
1562 if (name.indexOf(File.separatorChar) < 0) {
1563 return new File(base, name);
1564 }
1565 throw new IllegalArgumentException(
Oscar Montemayora8529f62009-11-18 10:14:20 -08001566 "File " + name + " contains a path separator");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 }
1568
1569 // ----------------------------------------------------------------------
1570 // ----------------------------------------------------------------------
1571 // ----------------------------------------------------------------------
1572
1573 private static final class ApplicationContentResolver extends ContentResolver {
1574 public ApplicationContentResolver(Context context,
1575 ActivityThread mainThread)
1576 {
1577 super(context);
1578 mMainThread = mainThread;
1579 }
1580
1581 @Override
1582 protected IContentProvider acquireProvider(Context context, String name)
1583 {
1584 return mMainThread.acquireProvider(context, name);
1585 }
1586
1587 @Override
1588 public boolean releaseProvider(IContentProvider provider)
1589 {
1590 return mMainThread.releaseProvider(provider);
1591 }
1592
1593 private final ActivityThread mMainThread;
1594 }
1595
1596 // ----------------------------------------------------------------------
1597 // ----------------------------------------------------------------------
1598 // ----------------------------------------------------------------------
1599
1600 /*package*/
1601 static final class ApplicationPackageManager extends PackageManager {
1602 @Override
1603 public PackageInfo getPackageInfo(String packageName, int flags)
1604 throws NameNotFoundException {
1605 try {
1606 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1607 if (pi != null) {
1608 return pi;
1609 }
1610 } catch (RemoteException e) {
1611 throw new RuntimeException("Package manager has died", e);
1612 }
1613
1614 throw new NameNotFoundException(packageName);
1615 }
1616
Mihai Predaeae850c2009-05-13 10:13:48 +02001617 @Override
Dianne Hackborn47096932010-02-11 15:57:09 -08001618 public String[] currentToCanonicalPackageNames(String[] names) {
1619 try {
1620 return mPM.currentToCanonicalPackageNames(names);
1621 } catch (RemoteException e) {
1622 throw new RuntimeException("Package manager has died", e);
1623 }
1624 }
1625
1626 @Override
1627 public String[] canonicalToCurrentPackageNames(String[] names) {
1628 try {
1629 return mPM.canonicalToCurrentPackageNames(names);
1630 } catch (RemoteException e) {
1631 throw new RuntimeException("Package manager has died", e);
1632 }
1633 }
1634
1635 @Override
Mihai Predaeae850c2009-05-13 10:13:48 +02001636 public Intent getLaunchIntentForPackage(String packageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 // First see if the package has an INFO activity; the existence of
1638 // such an activity is implied to be the desired front-door for the
1639 // overall package (such as if it has multiple launcher entries).
Mihai Predaeae850c2009-05-13 10:13:48 +02001640 Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1641 intentToResolve.addCategory(Intent.CATEGORY_INFO);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001642 intentToResolve.setPackage(packageName);
1643 ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
Mihai Predaeae850c2009-05-13 10:13:48 +02001644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 // Otherwise, try to find a main launcher activity.
Mihai Predaeae850c2009-05-13 10:13:48 +02001646 if (resolveInfo == null) {
1647 // reuse the intent instance
1648 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1649 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
Dianne Hackbornc14b9cc2009-06-17 18:02:12 -07001650 intentToResolve.setPackage(packageName);
1651 resolveInfo = resolveActivity(intentToResolve, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001652 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001653 if (resolveInfo == null) {
1654 return null;
1655 }
1656 Intent intent = new Intent(Intent.ACTION_MAIN);
1657 intent.setClassName(packageName, resolveInfo.activityInfo.name);
1658 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1659 return intent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 }
Mihai Predaeae850c2009-05-13 10:13:48 +02001661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 @Override
1663 public int[] getPackageGids(String packageName)
1664 throws NameNotFoundException {
1665 try {
1666 int[] gids = mPM.getPackageGids(packageName);
1667 if (gids == null || gids.length > 0) {
1668 return gids;
1669 }
1670 } catch (RemoteException e) {
1671 throw new RuntimeException("Package manager has died", e);
1672 }
1673
1674 throw new NameNotFoundException(packageName);
1675 }
1676
1677 @Override
1678 public PermissionInfo getPermissionInfo(String name, int flags)
1679 throws NameNotFoundException {
1680 try {
1681 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1682 if (pi != null) {
1683 return pi;
1684 }
1685 } catch (RemoteException e) {
1686 throw new RuntimeException("Package manager has died", e);
1687 }
1688
1689 throw new NameNotFoundException(name);
1690 }
1691
1692 @Override
1693 public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1694 throws NameNotFoundException {
1695 try {
1696 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1697 if (pi != null) {
1698 return pi;
1699 }
1700 } catch (RemoteException e) {
1701 throw new RuntimeException("Package manager has died", e);
1702 }
1703
1704 throw new NameNotFoundException(group);
1705 }
1706
1707 @Override
1708 public PermissionGroupInfo getPermissionGroupInfo(String name,
1709 int flags) throws NameNotFoundException {
1710 try {
1711 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1712 if (pgi != null) {
1713 return pgi;
1714 }
1715 } catch (RemoteException e) {
1716 throw new RuntimeException("Package manager has died", e);
1717 }
1718
1719 throw new NameNotFoundException(name);
1720 }
1721
1722 @Override
1723 public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1724 try {
1725 return mPM.getAllPermissionGroups(flags);
1726 } catch (RemoteException e) {
1727 throw new RuntimeException("Package manager has died", e);
1728 }
1729 }
1730
1731 @Override
1732 public ApplicationInfo getApplicationInfo(String packageName, int flags)
1733 throws NameNotFoundException {
1734 try {
1735 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1736 if (ai != null) {
1737 return ai;
1738 }
1739 } catch (RemoteException e) {
1740 throw new RuntimeException("Package manager has died", e);
1741 }
1742
1743 throw new NameNotFoundException(packageName);
1744 }
1745
1746 @Override
1747 public ActivityInfo getActivityInfo(ComponentName className, int flags)
1748 throws NameNotFoundException {
1749 try {
1750 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1751 if (ai != null) {
1752 return ai;
1753 }
1754 } catch (RemoteException e) {
1755 throw new RuntimeException("Package manager has died", e);
1756 }
1757
1758 throw new NameNotFoundException(className.toString());
1759 }
1760
1761 @Override
1762 public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1763 throws NameNotFoundException {
1764 try {
1765 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1766 if (ai != null) {
1767 return ai;
1768 }
1769 } catch (RemoteException e) {
1770 throw new RuntimeException("Package manager has died", e);
1771 }
1772
1773 throw new NameNotFoundException(className.toString());
1774 }
1775
1776 @Override
1777 public ServiceInfo getServiceInfo(ComponentName className, int flags)
1778 throws NameNotFoundException {
1779 try {
1780 ServiceInfo si = mPM.getServiceInfo(className, flags);
1781 if (si != null) {
1782 return si;
1783 }
1784 } catch (RemoteException e) {
1785 throw new RuntimeException("Package manager has died", e);
1786 }
1787
1788 throw new NameNotFoundException(className.toString());
1789 }
1790
1791 @Override
1792 public String[] getSystemSharedLibraryNames() {
1793 try {
1794 return mPM.getSystemSharedLibraryNames();
1795 } catch (RemoteException e) {
1796 throw new RuntimeException("Package manager has died", e);
1797 }
1798 }
1799
1800 @Override
Dianne Hackborn49237342009-08-27 20:08:01 -07001801 public FeatureInfo[] getSystemAvailableFeatures() {
1802 try {
1803 return mPM.getSystemAvailableFeatures();
1804 } catch (RemoteException e) {
1805 throw new RuntimeException("Package manager has died", e);
1806 }
1807 }
1808
1809 @Override
Dianne Hackborn039c68e2009-09-26 16:39:23 -07001810 public boolean hasSystemFeature(String name) {
1811 try {
1812 return mPM.hasSystemFeature(name);
1813 } catch (RemoteException e) {
1814 throw new RuntimeException("Package manager has died", e);
1815 }
1816 }
1817
1818 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001819 public int checkPermission(String permName, String pkgName) {
1820 try {
1821 return mPM.checkPermission(permName, pkgName);
1822 } catch (RemoteException e) {
1823 throw new RuntimeException("Package manager has died", e);
1824 }
1825 }
1826
1827 @Override
1828 public boolean addPermission(PermissionInfo info) {
1829 try {
1830 return mPM.addPermission(info);
1831 } catch (RemoteException e) {
1832 throw new RuntimeException("Package manager has died", e);
1833 }
1834 }
1835
1836 @Override
1837 public void removePermission(String name) {
1838 try {
1839 mPM.removePermission(name);
1840 } catch (RemoteException e) {
1841 throw new RuntimeException("Package manager has died", e);
1842 }
1843 }
1844
1845 @Override
1846 public int checkSignatures(String pkg1, String pkg2) {
1847 try {
1848 return mPM.checkSignatures(pkg1, pkg2);
1849 } catch (RemoteException e) {
1850 throw new RuntimeException("Package manager has died", e);
1851 }
1852 }
1853
1854 @Override
Dianne Hackborn766cbfe2009-08-12 18:33:39 -07001855 public int checkSignatures(int uid1, int uid2) {
1856 try {
1857 return mPM.checkUidSignatures(uid1, uid2);
1858 } catch (RemoteException e) {
1859 throw new RuntimeException("Package manager has died", e);
1860 }
1861 }
1862
1863 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001864 public String[] getPackagesForUid(int uid) {
1865 try {
1866 return mPM.getPackagesForUid(uid);
1867 } catch (RemoteException e) {
1868 throw new RuntimeException("Package manager has died", e);
1869 }
1870 }
1871
1872 @Override
1873 public String getNameForUid(int uid) {
1874 try {
1875 return mPM.getNameForUid(uid);
1876 } catch (RemoteException e) {
1877 throw new RuntimeException("Package manager has died", e);
1878 }
1879 }
1880
1881 @Override
1882 public int getUidForSharedUser(String sharedUserName)
1883 throws NameNotFoundException {
1884 try {
1885 int uid = mPM.getUidForSharedUser(sharedUserName);
1886 if(uid != -1) {
1887 return uid;
1888 }
1889 } catch (RemoteException e) {
1890 throw new RuntimeException("Package manager has died", e);
1891 }
1892 throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
1893 }
1894
1895 @Override
1896 public List<PackageInfo> getInstalledPackages(int flags) {
1897 try {
1898 return mPM.getInstalledPackages(flags);
1899 } catch (RemoteException e) {
1900 throw new RuntimeException("Package manager has died", e);
1901 }
1902 }
1903
1904 @Override
1905 public List<ApplicationInfo> getInstalledApplications(int flags) {
1906 try {
1907 return mPM.getInstalledApplications(flags);
1908 } catch (RemoteException e) {
1909 throw new RuntimeException("Package manager has died", e);
1910 }
1911 }
1912
1913 @Override
1914 public ResolveInfo resolveActivity(Intent intent, int flags) {
1915 try {
1916 return mPM.resolveIntent(
1917 intent,
1918 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1919 flags);
1920 } catch (RemoteException e) {
1921 throw new RuntimeException("Package manager has died", e);
1922 }
1923 }
1924
1925 @Override
1926 public List<ResolveInfo> queryIntentActivities(Intent intent,
1927 int flags) {
1928 try {
1929 return mPM.queryIntentActivities(
1930 intent,
1931 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1932 flags);
1933 } catch (RemoteException e) {
1934 throw new RuntimeException("Package manager has died", e);
1935 }
1936 }
1937
1938 @Override
1939 public List<ResolveInfo> queryIntentActivityOptions(
1940 ComponentName caller, Intent[] specifics, Intent intent,
1941 int flags) {
1942 final ContentResolver resolver = mContext.getContentResolver();
1943
1944 String[] specificTypes = null;
1945 if (specifics != null) {
1946 final int N = specifics.length;
1947 for (int i=0; i<N; i++) {
1948 Intent sp = specifics[i];
1949 if (sp != null) {
1950 String t = sp.resolveTypeIfNeeded(resolver);
1951 if (t != null) {
1952 if (specificTypes == null) {
1953 specificTypes = new String[N];
1954 }
1955 specificTypes[i] = t;
1956 }
1957 }
1958 }
1959 }
1960
1961 try {
1962 return mPM.queryIntentActivityOptions(caller, specifics,
1963 specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
1964 flags);
1965 } catch (RemoteException e) {
1966 throw new RuntimeException("Package manager has died", e);
1967 }
1968 }
1969
1970 @Override
1971 public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
1972 try {
1973 return mPM.queryIntentReceivers(
1974 intent,
1975 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1976 flags);
1977 } catch (RemoteException e) {
1978 throw new RuntimeException("Package manager has died", e);
1979 }
1980 }
1981
1982 @Override
1983 public ResolveInfo resolveService(Intent intent, int flags) {
1984 try {
1985 return mPM.resolveService(
1986 intent,
1987 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
1988 flags);
1989 } catch (RemoteException e) {
1990 throw new RuntimeException("Package manager has died", e);
1991 }
1992 }
1993
1994 @Override
1995 public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
1996 try {
1997 return mPM.queryIntentServices(
1998 intent,
1999 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2000 flags);
2001 } catch (RemoteException e) {
2002 throw new RuntimeException("Package manager has died", e);
2003 }
2004 }
2005
2006 @Override
2007 public ProviderInfo resolveContentProvider(String name,
2008 int flags) {
2009 try {
2010 return mPM.resolveContentProvider(name, flags);
2011 } catch (RemoteException e) {
2012 throw new RuntimeException("Package manager has died", e);
2013 }
2014 }
2015
2016 @Override
2017 public List<ProviderInfo> queryContentProviders(String processName,
2018 int uid, int flags) {
2019 try {
2020 return mPM.queryContentProviders(processName, uid, flags);
2021 } catch (RemoteException e) {
2022 throw new RuntimeException("Package manager has died", e);
2023 }
2024 }
2025
2026 @Override
2027 public InstrumentationInfo getInstrumentationInfo(
2028 ComponentName className, int flags)
2029 throws NameNotFoundException {
2030 try {
2031 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2032 className, flags);
2033 if (ii != null) {
2034 return ii;
2035 }
2036 } catch (RemoteException e) {
2037 throw new RuntimeException("Package manager has died", e);
2038 }
2039
2040 throw new NameNotFoundException(className.toString());
2041 }
2042
2043 @Override
2044 public List<InstrumentationInfo> queryInstrumentation(
2045 String targetPackage, int flags) {
2046 try {
2047 return mPM.queryInstrumentation(targetPackage, flags);
2048 } catch (RemoteException e) {
2049 throw new RuntimeException("Package manager has died", e);
2050 }
2051 }
2052
2053 @Override public Drawable getDrawable(String packageName, int resid,
2054 ApplicationInfo appInfo) {
2055 ResourceName name = new ResourceName(packageName, resid);
2056 Drawable dr = getCachedIcon(name);
2057 if (dr != null) {
2058 return dr;
2059 }
2060 if (appInfo == null) {
2061 try {
2062 appInfo = getApplicationInfo(packageName, 0);
2063 } catch (NameNotFoundException e) {
2064 return null;
2065 }
2066 }
2067 try {
2068 Resources r = getResourcesForApplication(appInfo);
2069 dr = r.getDrawable(resid);
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002070 if (false) {
2071 RuntimeException e = new RuntimeException("here");
2072 e.fillInStackTrace();
2073 Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2074 + " from package " + packageName
2075 + ": app scale=" + r.getCompatibilityInfo().applicationScale
2076 + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2077 e);
2078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002079 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2080 + Integer.toHexString(resid) + " from " + r
2081 + ": " + dr);
2082 putCachedIcon(name, dr);
2083 return dr;
2084 } catch (NameNotFoundException e) {
2085 Log.w("PackageManager", "Failure retrieving resources for"
2086 + appInfo.packageName);
2087 } catch (RuntimeException e) {
2088 // If an exception was thrown, fall through to return
2089 // default icon.
2090 Log.w("PackageManager", "Failure retrieving icon 0x"
2091 + Integer.toHexString(resid) + " in package "
2092 + packageName, e);
2093 }
2094 return null;
2095 }
2096
2097 @Override public Drawable getActivityIcon(ComponentName activityName)
2098 throws NameNotFoundException {
2099 return getActivityInfo(activityName, 0).loadIcon(this);
2100 }
2101
2102 @Override public Drawable getActivityIcon(Intent intent)
2103 throws NameNotFoundException {
2104 if (intent.getComponent() != null) {
2105 return getActivityIcon(intent.getComponent());
2106 }
2107
2108 ResolveInfo info = resolveActivity(
2109 intent, PackageManager.MATCH_DEFAULT_ONLY);
2110 if (info != null) {
2111 return info.activityInfo.loadIcon(this);
2112 }
2113
2114 throw new NameNotFoundException(intent.toURI());
2115 }
2116
2117 @Override public Drawable getDefaultActivityIcon() {
2118 return Resources.getSystem().getDrawable(
2119 com.android.internal.R.drawable.sym_def_app_icon);
2120 }
2121
2122 @Override public Drawable getApplicationIcon(ApplicationInfo info) {
2123 final int icon = info.icon;
2124 if (icon != 0) {
2125 ResourceName name = new ResourceName(info, icon);
2126 Drawable dr = getCachedIcon(name);
2127 if (dr != null) {
2128 return dr;
2129 }
2130 try {
2131 Resources r = getResourcesForApplication(info);
2132 dr = r.getDrawable(icon);
2133 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2134 + Integer.toHexString(icon) + " from " + r
2135 + ": " + dr);
2136 putCachedIcon(name, dr);
2137 return dr;
2138 } catch (NameNotFoundException e) {
2139 Log.w("PackageManager", "Failure retrieving resources for"
2140 + info.packageName);
2141 } catch (RuntimeException e) {
2142 // If an exception was thrown, fall through to return
2143 // default icon.
2144 Log.w("PackageManager", "Failure retrieving app icon", e);
2145 }
2146 }
2147 return getDefaultActivityIcon();
2148 }
2149
2150 @Override public Drawable getApplicationIcon(String packageName)
2151 throws NameNotFoundException {
2152 return getApplicationIcon(getApplicationInfo(packageName, 0));
2153 }
2154
2155 @Override public Resources getResourcesForActivity(
2156 ComponentName activityName) throws NameNotFoundException {
2157 return getResourcesForApplication(
2158 getActivityInfo(activityName, 0).applicationInfo);
2159 }
2160
2161 @Override public Resources getResourcesForApplication(
2162 ApplicationInfo app) throws NameNotFoundException {
2163 if (app.packageName.equals("system")) {
2164 return mContext.mMainThread.getSystemContext().getResources();
2165 }
2166 Resources r = mContext.mMainThread.getTopLevelResources(
2167 app.uid == Process.myUid() ? app.sourceDir
Dianne Hackborn11ea3342009-07-22 21:48:55 -07002168 : app.publicSourceDir, mContext.mPackageInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 if (r != null) {
2170 return r;
2171 }
2172 throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2173 }
2174
2175 @Override public Resources getResourcesForApplication(
2176 String appPackageName) throws NameNotFoundException {
2177 return getResourcesForApplication(
2178 getApplicationInfo(appPackageName, 0));
2179 }
2180
2181 int mCachedSafeMode = -1;
2182 @Override public boolean isSafeMode() {
2183 try {
2184 if (mCachedSafeMode < 0) {
2185 mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2186 }
2187 return mCachedSafeMode != 0;
2188 } catch (RemoteException e) {
2189 throw new RuntimeException("Package manager has died", e);
2190 }
2191 }
2192
2193 static void configurationChanged() {
2194 synchronized (sSync) {
2195 sIconCache.clear();
2196 sStringCache.clear();
2197 }
2198 }
2199
Dianne Hackborn21556372010-02-04 16:34:40 -08002200 ApplicationPackageManager(ContextImpl context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201 IPackageManager pm) {
2202 mContext = context;
2203 mPM = pm;
2204 }
2205
2206 private Drawable getCachedIcon(ResourceName name) {
2207 synchronized (sSync) {
2208 WeakReference<Drawable> wr = sIconCache.get(name);
2209 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2210 + name + ": " + wr);
2211 if (wr != null) { // we have the activity
2212 Drawable dr = wr.get();
2213 if (dr != null) {
2214 if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2215 + name + ": " + dr);
2216 return dr;
2217 }
2218 // our entry has been purged
2219 sIconCache.remove(name);
2220 }
2221 }
2222 return null;
2223 }
2224
2225 private void establishPackageRemovedReceiver() {
2226 // mContext.registerReceiverInternal() winds up acquiring the
2227 // main ActivityManagerService.this lock. If we hold our usual
2228 // sSync global lock at the same time, we impose a required ordering
2229 // on those two locks, which is not good for deadlock prevention.
2230 // Use a dedicated lock around initialization of
2231 // sPackageRemovedReceiver to avoid this.
2232 synchronized (sPackageRemovedSync) {
2233 if (sPackageRemovedReceiver == null) {
2234 sPackageRemovedReceiver = new PackageRemovedReceiver();
2235 IntentFilter filter = new IntentFilter(
2236 Intent.ACTION_PACKAGE_REMOVED);
2237 filter.addDataScheme("package");
2238 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2239 filter, null, null, null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002240 // Register for events related to sdcard installation.
2241 IntentFilter sdFilter = new IntentFilter();
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08002242 sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002243 mContext.registerReceiverInternal(sPackageRemovedReceiver,
2244 sdFilter, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 }
2246 }
2247 }
2248
2249 private void putCachedIcon(ResourceName name, Drawable dr) {
2250 establishPackageRemovedReceiver();
2251
2252 synchronized (sSync) {
2253 sIconCache.put(name, new WeakReference<Drawable>(dr));
2254 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2255 + name + ": " + dr);
2256 }
2257 }
2258
2259 private static final class PackageRemovedReceiver extends BroadcastReceiver {
2260 @Override
2261 public void onReceive(Context context, Intent intent) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002262 String pkgList[] = null;
2263 String action = intent.getAction();
2264 boolean immediateGc = false;
Suchi Amalapurapub56ae202010-02-04 22:51:07 -08002265 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002266 pkgList = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
2267 immediateGc = true;
2268 } else {
2269 Uri data = intent.getData();
2270 if (data != null) {
2271 String ssp = data.getSchemeSpecificPart();
2272 if (ssp != null) {
2273 pkgList = new String[] { ssp };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002274 }
2275 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08002276 }
2277 if (pkgList != null && (pkgList.length > 0)) {
2278 boolean needCleanup = false;
2279 boolean hasPkgInfo = false;
2280 for (String ssp : pkgList) {
2281 synchronized (sSync) {
2282 Iterator<ResourceName> it = sIconCache.keySet().iterator();
2283 while (it.hasNext()) {
2284 ResourceName nm = it.next();
2285 if (nm.packageName.equals(ssp)) {
2286 //Log.i(TAG, "Removing cached drawable for " + nm);
2287 it.remove();
2288 needCleanup = true;
2289 }
2290 }
2291 it = sStringCache.keySet().iterator();
2292 while (it.hasNext()) {
2293 ResourceName nm = it.next();
2294 if (nm.packageName.equals(ssp)) {
2295 //Log.i(TAG, "Removing cached string for " + nm);
2296 it.remove();
2297 needCleanup = true;
2298 }
2299 }
2300 }
2301 if (!hasPkgInfo) {
2302 hasPkgInfo = ActivityThread.currentActivityThread().hasPackageInfo(ssp);
2303 }
2304 }
2305 if (needCleanup || hasPkgInfo) {
2306 if (immediateGc) {
2307 // Schedule an immediate gc.
2308 Runtime.getRuntime().gc();
2309 } else {
2310 ActivityThread.currentActivityThread().scheduleGcIdler();
2311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 }
2313 }
2314 }
2315 }
2316
2317 private static final class ResourceName {
2318 final String packageName;
2319 final int iconId;
2320
2321 ResourceName(String _packageName, int _iconId) {
2322 packageName = _packageName;
2323 iconId = _iconId;
2324 }
2325
2326 ResourceName(ApplicationInfo aInfo, int _iconId) {
2327 this(aInfo.packageName, _iconId);
2328 }
2329
2330 ResourceName(ComponentInfo cInfo, int _iconId) {
2331 this(cInfo.applicationInfo.packageName, _iconId);
2332 }
2333
2334 ResourceName(ResolveInfo rInfo, int _iconId) {
2335 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2336 }
2337
2338 @Override
2339 public boolean equals(Object o) {
2340 if (this == o) return true;
2341 if (o == null || getClass() != o.getClass()) return false;
2342
2343 ResourceName that = (ResourceName) o;
2344
2345 if (iconId != that.iconId) return false;
2346 return !(packageName != null ?
2347 !packageName.equals(that.packageName) : that.packageName != null);
2348
2349 }
2350
2351 @Override
2352 public int hashCode() {
2353 int result;
2354 result = packageName.hashCode();
2355 result = 31 * result + iconId;
2356 return result;
2357 }
2358
2359 @Override
2360 public String toString() {
2361 return "{ResourceName " + packageName + " / " + iconId + "}";
2362 }
2363 }
2364
2365 private CharSequence getCachedString(ResourceName name) {
2366 synchronized (sSync) {
2367 WeakReference<CharSequence> wr = sStringCache.get(name);
2368 if (wr != null) { // we have the activity
2369 CharSequence cs = wr.get();
2370 if (cs != null) {
2371 return cs;
2372 }
2373 // our entry has been purged
2374 sStringCache.remove(name);
2375 }
2376 }
2377 return null;
2378 }
2379
2380 private void putCachedString(ResourceName name, CharSequence cs) {
2381 establishPackageRemovedReceiver();
2382
2383 synchronized (sSync) {
2384 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2385 }
2386 }
2387
2388 private CharSequence getLabel(ResourceName name, ApplicationInfo app, int id) {
2389 CharSequence cs = getCachedString(name);
2390 if (cs != null) {
2391 return cs;
2392 }
2393 try {
2394 Resources r = getResourcesForApplication(app);
2395 cs = r.getText(id);
2396 putCachedString(name, cs);
2397 } catch (NameNotFoundException e) {
2398 Log.w("PackageManager", "Failure retrieving resources for"
2399 + app.packageName);
2400 } catch (RuntimeException e) {
2401 // If an exception was thrown, fall through to return null
2402 Log.w("ApplicationInfo", "Failure retrieving activity name", e);
2403 }
2404 return cs;
2405 }
2406
2407 @Override
2408 public CharSequence getText(String packageName, int resid,
2409 ApplicationInfo appInfo) {
2410 ResourceName name = new ResourceName(packageName, resid);
2411 CharSequence text = getCachedString(name);
2412 if (text != null) {
2413 return text;
2414 }
2415 if (appInfo == null) {
2416 try {
2417 appInfo = getApplicationInfo(packageName, 0);
2418 } catch (NameNotFoundException e) {
2419 return null;
2420 }
2421 }
2422 try {
2423 Resources r = getResourcesForApplication(appInfo);
2424 text = r.getText(resid);
2425 putCachedString(name, text);
2426 return text;
2427 } catch (NameNotFoundException e) {
2428 Log.w("PackageManager", "Failure retrieving resources for"
2429 + appInfo.packageName);
2430 } catch (RuntimeException e) {
2431 // If an exception was thrown, fall through to return
2432 // default icon.
2433 Log.w("PackageManager", "Failure retrieving text 0x"
2434 + Integer.toHexString(resid) + " in package "
2435 + packageName, e);
2436 }
2437 return null;
2438 }
2439
2440 @Override
2441 public XmlResourceParser getXml(String packageName, int resid,
2442 ApplicationInfo appInfo) {
2443 if (appInfo == null) {
2444 try {
2445 appInfo = getApplicationInfo(packageName, 0);
2446 } catch (NameNotFoundException e) {
2447 return null;
2448 }
2449 }
2450 try {
2451 Resources r = getResourcesForApplication(appInfo);
2452 return r.getXml(resid);
2453 } catch (RuntimeException e) {
2454 // If an exception was thrown, fall through to return
2455 // default icon.
2456 Log.w("PackageManager", "Failure retrieving xml 0x"
2457 + Integer.toHexString(resid) + " in package "
2458 + packageName, e);
2459 } catch (NameNotFoundException e) {
2460 Log.w("PackageManager", "Failure retrieving resources for"
2461 + appInfo.packageName);
2462 }
2463 return null;
2464 }
2465
2466 @Override
2467 public CharSequence getApplicationLabel(ApplicationInfo info) {
2468 if (info.nonLocalizedLabel != null) {
2469 return info.nonLocalizedLabel;
2470 }
2471 final int id = info.labelRes;
2472 if (id != 0) {
2473 CharSequence cs = getLabel(new ResourceName(info, id), info, id);
2474 if (cs != null) {
2475 return cs;
2476 }
2477 }
2478 return info.packageName;
2479 }
2480
2481 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002482 public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2483 String installerPackageName) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 try {
Jacek Surazski65e13172009-04-28 15:26:38 +02002485 mPM.installPackage(packageURI, observer, flags, installerPackageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 } catch (RemoteException e) {
2487 // Should never happen!
2488 }
2489 }
2490
2491 @Override
Jacek Surazski65e13172009-04-28 15:26:38 +02002492 public String getInstallerPackageName(String packageName) {
2493 try {
2494 return mPM.getInstallerPackageName(packageName);
2495 } catch (RemoteException e) {
2496 // Should never happen!
2497 }
2498 return null;
2499 }
2500
2501 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002502 public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2503 try {
2504 mPM.deletePackage(packageName, observer, flags);
2505 } catch (RemoteException e) {
2506 // Should never happen!
2507 }
2508 }
2509 @Override
2510 public void clearApplicationUserData(String packageName,
2511 IPackageDataObserver observer) {
2512 try {
2513 mPM.clearApplicationUserData(packageName, observer);
2514 } catch (RemoteException e) {
2515 // Should never happen!
2516 }
2517 }
2518 @Override
2519 public void deleteApplicationCacheFiles(String packageName,
2520 IPackageDataObserver observer) {
2521 try {
2522 mPM.deleteApplicationCacheFiles(packageName, observer);
2523 } catch (RemoteException e) {
2524 // Should never happen!
2525 }
2526 }
2527 @Override
2528 public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2529 try {
2530 mPM.freeStorageAndNotify(idealStorageSize, observer);
2531 } catch (RemoteException e) {
2532 // Should never happen!
2533 }
2534 }
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002535
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002536 @Override
Suchi Amalapurapubc806f62009-06-17 15:18:19 -07002537 public void freeStorage(long freeStorageSize, IntentSender pi) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 try {
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -07002539 mPM.freeStorage(freeStorageSize, pi);
2540 } catch (RemoteException e) {
2541 // Should never happen!
2542 }
2543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544
2545 @Override
2546 public void getPackageSizeInfo(String packageName,
2547 IPackageStatsObserver observer) {
2548 try {
2549 mPM.getPackageSizeInfo(packageName, observer);
2550 } catch (RemoteException e) {
2551 // Should never happen!
2552 }
2553 }
2554 @Override
2555 public void addPackageToPreferred(String packageName) {
2556 try {
2557 mPM.addPackageToPreferred(packageName);
2558 } catch (RemoteException e) {
2559 // Should never happen!
2560 }
2561 }
2562
2563 @Override
2564 public void removePackageFromPreferred(String packageName) {
2565 try {
2566 mPM.removePackageFromPreferred(packageName);
2567 } catch (RemoteException e) {
2568 // Should never happen!
2569 }
2570 }
2571
2572 @Override
2573 public List<PackageInfo> getPreferredPackages(int flags) {
2574 try {
2575 return mPM.getPreferredPackages(flags);
2576 } catch (RemoteException e) {
2577 // Should never happen!
2578 }
2579 return new ArrayList<PackageInfo>();
2580 }
2581
2582 @Override
2583 public void addPreferredActivity(IntentFilter filter,
2584 int match, ComponentName[] set, ComponentName activity) {
2585 try {
2586 mPM.addPreferredActivity(filter, match, set, activity);
2587 } catch (RemoteException e) {
2588 // Should never happen!
2589 }
2590 }
2591
2592 @Override
Satish Sampath8dbe6122009-06-02 23:35:54 +01002593 public void replacePreferredActivity(IntentFilter filter,
2594 int match, ComponentName[] set, ComponentName activity) {
2595 try {
2596 mPM.replacePreferredActivity(filter, match, set, activity);
2597 } catch (RemoteException e) {
2598 // Should never happen!
2599 }
2600 }
2601
2602 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 public void clearPackagePreferredActivities(String packageName) {
2604 try {
2605 mPM.clearPackagePreferredActivities(packageName);
2606 } catch (RemoteException e) {
2607 // Should never happen!
2608 }
2609 }
2610
2611 @Override
2612 public int getPreferredActivities(List<IntentFilter> outFilters,
2613 List<ComponentName> outActivities, String packageName) {
2614 try {
2615 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2616 } catch (RemoteException e) {
2617 // Should never happen!
2618 }
2619 return 0;
2620 }
2621
2622 @Override
2623 public void setComponentEnabledSetting(ComponentName componentName,
2624 int newState, int flags) {
2625 try {
2626 mPM.setComponentEnabledSetting(componentName, newState, flags);
2627 } catch (RemoteException e) {
2628 // Should never happen!
2629 }
2630 }
2631
2632 @Override
2633 public int getComponentEnabledSetting(ComponentName componentName) {
2634 try {
2635 return mPM.getComponentEnabledSetting(componentName);
2636 } catch (RemoteException e) {
2637 // Should never happen!
2638 }
2639 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2640 }
2641
2642 @Override
2643 public void setApplicationEnabledSetting(String packageName,
2644 int newState, int flags) {
2645 try {
2646 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2647 } catch (RemoteException e) {
2648 // Should never happen!
2649 }
2650 }
2651
2652 @Override
2653 public int getApplicationEnabledSetting(String packageName) {
2654 try {
2655 return mPM.getApplicationEnabledSetting(packageName);
2656 } catch (RemoteException e) {
2657 // Should never happen!
2658 }
2659 return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2660 }
2661
Dianne Hackborn21556372010-02-04 16:34:40 -08002662 private final ContextImpl mContext;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 private final IPackageManager mPM;
2664
2665 private static final Object sSync = new Object();
2666 private static final Object sPackageRemovedSync = new Object();
2667 private static BroadcastReceiver sPackageRemovedReceiver;
2668 private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2669 = new HashMap<ResourceName, WeakReference<Drawable> >();
2670 private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2671 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2672 }
2673
2674 // ----------------------------------------------------------------------
2675 // ----------------------------------------------------------------------
2676 // ----------------------------------------------------------------------
2677
2678 private static final class SharedPreferencesImpl implements SharedPreferences {
2679
2680 private final File mFile;
2681 private final File mBackupFile;
2682 private final int mMode;
2683 private Map mMap;
2684 private final FileStatus mFileStatus = new FileStatus();
2685 private long mTimestamp;
2686
The Android Open Source Project10592532009-03-18 17:39:46 -07002687 private static final Object mContent = new Object();
2688 private WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689
2690 SharedPreferencesImpl(
2691 File file, int mode, Map initialContents) {
2692 mFile = file;
2693 mBackupFile = makeBackupFile(file);
2694 mMode = mode;
2695 mMap = initialContents != null ? initialContents : new HashMap();
2696 if (FileUtils.getFileStatus(file.getPath(), mFileStatus)) {
2697 mTimestamp = mFileStatus.mtime;
2698 }
The Android Open Source Project10592532009-03-18 17:39:46 -07002699 mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 }
2701
2702 public boolean hasFileChanged() {
2703 synchronized (this) {
2704 if (!FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2705 return true;
2706 }
2707 return mTimestamp != mFileStatus.mtime;
2708 }
2709 }
2710
2711 public void replace(Map newContents) {
2712 if (newContents != null) {
2713 synchronized (this) {
2714 mMap = newContents;
2715 }
2716 }
2717 }
2718
2719 public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2720 synchronized(this) {
The Android Open Source Project10592532009-03-18 17:39:46 -07002721 mListeners.put(listener, mContent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 }
2723 }
2724
2725 public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2726 synchronized(this) {
2727 mListeners.remove(listener);
2728 }
2729 }
2730
2731 public Map<String, ?> getAll() {
2732 synchronized(this) {
2733 //noinspection unchecked
2734 return new HashMap(mMap);
2735 }
2736 }
2737
2738 public String getString(String key, String defValue) {
2739 synchronized (this) {
2740 String v = (String)mMap.get(key);
2741 return v != null ? v : defValue;
2742 }
2743 }
2744
2745 public int getInt(String key, int defValue) {
2746 synchronized (this) {
2747 Integer v = (Integer)mMap.get(key);
2748 return v != null ? v : defValue;
2749 }
2750 }
2751 public long getLong(String key, long defValue) {
2752 synchronized (this) {
2753 Long v = (Long) mMap.get(key);
2754 return v != null ? v : defValue;
2755 }
2756 }
2757 public float getFloat(String key, float defValue) {
2758 synchronized (this) {
2759 Float v = (Float)mMap.get(key);
2760 return v != null ? v : defValue;
2761 }
2762 }
2763 public boolean getBoolean(String key, boolean defValue) {
2764 synchronized (this) {
2765 Boolean v = (Boolean)mMap.get(key);
2766 return v != null ? v : defValue;
2767 }
2768 }
2769
2770 public boolean contains(String key) {
2771 synchronized (this) {
2772 return mMap.containsKey(key);
2773 }
2774 }
2775
2776 public final class EditorImpl implements Editor {
2777 private final Map<String, Object> mModified = Maps.newHashMap();
2778 private boolean mClear = false;
2779
2780 public Editor putString(String key, String value) {
2781 synchronized (this) {
2782 mModified.put(key, value);
2783 return this;
2784 }
2785 }
2786 public Editor putInt(String key, int value) {
2787 synchronized (this) {
2788 mModified.put(key, value);
2789 return this;
2790 }
2791 }
2792 public Editor putLong(String key, long value) {
2793 synchronized (this) {
2794 mModified.put(key, value);
2795 return this;
2796 }
2797 }
2798 public Editor putFloat(String key, float value) {
2799 synchronized (this) {
2800 mModified.put(key, value);
2801 return this;
2802 }
2803 }
2804 public Editor putBoolean(String key, boolean value) {
2805 synchronized (this) {
2806 mModified.put(key, value);
2807 return this;
2808 }
2809 }
2810
2811 public Editor remove(String key) {
2812 synchronized (this) {
2813 mModified.put(key, this);
2814 return this;
2815 }
2816 }
2817
2818 public Editor clear() {
2819 synchronized (this) {
2820 mClear = true;
2821 return this;
2822 }
2823 }
2824
2825 public boolean commit() {
2826 boolean returnValue;
2827
2828 boolean hasListeners;
2829 List<String> keysModified = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002830 Set<OnSharedPreferenceChangeListener> listeners = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831
2832 synchronized (SharedPreferencesImpl.this) {
2833 hasListeners = mListeners.size() > 0;
2834 if (hasListeners) {
2835 keysModified = new ArrayList<String>();
The Android Open Source Project10592532009-03-18 17:39:46 -07002836 listeners =
2837 new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 }
2839
2840 synchronized (this) {
2841 if (mClear) {
2842 mMap.clear();
2843 mClear = false;
2844 }
2845
The Android Open Source Project10592532009-03-18 17:39:46 -07002846 for (Entry<String, Object> e : mModified.entrySet()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002847 String k = e.getKey();
2848 Object v = e.getValue();
2849 if (v == this) {
2850 mMap.remove(k);
2851 } else {
2852 mMap.put(k, v);
2853 }
2854
2855 if (hasListeners) {
2856 keysModified.add(k);
2857 }
2858 }
2859
2860 mModified.clear();
2861 }
2862
2863 returnValue = writeFileLocked();
2864 }
2865
2866 if (hasListeners) {
2867 for (int i = keysModified.size() - 1; i >= 0; i--) {
2868 final String key = keysModified.get(i);
The Android Open Source Project10592532009-03-18 17:39:46 -07002869 for (OnSharedPreferenceChangeListener listener : listeners) {
2870 if (listener != null) {
2871 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
2872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 }
2874 }
2875 }
2876
2877 return returnValue;
2878 }
2879 }
2880
2881 public Editor edit() {
2882 return new EditorImpl();
2883 }
2884
2885 private FileOutputStream createFileOutputStream(File file) {
2886 FileOutputStream str = null;
2887 try {
2888 str = new FileOutputStream(file);
2889 } catch (FileNotFoundException e) {
2890 File parent = file.getParentFile();
2891 if (!parent.mkdir()) {
2892 Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
2893 return null;
2894 }
2895 FileUtils.setPermissions(
2896 parent.getPath(),
2897 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2898 -1, -1);
2899 try {
2900 str = new FileOutputStream(file);
2901 } catch (FileNotFoundException e2) {
2902 Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
2903 }
2904 }
2905 return str;
2906 }
2907
2908 private boolean writeFileLocked() {
2909 // Rename the current file so it may be used as a backup during the next read
2910 if (mFile.exists()) {
2911 if (!mFile.renameTo(mBackupFile)) {
2912 Log.e(TAG, "Couldn't rename file " + mFile + " to backup file " + mBackupFile);
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07002913 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 }
2915 }
2916
2917 // Attempt to write the file, delete the backup and return true as atomically as
2918 // possible. If any exception occurs, delete the new file; next time we will restore
2919 // from the backup.
2920 try {
2921 FileOutputStream str = createFileOutputStream(mFile);
2922 if (str == null) {
2923 return false;
2924 }
2925 XmlUtils.writeMapXml(mMap, str);
2926 str.close();
2927 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
2928 if (FileUtils.getFileStatus(mFile.getPath(), mFileStatus)) {
2929 mTimestamp = mFileStatus.mtime;
2930 }
2931
Dianne Hackborn51bf0772009-03-24 19:11:41 -07002932 // Writing was successful, delete the backup file if there is one.
2933 mBackupFile.delete();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 return true;
2935 } catch (XmlPullParserException e) {
2936 Log.w(TAG, "writeFileLocked: Got exception:", e);
2937 } catch (IOException e) {
2938 Log.w(TAG, "writeFileLocked: Got exception:", e);
2939 }
2940 // Clean up an unsuccessfully written file
2941 if (mFile.exists()) {
2942 if (!mFile.delete()) {
2943 Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
2944 }
2945 }
2946 return false;
2947 }
2948 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949}