ContextImpl.java revision 221ea892dcc661bd07d6f36ff012edca2c48aed4
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
17package android.app;
18
19import android.os.Build;
20import com.android.internal.policy.PolicyManager;
21import com.android.internal.util.Preconditions;
22
23import android.bluetooth.BluetoothManager;
24import android.content.BroadcastReceiver;
25import android.content.ComponentName;
26import android.content.ContentResolver;
27import android.content.Context;
28import android.content.ContextWrapper;
29import android.content.IContentProvider;
30import android.content.Intent;
31import android.content.IntentFilter;
32import android.content.IIntentReceiver;
33import android.content.IntentSender;
34import android.content.ReceiverCallNotAllowedException;
35import android.content.ServiceConnection;
36import android.content.SharedPreferences;
37import android.content.pm.ApplicationInfo;
38import android.content.pm.IPackageManager;
39import android.content.pm.PackageManager;
40import android.content.pm.PackageManager.NameNotFoundException;
41import android.content.res.AssetManager;
42import android.content.res.CompatibilityInfo;
43import android.content.res.Configuration;
44import android.content.res.Resources;
45import android.database.DatabaseErrorHandler;
46import android.database.sqlite.SQLiteDatabase;
47import android.database.sqlite.SQLiteDatabase.CursorFactory;
48import android.graphics.Bitmap;
49import android.graphics.drawable.Drawable;
50import android.hardware.ISerialManager;
51import android.hardware.SerialManager;
52import android.hardware.SystemSensorManager;
53import android.hardware.camera2.CameraManager;
54import android.hardware.display.DisplayManager;
55import android.hardware.input.InputManager;
56import android.hardware.usb.IUsbManager;
57import android.hardware.usb.UsbManager;
58import android.location.CountryDetector;
59import android.location.ICountryDetector;
60import android.location.ILocationManager;
61import android.location.LocationManager;
62import android.media.AudioManager;
63import android.media.MediaRouter;
64import android.net.ConnectivityManager;
65import android.net.IConnectivityManager;
66import android.net.INetworkPolicyManager;
67import android.net.NetworkPolicyManager;
68import android.net.Uri;
69import android.net.nsd.INsdManager;
70import android.net.nsd.NsdManager;
71import android.net.wifi.IWifiManager;
72import android.net.wifi.WifiManager;
73import android.net.wifi.p2p.IWifiP2pManager;
74import android.net.wifi.p2p.WifiP2pManager;
75import android.nfc.NfcManager;
76import android.os.Binder;
77import android.os.Bundle;
78import android.os.Debug;
79import android.os.DropBoxManager;
80import android.os.Environment;
81import android.os.FileUtils;
82import android.os.Handler;
83import android.os.IBinder;
84import android.os.IPowerManager;
85import android.os.IUserManager;
86import android.os.Looper;
87import android.os.PowerManager;
88import android.os.Process;
89import android.os.RemoteException;
90import android.os.ServiceManager;
91import android.os.UserHandle;
92import android.os.SystemVibrator;
93import android.os.UserManager;
94import android.os.storage.StorageManager;
95import android.print.IPrintManager;
96import android.print.PrintManager;
97import android.telephony.TelephonyManager;
98import android.content.ClipboardManager;
99import android.util.AndroidRuntimeException;
100import android.util.ArrayMap;
101import android.util.Log;
102import android.util.Slog;
103import android.view.DisplayAdjustments;
104import android.view.ContextThemeWrapper;
105import android.view.Display;
106import android.view.WindowManagerImpl;
107import android.view.accessibility.AccessibilityManager;
108import android.view.inputmethod.InputMethodManager;
109import android.view.textservice.TextServicesManager;
110import android.accounts.AccountManager;
111import android.accounts.IAccountManager;
112import android.app.admin.DevicePolicyManager;
113
114import com.android.internal.app.IAppOpsService;
115import com.android.internal.os.IDropBoxManagerService;
116
117import java.io.File;
118import java.io.FileInputStream;
119import java.io.FileNotFoundException;
120import java.io.FileOutputStream;
121import java.io.IOException;
122import java.io.InputStream;
123import java.util.ArrayList;
124import java.util.HashMap;
125
126class ReceiverRestrictedContext extends ContextWrapper {
127    ReceiverRestrictedContext(Context base) {
128        super(base);
129    }
130
131    @Override
132    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
133        return registerReceiver(receiver, filter, null, null);
134    }
135
136    @Override
137    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
138            String broadcastPermission, Handler scheduler) {
139        if (receiver == null) {
140            // Allow retrieving current sticky broadcast; this is safe since we
141            // aren't actually registering a receiver.
142            return super.registerReceiver(null, filter, broadcastPermission, scheduler);
143        } else {
144            throw new ReceiverCallNotAllowedException(
145                    "BroadcastReceiver components are not allowed to register to receive intents");
146        }
147    }
148
149    @Override
150    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
151            IntentFilter filter, String broadcastPermission, Handler scheduler) {
152        if (receiver == null) {
153            // Allow retrieving current sticky broadcast; this is safe since we
154            // aren't actually registering a receiver.
155            return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler);
156        } else {
157            throw new ReceiverCallNotAllowedException(
158                    "BroadcastReceiver components are not allowed to register to receive intents");
159        }
160    }
161
162    @Override
163    public boolean bindService(Intent service, ServiceConnection conn, int flags) {
164        throw new ReceiverCallNotAllowedException(
165                "BroadcastReceiver components are not allowed to bind to services");
166    }
167}
168
169/**
170 * Common implementation of Context API, which provides the base
171 * context object for Activity and other application components.
172 */
173class ContextImpl extends Context {
174    private final static String TAG = "ContextImpl";
175    private final static boolean DEBUG = false;
176
177    /**
178     * Map from package name, to preference name, to cached preferences.
179     */
180    private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs;
181
182    /*package*/ LoadedApk mPackageInfo;
183    private String mBasePackageName;
184    private Resources mResources;
185    /*package*/ ActivityThread mMainThread;
186    private Context mOuterContext;
187    private IBinder mActivityToken = null;
188    private ApplicationContentResolver mContentResolver;
189    private int mThemeResource = 0;
190    private Resources.Theme mTheme = null;
191    private PackageManager mPackageManager;
192    private Display mDisplay; // may be null if default display
193    private Context mReceiverRestrictedContext = null;
194    private boolean mRestricted;
195    private UserHandle mUser;
196    private ResourcesManager mResourcesManager;
197
198    private final Object mSync = new Object();
199
200    private File mDatabasesDir;
201    private File mPreferencesDir;
202    private File mFilesDir;
203    private File mCacheDir;
204    private File mObbDir;
205    private File mExternalFilesDir;
206    private File mExternalCacheDir;
207
208    private static final String[] EMPTY_FILE_LIST = {};
209
210    final private DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments();
211
212    /**
213     * Override this class when the system service constructor needs a
214     * ContextImpl.  Else, use StaticServiceFetcher below.
215     */
216    /*package*/ static class ServiceFetcher {
217        int mContextCacheIndex = -1;
218
219        /**
220         * Main entrypoint; only override if you don't need caching.
221         */
222        public Object getService(ContextImpl ctx) {
223            ArrayList<Object> cache = ctx.mServiceCache;
224            Object service;
225            synchronized (cache) {
226                if (cache.size() == 0) {
227                    // Initialize the cache vector on first access.
228                    // At this point sNextPerContextServiceCacheIndex
229                    // is the number of potential services that are
230                    // cached per-Context.
231                    for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) {
232                        cache.add(null);
233                    }
234                } else {
235                    service = cache.get(mContextCacheIndex);
236                    if (service != null) {
237                        return service;
238                    }
239                }
240                service = createService(ctx);
241                cache.set(mContextCacheIndex, service);
242                return service;
243            }
244        }
245
246        /**
247         * Override this to create a new per-Context instance of the
248         * service.  getService() will handle locking and caching.
249         */
250        public Object createService(ContextImpl ctx) {
251            throw new RuntimeException("Not implemented");
252        }
253    }
254
255    /**
256     * Override this class for services to be cached process-wide.
257     */
258    abstract static class StaticServiceFetcher extends ServiceFetcher {
259        private Object mCachedInstance;
260
261        @Override
262        public final Object getService(ContextImpl unused) {
263            synchronized (StaticServiceFetcher.this) {
264                Object service = mCachedInstance;
265                if (service != null) {
266                    return service;
267                }
268                return mCachedInstance = createStaticService();
269            }
270        }
271
272        public abstract Object createStaticService();
273    }
274
275    private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP =
276            new HashMap<String, ServiceFetcher>();
277
278    private static int sNextPerContextServiceCacheIndex = 0;
279    private static void registerService(String serviceName, ServiceFetcher fetcher) {
280        if (!(fetcher instanceof StaticServiceFetcher)) {
281            fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++;
282        }
283        SYSTEM_SERVICE_MAP.put(serviceName, fetcher);
284    }
285
286    // This one's defined separately and given a variable name so it
287    // can be re-used by getWallpaperManager(), avoiding a HashMap
288    // lookup.
289    private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() {
290            public Object createService(ContextImpl ctx) {
291                return new WallpaperManager(ctx.getOuterContext(),
292                        ctx.mMainThread.getHandler());
293            }};
294
295    static {
296        registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() {
297                public Object getService(ContextImpl ctx) {
298                    return AccessibilityManager.getInstance(ctx);
299                }});
300
301        registerService(ACCOUNT_SERVICE, new ServiceFetcher() {
302                public Object createService(ContextImpl ctx) {
303                    IBinder b = ServiceManager.getService(ACCOUNT_SERVICE);
304                    IAccountManager service = IAccountManager.Stub.asInterface(b);
305                    return new AccountManager(ctx, service);
306                }});
307
308        registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
309                public Object createService(ContextImpl ctx) {
310                    return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
311                }});
312
313        registerService(ALARM_SERVICE, new ServiceFetcher() {
314                public Object createService(ContextImpl ctx) {
315                    IBinder b = ServiceManager.getService(ALARM_SERVICE);
316                    IAlarmManager service = IAlarmManager.Stub.asInterface(b);
317                    return new AlarmManager(service, ctx);
318                }});
319
320        registerService(AUDIO_SERVICE, new ServiceFetcher() {
321                public Object createService(ContextImpl ctx) {
322                    return new AudioManager(ctx);
323                }});
324
325        registerService(MEDIA_ROUTER_SERVICE, new ServiceFetcher() {
326                public Object createService(ContextImpl ctx) {
327                    return new MediaRouter(ctx);
328                }});
329
330        registerService(BLUETOOTH_SERVICE, new ServiceFetcher() {
331                public Object createService(ContextImpl ctx) {
332                    return new BluetoothManager(ctx);
333                }});
334
335        registerService(CLIPBOARD_SERVICE, new ServiceFetcher() {
336                public Object createService(ContextImpl ctx) {
337                    return new ClipboardManager(ctx.getOuterContext(),
338                            ctx.mMainThread.getHandler());
339                }});
340
341        registerService(CONNECTIVITY_SERVICE, new StaticServiceFetcher() {
342                public Object createStaticService() {
343                    IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE);
344                    return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b));
345                }});
346
347        registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() {
348                public Object createStaticService() {
349                    IBinder b = ServiceManager.getService(COUNTRY_DETECTOR);
350                    return new CountryDetector(ICountryDetector.Stub.asInterface(b));
351                }});
352
353        registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() {
354                public Object createService(ContextImpl ctx) {
355                    return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler());
356                }});
357
358        registerService(DOWNLOAD_SERVICE, new ServiceFetcher() {
359                public Object createService(ContextImpl ctx) {
360                    return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName());
361                }});
362
363        registerService(NFC_SERVICE, new ServiceFetcher() {
364                public Object createService(ContextImpl ctx) {
365                    return new NfcManager(ctx);
366                }});
367
368        registerService(DROPBOX_SERVICE, new StaticServiceFetcher() {
369                public Object createStaticService() {
370                    return createDropBoxManager();
371                }});
372
373        registerService(INPUT_SERVICE, new StaticServiceFetcher() {
374                public Object createStaticService() {
375                    return InputManager.getInstance();
376                }});
377
378        registerService(DISPLAY_SERVICE, new ServiceFetcher() {
379                @Override
380                public Object createService(ContextImpl ctx) {
381                    return new DisplayManager(ctx.getOuterContext());
382                }});
383
384        registerService(INPUT_METHOD_SERVICE, new StaticServiceFetcher() {
385                public Object createStaticService() {
386                    return InputMethodManager.getInstance();
387                }});
388
389        registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() {
390                public Object createService(ContextImpl ctx) {
391                    return TextServicesManager.getInstance();
392                }});
393
394        registerService(KEYGUARD_SERVICE, new ServiceFetcher() {
395                public Object getService(ContextImpl ctx) {
396                    // TODO: why isn't this caching it?  It wasn't
397                    // before, so I'm preserving the old behavior and
398                    // using getService(), instead of createService()
399                    // which would do the caching.
400                    return new KeyguardManager();
401                }});
402
403        registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() {
404                public Object createService(ContextImpl ctx) {
405                    return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext());
406                }});
407
408        registerService(LOCATION_SERVICE, new ServiceFetcher() {
409                public Object createService(ContextImpl ctx) {
410                    IBinder b = ServiceManager.getService(LOCATION_SERVICE);
411                    return new LocationManager(ctx, ILocationManager.Stub.asInterface(b));
412                }});
413
414        registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
415            @Override
416            public Object createService(ContextImpl ctx) {
417                return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
418                        ServiceManager.getService(NETWORK_POLICY_SERVICE)));
419            }
420        });
421
422        registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
423                public Object createService(ContextImpl ctx) {
424                    final Context outerContext = ctx.getOuterContext();
425                    return new NotificationManager(
426                        new ContextThemeWrapper(outerContext,
427                                Resources.selectSystemTheme(0,
428                                        outerContext.getApplicationInfo().targetSdkVersion,
429                                        com.android.internal.R.style.Theme_Dialog,
430                                        com.android.internal.R.style.Theme_Holo_Dialog,
431                                        com.android.internal.R.style.Theme_DeviceDefault_Dialog)),
432                        ctx.mMainThread.getHandler());
433                }});
434
435        registerService(NSD_SERVICE, new ServiceFetcher() {
436                @Override
437                public Object createService(ContextImpl ctx) {
438                    IBinder b = ServiceManager.getService(NSD_SERVICE);
439                    INsdManager service = INsdManager.Stub.asInterface(b);
440                    return new NsdManager(ctx.getOuterContext(), service);
441                }});
442
443        // Note: this was previously cached in a static variable, but
444        // constructed using mMainThread.getHandler(), so converting
445        // it to be a regular Context-cached service...
446        registerService(POWER_SERVICE, new ServiceFetcher() {
447                public Object createService(ContextImpl ctx) {
448                    IBinder b = ServiceManager.getService(POWER_SERVICE);
449                    IPowerManager service = IPowerManager.Stub.asInterface(b);
450                    return new PowerManager(ctx.getOuterContext(),
451                            service, ctx.mMainThread.getHandler());
452                }});
453
454        registerService(SEARCH_SERVICE, new ServiceFetcher() {
455                public Object createService(ContextImpl ctx) {
456                    return new SearchManager(ctx.getOuterContext(),
457                            ctx.mMainThread.getHandler());
458                }});
459
460        registerService(SENSOR_SERVICE, new ServiceFetcher() {
461                public Object createService(ContextImpl ctx) {
462                    return new SystemSensorManager(ctx.getOuterContext(),
463                      ctx.mMainThread.getHandler().getLooper());
464                }});
465
466        registerService(STATUS_BAR_SERVICE, new ServiceFetcher() {
467                public Object createService(ContextImpl ctx) {
468                    return new StatusBarManager(ctx.getOuterContext());
469                }});
470
471        registerService(STORAGE_SERVICE, new ServiceFetcher() {
472                public Object createService(ContextImpl ctx) {
473                    try {
474                        return new StorageManager(
475                                ctx.getContentResolver(), ctx.mMainThread.getHandler().getLooper());
476                    } catch (RemoteException rex) {
477                        Log.e(TAG, "Failed to create StorageManager", rex);
478                        return null;
479                    }
480                }});
481
482        registerService(TELEPHONY_SERVICE, new ServiceFetcher() {
483                public Object createService(ContextImpl ctx) {
484                    return new TelephonyManager(ctx.getOuterContext());
485                }});
486
487        registerService(UI_MODE_SERVICE, new ServiceFetcher() {
488                public Object createService(ContextImpl ctx) {
489                    return new UiModeManager();
490                }});
491
492        registerService(USB_SERVICE, new ServiceFetcher() {
493                public Object createService(ContextImpl ctx) {
494                    IBinder b = ServiceManager.getService(USB_SERVICE);
495                    return new UsbManager(ctx, IUsbManager.Stub.asInterface(b));
496                }});
497
498        registerService(SERIAL_SERVICE, new ServiceFetcher() {
499                public Object createService(ContextImpl ctx) {
500                    IBinder b = ServiceManager.getService(SERIAL_SERVICE);
501                    return new SerialManager(ctx, ISerialManager.Stub.asInterface(b));
502                }});
503
504        registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
505                public Object createService(ContextImpl ctx) {
506                    return new SystemVibrator(ctx);
507                }});
508
509        registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER);
510
511        registerService(WIFI_SERVICE, new ServiceFetcher() {
512                public Object createService(ContextImpl ctx) {
513                    IBinder b = ServiceManager.getService(WIFI_SERVICE);
514                    IWifiManager service = IWifiManager.Stub.asInterface(b);
515                    return new WifiManager(ctx.getOuterContext(), service);
516                }});
517
518        registerService(WIFI_P2P_SERVICE, new ServiceFetcher() {
519                public Object createService(ContextImpl ctx) {
520                    IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE);
521                    IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b);
522                    return new WifiP2pManager(service);
523                }});
524
525        registerService(WINDOW_SERVICE, new ServiceFetcher() {
526                Display mDefaultDisplay;
527                public Object getService(ContextImpl ctx) {
528                    Display display = ctx.mDisplay;
529                    if (display == null) {
530                        if (mDefaultDisplay == null) {
531                            DisplayManager dm = (DisplayManager)ctx.getOuterContext().
532                                    getSystemService(Context.DISPLAY_SERVICE);
533                            mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY);
534                        }
535                        display = mDefaultDisplay;
536                    }
537                    return new WindowManagerImpl(display);
538                }});
539
540        registerService(USER_SERVICE, new ServiceFetcher() {
541            public Object createService(ContextImpl ctx) {
542                IBinder b = ServiceManager.getService(USER_SERVICE);
543                IUserManager service = IUserManager.Stub.asInterface(b);
544                return new UserManager(ctx, service);
545            }});
546
547        registerService(APP_OPS_SERVICE, new ServiceFetcher() {
548            public Object createService(ContextImpl ctx) {
549                IBinder b = ServiceManager.getService(APP_OPS_SERVICE);
550                IAppOpsService service = IAppOpsService.Stub.asInterface(b);
551                return new AppOpsManager(ctx, service);
552            }});
553
554        registerService(CAMERA_SERVICE, new ServiceFetcher() {
555            public Object createService(ContextImpl ctx) {
556                return new CameraManager(ctx);
557            }
558        });
559
560        registerService(PRINT_SERVICE, new ServiceFetcher() {
561            public Object createService(ContextImpl ctx) {
562                IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE);
563                IPrintManager service = IPrintManager.Stub.asInterface(iBinder);
564                return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(),
565                        UserHandle.getAppId(Process.myUid()));
566            }});
567    }
568
569    static ContextImpl getImpl(Context context) {
570        Context nextContext;
571        while ((context instanceof ContextWrapper) &&
572                (nextContext=((ContextWrapper)context).getBaseContext()) != null) {
573            context = nextContext;
574        }
575        return (ContextImpl)context;
576    }
577
578    // The system service cache for the system services that are
579    // cached per-ContextImpl.  Package-scoped to avoid accessor
580    // methods.
581    final ArrayList<Object> mServiceCache = new ArrayList<Object>();
582
583    @Override
584    public AssetManager getAssets() {
585        return getResources().getAssets();
586    }
587
588    @Override
589    public Resources getResources() {
590        return mResources;
591    }
592
593    @Override
594    public PackageManager getPackageManager() {
595        if (mPackageManager != null) {
596            return mPackageManager;
597        }
598
599        IPackageManager pm = ActivityThread.getPackageManager();
600        if (pm != null) {
601            // Doesn't matter if we make more than one instance.
602            return (mPackageManager = new ApplicationPackageManager(this, pm));
603        }
604
605        return null;
606    }
607
608    @Override
609    public ContentResolver getContentResolver() {
610        return mContentResolver;
611    }
612
613    @Override
614    public Looper getMainLooper() {
615        return mMainThread.getLooper();
616    }
617
618    @Override
619    public Context getApplicationContext() {
620        return (mPackageInfo != null) ?
621                mPackageInfo.getApplication() : mMainThread.getApplication();
622    }
623
624    @Override
625    public void setTheme(int resid) {
626        mThemeResource = resid;
627    }
628
629    @Override
630    public int getThemeResId() {
631        return mThemeResource;
632    }
633
634    @Override
635    public Resources.Theme getTheme() {
636        if (mTheme == null) {
637            mThemeResource = Resources.selectDefaultTheme(mThemeResource,
638                    getOuterContext().getApplicationInfo().targetSdkVersion);
639            mTheme = mResources.newTheme();
640            mTheme.applyStyle(mThemeResource, true);
641        }
642        return mTheme;
643    }
644
645    @Override
646    public ClassLoader getClassLoader() {
647        return mPackageInfo != null ?
648                mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader();
649    }
650
651    @Override
652    public String getPackageName() {
653        if (mPackageInfo != null) {
654            return mPackageInfo.getPackageName();
655        }
656        // No mPackageInfo means this is a Context for the system itself,
657        // and this here is its name.
658        return "android";
659    }
660
661    /** @hide */
662    @Override
663    public String getBasePackageName() {
664        return mBasePackageName != null ? mBasePackageName : getPackageName();
665    }
666
667    @Override
668    public ApplicationInfo getApplicationInfo() {
669        if (mPackageInfo != null) {
670            return mPackageInfo.getApplicationInfo();
671        }
672        throw new RuntimeException("Not supported in system context");
673    }
674
675    @Override
676    public String getPackageResourcePath() {
677        if (mPackageInfo != null) {
678            return mPackageInfo.getResDir();
679        }
680        throw new RuntimeException("Not supported in system context");
681    }
682
683    @Override
684    public String getPackageCodePath() {
685        if (mPackageInfo != null) {
686            return mPackageInfo.getAppDir();
687        }
688        throw new RuntimeException("Not supported in system context");
689    }
690
691    public File getSharedPrefsFile(String name) {
692        return makeFilename(getPreferencesDir(), name + ".xml");
693    }
694
695    @Override
696    public SharedPreferences getSharedPreferences(String name, int mode) {
697        SharedPreferencesImpl sp;
698        synchronized (mSync) {
699            if (sSharedPrefs == null) {
700                sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>();
701            }
702
703            final String packageName = getPackageName();
704            ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName);
705            if (packagePrefs == null) {
706                packagePrefs = new ArrayMap<String, SharedPreferencesImpl>();
707                sSharedPrefs.put(packageName, packagePrefs);
708            }
709
710            // At least one application in the world actually passes in a null
711            // name.  This happened to work because when we generated the file name
712            // we would stringify it to "null.xml".  Nice.
713            if (mPackageInfo.getApplicationInfo().targetSdkVersion <
714                    Build.VERSION_CODES.KEY_LIME_PIE) {
715                if (name == null) {
716                    name = "null";
717                }
718            }
719
720            sp = packagePrefs.get(name);
721            if (sp == null) {
722                File prefsFile = getSharedPrefsFile(name);
723                sp = new SharedPreferencesImpl(prefsFile, mode);
724                packagePrefs.put(name, sp);
725                return sp;
726            }
727        }
728        if ((mode & Context.MODE_MULTI_PROCESS) != 0 ||
729            getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) {
730            // If somebody else (some other process) changed the prefs
731            // file behind our back, we reload it.  This has been the
732            // historical (if undocumented) behavior.
733            sp.startReloadIfChangedUnexpectedly();
734        }
735        return sp;
736    }
737
738    private File getPreferencesDir() {
739        synchronized (mSync) {
740            if (mPreferencesDir == null) {
741                mPreferencesDir = new File(getDataDirFile(), "shared_prefs");
742            }
743            return mPreferencesDir;
744        }
745    }
746
747    @Override
748    public FileInputStream openFileInput(String name)
749        throws FileNotFoundException {
750        File f = makeFilename(getFilesDir(), name);
751        return new FileInputStream(f);
752    }
753
754    @Override
755    public FileOutputStream openFileOutput(String name, int mode)
756        throws FileNotFoundException {
757        final boolean append = (mode&MODE_APPEND) != 0;
758        File f = makeFilename(getFilesDir(), name);
759        try {
760            FileOutputStream fos = new FileOutputStream(f, append);
761            setFilePermissionsFromMode(f.getPath(), mode, 0);
762            return fos;
763        } catch (FileNotFoundException e) {
764        }
765
766        File parent = f.getParentFile();
767        parent.mkdir();
768        FileUtils.setPermissions(
769            parent.getPath(),
770            FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
771            -1, -1);
772        FileOutputStream fos = new FileOutputStream(f, append);
773        setFilePermissionsFromMode(f.getPath(), mode, 0);
774        return fos;
775    }
776
777    @Override
778    public boolean deleteFile(String name) {
779        File f = makeFilename(getFilesDir(), name);
780        return f.delete();
781    }
782
783    @Override
784    public File getFilesDir() {
785        synchronized (mSync) {
786            if (mFilesDir == null) {
787                mFilesDir = new File(getDataDirFile(), "files");
788            }
789            if (!mFilesDir.exists()) {
790                if(!mFilesDir.mkdirs()) {
791                    Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath());
792                    return null;
793                }
794                FileUtils.setPermissions(
795                        mFilesDir.getPath(),
796                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
797                        -1, -1);
798            }
799            return mFilesDir;
800        }
801    }
802
803    @Override
804    public File getExternalFilesDir(String type) {
805        synchronized (mSync) {
806            if (mExternalFilesDir == null) {
807                mExternalFilesDir = Environment.getExternalStorageAppFilesDirectory(
808                        getPackageName());
809            }
810            if (!mExternalFilesDir.exists()) {
811                try {
812                    (new File(Environment.getExternalStorageAndroidDataDir(),
813                            ".nomedia")).createNewFile();
814                } catch (IOException e) {
815                }
816                if (!mExternalFilesDir.mkdirs()) {
817                    Log.w(TAG, "Unable to create external files directory");
818                    return null;
819                }
820            }
821            if (type == null) {
822                return mExternalFilesDir;
823            }
824            File dir = new File(mExternalFilesDir, type);
825            if (!dir.exists()) {
826                if (!dir.mkdirs()) {
827                    Log.w(TAG, "Unable to create external media directory " + dir);
828                    return null;
829                }
830            }
831            return dir;
832        }
833    }
834
835    @Override
836    public File getObbDir() {
837        synchronized (mSync) {
838            if (mObbDir == null) {
839                mObbDir = Environment.getExternalStorageAppObbDirectory(
840                        getPackageName());
841            }
842            return mObbDir;
843        }
844    }
845
846    @Override
847    public File getCacheDir() {
848        synchronized (mSync) {
849            if (mCacheDir == null) {
850                mCacheDir = new File(getDataDirFile(), "cache");
851            }
852            if (!mCacheDir.exists()) {
853                if(!mCacheDir.mkdirs()) {
854                    Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath());
855                    return null;
856                }
857                FileUtils.setPermissions(
858                        mCacheDir.getPath(),
859                        FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
860                        -1, -1);
861            }
862        }
863        return mCacheDir;
864    }
865
866    @Override
867    public File getExternalCacheDir() {
868        synchronized (mSync) {
869            if (mExternalCacheDir == null) {
870                mExternalCacheDir = Environment.getExternalStorageAppCacheDirectory(
871                        getPackageName());
872            }
873            if (!mExternalCacheDir.exists()) {
874                try {
875                    (new File(Environment.getExternalStorageAndroidDataDir(),
876                            ".nomedia")).createNewFile();
877                } catch (IOException e) {
878                }
879                if (!mExternalCacheDir.mkdirs()) {
880                    Log.w(TAG, "Unable to create external cache directory");
881                    return null;
882                }
883            }
884            return mExternalCacheDir;
885        }
886    }
887
888    @Override
889    public File getFileStreamPath(String name) {
890        return makeFilename(getFilesDir(), name);
891    }
892
893    @Override
894    public String[] fileList() {
895        final String[] list = getFilesDir().list();
896        return (list != null) ? list : EMPTY_FILE_LIST;
897    }
898
899    @Override
900    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
901        return openOrCreateDatabase(name, mode, factory, null);
902    }
903
904    @Override
905    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory,
906            DatabaseErrorHandler errorHandler) {
907        File f = validateFilePath(name, true);
908        int flags = SQLiteDatabase.CREATE_IF_NECESSARY;
909        if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) {
910            flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING;
911        }
912        SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler);
913        setFilePermissionsFromMode(f.getPath(), mode, 0);
914        return db;
915    }
916
917    @Override
918    public boolean deleteDatabase(String name) {
919        try {
920            File f = validateFilePath(name, false);
921            return SQLiteDatabase.deleteDatabase(f);
922        } catch (Exception e) {
923        }
924        return false;
925    }
926
927    @Override
928    public File getDatabasePath(String name) {
929        return validateFilePath(name, false);
930    }
931
932    @Override
933    public String[] databaseList() {
934        final String[] list = getDatabasesDir().list();
935        return (list != null) ? list : EMPTY_FILE_LIST;
936    }
937
938
939    private File getDatabasesDir() {
940        synchronized (mSync) {
941            if (mDatabasesDir == null) {
942                mDatabasesDir = new File(getDataDirFile(), "databases");
943            }
944            if (mDatabasesDir.getPath().equals("databases")) {
945                mDatabasesDir = new File("/data/system");
946            }
947            return mDatabasesDir;
948        }
949    }
950
951    @Override
952    public Drawable getWallpaper() {
953        return getWallpaperManager().getDrawable();
954    }
955
956    @Override
957    public Drawable peekWallpaper() {
958        return getWallpaperManager().peekDrawable();
959    }
960
961    @Override
962    public int getWallpaperDesiredMinimumWidth() {
963        return getWallpaperManager().getDesiredMinimumWidth();
964    }
965
966    @Override
967    public int getWallpaperDesiredMinimumHeight() {
968        return getWallpaperManager().getDesiredMinimumHeight();
969    }
970
971    @Override
972    public void setWallpaper(Bitmap bitmap) throws IOException  {
973        getWallpaperManager().setBitmap(bitmap);
974    }
975
976    @Override
977    public void setWallpaper(InputStream data) throws IOException {
978        getWallpaperManager().setStream(data);
979    }
980
981    @Override
982    public void clearWallpaper() throws IOException {
983        getWallpaperManager().clear();
984    }
985
986    @Override
987    public void startActivity(Intent intent) {
988        warnIfCallingFromSystemProcess();
989        startActivity(intent, null);
990    }
991
992    /** @hide */
993    @Override
994    public void startActivityAsUser(Intent intent, UserHandle user) {
995        startActivityAsUser(intent, null, user);
996    }
997
998    @Override
999    public void startActivity(Intent intent, Bundle options) {
1000        warnIfCallingFromSystemProcess();
1001        if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1002            throw new AndroidRuntimeException(
1003                    "Calling startActivity() from outside of an Activity "
1004                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
1005                    + " Is this really what you want?");
1006        }
1007        mMainThread.getInstrumentation().execStartActivity(
1008            getOuterContext(), mMainThread.getApplicationThread(), null,
1009            (Activity)null, intent, -1, options);
1010    }
1011
1012    /** @hide */
1013    @Override
1014    public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
1015        try {
1016            ActivityManagerNative.getDefault().startActivityAsUser(
1017                mMainThread.getApplicationThread(), getBasePackageName(), intent,
1018                intent.resolveTypeIfNeeded(getContentResolver()),
1019                null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options,
1020                user.getIdentifier());
1021        } catch (RemoteException re) {
1022        }
1023    }
1024
1025    @Override
1026    public void startActivities(Intent[] intents) {
1027        warnIfCallingFromSystemProcess();
1028        startActivities(intents, null);
1029    }
1030
1031    /** @hide */
1032    @Override
1033    public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) {
1034        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1035            throw new AndroidRuntimeException(
1036                    "Calling startActivities() from outside of an Activity "
1037                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1038                    + " Is this really what you want?");
1039        }
1040        mMainThread.getInstrumentation().execStartActivitiesAsUser(
1041            getOuterContext(), mMainThread.getApplicationThread(), null,
1042            (Activity)null, intents, options, userHandle.getIdentifier());
1043    }
1044
1045    @Override
1046    public void startActivities(Intent[] intents, Bundle options) {
1047        warnIfCallingFromSystemProcess();
1048        if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) {
1049            throw new AndroidRuntimeException(
1050                    "Calling startActivities() from outside of an Activity "
1051                    + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent."
1052                    + " Is this really what you want?");
1053        }
1054        mMainThread.getInstrumentation().execStartActivities(
1055            getOuterContext(), mMainThread.getApplicationThread(), null,
1056            (Activity)null, intents, options);
1057    }
1058
1059    @Override
1060    public void startIntentSender(IntentSender intent,
1061            Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags)
1062            throws IntentSender.SendIntentException {
1063        startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null);
1064    }
1065
1066    @Override
1067    public void startIntentSender(IntentSender intent, Intent fillInIntent,
1068            int flagsMask, int flagsValues, int extraFlags, Bundle options)
1069            throws IntentSender.SendIntentException {
1070        try {
1071            String resolvedType = null;
1072            if (fillInIntent != null) {
1073                fillInIntent.migrateExtraStreamToClipData();
1074                fillInIntent.prepareToLeaveProcess();
1075                resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver());
1076            }
1077            int result = ActivityManagerNative.getDefault()
1078                .startActivityIntentSender(mMainThread.getApplicationThread(), intent,
1079                        fillInIntent, resolvedType, null, null,
1080                        0, flagsMask, flagsValues, options);
1081            if (result == ActivityManager.START_CANCELED) {
1082                throw new IntentSender.SendIntentException();
1083            }
1084            Instrumentation.checkStartActivityResult(result, null);
1085        } catch (RemoteException e) {
1086        }
1087    }
1088
1089    @Override
1090    public void sendBroadcast(Intent intent) {
1091        warnIfCallingFromSystemProcess();
1092        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1093        try {
1094            intent.prepareToLeaveProcess();
1095            ActivityManagerNative.getDefault().broadcastIntent(
1096                mMainThread.getApplicationThread(), intent, resolvedType, null,
1097                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
1098                getUserId());
1099        } catch (RemoteException e) {
1100        }
1101    }
1102
1103    @Override
1104    public void sendBroadcast(Intent intent, String receiverPermission) {
1105        warnIfCallingFromSystemProcess();
1106        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1107        try {
1108            intent.prepareToLeaveProcess();
1109            ActivityManagerNative.getDefault().broadcastIntent(
1110                mMainThread.getApplicationThread(), intent, resolvedType, null,
1111                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE,
1112                false, false, getUserId());
1113        } catch (RemoteException e) {
1114        }
1115    }
1116
1117    @Override
1118    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
1119        warnIfCallingFromSystemProcess();
1120        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1121        try {
1122            intent.prepareToLeaveProcess();
1123            ActivityManagerNative.getDefault().broadcastIntent(
1124                mMainThread.getApplicationThread(), intent, resolvedType, null,
1125                Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false,
1126                getUserId());
1127        } catch (RemoteException e) {
1128        }
1129    }
1130
1131    @Override
1132    public void sendOrderedBroadcast(Intent intent,
1133            String receiverPermission) {
1134        warnIfCallingFromSystemProcess();
1135        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1136        try {
1137            intent.prepareToLeaveProcess();
1138            ActivityManagerNative.getDefault().broadcastIntent(
1139                mMainThread.getApplicationThread(), intent, resolvedType, null,
1140                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false,
1141                getUserId());
1142        } catch (RemoteException e) {
1143        }
1144    }
1145
1146    @Override
1147    public void sendOrderedBroadcast(Intent intent,
1148            String receiverPermission, BroadcastReceiver resultReceiver,
1149            Handler scheduler, int initialCode, String initialData,
1150            Bundle initialExtras) {
1151        sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE,
1152                resultReceiver, scheduler, initialCode, initialData, initialExtras);
1153    }
1154
1155    @Override
1156    public void sendOrderedBroadcast(Intent intent,
1157            String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
1158            Handler scheduler, int initialCode, String initialData,
1159            Bundle initialExtras) {
1160        warnIfCallingFromSystemProcess();
1161        IIntentReceiver rd = null;
1162        if (resultReceiver != null) {
1163            if (mPackageInfo != null) {
1164                if (scheduler == null) {
1165                    scheduler = mMainThread.getHandler();
1166                }
1167                rd = mPackageInfo.getReceiverDispatcher(
1168                    resultReceiver, getOuterContext(), scheduler,
1169                    mMainThread.getInstrumentation(), false);
1170            } else {
1171                if (scheduler == null) {
1172                    scheduler = mMainThread.getHandler();
1173                }
1174                rd = new LoadedApk.ReceiverDispatcher(
1175                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1176            }
1177        }
1178        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1179        try {
1180            intent.prepareToLeaveProcess();
1181            ActivityManagerNative.getDefault().broadcastIntent(
1182                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1183                initialCode, initialData, initialExtras, receiverPermission, appOp,
1184                    true, false, getUserId());
1185        } catch (RemoteException e) {
1186        }
1187    }
1188
1189    @Override
1190    public void sendBroadcastAsUser(Intent intent, UserHandle user) {
1191        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1192        try {
1193            intent.prepareToLeaveProcess();
1194            ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
1195                    intent, resolvedType, null, Activity.RESULT_OK, null, null, null,
1196                    AppOpsManager.OP_NONE, false, false, user.getIdentifier());
1197        } catch (RemoteException e) {
1198        }
1199    }
1200
1201    @Override
1202    public void sendBroadcastAsUser(Intent intent, UserHandle user,
1203            String receiverPermission) {
1204        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1205        try {
1206            intent.prepareToLeaveProcess();
1207            ActivityManagerNative.getDefault().broadcastIntent(
1208                mMainThread.getApplicationThread(), intent, resolvedType, null,
1209                Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, false, false,
1210                user.getIdentifier());
1211        } catch (RemoteException e) {
1212        }
1213    }
1214
1215    @Override
1216    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1217            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
1218            int initialCode, String initialData, Bundle initialExtras) {
1219        IIntentReceiver rd = null;
1220        if (resultReceiver != null) {
1221            if (mPackageInfo != null) {
1222                if (scheduler == null) {
1223                    scheduler = mMainThread.getHandler();
1224                }
1225                rd = mPackageInfo.getReceiverDispatcher(
1226                    resultReceiver, getOuterContext(), scheduler,
1227                    mMainThread.getInstrumentation(), false);
1228            } else {
1229                if (scheduler == null) {
1230                    scheduler = mMainThread.getHandler();
1231                }
1232                rd = new LoadedApk.ReceiverDispatcher(
1233                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1234            }
1235        }
1236        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1237        try {
1238            intent.prepareToLeaveProcess();
1239            ActivityManagerNative.getDefault().broadcastIntent(
1240                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1241                initialCode, initialData, initialExtras, receiverPermission,
1242                    AppOpsManager.OP_NONE, true, false, user.getIdentifier());
1243        } catch (RemoteException e) {
1244        }
1245    }
1246
1247    @Override
1248    public void sendStickyBroadcast(Intent intent) {
1249        warnIfCallingFromSystemProcess();
1250        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1251        try {
1252            intent.prepareToLeaveProcess();
1253            ActivityManagerNative.getDefault().broadcastIntent(
1254                mMainThread.getApplicationThread(), intent, resolvedType, null,
1255                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true,
1256                getUserId());
1257        } catch (RemoteException e) {
1258        }
1259    }
1260
1261    @Override
1262    public void sendStickyOrderedBroadcast(Intent intent,
1263            BroadcastReceiver resultReceiver,
1264            Handler scheduler, int initialCode, String initialData,
1265            Bundle initialExtras) {
1266        warnIfCallingFromSystemProcess();
1267        IIntentReceiver rd = null;
1268        if (resultReceiver != null) {
1269            if (mPackageInfo != null) {
1270                if (scheduler == null) {
1271                    scheduler = mMainThread.getHandler();
1272                }
1273                rd = mPackageInfo.getReceiverDispatcher(
1274                    resultReceiver, getOuterContext(), scheduler,
1275                    mMainThread.getInstrumentation(), false);
1276            } else {
1277                if (scheduler == null) {
1278                    scheduler = mMainThread.getHandler();
1279                }
1280                rd = new LoadedApk.ReceiverDispatcher(
1281                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1282            }
1283        }
1284        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1285        try {
1286            intent.prepareToLeaveProcess();
1287            ActivityManagerNative.getDefault().broadcastIntent(
1288                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1289                initialCode, initialData, initialExtras, null,
1290                    AppOpsManager.OP_NONE, true, true, getUserId());
1291        } catch (RemoteException e) {
1292        }
1293    }
1294
1295    @Override
1296    public void removeStickyBroadcast(Intent intent) {
1297        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1298        if (resolvedType != null) {
1299            intent = new Intent(intent);
1300            intent.setDataAndType(intent.getData(), resolvedType);
1301        }
1302        try {
1303            intent.prepareToLeaveProcess();
1304            ActivityManagerNative.getDefault().unbroadcastIntent(
1305                    mMainThread.getApplicationThread(), intent, getUserId());
1306        } catch (RemoteException e) {
1307        }
1308    }
1309
1310    @Override
1311    public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
1312        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1313        try {
1314            intent.prepareToLeaveProcess();
1315            ActivityManagerNative.getDefault().broadcastIntent(
1316                mMainThread.getApplicationThread(), intent, resolvedType, null,
1317                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier());
1318        } catch (RemoteException e) {
1319        }
1320    }
1321
1322    @Override
1323    public void sendStickyOrderedBroadcastAsUser(Intent intent,
1324            UserHandle user, BroadcastReceiver resultReceiver,
1325            Handler scheduler, int initialCode, String initialData,
1326            Bundle initialExtras) {
1327        IIntentReceiver rd = null;
1328        if (resultReceiver != null) {
1329            if (mPackageInfo != null) {
1330                if (scheduler == null) {
1331                    scheduler = mMainThread.getHandler();
1332                }
1333                rd = mPackageInfo.getReceiverDispatcher(
1334                    resultReceiver, getOuterContext(), scheduler,
1335                    mMainThread.getInstrumentation(), false);
1336            } else {
1337                if (scheduler == null) {
1338                    scheduler = mMainThread.getHandler();
1339                }
1340                rd = new LoadedApk.ReceiverDispatcher(
1341                        resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
1342            }
1343        }
1344        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1345        try {
1346            intent.prepareToLeaveProcess();
1347            ActivityManagerNative.getDefault().broadcastIntent(
1348                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1349                initialCode, initialData, initialExtras, null,
1350                    AppOpsManager.OP_NONE, true, true, user.getIdentifier());
1351        } catch (RemoteException e) {
1352        }
1353    }
1354
1355    @Override
1356    public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
1357        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1358        if (resolvedType != null) {
1359            intent = new Intent(intent);
1360            intent.setDataAndType(intent.getData(), resolvedType);
1361        }
1362        try {
1363            intent.prepareToLeaveProcess();
1364            ActivityManagerNative.getDefault().unbroadcastIntent(
1365                    mMainThread.getApplicationThread(), intent, user.getIdentifier());
1366        } catch (RemoteException e) {
1367        }
1368    }
1369
1370    @Override
1371    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
1372        return registerReceiver(receiver, filter, null, null);
1373    }
1374
1375    @Override
1376    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
1377            String broadcastPermission, Handler scheduler) {
1378        return registerReceiverInternal(receiver, getUserId(),
1379                filter, broadcastPermission, scheduler, getOuterContext());
1380    }
1381
1382    @Override
1383    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
1384            IntentFilter filter, String broadcastPermission, Handler scheduler) {
1385        return registerReceiverInternal(receiver, user.getIdentifier(),
1386                filter, broadcastPermission, scheduler, getOuterContext());
1387    }
1388
1389    private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
1390            IntentFilter filter, String broadcastPermission,
1391            Handler scheduler, Context context) {
1392        IIntentReceiver rd = null;
1393        if (receiver != null) {
1394            if (mPackageInfo != null && context != null) {
1395                if (scheduler == null) {
1396                    scheduler = mMainThread.getHandler();
1397                }
1398                rd = mPackageInfo.getReceiverDispatcher(
1399                    receiver, context, scheduler,
1400                    mMainThread.getInstrumentation(), true);
1401            } else {
1402                if (scheduler == null) {
1403                    scheduler = mMainThread.getHandler();
1404                }
1405                rd = new LoadedApk.ReceiverDispatcher(
1406                        receiver, context, scheduler, null, true).getIIntentReceiver();
1407            }
1408        }
1409        try {
1410            return ActivityManagerNative.getDefault().registerReceiver(
1411                    mMainThread.getApplicationThread(), mBasePackageName,
1412                    rd, filter, broadcastPermission, userId);
1413        } catch (RemoteException e) {
1414            return null;
1415        }
1416    }
1417
1418    @Override
1419    public void unregisterReceiver(BroadcastReceiver receiver) {
1420        if (mPackageInfo != null) {
1421            IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
1422                    getOuterContext(), receiver);
1423            try {
1424                ActivityManagerNative.getDefault().unregisterReceiver(rd);
1425            } catch (RemoteException e) {
1426            }
1427        } else {
1428            throw new RuntimeException("Not supported in system context");
1429        }
1430    }
1431
1432    @Override
1433    public ComponentName startService(Intent service) {
1434        warnIfCallingFromSystemProcess();
1435        return startServiceAsUser(service, mUser);
1436    }
1437
1438    @Override
1439    public boolean stopService(Intent service) {
1440        warnIfCallingFromSystemProcess();
1441        return stopServiceAsUser(service, mUser);
1442    }
1443
1444    @Override
1445    public ComponentName startServiceAsUser(Intent service, UserHandle user) {
1446        try {
1447            if (service.getComponent() == null && service.getPackage() == null) {
1448                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
1449                    IllegalArgumentException ex = new IllegalArgumentException(
1450                            "Service Intent must be explicit: " + service);
1451                    Log.wtf(TAG, "This will become an error", ex);
1452                    //throw ex;
1453                }
1454            }
1455            service.prepareToLeaveProcess();
1456            ComponentName cn = ActivityManagerNative.getDefault().startService(
1457                mMainThread.getApplicationThread(), service,
1458                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1459            if (cn != null) {
1460                if (cn.getPackageName().equals("!")) {
1461                    throw new SecurityException(
1462                            "Not allowed to start service " + service
1463                            + " without permission " + cn.getClassName());
1464                } else if (cn.getPackageName().equals("!!")) {
1465                    throw new SecurityException(
1466                            "Unable to start service " + service
1467                            + ": " + cn.getClassName());
1468                }
1469            }
1470            return cn;
1471        } catch (RemoteException e) {
1472            return null;
1473        }
1474    }
1475
1476    @Override
1477    public boolean stopServiceAsUser(Intent service, UserHandle user) {
1478        try {
1479            if (service.getComponent() == null && service.getPackage() == null) {
1480                if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
1481                    IllegalArgumentException ex = new IllegalArgumentException(
1482                            "Service Intent must be explicit: " + service);
1483                    Log.wtf(TAG, "This will become an error", ex);
1484                    //throw ex;
1485                }
1486            }
1487            service.prepareToLeaveProcess();
1488            int res = ActivityManagerNative.getDefault().stopService(
1489                mMainThread.getApplicationThread(), service,
1490                service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
1491            if (res < 0) {
1492                throw new SecurityException(
1493                        "Not allowed to stop service " + service);
1494            }
1495            return res != 0;
1496        } catch (RemoteException e) {
1497            return false;
1498        }
1499    }
1500
1501    @Override
1502    public boolean bindService(Intent service, ServiceConnection conn,
1503            int flags) {
1504        warnIfCallingFromSystemProcess();
1505        return bindServiceAsUser(service, conn, flags, Process.myUserHandle());
1506    }
1507
1508    /** @hide */
1509    @Override
1510    public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags,
1511            UserHandle user) {
1512        IServiceConnection sd;
1513        if (conn == null) {
1514            throw new IllegalArgumentException("connection is null");
1515        }
1516        if (mPackageInfo != null) {
1517            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),
1518                    mMainThread.getHandler(), flags);
1519        } else {
1520            throw new RuntimeException("Not supported in system context");
1521        }
1522        if (service.getComponent() == null && service.getPackage() == null) {
1523            if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.KEY_LIME_PIE) {
1524                IllegalArgumentException ex = new IllegalArgumentException(
1525                        "Service Intent must be explicit: " + service);
1526                Log.wtf(TAG, "This will become an error", ex);
1527                //throw ex;
1528            }
1529        }
1530        try {
1531            IBinder token = getActivityToken();
1532            if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1533                    && mPackageInfo.getApplicationInfo().targetSdkVersion
1534                    < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1535                flags |= BIND_WAIVE_PRIORITY;
1536            }
1537            service.prepareToLeaveProcess();
1538            int res = ActivityManagerNative.getDefault().bindService(
1539                mMainThread.getApplicationThread(), getActivityToken(),
1540                service, service.resolveTypeIfNeeded(getContentResolver()),
1541                sd, flags, user.getIdentifier());
1542            if (res < 0) {
1543                throw new SecurityException(
1544                        "Not allowed to bind to service " + service);
1545            }
1546            return res != 0;
1547        } catch (RemoteException e) {
1548            return false;
1549        }
1550    }
1551
1552    @Override
1553    public void unbindService(ServiceConnection conn) {
1554        if (conn == null) {
1555            throw new IllegalArgumentException("connection is null");
1556        }
1557        if (mPackageInfo != null) {
1558            IServiceConnection sd = mPackageInfo.forgetServiceDispatcher(
1559                    getOuterContext(), conn);
1560            try {
1561                ActivityManagerNative.getDefault().unbindService(sd);
1562            } catch (RemoteException e) {
1563            }
1564        } else {
1565            throw new RuntimeException("Not supported in system context");
1566        }
1567    }
1568
1569    @Override
1570    public boolean startInstrumentation(ComponentName className,
1571            String profileFile, Bundle arguments) {
1572        try {
1573            if (arguments != null) {
1574                arguments.setAllowFds(false);
1575            }
1576            return ActivityManagerNative.getDefault().startInstrumentation(
1577                    className, profileFile, 0, arguments, null, null, getUserId());
1578        } catch (RemoteException e) {
1579            // System has crashed, nothing we can do.
1580        }
1581        return false;
1582    }
1583
1584    @Override
1585    public Object getSystemService(String name) {
1586        ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name);
1587        return fetcher == null ? null : fetcher.getService(this);
1588    }
1589
1590    private WallpaperManager getWallpaperManager() {
1591        return (WallpaperManager) WALLPAPER_FETCHER.getService(this);
1592    }
1593
1594    /* package */ static DropBoxManager createDropBoxManager() {
1595        IBinder b = ServiceManager.getService(DROPBOX_SERVICE);
1596        IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b);
1597        if (service == null) {
1598            // Don't return a DropBoxManager that will NPE upon use.
1599            // This also avoids caching a broken DropBoxManager in
1600            // getDropBoxManager during early boot, before the
1601            // DROPBOX_SERVICE is registered.
1602            return null;
1603        }
1604        return new DropBoxManager(service);
1605    }
1606
1607    @Override
1608    public int checkPermission(String permission, int pid, int uid) {
1609        if (permission == null) {
1610            throw new IllegalArgumentException("permission is null");
1611        }
1612
1613        try {
1614            return ActivityManagerNative.getDefault().checkPermission(
1615                    permission, pid, uid);
1616        } catch (RemoteException e) {
1617            return PackageManager.PERMISSION_DENIED;
1618        }
1619    }
1620
1621    @Override
1622    public int checkCallingPermission(String permission) {
1623        if (permission == null) {
1624            throw new IllegalArgumentException("permission is null");
1625        }
1626
1627        int pid = Binder.getCallingPid();
1628        if (pid != Process.myPid()) {
1629            return checkPermission(permission, pid, Binder.getCallingUid());
1630        }
1631        return PackageManager.PERMISSION_DENIED;
1632    }
1633
1634    @Override
1635    public int checkCallingOrSelfPermission(String permission) {
1636        if (permission == null) {
1637            throw new IllegalArgumentException("permission is null");
1638        }
1639
1640        return checkPermission(permission, Binder.getCallingPid(),
1641                Binder.getCallingUid());
1642    }
1643
1644    private void enforce(
1645            String permission, int resultOfCheck,
1646            boolean selfToo, int uid, String message) {
1647        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1648            throw new SecurityException(
1649                    (message != null ? (message + ": ") : "") +
1650                    (selfToo
1651                     ? "Neither user " + uid + " nor current process has "
1652                     : "uid " + uid + " does not have ") +
1653                    permission +
1654                    ".");
1655        }
1656    }
1657
1658    public void enforcePermission(
1659            String permission, int pid, int uid, String message) {
1660        enforce(permission,
1661                checkPermission(permission, pid, uid),
1662                false,
1663                uid,
1664                message);
1665    }
1666
1667    public void enforceCallingPermission(String permission, String message) {
1668        enforce(permission,
1669                checkCallingPermission(permission),
1670                false,
1671                Binder.getCallingUid(),
1672                message);
1673    }
1674
1675    public void enforceCallingOrSelfPermission(
1676            String permission, String message) {
1677        enforce(permission,
1678                checkCallingOrSelfPermission(permission),
1679                true,
1680                Binder.getCallingUid(),
1681                message);
1682    }
1683
1684    @Override
1685    public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
1686         try {
1687            ActivityManagerNative.getDefault().grantUriPermission(
1688                    mMainThread.getApplicationThread(), toPackage, uri,
1689                    modeFlags);
1690        } catch (RemoteException e) {
1691        }
1692    }
1693
1694    @Override
1695    public void revokeUriPermission(Uri uri, int modeFlags) {
1696         try {
1697            ActivityManagerNative.getDefault().revokeUriPermission(
1698                    mMainThread.getApplicationThread(), uri,
1699                    modeFlags);
1700        } catch (RemoteException e) {
1701        }
1702    }
1703
1704    @Override
1705    public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
1706        try {
1707            return ActivityManagerNative.getDefault().checkUriPermission(
1708                    uri, pid, uid, modeFlags);
1709        } catch (RemoteException e) {
1710            return PackageManager.PERMISSION_DENIED;
1711        }
1712    }
1713
1714    @Override
1715    public int checkCallingUriPermission(Uri uri, int modeFlags) {
1716        int pid = Binder.getCallingPid();
1717        if (pid != Process.myPid()) {
1718            return checkUriPermission(uri, pid,
1719                    Binder.getCallingUid(), modeFlags);
1720        }
1721        return PackageManager.PERMISSION_DENIED;
1722    }
1723
1724    @Override
1725    public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
1726        return checkUriPermission(uri, Binder.getCallingPid(),
1727                Binder.getCallingUid(), modeFlags);
1728    }
1729
1730    @Override
1731    public int checkUriPermission(Uri uri, String readPermission,
1732            String writePermission, int pid, int uid, int modeFlags) {
1733        if (DEBUG) {
1734            Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission="
1735                    + readPermission + " writePermission=" + writePermission
1736                    + " pid=" + pid + " uid=" + uid + " mode" + modeFlags);
1737        }
1738        if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
1739            if (readPermission == null
1740                    || checkPermission(readPermission, pid, uid)
1741                    == PackageManager.PERMISSION_GRANTED) {
1742                return PackageManager.PERMISSION_GRANTED;
1743            }
1744        }
1745        if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
1746            if (writePermission == null
1747                    || checkPermission(writePermission, pid, uid)
1748                    == PackageManager.PERMISSION_GRANTED) {
1749                return PackageManager.PERMISSION_GRANTED;
1750            }
1751        }
1752        return uri != null ? checkUriPermission(uri, pid, uid, modeFlags)
1753                : PackageManager.PERMISSION_DENIED;
1754    }
1755
1756    private String uriModeFlagToString(int uriModeFlags) {
1757        switch (uriModeFlags) {
1758            case Intent.FLAG_GRANT_READ_URI_PERMISSION |
1759                    Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1760                return "read and write";
1761            case Intent.FLAG_GRANT_READ_URI_PERMISSION:
1762                return "read";
1763            case Intent.FLAG_GRANT_WRITE_URI_PERMISSION:
1764                return "write";
1765        }
1766        throw new IllegalArgumentException(
1767                "Unknown permission mode flags: " + uriModeFlags);
1768    }
1769
1770    private void enforceForUri(
1771            int modeFlags, int resultOfCheck, boolean selfToo,
1772            int uid, Uri uri, String message) {
1773        if (resultOfCheck != PackageManager.PERMISSION_GRANTED) {
1774            throw new SecurityException(
1775                    (message != null ? (message + ": ") : "") +
1776                    (selfToo
1777                     ? "Neither user " + uid + " nor current process has "
1778                     : "User " + uid + " does not have ") +
1779                    uriModeFlagToString(modeFlags) +
1780                    " permission on " +
1781                    uri +
1782                    ".");
1783        }
1784    }
1785
1786    public void enforceUriPermission(
1787            Uri uri, int pid, int uid, int modeFlags, String message) {
1788        enforceForUri(
1789                modeFlags, checkUriPermission(uri, pid, uid, modeFlags),
1790                false, uid, uri, message);
1791    }
1792
1793    public void enforceCallingUriPermission(
1794            Uri uri, int modeFlags, String message) {
1795        enforceForUri(
1796                modeFlags, checkCallingUriPermission(uri, modeFlags),
1797                false,
1798                Binder.getCallingUid(), uri, message);
1799    }
1800
1801    public void enforceCallingOrSelfUriPermission(
1802            Uri uri, int modeFlags, String message) {
1803        enforceForUri(
1804                modeFlags,
1805                checkCallingOrSelfUriPermission(uri, modeFlags), true,
1806                Binder.getCallingUid(), uri, message);
1807    }
1808
1809    public void enforceUriPermission(
1810            Uri uri, String readPermission, String writePermission,
1811            int pid, int uid, int modeFlags, String message) {
1812        enforceForUri(modeFlags,
1813                      checkUriPermission(
1814                              uri, readPermission, writePermission, pid, uid,
1815                              modeFlags),
1816                      false,
1817                      uid,
1818                      uri,
1819                      message);
1820    }
1821
1822    private void warnIfCallingFromSystemProcess() {
1823        if (Process.myUid() == Process.SYSTEM_UID) {
1824            Slog.w(TAG, "Calling a method in the system process without a qualified user: "
1825                    + Debug.getCallers(5));
1826        }
1827    }
1828
1829    @Override
1830    public Context createPackageContext(String packageName, int flags)
1831            throws NameNotFoundException {
1832        return createPackageContextAsUser(packageName, flags,
1833                mUser != null ? mUser : Process.myUserHandle());
1834    }
1835
1836    @Override
1837    public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
1838            throws NameNotFoundException {
1839        if (packageName.equals("system") || packageName.equals("android")) {
1840            final ContextImpl context = new ContextImpl(mMainThread.getSystemContext());
1841            context.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1842            context.init(mPackageInfo, null, mMainThread, mResources, mBasePackageName, user);
1843            return context;
1844        }
1845
1846        LoadedApk pi =
1847            mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), flags,
1848                    user.getIdentifier());
1849        if (pi != null) {
1850            ContextImpl c = new ContextImpl();
1851            c.mRestricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED;
1852            c.init(pi, null, mMainThread, mResources, mBasePackageName, user);
1853            if (c.mResources != null) {
1854                return c;
1855            }
1856        }
1857
1858        // Should be a better exception.
1859        throw new PackageManager.NameNotFoundException(
1860            "Application package " + packageName + " not found");
1861    }
1862
1863    @Override
1864    public Context createConfigurationContext(Configuration overrideConfiguration) {
1865        if (overrideConfiguration == null) {
1866            throw new IllegalArgumentException("overrideConfiguration must not be null");
1867        }
1868
1869        ContextImpl c = new ContextImpl();
1870        c.init(mPackageInfo, null, mMainThread);
1871        c.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
1872                getDisplayId(), overrideConfiguration, mResources.getCompatibilityInfo(),
1873                mActivityToken);
1874        return c;
1875    }
1876
1877    @Override
1878    public Context createDisplayContext(Display display) {
1879        if (display == null) {
1880            throw new IllegalArgumentException("display must not be null");
1881        }
1882
1883        int displayId = display.getDisplayId();
1884
1885        ContextImpl context = new ContextImpl();
1886        context.init(mPackageInfo, null, mMainThread);
1887        context.mDisplay = display;
1888        DisplayAdjustments daj = getDisplayAdjustments(displayId);
1889        context.mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
1890                displayId, null, daj.getCompatibilityInfo(), null);
1891        return context;
1892    }
1893
1894    private int getDisplayId() {
1895        return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY;
1896    }
1897
1898    @Override
1899    public boolean isRestricted() {
1900        return mRestricted;
1901    }
1902
1903    @Override
1904    public DisplayAdjustments getDisplayAdjustments(int displayId) {
1905        return mDisplayAdjustments;
1906    }
1907
1908    private File getDataDirFile() {
1909        if (mPackageInfo != null) {
1910            return mPackageInfo.getDataDirFile();
1911        }
1912        throw new RuntimeException("Not supported in system context");
1913    }
1914
1915    @Override
1916    public File getDir(String name, int mode) {
1917        name = "app_" + name;
1918        File file = makeFilename(getDataDirFile(), name);
1919        if (!file.exists()) {
1920            file.mkdir();
1921            setFilePermissionsFromMode(file.getPath(), mode,
1922                    FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH);
1923        }
1924        return file;
1925    }
1926
1927    /** {@hide} */
1928    public int getUserId() {
1929        return mUser.getIdentifier();
1930    }
1931
1932    static ContextImpl createSystemContext(ActivityThread mainThread) {
1933        final ContextImpl context = new ContextImpl();
1934        context.init(Resources.getSystem(), mainThread, Process.myUserHandle());
1935        return context;
1936    }
1937
1938    ContextImpl() {
1939        mOuterContext = this;
1940    }
1941
1942    /**
1943     * Create a new ApplicationContext from an existing one.  The new one
1944     * works and operates the same as the one it is copying.
1945     *
1946     * @param context Existing application context.
1947     */
1948    public ContextImpl(ContextImpl context) {
1949        mPackageInfo = context.mPackageInfo;
1950        mBasePackageName = context.mBasePackageName;
1951        mResources = context.mResources;
1952        mMainThread = context.mMainThread;
1953        mContentResolver = context.mContentResolver;
1954        mUser = context.mUser;
1955        mDisplay = context.mDisplay;
1956        mOuterContext = this;
1957        mDisplayAdjustments.setCompatibilityInfo(mPackageInfo.getCompatibilityInfo());
1958    }
1959
1960    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread) {
1961        init(packageInfo, activityToken, mainThread, null, null, Process.myUserHandle());
1962    }
1963
1964    final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread,
1965            Resources container, String basePackageName, UserHandle user) {
1966        mPackageInfo = packageInfo;
1967        mBasePackageName = basePackageName != null ? basePackageName : packageInfo.mPackageName;
1968        mResources = mPackageInfo.getResources(mainThread);
1969        mResourcesManager = ResourcesManager.getInstance();
1970
1971        CompatibilityInfo compatInfo =
1972                container == null ? null : container.getCompatibilityInfo();
1973        if (mResources != null &&
1974                ((compatInfo != null && compatInfo.applicationScale !=
1975                        mResources.getCompatibilityInfo().applicationScale)
1976                || activityToken != null)) {
1977            if (DEBUG) {
1978                Log.d(TAG, "loaded context has different scaling. Using container's" +
1979                        " compatiblity info:" + container.getDisplayMetrics());
1980            }
1981            if (compatInfo == null) {
1982                compatInfo = CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO;
1983            }
1984            mDisplayAdjustments.setCompatibilityInfo(compatInfo);
1985            mDisplayAdjustments.setActivityToken(activityToken);
1986            mResources = mResourcesManager.getTopLevelResources(mPackageInfo.getResDir(),
1987                    Display.DEFAULT_DISPLAY, null, compatInfo, activityToken);
1988        } else {
1989            mDisplayAdjustments.setCompatibilityInfo(packageInfo.getCompatibilityInfo());
1990            mDisplayAdjustments.setActivityToken(activityToken);
1991        }
1992        mMainThread = mainThread;
1993        mActivityToken = activityToken;
1994        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
1995        mUser = user;
1996    }
1997
1998    final void init(Resources resources, ActivityThread mainThread, UserHandle user) {
1999        mPackageInfo = null;
2000        mBasePackageName = null;
2001        mResources = resources;
2002        mMainThread = mainThread;
2003        mContentResolver = new ApplicationContentResolver(this, mainThread, user);
2004        mUser = user;
2005    }
2006
2007    final void scheduleFinalCleanup(String who, String what) {
2008        mMainThread.scheduleContextCleanup(this, who, what);
2009    }
2010
2011    final void performFinalCleanup(String who, String what) {
2012        //Log.i(TAG, "Cleanup up context: " + this);
2013        mPackageInfo.removeContextRegistrations(getOuterContext(), who, what);
2014    }
2015
2016    final Context getReceiverRestrictedContext() {
2017        if (mReceiverRestrictedContext != null) {
2018            return mReceiverRestrictedContext;
2019        }
2020        return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext());
2021    }
2022
2023    final void setOuterContext(Context context) {
2024        mOuterContext = context;
2025    }
2026
2027    final Context getOuterContext() {
2028        return mOuterContext;
2029    }
2030
2031    final IBinder getActivityToken() {
2032        return mActivityToken;
2033    }
2034
2035    static void setFilePermissionsFromMode(String name, int mode,
2036            int extraPermissions) {
2037        int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR
2038            |FileUtils.S_IRGRP|FileUtils.S_IWGRP
2039            |extraPermissions;
2040        if ((mode&MODE_WORLD_READABLE) != 0) {
2041            perms |= FileUtils.S_IROTH;
2042        }
2043        if ((mode&MODE_WORLD_WRITEABLE) != 0) {
2044            perms |= FileUtils.S_IWOTH;
2045        }
2046        if (DEBUG) {
2047            Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode)
2048                  + ", perms=0x" + Integer.toHexString(perms));
2049        }
2050        FileUtils.setPermissions(name, perms, -1, -1);
2051    }
2052
2053    private File validateFilePath(String name, boolean createDirectory) {
2054        File dir;
2055        File f;
2056
2057        if (name.charAt(0) == File.separatorChar) {
2058            String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar));
2059            dir = new File(dirPath);
2060            name = name.substring(name.lastIndexOf(File.separatorChar));
2061            f = new File(dir, name);
2062        } else {
2063            dir = getDatabasesDir();
2064            f = makeFilename(dir, name);
2065        }
2066
2067        if (createDirectory && !dir.isDirectory() && dir.mkdir()) {
2068            FileUtils.setPermissions(dir.getPath(),
2069                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
2070                -1, -1);
2071        }
2072
2073        return f;
2074    }
2075
2076    private File makeFilename(File base, String name) {
2077        if (name.indexOf(File.separatorChar) < 0) {
2078            return new File(base, name);
2079        }
2080        throw new IllegalArgumentException(
2081                "File " + name + " contains a path separator");
2082    }
2083
2084    // ----------------------------------------------------------------------
2085    // ----------------------------------------------------------------------
2086    // ----------------------------------------------------------------------
2087
2088    private static final class ApplicationContentResolver extends ContentResolver {
2089        private final ActivityThread mMainThread;
2090        private final UserHandle mUser;
2091
2092        public ApplicationContentResolver(
2093                Context context, ActivityThread mainThread, UserHandle user) {
2094            super(context);
2095            mMainThread = Preconditions.checkNotNull(mainThread);
2096            mUser = Preconditions.checkNotNull(user);
2097        }
2098
2099        @Override
2100        protected IContentProvider acquireProvider(Context context, String auth) {
2101            return mMainThread.acquireProvider(context, auth, mUser.getIdentifier(), true);
2102        }
2103
2104        @Override
2105        protected IContentProvider acquireExistingProvider(Context context, String auth) {
2106            return mMainThread.acquireExistingProvider(context, auth, mUser.getIdentifier(), true);
2107        }
2108
2109        @Override
2110        public boolean releaseProvider(IContentProvider provider) {
2111            return mMainThread.releaseProvider(provider, true);
2112        }
2113
2114        @Override
2115        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2116            return mMainThread.acquireProvider(c, auth, mUser.getIdentifier(), false);
2117        }
2118
2119        @Override
2120        public boolean releaseUnstableProvider(IContentProvider icp) {
2121            return mMainThread.releaseProvider(icp, false);
2122        }
2123
2124        @Override
2125        public void unstableProviderDied(IContentProvider icp) {
2126            mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
2127        }
2128    }
2129}
2130