All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robolectric.shadows.ShadowContextImpl Maven / Gradle / Ivy

The newest version!
package org.robolectric.shadows;

import static android.os.Build.VERSION_CODES.*;
import static org.robolectric.RuntimeEnvironment.getApiLevel;
import static org.robolectric.shadow.api.Shadow.newInstanceOf;

import android.accounts.IAccountManager;
import android.app.admin.IDevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IContentProvider;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.hardware.SystemSensorManager;
import android.net.wifi.p2p.IWifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.os.UserHandle;
import android.view.Display;
import android.view.accessibility.AccessibilityManager;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.annotation.Resetter;
import org.robolectric.util.ReflectionHelpers;
import org.robolectric.util.ReflectionHelpers.ClassParameter;

@Implements(className = ShadowContextImpl.CLASS_NAME)
public class ShadowContextImpl {

  public static final String CLASS_NAME = "android.app.ContextImpl";
  private static final Map SYSTEM_SERVICE_MAP = new HashMap<>();
  private ContentResolver contentResolver;

  @RealObject
  private Context realObject;

  static {
    // note that these are different!
    // They specify concrete classes within Robolectric for interfaces or abstract classes defined by Android
    SYSTEM_SERVICE_MAP.put(Context.WINDOW_SERVICE, "android.view.WindowManagerImpl");
    SYSTEM_SERVICE_MAP.put(Context.CLIPBOARD_SERVICE, "android.content.ClipboardManager");
    SYSTEM_SERVICE_MAP.put(Context.SENSOR_SERVICE, "android.hardware.SystemSensorManager");
    SYSTEM_SERVICE_MAP.put(Context.VIBRATOR_SERVICE, "org.robolectric.fakes.RoboVibrator");

    // the rest are as mapped in docs...
    SYSTEM_SERVICE_MAP.put(Context.LAYOUT_INFLATER_SERVICE, "android.view.LayoutInflater");
    SYSTEM_SERVICE_MAP.put(Context.ACTIVITY_SERVICE, "android.app.ActivityManager");
    SYSTEM_SERVICE_MAP.put(Context.POWER_SERVICE, "android.os.PowerManager");
    SYSTEM_SERVICE_MAP.put(Context.ALARM_SERVICE, "android.app.AlarmManager");
    SYSTEM_SERVICE_MAP.put(Context.NOTIFICATION_SERVICE, "android.app.NotificationManager");
    SYSTEM_SERVICE_MAP.put(Context.KEYGUARD_SERVICE, "android.app.KeyguardManager");
    SYSTEM_SERVICE_MAP.put(Context.LOCATION_SERVICE, "android.location.LocationManager");
    SYSTEM_SERVICE_MAP.put(Context.SEARCH_SERVICE, "android.app.SearchManager");
    SYSTEM_SERVICE_MAP.put(Context.STORAGE_SERVICE, "android.os.storage.StorageManager");
    SYSTEM_SERVICE_MAP.put(Context.CONNECTIVITY_SERVICE, "android.net.ConnectivityManager");
    SYSTEM_SERVICE_MAP.put(Context.WIFI_SERVICE, "android.net.wifi.WifiManager");
    SYSTEM_SERVICE_MAP.put(Context.AUDIO_SERVICE, "android.media.AudioManager");
    SYSTEM_SERVICE_MAP.put(Context.TELEPHONY_SERVICE, "android.telephony.TelephonyManager");
    SYSTEM_SERVICE_MAP.put(Context.INPUT_METHOD_SERVICE, "android.view.inputmethod.InputMethodManager");
    SYSTEM_SERVICE_MAP.put(Context.UI_MODE_SERVICE, "android.app.UiModeManager");
    SYSTEM_SERVICE_MAP.put(Context.DOWNLOAD_SERVICE, "android.app.DownloadManager");
    SYSTEM_SERVICE_MAP.put(Context.TEXT_SERVICES_MANAGER_SERVICE, "android.view.textservice.TextServicesManager");
    SYSTEM_SERVICE_MAP.put(Context.DEVICE_POLICY_SERVICE, "android.app.admin.DevicePolicyManager");
    SYSTEM_SERVICE_MAP.put(Context.DROPBOX_SERVICE, "android.os.DropBoxManager");
    SYSTEM_SERVICE_MAP.put(Context.MEDIA_ROUTER_SERVICE, "android.media.MediaRouter");
    SYSTEM_SERVICE_MAP.put(Context.ACCESSIBILITY_SERVICE, "android.view.accessibility.AccessibilityManager");
    SYSTEM_SERVICE_MAP.put(Context.ACCOUNT_SERVICE, "android.accounts.AccountManager");
    SYSTEM_SERVICE_MAP.put(Context.NFC_SERVICE, "android.nfc.NfcManager");
    SYSTEM_SERVICE_MAP.put(Context.WALLPAPER_SERVICE, "android.app.WallpaperManager");
    SYSTEM_SERVICE_MAP.put(Context.WIFI_P2P_SERVICE, "android.net.wifi.p2p.WifiP2pManager");
    if (getApiLevel() >= JELLY_BEAN_MR1) {
      SYSTEM_SERVICE_MAP.put(Context.DISPLAY_SERVICE, "android.hardware.display.DisplayManager");
      SYSTEM_SERVICE_MAP.put(Context.USER_SERVICE, "android.os.UserManager");
    }
    if (getApiLevel() >= JELLY_BEAN_MR2) {
      SYSTEM_SERVICE_MAP.put(Context.BLUETOOTH_SERVICE, "android.bluetooth.BluetoothManager");
    }
    if (getApiLevel() >= KITKAT) {
      SYSTEM_SERVICE_MAP.put(Context.PRINT_SERVICE, "android.print.PrintManager");
    }
    if (getApiLevel() >= LOLLIPOP) {
      SYSTEM_SERVICE_MAP.put(Context.JOB_SCHEDULER_SERVICE, "android.app.JobSchedulerImpl");
      SYSTEM_SERVICE_MAP.put(Context.TELECOM_SERVICE, "android.telecom.TelecomManager");
      SYSTEM_SERVICE_MAP.put(Context.MEDIA_SESSION_SERVICE, "android.media.session.MediaSessionManager");
      SYSTEM_SERVICE_MAP.put(Context.BATTERY_SERVICE, "android.os.BatteryManager");
    }
    if (getApiLevel() >= LOLLIPOP_MR1) {
      SYSTEM_SERVICE_MAP.put(Context.TELEPHONY_SUBSCRIPTION_SERVICE, "android.telephony.SubscriptionManager");
    }
    if (getApiLevel() >= N_MR1) {
      SYSTEM_SERVICE_MAP.put(Context.SHORTCUT_SERVICE, "android.content.pm.ShortcutManager");
    }
  }

