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