Home | History | Annotate | Download | only in shadows
      1 package org.robolectric.shadows;
      2 
      3 import static android.os.Build.VERSION_CODES.JELLY_BEAN;
      4 import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1;
      5 
      6 import android.content.Context;
      7 import android.content.res.Configuration;
      8 import android.graphics.Rect;
      9 import android.os.Build;
     10 import android.os.Looper;
     11 import android.util.MergedConfiguration;
     12 import android.view.Display;
     13 import android.view.IWindowSession;
     14 import android.view.ViewRootImpl;
     15 import android.view.WindowManager;
     16 import java.util.ArrayList;
     17 import org.robolectric.RuntimeEnvironment;
     18 import org.robolectric.annotation.Implementation;
     19 import org.robolectric.annotation.Implements;
     20 import org.robolectric.annotation.RealObject;
     21 import org.robolectric.annotation.Resetter;
     22 import org.robolectric.util.ReflectionHelpers;
     23 import org.robolectric.util.ReflectionHelpers.ClassParameter;
     24 
     25 @Implements(value = ViewRootImpl.class, isInAndroidSdk = false)
     26 public class ShadowViewRootImpl {
     27 
     28   @RealObject private ViewRootImpl realObject;
     29 
     30   @Implementation(maxSdk = JELLY_BEAN)
     31   public static IWindowSession getWindowSession(Looper mainLooper) {
     32     return null;
     33   }
     34 
     35   @Implementation
     36   public void playSoundEffect(int effectId) {
     37   }
     38 
     39   public void callDispatchResized() {
     40     Display display = getDisplay();
     41     Rect frame = new Rect();
     42     display.getRectSize(frame);
     43     Rect zeroSizedRect = new Rect(0, 0, 0, 0);
     44 
     45     int apiLevel = RuntimeEnvironment.getApiLevel();
     46     ViewRootImpl component = realObject;
     47     if (apiLevel <= Build.VERSION_CODES.JELLY_BEAN) {
     48       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     49           ClassParameter.from(int.class, frame.width()),
     50           ClassParameter.from(int.class, frame.height()),
     51           ClassParameter.from(Rect.class, zeroSizedRect),
     52           ClassParameter.from(Rect.class, zeroSizedRect),
     53           ClassParameter.from(boolean.class, true),
     54           ClassParameter.from(Configuration.class, null));
     55     } else if (apiLevel <= JELLY_BEAN_MR1) {
     56       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     57           ClassParameter.from(Rect.class, frame),
     58           ClassParameter.from(Rect.class, zeroSizedRect),
     59           ClassParameter.from(Rect.class, zeroSizedRect),
     60           ClassParameter.from(boolean.class, true),
     61           ClassParameter.from(Configuration.class, null));
     62     } else if (apiLevel <= Build.VERSION_CODES.KITKAT) {
     63       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     64           ClassParameter.from(Rect.class, frame),
     65           ClassParameter.from(Rect.class, zeroSizedRect),
     66           ClassParameter.from(Rect.class, zeroSizedRect),
     67           ClassParameter.from(Rect.class, zeroSizedRect),
     68           ClassParameter.from(boolean.class, true),
     69           ClassParameter.from(Configuration.class, null));
     70     } else if (apiLevel <= Build.VERSION_CODES.LOLLIPOP_MR1) {
     71       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     72           ClassParameter.from(Rect.class, frame),
     73           ClassParameter.from(Rect.class, zeroSizedRect),
     74           ClassParameter.from(Rect.class, zeroSizedRect),
     75           ClassParameter.from(Rect.class, zeroSizedRect),
     76           ClassParameter.from(Rect.class, zeroSizedRect),
     77           ClassParameter.from(boolean.class, true),
     78           ClassParameter.from(Configuration.class, null));
     79     } else if (apiLevel <= Build.VERSION_CODES.M) {
     80       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     81           ClassParameter.from(Rect.class, frame),
     82           ClassParameter.from(Rect.class, zeroSizedRect),
     83           ClassParameter.from(Rect.class, zeroSizedRect),
     84           ClassParameter.from(Rect.class, zeroSizedRect),
     85           ClassParameter.from(Rect.class, zeroSizedRect),
     86           ClassParameter.from(Rect.class, zeroSizedRect),
     87           ClassParameter.from(boolean.class, true),
     88           ClassParameter.from(Configuration.class, null));
     89     } else if (apiLevel <= Build.VERSION_CODES.N_MR1) {
     90       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
     91           ClassParameter.from(Rect.class, frame),
     92           ClassParameter.from(Rect.class, zeroSizedRect),
     93           ClassParameter.from(Rect.class, zeroSizedRect),
     94           ClassParameter.from(Rect.class, zeroSizedRect),
     95           ClassParameter.from(Rect.class, zeroSizedRect),
     96           ClassParameter.from(Rect.class, zeroSizedRect),
     97           ClassParameter.from(boolean.class, true),
     98           ClassParameter.from(Configuration.class, null),
     99           ClassParameter.from(Rect.class, frame),
    100           ClassParameter.from(boolean.class, false),
    101           ClassParameter.from(boolean.class, false));
    102     } else if (apiLevel <= Build.VERSION_CODES.O_MR1) {
    103       ReflectionHelpers.callInstanceMethod(
    104           ViewRootImpl.class,
    105           component,
    106           "dispatchResized",
    107           ClassParameter.from(Rect.class, frame),
    108           ClassParameter.from(Rect.class, zeroSizedRect),
    109           ClassParameter.from(Rect.class, zeroSizedRect),
    110           ClassParameter.from(Rect.class, zeroSizedRect),
    111           ClassParameter.from(Rect.class, zeroSizedRect),
    112           ClassParameter.from(Rect.class, zeroSizedRect),
    113           ClassParameter.from(boolean.class, true),
    114           ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
    115           ClassParameter.from(Rect.class, frame),
    116           ClassParameter.from(boolean.class, false),
    117           ClassParameter.from(boolean.class, false),
    118           ClassParameter.from(int.class, 0));
    119 
    120     } else if (apiLevel >= Build.VERSION_CODES.P) {
    121       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
    122           ClassParameter.from(Rect.class, frame),
    123           ClassParameter.from(Rect.class, zeroSizedRect),
    124           ClassParameter.from(Rect.class, zeroSizedRect),
    125           ClassParameter.from(Rect.class, zeroSizedRect),
    126           ClassParameter.from(Rect.class, zeroSizedRect),
    127           ClassParameter.from(Rect.class, zeroSizedRect),
    128           ClassParameter.from(boolean.class, true),
    129           ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
    130           ClassParameter.from(Rect.class, frame),
    131           ClassParameter.from(boolean.class, false),
    132           ClassParameter.from(boolean.class, false),
    133           ClassParameter.from(int.class, 0),
    134           ClassParameter.from(android.view.DisplayCutout.ParcelableWrapper.class,
    135               new android.view.DisplayCutout.ParcelableWrapper()));
    136 
    137     } else {
    138       throw new RuntimeException("Could not find AndroidRuntimeAdapter for API level: " + apiLevel);
    139     }
    140   }
    141 
    142   private Display getDisplay() {
    143     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN_MR1) {
    144       return realObject.getView().getDisplay();
    145     } else {
    146       WindowManager windowManager = (WindowManager) realObject.getView().getContext()
    147           .getSystemService(Context.WINDOW_SERVICE);
    148       return windowManager.getDefaultDisplay();
    149     }
    150   }
    151 
    152   @Resetter
    153   public static void reset() {
    154      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sRunQueues", new ThreadLocal<>());
    155      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sFirstDrawHandlers", new ArrayList<>());
    156      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sFirstDrawComplete", false);
    157      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sConfigCallbacks", new ArrayList<>());
    158   }
    159 }
    160