| /* |
| * Copyright (C) 2006 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.app; |
| |
| import android.net.wifi.IWifiScanner; |
| import android.net.wifi.WifiScanner; |
| import android.os.Build; |
| |
| import com.android.internal.policy.PolicyManager; |
| import com.android.internal.util.Preconditions; |
| |
| import android.bluetooth.BluetoothManager; |
| import android.content.BroadcastReceiver; |
| import android.content.ComponentName; |
| import android.content.ContentProvider; |
| import android.content.ContentResolver; |
| import android.content.Context; |
| import android.content.ContextWrapper; |
| import android.content.IContentProvider; |
| import android.content.Intent; |
| import android.content.IntentFilter; |
| import android.content.IIntentReceiver; |
| import android.content.IntentSender; |
| import android.content.IRestrictionsManager; |
| import android.content.ReceiverCallNotAllowedException; |
| import android.content.RestrictionsManager; |
| import android.content.ServiceConnection; |
| import android.content.SharedPreferences; |
| import android.content.pm.ApplicationInfo; |
| import android.content.pm.ILauncherApps; |
| import android.content.pm.IPackageManager; |
| import android.content.pm.LauncherApps; |
| import android.content.pm.PackageManager; |
| import android.content.pm.PackageManager.NameNotFoundException; |
| import android.content.res.AssetManager; |
| import android.content.res.CompatibilityInfo; |
| import android.content.res.Configuration; |
| import android.content.res.Resources; |
| import android.database.DatabaseErrorHandler; |
| import android.database.sqlite.SQLiteDatabase; |
| import android.database.sqlite.SQLiteDatabase.CursorFactory; |
| import android.graphics.Bitmap; |
| import android.graphics.drawable.Drawable; |
| import android.hardware.ConsumerIrManager; |
| import android.hardware.ISerialManager; |
| import android.hardware.SerialManager; |
| import android.hardware.SystemSensorManager; |
| import android.hardware.hdmi.HdmiCecManager; |
| import android.hardware.hdmi.HdmiControlManager; |
| import android.hardware.hdmi.IHdmiCecService; |
| import android.hardware.hdmi.IHdmiControlService; |
| import android.hardware.camera2.CameraManager; |
| import android.hardware.display.DisplayManager; |
| import android.hardware.input.InputManager; |
| import android.hardware.usb.IUsbManager; |
| import android.hardware.usb.UsbManager; |
| import android.location.CountryDetector; |
| import android.location.ICountryDetector; |
| import android.location.ILocationManager; |
| import android.location.LocationManager; |
| import android.media.AudioManager; |
| import android.media.MediaRouter; |
| import android.media.session.MediaSessionManager; |
| import android.media.tv.ITvInputManager; |
| import android.media.tv.TvInputManager; |
| import android.net.ConnectivityManager; |
| import android.net.IConnectivityManager; |
| import android.net.EthernetManager; |
| import android.net.IEthernetManager; |
| import android.net.INetworkPolicyManager; |
| import android.net.NetworkPolicyManager; |
| import android.net.NetworkScoreManager; |
| import android.net.Uri; |
| import android.net.nsd.INsdManager; |
| import android.net.nsd.NsdManager; |
| import android.net.wifi.IWifiManager; |
| import android.net.wifi.WifiManager; |
| import android.net.wifi.passpoint.IWifiPasspointManager; |
| import android.net.wifi.passpoint.WifiPasspointManager; |
| import android.net.wifi.p2p.IWifiP2pManager; |
| import android.net.wifi.p2p.WifiP2pManager; |
| import android.nfc.NfcManager; |
| import android.os.BatteryManager; |
| import android.os.Binder; |
| import android.os.Bundle; |
| import android.os.Debug; |
| import android.os.DropBoxManager; |
| import android.os.Environment; |
| import android.os.FileUtils; |
| import android.os.Handler; |
| import android.os.IBinder; |
| import android.os.IPowerManager; |
| import android.os.IUserManager; |
| import android.os.Looper; |
| import android.os.PowerManager; |
| import android.os.Process; |
| import android.os.RemoteException; |
| import android.os.ServiceManager; |
| import android.os.UserHandle; |
| import android.os.SystemVibrator; |
| import android.os.UserManager; |
| import android.os.storage.IMountService; |
| import android.os.storage.StorageManager; |
| import android.print.IPrintManager; |
| import android.print.PrintManager; |
| import android.service.fingerprint.FingerprintManager; |
| import android.service.fingerprint.FingerprintManagerReceiver; |
| import android.service.fingerprint.FingerprintService; |
| import android.telephony.TelephonyManager; |
| import android.content.ClipboardManager; |
| import android.util.AndroidRuntimeException; |
| import android.util.ArrayMap; |
| import android.util.Log; |
| import android.util.Slog; |
| import android.view.DisplayAdjustments; |
| import android.view.ContextThemeWrapper; |
| import android.view.Display; |
| import android.view.WindowManagerImpl; |
| import android.view.accessibility.AccessibilityManager; |
| import android.view.accessibility.CaptioningManager; |
| import android.view.inputmethod.InputMethodManager; |
| import android.view.textservice.TextServicesManager; |
| import android.accounts.AccountManager; |
| import android.accounts.IAccountManager; |
| import android.app.admin.DevicePolicyManager; |
| import android.app.task.ITaskManager; |
| import android.app.trust.TrustManager; |
| |
| import com.android.internal.annotations.GuardedBy; |
| import com.android.internal.app.IAppOpsService; |
| import com.android.internal.appwidget.IAppWidgetService.Stub; |
| import com.android.internal.os.IDropBoxManagerService; |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| |
| class ReceiverRestrictedContext extends ContextWrapper { |
| ReceiverRestrictedContext(Context base) { |
| super(base); |
| } |
| |
| @Override |
| public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { |
| return registerReceiver(receiver, filter, null, null); |
| } |
| |
| @Override |
| public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, |
| String broadcastPermission, Handler scheduler) { |
| if (receiver == null) { |
| // Allow retrieving current sticky broadcast; this is safe since we |
| // aren't actually registering a receiver. |
| return super.registerReceiver(null, filter, broadcastPermission, scheduler); |
| } else { |
| throw new ReceiverCallNotAllowedException( |
| "BroadcastReceiver components are not allowed to register to receive intents"); |
| } |
| } |
| |
| @Override |
| public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, |
| IntentFilter filter, String broadcastPermission, Handler scheduler) { |
| if (receiver == null) { |
| // Allow retrieving current sticky broadcast; this is safe since we |
| // aren't actually registering a receiver. |
| return super.registerReceiverAsUser(null, user, filter, broadcastPermission, scheduler); |
| } else { |
| throw new ReceiverCallNotAllowedException( |
| "BroadcastReceiver components are not allowed to register to receive intents"); |
| } |
| } |
| |
| @Override |
| public boolean bindService(Intent service, ServiceConnection conn, int flags) { |
| throw new ReceiverCallNotAllowedException( |
| "BroadcastReceiver components are not allowed to bind to services"); |
| } |
| } |
| |
| /** |
| * Common implementation of Context API, which provides the base |
| * context object for Activity and other application components. |
| */ |
| class ContextImpl extends Context { |
| private final static String TAG = "ContextImpl"; |
| private final static boolean DEBUG = false; |
| |
| /** |
| * Map from package name, to preference name, to cached preferences. |
| */ |
| private static ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>> sSharedPrefs; |
| |
| final ActivityThread mMainThread; |
| final LoadedApk mPackageInfo; |
| |
| private final IBinder mActivityToken; |
| |
| private final UserHandle mUser; |
| |
| private final ApplicationContentResolver mContentResolver; |
| |
| private final String mBasePackageName; |
| private final String mOpPackageName; |
| |
| private final ResourcesManager mResourcesManager; |
| private final Resources mResources; |
| private final Display mDisplay; // may be null if default display |
| private final DisplayAdjustments mDisplayAdjustments = new DisplayAdjustments(); |
| private final Configuration mOverrideConfiguration; |
| |
| private final boolean mRestricted; |
| |
| private Context mOuterContext; |
| private int mThemeResource = 0; |
| private Resources.Theme mTheme = null; |
| private PackageManager mPackageManager; |
| private Context mReceiverRestrictedContext = null; |
| |
| private final Object mSync = new Object(); |
| |
| @GuardedBy("mSync") |
| private File mDatabasesDir; |
| @GuardedBy("mSync") |
| private File mPreferencesDir; |
| @GuardedBy("mSync") |
| private File mFilesDir; |
| @GuardedBy("mSync") |
| private File mCacheDir; |
| |
| @GuardedBy("mSync") |
| private File[] mExternalObbDirs; |
| @GuardedBy("mSync") |
| private File[] mExternalFilesDirs; |
| @GuardedBy("mSync") |
| private File[] mExternalCacheDirs; |
| @GuardedBy("mSync") |
| private File[] mExternalMediaDirs; |
| |
| private static final String[] EMPTY_FILE_LIST = {}; |
| |
| /** |
| * Override this class when the system service constructor needs a |
| * ContextImpl. Else, use StaticServiceFetcher below. |
| */ |
| /*package*/ static class ServiceFetcher { |
| int mContextCacheIndex = -1; |
| |
| /** |
| * Main entrypoint; only override if you don't need caching. |
| */ |
| public Object getService(ContextImpl ctx) { |
| ArrayList<Object> cache = ctx.mServiceCache; |
| Object service; |
| synchronized (cache) { |
| if (cache.size() == 0) { |
| // Initialize the cache vector on first access. |
| // At this point sNextPerContextServiceCacheIndex |
| // is the number of potential services that are |
| // cached per-Context. |
| for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) { |
| cache.add(null); |
| } |
| } else { |
| service = cache.get(mContextCacheIndex); |
| if (service != null) { |
| return service; |
| } |
| } |
| service = createService(ctx); |
| cache.set(mContextCacheIndex, service); |
| return service; |
| } |
| } |
| |
| /** |
| * Override this to create a new per-Context instance of the |
| * service. getService() will handle locking and caching. |
| */ |
| public Object createService(ContextImpl ctx) { |
| throw new RuntimeException("Not implemented"); |
| } |
| } |
| |
| /** |
| * Override this class for services to be cached process-wide. |
| */ |
| abstract static class StaticServiceFetcher extends ServiceFetcher { |
| private Object mCachedInstance; |
| |
| @Override |
| public final Object getService(ContextImpl unused) { |
| synchronized (StaticServiceFetcher.this) { |
| Object service = mCachedInstance; |
| if (service != null) { |
| return service; |
| } |
| return mCachedInstance = createStaticService(); |
| } |
| } |
| |
| public abstract Object createStaticService(); |
| } |
| |
| private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = |
| new HashMap<String, ServiceFetcher>(); |
| |
| private static int sNextPerContextServiceCacheIndex = 0; |
| private static void registerService(String serviceName, ServiceFetcher fetcher) { |
| if (!(fetcher instanceof StaticServiceFetcher)) { |
| fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; |
| } |
| SYSTEM_SERVICE_MAP.put(serviceName, fetcher); |
| } |
| |
| // This one's defined separately and given a variable name so it |
| // can be re-used by getWallpaperManager(), avoiding a HashMap |
| // lookup. |
| private static ServiceFetcher WALLPAPER_FETCHER = new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new WallpaperManager(ctx.getOuterContext(), |
| ctx.mMainThread.getHandler()); |
| }}; |
| |
| static { |
| registerService(ACCESSIBILITY_SERVICE, new ServiceFetcher() { |
| public Object getService(ContextImpl ctx) { |
| return AccessibilityManager.getInstance(ctx); |
| }}); |
| |
| registerService(CAPTIONING_SERVICE, new ServiceFetcher() { |
| public Object getService(ContextImpl ctx) { |
| return new CaptioningManager(ctx); |
| }}); |
| |
| registerService(ACCOUNT_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(ACCOUNT_SERVICE); |
| IAccountManager service = IAccountManager.Stub.asInterface(b); |
| return new AccountManager(ctx, service); |
| }}); |
| |
| registerService(ACTIVITY_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(ALARM_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(ALARM_SERVICE); |
| IAlarmManager service = IAlarmManager.Stub.asInterface(b); |
| return new AlarmManager(service, ctx); |
| }}); |
| |
| registerService(AUDIO_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new AudioManager(ctx); |
| }}); |
| |
| registerService(MEDIA_ROUTER_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new MediaRouter(ctx); |
| }}); |
| |
| registerService(BLUETOOTH_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new BluetoothManager(ctx); |
| }}); |
| |
| registerService(HDMI_CEC_SERVICE, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| IBinder b = ServiceManager.getService(HDMI_CEC_SERVICE); |
| return new HdmiCecManager(IHdmiCecService.Stub.asInterface(b)); |
| }}); |
| |
| registerService(HDMI_CONTROL_SERVICE, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| IBinder b = ServiceManager.getService(HDMI_CONTROL_SERVICE); |
| return new HdmiControlManager(IHdmiControlService.Stub.asInterface(b)); |
| }}); |
| |
| registerService(CLIPBOARD_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new ClipboardManager(ctx.getOuterContext(), |
| ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(CONNECTIVITY_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(CONNECTIVITY_SERVICE); |
| return new ConnectivityManager(IConnectivityManager.Stub.asInterface(b), |
| ctx.getPackageName()); |
| }}); |
| |
| registerService(COUNTRY_DETECTOR, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| IBinder b = ServiceManager.getService(COUNTRY_DETECTOR); |
| return new CountryDetector(ICountryDetector.Stub.asInterface(b)); |
| }}); |
| |
| registerService(DEVICE_POLICY_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return DevicePolicyManager.create(ctx, ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(DOWNLOAD_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new DownloadManager(ctx.getContentResolver(), ctx.getPackageName()); |
| }}); |
| |
| registerService(BATTERY_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new BatteryManager(); |
| }}); |
| |
| registerService(NFC_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new NfcManager(ctx); |
| }}); |
| |
| registerService(DROPBOX_SERVICE, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| return createDropBoxManager(); |
| }}); |
| |
| registerService(INPUT_SERVICE, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| return InputManager.getInstance(); |
| }}); |
| |
| registerService(DISPLAY_SERVICE, new ServiceFetcher() { |
| @Override |
| public Object createService(ContextImpl ctx) { |
| return new DisplayManager(ctx.getOuterContext()); |
| }}); |
| |
| registerService(INPUT_METHOD_SERVICE, new StaticServiceFetcher() { |
| public Object createStaticService() { |
| return InputMethodManager.getInstance(); |
| }}); |
| |
| registerService(TEXT_SERVICES_MANAGER_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return TextServicesManager.getInstance(); |
| }}); |
| |
| registerService(KEYGUARD_SERVICE, new ServiceFetcher() { |
| public Object getService(ContextImpl ctx) { |
| // TODO: why isn't this caching it? It wasn't |
| // before, so I'm preserving the old behavior and |
| // using getService(), instead of createService() |
| // which would do the caching. |
| return new KeyguardManager(); |
| }}); |
| |
| registerService(FINGERPRINT_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new FingerprintManager(ctx); |
| }}); |
| |
| registerService(LAYOUT_INFLATER_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return PolicyManager.makeNewLayoutInflater(ctx.getOuterContext()); |
| }}); |
| |
| registerService(LOCATION_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(LOCATION_SERVICE); |
| return new LocationManager(ctx, ILocationManager.Stub.asInterface(b)); |
| }}); |
| |
| registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() { |
| @Override |
| public Object createService(ContextImpl ctx) { |
| return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface( |
| ServiceManager.getService(NETWORK_POLICY_SERVICE))); |
| } |
| }); |
| |
| registerService(NOTIFICATION_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| final Context outerContext = ctx.getOuterContext(); |
| return new NotificationManager( |
| new ContextThemeWrapper(outerContext, |
| Resources.selectSystemTheme(0, |
| outerContext.getApplicationInfo().targetSdkVersion, |
| com.android.internal.R.style.Theme_Dialog, |
| com.android.internal.R.style.Theme_Holo_Dialog, |
| com.android.internal.R.style.Theme_DeviceDefault_Dialog, |
| com.android.internal.R.style.Theme_DeviceDefault_Light_Dialog)), |
| ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(NSD_SERVICE, new ServiceFetcher() { |
| @Override |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(NSD_SERVICE); |
| INsdManager service = INsdManager.Stub.asInterface(b); |
| return new NsdManager(ctx.getOuterContext(), service); |
| }}); |
| |
| // Note: this was previously cached in a static variable, but |
| // constructed using mMainThread.getHandler(), so converting |
| // it to be a regular Context-cached service... |
| registerService(POWER_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(POWER_SERVICE); |
| IPowerManager service = IPowerManager.Stub.asInterface(b); |
| return new PowerManager(ctx.getOuterContext(), |
| service, ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(SEARCH_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new SearchManager(ctx.getOuterContext(), |
| ctx.mMainThread.getHandler()); |
| }}); |
| |
| registerService(SENSOR_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new SystemSensorManager(ctx.getOuterContext(), |
| ctx.mMainThread.getHandler().getLooper()); |
| }}); |
| |
| registerService(STATUS_BAR_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new StatusBarManager(ctx.getOuterContext()); |
| }}); |
| |
| registerService(STORAGE_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| try { |
| return new StorageManager( |
| ctx.getContentResolver(), ctx.mMainThread.getHandler().getLooper()); |
| } catch (RemoteException rex) { |
| Log.e(TAG, "Failed to create StorageManager", rex); |
| return null; |
| } |
| }}); |
| |
| registerService(TELEPHONY_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new TelephonyManager(ctx.getOuterContext()); |
| }}); |
| |
| registerService(UI_MODE_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new UiModeManager(); |
| }}); |
| |
| registerService(USB_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(USB_SERVICE); |
| return new UsbManager(ctx, IUsbManager.Stub.asInterface(b)); |
| }}); |
| |
| registerService(SERIAL_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(SERIAL_SERVICE); |
| return new SerialManager(ctx, ISerialManager.Stub.asInterface(b)); |
| }}); |
| |
| registerService(VIBRATOR_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new SystemVibrator(ctx); |
| }}); |
| |
| registerService(WALLPAPER_SERVICE, WALLPAPER_FETCHER); |
| |
| registerService(WIFI_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(WIFI_SERVICE); |
| IWifiManager service = IWifiManager.Stub.asInterface(b); |
| return new WifiManager(ctx.getOuterContext(), service); |
| }}); |
| |
| registerService(WIFI_PASSPOINT_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(WIFI_PASSPOINT_SERVICE); |
| IWifiPasspointManager service = IWifiPasspointManager.Stub.asInterface(b); |
| return new WifiPasspointManager(ctx.getOuterContext(), service); |
| }}); |
| |
| registerService(WIFI_P2P_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(WIFI_P2P_SERVICE); |
| IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b); |
| return new WifiP2pManager(service); |
| }}); |
| |
| registerService(WIFI_SCANNING_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(WIFI_SCANNING_SERVICE); |
| IWifiScanner service = IWifiScanner.Stub.asInterface(b); |
| return new WifiScanner(ctx.getOuterContext(), service); |
| }}); |
| |
| registerService(ETHERNET_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(ETHERNET_SERVICE); |
| IEthernetManager service = IEthernetManager.Stub.asInterface(b); |
| return new EthernetManager(ctx.getOuterContext(), service); |
| }}); |
| |
| registerService(WINDOW_SERVICE, new ServiceFetcher() { |
| Display mDefaultDisplay; |
| public Object getService(ContextImpl ctx) { |
| Display display = ctx.mDisplay; |
| if (display == null) { |
| if (mDefaultDisplay == null) { |
| DisplayManager dm = (DisplayManager)ctx.getOuterContext(). |
| getSystemService(Context.DISPLAY_SERVICE); |
| mDefaultDisplay = dm.getDisplay(Display.DEFAULT_DISPLAY); |
| } |
| display = mDefaultDisplay; |
| } |
| return new WindowManagerImpl(display); |
| }}); |
| |
| registerService(USER_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(USER_SERVICE); |
| IUserManager service = IUserManager.Stub.asInterface(b); |
| return new UserManager(ctx, service); |
| }}); |
| |
| registerService(APP_OPS_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(APP_OPS_SERVICE); |
| IAppOpsService service = IAppOpsService.Stub.asInterface(b); |
| return new AppOpsManager(ctx, service); |
| }}); |
| |
| registerService(CAMERA_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new CameraManager(ctx); |
| } |
| }); |
| |
| registerService(LAUNCHER_APPS_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(LAUNCHER_APPS_SERVICE); |
| ILauncherApps service = ILauncherApps.Stub.asInterface(b); |
| return new LauncherApps(ctx, service); |
| } |
| }); |
| |
| registerService(RESTRICTIONS_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(RESTRICTIONS_SERVICE); |
| IRestrictionsManager service = IRestrictionsManager.Stub.asInterface(b); |
| return new RestrictionsManager(ctx, service); |
| } |
| }); |
| registerService(PRINT_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder iBinder = ServiceManager.getService(Context.PRINT_SERVICE); |
| IPrintManager service = IPrintManager.Stub.asInterface(iBinder); |
| return new PrintManager(ctx.getOuterContext(), service, UserHandle.myUserId(), |
| UserHandle.getAppId(Process.myUid())); |
| }}); |
| |
| registerService(CONSUMER_IR_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new ConsumerIrManager(ctx); |
| }}); |
| |
| registerService(MEDIA_SESSION_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new MediaSessionManager(ctx); |
| } |
| }); |
| registerService(TRUST_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(TRUST_SERVICE); |
| return new TrustManager(b); |
| } |
| }); |
| |
| registerService(TV_INPUT_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder iBinder = ServiceManager.getService(TV_INPUT_SERVICE); |
| ITvInputManager service = ITvInputManager.Stub.asInterface(iBinder); |
| return new TvInputManager(service, UserHandle.myUserId()); |
| }}); |
| |
| registerService(NETWORK_SCORE_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new NetworkScoreManager(ctx); |
| } |
| }); |
| |
| registerService(USAGE_STATS_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| return new UsageStatsManager(ctx.getOuterContext()); |
| }}); |
| |
| registerService(TASK_SERVICE, new ServiceFetcher() { |
| public Object createService(ContextImpl ctx) { |
| IBinder b = ServiceManager.getService(TASK_SERVICE); |
| return new TaskManagerImpl(ITaskManager.Stub.asInterface(b)); |
| }}); |
| } |
| |
| static ContextImpl getImpl(Context context) { |
| Context nextContext; |
| while ((context instanceof ContextWrapper) && |
| (nextContext=((ContextWrapper)context).getBaseContext()) != null) { |
| context = nextContext; |
| } |
| return (ContextImpl)context; |
| } |
| |
| // The system service cache for the system services that are |
| // cached per-ContextImpl. Package-scoped to avoid accessor |
| // methods. |
| final ArrayList<Object> mServiceCache = new ArrayList<Object>(); |
| |
| @Override |
| public AssetManager getAssets() { |
| return getResources().getAssets(); |
| } |
| |
| @Override |
| public Resources getResources() { |
| return mResources; |
| } |
| |
| @Override |
| public PackageManager getPackageManager() { |
| if (mPackageManager != null) { |
| return mPackageManager; |
| } |
| |
| IPackageManager pm = ActivityThread.getPackageManager(); |
| if (pm != null) { |
| // Doesn't matter if we make more than one instance. |
| return (mPackageManager = new ApplicationPackageManager(this, pm)); |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public ContentResolver getContentResolver() { |
| return mContentResolver; |
| } |
| |
| @Override |
| public Looper getMainLooper() { |
| return mMainThread.getLooper(); |
| } |
| |
| @Override |
| public Context getApplicationContext() { |
| return (mPackageInfo != null) ? |
| mPackageInfo.getApplication() : mMainThread.getApplication(); |
| } |
| |
| @Override |
| public void setTheme(int resid) { |
| mThemeResource = resid; |
| } |
| |
| @Override |
| public int getThemeResId() { |
| return mThemeResource; |
| } |
| |
| @Override |
| public Resources.Theme getTheme() { |
| if (mTheme == null) { |
| mThemeResource = Resources.selectDefaultTheme(mThemeResource, |
| getOuterContext().getApplicationInfo().targetSdkVersion); |
| mTheme = mResources.newTheme(); |
| mTheme.applyStyle(mThemeResource, true); |
| } |
| return mTheme; |
| } |
| |
| @Override |
| public ClassLoader getClassLoader() { |
| return mPackageInfo != null ? |
| mPackageInfo.getClassLoader() : ClassLoader.getSystemClassLoader(); |
| } |
| |
| @Override |
| public String getPackageName() { |
| if (mPackageInfo != null) { |
| return mPackageInfo.getPackageName(); |
| } |
| // No mPackageInfo means this is a Context for the system itself, |
| // and this here is its name. |
| return "android"; |
| } |
| |
| /** @hide */ |
| @Override |
| public String getBasePackageName() { |
| return mBasePackageName != null ? mBasePackageName : getPackageName(); |
| } |
| |
| /** @hide */ |
| @Override |
| public String getOpPackageName() { |
| return mOpPackageName != null ? mOpPackageName : getBasePackageName(); |
| } |
| |
| @Override |
| public ApplicationInfo getApplicationInfo() { |
| if (mPackageInfo != null) { |
| return mPackageInfo.getApplicationInfo(); |
| } |
| throw new RuntimeException("Not supported in system context"); |
| } |
| |
| @Override |
| public String getPackageResourcePath() { |
| if (mPackageInfo != null) { |
| return mPackageInfo.getResDir(); |
| } |
| throw new RuntimeException("Not supported in system context"); |
| } |
| |
| @Override |
| public String getPackageCodePath() { |
| if (mPackageInfo != null) { |
| return mPackageInfo.getAppDir(); |
| } |
| throw new RuntimeException("Not supported in system context"); |
| } |
| |
| public File getSharedPrefsFile(String name) { |
| return makeFilename(getPreferencesDir(), name + ".xml"); |
| } |
| |
| @Override |
| public SharedPreferences getSharedPreferences(String name, int mode) { |
| SharedPreferencesImpl sp; |
| synchronized (ContextImpl.class) { |
| if (sSharedPrefs == null) { |
| sSharedPrefs = new ArrayMap<String, ArrayMap<String, SharedPreferencesImpl>>(); |
| } |
| |
| final String packageName = getPackageName(); |
| ArrayMap<String, SharedPreferencesImpl> packagePrefs = sSharedPrefs.get(packageName); |
| if (packagePrefs == null) { |
| packagePrefs = new ArrayMap<String, SharedPreferencesImpl>(); |
| sSharedPrefs.put(packageName, packagePrefs); |
| } |
| |
| // At least one application in the world actually passes in a null |
| // name. This happened to work because when we generated the file name |
| // we would stringify it to "null.xml". Nice. |
| if (mPackageInfo.getApplicationInfo().targetSdkVersion < |
| Build.VERSION_CODES.KITKAT) { |
| if (name == null) { |
| name = "null"; |
| } |
| } |
| |
| sp = packagePrefs.get(name); |
| if (sp == null) { |
| File prefsFile = getSharedPrefsFile(name); |
| sp = new SharedPreferencesImpl(prefsFile, mode); |
| packagePrefs.put(name, sp); |
| return sp; |
| } |
| } |
| if ((mode & Context.MODE_MULTI_PROCESS) != 0 || |
| getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { |
| // If somebody else (some other process) changed the prefs |
| // file behind our back, we reload it. This has been the |
| // historical (if undocumented) behavior. |
| sp.startReloadIfChangedUnexpectedly(); |
| } |
| return sp; |
| } |
| |
| private File getPreferencesDir() { |
| synchronized (mSync) { |
| if (mPreferencesDir == null) { |
| mPreferencesDir = new File(getDataDirFile(), "shared_prefs"); |
| } |
| return mPreferencesDir; |
| } |
| } |
| |
| @Override |
| public FileInputStream openFileInput(String name) |
| throws FileNotFoundException { |
| File f = makeFilename(getFilesDir(), name); |
| return new FileInputStream(f); |
| } |
| |
| @Override |
| public FileOutputStream openFileOutput(String name, int mode) |
| throws FileNotFoundException { |
| final boolean append = (mode&MODE_APPEND) != 0; |
| File f = makeFilename(getFilesDir(), name); |
| try { |
| FileOutputStream fos = new FileOutputStream(f, append); |
| setFilePermissionsFromMode(f.getPath(), mode, 0); |
| return fos; |
| } catch (FileNotFoundException e) { |
| } |
| |
| File parent = f.getParentFile(); |
| parent.mkdir(); |
| FileUtils.setPermissions( |
| parent.getPath(), |
| FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, |
| -1, -1); |
| FileOutputStream fos = new FileOutputStream(f, append); |
| setFilePermissionsFromMode(f.getPath(), mode, 0); |
| return fos; |
| } |
| |
| @Override |
| public boolean deleteFile(String name) { |
| File f = makeFilename(getFilesDir(), name); |
| return f.delete(); |
| } |
| |
| @Override |
| public File getFilesDir() { |
| synchronized (mSync) { |
| if (mFilesDir == null) { |
| mFilesDir = new File(getDataDirFile(), "files"); |
| } |
| if (!mFilesDir.exists()) { |
| if(!mFilesDir.mkdirs()) { |
| if (mFilesDir.exists()) { |
| // spurious failure; probably racing with another process for this app |
| return mFilesDir; |
| } |
| Log.w(TAG, "Unable to create files directory " + mFilesDir.getPath()); |
| return null; |
| } |
| FileUtils.setPermissions( |
| mFilesDir.getPath(), |
| FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, |
| -1, -1); |
| } |
| return mFilesDir; |
| } |
| } |
| |
| @Override |
| public File getExternalFilesDir(String type) { |
| // Operates on primary external storage |
| return getExternalFilesDirs(type)[0]; |
| } |
| |
| @Override |
| public File[] getExternalFilesDirs(String type) { |
| synchronized (mSync) { |
| if (mExternalFilesDirs == null) { |
| mExternalFilesDirs = Environment.buildExternalStorageAppFilesDirs(getPackageName()); |
| } |
| |
| // Splice in requested type, if any |
| File[] dirs = mExternalFilesDirs; |
| if (type != null) { |
| dirs = Environment.buildPaths(dirs, type); |
| } |
| |
| // Create dirs if needed |
| return ensureDirsExistOrFilter(dirs); |
| } |
| } |
| |
| @Override |
| public File getObbDir() { |
| // Operates on primary external storage |
| return getObbDirs()[0]; |
| } |
| |
| @Override |
| public File[] getObbDirs() { |
| synchronized (mSync) { |
| if (mExternalObbDirs == null) { |
| mExternalObbDirs = Environment.buildExternalStorageAppObbDirs(getPackageName()); |
| } |
| |
| // Create dirs if needed |
| return ensureDirsExistOrFilter(mExternalObbDirs); |
| } |
| } |
| |
| @Override |
| public File getCacheDir() { |
| synchronized (mSync) { |
| if (mCacheDir == null) { |
| mCacheDir = new File(getDataDirFile(), "cache"); |
| } |
| if (!mCacheDir.exists()) { |
| if(!mCacheDir.mkdirs()) { |
| if (mCacheDir.exists()) { |
| // spurious failure; probably racing with another process for this app |
| return mCacheDir; |
| } |
| Log.w(TAG, "Unable to create cache directory " + mCacheDir.getAbsolutePath()); |
| return null; |
| } |
| FileUtils.setPermissions( |
| mCacheDir.getPath(), |
| FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, |
| -1, -1); |
| } |
| } |
| return mCacheDir; |
| } |
| |
| @Override |
| public File getExternalCacheDir() { |
| // Operates on primary external storage |
| return getExternalCacheDirs()[0]; |
| } |
| |
| @Override |
| public File[] getExternalCacheDirs() { |
| synchronized (mSync) { |
| if (mExternalCacheDirs == null) { |
| mExternalCacheDirs = Environment.buildExternalStorageAppCacheDirs(getPackageName()); |
| } |
| |
| // Create dirs if needed |
| return ensureDirsExistOrFilter(mExternalCacheDirs); |
| } |
| } |
| |
| @Override |
| public File[] getExternalMediaDirs() { |
| synchronized (mSync) { |
| if (mExternalMediaDirs == null) { |
| mExternalMediaDirs = Environment.buildExternalStorageAppMediaDirs(getPackageName()); |
| } |
| |
| // Create dirs if needed |
| return ensureDirsExistOrFilter(mExternalMediaDirs); |
| } |
| } |
| |
| @Override |
| public File getFileStreamPath(String name) { |
| return makeFilename(getFilesDir(), name); |
| } |
| |
| @Override |
| public String[] fileList() { |
| final String[] list = getFilesDir().list(); |
| return (list != null) ? list : EMPTY_FILE_LIST; |
| } |
| |
| @Override |
| public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) { |
| return openOrCreateDatabase(name, mode, factory, null); |
| } |
| |
| @Override |
| public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, |
| DatabaseErrorHandler errorHandler) { |
| File f = validateFilePath(name, true); |
| int flags = SQLiteDatabase.CREATE_IF_NECESSARY; |
| if ((mode & MODE_ENABLE_WRITE_AHEAD_LOGGING) != 0) { |
| flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING; |
| } |
| SQLiteDatabase db = SQLiteDatabase.openDatabase(f.getPath(), factory, flags, errorHandler); |
| setFilePermissionsFromMode(f.getPath(), mode, 0); |
| return db; |
| } |
| |
| @Override |
| public boolean deleteDatabase(String name) { |
| try { |
| File f = validateFilePath(name, false); |
| return SQLiteDatabase.deleteDatabase(f); |
| } catch (Exception e) { |
| } |
| return false; |
| } |
| |
| @Override |
| public File getDatabasePath(String name) { |
| return validateFilePath(name, false); |
| } |
| |
| @Override |
| public String[] databaseList() { |
| final String[] list = getDatabasesDir().list(); |
| return (list != null) ? list : EMPTY_FILE_LIST; |
| } |
| |
| |
| private File getDatabasesDir() { |
| synchronized (mSync) { |
| if (mDatabasesDir == null) { |
| mDatabasesDir = new File(getDataDirFile(), "databases"); |
| } |
| if (mDatabasesDir.getPath().equals("databases")) { |
| mDatabasesDir = new File("/data/system"); |
| } |
| return mDatabasesDir; |
| } |
| } |
| |
| @Override |
| public Drawable getWallpaper() { |
| return getWallpaperManager().getDrawable(); |
| } |
| |
| @Override |
| public Drawable peekWallpaper() { |
| return getWallpaperManager().peekDrawable(); |
| } |
| |
| @Override |
| public int getWallpaperDesiredMinimumWidth() { |
| return getWallpaperManager().getDesiredMinimumWidth(); |
| } |
| |
| @Override |
| public int getWallpaperDesiredMinimumHeight() { |
| return getWallpaperManager().getDesiredMinimumHeight(); |
| } |
| |
| @Override |
| public void setWallpaper(Bitmap bitmap) throws IOException { |
| getWallpaperManager().setBitmap(bitmap); |
| } |
| |
| @Override |
| public void setWallpaper(InputStream data) throws IOException { |
| getWallpaperManager().setStream(data); |
| } |
| |
| @Override |
| public void clearWallpaper() throws IOException { |
| getWallpaperManager().clear(); |
| } |
| |
| @Override |
| public void startActivity(Intent intent) { |
| warnIfCallingFromSystemProcess(); |
| startActivity(intent, null); |
| } |
| |
| /** @hide */ |
| @Override |
| public void startActivityAsUser(Intent intent, UserHandle user) { |
| startActivityAsUser(intent, null, user); |
| } |
| |
| @Override |
| public void startActivity(Intent intent, Bundle options) { |
| warnIfCallingFromSystemProcess(); |
| if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { |
| throw new AndroidRuntimeException( |
| "Calling startActivity() from outside of an Activity " |
| + " context requires the FLAG_ACTIVITY_NEW_TASK flag." |
| + " Is this really what you want?"); |
| } |
| mMainThread.getInstrumentation().execStartActivity( |
| getOuterContext(), mMainThread.getApplicationThread(), null, |
| (Activity)null, intent, -1, options); |
| } |
| |
| /** @hide */ |
| @Override |
| public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) { |
| try { |
| ActivityManagerNative.getDefault().startActivityAsUser( |
| mMainThread.getApplicationThread(), getBasePackageName(), intent, |
| intent.resolveTypeIfNeeded(getContentResolver()), |
| null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null, options, |
| user.getIdentifier()); |
| } catch (RemoteException re) { |
| } |
| } |
| |
| @Override |
| public void startActivities(Intent[] intents) { |
| warnIfCallingFromSystemProcess(); |
| startActivities(intents, null); |
| } |
| |
| /** @hide */ |
| @Override |
| public void startActivitiesAsUser(Intent[] intents, Bundle options, UserHandle userHandle) { |
| if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { |
| throw new AndroidRuntimeException( |
| "Calling startActivities() from outside of an Activity " |
| + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." |
| + " Is this really what you want?"); |
| } |
| mMainThread.getInstrumentation().execStartActivitiesAsUser( |
| getOuterContext(), mMainThread.getApplicationThread(), null, |
| (Activity)null, intents, options, userHandle.getIdentifier()); |
| } |
| |
| @Override |
| public void startActivities(Intent[] intents, Bundle options) { |
| warnIfCallingFromSystemProcess(); |
| if ((intents[0].getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0) { |
| throw new AndroidRuntimeException( |
| "Calling startActivities() from outside of an Activity " |
| + " context requires the FLAG_ACTIVITY_NEW_TASK flag on first Intent." |
| + " Is this really what you want?"); |
| } |
| mMainThread.getInstrumentation().execStartActivities( |
| getOuterContext(), mMainThread.getApplicationThread(), null, |
| (Activity)null, intents, options); |
| } |
| |
| @Override |
| public void startIntentSender(IntentSender intent, |
| Intent fillInIntent, int flagsMask, int flagsValues, int extraFlags) |
| throws IntentSender.SendIntentException { |
| startIntentSender(intent, fillInIntent, flagsMask, flagsValues, extraFlags, null); |
| } |
| |
| @Override |
| public void startIntentSender(IntentSender intent, Intent fillInIntent, |
| int flagsMask, int flagsValues, int extraFlags, Bundle options) |
| throws IntentSender.SendIntentException { |
| try { |
| String resolvedType = null; |
| if (fillInIntent != null) { |
| fillInIntent.migrateExtraStreamToClipData(); |
| fillInIntent.prepareToLeaveProcess(); |
| resolvedType = fillInIntent.resolveTypeIfNeeded(getContentResolver()); |
| } |
| int result = ActivityManagerNative.getDefault() |
| .startActivityIntentSender(mMainThread.getApplicationThread(), intent, |
| fillInIntent, resolvedType, null, null, |
| 0, flagsMask, flagsValues, options); |
| if (result == ActivityManager.START_CANCELED) { |
| throw new IntentSender.SendIntentException(); |
| } |
| Instrumentation.checkStartActivityResult(result, null); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendBroadcast(Intent intent) { |
| warnIfCallingFromSystemProcess(); |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false, |
| getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendBroadcast(Intent intent, String receiverPermission) { |
| warnIfCallingFromSystemProcess(); |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, |
| false, false, getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { |
| warnIfCallingFromSystemProcess(); |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, receiverPermission, appOp, false, false, |
| getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendOrderedBroadcast(Intent intent, |
| String receiverPermission) { |
| warnIfCallingFromSystemProcess(); |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, true, false, |
| getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendOrderedBroadcast(Intent intent, |
| String receiverPermission, BroadcastReceiver resultReceiver, |
| Handler scheduler, int initialCode, String initialData, |
| Bundle initialExtras) { |
| sendOrderedBroadcast(intent, receiverPermission, AppOpsManager.OP_NONE, |
| resultReceiver, scheduler, initialCode, initialData, initialExtras); |
| } |
| |
| @Override |
| public void sendOrderedBroadcast(Intent intent, |
| String receiverPermission, int appOp, BroadcastReceiver resultReceiver, |
| Handler scheduler, int initialCode, String initialData, |
| Bundle initialExtras) { |
| warnIfCallingFromSystemProcess(); |
| IIntentReceiver rd = null; |
| if (resultReceiver != null) { |
| if (mPackageInfo != null) { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = mPackageInfo.getReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, |
| mMainThread.getInstrumentation(), false); |
| } else { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = new LoadedApk.ReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); |
| } |
| } |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, rd, |
| initialCode, initialData, initialExtras, receiverPermission, appOp, |
| true, false, getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendBroadcastAsUser(Intent intent, UserHandle user) { |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(), |
| intent, resolvedType, null, Activity.RESULT_OK, null, null, null, |
| AppOpsManager.OP_NONE, false, false, user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendBroadcastAsUser(Intent intent, UserHandle user, |
| String receiverPermission) { |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, receiverPermission, AppOpsManager.OP_NONE, false, false, |
| user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, |
| String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, |
| int initialCode, String initialData, Bundle initialExtras) { |
| sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE, |
| resultReceiver, scheduler, initialCode, initialData, initialExtras); |
| } |
| |
| @Override |
| public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, |
| String receiverPermission, int appOp, BroadcastReceiver resultReceiver, |
| Handler scheduler, |
| int initialCode, String initialData, Bundle initialExtras) { |
| IIntentReceiver rd = null; |
| if (resultReceiver != null) { |
| if (mPackageInfo != null) { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = mPackageInfo.getReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, |
| mMainThread.getInstrumentation(), false); |
| } else { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = new LoadedApk.ReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); |
| } |
| } |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, rd, |
| initialCode, initialData, initialExtras, receiverPermission, |
| appOp, true, false, user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendStickyBroadcast(Intent intent) { |
| warnIfCallingFromSystemProcess(); |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, |
| getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendStickyOrderedBroadcast(Intent intent, |
| BroadcastReceiver resultReceiver, |
| Handler scheduler, int initialCode, String initialData, |
| Bundle initialExtras) { |
| warnIfCallingFromSystemProcess(); |
| IIntentReceiver rd = null; |
| if (resultReceiver != null) { |
| if (mPackageInfo != null) { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = mPackageInfo.getReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, |
| mMainThread.getInstrumentation(), false); |
| } else { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = new LoadedApk.ReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); |
| } |
| } |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, rd, |
| initialCode, initialData, initialExtras, null, |
| AppOpsManager.OP_NONE, true, true, getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void removeStickyBroadcast(Intent intent) { |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| if (resolvedType != null) { |
| intent = new Intent(intent); |
| intent.setDataAndType(intent.getData(), resolvedType); |
| } |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().unbroadcastIntent( |
| mMainThread.getApplicationThread(), intent, getUserId()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, null, |
| Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, true, user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void sendStickyOrderedBroadcastAsUser(Intent intent, |
| UserHandle user, BroadcastReceiver resultReceiver, |
| Handler scheduler, int initialCode, String initialData, |
| Bundle initialExtras) { |
| IIntentReceiver rd = null; |
| if (resultReceiver != null) { |
| if (mPackageInfo != null) { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = mPackageInfo.getReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, |
| mMainThread.getInstrumentation(), false); |
| } else { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = new LoadedApk.ReceiverDispatcher( |
| resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver(); |
| } |
| } |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().broadcastIntent( |
| mMainThread.getApplicationThread(), intent, resolvedType, rd, |
| initialCode, initialData, initialExtras, null, |
| AppOpsManager.OP_NONE, true, true, user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { |
| String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); |
| if (resolvedType != null) { |
| intent = new Intent(intent); |
| intent.setDataAndType(intent.getData(), resolvedType); |
| } |
| try { |
| intent.prepareToLeaveProcess(); |
| ActivityManagerNative.getDefault().unbroadcastIntent( |
| mMainThread.getApplicationThread(), intent, user.getIdentifier()); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { |
| return registerReceiver(receiver, filter, null, null); |
| } |
| |
| @Override |
| public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, |
| String broadcastPermission, Handler scheduler) { |
| return registerReceiverInternal(receiver, getUserId(), |
| filter, broadcastPermission, scheduler, getOuterContext()); |
| } |
| |
| @Override |
| public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, |
| IntentFilter filter, String broadcastPermission, Handler scheduler) { |
| return registerReceiverInternal(receiver, user.getIdentifier(), |
| filter, broadcastPermission, scheduler, getOuterContext()); |
| } |
| |
| private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, |
| IntentFilter filter, String broadcastPermission, |
| Handler scheduler, Context context) { |
| IIntentReceiver rd = null; |
| if (receiver != null) { |
| if (mPackageInfo != null && context != null) { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = mPackageInfo.getReceiverDispatcher( |
| receiver, context, scheduler, |
| mMainThread.getInstrumentation(), true); |
| } else { |
| if (scheduler == null) { |
| scheduler = mMainThread.getHandler(); |
| } |
| rd = new LoadedApk.ReceiverDispatcher( |
| receiver, context, scheduler, null, true).getIIntentReceiver(); |
| } |
| } |
| try { |
| return ActivityManagerNative.getDefault().registerReceiver( |
| mMainThread.getApplicationThread(), mBasePackageName, |
| rd, filter, broadcastPermission, userId); |
| } catch (RemoteException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public void unregisterReceiver(BroadcastReceiver receiver) { |
| if (mPackageInfo != null) { |
| IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( |
| getOuterContext(), receiver); |
| try { |
| ActivityManagerNative.getDefault().unregisterReceiver(rd); |
| } catch (RemoteException e) { |
| } |
| } else { |
| throw new RuntimeException("Not supported in system context"); |
| } |
| } |
| |
| private void validateServiceIntent(Intent service) { |
| if (service.getComponent() == null && service.getPackage() == null) { |
| if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) { |
| IllegalArgumentException ex = new IllegalArgumentException( |
| "Service Intent must be explicit: " + service); |
| throw ex; |
| } else { |
| Log.w(TAG, "Implicit intents with startService are not safe: " + service |
| + " " + Debug.getCallers(2, 3)); |
| } |
| } |
| } |
| |
| @Override |
| public ComponentName startService(Intent service) { |
| warnIfCallingFromSystemProcess(); |
| return startServiceCommon(service, mUser); |
| } |
| |
| @Override |
| public boolean stopService(Intent service) { |
| warnIfCallingFromSystemProcess(); |
| return stopServiceCommon(service, mUser); |
| } |
| |
| @Override |
| public ComponentName startServiceAsUser(Intent service, UserHandle user) { |
| return startServiceCommon(service, user); |
| } |
| |
| private ComponentName startServiceCommon(Intent service, UserHandle user) { |
| try { |
| validateServiceIntent(service); |
| service.prepareToLeaveProcess(); |
| ComponentName cn = ActivityManagerNative.getDefault().startService( |
| mMainThread.getApplicationThread(), service, |
| service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); |
| if (cn != null) { |
| if (cn.getPackageName().equals("!")) { |
| throw new SecurityException( |
| "Not allowed to start service " + service |
| + " without permission " + cn.getClassName()); |
| } else if (cn.getPackageName().equals("!!")) { |
| throw new SecurityException( |
| "Unable to start service " + service |
| + ": " + cn.getClassName()); |
| } |
| } |
| return cn; |
| } catch (RemoteException e) { |
| return null; |
| } |
| } |
| |
| @Override |
| public boolean stopServiceAsUser(Intent service, UserHandle user) { |
| return stopServiceCommon(service, user); |
| } |
| |
| private boolean stopServiceCommon(Intent service, UserHandle user) { |
| try { |
| validateServiceIntent(service); |
| service.prepareToLeaveProcess(); |
| int res = ActivityManagerNative.getDefault().stopService( |
| mMainThread.getApplicationThread(), service, |
| service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); |
| if (res < 0) { |
| throw new SecurityException( |
| "Not allowed to stop service " + service); |
| } |
| return res != 0; |
| } catch (RemoteException e) { |
| return false; |
| } |
| } |
| |
| @Override |
| public boolean bindService(Intent service, ServiceConnection conn, |
| int flags) { |
| warnIfCallingFromSystemProcess(); |
| return bindServiceCommon(service, conn, flags, Process.myUserHandle()); |
| } |
| |
| /** @hide */ |
| @Override |
| public boolean bindServiceAsUser(Intent service, ServiceConnection conn, int flags, |
| UserHandle user) { |
| return bindServiceCommon(service, conn, flags, user); |
| } |
| |
| private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, |
| UserHandle user) { |
| IServiceConnection sd; |
| if (conn == null) { |
| throw new IllegalArgumentException("connection is null"); |
| } |
| if (mPackageInfo != null) { |
| sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), |
| mMainThread.getHandler(), flags); |
| } else { |
| throw new RuntimeException("Not supported in system context"); |
| } |
| validateServiceIntent(service); |
| try { |
| IBinder token = getActivityToken(); |
| if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null |
| && mPackageInfo.getApplicationInfo().targetSdkVersion |
| < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { |
| flags |= BIND_WAIVE_PRIORITY; |
| } |
| service.prepareToLeaveProcess(); |
| int res = ActivityManagerNative.getDefault().bindService( |
| mMainThread.getApplicationThread(), getActivityToken(), |
| service, service.resolveTypeIfNeeded(getContentResolver()), |
| sd, flags, user.getIdentifier()); |
| if (res < 0) { |
| throw new SecurityException( |
| "Not allowed to bind to service " + service); |
| } |
| return res != 0; |
| } catch (RemoteException e) { |
| return false; |
| } |
| } |
| |
| @Override |
| public void unbindService(ServiceConnection conn) { |
| if (conn == null) { |
| throw new IllegalArgumentException("connection is null"); |
| } |
| if (mPackageInfo != null) { |
| IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( |
| getOuterContext(), conn); |
| try { |
| ActivityManagerNative.getDefault().unbindService(sd); |
| } catch (RemoteException e) { |
| } |
| } else { |
| throw new RuntimeException("Not supported in system context"); |
| } |
| } |
| |
| @Override |
| public boolean startInstrumentation(ComponentName className, |
| String profileFile, Bundle arguments) { |
| try { |
| if (arguments != null) { |
| arguments.setAllowFds(false); |
| } |
| return ActivityManagerNative.getDefault().startInstrumentation( |
| className, profileFile, 0, arguments, null, null, getUserId(), |
| null /* ABI override */); |
| } catch (RemoteException e) { |
| // System has crashed, nothing we can do. |
| } |
| return false; |
| } |
| |
| @Override |
| public Object getSystemService(String name) { |
| ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); |
| return fetcher == null ? null : fetcher.getService(this); |
| } |
| |
| private WallpaperManager getWallpaperManager() { |
| return (WallpaperManager) WALLPAPER_FETCHER.getService(this); |
| } |
| |
| /* package */ static DropBoxManager createDropBoxManager() { |
| IBinder b = ServiceManager.getService(DROPBOX_SERVICE); |
| IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); |
| if (service == null) { |
| // Don't return a DropBoxManager that will NPE upon use. |
| // This also avoids caching a broken DropBoxManager in |
| // getDropBoxManager during early boot, before the |
| // DROPBOX_SERVICE is registered. |
| return null; |
| } |
| return new DropBoxManager(service); |
| } |
| |
| @Override |
| public int checkPermission(String permission, int pid, int uid) { |
| if (permission == null) { |
| throw new IllegalArgumentException("permission is null"); |
| } |
| |
| try { |
| return ActivityManagerNative.getDefault().checkPermission( |
| permission, pid, uid); |
| } catch (RemoteException e) { |
| return PackageManager.PERMISSION_DENIED; |
| } |
| } |
| |
| @Override |
| public int checkCallingPermission(String permission) { |
| if (permission == null) { |
| throw new IllegalArgumentException("permission is null"); |
| } |
| |
| int pid = Binder.getCallingPid(); |
| if (pid != Process.myPid()) { |
| return checkPermission(permission, pid, Binder.getCallingUid()); |
| } |
| return PackageManager.PERMISSION_DENIED; |
| } |
| |
| @Override |
| public int checkCallingOrSelfPermission(String permission) { |
| if (permission == null) { |
| throw new IllegalArgumentException("permission is null"); |
| } |
| |
| return checkPermission(permission, Binder.getCallingPid(), |
| Binder.getCallingUid()); |
| } |
| |
| private void enforce( |
| String permission, int resultOfCheck, |
| boolean selfToo, int uid, String message) { |
| if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { |
| throw new SecurityException( |
| (message != null ? (message + ": ") : "") + |
| (selfToo |
| ? "Neither user " + uid + " nor current process has " |
| : "uid " + uid + " does not have ") + |
| permission + |
| "."); |
| } |
| } |
| |
| public void enforcePermission( |
| String permission, int pid, int uid, String message) { |
| enforce(permission, |
| checkPermission(permission, pid, uid), |
| false, |
| uid, |
| message); |
| } |
| |
| public void enforceCallingPermission(String permission, String message) { |
| enforce(permission, |
| checkCallingPermission(permission), |
| false, |
| Binder.getCallingUid(), |
| message); |
| } |
| |
| public void enforceCallingOrSelfPermission( |
| String permission, String message) { |
| enforce(permission, |
| checkCallingOrSelfPermission(permission), |
| true, |
| Binder.getCallingUid(), |
| message); |
| } |
| |
| @Override |
| public void grantUriPermission(String toPackage, Uri uri, int modeFlags) { |
| try { |
| ActivityManagerNative.getDefault().grantUriPermission( |
| mMainThread.getApplicationThread(), toPackage, |
| ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public void revokeUriPermission(Uri uri, int modeFlags) { |
| try { |
| ActivityManagerNative.getDefault().revokeUriPermission( |
| mMainThread.getApplicationThread(), |
| ContentProvider.getUriWithoutUserId(uri), modeFlags, resolveUserId(uri)); |
| } catch (RemoteException e) { |
| } |
| } |
| |
| @Override |
| public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { |
| try { |
| return ActivityManagerNative.getDefault().checkUriPermission( |
| ContentProvider.getUriWithoutUserId(uri), pid, uid, modeFlags, |
| resolveUserId(uri)); |
| } catch (RemoteException e) { |
| return PackageManager.PERMISSION_DENIED; |
| } |
| } |
| |
| private int resolveUserId(Uri uri) { |
| return ContentProvider.getUserIdFromUri(uri, getUserId()); |
| } |
| |
| @Override |
| public int checkCallingUriPermission(Uri uri, int modeFlags) { |
| int pid = Binder.getCallingPid(); |
| if (pid != Process.myPid()) { |
| return checkUriPermission(uri, pid, |
| Binder.getCallingUid(), modeFlags); |
| } |
| return PackageManager.PERMISSION_DENIED; |
| } |
| |
| @Override |
| public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) { |
| return checkUriPermission(uri, Binder.getCallingPid(), |
| Binder.getCallingUid(), modeFlags); |
| } |
| |
| @Override |
| public int checkUriPermission(Uri uri, String readPermission, |
| String writePermission, int pid, int uid, int modeFlags) { |
| if (DEBUG) { |
| Log.i("foo", "checkUriPermission: uri=" + uri + "readPermission=" |
| + readPermission + " writePermission=" + writePermission |
| + " pid=" + pid + " uid=" + uid + " mode" + modeFlags); |
| } |
| if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { |
| if (readPermission == null |
| || checkPermission(readPermission, pid, uid) |
| == PackageManager.PERMISSION_GRANTED) { |
| return PackageManager.PERMISSION_GRANTED; |
| } |
| } |
| if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { |
| if (writePermission == null |
| || checkPermission(writePermission, pid, uid) |
| == PackageManager.PERMISSION_GRANTED) { |
| return PackageManager.PERMISSION_GRANTED; |
| } |
| } |
| return uri != null ? checkUriPermission(uri, pid, uid, modeFlags) |
| : PackageManager.PERMISSION_DENIED; |
| } |
| |
| private String uriModeFlagToString(int uriModeFlags) { |
| StringBuilder builder = new StringBuilder(); |
| if ((uriModeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { |
| builder.append("read and "); |
| } |
| if ((uriModeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { |
| builder.append("write and "); |
| } |
| if ((uriModeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0) { |
| builder.append("persistable and "); |
| } |
| if ((uriModeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { |
| builder.append("prefix and "); |
| } |
| |
| if (builder.length() > 5) { |
| builder.setLength(builder.length() - 5); |
| return builder.toString(); |
| } else { |
| throw new IllegalArgumentException("Unknown permission mode flags: " + uriModeFlags); |
| } |
| } |
| |
| private void enforceForUri( |
| int modeFlags, int resultOfCheck, boolean selfToo, |
| int uid, Uri uri, String message) { |
| if (resultOfCheck != PackageManager.PERMISSION_GRANTED) { |
| throw new SecurityException( |
| (message != null ? (message + ": ") : "") + |
| (selfToo |
| ? "Neither user " + uid + " nor current process has " |
| : "User " + uid + " does not have ") + |
| uriModeFlagToString(modeFlags) + |
| " permission on " + |
| uri + |
| "."); |
| } |
| } |
| |
| public void enforceUriPermission( |
| Uri uri, int pid, int uid, int modeFlags, String message) { |
| enforceForUri( |
| modeFlags, checkUriPermission(uri, pid, uid, modeFlags), |
| false, uid, uri, message); |
| } |
| |
| public void enforceCallingUriPermission( |
| Uri uri, int modeFlags, String message) { |
| enforceForUri( |
| modeFlags, checkCallingUriPermission(uri, modeFlags), |
| false, |
| Binder.getCallingUid(), uri, message); |
| } |
| |
| public void enforceCallingOrSelfUriPermission( |
| Uri uri, int modeFlags, String message) { |
| enforceForUri( |
| modeFlags, |
| checkCallingOrSelfUriPermission(uri, modeFlags), true, |
| Binder.getCallingUid(), uri, message); |
| } |
| |
| public void enforceUriPermission( |
| Uri uri, String readPermission, String writePermission, |
| int pid, int uid, int modeFlags, String message) { |
| enforceForUri(modeFlags, |
| checkUriPermission( |
| uri, readPermission, writePermission, pid, uid, |
| modeFlags), |
| false, |
| uid, |
| uri, |
| message); |
| } |
| |
| /** |
| * Logs a warning if the system process directly called a method such as |
| * {@link #startService(Intent)} instead of {@link #startServiceAsUser(Intent, UserHandle)}. |
| * The "AsUser" variants allow us to properly enforce the user's restrictions. |
| */ |
| private void warnIfCallingFromSystemProcess() { |
| if (Process.myUid() == Process.SYSTEM_UID) { |
| Slog.w(TAG, "Calling a method in the system process without a qualified user: " |
| + Debug.getCallers(5)); |
| } |
| } |
| |
| @Override |
| public Context createPackageContext(String packageName, int flags) |
| throws NameNotFoundException { |
| return createPackageContextAsUser(packageName, flags, |
| mUser != null ? mUser : Process.myUserHandle()); |
| } |
| |
| @Override |
| public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) |
| throws NameNotFoundException { |
| final boolean restricted = (flags & CONTEXT_RESTRICTED) == CONTEXT_RESTRICTED; |
| if (packageName.equals("system") || packageName.equals("android")) { |
| return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, |
| user, restricted, mDisplay, mOverrideConfiguration); |
| } |
| |
| LoadedApk pi = mMainThread.getPackageInfo(packageName, mResources.getCompatibilityInfo(), |
| flags, user.getIdentifier()); |
| if (pi != null) { |
| ContextImpl c = new ContextImpl(this, mMainThread, pi, mActivityToken, |
| user, restricted, mDisplay, mOverrideConfiguration); |
| if (c.mResources != null) { |
| return c; |
| } |
| } |
| |
| // Should be a better exception. |
| throw new PackageManager.NameNotFoundException( |
| "Application package " + packageName + " not found"); |
| } |
| |
| @Override |
| public Context createConfigurationContext(Configuration overrideConfiguration) { |
| if (overrideConfiguration == null) { |
| throw new IllegalArgumentException("overrideConfiguration must not be null"); |
| } |
| |
| return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, |
| mUser, mRestricted, mDisplay, overrideConfiguration); |
| } |
| |
| @Override |
| public Context createDisplayContext(Display display) { |
| if (display == null) { |
| throw new IllegalArgumentException("display must not be null"); |
| } |
| |
| return new ContextImpl(this, mMainThread, mPackageInfo, mActivityToken, |
| mUser, mRestricted, display, mOverrideConfiguration); |
| } |
| |
| private int getDisplayId() { |
| return mDisplay != null ? mDisplay.getDisplayId() : Display.DEFAULT_DISPLAY; |
| } |
| |
| @Override |
| public boolean isRestricted() { |
| return mRestricted; |
| } |
| |
| @Override |
| public DisplayAdjustments getDisplayAdjustments(int displayId) { |
| return mDisplayAdjustments; |
| } |
| |
| private File getDataDirFile() { |
| if (mPackageInfo != null) { |
| return mPackageInfo.getDataDirFile(); |
| } |
| throw new RuntimeException("Not supported in system context"); |
| } |
| |
| @Override |
| public File getDir(String name, int mode) { |
| name = "app_" + name; |
| File file = makeFilename(getDataDirFile(), name); |
| if (!file.exists()) { |
| file.mkdir(); |
| setFilePermissionsFromMode(file.getPath(), mode, |
| FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH); |
| } |
| return file; |
| } |
| |
| /** {@hide} */ |
| public int getUserId() { |
| return mUser.getIdentifier(); |
| } |
| |
| static ContextImpl createSystemContext(ActivityThread mainThread) { |
| LoadedApk packageInfo = new LoadedApk(mainThread); |
| ContextImpl context = new ContextImpl(null, mainThread, |
| packageInfo, null, null, false, null, null); |
| context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), |
| context.mResourcesManager.getDisplayMetricsLocked(Display.DEFAULT_DISPLAY)); |
| return context; |
| } |
| |
| static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { |
| if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); |
| return new ContextImpl(null, mainThread, |
| packageInfo, null, null, false, null, null); |
| } |
| |
| static ContextImpl createActivityContext(ActivityThread mainThread, |
| LoadedApk packageInfo, IBinder activityToken) { |
| if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); |
| if (activityToken == null) throw new IllegalArgumentException("activityInfo"); |
| return new ContextImpl(null, mainThread, |
| packageInfo, activityToken, null, false, null, null); |
| } |
| |
| private ContextImpl(ContextImpl container, ActivityThread mainThread, |
| LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted, |
| Display display, Configuration overrideConfiguration) { |
| mOuterContext = this; |
| |
| mMainThread = mainThread; |
| mActivityToken = activityToken; |
| mRestricted = restricted; |
| |
| if (user == null) { |
| user = Process.myUserHandle(); |
| } |
| mUser = user; |
| |
| mPackageInfo = packageInfo; |
| mContentResolver = new ApplicationContentResolver(this, mainThread, user); |
| mResourcesManager = ResourcesManager.getInstance(); |
| mDisplay = display; |
| mOverrideConfiguration = overrideConfiguration; |
| |
| final int displayId = getDisplayId(); |
| CompatibilityInfo compatInfo = null; |
| if (container != null) { |
| compatInfo = container.getDisplayAdjustments(displayId).getCompatibilityInfo(); |
| } |
| if (compatInfo == null && displayId == Display.DEFAULT_DISPLAY) { |
| compatInfo = packageInfo.getCompatibilityInfo(); |
| } |
| mDisplayAdjustments.setCompatibilityInfo(compatInfo); |
| mDisplayAdjustments.setActivityToken(activityToken); |
| |
| Resources resources = packageInfo.getResources(mainThread); |
| if (resources != null) { |
| if (activityToken != null |
| || displayId != Display.DEFAULT_DISPLAY |
| || overrideConfiguration != null |
| || (compatInfo != null && compatInfo.applicationScale |
| != resources.getCompatibilityInfo().applicationScale)) { |
| resources = mResourcesManager.getTopLevelResources( |
| packageInfo.getResDir(), packageInfo.getOverlayDirs(), |
| packageInfo.getApplicationInfo().sharedLibraryFiles, |
| displayId, overrideConfiguration, compatInfo, activityToken); |
| } |
| } |
| mResources = resources; |
| |
| if (container != null) { |
| mBasePackageName = container.mBasePackageName; |
| mOpPackageName = container.mOpPackageName; |
| } else { |
| mBasePackageName = packageInfo.mPackageName; |
| ApplicationInfo ainfo = packageInfo.getApplicationInfo(); |
| if (ainfo.uid == Process.SYSTEM_UID && ainfo.uid != Process.myUid()) { |
| // Special case: system components allow themselves to be loaded in to other |
| // processes. For purposes of app ops, we must then consider the context as |
| // belonging to the package of this process, not the system itself, otherwise |
| // the package+uid verifications in app ops will fail. |
| mOpPackageName = ActivityThread.currentPackageName(); |
| } else { |
| mOpPackageName = mBasePackageName; |
| } |
| } |
| } |
| |
| void installSystemApplicationInfo(ApplicationInfo info) { |
| mPackageInfo.installSystemApplicationInfo(info); |
| } |
| |
| final void scheduleFinalCleanup(String who, String what) { |
| mMainThread.scheduleContextCleanup(this, who, what); |
| } |
| |
| final void performFinalCleanup(String who, String what) { |
| //Log.i(TAG, "Cleanup up context: " + this); |
| mPackageInfo.removeContextRegistrations(getOuterContext(), who, what); |
| } |
| |
| final Context getReceiverRestrictedContext() { |
| if (mReceiverRestrictedContext != null) { |
| return mReceiverRestrictedContext; |
| } |
| return mReceiverRestrictedContext = new ReceiverRestrictedContext(getOuterContext()); |
| } |
| |
| final void setOuterContext(Context context) { |
| mOuterContext = context; |
| } |
| |
| final Context getOuterContext() { |
| return mOuterContext; |
| } |
| |
| final IBinder getActivityToken() { |
| return mActivityToken; |
| } |
| |
| static void setFilePermissionsFromMode(String name, int mode, |
| int extraPermissions) { |
| int perms = FileUtils.S_IRUSR|FileUtils.S_IWUSR |
| |FileUtils.S_IRGRP|FileUtils.S_IWGRP |
| |extraPermissions; |
| if ((mode&MODE_WORLD_READABLE) != 0) { |
| perms |= FileUtils.S_IROTH; |
| } |
| if ((mode&MODE_WORLD_WRITEABLE) != 0) { |
| perms |= FileUtils.S_IWOTH; |
| } |
| if (DEBUG) { |
| Log.i(TAG, "File " + name + ": mode=0x" + Integer.toHexString(mode) |
| + ", perms=0x" + Integer.toHexString(perms)); |
| } |
| FileUtils.setPermissions(name, perms, -1, -1); |
| } |
| |
| private File validateFilePath(String name, boolean createDirectory) { |
| File dir; |
| File f; |
| |
| if (name.charAt(0) == File.separatorChar) { |
| String dirPath = name.substring(0, name.lastIndexOf(File.separatorChar)); |
| dir = new File(dirPath); |
| name = name.substring(name.lastIndexOf(File.separatorChar)); |
| f = new File(dir, name); |
| } else { |
| dir = getDatabasesDir(); |
| f = makeFilename(dir, name); |
| } |
| |
| if (createDirectory && !dir.isDirectory() && dir.mkdir()) { |
| FileUtils.setPermissions(dir.getPath(), |
| FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH, |
| -1, -1); |
| } |
| |
| return f; |
| } |
| |
| private File makeFilename(File base, String name) { |
| if (name.indexOf(File.separatorChar) < 0) { |
| return new File(base, name); |
| } |
| throw new IllegalArgumentException( |
| "File " + name + " contains a path separator"); |
| } |
| |
| /** |
| * Ensure that given directories exist, trying to create them if missing. If |
| * unable to create, they are filtered by replacing with {@code null}. |
| */ |
| private File[] ensureDirsExistOrFilter(File[] dirs) { |
| File[] result = new File[dirs.length]; |
| for (int i = 0; i < dirs.length; i++) { |
| File dir = dirs[i]; |
| if (!dir.exists()) { |
| if (!dir.mkdirs()) { |
| // recheck existence in case of cross-process race |
| if (!dir.exists()) { |
| // Failing to mkdir() may be okay, since we might not have |
| // enough permissions; ask vold to create on our behalf. |
| final IMountService mount = IMountService.Stub.asInterface( |
| ServiceManager.getService("mount")); |
| int res = -1; |
| try { |
| res = mount.mkdirs(getPackageName(), dir.getAbsolutePath()); |
| } catch (RemoteException e) { |
| } |
| if (res != 0) { |
| Log.w(TAG, "Failed to ensure directory: " + dir); |
| dir = null; |
| } |
| } |
| } |
| } |
| result[i] = dir; |
| } |
| return result; |
| } |
| |
| // ---------------------------------------------------------------------- |
| // ---------------------------------------------------------------------- |
| // ---------------------------------------------------------------------- |
| |
| private static final class ApplicationContentResolver extends ContentResolver { |
| private final ActivityThread mMainThread; |
| private final UserHandle mUser; |
| |
| public ApplicationContentResolver( |
| Context context, ActivityThread mainThread, UserHandle user) { |
| super(context); |
| mMainThread = Preconditions.checkNotNull(mainThread); |
| mUser = Preconditions.checkNotNull(user); |
| } |
| |
| @Override |
| protected IContentProvider acquireProvider(Context context, String auth) { |
| return mMainThread.acquireProvider(context, |
| ContentProvider.getAuthorityWithoutUserId(auth), |
| resolveUserIdFromAuthority(auth), true); |
| } |
| |
| @Override |
| protected IContentProvider acquireExistingProvider(Context context, String auth) { |
| return mMainThread.acquireExistingProvider(context, |
| ContentProvider.getAuthorityWithoutUserId(auth), |
| resolveUserIdFromAuthority(auth), true); |
| } |
| |
| @Override |
| public boolean releaseProvider(IContentProvider provider) { |
| return mMainThread.releaseProvider(provider, true); |
| } |
| |
| @Override |
| protected IContentProvider acquireUnstableProvider(Context c, String auth) { |
| return mMainThread.acquireProvider(c, |
| ContentProvider.getAuthorityWithoutUserId(auth), |
| resolveUserIdFromAuthority(auth), false); |
| } |
| |
| @Override |
| public boolean releaseUnstableProvider(IContentProvider icp) { |
| return mMainThread.releaseProvider(icp, false); |
| } |
| |
| @Override |
| public void unstableProviderDied(IContentProvider icp) { |
| mMainThread.handleUnstableProviderDied(icp.asBinder(), true); |
| } |
| |
| @Override |
| public void appNotRespondingViaProvider(IContentProvider icp) { |
| mMainThread.appNotRespondingViaProvider(icp.asBinder()); |
| } |
| |
| /** @hide */ |
| protected int resolveUserIdFromAuthority(String auth) { |
| return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier()); |
| } |
| } |
| } |