  private Map systemServices = new HashMap();

  @Implementation
  public Object getSystemService(String name) {
    if (name.equals(Context.LAYOUT_INFLATER_SERVICE)) {
      return new RoboLayoutInflater(RuntimeEnvironment.application);
    }

    Object service = systemServices.get(name);
    if (service == null) {
      String serviceClassName = SYSTEM_SERVICE_MAP.get(name);
      if (serviceClassName == null) {
        System.err.println("WARNING: unknown service " + name);
        return null;
      }

      try {
        Class clazz = Class.forName(serviceClassName);

        if (serviceClassName.equals("android.app.admin.DevicePolicyManager")) {
          if (getApiLevel() >= N) {
            service = ReflectionHelpers.callConstructor(clazz,
                ClassParameter.from(Context.class, RuntimeEnvironment.application),
                ClassParameter.from(IDevicePolicyManager.class, null),
                ClassParameter.from(boolean.class, false));
          } else {
            service = ReflectionHelpers.callConstructor(clazz,
                ClassParameter.from(Context.class, RuntimeEnvironment.application),
                ClassParameter.from(Handler.class, null));
          }
        } else if (serviceClassName.equals("android.app.SearchManager")
            || serviceClassName.equals("android.app.ActivityManager")
            || serviceClassName.equals("android.app.WallpaperManager")) {

          service = ReflectionHelpers.callConstructor(clazz,
              ClassParameter.from(Context.class, RuntimeEnvironment.application),
              ClassParameter.from(Handler.class, null));
        } else if (serviceClassName.equals("android.os.storage.StorageManager")) {
          service = ReflectionHelpers.callConstructor(clazz);
        } else if (serviceClassName.equals("android.nfc.NfcManager") || serviceClassName.equals("android.telecom.TelecomManager")) {
          service = ReflectionHelpers.callConstructor(clazz,
              ClassParameter.from(Context.class, RuntimeEnvironment.application));
        } else if (serviceClassName.equals("android.hardware.display.DisplayManager") || serviceClassName.equals("android.telephony.SubscriptionManager")) {
          service = ReflectionHelpers.callConstructor(clazz, ClassParameter.from(Context.class, RuntimeEnvironment.application));
        } else if (serviceClassName.equals("android.view.accessibility.AccessibilityManager")) {
          service = AccessibilityManager.getInstance(realObject);
        } else if (getApiLevel() >= JELLY_BEAN_MR1 && serviceClassName.equals("android.view.WindowManagerImpl")) {
          Class windowMgrImplClass = Class.forName("android.view.WindowManagerImpl");
          if (getApiLevel() >= N) {
            service = ReflectionHelpers.callConstructor(windowMgrImplClass,
                ClassParameter.from(Context.class, realObject));
          } else {
            Display display = newInstanceOf(Display.class);
            service = ReflectionHelpers.callConstructor(windowMgrImplClass,
                ClassParameter.from(Display.class, display));
          }
        } else if (serviceClassName.equals("android.accounts.AccountManager")) {
          service = ReflectionHelpers.callConstructor(Class.forName("android.accounts.AccountManager"),
                ClassParameter.from(Context.class, RuntimeEnvironment.application),
                ClassParameter.from(IAccountManager.class , null));
        } else if (serviceClassName.equals("android.net.wifi.p2p.WifiP2pManager")) {
          service = new WifiP2pManager(ReflectionHelpers.createNullProxy(IWifiP2pManager.class));
        } else if (getApiLevel() >= KITKAT && serviceClassName.equals("android.print.PrintManager")) {
          service = ReflectionHelpers.callConstructor(Class.forName("android.print.PrintManager"),
            ClassParameter.from(Context.class, RuntimeEnvironment.application),
            ClassParameter.from(android.print.IPrintManager.class, null),
            ClassParameter.from(int.class, -1),
            ClassParameter.from(int.class, -1));
        } else if (serviceClassName.equals("android.hardware.SystemSensorManager")) {
          if (RuntimeEnvironment.getApiLevel() >= JELLY_BEAN_MR2) {
            service = new SystemSensorManager(RuntimeEnvironment.application, Looper.getMainLooper());
          } else {
            service = ReflectionHelpers.callConstructor(
                Class.forName(serviceClassName),
                ClassParameter.from(Looper.class, Looper.getMainLooper()));
          }
        } else {
          service = newInstanceOf(clazz);
        }
      } catch (ClassNotFoundException e) {
        throw new RuntimeException(e);
      }

      systemServices.put(name, service);
    }
    return service;
  }

