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