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