  public void setSystemService(String key, Object service) {
    systemServices.put(key, service);
  }

  @Implementation
  public void startIntentSender(IntentSender intent, Intent fillInIntent,
                    int flagsMask, int flagsValues, int extraFlags, Bundle options) throws IntentSender.SendIntentException {
    intent.sendIntent(realObject, 0, fillInIntent, null, null, null);
  }

  @Implementation
  public ComponentName startService(Intent service) {
    return ShadowApplication.getInstance().startService(service);
  }

  @Implementation
  public void startActivity(Intent intent) {
    ShadowApplication.getInstance().startActivity(intent);
  }

  @Implementation
  public void sendBroadcast(Intent intent) {
    ShadowApplication.getInstance().sendBroadcast(intent);
  }

  @Implementation
  public ClassLoader getClassLoader() {
    return this.getClass().getClassLoader();
  }

  @Implementation
  public boolean bindService(Intent intent, final ServiceConnection serviceConnection, int i) {
    return ShadowApplication.getInstance().bindService(intent, serviceConnection, i);
  }

  @Implementation
  public void unbindService(final ServiceConnection serviceConnection) {
    ShadowApplication.getInstance().unbindService(serviceConnection);
  }

  @Implementation
  public int checkCallingPermission(String permission) {
    return checkPermission(permission, -1, -1);
  }

