diff --git a/annotations/src/main/java/org/robolectric/annotation/ClassName.java b/annotations/src/main/java/org/robolectric/annotation/ClassName.java new file mode 100644 index 00000000000..7f6b2c5611f --- /dev/null +++ b/annotations/src/main/java/org/robolectric/annotation/ClassName.java @@ -0,0 +1,28 @@ +package org.robolectric.annotation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Indicate a real class name of method's input parameter. + * + *

For some important Android framework's shadow class, we might bring new APIs to current shadow + * class, but these APIs might be added from newer SDK version, and it will cause compiling error + * when using these shadow classes with lower compileSdk. We can use this annotation and Object type + * to avoid compiling error but with implicit type checking. + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface ClassName { + /** + * The class name intended for this parameter. + * + *

Use the value as returned from {@link Class#getName()}, not {@link + * Class#getCanonicalName()}; e.g. {@code Foo$Bar} instead of {@code Foo.Bar}. + */ + String value() default ""; +} diff --git a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java index 51953fdc9b1..cc8a268b538 100644 --- a/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java +++ b/sandbox/src/main/java/org/robolectric/internal/bytecode/ShadowWrangler.java @@ -8,6 +8,7 @@ import static org.robolectric.util.reflector.Reflector.reflector; import com.google.auto.service.AutoService; +import java.lang.annotation.Annotation; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -21,6 +22,7 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.Priority; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.RealObject; import org.robolectric.annotation.ReflectorObject; import org.robolectric.sandbox.ShadowMatcher; @@ -291,9 +293,16 @@ private Method findShadowMethod( Class shadowClass) { Method method = findShadowMethodDeclaredOnClass(shadowClass, name, types); - if (method == null && shadowInfo.looseSignatures) { - Class[] genericTypes = MethodType.genericMethodType(types.length).parameterArray(); - method = findShadowMethodDeclaredOnClass(shadowClass, name, genericTypes); + if (method == null) { + // If user sets looseSignatures for shadow class, we will try to find method with generic + // types again. + if (shadowInfo.looseSignatures) { + Class[] genericTypes = MethodType.genericMethodType(types.length).parameterArray(); + method = findShadowMethodDeclaredOnClass(shadowClass, name, genericTypes); + } else { + // Otherwise, we will try to find method with ClassName annotation that can match signature. + method = findShadowMethodWithClassNameDeclaredOnClass(shadowClass, name, types); + } } if (method != null) { @@ -317,6 +326,76 @@ private Method findShadowMethod( return method; } + private ClassName finClassNameAnnotation(Annotation[] annotations) { + for (Annotation annotation : annotations) { + if (ClassName.class.isAssignableFrom(annotation.annotationType())) { + return (ClassName) annotation; + } + } + return null; + } + + private boolean hasClassNameAnnotation(Annotation[][] annotations) { + for (Annotation[] parameterAnnotations : annotations) { + for (Annotation annotation : parameterAnnotations) { + if (ClassName.class.isAssignableFrom(annotation.annotationType())) { + return true; + } + } + } + return false; + } + + private Method findShadowMethodWithClassNameDeclaredOnClass( + Class shadowClass, String methodName, Class[] paramClasses) { + // We don't process the method without input parameters now. + if (paramClasses == null || paramClasses.length == 0) { + return null; + } + Method[] methods = shadowClass.getDeclaredMethods(); + for (Method method : methods) { + if (method == null + || !method.getName().equals(methodName) + || method.getParameterCount() != paramClasses.length + || !isValidShadowMethod(method)) { + continue; + } + Class[] parameterTypes = method.getParameterTypes(); + Annotation[][] allAnnotations = method.getParameterAnnotations(); + if (!hasClassNameAnnotation(allAnnotations)) { + continue; + } + boolean matched = true; + for (int i = 0; i < parameterTypes.length; i++) { + // If method's parameter type is superclass of input parameter, we can pass checking for + // this parameter. + if (parameterTypes[i].isAssignableFrom(paramClasses[i])) { + continue; + } + if (allAnnotations.length <= i) { + matched = false; + break; + } + ClassName className = finClassNameAnnotation(allAnnotations[i]); + try { + if (className != null + && Class.forName(className.value()).isAssignableFrom(paramClasses[i])) { + continue; + } + } catch (ClassNotFoundException ignored) { + // Do nothing + } + matched = false; + break; + } + // TODO identify why above logic will affect __constructor__ without ClassName + if (matched) { + return method; + } + } + return null; + } + private Method findShadowMethodDeclaredOnClass( Class shadowClass, String methodName, Class[] paramClasses) { try { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java index 47f7306a4ae..be8c9ca1008 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivity.java @@ -76,7 +76,7 @@ import org.robolectric.util.reflector.WithType; @SuppressWarnings("NewApi") -@Implements(value = Activity.class, looseSignatures = true) +@Implements(value = Activity.class) public class ShadowActivity extends ShadowContextThemeWrapper { @RealObject protected Activity realActivity; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java index 9d4f6ab1188..d496874779c 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowActivityThread.java @@ -38,7 +38,7 @@ import org.robolectric.util.reflector.ForType; import org.robolectric.util.reflector.Reflector; -@Implements(value = ActivityThread.class, isInAndroidSdk = false, looseSignatures = true) +@Implements(value = ActivityThread.class, isInAndroidSdk = false) public class ShadowActivityThread { private static ApplicationInfo applicationInfo; @RealObject protected ActivityThread realActivityThread; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppIntegrityManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppIntegrityManager.java index 1065554d327..4d7eaa507a2 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppIntegrityManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppIntegrityManager.java @@ -13,7 +13,6 @@ @Implements( value = AppIntegrityManager.class, minSdk = R, - looseSignatures = true, isInAndroidSdk = false) public class ShadowAppIntegrityManager { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java index f420031c94c..be4876cd182 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAppOpsManager.java @@ -51,6 +51,7 @@ import java.util.Set; import java.util.stream.IntStream; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -61,7 +62,7 @@ import org.robolectric.util.ReflectionHelpers.ClassParameter; /** Shadow for {@link AppOpsManager}. */ -@Implements(value = AppOpsManager.class, minSdk = KITKAT, looseSignatures = true) +@Implements(value = AppOpsManager.class, minSdk = KITKAT) public class ShadowAppOpsManager { // OpEntry fields that the shadow doesn't currently allow the test to configure. @@ -404,18 +405,18 @@ protected int noteProxyOpNoThrow( @RequiresApi(api = S) @Implementation(minSdk = S) protected int noteProxyOpNoThrow( - Object op, Object attributionSource, Object message, Object ignoredSkipProxyOperation) { - Preconditions.checkArgument(op instanceof Integer); + int op, + @ClassName(value = "android.content.AttributionSource ") Object attributionSource, + String message, + boolean ignoredSkipProxyOperation) { Preconditions.checkArgument(attributionSource instanceof AttributionSource); - Preconditions.checkArgument(message == null || message instanceof String); - Preconditions.checkArgument(ignoredSkipProxyOperation instanceof Boolean); AttributionSource castedAttributionSource = (AttributionSource) attributionSource; return noteProxyOpNoThrow( - (int) op, + op, castedAttributionSource.getNextPackageName(), castedAttributionSource.getNextUid(), castedAttributionSource.getNextAttributionTag(), - (String) message); + message); } @Implementation diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java index eb2276c9e02..644bef18f88 100755 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowArscApkAssets9.java @@ -19,6 +19,7 @@ import java.util.HashMap; import java.util.Objects; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.RealObject; @@ -42,8 +43,7 @@ value = ApkAssets.class, minSdk = P, shadowPicker = Picker.class, - isInAndroidSdk = false, - looseSignatures = true) + isInAndroidSdk = false) public class ShadowArscApkAssets9 extends ShadowApkAssets { // #define ATRACE_TAG ATRACE_TAG_RESOURCES // @@ -286,11 +286,15 @@ protected static long nativeLoad( @Implementation(minSdk = R) protected static Object nativeLoad( - Object format, Object javaPath, Object flags, Object assetsProvider) throws IOException { - boolean system = ((int) flags & PROPERTY_SYSTEM) == PROPERTY_SYSTEM; - boolean overlay = ((int) flags & PROPERTY_OVERLAY) == PROPERTY_OVERLAY; - boolean forceSharedLib = ((int) flags & PROPERTY_DYNAMIC) == PROPERTY_DYNAMIC; - return nativeLoad((String) javaPath, system, forceSharedLib, overlay); + int format, + String javaPath, + int flags, + @ClassName(value = "android.content.res.loader.AssetsProvider") Object assetsProvider) + throws IOException { + boolean system = (flags & PROPERTY_SYSTEM) == PROPERTY_SYSTEM; + boolean overlay = (flags & PROPERTY_OVERLAY) == PROPERTY_OVERLAY; + boolean forceSharedLib = (flags & PROPERTY_DYNAMIC) == PROPERTY_DYNAMIC; + return nativeLoad(javaPath, system, forceSharedLib, overlay); } // static jlong NativeLoadFromFd(JNIEnv* env, jclass /*clazz*/, jobject file_descriptor, diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java index 183e9f38d2a..acc80aeccaf 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioManager.java @@ -34,13 +34,14 @@ import java.util.List; import java.util.Map; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.util.ReflectionHelpers; @SuppressWarnings({"UnusedDeclaration"}) -@Implements(value = AudioManager.class, looseSignatures = true) +@Implements(value = AudioManager.class) public class ShadowAudioManager { public static final int MAX_VOLUME_MUSIC_DTMF = 15; @@ -637,7 +638,8 @@ public AudioRecordingConfiguration createActiveRecordingConfiguration( @HiddenApi @Implementation(minSdk = P) @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) - protected int registerAudioPolicy(@NonNull Object audioPolicy) { + protected int registerAudioPolicy( + @NonNull @ClassName(value = "android.media.audiopolicy.AudioPolicy") Object audioPolicy) { Preconditions.checkNotNull(audioPolicy, "Illegal null AudioPolicy argument"); AudioPolicy policy = (AudioPolicy) audioPolicy; String id = getIdForAudioPolicy(audioPolicy); @@ -651,7 +653,8 @@ protected int registerAudioPolicy(@NonNull Object audioPolicy) { @HiddenApi @Implementation(minSdk = Q) - protected void unregisterAudioPolicy(@NonNull Object audioPolicy) { + protected void unregisterAudioPolicy( + @NonNull @ClassName(value = "android.media.audiopolicy.AudioPolicy") Object audioPolicy) { Preconditions.checkNotNull(audioPolicy, "Illegal null AudioPolicy argument"); AudioPolicy policy = (AudioPolicy) audioPolicy; registeredAudioPolicies.remove(getIdForAudioPolicy(policy)); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioTrack.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioTrack.java index 45a5557a6f4..d981569f962 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioTrack.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowAudioTrack.java @@ -26,7 +26,7 @@ * other methods are expected run through the real class. The two {@link WriteMode} are treated the * same. */ -@Implements(value = AudioTrack.class, looseSignatures = true) +@Implements(value = AudioTrack.class) public class ShadowAudioTrack { /** diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java index 863458509af..77f51316e92 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowBluetoothAdapter.java @@ -42,6 +42,7 @@ import java.util.concurrent.ConcurrentMap; import javax.annotation.Nullable; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.RealObject; @@ -54,7 +55,7 @@ import org.robolectric.util.reflector.Static; @SuppressWarnings({"UnusedDeclaration"}) -@Implements(value = BluetoothAdapter.class, looseSignatures = true) +@Implements(value = BluetoothAdapter.class) public class ShadowBluetoothAdapter { @RealObject private BluetoothAdapter realAdapter; @@ -121,9 +122,9 @@ protected static BluetoothAdapter getDefaultAdapter() { return reflector(BluetoothAdapterReflector.class).getDefaultAdapter(); } - /** Requires LooseSignatures because of {@link AttributionSource} parameter */ @Implementation(minSdk = VERSION_CODES.TIRAMISU) - protected static Object createAdapter(Object attributionSource) { + protected static Object createAdapter( + @ClassName(value = "android.content.AttributionSource") Object attributionSource) { IBluetoothManager service = ReflectionHelpers.createNullProxy(IBluetoothManager.class); return ReflectionHelpers.callConstructor( BluetoothAdapter.class, @@ -319,10 +320,6 @@ protected boolean setName(String name) { return true; } - /** - * Needs looseSignatures because in Android T the return value of this method was changed from - * bool to int. - */ @Implementation protected Object setScanMode(int scanMode) { boolean result = true; @@ -358,10 +355,7 @@ protected int getScanMode() { return scanMode; } - /** - * Needs looseSignatures because the return value changed from {@code int} to {@link Duration} - * starting in T. - */ + /** In Android T the return value of this method was changed from bool to int. */ @Implementation protected Object getDiscoverableTimeout() { if (RuntimeEnvironment.getApiLevel() <= S_V2) { @@ -371,6 +365,7 @@ protected Object getDiscoverableTimeout() { } } + /** T return value changed from {@code int} to {@link Duration} starting in T. */ @Implementation(maxSdk = S_V2) protected void setDiscoverableTimeout(int timeout) { discoverableTimeout = Duration.ofSeconds(timeout); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextHubClient.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextHubClient.java index 4a99909dea3..9e871a4c252 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextHubClient.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowContextHubClient.java @@ -12,11 +12,7 @@ import org.robolectric.annotation.Implements; /** Shadow for {@link ContextHubClient}. */ -@Implements( - value = ContextHubClient.class, - minSdk = VERSION_CODES.P, - isInAndroidSdk = false, - looseSignatures = true) +@Implements(value = ContextHubClient.class, minSdk = VERSION_CODES.P, isInAndroidSdk = false) public class ShadowContextHubClient { private final List messages = new ArrayList<>(); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManager.java index 9959ca1600a..f66b0d52d42 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowDisplayManager.java @@ -23,6 +23,7 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.android.Bootstrap; import org.robolectric.android.internal.DisplayConfig; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -37,7 +38,7 @@ * For tests, display properties may be changed and devices may be added or removed * programmatically. */ -@Implements(value = DisplayManager.class, minSdk = JELLY_BEAN_MR1, looseSignatures = true) +@Implements(value = DisplayManager.class, minSdk = JELLY_BEAN_MR1) public class ShadowDisplayManager { @RealObject private DisplayManager realDisplayManager; @@ -249,14 +250,17 @@ public void setSaturationLevel(float level) { @Implementation(minSdk = P) @HiddenApi - protected void setBrightnessConfiguration(Object config) { + protected void setBrightnessConfiguration( + @ClassName(value = "android.hardware.display.BrightnessConfiguration") Object config) { setBrightnessConfigurationForUser(config, 0, context.getPackageName()); } @Implementation(minSdk = P) @HiddenApi protected void setBrightnessConfigurationForUser( - Object config, Object userId, Object packageName) { + @ClassName(value = "android.hardware.display.BrightnessConfiguration") Object config, + int userId, + String packageName) { getShadowDisplayManagerGlobal().setBrightnessConfigurationForUser(config, userId, packageName); } diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java index 7b86dc2f487..f37e38f8761 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowHardwareRenderer.java @@ -40,6 +40,7 @@ protected static long nCreateProxy( // need to use loose signatures here to account for signature changes @Implementation(minSdk = S) protected static long nCreateProxy(Object translucent, Object rootRenderNode) { + // TODO Find an approach to support the same method with disconnected range return nCreateProxy((boolean) translucent, (long) rootRenderNode); } diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImsMmTelManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImsMmTelManager.java index 59dd70783fc..1ee04482bf6 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImsMmTelManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowImsMmTelManager.java @@ -36,7 +36,6 @@ @Implements( value = ImsMmTelManager.class, minSdk = VERSION_CODES.Q, - looseSignatures = true, isInAndroidSdk = false) @SystemApi public class ShadowImsMmTelManager { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java index e76b7973cc2..af0d0fa60b0 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowInstrumentation.java @@ -74,7 +74,7 @@ import org.robolectric.util.reflector.ForType; import org.robolectric.util.reflector.WithType; -@Implements(value = Instrumentation.class, looseSignatures = true) +@Implements(value = Instrumentation.class) public class ShadowInstrumentation { @RealObject private Instrumentation realObject; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeAllocationRegistry.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeAllocationRegistry.java index dfe78a2e4ef..edb4d8038f8 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeAllocationRegistry.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowNativeAllocationRegistry.java @@ -6,14 +6,8 @@ import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -@Implements(value = NativeAllocationRegistry.class, minSdk = N, isInAndroidSdk = false, looseSignatures = true) +@Implements(value = NativeAllocationRegistry.class, minSdk = N, isInAndroidSdk = false) public class ShadowNativeAllocationRegistry { - - @Implementation - protected Runnable registerNativeAllocation(Object referent, Object allocator) { - return () -> {}; - } - @Implementation protected Runnable registerNativeAllocation(Object referent, long nativePtr) { return () -> {}; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java index 8fec6464ac7..84403b2f058 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPaint.java @@ -22,6 +22,7 @@ import android.graphics.PathEffect; import android.graphics.Shader; import android.graphics.Typeface; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.RealObject; @@ -31,7 +32,7 @@ import org.robolectric.util.ReflectionHelpers.ClassParameter; @SuppressWarnings({"UnusedDeclaration"}) -@Implements(value = Paint.class, looseSignatures = true) +@Implements(value = Paint.class) public class ShadowPaint { private int color; @@ -505,8 +506,11 @@ protected static int nGetFontMetricsInt( } @Implementation(minSdk = N, maxSdk = N_MR1) - protected int nGetFontMetricsInt(Object nativePaint, Object nativeTypeface, Object fmi) { - return nGetFontMetricsInt((long) nativePaint, (FontMetricsInt) fmi); + protected int nGetFontMetricsInt( + long nativePaint, + long nativeTypeface, + @ClassName(value = "android.graphics.Paint#FontMetricsInt") Object fmi) { + return nGetFontMetricsInt(nativePaint, (FontMetricsInt) fmi); } @Implementation(maxSdk = M) diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindow.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindow.java index 232132945d1..8891e8d2fff 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindow.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindow.java @@ -11,11 +11,11 @@ import org.robolectric.annotation.RealObject; import org.robolectric.util.reflector.ForType; -/** - * Shadow for PhoneWindow for APIs 23+ - */ -@Implements(className = "com.android.internal.policy.PhoneWindow", isInAndroidSdk = false, - minSdk = M, looseSignatures = true) +/** Shadow for PhoneWindow for APIs 23+ */ +@Implements( + className = "com.android.internal.policy.PhoneWindow", + isInAndroidSdk = false, + minSdk = M) public class ShadowPhoneWindow extends ShadowWindow { @SuppressWarnings("UnusedDeclaration") protected @RealObject Window realWindow; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindowFor22.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindowFor22.java index f39f66e693b..6fae3dd26c5 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindowFor22.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPhoneWindowFor22.java @@ -8,11 +8,11 @@ import org.robolectric.annotation.Implements; import org.robolectric.util.reflector.ForType; -/** - * Shadow for the API 16-22 PhoneWindow.li - */ -@Implements(className = "com.android.internal.policy.impl.PhoneWindow", maxSdk = LOLLIPOP_MR1, - looseSignatures = true, isInAndroidSdk = false) +/** Shadow for the API 16-22 PhoneWindow.li */ +@Implements( + className = "com.android.internal.policy.impl.PhoneWindow", + maxSdk = LOLLIPOP_MR1, + isInAndroidSdk = false) public class ShadowPhoneWindowFor22 extends ShadowPhoneWindow { @Override @Implementation(maxSdk = LOLLIPOP_MR1) diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java index db47fc850ad..a509370e0fe 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowPowerManager.java @@ -42,6 +42,7 @@ import java.util.Optional; import java.util.Set; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -52,7 +53,7 @@ import org.robolectric.util.reflector.ForType; /** Shadow of PowerManager */ -@Implements(value = PowerManager.class, looseSignatures = true) +@Implements(value = PowerManager.class) public class ShadowPowerManager { @RealObject private PowerManager realPowerManager; @@ -213,7 +214,9 @@ protected int getCurrentThermalStatus() { /** This function adds a listener for thermal status change. */ @Implementation(minSdk = Q) - protected void addThermalStatusListener(Object listener) { + protected void addThermalStatusListener( + @ClassName(value = "android.os.PowerManager#OnThermalStatusChangedListener") + Object listener) { checkState( listener instanceof PowerManager.OnThermalStatusChangedListener, "Listener must implement PowerManager.OnThermalStatusChangedListener"); @@ -227,7 +230,9 @@ public ImmutableSet getThermalStatusListeners() { /** This function removes a listener for thermal status change. */ @Implementation(minSdk = Q) - protected void removeThermalStatusListener(Object listener) { + protected void removeThermalStatusListener( + @ClassName(value = "android.os.PowerManager#OnThermalStatusChangedListener") + Object listener) { checkState( listener instanceof PowerManager.OnThermalStatusChangedListener, "Listener must implement PowerManager.OnThermalStatusChangedListener"); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRotationWatcherFor22.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRotationWatcherFor22.java index b27c7d61f4d..25c526aab4a 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRotationWatcherFor22.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowRotationWatcherFor22.java @@ -2,18 +2,20 @@ import static android.os.Build.VERSION_CODES.LOLLIPOP_MR1; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -/** - * Shadow for RotationWatcher for API 16-22 - */ -@Implements(className = "com.android.internal.policy.impl.PhoneWindow$RotationWatcher", - isInAndroidSdk = false, maxSdk = LOLLIPOP_MR1, looseSignatures = true) +/** Shadow for RotationWatcher for API 16-22 */ +@Implements( + className = "com.android.internal.policy.impl.PhoneWindow$RotationWatcher", + isInAndroidSdk = false, + maxSdk = LOLLIPOP_MR1) public class ShadowRotationWatcherFor22 { @Implementation - protected void addWindow(Object phoneWindow) { + protected void addWindow( + @ClassName(value = "com.android.internal.policy.impl.PhoneWindow") Object phoneWindow) { // ignore } } diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java index 5aa44afd29b..84033c768be 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSensorManager.java @@ -26,7 +26,7 @@ import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers.ClassParameter; -@Implements(value = SensorManager.class, looseSignatures = true) +@Implements(value = SensorManager.class) public class ShadowSensorManager { public boolean forceListenersToFail = false; private final Map sensorMap = new HashMap<>(); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStaticLayout.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStaticLayout.java index 5a08de4eb16..f98ce7ef47f 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStaticLayout.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowStaticLayout.java @@ -10,6 +10,7 @@ import android.text.DynamicLayout; import android.text.StaticLayout; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -19,7 +20,7 @@ import org.robolectric.util.reflector.ForType; /** Shadow for android.text.StaticLayout */ -@Implements(value = StaticLayout.class, looseSignatures = true) +@Implements(value = StaticLayout.class) public class ShadowStaticLayout { @ForType(className = "android.text.StaticLayout$LineBreaks") @@ -46,37 +47,37 @@ public static int[] nLineBreakOpportunities( @HiddenApi @Implementation(minSdk = M, maxSdk = O_MR1) public static int nComputeLineBreaks( - Object nativePtr, - Object recycle, - Object recycleBreaks, - Object recycleWidths, - Object recycleFlags, - Object recycleLength) { + long nativePtr, + @ClassName(value = "android.text.StaticLayout$LineBreaks") Object recycle, + int[] recycleBreaks, + float[] recycleWidths, + int[] recycleFlags, + int recycleLength) { return 1; } @HiddenApi @Implementation(minSdk = P, maxSdk = P) protected static int nComputeLineBreaks( - Object nativePtr, - Object text, - Object measuredTextPtr, - Object length, - Object firstWidth, - Object firstWidthLineCount, - Object restWidth, - Object variableTabStops, - Object defaultTabStop, - Object indentsOffset, - Object recycle, - Object recycleLength, - Object recycleBreaks, - Object recycleWidths, - Object recycleAscents, - Object recycleDescents, - Object recycleFlags, - Object charWidths) { - reflector(LineBreaksReflector.class, recycle).setBreaks(new int[] {((char[]) text).length}); + long nativePtr, + char[] text, + long measuredTextPtr, + int length, + float firstWidth, + int firstWidthLineCount, + float restWidth, + int[] variableTabStops, + int defaultTabStop, + int indentsOffset, + @ClassName(value = "android.text.StaticLayout$LineBreaks") Object recycle, + int recycleLength, + int[] recycleBreaks, + float[] recycleWidths, + float[] recycleAscents, + float[] recycleDescents, + int[] recycleFlags, + float[] charWidths) { + reflector(LineBreaksReflector.class, recycle).setBreaks(new int[] {text.length}); return 1; } } diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java index 03d756c4ead..f811601a6e7 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemClock.java @@ -17,12 +17,11 @@ /** * The shadow API for {@link SystemClock}. * - * The behavior of SystemClock in Robolectric will differ based on the current {@link + *

The behavior of SystemClock in Robolectric will differ based on the current {@link * LooperMode}. See {@link ShadowLegacySystemClock} and {@link ShadowPausedSystemClock} for more * details. */ -@Implements(value = SystemClock.class, shadowPicker = ShadowSystemClock.Picker.class, - looseSignatures = true) +@Implements(value = SystemClock.class, shadowPicker = ShadowSystemClock.Picker.class) public abstract class ShadowSystemClock { protected static boolean networkTimeAvailable = true; private static boolean gnssTimeAvailable = true; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemServiceRegistry.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemServiceRegistry.java index f8e7bc6ea0c..8050039515c 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemServiceRegistry.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowSystemServiceRegistry.java @@ -6,6 +6,7 @@ import android.content.Context; import android.os.Build; import java.util.Map; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.annotation.Resetter; @@ -15,7 +16,6 @@ @Implements( className = "android.app.SystemServiceRegistry", isInAndroidSdk = false, - looseSignatures = true, minSdk = Build.VERSION_CODES.M ) public class ShadowSystemServiceRegistry { @@ -121,7 +121,8 @@ public interface _ServiceFetcherN_ extends _ServiceFetcher_ { } @Implementation(minSdk = O) - protected static void onServiceNotFound(/* ServiceNotFoundException */ Object e0) { + protected static void onServiceNotFound( + @ClassName(value = "android.os.ServiceManager.ServiceNotFoundException") Object e0) { // otherwise the full stacktrace might be swallowed... Exception e = (Exception) e0; e.printStackTrace(); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java index e7499eafce8..ec17f0b5a19 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTelephonyManager.java @@ -64,6 +64,7 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.Executor; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -71,7 +72,7 @@ import org.robolectric.annotation.Resetter; import org.robolectric.util.ReflectionHelpers; -@Implements(value = TelephonyManager.class, looseSignatures = true) +@Implements(value = TelephonyManager.class) public class ShadowTelephonyManager { @RealObject protected TelephonyManager realTelephonyManager; @@ -180,12 +181,13 @@ public Object getBootstrapAuthenticationCallback() { @Implementation(minSdk = S) @HiddenApi public void bootstrapAuthenticationRequest( - Object appType, - Object nafId, - Object securityProtocol, - Object forceBootStrapping, - Object e, - Object callback) { + int appType, + Uri nafId, + @ClassName(value = "android.telephony.gba.UaSecurityProtocolIdentifier") + Object securityProtocol, + boolean forceBootStrapping, + Executor e, + @ClassName(value = "android.telephony.BootstrapAuthenticationCallback") Object callback) { this.callback = callback; } @@ -605,8 +607,9 @@ public void setAllCellInfo(List allCellInfo) { * TelephonyManager#NETWORK_TYPE_UNKNOWN} if it was never called. */ @Implementation(minSdk = Q) - protected void requestCellInfoUpdate(Object cellInfoExecutor, Object cellInfoCallback) { - Executor executor = (Executor) cellInfoExecutor; + protected void requestCellInfoUpdate( + Executor executor, + @ClassName(value = "android.telephony.CellInfoCallback") Object cellInfoCallback) { if (callbackCellInfos == null) { // ignore } else if (requestCellInfoUpdateErrorCode != 0 || requestCellInfoUpdateDetail != null) { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java index 7675c9996ff..36f3c9f1a06 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowThreadedRenderer.java @@ -5,6 +5,7 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import org.robolectric.shadow.api.Shadow; @@ -12,15 +13,14 @@ @Implements( className = "android.view.ThreadedRenderer", isInAndroidSdk = false, - looseSignatures = true, minSdk = O, maxSdk = P) public class ShadowThreadedRenderer { @Implementation protected static Bitmap createHardwareBitmap( - /*RenderNode*/ Object node, /*int*/ Object width, /*int*/ Object height) { - return createHardwareBitmap((int) width, (int) height); + @ClassName(value = "android.view.RenderNode") Object node, int width, int height) { + return createHardwareBitmap(width, height); } private static Bitmap createHardwareBitmap(int width, int height) { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java index 926ae6e8d2b..9f1df6aef81 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinder.java @@ -18,8 +18,7 @@ className = "libcore.util.TimeZoneFinder", minSdk = O, maxSdk = P, - isInAndroidSdk = false, - looseSignatures = true) + isInAndroidSdk = false) public class ShadowTimeZoneFinder { private static final String TZLOOKUP_PATH = "/usr/share/zoneinfo/tzlookup.xml"; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderQ.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderQ.java index 97134bd4268..74ee1fa27c0 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderQ.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderQ.java @@ -14,8 +14,7 @@ className = "libcore.timezone.TimeZoneFinder", minSdk = Q, maxSdk = R, - isInAndroidSdk = false, - looseSignatures = true) + isInAndroidSdk = false) public class ShadowTimeZoneFinderQ { @Implementation diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderS.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderS.java index f28a12edfb2..6e5faec5834 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderS.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTimeZoneFinderS.java @@ -12,11 +12,7 @@ import org.robolectric.annotation.Implements; /** Shadow for TimeZoneFinder on S or above. */ -@Implements( - value = TimeZoneFinder.class, - minSdk = S, - isInAndroidSdk = false, - looseSignatures = true) +@Implements(value = TimeZoneFinder.class, minSdk = S, isInAndroidSdk = false) public class ShadowTimeZoneFinderS { private static final String TZLOOKUP_PATH = "/usr/share/zoneinfo/tzlookup.xml"; diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java index 58abb5844bc..cdd488324ec 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowTypeface.java @@ -28,6 +28,7 @@ import java.util.Objects; import java.util.concurrent.atomic.AtomicLong; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -38,7 +39,7 @@ import org.robolectric.util.ReflectionHelpers; import org.robolectric.util.ReflectionHelpers.ClassParameter; -@Implements(value = Typeface.class, looseSignatures = true) +@Implements(value = Typeface.class) @SuppressLint("NewApi") public class ShadowTypeface { private static final Map FONTS = Collections.synchronizedMap(new HashMap<>()); @@ -122,10 +123,10 @@ protected static Typeface createFromResources(AssetManager mgr, String path, int @Implementation(minSdk = O) protected static Typeface createFromResources( - Object /* FamilyResourceEntry */ entry, - Object /* AssetManager */ mgr, - Object /* String */ path) { - return createUnderlyingTypeface((String) path, Typeface.NORMAL); + @ClassName(value = "android.content.res.FamilyResourceEntry") Object entry, + AssetManager mgr, + String path) { + return createUnderlyingTypeface(path, Typeface.NORMAL); } @Implementation diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java index 40dc52690ec..0cb7489b479 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsageStatsManager.java @@ -45,10 +45,7 @@ import org.robolectric.annotation.Resetter; /** Shadow of {@link UsageStatsManager}. */ -@Implements( - value = UsageStatsManager.class, - minSdk = Build.VERSION_CODES.LOLLIPOP, - looseSignatures = true) +@Implements(value = UsageStatsManager.class, minSdk = Build.VERSION_CODES.LOLLIPOP) public class ShadowUsageStatsManager { private static @StandbyBuckets int currentAppStandbyBucket = UsageStatsManager.STANDBY_BUCKET_ACTIVE; @@ -596,7 +593,7 @@ public void setUsageSource(@UsageSource int usageSource) { @SuppressWarnings("unchecked") @Implementation(minSdk = TIRAMISU) protected Object /* List */ queryBroadcastResponseStats( - @Nullable Object packageName, Object id) { + @Nullable String packageName, long id) { List result = new ArrayList<>(); for (Map.Entry> entry : appBroadcastStats.entrySet()) { diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java index 6e7ab58403e..f8bb8e14290 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowUsbManager.java @@ -25,6 +25,7 @@ import java.util.HashMap; import java.util.List; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -32,7 +33,7 @@ import org.robolectric.util.reflector.ForType; /** Robolectric implementation of {@link android.hardware.usb.UsbManager}. */ -@Implements(value = UsbManager.class, looseSignatures = true) +@Implements(value = UsbManager.class) public class ShadowUsbManager { @RealObject private UsbManager realUsbManager; @@ -261,22 +262,23 @@ public void addPort( @Implementation(minSdk = M) @HiddenApi - protected /* UsbPortStatus */ Object getPortStatus(/* UsbPort */ Object port) { + protected /* UsbPortStatus */ Object getPortStatus( + @ClassName(value = "android.hardware.usb.UsbPort") Object port) { return usbPortStatuses.get(port); } @Implementation(minSdk = M) @HiddenApi protected void setPortRoles( - /* UsbPort */ Object port, /* int */ Object powerRole, /* int */ Object dataRole) { + @ClassName(value = "android.hardware.usb.UsbPort") Object port, int powerRole, int dataRole) { UsbPortStatus status = usbPortStatuses.get(port); usbPortStatuses.put( (UsbPort) port, (UsbPortStatus) createUsbPortStatus( status.getCurrentMode(), - (int) powerRole, - (int) dataRole, + powerRole, + dataRole, status.getSupportedRoleCombinations())); RuntimeEnvironment.getApplication() .sendBroadcast(new Intent(UsbManager.ACTION_USB_PORT_CHANGED)); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java index 83ca1fb3c72..f9fabebfa2d 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWifiManager.java @@ -34,6 +34,7 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicInteger; import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.ClassName; import org.robolectric.annotation.HiddenApi; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; @@ -42,7 +43,7 @@ import org.robolectric.util.ReflectionHelpers; /** Shadow for {@link android.net.wifi.WifiManager}. */ -@Implements(value = WifiManager.class, looseSignatures = true) +@Implements(value = WifiManager.class) @SuppressWarnings("AndroidConcurrentHashMap") public class ShadowWifiManager { private static final int LOCAL_HOST = 2130706433; @@ -413,8 +414,10 @@ public WifiConfiguration getWifiConfiguration(int netId) { @Implementation(minSdk = Q) @HiddenApi - protected void addOnWifiUsabilityStatsListener(Object executorObject, Object listenerObject) { - Executor executor = (Executor) executorObject; + protected void addOnWifiUsabilityStatsListener( + Executor executor, + @ClassName(value = "android.net.wifi.WifiManager$OnWifiUsabilityStatsListener") + Object listenerObject) { WifiManager.OnWifiUsabilityStatsListener listener = (WifiManager.OnWifiUsabilityStatsListener) listenerObject; wifiUsabilityStatsListeners.put(listener, executor); @@ -422,7 +425,9 @@ protected void addOnWifiUsabilityStatsListener(Object executorObject, Object lis @Implementation(minSdk = Q) @HiddenApi - protected void removeOnWifiUsabilityStatsListener(Object listenerObject) { + protected void removeOnWifiUsabilityStatsListener( + @ClassName(value = "android.net.wifi.WifiManager$OnWifiUsabilityStatsListener") + Object listenerObject) { WifiManager.OnWifiUsabilityStatsListener listener = (WifiManager.OnWifiUsabilityStatsListener) listenerObject; wifiUsabilityStatsListeners.remove(listener); diff --git a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java index 80b484cdc48..b707b96b250 100644 --- a/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java +++ b/shadows/framework/src/main/java/org/robolectric/shadows/ShadowWindowManagerGlobal.java @@ -47,11 +47,7 @@ /** Shadow for {@link WindowManagerGlobal}. */ @SuppressWarnings("unused") // Unused params are implementations of Android SDK methods. -@Implements( - value = WindowManagerGlobal.class, - isInAndroidSdk = false, - minSdk = JELLY_BEAN_MR1, - looseSignatures = true) +@Implements(value = WindowManagerGlobal.class, isInAndroidSdk = false, minSdk = JELLY_BEAN_MR1) public class ShadowWindowManagerGlobal { private static WindowSessionDelegate windowSessionDelegate; private static IWindowSession windowSession;