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