  @Implementation
  public int checkCallingOrSelfPermission(String permission) {
    return checkPermission(permission, -1, -1);
  }

  @Implementation
  public ContentResolver getContentResolver() {
    if (contentResolver == null) {
      contentResolver = new ContentResolver(realObject) {
        @Override
        protected IContentProvider acquireProvider(Context c, String name) {
          return null;
        }

        @Override
        public boolean releaseProvider(IContentProvider icp) {
          return false;
        }

        @Override
        protected IContentProvider acquireUnstableProvider(Context c, String name) {
          return null;
        }

        @Override
        public boolean releaseUnstableProvider(IContentProvider icp) {
          return false;
        }

        @Override
        public void unstableProviderDied(IContentProvider icp) {

        }
      };
    }
    return contentResolver;
  }

  @Implementation
  public void sendBroadcast(Intent intent, String receiverPermission) {
    ShadowApplication.getInstance().sendBroadcast(intent, receiverPermission);
  }

  @Implementation
  public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
    ShadowApplication.getInstance().sendOrderedBroadcast(intent, receiverPermission);
  }

  @Implementation
  public void sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver,
                                   Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    ShadowApplication.getInstance().sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, initialCode,
        initialData, initialExtras);
  }

  @Implementation
  public void sendStickyBroadcast(Intent intent) {
    ShadowApplication.getInstance().sendStickyBroadcast(intent);
  }

  @Implementation
  public int checkPermission(String permission, int pid, int uid) {
    return ShadowApplication.getInstance().checkPermission(permission, pid, uid);
  }

  @Implementation
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    return ShadowApplication.getInstance().registerReceiverWithContext(receiver, filter, null, null, realObject);
  }

  @Implementation
  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler) {
    return ShadowApplication.getInstance().registerReceiverWithContext(receiver, filter, broadcastPermission, scheduler, realObject);
  }

  @Implementation
  public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
      IntentFilter filter, String broadcastPermission, Handler scheduler) {
    return ShadowApplication.getInstance().registerReceiverWithContext(receiver, filter, broadcastPermission, scheduler, realObject);
  }

  @Implementation
  public void unregisterReceiver(BroadcastReceiver broadcastReceiver) {
    ShadowApplication.getInstance().unregisterReceiver(broadcastReceiver);
  }

  @Implementation
  public boolean stopService(Intent name) {
    return ShadowApplication.getInstance().stopService(name);
  }

  @Implementation
  public void startActivity(Intent intent, Bundle options) {
    ShadowApplication.getInstance().startActivity(intent, options);
  }

  @Implementation
  public void startActivities(Intent[] intents) {
    for (int i = intents.length - 1; i >= 0; i--) {
      startActivity(intents[i]);
    }
  }

  @Implementation
  public void startActivities(Intent[] intents, Bundle options) {
    for (int i = intents.length - 1; i >= 0; i--) {
      startActivity(intents[i], options);
    }
  }

  @Implementation
  public int getUserId() {
    return 0;
  }

  @Implementation
  public File getExternalCacheDir() {
    return Environment.getExternalStorageDirectory();
  }

  @Implementation(maxSdk = JELLY_BEAN_MR2)
  public File getExternalFilesDir(String type) {
    return Environment.getExternalStoragePublicDirectory(type);
  }

  @Implementation(minSdk = KITKAT)
  public File[] getExternalFilesDirs(String type) {
    return new File[] { Environment.getExternalStoragePublicDirectory(type) };
  }

  @Resetter
  public static void reset() {
    String prefsCacheFieldName = RuntimeEnvironment.getApiLevel() >= N ? "sSharedPrefsCache" : "sSharedPrefs";
    Object prefsDefaultValue = RuntimeEnvironment.getApiLevel() >= KITKAT ? null : new HashMap<>();
    Class contextImplClass = ReflectionHelpers.loadClass(ShadowContextImpl.class.getClassLoader(), "android.app.ContextImpl");
    ReflectionHelpers.setStaticField(contextImplClass, prefsCacheFieldName, prefsDefaultValue);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy