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