• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 android.window.ClientWindowFrames;
17 import java.util.ArrayList;
18 import org.robolectric.RuntimeEnvironment;
19 import org.robolectric.annotation.Implementation;
20 import org.robolectric.annotation.Implements;
21 import org.robolectric.annotation.RealObject;
22 import org.robolectric.annotation.Resetter;
23 import org.robolectric.util.ReflectionHelpers;
24 import org.robolectric.util.ReflectionHelpers.ClassParameter;
25 
26 @Implements(value = ViewRootImpl.class, isInAndroidSdk = false)
27 public class ShadowViewRootImpl {
28 
29   @RealObject private ViewRootImpl realObject;
30 
31   @Implementation(maxSdk = JELLY_BEAN)
getWindowSession(Looper mainLooper)32   public static IWindowSession getWindowSession(Looper mainLooper) {
33     return null;
34   }
35 
36   @Implementation
playSoundEffect(int effectId)37   public void playSoundEffect(int effectId) {
38   }
39 
callDispatchResized()40   public void callDispatchResized() {
41     Display display = getDisplay();
42     Rect frame = new Rect();
43     display.getRectSize(frame);
44     Rect zeroSizedRect = new Rect(0, 0, 0, 0);
45     ClientWindowFrames clientWindowFrame = new ClientWindowFrames();
46 
47     int apiLevel = RuntimeEnvironment.getApiLevel();
48     ViewRootImpl component = realObject;
49     if (apiLevel <= Build.VERSION_CODES.JELLY_BEAN) {
50       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
51           ClassParameter.from(int.class, frame.width()),
52           ClassParameter.from(int.class, frame.height()),
53           ClassParameter.from(Rect.class, zeroSizedRect),
54           ClassParameter.from(Rect.class, zeroSizedRect),
55           ClassParameter.from(boolean.class, true),
56           ClassParameter.from(Configuration.class, null));
57     } else if (apiLevel <= JELLY_BEAN_MR1) {
58       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
59           ClassParameter.from(Rect.class, frame),
60           ClassParameter.from(Rect.class, zeroSizedRect),
61           ClassParameter.from(Rect.class, zeroSizedRect),
62           ClassParameter.from(boolean.class, true),
63           ClassParameter.from(Configuration.class, null));
64     } else if (apiLevel <= Build.VERSION_CODES.KITKAT) {
65       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
66           ClassParameter.from(Rect.class, frame),
67           ClassParameter.from(Rect.class, zeroSizedRect),
68           ClassParameter.from(Rect.class, zeroSizedRect),
69           ClassParameter.from(Rect.class, zeroSizedRect),
70           ClassParameter.from(boolean.class, true),
71           ClassParameter.from(Configuration.class, null));
72     } else if (apiLevel <= Build.VERSION_CODES.LOLLIPOP_MR1) {
73       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
74           ClassParameter.from(Rect.class, frame),
75           ClassParameter.from(Rect.class, zeroSizedRect),
76           ClassParameter.from(Rect.class, zeroSizedRect),
77           ClassParameter.from(Rect.class, zeroSizedRect),
78           ClassParameter.from(Rect.class, zeroSizedRect),
79           ClassParameter.from(boolean.class, true),
80           ClassParameter.from(Configuration.class, null));
81     } else if (apiLevel <= Build.VERSION_CODES.M) {
82       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
83           ClassParameter.from(Rect.class, frame),
84           ClassParameter.from(Rect.class, zeroSizedRect),
85           ClassParameter.from(Rect.class, zeroSizedRect),
86           ClassParameter.from(Rect.class, zeroSizedRect),
87           ClassParameter.from(Rect.class, zeroSizedRect),
88           ClassParameter.from(Rect.class, zeroSizedRect),
89           ClassParameter.from(boolean.class, true),
90           ClassParameter.from(Configuration.class, null));
91     } else if (apiLevel <= Build.VERSION_CODES.N_MR1) {
92       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
93           ClassParameter.from(Rect.class, frame),
94           ClassParameter.from(Rect.class, zeroSizedRect),
95           ClassParameter.from(Rect.class, zeroSizedRect),
96           ClassParameter.from(Rect.class, zeroSizedRect),
97           ClassParameter.from(Rect.class, zeroSizedRect),
98           ClassParameter.from(Rect.class, zeroSizedRect),
99           ClassParameter.from(boolean.class, true),
100           ClassParameter.from(Configuration.class, null),
101           ClassParameter.from(Rect.class, frame),
102           ClassParameter.from(boolean.class, false),
103           ClassParameter.from(boolean.class, false));
104     } else if (apiLevel <= Build.VERSION_CODES.O_MR1) {
105       ReflectionHelpers.callInstanceMethod(
106           ViewRootImpl.class,
107           component,
108           "dispatchResized",
109           ClassParameter.from(Rect.class, frame),
110           ClassParameter.from(Rect.class, zeroSizedRect),
111           ClassParameter.from(Rect.class, zeroSizedRect),
112           ClassParameter.from(Rect.class, zeroSizedRect),
113           ClassParameter.from(Rect.class, zeroSizedRect),
114           ClassParameter.from(Rect.class, zeroSizedRect),
115           ClassParameter.from(boolean.class, true),
116           ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
117           ClassParameter.from(Rect.class, frame),
118           ClassParameter.from(boolean.class, false),
119           ClassParameter.from(boolean.class, false),
120           ClassParameter.from(int.class, 0));
121     } else if (apiLevel <= Build.VERSION_CODES.Q) {
122       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
123           ClassParameter.from(Rect.class, frame),
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(Rect.class, zeroSizedRect),
129           ClassParameter.from(boolean.class, true),
130           ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
131           ClassParameter.from(Rect.class, frame),
132           ClassParameter.from(boolean.class, false),
133           ClassParameter.from(boolean.class, false),
134           ClassParameter.from(int.class, 0),
135           ClassParameter.from(android.view.DisplayCutout.ParcelableWrapper.class,
136               new android.view.DisplayCutout.ParcelableWrapper()));
137     } else if (apiLevel <= Build.VERSION_CODES.R) {
138       // BEGIN-INTERNAL
139       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
140               ClassParameter.from(Rect.class, frame),
141               ClassParameter.from(Rect.class, zeroSizedRect),
142               ClassParameter.from(Rect.class, zeroSizedRect),
143               ClassParameter.from(Rect.class, zeroSizedRect),
144               ClassParameter.from(boolean.class, true),
145               ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
146               ClassParameter.from(Rect.class, frame),
147               ClassParameter.from(boolean.class, false),
148               ClassParameter.from(boolean.class, false),
149               ClassParameter.from(int.class, 0),
150               ClassParameter.from(android.view.DisplayCutout.ParcelableWrapper.class,
151                       new android.view.DisplayCutout.ParcelableWrapper()));
152       // END-INTERNAL
153     } else if (apiLevel >= Build.VERSION_CODES.S) {
154       // BEGIN-INTERNAL
155       ReflectionHelpers.callInstanceMethod(ViewRootImpl.class, component, "dispatchResized",
156               ClassParameter.from(ClientWindowFrames.class, clientWindowFrame),
157               ClassParameter.from(boolean.class, true),
158               ClassParameter.from(MergedConfiguration.class, new MergedConfiguration()),
159               ClassParameter.from(boolean.class, false),
160               ClassParameter.from(boolean.class, false),
161               ClassParameter.from(int.class, 0));
162       // END-INTERNAL
163     } else {
164       throw new RuntimeException("Could not find AndroidRuntimeAdapter for API level: " + apiLevel);
165     }
166   }
167 
getDisplay()168   private Display getDisplay() {
169     if (RuntimeEnvironment.getApiLevel() > JELLY_BEAN_MR1) {
170       return realObject.getView().getDisplay();
171     } else {
172       WindowManager windowManager = (WindowManager) realObject.getView().getContext()
173           .getSystemService(Context.WINDOW_SERVICE);
174       return windowManager.getDefaultDisplay();
175     }
176   }
177 
178   @Resetter
reset()179   public static void reset() {
180      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sRunQueues", new ThreadLocal<>());
181      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sFirstDrawHandlers", new ArrayList<>());
182      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sFirstDrawComplete", false);
183      ReflectionHelpers.setStaticField(ViewRootImpl.class, "sConfigCallbacks", new ArrayList<>());
184   }
185 }
186