1 package org.robolectric.shadows; 2 3 import android.content.res.ApkAssets; 4 import android.graphics.PathIterator; 5 import dalvik.system.VMRuntime; 6 import org.robolectric.RuntimeEnvironment; 7 import org.robolectric.annotation.Implementation; 8 import org.robolectric.annotation.Implements; 9 import org.robolectric.nativeruntime.PathIteratorNatives; 10 import org.robolectric.shadow.api.Shadow; 11 import org.robolectric.shadows.ShadowNativePathIterator.Picker; 12 import org.robolectric.util.ReflectionHelpers; 13 import org.robolectric.util.ReflectionHelpers.ClassParameter; 14 import org.robolectric.versioning.AndroidVersions.U; 15 import org.robolectric.versioning.AndroidVersions.V; 16 17 /** Shadow for {@link PathIterator} that is backed by native code. */ 18 @Implements( 19 value = PathIterator.class, 20 minSdk = U.SDK_INT, 21 callNativeMethodsByDefault = true, 22 shadowPicker = Picker.class, 23 isInAndroidSdk = false /* disable shadowOf generation */) 24 public class ShadowNativePathIterator { 25 26 /** 27 * The {@link PathIterator} static initializer invokes its own native methods. This has to be 28 * deferred starting in Android V. 29 */ 30 @Implementation(minSdk = V.SDK_INT) __staticInitializer__()31 protected static void __staticInitializer__() { 32 // deferred 33 } 34 35 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nCreate(long nativePath)36 protected static long nCreate(long nativePath) { 37 return PathIteratorNatives.nCreate(nativePath); 38 } 39 40 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nGetFinalizer()41 protected static long nGetFinalizer() { 42 return PathIteratorNatives.nGetFinalizer(); 43 } 44 45 @Implementation(minSdk = U.SDK_INT) nNext(long nativeIterator, long pointsAddress)46 protected static int nNext(long nativeIterator, long pointsAddress) { 47 ShadowVMRuntime shadowVmRuntime = Shadow.extract(VMRuntime.getRuntime()); 48 int token; 49 if (RuntimeEnvironment.getApiLevel() == U.SDK_INT) { 50 token = PathIteratorNatives.nNext(nativeIterator, pointsAddress); 51 } else { 52 token = 53 ReflectionHelpers.callStaticMethod( 54 PathIterator.class, 55 Shadow.directNativeMethodName(ApkAssets.class.getName(), "nNext"), 56 ClassParameter.from(long.class, nativeIterator), 57 ClassParameter.from(long.class, pointsAddress)); 58 } 59 float[] points = (float[]) shadowVmRuntime.getObjectForAddress(pointsAddress); 60 shadowVmRuntime.getBackingBuffer(pointsAddress).asFloatBuffer().get(points); 61 return token; 62 } 63 64 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nPeek(long nativeIterator)65 protected static int nPeek(long nativeIterator) { 66 return PathIteratorNatives.nPeek(nativeIterator); 67 } 68 69 /** Shadow picker for {@link PathIterator}. */ 70 public static final class Picker extends GraphicsShadowPicker<Object> { Picker()71 public Picker() { 72 super(ShadowPathIterator.class, ShadowNativePathIterator.class); 73 } 74 } 75 } 76