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