• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package android.app;
18 
19 import com.android.internal.policy.PolicyManager;
20 import com.android.internal.util.XmlUtils;
21 import com.google.android.collect.Maps;
22 
23 import org.xmlpull.v1.XmlPullParserException;
24 
25 import android.content.BroadcastReceiver;
26 import android.content.ComponentName;
27 import android.content.ContentResolver;
28 import android.content.Context;
29 import android.content.ContextWrapper;
30 import android.content.IContentProvider;
31 import android.content.Intent;
32 import android.content.IntentFilter;
33 import android.content.IIntentReceiver;
34 import android.content.IntentSender;
35 import android.content.ReceiverCallNotAllowedException;
36 import android.content.ServiceConnection;
37 import android.content.SharedPreferences;
38 import android.content.pm.ActivityInfo;
39 import android.content.pm.ApplicationInfo;
40 import android.content.pm.ComponentInfo;
41 import android.content.pm.FeatureInfo;
42 import android.content.pm.IPackageDataObserver;
43 import android.content.pm.IPackageDeleteObserver;
44 import android.content.pm.IPackageInstallObserver;
45 import android.content.pm.IPackageMoveObserver;
46 import android.content.pm.IPackageManager;
47 import android.content.pm.IPackageStatsObserver;
48 import android.content.pm.InstrumentationInfo;
49 import android.content.pm.PackageInfo;
50 import android.content.pm.PackageManager;
51 import android.content.pm.ParceledListSlice;
52 import android.content.pm.PermissionGroupInfo;
53 import android.content.pm.PermissionInfo;
54 import android.content.pm.ProviderInfo;
55 import android.content.pm.ResolveInfo;
56 import android.content.pm.ServiceInfo;
57 import android.content.pm.PackageParser.Package;
58 import android.content.res.AssetManager;
59 import android.content.res.Resources;
60 import android.content.res.XmlResourceParser;
61 import android.database.sqlite.SQLiteDatabase;
62 import android.database.sqlite.SQLiteDatabase.CursorFactory;
63 import android.graphics.Bitmap;
64 import android.graphics.drawable.Drawable;
65 import android.hardware.SensorManager;
66 import android.hardware.usb.IUsbManager;
67 import android.hardware.usb.UsbManager;
68 import android.location.ILocationManager;
69 import android.location.LocationManager;
70 import android.media.AudioManager;
71 import android.net.ConnectivityManager;
72 import android.net.IConnectivityManager;
73 import android.net.ThrottleManager;
74 import android.net.IThrottleManager;
75 import android.net.Uri;
76 import android.net.wifi.IWifiManager;
77 import android.net.wifi.WifiManager;
78 import android.nfc.NfcManager;
79 import android.os.Binder;
80 import android.os.Bundle;
81 import android.os.DropBoxManager;
82 import android.os.Environment;
83 import android.os.FileUtils;
84 import android.os.Handler;
85 import android.os.IBinder;
86 import android.os.IPowerManager;
87 import android.os.Looper;
88 import android.os.Parcel;
89 import android.os.PowerManager;
90 import android.os.Process;
91 import android.os.RemoteException;
92 import android.os.ServiceManager;
93 import android.os.StatFs;
94 import android.os.Vibrator;
95 import android.os.FileUtils.FileStatus;
96 import android.os.storage.StorageManager;
97 import android.provider.Settings;
98 import android.telephony.TelephonyManager;
99 import android.text.ClipboardManager;
100 import android.util.AndroidRuntimeException;
101 import android.util.Log;
102 import android.view.ContextThemeWrapper;
103 import android.view.LayoutInflater;
104 import android.view.WindowManagerImpl;
105 import android.view.accessibility.AccessibilityManager;
106 import android.view.inputmethod.InputMethodManager;
107 import android.accounts.AccountManager;
108 import android.accounts.IAccountManager;
109 import android.app.admin.DevicePolicyManager;
110 import com.android.internal.os.IDropBoxManagerService;
111 
112 import java.io.File;
113 import java.io.FileInputStream;
114 import java.io.FileNotFoundException;
115 import java.io.FileOutputStream;
116 import java.io.IOException;
117 import java.io.InputStream;
118 import java.lang.ref.WeakReference;
119 import java.util.ArrayList;
120 import java.util.HashMap;
121 import java.util.HashSet;
122 import java.util.Iterator;
123 import java.util.List;
124 import java.util.Map;
125 import java.util.Map.Entry;
126 import java.util.Set;
127 import java.util.WeakHashMap;
128 import java.util.concurrent.CountDownLatch;
129 import java.util.concurrent.ExecutorService;
130 
131 class ReceiverRestrictedContext extends ContextWrapper {
ReceiverRestrictedContext(Context base)132     ReceiverRestrictedContext(Context base) {
133         super(base);
134     }
135 
136     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)137     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
138         return registerReceiver(receiver, filter, null, null);
139     }
140 
141     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)142     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
143             String broadcastPermission, Handler scheduler) {
144         throw new ReceiverCallNotAllowedException(
145                 "IntentReceiver components are not allowed to register to receive intents");
146         //ex.fillInStackTrace();
147         //Log.e("IntentReceiver", ex.getMessage(), ex);
148         //return mContext.registerReceiver(receiver, filter, broadcastPermission,
149         //        scheduler);
150     }
151 
152     @Override
bindService(Intent service, ServiceConnection conn, int flags)153     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
154         throw new ReceiverCallNotAllowedException(
155                 "IntentReceiver components are not allowed to bind to services");
156         //ex.fillInStackTrace();
157         //Log.e("IntentReceiver", ex.getMessage(), ex);
158         //return mContext.bindService(service, interfaceName, conn, flags);
159     }
160 }
161 
162 /**
163  * Common implementation of Context API, which provides the base
164  * context object for Activity and other application components.
165  */
166 class ContextImpl extends Context {
167     private final static String TAG = "ApplicationContext";
168     private final static boolean DEBUG = false;
169     private final static boolean DEBUG_ICONS = false;
170 
171     private static final Object sSync = new Object();
172     private static AlarmManager sAlarmManager;
173     private static PowerManager sPowerManager;
174     private static ConnectivityManager sConnectivityManager;
175     private static ThrottleManager sThrottleManager;
176     private static WifiManager sWifiManager;
177     private static LocationManager sLocationManager;
178     private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
179             new HashMap<String, SharedPreferencesImpl>();
180 
181     private AudioManager mAudioManager;
182     /*package*/ LoadedApk mPackageInfo;
183     private Resources mResources;
184     /*package*/ ActivityThread mMainThread;
185     private Context mOuterContext;
186     private IBinder mActivityToken = null;
187     private ApplicationContentResolver mContentResolver;
188     private int mThemeResource = 0;
189     private Resources.Theme mTheme = null;
190     private PackageManager mPackageManager;
191     private NotificationManager mNotificationManager = null;
192     private ActivityManager mActivityManager = null;
193     private WallpaperManager mWallpaperManager = null;
194     private Context mReceiverRestrictedContext = null;
195     private SearchManager mSearchManager = null;
196     private SensorManager mSensorManager = null;
197     private StorageManager mStorageManager = null;
198     private UsbManager mUsbManager = null;
199     private Vibrator mVibrator = null;
200     private LayoutInflater mLayoutInflater = null;
201     private StatusBarManager mStatusBarManager = null;
202     private TelephonyManager mTelephonyManager = null;
203     private ClipboardManager mClipboardManager = null;
204     private boolean mRestricted;
205     private AccountManager mAccountManager; // protected by mSync
206     private DropBoxManager mDropBoxManager = null;
207     private DevicePolicyManager mDevicePolicyManager = null;
208     private UiModeManager mUiModeManager = null;
209     private DownloadManager mDownloadManager = null;
210     private NfcManager mNfcManager = null;
211 
212     private final Object mSync = new Object();
213 
214     private File mDatabasesDir;
215     private File mPreferencesDir;
216     private File mFilesDir;
217     private File mCacheDir;
218     private File mExternalFilesDir;
219     private File mExternalCacheDir;
220 
221     private static long sInstanceCount = 0;
222 
223     private static final String[] EMPTY_FILE_LIST = {};
224 
225     // For debug only
226     /*
227     @Override
228     protected void finalize() throws Throwable {
229         super.finalize();
230         --sInstanceCount;
231     }
232     */
233 
getInstanceCount()234     public static long getInstanceCount() {
235         return sInstanceCount;
236     }
237 
238     @Override
getAssets()239     public AssetManager getAssets() {
240         return mResources.getAssets();
241     }
242 
243     @Override
getResources()244     public Resources getResources() {
245         return mResources;
246     }
247 
248     @Override
getPackageManager()249     public PackageManager getPackageManager() {
250         if (mPackageManager != null) {
251             return mPackageManager;
252         }
253 
254         IPackageManager pm = ActivityThread.getPackageManager();
255         if (pm != null) {
256             // Doesn't matter if we make more than one instance.
257             return (mPackageManager = new ApplicationPackageManager(this, pm));
258         }
259 
260         return null;
261     }
262 
263     @Override
getContentResolver()264     public ContentResolver getContentResolver() {
265         return mContentResolver;
266     }
267 
268     @Override
getMainLooper()269     public Looper getMainLooper() {
270         return mMainThread.getLooper();
271     }
272 
273     @Override
getApplicationContext()274     public Context getApplicationContext() {
275         return (mPackageInfo != null) ?
276                 mPackageInfo.getApplication() : mMainThread.getApplication();
277     }
278 
279     @Override
setTheme(int resid)280     public void setTheme(int resid) {
281         mThemeResource = resid;
282     }
283 
284     @Override
getTheme()285     public Resources.Theme getTheme() {
286         if (mTheme == null) {
287             if (mThemeResource == 0) {
288                 mThemeResource = com.android.internal.R.style.Theme;
289             }
290             mTheme = mResources.newTheme();
291             mTheme.applyStyle(mThemeResource, true);
292         }
293         return mTheme;
294     }
295 
296     @Override
getClassLoader()297     public ClassLoader getClassLoader() {
298         return mPackageInfo != null ?
299                 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
300     }
301 
302     @Override
getPackageName()303     public String getPackageName() {
304         if (mPackageInfo != null) {
305             return mPackageInfo.getPackageName();
306         }
307         throw new RuntimeException("Not supported in system context");
308     }
309 
310     @Override
getApplicationInfo()311     public ApplicationInfo getApplicationInfo() {
312         if (mPackageInfo != null) {
313             return mPackageInfo.getApplicationInfo();
314         }
315         throw new RuntimeException("Not supported in system context");
316     }
317 
318     @Override
getPackageResourcePath()319     public String getPackageResourcePath() {
320         if (mPackageInfo != null) {
321             return mPackageInfo.getResDir();
322         }
323         throw new RuntimeException("Not supported in system context");
324     }
325 
326     @Override
getPackageCodePath()327     public String getPackageCodePath() {
328         if (mPackageInfo != null) {
329             return mPackageInfo.getAppDir();
330         }
331         throw new RuntimeException("Not supported in system context");
332     }
333 
makeBackupFile(File prefsFile)334     private static File makeBackupFile(File prefsFile) {
335         return new File(prefsFile.getPath() + ".bak");
336     }
337 
getSharedPrefsFile(String name)338     public File getSharedPrefsFile(String name) {
339         return makeFilename(getPreferencesDir(), name + ".xml");
340     }
341 
342     @Override
getSharedPreferences(String name, int mode)343     public SharedPreferences getSharedPreferences(String name, int mode) {
344         SharedPreferencesImpl sp;
345         File prefsFile;
346         boolean needInitialLoad = false;
347         synchronized (sSharedPrefs) {
348             sp = sSharedPrefs.get(name);
349             if (sp != null && !sp.hasFileChangedUnexpectedly()) {
350                 return sp;
351             }
352             prefsFile = getSharedPrefsFile(name);
353             if (sp == null) {
354                 sp = new SharedPreferencesImpl(prefsFile, mode, null);
355                 sSharedPrefs.put(name, sp);
356                 needInitialLoad = true;
357             }
358         }
359 
360         synchronized (sp) {
361             if (needInitialLoad && sp.isLoaded()) {
362                 // lost the race to load; another thread handled it
363                 return sp;
364             }
365             File backup = makeBackupFile(prefsFile);
366             if (backup.exists()) {
367                 prefsFile.delete();
368                 backup.renameTo(prefsFile);
369             }
370 
371             // Debugging
372             if (prefsFile.exists() && !prefsFile.canRead()) {
373                 Log.w(TAG, "Attempt to read preferences file " + prefsFile + " without permission");
374             }
375 
376             Map map = null;
377             FileStatus stat = new FileStatus();
378             if (FileUtils.getFileStatus(prefsFile.getPath(), stat) && prefsFile.canRead()) {
379                 try {
380                     FileInputStream str = new FileInputStream(prefsFile);
381                     map = XmlUtils.readMapXml(str);
382                     str.close();
383                 } catch (org.xmlpull.v1.XmlPullParserException e) {
384                     Log.w(TAG, "getSharedPreferences", e);
385                 } catch (FileNotFoundException e) {
386                     Log.w(TAG, "getSharedPreferences", e);
387                 } catch (IOException e) {
388                     Log.w(TAG, "getSharedPreferences", e);
389                 }
390             }
391             sp.replace(map, stat);
392         }
393         return sp;
394     }
395 
getPreferencesDir()396     private File getPreferencesDir() {
397         synchronized (mSync) {
398             if (mPreferencesDir == null) {
399                 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
400             }
401             return mPreferencesDir;
402         }
403     }
404 
405     @Override
openFileInput(String name)406     public FileInputStream openFileInput(String name)
407         throws FileNotFoundException {
408         File f = makeFilename(getFilesDir(), name);
409         return new FileInputStream(f);
410     }
411 
412     @Override
openFileOutput(String name, int mode)413     public FileOutputStream openFileOutput(String name, int mode)
414         throws FileNotFoundException {
415         final boolean append = (mode&MODE_APPEND) != 0;
416         File f = makeFilename(getFilesDir(), name);
417         try {
418             FileOutputStream fos = new FileOutputStream(f, append);
419             setFilePermissionsFromMode(f.getPath(), mode, 0);
420             return fos;
421         } catch (FileNotFoundException e) {
422         }
423 
424         File parent = f.getParentFile();
425         parent.mkdir();
426         FileUtils.setPermissions(
427             parent.getPath(),
428             FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
429             -1, -1);
430         FileOutputStream fos = new FileOutputStream(f, append);
431         setFilePermissionsFromMode(f.getPath(), mode, 0);
432         return fos;
433     }
434 
435     @Override
deleteFile(String name)436     public boolean deleteFile(String name) {
437         File f = makeFilename(getFilesDir(), name);
438         return f.delete();
439     }
440 
441     @Override
getFilesDir()442     public File getFilesDir() {
443         synchronized (mSync) {
444             if (mFilesDir == null) {
445                 mFilesDir = new File(getDataDirFile(), "files");
446             }
447             if (!mFilesDir.exists()) {
448                 if(!mFilesDir.mkdirs()) {
449                     Log.w(TAG, "Unable to create files directory");
450                     return null;
451                 }
452                 FileUtils.setPermissions(
453                         mFilesDir.getPath(),
454                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
455                         -1, -1);
456             }
457             return mFilesDir;
458         }
459     }
460 
461     @Override
getExternalFilesDir(String type)462     public File getExternalFilesDir(String type) {
463         synchronized (mSync) {
464             if (mExternalFilesDir == null) {
465                 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
466                         getPackageName());
467             }
468             if (!mExternalFilesDir.exists()) {
469                 try {
470                     (new File(Environment.getExternalStorageAndroidDataDir(),
471                             ".nomedia")).createNewFile();
472                 } catch (IOException e) {
473                 }
474                 if (!mExternalFilesDir.mkdirs()) {
475                     Log.w(TAG, "Unable to create external files directory");
476                     return null;
477                 }
478             }
479             if (type == null) {
480                 return mExternalFilesDir;
481             }
482             File dir = new File(mExternalFilesDir, type);
483             if (!dir.exists()) {
484                 if (!dir.mkdirs()) {
485                     Log.w(TAG, "Unable to create external media directory " + dir);
486                     return null;
487                 }
488             }
489             return dir;
490         }
491     }
492 
493     @Override
getCacheDir()494     public File getCacheDir() {
495         synchronized (mSync) {
496             if (mCacheDir == null) {
497                 mCacheDir = new File(getDataDirFile(), "cache");
498             }
499             if (!mCacheDir.exists()) {
500                 if(!mCacheDir.mkdirs()) {
501                     Log.w(TAG, "Unable to create cache directory");
502                     return null;
503                 }
504                 FileUtils.setPermissions(
505                         mCacheDir.getPath(),
506                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
507                         -1, -1);
508             }
509         }
510         return mCacheDir;
511     }
512 
513     @Override
getExternalCacheDir()514     public File getExternalCacheDir() {
515         synchronized (mSync) {
516             if (mExternalCacheDir == null) {
517                 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
518                         getPackageName());
519             }
520             if (!mExternalCacheDir.exists()) {
521                 try {
522                     (new File(Environment.getExternalStorageAndroidDataDir(),
523                             ".nomedia")).createNewFile();
524                 } catch (IOException e) {
525                 }
526                 if (!mExternalCacheDir.mkdirs()) {
527                     Log.w(TAG, "Unable to create external cache directory");
528                     return null;
529                 }
530             }
531             return mExternalCacheDir;
532         }
533     }
534 
535     @Override
getFileStreamPath(String name)536     public File getFileStreamPath(String name) {
537         return makeFilename(getFilesDir(), name);
538     }
539 
540     @Override
fileList()541     public String[] fileList() {
542         final String[] list = getFilesDir().list();
543         return (list != null) ? list : EMPTY_FILE_LIST;
544     }
545 
546     @Override
openOrCreateDatabase(String name, int mode, CursorFactory factory)547     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
548         File f = validateFilePath(name, true);
549         SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
550         setFilePermissionsFromMode(f.getPath(), mode, 0);
551         return db;
552     }
553 
554     @Override
deleteDatabase(String name)555     public boolean deleteDatabase(String name) {
556         try {
557             File f = validateFilePath(name, false);
558             return f.delete();
559         } catch (Exception e) {
560         }
561         return false;
562     }
563 
564     @Override
getDatabasePath(String name)565     public File getDatabasePath(String name) {
566         return validateFilePath(name, false);
567     }
568 
569     @Override
databaseList()570     public String[] databaseList() {
571         final String[] list = getDatabasesDir().list();
572         return (list != null) ? list : EMPTY_FILE_LIST;
573     }
574 
575 
getDatabasesDir()576     private File getDatabasesDir() {
577         synchronized (mSync) {
578             if (mDatabasesDir == null) {
579                 mDatabasesDir = new File(getDataDirFile(), "databases");
580             }
581             if (mDatabasesDir.getPath().equals("databases")) {
582                 mDatabasesDir = new File("/data/system");
583             }
584             return mDatabasesDir;
585         }
586     }
587 
588     @Override
getWallpaper()589     public Drawable getWallpaper() {
590         return getWallpaperManager().getDrawable();
591     }
592 
593     @Override
peekWallpaper()594     public Drawable peekWallpaper() {
595         return getWallpaperManager().peekDrawable();
596     }
597 
598     @Override
getWallpaperDesiredMinimumWidth()599     public int getWallpaperDesiredMinimumWidth() {
600         return getWallpaperManager().getDesiredMinimumWidth();
601     }
602 
603     @Override
getWallpaperDesiredMinimumHeight()604     public int getWallpaperDesiredMinimumHeight() {
605         return getWallpaperManager().getDesiredMinimumHeight();
606     }
607 
608     @Override
setWallpaper(Bitmap bitmap)609     public void setWallpaper(Bitmap bitmap) throws IOException  {
610         getWallpaperManager().setBitmap(bitmap);
611     }
612 
613     @Override
setWallpaper(InputStream data)614     public void setWallpaper(InputStream data) throws IOException {
615         getWallpaperManager().setStream(data);
616     }
617 
618     @Override
clearWallpaper()619     public void clearWallpaper() throws IOException {
620         getWallpaperManager().clear();
621     }
622 
623     @Override
startActivity(Intent intent)624     public void startActivity(Intent intent) {
625         if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
626             throw new AndroidRuntimeException(
627                     "Calling startActivity() from outside of an Activity "
628                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
629                     + " Is this really what you want?");
630         }
631         mMainThread.getInstrumentation().execStartActivity(
632             getOuterContext(), mMainThread.getApplicationThread(), null, null, intent, -1);
633     }
634 
635     @Override
startIntentSender(IntentSender intent, Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)636     public void startIntentSender(IntentSender intent,
637             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
638             throws IntentSender.SendIntentException {
639         try {
640             String resolvedType = null;
641             if (fillInIntent != null) {
642                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
643             }
644             int result = ActivityManagerNative.getDefault()
645                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
646                         fillInIntent, resolvedType, null, null,
647                         0, flagsMask, flagsValues);
648             if (result == IActivityManager.START_CANCELED) {
649                 throw new IntentSender.SendIntentException();
650             }
651             Instrumentation.checkStartActivityResult(result, null);
652         } catch (RemoteException e) {
653         }
654     }
655 
656     @Override
sendBroadcast(Intent intent)657     public void sendBroadcast(Intent intent) {
658         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
659         try {
660             ActivityManagerNative.getDefault().broadcastIntent(
661                 mMainThread.getApplicationThread(), intent, resolvedType, null,
662                 Activity.RESULT_OK, null, null, null, false, false);
663         } catch (RemoteException e) {
664         }
665     }
666 
667     @Override
sendBroadcast(Intent intent, String receiverPermission)668     public void sendBroadcast(Intent intent, String receiverPermission) {
669         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
670         try {
671             ActivityManagerNative.getDefault().broadcastIntent(
672                 mMainThread.getApplicationThread(), intent, resolvedType, null,
673                 Activity.RESULT_OK, null, null, receiverPermission, false, false);
674         } catch (RemoteException e) {
675         }
676     }
677 
678     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission)679     public void sendOrderedBroadcast(Intent intent,
680             String receiverPermission) {
681         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
682         try {
683             ActivityManagerNative.getDefault().broadcastIntent(
684                 mMainThread.getApplicationThread(), intent, resolvedType, null,
685                 Activity.RESULT_OK, null, null, receiverPermission, true, false);
686         } catch (RemoteException e) {
687         }
688     }
689 
690     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)691     public void sendOrderedBroadcast(Intent intent,
692             String receiverPermission, BroadcastReceiver resultReceiver,
693             Handler scheduler, int initialCode, String initialData,
694             Bundle initialExtras) {
695         IIntentReceiver rd = null;
696         if (resultReceiver != null) {
697             if (mPackageInfo != null) {
698                 if (scheduler == null) {
699                     scheduler = mMainThread.getHandler();
700                 }
701                 rd = mPackageInfo.getReceiverDispatcher(
702                     resultReceiver, getOuterContext(), scheduler,
703                     mMainThread.getInstrumentation(), false);
704             } else {
705                 if (scheduler == null) {
706                     scheduler = mMainThread.getHandler();
707                 }
708                 rd = new LoadedApk.ReceiverDispatcher(
709                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
710             }
711         }
712         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
713         try {
714             ActivityManagerNative.getDefault().broadcastIntent(
715                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
716                 initialCode, initialData, initialExtras, receiverPermission,
717                 true, false);
718         } catch (RemoteException e) {
719         }
720     }
721 
722     @Override
sendStickyBroadcast(Intent intent)723     public void sendStickyBroadcast(Intent intent) {
724         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
725         try {
726             ActivityManagerNative.getDefault().broadcastIntent(
727                 mMainThread.getApplicationThread(), intent, resolvedType, null,
728                 Activity.RESULT_OK, null, null, null, false, true);
729         } catch (RemoteException e) {
730         }
731     }
732 
733     @Override
sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)734     public void sendStickyOrderedBroadcast(Intent intent,
735             BroadcastReceiver resultReceiver,
736             Handler scheduler, int initialCode, String initialData,
737             Bundle initialExtras) {
738         IIntentReceiver rd = null;
739         if (resultReceiver != null) {
740             if (mPackageInfo != null) {
741                 if (scheduler == null) {
742                     scheduler = mMainThread.getHandler();
743                 }
744                 rd = mPackageInfo.getReceiverDispatcher(
745                     resultReceiver, getOuterContext(), scheduler,
746                     mMainThread.getInstrumentation(), false);
747             } else {
748                 if (scheduler == null) {
749                     scheduler = mMainThread.getHandler();
750                 }
751                 rd = new LoadedApk.ReceiverDispatcher(
752                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
753             }
754         }
755         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
756         try {
757             ActivityManagerNative.getDefault().broadcastIntent(
758                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
759                 initialCode, initialData, initialExtras, null,
760                 true, true);
761         } catch (RemoteException e) {
762         }
763     }
764 
765     @Override
removeStickyBroadcast(Intent intent)766     public void removeStickyBroadcast(Intent intent) {
767         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
768         if (resolvedType != null) {
769             intent = new Intent(intent);
770             intent.setDataAndType(intent.getData(), resolvedType);
771         }
772         try {
773             ActivityManagerNative.getDefault().unbroadcastIntent(
774                 mMainThread.getApplicationThread(), intent);
775         } catch (RemoteException e) {
776         }
777     }
778 
779     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)780     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
781         return registerReceiver(receiver, filter, null, null);
782     }
783 
784     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)785     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
786             String broadcastPermission, Handler scheduler) {
787         return registerReceiverInternal(receiver, filter, broadcastPermission,
788                 scheduler, getOuterContext());
789     }
790 
registerReceiverInternal(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler, Context context)791     private Intent registerReceiverInternal(BroadcastReceiver receiver,
792             IntentFilter filter, String broadcastPermission,
793             Handler scheduler, Context context) {
794         IIntentReceiver rd = null;
795         if (receiver != null) {
796             if (mPackageInfo != null && context != null) {
797                 if (scheduler == null) {
798                     scheduler = mMainThread.getHandler();
799                 }
800                 rd = mPackageInfo.getReceiverDispatcher(
801                     receiver, context, scheduler,
802                     mMainThread.getInstrumentation(), true);
803             } else {
804                 if (scheduler == null) {
805                     scheduler = mMainThread.getHandler();
806                 }
807                 rd = new LoadedApk.ReceiverDispatcher(
808                         receiver, context, scheduler, null, true).getIIntentReceiver();
809             }
810         }
811         try {
812             return ActivityManagerNative.getDefault().registerReceiver(
813                     mMainThread.getApplicationThread(),
814                     rd, filter, broadcastPermission);
815         } catch (RemoteException e) {
816             return null;
817         }
818     }
819 
820     @Override
unregisterReceiver(BroadcastReceiver receiver)821     public void unregisterReceiver(BroadcastReceiver receiver) {
822         if (mPackageInfo != null) {
823             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
824                     getOuterContext(), receiver);
825             try {
826                 ActivityManagerNative.getDefault().unregisterReceiver(rd);
827             } catch (RemoteException e) {
828             }
829         } else {
830             throw new RuntimeException("Not supported in system context");
831         }
832     }
833 
834     @Override
startService(Intent service)835     public ComponentName startService(Intent service) {
836         try {
837             ComponentName cn = ActivityManagerNative.getDefault().startService(
838                 mMainThread.getApplicationThread(), service,
839                 service.resolveTypeIfNeeded(getContentResolver()));
840             if (cn != null && cn.getPackageName().equals("!")) {
841                 throw new SecurityException(
842                         "Not allowed to start service " + service
843                         + " without permission " + cn.getClassName());
844             }
845             return cn;
846         } catch (RemoteException e) {
847             return null;
848         }
849     }
850 
851     @Override
stopService(Intent service)852     public boolean stopService(Intent service) {
853         try {
854             int res = ActivityManagerNative.getDefault().stopService(
855                 mMainThread.getApplicationThread(), service,
856                 service.resolveTypeIfNeeded(getContentResolver()));
857             if (res < 0) {
858                 throw new SecurityException(
859                         "Not allowed to stop service " + service);
860             }
861             return res != 0;
862         } catch (RemoteException e) {
863             return false;
864         }
865     }
866 
867     @Override
bindService(Intent service, ServiceConnection conn, int flags)868     public boolean bindService(Intent service, ServiceConnection conn,
869             int flags) {
870         IServiceConnection sd;
871         if (mPackageInfo != null) {
872             sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
873                     mMainThread.getHandler(), flags);
874         } else {
875             throw new RuntimeException("Not supported in system context");
876         }
877         try {
878             int res = ActivityManagerNative.getDefault().bindService(
879                 mMainThread.getApplicationThread(), getActivityToken(),
880                 service, service.resolveTypeIfNeeded(getContentResolver()),
881                 sd, flags);
882             if (res < 0) {
883                 throw new SecurityException(
884                         "Not allowed to bind to service " + service);
885             }
886             return res != 0;
887         } catch (RemoteException e) {
888             return false;
889         }
890     }
891 
892     @Override
unbindService(ServiceConnection conn)893     public void unbindService(ServiceConnection conn) {
894         if (mPackageInfo != null) {
895             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
896                     getOuterContext(), conn);
897             try {
898                 ActivityManagerNative.getDefault().unbindService(sd);
899             } catch (RemoteException e) {
900             }
901         } else {
902             throw new RuntimeException("Not supported in system context");
903         }
904     }
905 
906     @Override
startInstrumentation(ComponentName className, String profileFile, Bundle arguments)907     public boolean startInstrumentation(ComponentName className,
908             String profileFile, Bundle arguments) {
909         try {
910             return ActivityManagerNative.getDefault().startInstrumentation(
911                     className, profileFile, 0, arguments, null);
912         } catch (RemoteException e) {
913             // System has crashed, nothing we can do.
914         }
915         return false;
916     }
917 
918     @Override
getSystemService(String name)919     public Object getSystemService(String name) {
920         if (WINDOW_SERVICE.equals(name)) {
921             return WindowManagerImpl.getDefault();
922         } else if (LAYOUT_INFLATER_SERVICE.equals(name)) {
923             synchronized (mSync) {
924                 LayoutInflater inflater = mLayoutInflater;
925                 if (inflater != null) {
926                     return inflater;
927                 }
928                 mLayoutInflater = inflater =
929                     PolicyManager.makeNewLayoutInflater(getOuterContext());
930                 return inflater;
931             }
932         } else if (ACTIVITY_SERVICE.equals(name)) {
933             return getActivityManager();
934         } else if (INPUT_METHOD_SERVICE.equals(name)) {
935             return InputMethodManager.getInstance(this);
936         } else if (ALARM_SERVICE.equals(name)) {
937             return getAlarmManager();
938         } else if (ACCOUNT_SERVICE.equals(name)) {
939             return getAccountManager();
940         } else if (POWER_SERVICE.equals(name)) {
941             return getPowerManager();
942         } else if (CONNECTIVITY_SERVICE.equals(name)) {
943             return getConnectivityManager();
944         } else if (THROTTLE_SERVICE.equals(name)) {
945             return getThrottleManager();
946         } else if (WIFI_SERVICE.equals(name)) {
947             return getWifiManager();
948         } else if (NOTIFICATION_SERVICE.equals(name)) {
949             return getNotificationManager();
950         } else if (KEYGUARD_SERVICE.equals(name)) {
951             return new KeyguardManager();
952         } else if (ACCESSIBILITY_SERVICE.equals(name)) {
953             return AccessibilityManager.getInstance(this);
954         } else if (LOCATION_SERVICE.equals(name)) {
955             return getLocationManager();
956         } else if (SEARCH_SERVICE.equals(name)) {
957             return getSearchManager();
958         } else if (SENSOR_SERVICE.equals(name)) {
959             return getSensorManager();
960         } else if (STORAGE_SERVICE.equals(name)) {
961             return getStorageManager();
962         } else if (USB_SERVICE.equals(name)) {
963             return getUsbManager();
964         } else if (VIBRATOR_SERVICE.equals(name)) {
965             return getVibrator();
966         } else if (STATUS_BAR_SERVICE.equals(name)) {
967             synchronized (mSync) {
968                 if (mStatusBarManager == null) {
969                     mStatusBarManager = new StatusBarManager(getOuterContext());
970                 }
971                 return mStatusBarManager;
972             }
973         } else if (AUDIO_SERVICE.equals(name)) {
974             return getAudioManager();
975         } else if (TELEPHONY_SERVICE.equals(name)) {
976             return getTelephonyManager();
977         } else if (CLIPBOARD_SERVICE.equals(name)) {
978             return getClipboardManager();
979         } else if (WALLPAPER_SERVICE.equals(name)) {
980             return getWallpaperManager();
981         } else if (DROPBOX_SERVICE.equals(name)) {
982             return getDropBoxManager();
983         } else if (DEVICE_POLICY_SERVICE.equals(name)) {
984             return getDevicePolicyManager();
985         } else if (UI_MODE_SERVICE.equals(name)) {
986             return getUiModeManager();
987         } else if (DOWNLOAD_SERVICE.equals(name)) {
988             return getDownloadManager();
989         } else if (NFC_SERVICE.equals(name)) {
990             return getNfcManager();
991         }
992 
993         return null;
994     }
995 
getAccountManager()996     private AccountManager getAccountManager() {
997         synchronized (mSync) {
998             if (mAccountManager == null) {
999                 IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
1000                 IAccountManager service = IAccountManager.Stub.asInterface(b);
1001                 mAccountManager = new AccountManager(this, service);
1002             }
1003             return mAccountManager;
1004         }
1005     }
1006 
getActivityManager()1007     private ActivityManager getActivityManager() {
1008         synchronized (mSync) {
1009             if (mActivityManager == null) {
1010                 mActivityManager = new ActivityManager(getOuterContext(),
1011                         mMainThread.getHandler());
1012             }
1013         }
1014         return mActivityManager;
1015     }
1016 
getAlarmManager()1017     private AlarmManager getAlarmManager() {
1018         synchronized (sSync) {
1019             if (sAlarmManager == null) {
1020                 IBinder b = ServiceManager.getService(ALARM_SERVICE);
1021                 IAlarmManager service = IAlarmManager.Stub.asInterface(b);
1022                 sAlarmManager = new AlarmManager(service);
1023             }
1024         }
1025         return sAlarmManager;
1026     }
1027 
getPowerManager()1028     private PowerManager getPowerManager() {
1029         synchronized (sSync) {
1030             if (sPowerManager == null) {
1031                 IBinder b = ServiceManager.getService(POWER_SERVICE);
1032                 IPowerManager service = IPowerManager.Stub.asInterface(b);
1033                 sPowerManager = new PowerManager(service, mMainThread.getHandler());
1034             }
1035         }
1036         return sPowerManager;
1037     }
1038 
getConnectivityManager()1039     private ConnectivityManager getConnectivityManager()
1040     {
1041         synchronized (sSync) {
1042             if (sConnectivityManager == null) {
1043                 IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
1044                 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
1045                 sConnectivityManager = new ConnectivityManager(service);
1046             }
1047         }
1048         return sConnectivityManager;
1049     }
1050 
getThrottleManager()1051     private ThrottleManager getThrottleManager()
1052     {
1053         synchronized (sSync) {
1054             if (sThrottleManager == null) {
1055                 IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
1056                 IThrottleManager service = IThrottleManager.Stub.asInterface(b);
1057                 sThrottleManager = new ThrottleManager(service);
1058             }
1059         }
1060         return sThrottleManager;
1061     }
1062 
getWifiManager()1063     private WifiManager getWifiManager()
1064     {
1065         synchronized (sSync) {
1066             if (sWifiManager == null) {
1067                 IBinder b = ServiceManager.getService(WIFI_SERVICE);
1068                 IWifiManager service = IWifiManager.Stub.asInterface(b);
1069                 sWifiManager = new WifiManager(service, mMainThread.getHandler());
1070             }
1071         }
1072         return sWifiManager;
1073     }
1074 
getNotificationManager()1075     private NotificationManager getNotificationManager() {
1076         synchronized (mSync) {
1077             if (mNotificationManager == null) {
1078                 mNotificationManager = new NotificationManager(
1079                         new ContextThemeWrapper(getOuterContext(), com.android.internal.R.style.Theme_Dialog),
1080                         mMainThread.getHandler());
1081             }
1082         }
1083         return mNotificationManager;
1084     }
1085 
getWallpaperManager()1086     private WallpaperManager getWallpaperManager() {
1087         synchronized (mSync) {
1088             if (mWallpaperManager == null) {
1089                 mWallpaperManager = new WallpaperManager(getOuterContext(),
1090                         mMainThread.getHandler());
1091             }
1092         }
1093         return mWallpaperManager;
1094     }
1095 
getTelephonyManager()1096     private TelephonyManager getTelephonyManager() {
1097         synchronized (mSync) {
1098             if (mTelephonyManager == null) {
1099                 mTelephonyManager = new TelephonyManager(getOuterContext());
1100             }
1101         }
1102         return mTelephonyManager;
1103     }
1104 
getClipboardManager()1105     private ClipboardManager getClipboardManager() {
1106         synchronized (mSync) {
1107             if (mClipboardManager == null) {
1108                 mClipboardManager = new ClipboardManager(getOuterContext(),
1109                         mMainThread.getHandler());
1110             }
1111         }
1112         return mClipboardManager;
1113     }
1114 
getLocationManager()1115     private LocationManager getLocationManager() {
1116         synchronized (sSync) {
1117             if (sLocationManager == null) {
1118                 IBinder b = ServiceManager.getService(LOCATION_SERVICE);
1119                 ILocationManager service = ILocationManager.Stub.asInterface(b);
1120                 sLocationManager = new LocationManager(service);
1121             }
1122         }
1123         return sLocationManager;
1124     }
1125 
getSearchManager()1126     private SearchManager getSearchManager() {
1127         synchronized (mSync) {
1128             if (mSearchManager == null) {
1129                 mSearchManager = new SearchManager(getOuterContext(), mMainThread.getHandler());
1130             }
1131         }
1132         return mSearchManager;
1133     }
1134 
getSensorManager()1135     private SensorManager getSensorManager() {
1136         synchronized (mSync) {
1137             if (mSensorManager == null) {
1138                 mSensorManager = new SensorManager(mMainThread.getHandler().getLooper());
1139             }
1140         }
1141         return mSensorManager;
1142     }
1143 
getStorageManager()1144     private StorageManager getStorageManager() {
1145         synchronized (mSync) {
1146             if (mStorageManager == null) {
1147                 try {
1148                     mStorageManager = new StorageManager(mMainThread.getHandler().getLooper());
1149                 } catch (RemoteException rex) {
1150                     Log.e(TAG, "Failed to create StorageManager", rex);
1151                     mStorageManager = null;
1152                 }
1153             }
1154         }
1155         return mStorageManager;
1156     }
1157 
getUsbManager()1158     private UsbManager getUsbManager() {
1159         synchronized (mSync) {
1160             if (mUsbManager == null) {
1161                 IBinder b = ServiceManager.getService(USB_SERVICE);
1162                 IUsbManager service = IUsbManager.Stub.asInterface(b);
1163                 mUsbManager = new UsbManager(this, service);
1164             }
1165         }
1166         return mUsbManager;
1167     }
1168 
getVibrator()1169     private Vibrator getVibrator() {
1170         synchronized (mSync) {
1171             if (mVibrator == null) {
1172                 mVibrator = new Vibrator();
1173             }
1174         }
1175         return mVibrator;
1176     }
1177 
getAudioManager()1178     private AudioManager getAudioManager()
1179     {
1180         if (mAudioManager == null) {
1181             mAudioManager = new AudioManager(this);
1182         }
1183         return mAudioManager;
1184     }
1185 
createDropBoxManager()1186     /* package */ static DropBoxManager createDropBoxManager() {
1187         IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1188         IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1189         return new DropBoxManager(service);
1190     }
1191 
getDropBoxManager()1192     private DropBoxManager getDropBoxManager() {
1193         synchronized (mSync) {
1194             if (mDropBoxManager == null) {
1195                 mDropBoxManager = createDropBoxManager();
1196             }
1197         }
1198         return mDropBoxManager;
1199     }
1200 
getDevicePolicyManager()1201     private DevicePolicyManager getDevicePolicyManager() {
1202         synchronized (mSync) {
1203             if (mDevicePolicyManager == null) {
1204                 mDevicePolicyManager = DevicePolicyManager.create(this,
1205                         mMainThread.getHandler());
1206             }
1207         }
1208         return mDevicePolicyManager;
1209     }
1210 
getUiModeManager()1211     private UiModeManager getUiModeManager() {
1212         synchronized (mSync) {
1213             if (mUiModeManager == null) {
1214                 mUiModeManager = new UiModeManager();
1215             }
1216         }
1217         return mUiModeManager;
1218     }
1219 
getDownloadManager()1220     private DownloadManager getDownloadManager() {
1221         synchronized (mSync) {
1222             if (mDownloadManager == null) {
1223                 mDownloadManager = new DownloadManager(getContentResolver(), getPackageName());
1224             }
1225         }
1226         return mDownloadManager;
1227     }
1228 
getNfcManager()1229     private NfcManager getNfcManager() {
1230         synchronized (mSync) {
1231             if (mNfcManager == null) {
1232                 mNfcManager = new NfcManager(this);
1233             }
1234         }
1235         return mNfcManager;
1236     }
1237 
1238     @Override
checkPermission(String permission, int pid, int uid)1239     public int checkPermission(String permission, int pid, int uid) {
1240         if (permission == null) {
1241             throw new IllegalArgumentException("permission is null");
1242         }
1243 
1244         if (!Process.supportsProcesses()) {
1245             return PackageManager.PERMISSION_GRANTED;
1246         }
1247         try {
1248             return ActivityManagerNative.getDefault().checkPermission(
1249                     permission, pid, uid);
1250         } catch (RemoteException e) {
1251             return PackageManager.PERMISSION_DENIED;
1252         }
1253     }
1254 
1255     @Override
checkCallingPermission(String permission)1256     public int checkCallingPermission(String permission) {
1257         if (permission == null) {
1258             throw new IllegalArgumentException("permission is null");
1259         }
1260 
1261         if (!Process.supportsProcesses()) {
1262             return PackageManager.PERMISSION_GRANTED;
1263         }
1264         int pid = Binder.getCallingPid();
1265         if (pid != Process.myPid()) {
1266             return checkPermission(permission, pid,
1267                     Binder.getCallingUid());
1268         }
1269         return PackageManager.PERMISSION_DENIED;
1270     }
1271 
1272     @Override
checkCallingOrSelfPermission(String permission)1273     public int checkCallingOrSelfPermission(String permission) {
1274         if (permission == null) {
1275             throw new IllegalArgumentException("permission is null");
1276         }
1277 
1278         return checkPermission(permission, Binder.getCallingPid(),
1279                 Binder.getCallingUid());
1280     }
1281 
enforce( String permission, int resultOfCheck, boolean selfToo, int uid, String message)1282     private void enforce(
1283             String permission, int resultOfCheck,
1284             boolean selfToo, int uid, String message) {
1285         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1286             throw new SecurityException(
1287                     (message != null ? (message + ": ") : "") +
1288                     (selfToo
1289                      ? "Neither user " + uid + " nor current process has "
1290                      : "User " + uid + " does not have ") +
1291                     permission +
1292                     ".");
1293         }
1294     }
1295 
enforcePermission( String permission, int pid, int uid, String message)1296     public void enforcePermission(
1297             String permission, int pid, int uid, String message) {
1298         enforce(permission,
1299                 checkPermission(permission, pid, uid),
1300                 false,
1301                 uid,
1302                 message);
1303     }
1304 
enforceCallingPermission(String permission, String message)1305     public void enforceCallingPermission(String permission, String message) {
1306         enforce(permission,
1307                 checkCallingPermission(permission),
1308                 false,
1309                 Binder.getCallingUid(),
1310                 message);
1311     }
1312 
enforceCallingOrSelfPermission( String permission, String message)1313     public void enforceCallingOrSelfPermission(
1314             String permission, String message) {
1315         enforce(permission,
1316                 checkCallingOrSelfPermission(permission),
1317                 true,
1318                 Binder.getCallingUid(),
1319                 message);
1320     }
1321 
1322     @Override
grantUriPermission(String toPackage, Uri uri, int modeFlags)1323     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1324          try {
1325             ActivityManagerNative.getDefault().grantUriPermission(
1326                     mMainThread.getApplicationThread(), toPackage, uri,
1327                     modeFlags);
1328         } catch (RemoteException e) {
1329         }
1330     }
1331 
1332     @Override
revokeUriPermission(Uri uri, int modeFlags)1333     public void revokeUriPermission(Uri uri, int modeFlags) {
1334          try {
1335             ActivityManagerNative.getDefault().revokeUriPermission(
1336                     mMainThread.getApplicationThread(), uri,
1337                     modeFlags);
1338         } catch (RemoteException e) {
1339         }
1340     }
1341 
1342     @Override
checkUriPermission(Uri uri, int pid, int uid, int modeFlags)1343     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1344         if (!Process.supportsProcesses()) {
1345             return PackageManager.PERMISSION_GRANTED;
1346         }
1347         try {
1348             return ActivityManagerNative.getDefault().checkUriPermission(
1349                     uri, pid, uid, modeFlags);
1350         } catch (RemoteException e) {
1351             return PackageManager.PERMISSION_DENIED;
1352         }
1353     }
1354 
1355     @Override
checkCallingUriPermission(Uri uri, int modeFlags)1356     public int checkCallingUriPermission(Uri uri, int modeFlags) {
1357         if (!Process.supportsProcesses()) {
1358             return PackageManager.PERMISSION_GRANTED;
1359         }
1360         int pid = Binder.getCallingPid();
1361         if (pid != Process.myPid()) {
1362             return checkUriPermission(uri, pid,
1363                     Binder.getCallingUid(), modeFlags);
1364         }
1365         return PackageManager.PERMISSION_DENIED;
1366     }
1367 
1368     @Override
checkCallingOrSelfUriPermission(Uri uri, int modeFlags)1369     public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1370         return checkUriPermission(uri, Binder.getCallingPid(),
1371                 Binder.getCallingUid(), modeFlags);
1372     }
1373 
1374     @Override
checkUriPermission(Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags)1375     public int checkUriPermission(Uri uri, String readPermission,
1376             String writePermission, int pid, int uid, int modeFlags) {
1377         if (DEBUG) {
1378             Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1379                     + readPermission + " writePermission=" + writePermission
1380                     + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1381         }
1382         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1383             if (readPermission == null
1384                     || checkPermission(readPermission, pid, uid)
1385                     == PackageManager.PERMISSION_GRANTED) {
1386                 return PackageManager.PERMISSION_GRANTED;
1387             }
1388         }
1389         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1390             if (writePermission == null
1391                     || checkPermission(writePermission, pid, uid)
1392                     == PackageManager.PERMISSION_GRANTED) {
1393                 return PackageManager.PERMISSION_GRANTED;
1394             }
1395         }
1396         return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1397                 : PackageManager.PERMISSION_DENIED;
1398     }
1399 
uriModeFlagToString(int uriModeFlags)1400     private String uriModeFlagToString(int uriModeFlags) {
1401         switch (uriModeFlags) {
1402             case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1403                     Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1404                 return "read and write";
1405             case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1406                 return "read";
1407             case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1408                 return "write";
1409         }
1410         throw new IllegalArgumentException(
1411                 "Unknown permission mode flags: " + uriModeFlags);
1412     }
1413 
enforceForUri( int modeFlags, int resultOfCheck, boolean selfToo, int uid, Uri uri, String message)1414     private void enforceForUri(
1415             int modeFlags, int resultOfCheck, boolean selfToo,
1416             int uid, Uri uri, String message) {
1417         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1418             throw new SecurityException(
1419                     (message != null ? (message + ": ") : "") +
1420                     (selfToo
1421                      ? "Neither user " + uid + " nor current process has "
1422                      : "User " + uid + " does not have ") +
1423                     uriModeFlagToString(modeFlags) +
1424                     " permission on " +
1425                     uri +
1426                     ".");
1427         }
1428     }
1429 
enforceUriPermission( Uri uri, int pid, int uid, int modeFlags, String message)1430     public void enforceUriPermission(
1431             Uri uri, int pid, int uid, int modeFlags, String message) {
1432         enforceForUri(
1433                 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1434                 false, uid, uri, message);
1435     }
1436 
enforceCallingUriPermission( Uri uri, int modeFlags, String message)1437     public void enforceCallingUriPermission(
1438             Uri uri, int modeFlags, String message) {
1439         enforceForUri(
1440                 modeFlags, checkCallingUriPermission(uri, modeFlags),
1441                 false, Binder.getCallingUid(), uri, message);
1442     }
1443 
enforceCallingOrSelfUriPermission( Uri uri, int modeFlags, String message)1444     public void enforceCallingOrSelfUriPermission(
1445             Uri uri, int modeFlags, String message) {
1446         enforceForUri(
1447                 modeFlags,
1448                 checkCallingOrSelfUriPermission(uri, modeFlags), true,
1449                 Binder.getCallingUid(), uri, message);
1450     }
1451 
enforceUriPermission( Uri uri, String readPermission, String writePermission, int pid, int uid, int modeFlags, String message)1452     public void enforceUriPermission(
1453             Uri uri, String readPermission, String writePermission,
1454             int pid, int uid, int modeFlags, String message) {
1455         enforceForUri(modeFlags,
1456                       checkUriPermission(
1457                               uri, readPermission, writePermission, pid, uid,
1458                               modeFlags),
1459                       false,
1460                       uid,
1461                       uri,
1462                       message);
1463     }
1464 
1465     @Override
createPackageContext(String packageName, int flags)1466     public Context createPackageContext(String packageName, int flags)
1467         throws PackageManager.NameNotFoundException {
1468         if (packageName.equals("system") || packageName.equals("android")) {
1469             return new ContextImpl(mMainThread.getSystemContext());
1470         }
1471 
1472         LoadedApk pi =
1473             mMainThread.getPackageInfo(packageName, flags);
1474         if (pi != null) {
1475             ContextImpl c = new ContextImpl();
1476             c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1477             c.init(pi, null, mMainThread, mResources);
1478             if (c.mResources != null) {
1479                 return c;
1480             }
1481         }
1482 
1483         // Should be a better exception.
1484         throw new PackageManager.NameNotFoundException(
1485             "Application package " + packageName + " not found");
1486     }
1487 
1488     @Override
isRestricted()1489     public boolean isRestricted() {
1490         return mRestricted;
1491     }
1492 
getDataDirFile()1493     private File getDataDirFile() {
1494         if (mPackageInfo != null) {
1495             return mPackageInfo.getDataDirFile();
1496         }
1497         throw new RuntimeException("Not supported in system context");
1498     }
1499 
1500     @Override
getDir(String name, int mode)1501     public File getDir(String name, int mode) {
1502         name = "app_" + name;
1503         File file = makeFilename(getDataDirFile(), name);
1504         if (!file.exists()) {
1505             file.mkdir();
1506             setFilePermissionsFromMode(file.getPath(), mode,
1507                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1508         }
1509         return file;
1510     }
1511 
createSystemContext(ActivityThread mainThread)1512     static ContextImpl createSystemContext(ActivityThread mainThread) {
1513         ContextImpl context = new ContextImpl();
1514         context.init(Resources.getSystem(), mainThread);
1515         return context;
1516     }
1517 
ContextImpl()1518     ContextImpl() {
1519         // For debug only
1520         //++sInstanceCount;
1521         mOuterContext = this;
1522     }
1523 
1524     /**
1525      * Create a new ApplicationContext from an existing one.  The new one
1526      * works and operates the same as the one it is copying.
1527      *
1528      * @param context Existing application context.
1529      */
ContextImpl(ContextImpl context)1530     public ContextImpl(ContextImpl context) {
1531         ++sInstanceCount;
1532         mPackageInfo = context.mPackageInfo;
1533         mResources = context.mResources;
1534         mMainThread = context.mMainThread;
1535         mContentResolver = context.mContentResolver;
1536         mOuterContext = this;
1537     }
1538 
init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread)1539     final void init(LoadedApk packageInfo,
1540             IBinder activityToken, ActivityThread mainThread) {
1541         init(packageInfo, activityToken, mainThread, null);
1542     }
1543 
init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread, Resources container)1544     final void init(LoadedApk packageInfo,
1545                 IBinder activityToken, ActivityThread mainThread,
1546                 Resources container) {
1547         mPackageInfo = packageInfo;
1548         mResources = mPackageInfo.getResources(mainThread);
1549 
1550         if (mResources != null && container != null
1551                 && container.getCompatibilityInfo().applicationScale !=
1552                         mResources.getCompatibilityInfo().applicationScale) {
1553             if (DEBUG) {
1554                 Log.d(TAG, "loaded context has different scaling. Using container's" +
1555                         " compatiblity info:" + container.getDisplayMetrics());
1556             }
1557             mResources = mainThread.getTopLevelResources(
1558                     mPackageInfo.getResDir(), container.getCompatibilityInfo().copy());
1559         }
1560         mMainThread = mainThread;
1561         mContentResolver = new ApplicationContentResolver(this, mainThread);
1562 
1563         setActivityToken(activityToken);
1564     }
1565 
init(Resources resources, ActivityThread mainThread)1566     final void init(Resources resources, ActivityThread mainThread) {
1567         mPackageInfo = null;
1568         mResources = resources;
1569         mMainThread = mainThread;
1570         mContentResolver = new ApplicationContentResolver(this, mainThread);
1571     }
1572 
scheduleFinalCleanup(String who, String what)1573     final void scheduleFinalCleanup(String who, String what) {
1574         mMainThread.scheduleContextCleanup(this, who, what);
1575     }
1576 
performFinalCleanup(String who, String what)1577     final void performFinalCleanup(String who, String what) {
1578         //Log.i(TAG, "Cleanup up context: " + this);
1579         mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
1580     }
1581 
getReceiverRestrictedContext()1582     final Context getReceiverRestrictedContext() {
1583         if (mReceiverRestrictedContext != null) {
1584             return mReceiverRestrictedContext;
1585         }
1586         return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
1587     }
1588 
setActivityToken(IBinder token)1589     final void setActivityToken(IBinder token) {
1590         mActivityToken = token;
1591     }
1592 
setOuterContext(Context context)1593     final void setOuterContext(Context context) {
1594         mOuterContext = context;
1595     }
1596 
getOuterContext()1597     final Context getOuterContext() {
1598         return mOuterContext;
1599     }
1600 
getActivityToken()1601     final IBinder getActivityToken() {
1602         return mActivityToken;
1603     }
1604 
setFilePermissionsFromMode(String name, int mode, int extraPermissions)1605     private static void setFilePermissionsFromMode(String name, int mode,
1606             int extraPermissions) {
1607         int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
1608             |FileUtils.S_IRGRP|FileUtils.S_IWGRP
1609             |extraPermissions;
1610         if ((mode&MODE_WORLD_READABLE) != 0) {
1611             perms |= FileUtils.S_IROTH;
1612         }
1613         if ((mode&MODE_WORLD_WRITEABLE) != 0) {
1614             perms |= FileUtils.S_IWOTH;
1615         }
1616         if (DEBUG) {
1617             Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
1618                   + ", perms=0x" + Integer.toHexString(perms));
1619         }
1620         FileUtils.setPermissions(name, perms, -1, -1);
1621     }
1622 
validateFilePath(String name, boolean createDirectory)1623     private File validateFilePath(String name, boolean createDirectory) {
1624         File dir;
1625         File f;
1626 
1627         if (name.charAt(0) == File.separatorChar) {
1628             String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
1629             dir = new File(dirPath);
1630             name = name.substring(name.lastIndexOf(File.separatorChar));
1631             f = new File(dir, name);
1632         } else {
1633             dir = getDatabasesDir();
1634             f = makeFilename(dir, name);
1635         }
1636 
1637         if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
1638             FileUtils.setPermissions(dir.getPath(),
1639                 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
1640                 -1, -1);
1641         }
1642 
1643         return f;
1644     }
1645 
makeFilename(File base, String name)1646     private File makeFilename(File base, String name) {
1647         if (name.indexOf(File.separatorChar) < 0) {
1648             return new File(base, name);
1649         }
1650         throw new IllegalArgumentException(
1651                 "File " + name + " contains a path separator");
1652     }
1653 
1654     // ----------------------------------------------------------------------
1655     // ----------------------------------------------------------------------
1656     // ----------------------------------------------------------------------
1657 
1658     private static final class ApplicationContentResolver extends ContentResolver {
ApplicationContentResolver(Context context, ActivityThread mainThread)1659         public ApplicationContentResolver(Context context, ActivityThread mainThread) {
1660             super(context);
1661             mMainThread = mainThread;
1662         }
1663 
1664         @Override
acquireProvider(Context context, String name)1665         protected IContentProvider acquireProvider(Context context, String name) {
1666             return mMainThread.acquireProvider(context, name);
1667         }
1668 
1669         @Override
acquireExistingProvider(Context context, String name)1670         protected IContentProvider acquireExistingProvider(Context context, String name) {
1671             return mMainThread.acquireExistingProvider(context, name);
1672         }
1673 
1674         @Override
releaseProvider(IContentProvider provider)1675         public boolean releaseProvider(IContentProvider provider) {
1676             return mMainThread.releaseProvider(provider);
1677         }
1678 
1679         private final ActivityThread mMainThread;
1680     }
1681 
1682     // ----------------------------------------------------------------------
1683     // ----------------------------------------------------------------------
1684     // ----------------------------------------------------------------------
1685 
1686     /*package*/
1687     static final class ApplicationPackageManager extends PackageManager {
1688         @Override
getPackageInfo(String packageName, int flags)1689         public PackageInfo getPackageInfo(String packageName, int flags)
1690                 throws NameNotFoundException {
1691             try {
1692                 PackageInfo pi = mPM.getPackageInfo(packageName, flags);
1693                 if (pi != null) {
1694                     return pi;
1695                 }
1696             } catch (RemoteException e) {
1697                 throw new RuntimeException("Package manager has died", e);
1698             }
1699 
1700             throw new NameNotFoundException(packageName);
1701         }
1702 
1703         @Override
currentToCanonicalPackageNames(String[] names)1704         public String[] currentToCanonicalPackageNames(String[] names) {
1705             try {
1706                 return mPM.currentToCanonicalPackageNames(names);
1707             } catch (RemoteException e) {
1708                 throw new RuntimeException("Package manager has died", e);
1709             }
1710         }
1711 
1712         @Override
canonicalToCurrentPackageNames(String[] names)1713         public String[] canonicalToCurrentPackageNames(String[] names) {
1714             try {
1715                 return mPM.canonicalToCurrentPackageNames(names);
1716             } catch (RemoteException e) {
1717                 throw new RuntimeException("Package manager has died", e);
1718             }
1719         }
1720 
1721         @Override
getLaunchIntentForPackage(String packageName)1722         public Intent getLaunchIntentForPackage(String packageName) {
1723             // First see if the package has an INFO activity; the existence of
1724             // such an activity is implied to be the desired front-door for the
1725             // overall package (such as if it has multiple launcher entries).
1726             Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
1727             intentToResolve.addCategory(Intent.CATEGORY_INFO);
1728             intentToResolve.setPackage(packageName);
1729             ResolveInfo resolveInfo = resolveActivity(intentToResolve, 0);
1730 
1731             // Otherwise, try to find a main launcher activity.
1732             if (resolveInfo == null) {
1733                 // reuse the intent instance
1734                 intentToResolve.removeCategory(Intent.CATEGORY_INFO);
1735                 intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
1736                 intentToResolve.setPackage(packageName);
1737                 resolveInfo = resolveActivity(intentToResolve, 0);
1738             }
1739             if (resolveInfo == null) {
1740                 return null;
1741             }
1742             Intent intent = new Intent(Intent.ACTION_MAIN);
1743             intent.setClassName(packageName, resolveInfo.activityInfo.name);
1744             intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1745             return intent;
1746         }
1747 
1748         @Override
getPackageGids(String packageName)1749         public int[] getPackageGids(String packageName)
1750             throws NameNotFoundException {
1751             try {
1752                 int[] gids = mPM.getPackageGids(packageName);
1753                 if (gids == null || gids.length > 0) {
1754                     return gids;
1755                 }
1756             } catch (RemoteException e) {
1757                 throw new RuntimeException("Package manager has died", e);
1758             }
1759 
1760             throw new NameNotFoundException(packageName);
1761         }
1762 
1763         @Override
getPermissionInfo(String name, int flags)1764         public PermissionInfo getPermissionInfo(String name, int flags)
1765             throws NameNotFoundException {
1766             try {
1767                 PermissionInfo pi = mPM.getPermissionInfo(name, flags);
1768                 if (pi != null) {
1769                     return pi;
1770                 }
1771             } catch (RemoteException e) {
1772                 throw new RuntimeException("Package manager has died", e);
1773             }
1774 
1775             throw new NameNotFoundException(name);
1776         }
1777 
1778         @Override
queryPermissionsByGroup(String group, int flags)1779         public List<PermissionInfo> queryPermissionsByGroup(String group, int flags)
1780                 throws NameNotFoundException {
1781             try {
1782                 List<PermissionInfo> pi = mPM.queryPermissionsByGroup(group, flags);
1783                 if (pi != null) {
1784                     return pi;
1785                 }
1786             } catch (RemoteException e) {
1787                 throw new RuntimeException("Package manager has died", e);
1788             }
1789 
1790             throw new NameNotFoundException(group);
1791         }
1792 
1793         @Override
getPermissionGroupInfo(String name, int flags)1794         public PermissionGroupInfo getPermissionGroupInfo(String name,
1795                 int flags) throws NameNotFoundException {
1796             try {
1797                 PermissionGroupInfo pgi = mPM.getPermissionGroupInfo(name, flags);
1798                 if (pgi != null) {
1799                     return pgi;
1800                 }
1801             } catch (RemoteException e) {
1802                 throw new RuntimeException("Package manager has died", e);
1803             }
1804 
1805             throw new NameNotFoundException(name);
1806         }
1807 
1808         @Override
getAllPermissionGroups(int flags)1809         public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
1810             try {
1811                 return mPM.getAllPermissionGroups(flags);
1812             } catch (RemoteException e) {
1813                 throw new RuntimeException("Package manager has died", e);
1814             }
1815         }
1816 
1817         @Override
getApplicationInfo(String packageName, int flags)1818         public ApplicationInfo getApplicationInfo(String packageName, int flags)
1819             throws NameNotFoundException {
1820             try {
1821                 ApplicationInfo ai = mPM.getApplicationInfo(packageName, flags);
1822                 if (ai != null) {
1823                     return ai;
1824                 }
1825             } catch (RemoteException e) {
1826                 throw new RuntimeException("Package manager has died", e);
1827             }
1828 
1829             throw new NameNotFoundException(packageName);
1830         }
1831 
1832         @Override
getActivityInfo(ComponentName className, int flags)1833         public ActivityInfo getActivityInfo(ComponentName className, int flags)
1834             throws NameNotFoundException {
1835             try {
1836                 ActivityInfo ai = mPM.getActivityInfo(className, flags);
1837                 if (ai != null) {
1838                     return ai;
1839                 }
1840             } catch (RemoteException e) {
1841                 throw new RuntimeException("Package manager has died", e);
1842             }
1843 
1844             throw new NameNotFoundException(className.toString());
1845         }
1846 
1847         @Override
getReceiverInfo(ComponentName className, int flags)1848         public ActivityInfo getReceiverInfo(ComponentName className, int flags)
1849             throws NameNotFoundException {
1850             try {
1851                 ActivityInfo ai = mPM.getReceiverInfo(className, flags);
1852                 if (ai != null) {
1853                     return ai;
1854                 }
1855             } catch (RemoteException e) {
1856                 throw new RuntimeException("Package manager has died", e);
1857             }
1858 
1859             throw new NameNotFoundException(className.toString());
1860         }
1861 
1862         @Override
getServiceInfo(ComponentName className, int flags)1863         public ServiceInfo getServiceInfo(ComponentName className, int flags)
1864             throws NameNotFoundException {
1865             try {
1866                 ServiceInfo si = mPM.getServiceInfo(className, flags);
1867                 if (si != null) {
1868                     return si;
1869                 }
1870             } catch (RemoteException e) {
1871                 throw new RuntimeException("Package manager has died", e);
1872             }
1873 
1874             throw new NameNotFoundException(className.toString());
1875         }
1876 
1877         @Override
getProviderInfo(ComponentName className, int flags)1878         public ProviderInfo getProviderInfo(ComponentName className, int flags)
1879             throws NameNotFoundException {
1880             try {
1881                 ProviderInfo pi = mPM.getProviderInfo(className, flags);
1882                 if (pi != null) {
1883                     return pi;
1884                 }
1885             } catch (RemoteException e) {
1886                 throw new RuntimeException("Package manager has died", e);
1887             }
1888 
1889             throw new NameNotFoundException(className.toString());
1890         }
1891 
1892         @Override
getSystemSharedLibraryNames()1893         public String[] getSystemSharedLibraryNames() {
1894              try {
1895                  return mPM.getSystemSharedLibraryNames();
1896              } catch (RemoteException e) {
1897                  throw new RuntimeException("Package manager has died", e);
1898              }
1899         }
1900 
1901         @Override
getSystemAvailableFeatures()1902         public FeatureInfo[] getSystemAvailableFeatures() {
1903             try {
1904                 return mPM.getSystemAvailableFeatures();
1905             } catch (RemoteException e) {
1906                 throw new RuntimeException("Package manager has died", e);
1907             }
1908         }
1909 
1910         @Override
hasSystemFeature(String name)1911         public boolean hasSystemFeature(String name) {
1912             try {
1913                 return mPM.hasSystemFeature(name);
1914             } catch (RemoteException e) {
1915                 throw new RuntimeException("Package manager has died", e);
1916             }
1917         }
1918 
1919         @Override
checkPermission(String permName, String pkgName)1920         public int checkPermission(String permName, String pkgName) {
1921             try {
1922                 return mPM.checkPermission(permName, pkgName);
1923             } catch (RemoteException e) {
1924                 throw new RuntimeException("Package manager has died", e);
1925             }
1926         }
1927 
1928         @Override
addPermission(PermissionInfo info)1929         public boolean addPermission(PermissionInfo info) {
1930             try {
1931                 return mPM.addPermission(info);
1932             } catch (RemoteException e) {
1933                 throw new RuntimeException("Package manager has died", e);
1934             }
1935         }
1936 
1937         @Override
addPermissionAsync(PermissionInfo info)1938         public boolean addPermissionAsync(PermissionInfo info) {
1939             try {
1940                 return mPM.addPermissionAsync(info);
1941             } catch (RemoteException e) {
1942                 throw new RuntimeException("Package manager has died", e);
1943             }
1944         }
1945 
1946         @Override
removePermission(String name)1947         public void removePermission(String name) {
1948             try {
1949                 mPM.removePermission(name);
1950             } catch (RemoteException e) {
1951                 throw new RuntimeException("Package manager has died", e);
1952             }
1953         }
1954 
1955         @Override
checkSignatures(String pkg1, String pkg2)1956         public int checkSignatures(String pkg1, String pkg2) {
1957             try {
1958                 return mPM.checkSignatures(pkg1, pkg2);
1959             } catch (RemoteException e) {
1960                 throw new RuntimeException("Package manager has died", e);
1961             }
1962         }
1963 
1964         @Override
checkSignatures(int uid1, int uid2)1965         public int checkSignatures(int uid1, int uid2) {
1966             try {
1967                 return mPM.checkUidSignatures(uid1, uid2);
1968             } catch (RemoteException e) {
1969                 throw new RuntimeException("Package manager has died", e);
1970             }
1971         }
1972 
1973         @Override
getPackagesForUid(int uid)1974         public String[] getPackagesForUid(int uid) {
1975             try {
1976                 return mPM.getPackagesForUid(uid);
1977             } catch (RemoteException e) {
1978                 throw new RuntimeException("Package manager has died", e);
1979             }
1980         }
1981 
1982         @Override
getNameForUid(int uid)1983         public String getNameForUid(int uid) {
1984             try {
1985                 return mPM.getNameForUid(uid);
1986             } catch (RemoteException e) {
1987                 throw new RuntimeException("Package manager has died", e);
1988             }
1989         }
1990 
1991         @Override
getUidForSharedUser(String sharedUserName)1992         public int getUidForSharedUser(String sharedUserName)
1993                 throws NameNotFoundException {
1994             try {
1995                 int uid = mPM.getUidForSharedUser(sharedUserName);
1996                 if(uid != -1) {
1997                     return uid;
1998                 }
1999             } catch (RemoteException e) {
2000                 throw new RuntimeException("Package manager has died", e);
2001             }
2002             throw new NameNotFoundException("No shared userid for user:"+sharedUserName);
2003         }
2004 
2005         @SuppressWarnings("unchecked")
2006         @Override
getInstalledPackages(int flags)2007         public List<PackageInfo> getInstalledPackages(int flags) {
2008             try {
2009                 final List<PackageInfo> packageInfos = new ArrayList<PackageInfo>();
2010                 PackageInfo lastItem = null;
2011                 ParceledListSlice<PackageInfo> slice;
2012 
2013                 do {
2014                     final String lastKey = lastItem != null ? lastItem.packageName : null;
2015                     slice = mPM.getInstalledPackages(flags, lastKey);
2016                     lastItem = slice.populateList(packageInfos, PackageInfo.CREATOR);
2017                 } while (!slice.isLastSlice());
2018 
2019                 return packageInfos;
2020             } catch (RemoteException e) {
2021                 throw new RuntimeException("Package manager has died", e);
2022             }
2023         }
2024 
2025         @SuppressWarnings("unchecked")
2026         @Override
getInstalledApplications(int flags)2027         public List<ApplicationInfo> getInstalledApplications(int flags) {
2028             try {
2029                 final List<ApplicationInfo> applicationInfos = new ArrayList<ApplicationInfo>();
2030                 ApplicationInfo lastItem = null;
2031                 ParceledListSlice<ApplicationInfo> slice;
2032 
2033                 do {
2034                     final String lastKey = lastItem != null ? lastItem.packageName : null;
2035                     slice = mPM.getInstalledApplications(flags, lastKey);
2036                     lastItem = slice.populateList(applicationInfos, ApplicationInfo.CREATOR);
2037                 } while (!slice.isLastSlice());
2038 
2039                 return applicationInfos;
2040             } catch (RemoteException e) {
2041                 throw new RuntimeException("Package manager has died", e);
2042             }
2043         }
2044 
2045         @Override
resolveActivity(Intent intent, int flags)2046         public ResolveInfo resolveActivity(Intent intent, int flags) {
2047             try {
2048                 return mPM.resolveIntent(
2049                     intent,
2050                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2051                     flags);
2052             } catch (RemoteException e) {
2053                 throw new RuntimeException("Package manager has died", e);
2054             }
2055         }
2056 
2057         @Override
queryIntentActivities(Intent intent, int flags)2058         public List<ResolveInfo> queryIntentActivities(Intent intent,
2059                 int flags) {
2060             try {
2061                 return mPM.queryIntentActivities(
2062                     intent,
2063                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2064                     flags);
2065             } catch (RemoteException e) {
2066                 throw new RuntimeException("Package manager has died", e);
2067             }
2068         }
2069 
2070         @Override
queryIntentActivityOptions( ComponentName caller, Intent[] specifics, Intent intent, int flags)2071         public List<ResolveInfo> queryIntentActivityOptions(
2072                 ComponentName caller, Intent[] specifics, Intent intent,
2073                 int flags) {
2074             final ContentResolver resolver = mContext.getContentResolver();
2075 
2076             String[] specificTypes = null;
2077             if (specifics != null) {
2078                 final int N = specifics.length;
2079                 for (int i=0; i<N; i++) {
2080                     Intent sp = specifics[i];
2081                     if (sp != null) {
2082                         String t = sp.resolveTypeIfNeeded(resolver);
2083                         if (t != null) {
2084                             if (specificTypes == null) {
2085                                 specificTypes = new String[N];
2086                             }
2087                             specificTypes[i] = t;
2088                         }
2089                     }
2090                 }
2091             }
2092 
2093             try {
2094                 return mPM.queryIntentActivityOptions(caller, specifics,
2095                     specificTypes, intent, intent.resolveTypeIfNeeded(resolver),
2096                     flags);
2097             } catch (RemoteException e) {
2098                 throw new RuntimeException("Package manager has died", e);
2099             }
2100         }
2101 
2102         @Override
queryBroadcastReceivers(Intent intent, int flags)2103         public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
2104             try {
2105                 return mPM.queryIntentReceivers(
2106                     intent,
2107                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2108                     flags);
2109             } catch (RemoteException e) {
2110                 throw new RuntimeException("Package manager has died", e);
2111             }
2112         }
2113 
2114         @Override
resolveService(Intent intent, int flags)2115         public ResolveInfo resolveService(Intent intent, int flags) {
2116             try {
2117                 return mPM.resolveService(
2118                     intent,
2119                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2120                     flags);
2121             } catch (RemoteException e) {
2122                 throw new RuntimeException("Package manager has died", e);
2123             }
2124         }
2125 
2126         @Override
queryIntentServices(Intent intent, int flags)2127         public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
2128             try {
2129                 return mPM.queryIntentServices(
2130                     intent,
2131                     intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2132                     flags);
2133             } catch (RemoteException e) {
2134                 throw new RuntimeException("Package manager has died", e);
2135             }
2136         }
2137 
2138         @Override
resolveContentProvider(String name, int flags)2139         public ProviderInfo resolveContentProvider(String name,
2140                 int flags) {
2141             try {
2142                 return mPM.resolveContentProvider(name, flags);
2143             } catch (RemoteException e) {
2144                 throw new RuntimeException("Package manager has died", e);
2145             }
2146         }
2147 
2148         @Override
queryContentProviders(String processName, int uid, int flags)2149         public List<ProviderInfo> queryContentProviders(String processName,
2150                 int uid, int flags) {
2151             try {
2152                 return mPM.queryContentProviders(processName, uid, flags);
2153             } catch (RemoteException e) {
2154                 throw new RuntimeException("Package manager has died", e);
2155             }
2156         }
2157 
2158         @Override
getInstrumentationInfo( ComponentName className, int flags)2159         public InstrumentationInfo getInstrumentationInfo(
2160                 ComponentName className, int flags)
2161                 throws NameNotFoundException {
2162             try {
2163                 InstrumentationInfo ii = mPM.getInstrumentationInfo(
2164                         className, flags);
2165                 if (ii != null) {
2166                     return ii;
2167                 }
2168             } catch (RemoteException e) {
2169                 throw new RuntimeException("Package manager has died", e);
2170             }
2171 
2172             throw new NameNotFoundException(className.toString());
2173         }
2174 
2175         @Override
queryInstrumentation( String targetPackage, int flags)2176         public List<InstrumentationInfo> queryInstrumentation(
2177                 String targetPackage, int flags) {
2178             try {
2179                 return mPM.queryInstrumentation(targetPackage, flags);
2180             } catch (RemoteException e) {
2181                 throw new RuntimeException("Package manager has died", e);
2182             }
2183         }
2184 
getDrawable(String packageName, int resid, ApplicationInfo appInfo)2185         @Override public Drawable getDrawable(String packageName, int resid,
2186                 ApplicationInfo appInfo) {
2187             ResourceName name = new ResourceName(packageName, resid);
2188             Drawable dr = getCachedIcon(name);
2189             if (dr != null) {
2190                 return dr;
2191             }
2192             if (appInfo == null) {
2193                 try {
2194                     appInfo = getApplicationInfo(packageName, 0);
2195                 } catch (NameNotFoundException e) {
2196                     return null;
2197                 }
2198             }
2199             try {
2200                 Resources r = getResourcesForApplication(appInfo);
2201                 dr = r.getDrawable(resid);
2202                 if (false) {
2203                     RuntimeException e = new RuntimeException("here");
2204                     e.fillInStackTrace();
2205                     Log.w(TAG, "Getting drawable 0x" + Integer.toHexString(resid)
2206                             + " from package " + packageName
2207                             + ": app scale=" + r.getCompatibilityInfo().applicationScale
2208                             + ", caller scale=" + mContext.getResources().getCompatibilityInfo().applicationScale,
2209                             e);
2210                 }
2211                 if (DEBUG_ICONS) Log.v(TAG, "Getting drawable 0x"
2212                         + Integer.toHexString(resid) + " from " + r
2213                         + ": " + dr);
2214                 putCachedIcon(name, dr);
2215                 return dr;
2216             } catch (NameNotFoundException e) {
2217                 Log.w("PackageManager", "Failure retrieving resources for"
2218                         + appInfo.packageName);
2219             } catch (RuntimeException e) {
2220                 // If an exception was thrown, fall through to return
2221                 // default icon.
2222                 Log.w("PackageManager", "Failure retrieving icon 0x"
2223                         + Integer.toHexString(resid) + " in package "
2224                         + packageName, e);
2225             }
2226             return null;
2227         }
2228 
getActivityIcon(ComponentName activityName)2229         @Override public Drawable getActivityIcon(ComponentName activityName)
2230                 throws NameNotFoundException {
2231             return getActivityInfo(activityName, 0).loadIcon(this);
2232         }
2233 
getActivityIcon(Intent intent)2234         @Override public Drawable getActivityIcon(Intent intent)
2235                 throws NameNotFoundException {
2236             if (intent.getComponent() != null) {
2237                 return getActivityIcon(intent.getComponent());
2238             }
2239 
2240             ResolveInfo info = resolveActivity(
2241                 intent, PackageManager.MATCH_DEFAULT_ONLY);
2242             if (info != null) {
2243                 return info.activityInfo.loadIcon(this);
2244             }
2245 
2246             throw new NameNotFoundException(intent.toURI());
2247         }
2248 
getDefaultActivityIcon()2249         @Override public Drawable getDefaultActivityIcon() {
2250             return Resources.getSystem().getDrawable(
2251                 com.android.internal.R.drawable.sym_def_app_icon);
2252         }
2253 
getApplicationIcon(ApplicationInfo info)2254         @Override public Drawable getApplicationIcon(ApplicationInfo info) {
2255             return info.loadIcon(this);
2256         }
2257 
getApplicationIcon(String packageName)2258         @Override public Drawable getApplicationIcon(String packageName)
2259                 throws NameNotFoundException {
2260             return getApplicationIcon(getApplicationInfo(packageName, 0));
2261         }
2262 
2263         @Override
getActivityLogo(ComponentName activityName)2264         public Drawable getActivityLogo(ComponentName activityName)
2265                 throws NameNotFoundException {
2266             return getActivityInfo(activityName, 0).loadLogo(this);
2267         }
2268 
2269         @Override
getActivityLogo(Intent intent)2270         public Drawable getActivityLogo(Intent intent)
2271                 throws NameNotFoundException {
2272             if (intent.getComponent() != null) {
2273                 return getActivityLogo(intent.getComponent());
2274             }
2275 
2276             ResolveInfo info = resolveActivity(
2277                     intent, PackageManager.MATCH_DEFAULT_ONLY);
2278             if (info != null) {
2279                 return info.activityInfo.loadLogo(this);
2280             }
2281 
2282             throw new NameNotFoundException(intent.toUri(0));
2283         }
2284 
2285         @Override
getApplicationLogo(ApplicationInfo info)2286         public Drawable getApplicationLogo(ApplicationInfo info) {
2287             return info.loadLogo(this);
2288         }
2289 
2290         @Override
getApplicationLogo(String packageName)2291         public Drawable getApplicationLogo(String packageName)
2292                 throws NameNotFoundException {
2293             return getApplicationLogo(getApplicationInfo(packageName, 0));
2294         }
2295 
getResourcesForActivity( ComponentName activityName)2296         @Override public Resources getResourcesForActivity(
2297                 ComponentName activityName) throws NameNotFoundException {
2298             return getResourcesForApplication(
2299                 getActivityInfo(activityName, 0).applicationInfo);
2300         }
2301 
getResourcesForApplication( ApplicationInfo app)2302         @Override public Resources getResourcesForApplication(
2303                 ApplicationInfo app) throws NameNotFoundException {
2304             if (app.packageName.equals("system")) {
2305                 return mContext.mMainThread.getSystemContext().getResources();
2306             }
2307             Resources r = mContext.mMainThread.getTopLevelResources(
2308                     app.uid == Process.myUid() ? app.sourceDir
2309                     : app.publicSourceDir, mContext.mPackageInfo);
2310             if (r != null) {
2311                 return r;
2312             }
2313             throw new NameNotFoundException("Unable to open " + app.publicSourceDir);
2314         }
2315 
getResourcesForApplication( String appPackageName)2316         @Override public Resources getResourcesForApplication(
2317                 String appPackageName) throws NameNotFoundException {
2318             return getResourcesForApplication(
2319                 getApplicationInfo(appPackageName, 0));
2320         }
2321 
2322         int mCachedSafeMode = -1;
isSafeMode()2323         @Override public boolean isSafeMode() {
2324             try {
2325                 if (mCachedSafeMode < 0) {
2326                     mCachedSafeMode = mPM.isSafeMode() ? 1 : 0;
2327                 }
2328                 return mCachedSafeMode != 0;
2329             } catch (RemoteException e) {
2330                 throw new RuntimeException("Package manager has died", e);
2331             }
2332         }
2333 
configurationChanged()2334         static void configurationChanged() {
2335             synchronized (sSync) {
2336                 sIconCache.clear();
2337                 sStringCache.clear();
2338             }
2339         }
2340 
ApplicationPackageManager(ContextImpl context, IPackageManager pm)2341         ApplicationPackageManager(ContextImpl context,
2342                 IPackageManager pm) {
2343             mContext = context;
2344             mPM = pm;
2345         }
2346 
getCachedIcon(ResourceName name)2347         private Drawable getCachedIcon(ResourceName name) {
2348             synchronized (sSync) {
2349                 WeakReference<Drawable> wr = sIconCache.get(name);
2350                 if (DEBUG_ICONS) Log.v(TAG, "Get cached weak drawable ref for "
2351                         + name + ": " + wr);
2352                 if (wr != null) {   // we have the activity
2353                     Drawable dr = wr.get();
2354                     if (dr != null) {
2355                         if (DEBUG_ICONS) Log.v(TAG, "Get cached drawable for "
2356                                 + name + ": " + dr);
2357                         return dr;
2358                     }
2359                     // our entry has been purged
2360                     sIconCache.remove(name);
2361                 }
2362             }
2363             return null;
2364         }
2365 
putCachedIcon(ResourceName name, Drawable dr)2366         private void putCachedIcon(ResourceName name, Drawable dr) {
2367             synchronized (sSync) {
2368                 sIconCache.put(name, new WeakReference<Drawable>(dr));
2369                 if (DEBUG_ICONS) Log.v(TAG, "Added cached drawable for "
2370                         + name + ": " + dr);
2371             }
2372         }
2373 
handlePackageBroadcast(int cmd, String[] pkgList, boolean hasPkgInfo)2374         static final void handlePackageBroadcast(int cmd, String[] pkgList,
2375                 boolean hasPkgInfo) {
2376             boolean immediateGc = false;
2377             if (cmd == IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE) {
2378                 immediateGc = true;
2379             }
2380             if (pkgList != null && (pkgList.length > 0)) {
2381                 boolean needCleanup = false;
2382                 for (String ssp : pkgList) {
2383                     synchronized (sSync) {
2384                         if (sIconCache.size() > 0) {
2385                             Iterator<ResourceName> it = sIconCache.keySet().iterator();
2386                             while (it.hasNext()) {
2387                                 ResourceName nm = it.next();
2388                                 if (nm.packageName.equals(ssp)) {
2389                                     //Log.i(TAG, "Removing cached drawable for " + nm);
2390                                     it.remove();
2391                                     needCleanup = true;
2392                                 }
2393                             }
2394                         }
2395                         if (sStringCache.size() > 0) {
2396                             Iterator<ResourceName> it = sStringCache.keySet().iterator();
2397                             while (it.hasNext()) {
2398                                 ResourceName nm = it.next();
2399                                 if (nm.packageName.equals(ssp)) {
2400                                     //Log.i(TAG, "Removing cached string for " + nm);
2401                                     it.remove();
2402                                     needCleanup = true;
2403                                 }
2404                             }
2405                         }
2406                     }
2407                 }
2408                 if (needCleanup || hasPkgInfo) {
2409                     if (immediateGc) {
2410                         // Schedule an immediate gc.
2411                         Runtime.getRuntime().gc();
2412                     } else {
2413                         ActivityThread.currentActivityThread().scheduleGcIdler();
2414                     }
2415                 }
2416             }
2417         }
2418 
2419         private static final class ResourceName {
2420             final String packageName;
2421             final int iconId;
2422 
ResourceName(String _packageName, int _iconId)2423             ResourceName(String _packageName, int _iconId) {
2424                 packageName = _packageName;
2425                 iconId = _iconId;
2426             }
2427 
ResourceName(ApplicationInfo aInfo, int _iconId)2428             ResourceName(ApplicationInfo aInfo, int _iconId) {
2429                 this(aInfo.packageName, _iconId);
2430             }
2431 
ResourceName(ComponentInfo cInfo, int _iconId)2432             ResourceName(ComponentInfo cInfo, int _iconId) {
2433                 this(cInfo.applicationInfo.packageName, _iconId);
2434             }
2435 
ResourceName(ResolveInfo rInfo, int _iconId)2436             ResourceName(ResolveInfo rInfo, int _iconId) {
2437                 this(rInfo.activityInfo.applicationInfo.packageName, _iconId);
2438             }
2439 
2440             @Override
equals(Object o)2441             public boolean equals(Object o) {
2442                 if (this == o) return true;
2443                 if (o == null || getClass() != o.getClass()) return false;
2444 
2445                 ResourceName that = (ResourceName) o;
2446 
2447                 if (iconId != that.iconId) return false;
2448                 return !(packageName != null ?
2449                         !packageName.equals(that.packageName) : that.packageName != null);
2450 
2451             }
2452 
2453             @Override
hashCode()2454             public int hashCode() {
2455                 int result;
2456                 result = packageName.hashCode();
2457                 result = 31 * result + iconId;
2458                 return result;
2459             }
2460 
2461             @Override
toString()2462             public String toString() {
2463                 return "{ResourceName " + packageName + " / " + iconId + "}";
2464             }
2465         }
2466 
getCachedString(ResourceName name)2467         private CharSequence getCachedString(ResourceName name) {
2468             synchronized (sSync) {
2469                 WeakReference<CharSequence> wr = sStringCache.get(name);
2470                 if (wr != null) {   // we have the activity
2471                     CharSequence cs = wr.get();
2472                     if (cs != null) {
2473                         return cs;
2474                     }
2475                     // our entry has been purged
2476                     sStringCache.remove(name);
2477                 }
2478             }
2479             return null;
2480         }
2481 
putCachedString(ResourceName name, CharSequence cs)2482         private void putCachedString(ResourceName name, CharSequence cs) {
2483             synchronized (sSync) {
2484                 sStringCache.put(name, new WeakReference<CharSequence>(cs));
2485             }
2486         }
2487 
2488         @Override
getText(String packageName, int resid, ApplicationInfo appInfo)2489         public CharSequence getText(String packageName, int resid,
2490                 ApplicationInfo appInfo) {
2491             ResourceName name = new ResourceName(packageName, resid);
2492             CharSequence text = getCachedString(name);
2493             if (text != null) {
2494                 return text;
2495             }
2496             if (appInfo == null) {
2497                 try {
2498                     appInfo = getApplicationInfo(packageName, 0);
2499                 } catch (NameNotFoundException e) {
2500                     return null;
2501                 }
2502             }
2503             try {
2504                 Resources r = getResourcesForApplication(appInfo);
2505                 text = r.getText(resid);
2506                 putCachedString(name, text);
2507                 return text;
2508             } catch (NameNotFoundException e) {
2509                 Log.w("PackageManager", "Failure retrieving resources for"
2510                         + appInfo.packageName);
2511             } catch (RuntimeException e) {
2512                 // If an exception was thrown, fall through to return
2513                 // default icon.
2514                 Log.w("PackageManager", "Failure retrieving text 0x"
2515                         + Integer.toHexString(resid) + " in package "
2516                         + packageName, e);
2517             }
2518             return null;
2519         }
2520 
2521         @Override
getXml(String packageName, int resid, ApplicationInfo appInfo)2522         public XmlResourceParser getXml(String packageName, int resid,
2523                 ApplicationInfo appInfo) {
2524             if (appInfo == null) {
2525                 try {
2526                     appInfo = getApplicationInfo(packageName, 0);
2527                 } catch (NameNotFoundException e) {
2528                     return null;
2529                 }
2530             }
2531             try {
2532                 Resources r = getResourcesForApplication(appInfo);
2533                 return r.getXml(resid);
2534             } catch (RuntimeException e) {
2535                 // If an exception was thrown, fall through to return
2536                 // default icon.
2537                 Log.w("PackageManager", "Failure retrieving xml 0x"
2538                         + Integer.toHexString(resid) + " in package "
2539                         + packageName, e);
2540             } catch (NameNotFoundException e) {
2541                 Log.w("PackageManager", "Failure retrieving resources for"
2542                         + appInfo.packageName);
2543             }
2544             return null;
2545         }
2546 
2547         @Override
getApplicationLabel(ApplicationInfo info)2548         public CharSequence getApplicationLabel(ApplicationInfo info) {
2549             return info.loadLabel(this);
2550         }
2551 
2552         @Override
installPackage(Uri packageURI, IPackageInstallObserver observer, int flags, String installerPackageName)2553         public void installPackage(Uri packageURI, IPackageInstallObserver observer, int flags,
2554                 String installerPackageName) {
2555             try {
2556                 mPM.installPackage(packageURI, observer, flags, installerPackageName);
2557             } catch (RemoteException e) {
2558                 // Should never happen!
2559             }
2560         }
2561 
2562         @Override
movePackage(String packageName, IPackageMoveObserver observer, int flags)2563         public void movePackage(String packageName, IPackageMoveObserver observer, int flags) {
2564             try {
2565                 mPM.movePackage(packageName, observer, flags);
2566             } catch (RemoteException e) {
2567                 // Should never happen!
2568             }
2569         }
2570 
2571         @Override
getInstallerPackageName(String packageName)2572         public String getInstallerPackageName(String packageName) {
2573             try {
2574                 return mPM.getInstallerPackageName(packageName);
2575             } catch (RemoteException e) {
2576                 // Should never happen!
2577             }
2578             return null;
2579         }
2580 
2581         @Override
deletePackage(String packageName, IPackageDeleteObserver observer, int flags)2582         public void deletePackage(String packageName, IPackageDeleteObserver observer, int flags) {
2583             try {
2584                 mPM.deletePackage(packageName, observer, flags);
2585             } catch (RemoteException e) {
2586                 // Should never happen!
2587             }
2588         }
2589         @Override
clearApplicationUserData(String packageName, IPackageDataObserver observer)2590         public void clearApplicationUserData(String packageName,
2591                 IPackageDataObserver observer) {
2592             try {
2593                 mPM.clearApplicationUserData(packageName, observer);
2594             } catch (RemoteException e) {
2595                 // Should never happen!
2596             }
2597         }
2598         @Override
deleteApplicationCacheFiles(String packageName, IPackageDataObserver observer)2599         public void deleteApplicationCacheFiles(String packageName,
2600                 IPackageDataObserver observer) {
2601             try {
2602                 mPM.deleteApplicationCacheFiles(packageName, observer);
2603             } catch (RemoteException e) {
2604                 // Should never happen!
2605             }
2606         }
2607         @Override
freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer)2608         public void freeStorageAndNotify(long idealStorageSize, IPackageDataObserver observer) {
2609             try {
2610                 mPM.freeStorageAndNotify(idealStorageSize, observer);
2611             } catch (RemoteException e) {
2612                 // Should never happen!
2613             }
2614         }
2615 
2616         @Override
freeStorage(long freeStorageSize, IntentSender pi)2617         public void freeStorage(long freeStorageSize, IntentSender pi) {
2618             try {
2619                 mPM.freeStorage(freeStorageSize, pi);
2620             } catch (RemoteException e) {
2621                 // Should never happen!
2622             }
2623         }
2624 
2625         @Override
getPackageSizeInfo(String packageName, IPackageStatsObserver observer)2626         public void getPackageSizeInfo(String packageName,
2627                 IPackageStatsObserver observer) {
2628             try {
2629                 mPM.getPackageSizeInfo(packageName, observer);
2630             } catch (RemoteException e) {
2631                 // Should never happen!
2632             }
2633         }
2634         @Override
addPackageToPreferred(String packageName)2635         public void addPackageToPreferred(String packageName) {
2636             try {
2637                 mPM.addPackageToPreferred(packageName);
2638             } catch (RemoteException e) {
2639                 // Should never happen!
2640             }
2641         }
2642 
2643         @Override
removePackageFromPreferred(String packageName)2644         public void removePackageFromPreferred(String packageName) {
2645             try {
2646                 mPM.removePackageFromPreferred(packageName);
2647             } catch (RemoteException e) {
2648                 // Should never happen!
2649             }
2650         }
2651 
2652         @Override
getPreferredPackages(int flags)2653         public List<PackageInfo> getPreferredPackages(int flags) {
2654             try {
2655                 return mPM.getPreferredPackages(flags);
2656             } catch (RemoteException e) {
2657                 // Should never happen!
2658             }
2659             return new ArrayList<PackageInfo>();
2660         }
2661 
2662         @Override
addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2663         public void addPreferredActivity(IntentFilter filter,
2664                 int match, ComponentName[] set, ComponentName activity) {
2665             try {
2666                 mPM.addPreferredActivity(filter, match, set, activity);
2667             } catch (RemoteException e) {
2668                 // Should never happen!
2669             }
2670         }
2671 
2672         @Override
replacePreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity)2673         public void replacePreferredActivity(IntentFilter filter,
2674                 int match, ComponentName[] set, ComponentName activity) {
2675             try {
2676                 mPM.replacePreferredActivity(filter, match, set, activity);
2677             } catch (RemoteException e) {
2678                 // Should never happen!
2679             }
2680         }
2681 
2682         @Override
clearPackagePreferredActivities(String packageName)2683         public void clearPackagePreferredActivities(String packageName) {
2684             try {
2685                 mPM.clearPackagePreferredActivities(packageName);
2686             } catch (RemoteException e) {
2687                 // Should never happen!
2688             }
2689         }
2690 
2691         @Override
getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName)2692         public int getPreferredActivities(List<IntentFilter> outFilters,
2693                 List<ComponentName> outActivities, String packageName) {
2694             try {
2695                 return mPM.getPreferredActivities(outFilters, outActivities, packageName);
2696             } catch (RemoteException e) {
2697                 // Should never happen!
2698             }
2699             return 0;
2700         }
2701 
2702         @Override
setComponentEnabledSetting(ComponentName componentName, int newState, int flags)2703         public void setComponentEnabledSetting(ComponentName componentName,
2704                 int newState, int flags) {
2705             try {
2706                 mPM.setComponentEnabledSetting(componentName, newState, flags);
2707             } catch (RemoteException e) {
2708                 // Should never happen!
2709             }
2710         }
2711 
2712         @Override
getComponentEnabledSetting(ComponentName componentName)2713         public int getComponentEnabledSetting(ComponentName componentName) {
2714             try {
2715                 return mPM.getComponentEnabledSetting(componentName);
2716             } catch (RemoteException e) {
2717                 // Should never happen!
2718             }
2719             return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2720         }
2721 
2722         @Override
setApplicationEnabledSetting(String packageName, int newState, int flags)2723         public void setApplicationEnabledSetting(String packageName,
2724                 int newState, int flags) {
2725             try {
2726                 mPM.setApplicationEnabledSetting(packageName, newState, flags);
2727             } catch (RemoteException e) {
2728                 // Should never happen!
2729             }
2730         }
2731 
2732         @Override
getApplicationEnabledSetting(String packageName)2733         public int getApplicationEnabledSetting(String packageName) {
2734             try {
2735                 return mPM.getApplicationEnabledSetting(packageName);
2736             } catch (RemoteException e) {
2737                 // Should never happen!
2738             }
2739             return PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
2740         }
2741 
2742         private final ContextImpl mContext;
2743         private final IPackageManager mPM;
2744 
2745         private static final Object sSync = new Object();
2746         private static HashMap<ResourceName, WeakReference<Drawable> > sIconCache
2747                 = new HashMap<ResourceName, WeakReference<Drawable> >();
2748         private static HashMap<ResourceName, WeakReference<CharSequence> > sStringCache
2749                 = new HashMap<ResourceName, WeakReference<CharSequence> >();
2750     }
2751 
2752     // ----------------------------------------------------------------------
2753     // ----------------------------------------------------------------------
2754     // ----------------------------------------------------------------------
2755 
2756     private static final class SharedPreferencesImpl implements SharedPreferences {
2757 
2758         // Lock ordering rules:
2759         //  - acquire SharedPreferencesImpl.this before EditorImpl.this
2760         //  - acquire mWritingToDiskLock before EditorImpl.this
2761 
2762         private final File mFile;
2763         private final File mBackupFile;
2764         private final int mMode;
2765 
2766         private Map<String, Object> mMap;     // guarded by 'this'
2767         private int mDiskWritesInFlight = 0;  // guarded by 'this'
2768         private boolean mLoaded = false;      // guarded by 'this'
2769         private long mStatTimestamp;          // guarded by 'this'
2770         private long mStatSize;               // guarded by 'this'
2771 
2772         private final Object mWritingToDiskLock = new Object();
2773         private static final Object mContent = new Object();
2774         private final WeakHashMap<OnSharedPreferenceChangeListener, Object> mListeners;
2775 
SharedPreferencesImpl( File file, int mode, Map initialContents)2776         SharedPreferencesImpl(
2777             File file, int mode, Map initialContents) {
2778             mFile = file;
2779             mBackupFile = makeBackupFile(file);
2780             mMode = mode;
2781             mLoaded = initialContents != null;
2782             mMap = initialContents != null ? initialContents : new HashMap<String, Object>();
2783             FileStatus stat = new FileStatus();
2784             if (FileUtils.getFileStatus(file.getPath(), stat)) {
2785                 mStatTimestamp = stat.mtime;
2786             }
2787             mListeners = new WeakHashMap<OnSharedPreferenceChangeListener, Object>();
2788         }
2789 
2790         // Has this SharedPreferences ever had values assigned to it?
isLoaded()2791         boolean isLoaded() {
2792             synchronized (this) {
2793                 return mLoaded;
2794             }
2795         }
2796 
2797         // Has the file changed out from under us?  i.e. writes that
2798         // we didn't instigate.
hasFileChangedUnexpectedly()2799         public boolean hasFileChangedUnexpectedly() {
2800             synchronized (this) {
2801                 if (mDiskWritesInFlight > 0) {
2802                     // If we know we caused it, it's not unexpected.
2803                     if (DEBUG) Log.d(TAG, "disk write in flight, not unexpected.");
2804                     return false;
2805                 }
2806             }
2807             FileStatus stat = new FileStatus();
2808             if (!FileUtils.getFileStatus(mFile.getPath(), stat)) {
2809                 return true;
2810             }
2811             synchronized (this) {
2812                 return mStatTimestamp != stat.mtime || mStatSize != stat.size;
2813             }
2814         }
2815 
replace(Map newContents, FileStatus stat)2816         /* package */ void replace(Map newContents, FileStatus stat) {
2817             synchronized (this) {
2818                 mLoaded = true;
2819                 if (newContents != null) {
2820                     mMap = newContents;
2821                 }
2822                 if (stat != null) {
2823                     mStatTimestamp = stat.mtime;
2824                     mStatSize = stat.size;
2825                 }
2826             }
2827         }
2828 
registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)2829         public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2830             synchronized(this) {
2831                 mListeners.put(listener, mContent);
2832             }
2833         }
2834 
unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener)2835         public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener) {
2836             synchronized(this) {
2837                 mListeners.remove(listener);
2838             }
2839         }
2840 
getAll()2841         public Map<String, ?> getAll() {
2842             synchronized(this) {
2843                 //noinspection unchecked
2844                 return new HashMap<String, Object>(mMap);
2845             }
2846         }
2847 
getString(String key, String defValue)2848         public String getString(String key, String defValue) {
2849             synchronized (this) {
2850                 String v = (String)mMap.get(key);
2851                 return v != null ? v : defValue;
2852             }
2853         }
2854 
getInt(String key, int defValue)2855         public int getInt(String key, int defValue) {
2856             synchronized (this) {
2857                 Integer v = (Integer)mMap.get(key);
2858                 return v != null ? v : defValue;
2859             }
2860         }
getLong(String key, long defValue)2861         public long getLong(String key, long defValue) {
2862             synchronized (this) {
2863                 Long v = (Long)mMap.get(key);
2864                 return v != null ? v : defValue;
2865             }
2866         }
getFloat(String key, float defValue)2867         public float getFloat(String key, float defValue) {
2868             synchronized (this) {
2869                 Float v = (Float)mMap.get(key);
2870                 return v != null ? v : defValue;
2871             }
2872         }
getBoolean(String key, boolean defValue)2873         public boolean getBoolean(String key, boolean defValue) {
2874             synchronized (this) {
2875                 Boolean v = (Boolean)mMap.get(key);
2876                 return v != null ? v : defValue;
2877             }
2878         }
2879 
contains(String key)2880         public boolean contains(String key) {
2881             synchronized (this) {
2882                 return mMap.containsKey(key);
2883             }
2884         }
2885 
edit()2886         public Editor edit() {
2887             return new EditorImpl();
2888         }
2889 
2890         // Return value from EditorImpl#commitToMemory()
2891         private static class MemoryCommitResult {
2892             public boolean changesMade;  // any keys different?
2893             public List<String> keysModified;  // may be null
2894             public Set<OnSharedPreferenceChangeListener> listeners;  // may be null
2895             public Map<?, ?> mapToWriteToDisk;
2896             public final CountDownLatch writtenToDiskLatch = new CountDownLatch(1);
2897             public volatile boolean writeToDiskResult = false;
2898 
setDiskWriteResult(boolean result)2899             public void setDiskWriteResult(boolean result) {
2900                 writeToDiskResult = result;
2901                 writtenToDiskLatch.countDown();
2902             }
2903         }
2904 
2905         public final class EditorImpl implements Editor {
2906             private final Map<String, Object> mModified = Maps.newHashMap();
2907             private boolean mClear = false;
2908 
putString(String key, String value)2909             public Editor putString(String key, String value) {
2910                 synchronized (this) {
2911                     mModified.put(key, value);
2912                     return this;
2913                 }
2914             }
putInt(String key, int value)2915             public Editor putInt(String key, int value) {
2916                 synchronized (this) {
2917                     mModified.put(key, value);
2918                     return this;
2919                 }
2920             }
putLong(String key, long value)2921             public Editor putLong(String key, long value) {
2922                 synchronized (this) {
2923                     mModified.put(key, value);
2924                     return this;
2925                 }
2926             }
putFloat(String key, float value)2927             public Editor putFloat(String key, float value) {
2928                 synchronized (this) {
2929                     mModified.put(key, value);
2930                     return this;
2931                 }
2932             }
putBoolean(String key, boolean value)2933             public Editor putBoolean(String key, boolean value) {
2934                 synchronized (this) {
2935                     mModified.put(key, value);
2936                     return this;
2937                 }
2938             }
2939 
remove(String key)2940             public Editor remove(String key) {
2941                 synchronized (this) {
2942                     mModified.put(key, this);
2943                     return this;
2944                 }
2945             }
2946 
clear()2947             public Editor clear() {
2948                 synchronized (this) {
2949                     mClear = true;
2950                     return this;
2951                 }
2952             }
2953 
apply()2954             public void apply() {
2955                 final MemoryCommitResult mcr = commitToMemory();
2956                 final Runnable awaitCommit = new Runnable() {
2957                         public void run() {
2958                             try {
2959                                 mcr.writtenToDiskLatch.await();
2960                             } catch (InterruptedException ignored) {
2961                             }
2962                         }
2963                     };
2964 
2965                 QueuedWork.add(awaitCommit);
2966 
2967                 Runnable postWriteRunnable = new Runnable() {
2968                         public void run() {
2969                             awaitCommit.run();
2970                             QueuedWork.remove(awaitCommit);
2971                         }
2972                     };
2973 
2974                 SharedPreferencesImpl.this.enqueueDiskWrite(mcr, postWriteRunnable);
2975 
2976                 // Okay to notify the listeners before it's hit disk
2977                 // because the listeners should always get the same
2978                 // SharedPreferences instance back, which has the
2979                 // changes reflected in memory.
2980                 notifyListeners(mcr);
2981             }
2982 
2983             // Returns true if any changes were made
commitToMemory()2984             private MemoryCommitResult commitToMemory() {
2985                 MemoryCommitResult mcr = new MemoryCommitResult();
2986                 synchronized (SharedPreferencesImpl.this) {
2987                     // We optimistically don't make a deep copy until
2988                     // a memory commit comes in when we're already
2989                     // writing to disk.
2990                     if (mDiskWritesInFlight > 0) {
2991                         // We can't modify our mMap as a currently
2992                         // in-flight write owns it.  Clone it before
2993                         // modifying it.
2994                         // noinspection unchecked
2995                         mMap = new HashMap<String, Object>(mMap);
2996                     }
2997                     mcr.mapToWriteToDisk = mMap;
2998                     mDiskWritesInFlight++;
2999 
3000                     boolean hasListeners = mListeners.size() > 0;
3001                     if (hasListeners) {
3002                         mcr.keysModified = new ArrayList<String>();
3003                         mcr.listeners =
3004                             new HashSet<OnSharedPreferenceChangeListener>(mListeners.keySet());
3005                     }
3006 
3007                     synchronized (this) {
3008                         if (mClear) {
3009                             if (!mMap.isEmpty()) {
3010                                 mcr.changesMade = true;
3011                                 mMap.clear();
3012                             }
3013                             mClear = false;
3014                         }
3015 
3016                         for (Entry<String, Object> e : mModified.entrySet()) {
3017                             String k = e.getKey();
3018                             Object v = e.getValue();
3019                             if (v == this) {  // magic value for a removal mutation
3020                                 if (!mMap.containsKey(k)) {
3021                                     continue;
3022                                 }
3023                                 mMap.remove(k);
3024                             } else {
3025                                 boolean isSame = false;
3026                                 if (mMap.containsKey(k)) {
3027                                     Object existingValue = mMap.get(k);
3028                                     if (existingValue != null && existingValue.equals(v)) {
3029                                         continue;
3030                                     }
3031                                 }
3032                                 mMap.put(k, v);
3033                             }
3034 
3035                             mcr.changesMade = true;
3036                             if (hasListeners) {
3037                                 mcr.keysModified.add(k);
3038                             }
3039                         }
3040 
3041                         mModified.clear();
3042                     }
3043                 }
3044                 return mcr;
3045             }
3046 
commit()3047             public boolean commit() {
3048                 MemoryCommitResult mcr = commitToMemory();
3049                 SharedPreferencesImpl.this.enqueueDiskWrite(
3050                     mcr, null /* sync write on this thread okay */);
3051                 try {
3052                     mcr.writtenToDiskLatch.await();
3053                 } catch (InterruptedException e) {
3054                     return false;
3055                 }
3056                 notifyListeners(mcr);
3057                 return mcr.writeToDiskResult;
3058             }
3059 
notifyListeners(final MemoryCommitResult mcr)3060             private void notifyListeners(final MemoryCommitResult mcr) {
3061                 if (mcr.listeners == null || mcr.keysModified == null ||
3062                     mcr.keysModified.size() == 0) {
3063                     return;
3064                 }
3065                 if (Looper.myLooper() == Looper.getMainLooper()) {
3066                     for (int i = mcr.keysModified.size() - 1; i >= 0; i--) {
3067                         final String key = mcr.keysModified.get(i);
3068                         for (OnSharedPreferenceChangeListener listener : mcr.listeners) {
3069                             if (listener != null) {
3070                                 listener.onSharedPreferenceChanged(SharedPreferencesImpl.this, key);
3071                             }
3072                         }
3073                     }
3074                 } else {
3075                     // Run this function on the main thread.
3076                     ActivityThread.sMainThreadHandler.post(new Runnable() {
3077                             public void run() {
3078                                 notifyListeners(mcr);
3079                             }
3080                         });
3081                 }
3082             }
3083         }
3084 
3085         /**
3086          * Enqueue an already-committed-to-memory result to be written
3087          * to disk.
3088          *
3089          * They will be written to disk one-at-a-time in the order
3090          * that they're enqueued.
3091          *
3092          * @param postWriteRunnable if non-null, we're being called
3093          *   from apply() and this is the runnable to run after
3094          *   the write proceeds.  if null (from a regular commit()),
3095          *   then we're allowed to do this disk write on the main
3096          *   thread (which in addition to reducing allocations and
3097          *   creating a background thread, this has the advantage that
3098          *   we catch them in userdebug StrictMode reports to convert
3099          *   them where possible to apply() ...)
3100          */
enqueueDiskWrite(final MemoryCommitResult mcr, final Runnable postWriteRunnable)3101         private void enqueueDiskWrite(final MemoryCommitResult mcr,
3102                                       final Runnable postWriteRunnable) {
3103             final Runnable writeToDiskRunnable = new Runnable() {
3104                     public void run() {
3105                         synchronized (mWritingToDiskLock) {
3106                             writeToFile(mcr);
3107                         }
3108                         synchronized (SharedPreferencesImpl.this) {
3109                             mDiskWritesInFlight--;
3110                         }
3111                         if (postWriteRunnable != null) {
3112                             postWriteRunnable.run();
3113                         }
3114                     }
3115                 };
3116 
3117             final boolean isFromSyncCommit = (postWriteRunnable == null);
3118 
3119             // Typical #commit() path with fewer allocations, doing a write on
3120             // the current thread.
3121             if (isFromSyncCommit) {
3122                 boolean wasEmpty = false;
3123                 synchronized (SharedPreferencesImpl.this) {
3124                     wasEmpty = mDiskWritesInFlight == 1;
3125                 }
3126                 if (wasEmpty) {
3127                     writeToDiskRunnable.run();
3128                     return;
3129                 }
3130             }
3131 
3132             QueuedWork.singleThreadExecutor().execute(writeToDiskRunnable);
3133         }
3134 
createFileOutputStream(File file)3135         private static FileOutputStream createFileOutputStream(File file) {
3136             FileOutputStream str = null;
3137             try {
3138                 str = new FileOutputStream(file);
3139             } catch (FileNotFoundException e) {
3140                 File parent = file.getParentFile();
3141                 if (!parent.mkdir()) {
3142                     Log.e(TAG, "Couldn't create directory for SharedPreferences file " + file);
3143                     return null;
3144                 }
3145                 FileUtils.setPermissions(
3146                     parent.getPath(),
3147                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
3148                     -1, -1);
3149                 try {
3150                     str = new FileOutputStream(file);
3151                 } catch (FileNotFoundException e2) {
3152                     Log.e(TAG, "Couldn't create SharedPreferences file " + file, e2);
3153                 }
3154             }
3155             return str;
3156         }
3157 
3158         // Note: must hold mWritingToDiskLock
writeToFile(MemoryCommitResult mcr)3159         private void writeToFile(MemoryCommitResult mcr) {
3160             // Rename the current file so it may be used as a backup during the next read
3161             if (mFile.exists()) {
3162                 if (!mcr.changesMade) {
3163                     // If the file already exists, but no changes were
3164                     // made to the underlying map, it's wasteful to
3165                     // re-write the file.  Return as if we wrote it
3166                     // out.
3167                     mcr.setDiskWriteResult(true);
3168                     return;
3169                 }
3170                 if (!mBackupFile.exists()) {
3171                     if (!mFile.renameTo(mBackupFile)) {
3172                         Log.e(TAG, "Couldn't rename file " + mFile
3173                                 + " to backup file " + mBackupFile);
3174                         mcr.setDiskWriteResult(false);
3175                         return;
3176                     }
3177                 } else {
3178                     mFile.delete();
3179                 }
3180             }
3181 
3182             // Attempt to write the file, delete the backup and return true as atomically as
3183             // possible.  If any exception occurs, delete the new file; next time we will restore
3184             // from the backup.
3185             try {
3186                 FileOutputStream str = createFileOutputStream(mFile);
3187                 if (str == null) {
3188                     mcr.setDiskWriteResult(false);
3189                     return;
3190                 }
3191                 XmlUtils.writeMapXml(mcr.mapToWriteToDisk, str);
3192                 FileUtils.sync(str);
3193                 str.close();
3194                 setFilePermissionsFromMode(mFile.getPath(), mMode, 0);
3195                 FileStatus stat = new FileStatus();
3196                 if (FileUtils.getFileStatus(mFile.getPath(), stat)) {
3197                     synchronized (this) {
3198                         mStatTimestamp = stat.mtime;
3199                         mStatSize = stat.size;
3200                     }
3201                 }
3202                 // Writing was successful, delete the backup file if there is one.
3203                 mBackupFile.delete();
3204                 mcr.setDiskWriteResult(true);
3205                 return;
3206             } catch (XmlPullParserException e) {
3207                 Log.w(TAG, "writeToFile: Got exception:", e);
3208             } catch (IOException e) {
3209                 Log.w(TAG, "writeToFile: Got exception:", e);
3210             }
3211             // Clean up an unsuccessfully written file
3212             if (mFile.exists()) {
3213                 if (!mFile.delete()) {
3214                     Log.e(TAG, "Couldn't clean up partially-written file " + mFile);
3215                 }
3216             }
3217             mcr.setDiskWriteResult(false);
3218         }
3219     }
3220 }
3221