diff options
Diffstat (limited to 'dexmaker-mockito-inline')
-rw-r--r-- | dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java index 319ff0d..abcf4f5 100644 --- a/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java +++ b/dexmaker-mockito-inline/src/main/java/com/android/dx/mockito/inline/InlineDexmakerMockMaker.java @@ -26,6 +26,7 @@ import com.android.dx.stock.ProxyBuilder.MethodSetEntry; import org.mockito.Mockito; import org.mockito.exceptions.base.MockitoException; import org.mockito.internal.creation.instance.Instantiator; +import org.mockito.internal.util.reflection.LenientCopyTool; import org.mockito.invocation.MockHandler; import org.mockito.mock.MockCreationSettings; import org.mockito.plugins.InstantiatorProvider; @@ -36,6 +37,7 @@ import java.io.InputStream; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; @@ -106,6 +108,40 @@ public final class InlineDexmakerMockMaker implements MockMaker { + "Potentially, the current VM does not support the jvmti API correctly", ioe); } + + // Blacklisted APIs were introduced in Android P: + // + // https://android-developers.googleblog.com/2018/02/ + // improving-stability-by-reducing-usage.html + // + // This feature prevents access to blacklisted fields and calling of blacklisted APIs + // if the calling class is not trusted. + Method allowHiddenApiReflectionFrom; + try { + Class vmDebug = Class.forName("dalvik.system.VMDebug"); + allowHiddenApiReflectionFrom = vmDebug.getDeclaredMethod( + "allowHiddenApiReflectionFrom", Class.class); + } catch (ClassNotFoundException | NoSuchMethodException e) { + throw new IllegalStateException("Cannot find " + + "VMDebug#allowHiddenApiReflectionFrom."); + } + + // The LenientCopyTool copies the fields to a spy when creating the copy from an + // existing object. Some of the fields might be blacklisted. Marking the LenientCopyTool + // as trusted allows the tool to copy all fields, including the blacklisted ones. + try { + allowHiddenApiReflectionFrom.invoke(null, LenientCopyTool.class); + } catch (InvocationTargetException e) { + throw e.getCause(); + } + + // The MockMethodAdvice is used by methods of spies to call the real methods. As the + // real methods might be blacklisted, this class needs to be marked as trusted. + try { + allowHiddenApiReflectionFrom.invoke(null, MockMethodAdvice.class); + } catch (InvocationTargetException e) { + throw e.getCause(); + } } catch (Throwable throwable) { agent = null; initializationError = throwable; |