Home | History | Annotate | Download | only in app
      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 
     21 import android.content.BroadcastReceiver;
     22 import android.content.ComponentName;
     23 import android.content.ContentResolver;
     24 import android.content.Context;
     25 import android.content.ContextWrapper;
     26 import android.content.IContentProvider;
     27 import android.content.Intent;
     28 import android.content.IntentFilter;
     29 import android.content.IIntentReceiver;
     30 import android.content.IntentSender;
     31 import android.content.ReceiverCallNotAllowedException;
     32 import android.content.ServiceConnection;
     33 import android.content.SharedPreferences;
     34 import android.content.pm.ApplicationInfo;
     35 import android.content.pm.IPackageManager;
     36 import android.content.pm.PackageManager;
     37 import android.content.res.AssetManager;
     38 import android.content.res.CompatibilityInfo;
     39 import android.content.res.Resources;
     40 import android.database.DatabaseErrorHandler;
     41 import android.database.sqlite.SQLiteDatabase;
     42 import android.database.sqlite.SQLiteDatabase.CursorFactory;
     43 import android.graphics.Bitmap;
     44 import android.graphics.drawable.Drawable;
     45 import android.hardware.SensorManager;
     46 import android.hardware.usb.IUsbManager;
     47 import android.hardware.usb.UsbManager;
     48 import android.location.CountryDetector;
     49 import android.location.ICountryDetector;
     50 import android.location.ILocationManager;
     51 import android.location.LocationManager;
     52 import android.media.AudioManager;
     53 import android.net.ConnectivityManager;
     54 import android.net.IConnectivityManager;
     55 import android.net.INetworkPolicyManager;
     56 import android.net.NetworkPolicyManager;
     57 import android.net.ThrottleManager;
     58 import android.net.IThrottleManager;
     59 import android.net.Uri;
     60 import android.net.wifi.IWifiManager;
     61 import android.net.wifi.WifiManager;
     62 import android.net.wifi.p2p.IWifiP2pManager;
     63 import android.net.wifi.p2p.WifiP2pManager;
     64 import android.nfc.NfcManager;
     65 import android.os.Binder;
     66 import android.os.Bundle;
     67 import android.os.DropBoxManager;
     68 import android.os.Environment;
     69 import android.os.FileUtils;
     70 import android.os.Handler;
     71 import android.os.IBinder;
     72 import android.os.IPowerManager;
     73 import android.os.Looper;
     74 import android.os.PowerManager;
     75 import android.os.Process;
     76 import android.os.RemoteException;
     77 import android.os.ServiceManager;
     78 import android.os.Vibrator;
     79 import android.os.storage.StorageManager;
     80 import android.telephony.TelephonyManager;
     81 import android.content.ClipboardManager;
     82 import android.util.AndroidRuntimeException;
     83 import android.util.Log;
     84 import android.view.ContextThemeWrapper;
     85 import android.view.WindowManagerImpl;
     86 import android.view.accessibility.AccessibilityManager;
     87 import android.view.inputmethod.InputMethodManager;
     88 import android.view.textservice.TextServicesManager;
     89 import android.accounts.AccountManager;
     90 import android.accounts.IAccountManager;
     91 import android.app.admin.DevicePolicyManager;
     92 import com.android.internal.os.IDropBoxManagerService;
     93 
     94 import java.io.File;
     95 import java.io.FileInputStream;
     96 import java.io.FileNotFoundException;
     97 import java.io.FileOutputStream;
     98 import java.io.IOException;
     99 import java.io.InputStream;
    100 import java.util.ArrayList;
    101 import java.util.HashMap;
    102 
    103 class ReceiverRestrictedContext extends ContextWrapper {
    104     ReceiverRestrictedContext(Context base) {
    105         super(base);
    106     }
    107 
    108     @Override
    109     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    110         return registerReceiver(receiver, filter, null, null);
    111     }
    112 
    113     @Override
    114     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    115             String broadcastPermission, Handler scheduler) {
    116         throw new ReceiverCallNotAllowedException(
    117                 "IntentReceiver components are not allowed to register to receive intents");
    118         //ex.fillInStackTrace();
    119         //Log.e("IntentReceiver", ex.getMessage(), ex);
    120         //return mContext.registerReceiver(receiver, filter, broadcastPermission,
    121         //        scheduler);
    122     }
    123 
    124     @Override
    125     public boolean bindService(Intent service, ServiceConnection conn, int flags) {
    126         throw new ReceiverCallNotAllowedException(
    127                 "IntentReceiver components are not allowed to bind to services");
    128         //ex.fillInStackTrace();
    129         //Log.e("IntentReceiver", ex.getMessage(), ex);
    130         //return mContext.bindService(service, interfaceName, conn, flags);
    131     }
    132 }
    133 
    134 /**
    135  * Common implementation of Context API, which provides the base
    136  * context object for Activity and other application components.
    137  */
    138 class ContextImpl extends Context {
    139     private final static String TAG = "ApplicationContext";
    140     private final static boolean DEBUG = false;
    141 
    142     private static final HashMap<String, SharedPreferencesImpl> sSharedPrefs =
    143             new HashMap<String, SharedPreferencesImpl>();
    144 
    145     /*package*/ LoadedApk mPackageInfo;
    146     private String mBasePackageName;
    147     private Resources mResources;
    148     /*package*/ ActivityThread mMainThread;
    149     private Context mOuterContext;
    150     private IBinder mActivityToken = null;
    151     private ApplicationContentResolver mContentResolver;
    152     private int mThemeResource = 0;
    153     private Resources.Theme mTheme = null;
    154     private PackageManager mPackageManager;
    155     private Context mReceiverRestrictedContext = null;
    156     private boolean mRestricted;
    157 
    158     private final Object mSync = new Object();
    159 
    160     private File mDatabasesDir;
    161     private File mPreferencesDir;
    162     private File mFilesDir;
    163     private File mCacheDir;
    164     private File mObbDir;
    165     private File mExternalFilesDir;
    166     private File mExternalCacheDir;
    167 
    168     private static final String[] EMPTY_FILE_LIST = {};
    169 
    170     /**
    171      * Override this class when the system service constructor needs a
    172      * ContextImpl.  Else, use StaticServiceFetcher below.
    173      */
    174     /*package*/ static class ServiceFetcher {
    175         int mContextCacheIndex = -1;
    176 
    177         /**
    178          * Main entrypoint; only override if you don't need caching.
    179          */
    180         public Object getService(ContextImpl ctx) {
    181             ArrayList<Object> cache = ctx.mServiceCache;
    182             Object service;
    183             synchronized (cache) {
    184                 if (cache.size() == 0) {
    185                     // Initialize the cache vector on first access.
    186                     // At this point sNextPerContextServiceCacheIndex
    187                     // is the number of potential services that are
    188                     // cached per-Context.
    189                     for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
    190                         cache.add(null);
    191                     }
    192                 } else {
    193                     service = cache.get(mContextCacheIndex);
    194                     if (service != null) {
    195                         return service;
    196                     }
    197                 }
    198                 service = createService(ctx);
    199                 cache.set(mContextCacheIndex, service);
    200                 return service;
    201             }
    202         }
    203 
    204         /**
    205          * Override this to create a new per-Context instance of the
    206          * service.  getService() will handle locking and caching.
    207          */
    208         public Object createService(ContextImpl ctx) {
    209             throw new RuntimeException("Not implemented");
    210         }
    211     }
    212 
    213     /**
    214      * Override this class for services to be cached process-wide.
    215      */
    216     abstract static class StaticServiceFetcher extends ServiceFetcher {
    217         private Object mCachedInstance;
    218 
    219         @Override
    220         public final Object getService(ContextImpl unused) {
    221             synchronized (StaticServiceFetcher.this) {
    222                 Object service = mCachedInstance;
    223                 if (service != null) {
    224                     return service;
    225                 }
    226                 return mCachedInstance = createStaticService();
    227             }
    228         }
    229 
    230         public abstract Object createStaticService();
    231     }
    232 
    233     private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
    234             new HashMap<String, ServiceFetcher>();
    235 
    236     private static int sNextPerContextServiceCacheIndex = 0;
    237     private static void registerService(String serviceName, ServiceFetcher fetcher) {
    238         if (!(fetcher instanceof StaticServiceFetcher)) {
    239             fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
    240         }
    241         SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
    242     }
    243 
    244     // This one's defined separately and given a variable name so it
    245     // can be re-used by getWallpaperManager(), avoiding a HashMap
    246     // lookup.
    247     private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
    248             public Object createService(ContextImpl ctx) {
    249                 return new WallpaperManager(ctx.getOuterContext(),
    250                         ctx.mMainThread.getHandler());
    251             }};
    252 
    253     static {
    254         registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
    255                 public Object getService(ContextImpl ctx) {
    256                     return AccessibilityManager.getInstance(ctx);
    257                 }});
    258 
    259         registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
    260                 public Object createService(ContextImpl ctx) {
    261                     IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
    262                     IAccountManager service = IAccountManager.Stub.asInterface(b);
    263                     return new AccountManager(ctx, service);
    264                 }});
    265 
    266         registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
    267                 public Object createService(ContextImpl ctx) {
    268                     return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
    269                 }});
    270 
    271         registerService(ALARM_SERVICE, new StaticServiceFetcher() {
    272                 public Object createStaticService() {
    273                     IBinder b = ServiceManager.getService(ALARM_SERVICE);
    274                     IAlarmManager service = IAlarmManager.Stub.asInterface(b);
    275                     return new AlarmManager(service);
    276                 }});
    277 
    278         registerService(AUDIO_SERVICE, new ServiceFetcher() {
    279                 public Object createService(ContextImpl ctx) {
    280                     return new AudioManager(ctx);
    281                 }});
    282 
    283         registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
    284                 public Object createService(ContextImpl ctx) {
    285                     return new ClipboardManager(ctx.getOuterContext(),
    286                             ctx.mMainThread.getHandler());
    287                 }});
    288 
    289         registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
    290                 public Object createStaticService() {
    291                     IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
    292                     return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
    293                 }});
    294 
    295         registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
    296                 public Object createStaticService() {
    297                     IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
    298                     return new CountryDetector(ICountryDetector.Stub.asInterface(b));
    299                 }});
    300 
    301         registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
    302                 public Object createService(ContextImpl ctx) {
    303                     return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
    304                 }});
    305 
    306         registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
    307                 public Object createService(ContextImpl ctx) {
    308                     return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
    309                 }});
    310 
    311         registerService(NFC_SERVICE, new ServiceFetcher() {
    312                 public Object createService(ContextImpl ctx) {
    313                     return new NfcManager(ctx);
    314                 }});
    315 
    316         registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
    317                 public Object createStaticService() {
    318                     return createDropBoxManager();
    319                 }});
    320 
    321         registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
    322                 public Object createService(ContextImpl ctx) {
    323                     return InputMethodManager.getInstance(ctx);
    324                 }});
    325 
    326         registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
    327                 public Object createService(ContextImpl ctx) {
    328                     return TextServicesManager.getInstance();
    329                 }});
    330 
    331         registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
    332                 public Object getService(ContextImpl ctx) {
    333                     // TODO: why isn't this caching it?  It wasn't
    334                     // before, so I'm preserving the old behavior and
    335                     // using getService(), instead of createService()
    336                     // which would do the caching.
    337                     return new KeyguardManager();
    338                 }});
    339 
    340         registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
    341                 public Object createService(ContextImpl ctx) {
    342                     return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
    343                 }});
    344 
    345         registerService(LOCATION_SERVICE, new StaticServiceFetcher() {
    346                 public Object createStaticService() {
    347                     IBinder b = ServiceManager.getService(LOCATION_SERVICE);
    348                     return new LocationManager(ILocationManager.Stub.asInterface(b));
    349                 }});
    350 
    351         registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
    352             @Override
    353             public Object createService(ContextImpl ctx) {
    354                 return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
    355                         ServiceManager.getService(NETWORK_POLICY_SERVICE)));
    356             }
    357         });
    358 
    359         registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
    360                 public Object createService(ContextImpl ctx) {
    361                     final Context outerContext = ctx.getOuterContext();
    362                     return new NotificationManager(
    363                         new ContextThemeWrapper(outerContext,
    364                                 Resources.selectSystemTheme(0,
    365                                         outerContext.getApplicationInfo().targetSdkVersion,
    366                                         com.android.internal.R.style.Theme_Dialog,
    367                                         com.android.internal.R.style.Theme_Holo_Dialog,
    368                                         com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
    369                         ctx.mMainThread.getHandler());
    370                 }});
    371 
    372         // Note: this was previously cached in a static variable, but
    373         // constructed using mMainThread.getHandler(), so converting
    374         // it to be a regular Context-cached service...
    375         registerService(POWER_SERVICE, new ServiceFetcher() {
    376                 public Object createService(ContextImpl ctx) {
    377                     IBinder b = ServiceManager.getService(POWER_SERVICE);
    378                     IPowerManager service = IPowerManager.Stub.asInterface(b);
    379                     return new PowerManager(service, ctx.mMainThread.getHandler());
    380                 }});
    381 
    382         registerService(SEARCH_SERVICE, new ServiceFetcher() {
    383                 public Object createService(ContextImpl ctx) {
    384                     return new SearchManager(ctx.getOuterContext(),
    385                             ctx.mMainThread.getHandler());
    386                 }});
    387 
    388         registerService(SENSOR_SERVICE, new ServiceFetcher() {
    389                 public Object createService(ContextImpl ctx) {
    390                     return new SensorManager(ctx.mMainThread.getHandler().getLooper());
    391                 }});
    392 
    393         registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
    394                 public Object createService(ContextImpl ctx) {
    395                     return new StatusBarManager(ctx.getOuterContext());
    396                 }});
    397 
    398         registerService(STORAGE_SERVICE, new ServiceFetcher() {
    399                 public Object createService(ContextImpl ctx) {
    400                     try {
    401                         return new StorageManager(ctx.mMainThread.getHandler().getLooper());
    402                     } catch (RemoteException rex) {
    403                         Log.e(TAG, "Failed to create StorageManager", rex);
    404                         return null;
    405                     }
    406                 }});
    407 
    408         registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
    409                 public Object createService(ContextImpl ctx) {
    410                     return new TelephonyManager(ctx.getOuterContext());
    411                 }});
    412 
    413         registerService(THROTTLE_SERVICE, new StaticServiceFetcher() {
    414                 public Object createStaticService() {
    415                     IBinder b = ServiceManager.getService(THROTTLE_SERVICE);
    416                     return new ThrottleManager(IThrottleManager.Stub.asInterface(b));
    417                 }});
    418 
    419         registerService(UI_MODE_SERVICE, new ServiceFetcher() {
    420                 public Object createService(ContextImpl ctx) {
    421                     return new UiModeManager();
    422                 }});
    423 
    424         registerService(USB_SERVICE, new ServiceFetcher() {
    425                 public Object createService(ContextImpl ctx) {
    426                     IBinder b = ServiceManager.getService(USB_SERVICE);
    427                     return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
    428                 }});
    429 
    430         registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
    431                 public Object createService(ContextImpl ctx) {
    432                     return new Vibrator();
    433                 }});
    434 
    435         registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
    436 
    437         registerService(WIFI_SERVICE, new ServiceFetcher() {
    438                 public Object createService(ContextImpl ctx) {
    439                     IBinder b = ServiceManager.getService(WIFI_SERVICE);
    440                     IWifiManager service = IWifiManager.Stub.asInterface(b);
    441                     return new WifiManager(service, ctx.mMainThread.getHandler());
    442                 }});
    443 
    444         registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
    445                 public Object createService(ContextImpl ctx) {
    446                     IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
    447                     IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
    448                     return new WifiP2pManager(service);
    449                 }});
    450 
    451         registerService(WINDOW_SERVICE, new ServiceFetcher() {
    452                 public Object getService(ContextImpl ctx) {
    453                     return WindowManagerImpl.getDefault(ctx.mPackageInfo.mCompatibilityInfo);
    454                 }});
    455     }
    456 
    457     static ContextImpl getImpl(Context context) {
    458         Context nextContext;
    459         while ((context instanceof ContextWrapper) &&
    460                 (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
    461             context = nextContext;
    462         }
    463         return (ContextImpl)context;
    464     }
    465 
    466     // The system service cache for the system services that are
    467     // cached per-ContextImpl.  Package-scoped to avoid accessor
    468     // methods.
    469     final ArrayList<Object> mServiceCache = new ArrayList<Object>();
    470 
    471     @Override
    472     public AssetManager getAssets() {
    473         return mResources.getAssets();
    474     }
    475 
    476     @Override
    477     public Resources getResources() {
    478         return mResources;
    479     }
    480 
    481     @Override
    482     public PackageManager getPackageManager() {
    483         if (mPackageManager != null) {
    484             return mPackageManager;
    485         }
    486 
    487         IPackageManager pm = ActivityThread.getPackageManager();
    488         if (pm != null) {
    489             // Doesn't matter if we make more than one instance.
    490             return (mPackageManager = new ApplicationPackageManager(this, pm));
    491         }
    492 
    493         return null;
    494     }
    495 
    496     @Override
    497     public ContentResolver getContentResolver() {
    498         return mContentResolver;
    499     }
    500 
    501     @Override
    502     public Looper getMainLooper() {
    503         return mMainThread.getLooper();
    504     }
    505 
    506     @Override
    507     public Context getApplicationContext() {
    508         return (mPackageInfo != null) ?
    509                 mPackageInfo.getApplication() : mMainThread.getApplication();
    510     }
    511 
    512     @Override
    513     public void setTheme(int resid) {
    514         mThemeResource = resid;
    515     }
    516 
    517     @Override
    518     public int getThemeResId() {
    519         return mThemeResource;
    520     }
    521 
    522     @Override
    523     public Resources.Theme getTheme() {
    524         if (mTheme == null) {
    525             mThemeResource = Resources.selectDefaultTheme(mThemeResource,
    526                     getOuterContext().getApplicationInfo().targetSdkVersion);
    527             mTheme = mResources.newTheme();
    528             mTheme.applyStyle(mThemeResource, true);
    529         }
    530         return mTheme;
    531     }
    532 
    533     @Override
    534     public ClassLoader getClassLoader() {
    535         return mPackageInfo != null ?
    536                 mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
    537     }
    538 
    539     @Override
    540     public String getPackageName() {
    541         if (mPackageInfo != null) {
    542             return mPackageInfo.getPackageName();
    543         }
    544         throw new RuntimeException("Not supported in system context");
    545     }
    546 
    547     @Override
    548     public ApplicationInfo getApplicationInfo() {
    549         if (mPackageInfo != null) {
    550             return mPackageInfo.getApplicationInfo();
    551         }
    552         throw new RuntimeException("Not supported in system context");
    553     }
    554 
    555     @Override
    556     public String getPackageResourcePath() {
    557         if (mPackageInfo != null) {
    558             return mPackageInfo.getResDir();
    559         }
    560         throw new RuntimeException("Not supported in system context");
    561     }
    562 
    563     @Override
    564     public String getPackageCodePath() {
    565         if (mPackageInfo != null) {
    566             return mPackageInfo.getAppDir();
    567         }
    568         throw new RuntimeException("Not supported in system context");
    569     }
    570 
    571     public File getSharedPrefsFile(String name) {
    572         return makeFilename(getPreferencesDir(), name + ".xml");
    573     }
    574 
    575     @Override
    576     public SharedPreferences getSharedPreferences(String name, int mode) {
    577         SharedPreferencesImpl sp;
    578         synchronized (sSharedPrefs) {
    579             sp = sSharedPrefs.get(name);
    580             if (sp == null) {
    581                 File prefsFile = getSharedPrefsFile(name);
    582                 sp = new SharedPreferencesImpl(prefsFile, mode);
    583                 sSharedPrefs.put(name, sp);
    584                 return sp;
    585             }
    586         }
    587         if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
    588             getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
    589             // If somebody else (some other process) changed the prefs
    590             // file behind our back, we reload it.  This has been the
    591             // historical (if undocumented) behavior.
    592             sp.startReloadIfChangedUnexpectedly();
    593         }
    594         return sp;
    595     }
    596 
    597     private File getPreferencesDir() {
    598         synchronized (mSync) {
    599             if (mPreferencesDir == null) {
    600                 mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
    601             }
    602             return mPreferencesDir;
    603         }
    604     }
    605 
    606     @Override
    607     public FileInputStream openFileInput(String name)
    608         throws FileNotFoundException {
    609         File f = makeFilename(getFilesDir(), name);
    610         return new FileInputStream(f);
    611     }
    612 
    613     @Override
    614     public FileOutputStream openFileOutput(String name, int mode)
    615         throws FileNotFoundException {
    616         final boolean append = (mode&MODE_APPEND) != 0;
    617         File f = makeFilename(getFilesDir(), name);
    618         try {
    619             FileOutputStream fos = new FileOutputStream(f, append);
    620             setFilePermissionsFromMode(f.getPath(), mode, 0);
    621             return fos;
    622         } catch (FileNotFoundException e) {
    623         }
    624 
    625         File parent = f.getParentFile();
    626         parent.mkdir();
    627         FileUtils.setPermissions(
    628             parent.getPath(),
    629             FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
    630             -1, -1);
    631         FileOutputStream fos = new FileOutputStream(f, append);
    632         setFilePermissionsFromMode(f.getPath(), mode, 0);
    633         return fos;
    634     }
    635 
    636     @Override
    637     public boolean deleteFile(String name) {
    638         File f = makeFilename(getFilesDir(), name);
    639         return f.delete();
    640     }
    641 
    642     @Override
    643     public File getFilesDir() {
    644         synchronized (mSync) {
    645             if (mFilesDir == null) {
    646                 mFilesDir = new File(getDataDirFile(), "files");
    647             }
    648             if (!mFilesDir.exists()) {
    649                 if(!mFilesDir.mkdirs()) {
    650                     Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
    651                     return null;
    652                 }
    653                 FileUtils.setPermissions(
    654                         mFilesDir.getPath(),
    655                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
    656                         -1, -1);
    657             }
    658             return mFilesDir;
    659         }
    660     }
    661 
    662     @Override
    663     public File getExternalFilesDir(String type) {
    664         synchronized (mSync) {
    665             if (mExternalFilesDir == null) {
    666                 mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
    667                         getPackageName());
    668             }
    669             if (!mExternalFilesDir.exists()) {
    670                 try {
    671                     (new File(Environment.getExternalStorageAndroidDataDir(),
    672                             ".nomedia")).createNewFile();
    673                 } catch (IOException e) {
    674                 }
    675                 if (!mExternalFilesDir.mkdirs()) {
    676                     Log.w(TAG, "Unable to create external files directory");
    677                     return null;
    678                 }
    679             }
    680             if (type == null) {
    681                 return mExternalFilesDir;
    682             }
    683             File dir = new File(mExternalFilesDir, type);
    684             if (!dir.exists()) {
    685                 if (!dir.mkdirs()) {
    686                     Log.w(TAG, "Unable to create external media directory " + dir);
    687                     return null;
    688                 }
    689             }
    690             return dir;
    691         }
    692     }
    693 
    694     @Override
    695     public File getObbDir() {
    696         synchronized (mSync) {
    697             if (mObbDir == null) {
    698                 mObbDir = Environment.getExternalStorageAppObbDirectory(
    699                         getPackageName());
    700             }
    701             return mObbDir;
    702         }
    703     }
    704 
    705     @Override
    706     public File getCacheDir() {
    707         synchronized (mSync) {
    708             if (mCacheDir == null) {
    709                 mCacheDir = new File(getDataDirFile(), "cache");
    710             }
    711             if (!mCacheDir.exists()) {
    712                 if(!mCacheDir.mkdirs()) {
    713                     Log.w(TAG, "Unable to create cache directory");
    714                     return null;
    715                 }
    716                 FileUtils.setPermissions(
    717                         mCacheDir.getPath(),
    718                         FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
    719                         -1, -1);
    720             }
    721         }
    722         return mCacheDir;
    723     }
    724 
    725     @Override
    726     public File getExternalCacheDir() {
    727         synchronized (mSync) {
    728             if (mExternalCacheDir == null) {
    729                 mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
    730                         getPackageName());
    731             }
    732             if (!mExternalCacheDir.exists()) {
    733                 try {
    734                     (new File(Environment.getExternalStorageAndroidDataDir(),
    735                             ".nomedia")).createNewFile();
    736                 } catch (IOException e) {
    737                 }
    738                 if (!mExternalCacheDir.mkdirs()) {
    739                     Log.w(TAG, "Unable to create external cache directory");
    740                     return null;
    741                 }
    742             }
    743             return mExternalCacheDir;
    744         }
    745     }
    746 
    747     @Override
    748     public File getFileStreamPath(String name) {
    749         return makeFilename(getFilesDir(), name);
    750     }
    751 
    752     @Override
    753     public String[] fileList() {
    754         final String[] list = getFilesDir().list();
    755         return (list != null) ? list : EMPTY_FILE_LIST;
    756     }
    757 
    758     @Override
    759     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
    760         File f = validateFilePath(name, true);
    761         SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f, factory);
    762         setFilePermissionsFromMode(f.getPath(), mode, 0);
    763         return db;
    764     }
    765 
    766     @Override
    767     public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
    768             DatabaseErrorHandler errorHandler) {
    769         File f = validateFilePath(name, true);
    770         SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(f.getPath(), factory, errorHandler);
    771         setFilePermissionsFromMode(f.getPath(), mode, 0);
    772         return db;
    773     }
    774 
    775     @Override
    776     public boolean deleteDatabase(String name) {
    777         try {
    778             File f = validateFilePath(name, false);
    779             return f.delete();
    780         } catch (Exception e) {
    781         }
    782         return false;
    783     }
    784 
    785     @Override
    786     public File getDatabasePath(String name) {
    787         return validateFilePath(name, false);
    788     }
    789 
    790     @Override
    791     public String[] databaseList() {
    792         final String[] list = getDatabasesDir().list();
    793         return (list != null) ? list : EMPTY_FILE_LIST;
    794     }
    795 
    796 
    797     private File getDatabasesDir() {
    798         synchronized (mSync) {
    799             if (mDatabasesDir == null) {
    800                 mDatabasesDir = new File(getDataDirFile(), "databases");
    801             }
    802             if (mDatabasesDir.getPath().equals("databases")) {
    803                 mDatabasesDir = new File("/data/system");
    804             }
    805             return mDatabasesDir;
    806         }
    807     }
    808 
    809     @Override
    810     public Drawable getWallpaper() {
    811         return getWallpaperManager().getDrawable();
    812     }
    813 
    814     @Override
    815     public Drawable peekWallpaper() {
    816         return getWallpaperManager().peekDrawable();
    817     }
    818 
    819     @Override
    820     public int getWallpaperDesiredMinimumWidth() {
    821         return getWallpaperManager().getDesiredMinimumWidth();
    822     }
    823 
    824     @Override
    825     public int getWallpaperDesiredMinimumHeight() {
    826         return getWallpaperManager().getDesiredMinimumHeight();
    827     }
    828 
    829     @Override
    830     public void setWallpaper(Bitmap bitmap) throws IOException  {
    831         getWallpaperManager().setBitmap(bitmap);
    832     }
    833 
    834     @Override
    835     public void setWallpaper(InputStream data) throws IOException {
    836         getWallpaperManager().setStream(data);
    837     }
    838 
    839     @Override
    840     public void clearWallpaper() throws IOException {
    841         getWallpaperManager().clear();
    842     }
    843 
    844     @Override
    845     public void startActivity(Intent intent) {
    846         if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
    847             throw new AndroidRuntimeException(
    848                     "Calling startActivity() from outside of an Activity "
    849                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
    850                     + " Is this really what you want?");
    851         }
    852         mMainThread.getInstrumentation().execStartActivity(
    853             getOuterContext(), mMainThread.getApplicationThread(), null,
    854             (Activity)null, intent, -1);
    855     }
    856 
    857     @Override
    858     public void startActivities(Intent[] intents) {
    859         if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
    860             throw new AndroidRuntimeException(
    861                     "Calling startActivities() from outside of an Activity "
    862                     + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
    863                     + " Is this really what you want?");
    864         }
    865         mMainThread.getInstrumentation().execStartActivities(
    866             getOuterContext(), mMainThread.getApplicationThread(), null,
    867             (Activity)null, intents);
    868     }
    869 
    870     @Override
    871     public void startIntentSender(IntentSender intent,
    872             Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
    873             throws IntentSender.SendIntentException {
    874         try {
    875             String resolvedType = null;
    876             if (fillInIntent != null) {
    877                 fillInIntent.setAllowFds(false);
    878                 resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
    879             }
    880             int result = ActivityManagerNative.getDefault()
    881                 .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
    882                         fillInIntent, resolvedType, null, null,
    883                         0, flagsMask, flagsValues);
    884             if (result == IActivityManager.START_CANCELED) {
    885                 throw new IntentSender.SendIntentException();
    886             }
    887             Instrumentation.checkStartActivityResult(result, null);
    888         } catch (RemoteException e) {
    889         }
    890     }
    891 
    892     @Override
    893     public void sendBroadcast(Intent intent) {
    894         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    895         try {
    896             intent.setAllowFds(false);
    897             ActivityManagerNative.getDefault().broadcastIntent(
    898                 mMainThread.getApplicationThread(), intent, resolvedType, null,
    899                 Activity.RESULT_OK, null, null, null, false, false);
    900         } catch (RemoteException e) {
    901         }
    902     }
    903 
    904     @Override
    905     public void sendBroadcast(Intent intent, String receiverPermission) {
    906         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    907         try {
    908             intent.setAllowFds(false);
    909             ActivityManagerNative.getDefault().broadcastIntent(
    910                 mMainThread.getApplicationThread(), intent, resolvedType, null,
    911                 Activity.RESULT_OK, null, null, receiverPermission, false, false);
    912         } catch (RemoteException e) {
    913         }
    914     }
    915 
    916     @Override
    917     public void sendOrderedBroadcast(Intent intent,
    918             String receiverPermission) {
    919         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    920         try {
    921             intent.setAllowFds(false);
    922             ActivityManagerNative.getDefault().broadcastIntent(
    923                 mMainThread.getApplicationThread(), intent, resolvedType, null,
    924                 Activity.RESULT_OK, null, null, receiverPermission, true, false);
    925         } catch (RemoteException e) {
    926         }
    927     }
    928 
    929     @Override
    930     public void sendOrderedBroadcast(Intent intent,
    931             String receiverPermission, BroadcastReceiver resultReceiver,
    932             Handler scheduler, int initialCode, String initialData,
    933             Bundle initialExtras) {
    934         IIntentReceiver rd = null;
    935         if (resultReceiver != null) {
    936             if (mPackageInfo != null) {
    937                 if (scheduler == null) {
    938                     scheduler = mMainThread.getHandler();
    939                 }
    940                 rd = mPackageInfo.getReceiverDispatcher(
    941                     resultReceiver, getOuterContext(), scheduler,
    942                     mMainThread.getInstrumentation(), false);
    943             } else {
    944                 if (scheduler == null) {
    945                     scheduler = mMainThread.getHandler();
    946                 }
    947                 rd = new LoadedApk.ReceiverDispatcher(
    948                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
    949             }
    950         }
    951         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    952         try {
    953             intent.setAllowFds(false);
    954             ActivityManagerNative.getDefault().broadcastIntent(
    955                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
    956                 initialCode, initialData, initialExtras, receiverPermission,
    957                 true, false);
    958         } catch (RemoteException e) {
    959         }
    960     }
    961 
    962     @Override
    963     public void sendStickyBroadcast(Intent intent) {
    964         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    965         try {
    966             intent.setAllowFds(false);
    967             ActivityManagerNative.getDefault().broadcastIntent(
    968                 mMainThread.getApplicationThread(), intent, resolvedType, null,
    969                 Activity.RESULT_OK, null, null, null, false, true);
    970         } catch (RemoteException e) {
    971         }
    972     }
    973 
    974     @Override
    975     public void sendStickyOrderedBroadcast(Intent intent,
    976             BroadcastReceiver resultReceiver,
    977             Handler scheduler, int initialCode, String initialData,
    978             Bundle initialExtras) {
    979         IIntentReceiver rd = null;
    980         if (resultReceiver != null) {
    981             if (mPackageInfo != null) {
    982                 if (scheduler == null) {
    983                     scheduler = mMainThread.getHandler();
    984                 }
    985                 rd = mPackageInfo.getReceiverDispatcher(
    986                     resultReceiver, getOuterContext(), scheduler,
    987                     mMainThread.getInstrumentation(), false);
    988             } else {
    989                 if (scheduler == null) {
    990                     scheduler = mMainThread.getHandler();
    991                 }
    992                 rd = new LoadedApk.ReceiverDispatcher(
    993                         resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
    994             }
    995         }
    996         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    997         try {
    998             intent.setAllowFds(false);
    999             ActivityManagerNative.getDefault().broadcastIntent(
   1000                 mMainThread.getApplicationThread(), intent, resolvedType, rd,
   1001                 initialCode, initialData, initialExtras, null,
   1002                 true, true);
   1003         } catch (RemoteException e) {
   1004         }
   1005     }
   1006 
   1007     @Override
   1008     public void removeStickyBroadcast(Intent intent) {
   1009         String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
   1010         if (resolvedType != null) {
   1011             intent = new Intent(intent);
   1012             intent.setDataAndType(intent.getData(), resolvedType);
   1013         }
   1014         try {
   1015             intent.setAllowFds(false);
   1016             ActivityManagerNative.getDefault().unbroadcastIntent(
   1017                 mMainThread.getApplicationThread(), intent);
   1018         } catch (RemoteException e) {
   1019         }
   1020     }
   1021 
   1022     @Override
   1023     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
   1024         return registerReceiver(receiver, filter, null, null);
   1025     }
   1026 
   1027     @Override
   1028     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
   1029             String broadcastPermission, Handler scheduler) {
   1030         return registerReceiverInternal(receiver, filter, broadcastPermission,
   1031                 scheduler, getOuterContext());
   1032     }
   1033 
   1034     private Intent registerReceiverInternal(BroadcastReceiver receiver,
   1035             IntentFilter filter, String broadcastPermission,
   1036             Handler scheduler, Context context) {
   1037         IIntentReceiver rd = null;
   1038         if (receiver != null) {
   1039             if (mPackageInfo != null && context != null) {
   1040                 if (scheduler == null) {
   1041                     scheduler = mMainThread.getHandler();
   1042                 }
   1043                 rd = mPackageInfo.getReceiverDispatcher(
   1044                     receiver, context, scheduler,
   1045                     mMainThread.getInstrumentation(), true);
   1046             } else {
   1047                 if (scheduler == null) {
   1048                     scheduler = mMainThread.getHandler();
   1049                 }
   1050                 rd = new LoadedApk.ReceiverDispatcher(
   1051                         receiver, context, scheduler, null, true).getIIntentReceiver();
   1052             }
   1053         }
   1054         try {
   1055             return ActivityManagerNative.getDefault().registerReceiver(
   1056                     mMainThread.getApplicationThread(), mBasePackageName,
   1057                     rd, filter, broadcastPermission);
   1058         } catch (RemoteException e) {
   1059             return null;
   1060         }
   1061     }
   1062 
   1063     @Override
   1064     public void unregisterReceiver(BroadcastReceiver receiver) {
   1065         if (mPackageInfo != null) {
   1066             IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
   1067                     getOuterContext(), receiver);
   1068             try {
   1069                 ActivityManagerNative.getDefault().unregisterReceiver(rd);
   1070             } catch (RemoteException e) {
   1071             }
   1072         } else {
   1073             throw new RuntimeException("Not supported in system context");
   1074         }
   1075     }
   1076 
   1077     @Override
   1078     public ComponentName startService(Intent service) {
   1079         try {
   1080             service.setAllowFds(false);
   1081             ComponentName cn = ActivityManagerNative.getDefault().startService(
   1082                 mMainThread.getApplicationThread(), service,
   1083                 service.resolveTypeIfNeeded(getContentResolver()));
   1084             if (cn != null && cn.getPackageName().equals("!")) {
   1085                 throw new SecurityException(
   1086                         "Not allowed to start service " + service
   1087                         + " without permission " + cn.getClassName());
   1088             }
   1089             return cn;
   1090         } catch (RemoteException e) {
   1091             return null;
   1092         }
   1093     }
   1094 
   1095     @Override
   1096     public boolean stopService(Intent service) {
   1097         try {
   1098             service.setAllowFds(false);
   1099             int res = ActivityManagerNative.getDefault().stopService(
   1100                 mMainThread.getApplicationThread(), service,
   1101                 service.resolveTypeIfNeeded(getContentResolver()));
   1102             if (res < 0) {
   1103                 throw new SecurityException(
   1104                         "Not allowed to stop service " + service);
   1105             }
   1106             return res != 0;
   1107         } catch (RemoteException e) {
   1108             return false;
   1109         }
   1110     }
   1111 
   1112     @Override
   1113     public boolean bindService(Intent service, ServiceConnection conn,
   1114             int flags) {
   1115         IServiceConnection sd;
   1116         if (mPackageInfo != null) {
   1117             sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
   1118                     mMainThread.getHandler(), flags);
   1119         } else {
   1120             throw new RuntimeException("Not supported in system context");
   1121         }
   1122         try {
   1123             IBinder token = getActivityToken();
   1124             if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
   1125                     && mPackageInfo.getApplicationInfo().targetSdkVersion
   1126                     < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
   1127                 flags |= BIND_WAIVE_PRIORITY;
   1128             }
   1129             service.setAllowFds(false);
   1130             int res = ActivityManagerNative.getDefault().bindService(
   1131                 mMainThread.getApplicationThread(), getActivityToken(),
   1132                 service, service.resolveTypeIfNeeded(getContentResolver()),
   1133                 sd, flags);
   1134             if (res < 0) {
   1135                 throw new SecurityException(
   1136                         "Not allowed to bind to service " + service);
   1137             }
   1138             return res != 0;
   1139         } catch (RemoteException e) {
   1140             return false;
   1141         }
   1142     }
   1143 
   1144     @Override
   1145     public void unbindService(ServiceConnection conn) {
   1146         if (mPackageInfo != null) {
   1147             IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
   1148                     getOuterContext(), conn);
   1149             try {
   1150                 ActivityManagerNative.getDefault().unbindService(sd);
   1151             } catch (RemoteException e) {
   1152             }
   1153         } else {
   1154             throw new RuntimeException("Not supported in system context");
   1155         }
   1156     }
   1157 
   1158     @Override
   1159     public boolean startInstrumentation(ComponentName className,
   1160             String profileFile, Bundle arguments) {
   1161         try {
   1162             if (arguments != null) {
   1163                 arguments.setAllowFds(false);
   1164             }
   1165             return ActivityManagerNative.getDefault().startInstrumentation(
   1166                     className, profileFile, 0, arguments, null);
   1167         } catch (RemoteException e) {
   1168             // System has crashed, nothing we can do.
   1169         }
   1170         return false;
   1171     }
   1172 
   1173     @Override
   1174     public Object getSystemService(String name) {
   1175         ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
   1176         return fetcher == null ? null : fetcher.getService(this);
   1177     }
   1178 
   1179     private WallpaperManager getWallpaperManager() {
   1180         return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
   1181     }
   1182 
   1183     /* package */ static DropBoxManager createDropBoxManager() {
   1184         IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
   1185         IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
   1186         if (service == null) {
   1187             // Don't return a DropBoxManager that will NPE upon use.
   1188             // This also avoids caching a broken DropBoxManager in
   1189             // getDropBoxManager during early boot, before the
   1190             // DROPBOX_SERVICE is registered.
   1191             return null;
   1192         }
   1193         return new DropBoxManager(service);
   1194     }
   1195 
   1196     @Override
   1197     public int checkPermission(String permission, int pid, int uid) {
   1198         if (permission == null) {
   1199             throw new IllegalArgumentException("permission is null");
   1200         }
   1201 
   1202         try {
   1203             return ActivityManagerNative.getDefault().checkPermission(
   1204                     permission, pid, uid);
   1205         } catch (RemoteException e) {
   1206             return PackageManager.PERMISSION_DENIED;
   1207         }
   1208     }
   1209 
   1210     @Override
   1211     public int checkCallingPermission(String permission) {
   1212         if (permission == null) {
   1213             throw new IllegalArgumentException("permission is null");
   1214         }
   1215 
   1216         int pid = Binder.getCallingPid();
   1217         if (pid != Process.myPid()) {
   1218             return checkPermission(permission, pid,
   1219                     Binder.getCallingUid());
   1220         }
   1221         return PackageManager.PERMISSION_DENIED;
   1222     }
   1223 
   1224     @Override
   1225     public int checkCallingOrSelfPermission(String permission) {
   1226         if (permission == null) {
   1227             throw new IllegalArgumentException("permission is null");
   1228         }
   1229 
   1230         return checkPermission(permission, Binder.getCallingPid(),
   1231                 Binder.getCallingUid());
   1232     }
   1233 
   1234     private void enforce(
   1235             String permission, int resultOfCheck,
   1236             boolean selfToo, int uid, String message) {
   1237         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
   1238             throw new SecurityException(
   1239                     (message != null ? (message + ": ") : "") +
   1240                     (selfToo
   1241                      ? "Neither user " + uid + " nor current process has "
   1242                      : "User " + uid + " does not have ") +
   1243                     permission +
   1244                     ".");
   1245         }
   1246     }
   1247 
   1248     public void enforcePermission(
   1249             String permission, int pid, int uid, String message) {
   1250         enforce(permission,
   1251                 checkPermission(permission, pid, uid),
   1252                 false,
   1253                 uid,
   1254                 message);
   1255     }
   1256 
   1257     public void enforceCallingPermission(String permission, String message) {
   1258         enforce(permission,
   1259                 checkCallingPermission(permission),
   1260                 false,
   1261                 Binder.getCallingUid(),
   1262                 message);
   1263     }
   1264 
   1265     public void enforceCallingOrSelfPermission(
   1266             String permission, String message) {
   1267         enforce(permission,
   1268                 checkCallingOrSelfPermission(permission),
   1269                 true,
   1270                 Binder.getCallingUid(),
   1271                 message);
   1272     }
   1273 
   1274     @Override
   1275     public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
   1276          try {
   1277             ActivityManagerNative.getDefault().grantUriPermission(
   1278                     mMainThread.getApplicationThread(), toPackage, uri,
   1279                     modeFlags);
   1280         } catch (RemoteException e) {
   1281         }
   1282     }
   1283 
   1284     @Override
   1285     public void revokeUriPermission(Uri uri, int modeFlags) {
   1286          try {
   1287             ActivityManagerNative.getDefault().revokeUriPermission(
   1288                     mMainThread.getApplicationThread(), uri,
   1289                     modeFlags);
   1290         } catch (RemoteException e) {
   1291         }
   1292     }
   1293 
   1294     @Override
   1295     public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
   1296         try {
   1297             return ActivityManagerNative.getDefault().checkUriPermission(
   1298                     uri, pid, uid, modeFlags);
   1299         } catch (RemoteException e) {
   1300             return PackageManager.PERMISSION_DENIED;
   1301         }
   1302     }
   1303 
   1304     @Override
   1305     public int checkCallingUriPermission(Uri uri, int modeFlags) {
   1306         int pid = Binder.getCallingPid();
   1307         if (pid != Process.myPid()) {
   1308             return checkUriPermission(uri, pid,
   1309                     Binder.getCallingUid(), modeFlags);
   1310         }
   1311         return PackageManager.PERMISSION_DENIED;
   1312     }
   1313 
   1314     @Override
   1315     public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
   1316         return checkUriPermission(uri, Binder.getCallingPid(),
   1317                 Binder.getCallingUid(), modeFlags);
   1318     }
   1319 
   1320     @Override
   1321     public int checkUriPermission(Uri uri, String readPermission,
   1322             String writePermission, int pid, int uid, int modeFlags) {
   1323         if (DEBUG) {
   1324             Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
   1325                     + readPermission + " writePermission=" + writePermission
   1326                     + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
   1327         }
   1328         if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
   1329             if (readPermission == null
   1330                     || checkPermission(readPermission, pid, uid)
   1331                     == PackageManager.PERMISSION_GRANTED) {
   1332                 return PackageManager.PERMISSION_GRANTED;
   1333             }
   1334         }
   1335         if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
   1336             if (writePermission == null
   1337                     || checkPermission(writePermission, pid, uid)
   1338                     == PackageManager.PERMISSION_GRANTED) {
   1339                 return PackageManager.PERMISSION_GRANTED;
   1340             }
   1341         }
   1342         return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
   1343                 : PackageManager.PERMISSION_DENIED;
   1344     }
   1345 
   1346     private String uriModeFlagToString(int uriModeFlags) {
   1347         switch (uriModeFlags) {
   1348             case Intent.FLAG_GRANT_READ_URI_PERMISSION |
   1349                     Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
   1350                 return "read and write";
   1351             case Intent.FLAG_GRANT_READ_URI_PERMISSION:
   1352                 return "read";
   1353             case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
   1354                 return "write";
   1355         }
   1356         throw new IllegalArgumentException(
   1357                 "Unknown permission mode flags: " + uriModeFlags);
   1358     }
   1359 
   1360     private void enforceForUri(
   1361             int modeFlags, int resultOfCheck, boolean selfToo,
   1362             int uid, Uri uri, String message) {
   1363         if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
   1364             throw new SecurityException(
   1365                     (message != null ? (message + ": ") : "") +
   1366                     (selfToo
   1367                      ? "Neither user " + uid + " nor current process has "
   1368                      : "User " + uid + " does not have ") +
   1369                     uriModeFlagToString(modeFlags) +
   1370                     " permission on " +
   1371                     uri +
   1372                     ".");
   1373         }
   1374     }
   1375 
   1376     public void enforceUriPermission(
   1377             Uri uri, int pid, int uid, int modeFlags, String message) {
   1378         enforceForUri(
   1379                 modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
   1380                 false, uid, uri, message);
   1381     }
   1382 
   1383     public void enforceCallingUriPermission(
   1384             Uri uri, int modeFlags, String message) {
   1385         enforceForUri(
   1386                 modeFlags, checkCallingUriPermission(uri, modeFlags),
   1387                 false, Binder.getCallingUid(), uri, message);
   1388     }
   1389 
   1390     public void enforceCallingOrSelfUriPermission(
   1391             Uri uri, int modeFlags, String message) {
   1392         enforceForUri(
   1393                 modeFlags,
   1394                 checkCallingOrSelfUriPermission(uri, modeFlags), true,
   1395                 Binder.getCallingUid(), uri, message);
   1396     }
   1397 
   1398     public void enforceUriPermission(
   1399             Uri uri, String readPermission, String writePermission,
   1400             int pid, int uid, int modeFlags, String message) {
   1401         enforceForUri(modeFlags,
   1402                       checkUriPermission(
   1403                               uri, readPermission, writePermission, pid, uid,
   1404                               modeFlags),
   1405                       false,
   1406                       uid,
   1407                       uri,
   1408                       message);
   1409     }
   1410 
   1411     @Override
   1412     public Context createPackageContext(String packageName, int flags)
   1413         throws PackageManager.NameNotFoundException {
   1414         if (packageName.equals("system") || packageName.equals("android")) {
   1415             return new ContextImpl(mMainThread.getSystemContext());
   1416         }
   1417 
   1418         LoadedApk pi =
   1419             mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags);
   1420         if (pi != null) {
   1421             ContextImpl c = new ContextImpl();
   1422             c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
   1423             c.init(pi, null, mMainThread, mResources, mBasePackageName);
   1424             if (c.mResources != null) {
   1425                 return c;
   1426             }
   1427         }
   1428 
   1429         // Should be a better exception.
   1430         throw new PackageManager.NameNotFoundException(
   1431             "Application package " + packageName + " not found");
   1432     }
   1433 
   1434     @Override
   1435     public boolean isRestricted() {
   1436         return mRestricted;
   1437     }
   1438 
   1439     private File getDataDirFile() {
   1440         if (mPackageInfo != null) {
   1441             return mPackageInfo.getDataDirFile();
   1442         }
   1443         throw new RuntimeException("Not supported in system context");
   1444     }
   1445 
   1446     @Override
   1447     public File getDir(String name, int mode) {
   1448         name = "app_" + name;
   1449         File file = makeFilename(getDataDirFile(), name);
   1450         if (!file.exists()) {
   1451             file.mkdir();
   1452             setFilePermissionsFromMode(file.getPath(), mode,
   1453                     FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
   1454         }
   1455         return file;
   1456     }
   1457 
   1458     static ContextImpl createSystemContext(ActivityThread mainThread) {
   1459         ContextImpl context = new ContextImpl();
   1460         context.init(Resources.getSystem(), mainThread);
   1461         return context;
   1462     }
   1463 
   1464     ContextImpl() {
   1465         mOuterContext = this;
   1466     }
   1467 
   1468     /**
   1469      * Create a new ApplicationContext from an existing one.  The new one
   1470      * works and operates the same as the one it is copying.
   1471      *
   1472      * @param context Existing application context.
   1473      */
   1474     public ContextImpl(ContextImpl context) {
   1475         mPackageInfo = context.mPackageInfo;
   1476         mBasePackageName = context.mBasePackageName;
   1477         mResources = context.mResources;
   1478         mMainThread = context.mMainThread;
   1479         mContentResolver = context.mContentResolver;
   1480         mOuterContext = this;
   1481     }
   1482 
   1483     final void init(LoadedApk packageInfo,
   1484             IBinder activityToken, ActivityThread mainThread) {
   1485         init(packageInfo, activityToken, mainThread, null, null);
   1486     }
   1487 
   1488     final void init(LoadedApk packageInfo,
   1489                 IBinder activityToken, ActivityThread mainThread,
   1490                 Resources container, String basePackageName) {
   1491         mPackageInfo = packageInfo;
   1492         mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
   1493         mResources = mPackageInfo.getResources(mainThread);
   1494 
   1495         if (mResources != null && container != null
   1496                 && container.getCompatibilityInfo().applicationScale !=
   1497                         mResources.getCompatibilityInfo().applicationScale) {
   1498             if (DEBUG) {
   1499                 Log.d(TAG, "loaded context has different scaling. Using container's" +
   1500                         " compatiblity info:" + container.getDisplayMetrics());
   1501             }
   1502             mResources = mainThread.getTopLevelResources(
   1503                     mPackageInfo.getResDir(), container.getCompatibilityInfo());
   1504         }
   1505         mMainThread = mainThread;
   1506         mContentResolver = new ApplicationContentResolver(this, mainThread);
   1507 
   1508         setActivityToken(activityToken);
   1509     }
   1510 
   1511     final void init(Resources resources, ActivityThread mainThread) {
   1512         mPackageInfo = null;
   1513         mBasePackageName = null;
   1514         mResources = resources;
   1515         mMainThread = mainThread;
   1516         mContentResolver = new ApplicationContentResolver(this, mainThread);
   1517     }
   1518 
   1519     final void scheduleFinalCleanup(String who, String what) {
   1520         mMainThread.scheduleContextCleanup(this, who, what);
   1521     }
   1522 
   1523     final void performFinalCleanup(String who, String what) {
   1524         //Log.i(TAG, "Cleanup up context: " + this);
   1525         mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
   1526     }
   1527 
   1528     final Context getReceiverRestrictedContext() {
   1529         if (mReceiverRestrictedContext != null) {
   1530             return mReceiverRestrictedContext;
   1531         }
   1532         return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
   1533     }
   1534 
   1535     final void setActivityToken(IBinder token) {
   1536         mActivityToken = token;
   1537     }
   1538 
   1539     final void setOuterContext(Context context) {
   1540         mOuterContext = context;
   1541     }
   1542 
   1543     final Context getOuterContext() {
   1544         return mOuterContext;
   1545     }
   1546 
   1547     final IBinder getActivityToken() {
   1548         return mActivityToken;
   1549     }
   1550 
   1551     static void setFilePermissionsFromMode(String name, int mode,
   1552             int extraPermissions) {
   1553         int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
   1554             |FileUtils.S_IRGRP|FileUtils.S_IWGRP
   1555             |extraPermissions;
   1556         if ((mode&MODE_WORLD_READABLE) != 0) {
   1557             perms |= FileUtils.S_IROTH;
   1558         }
   1559         if ((mode&MODE_WORLD_WRITEABLE) != 0) {
   1560             perms |= FileUtils.S_IWOTH;
   1561         }
   1562         if (DEBUG) {
   1563             Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
   1564                   + ", perms=0x" + Integer.toHexString(perms));
   1565         }
   1566         FileUtils.setPermissions(name, perms, -1, -1);
   1567     }
   1568 
   1569     private File validateFilePath(String name, boolean createDirectory) {
   1570         File dir;
   1571         File f;
   1572 
   1573         if (name.charAt(0) == File.separatorChar) {
   1574             String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
   1575             dir = new File(dirPath);
   1576             name = name.substring(name.lastIndexOf(File.separatorChar));
   1577             f = new File(dir, name);
   1578         } else {
   1579             dir = getDatabasesDir();
   1580             f = makeFilename(dir, name);
   1581         }
   1582 
   1583         if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
   1584             FileUtils.setPermissions(dir.getPath(),
   1585                 FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
   1586                 -1, -1);
   1587         }
   1588 
   1589         return f;
   1590     }
   1591 
   1592     private File makeFilename(File base, String name) {
   1593         if (name.indexOf(File.separatorChar) < 0) {
   1594             return new File(base, name);
   1595         }
   1596         throw new IllegalArgumentException(
   1597                 "File " + name + " contains a path separator");
   1598     }
   1599 
   1600     // ----------------------------------------------------------------------
   1601     // ----------------------------------------------------------------------
   1602     // ----------------------------------------------------------------------
   1603 
   1604     private static final class ApplicationContentResolver extends ContentResolver {
   1605         public ApplicationContentResolver(Context context, ActivityThread mainThread) {
   1606             super(context);
   1607             mMainThread = mainThread;
   1608         }
   1609 
   1610         @Override
   1611         protected IContentProvider acquireProvider(Context context, String name) {
   1612             return mMainThread.acquireProvider(context, name);
   1613         }
   1614 
   1615         @Override
   1616         protected IContentProvider acquireExistingProvider(Context context, String name) {
   1617             return mMainThread.acquireExistingProvider(context, name);
   1618         }
   1619 
   1620         @Override
   1621         public boolean releaseProvider(IContentProvider provider) {
   1622             return mMainThread.releaseProvider(provider);
   1623         }
   1624 
   1625         private final ActivityThread mMainThread;
   1626     }
   1627 }
   1628