1 package org.robolectric.shadows; 2 3 import static android.os.Build.VERSION_CODES.O; 4 import static android.os.Build.VERSION_CODES.P; 5 6 import android.graphics.Path; 7 import android.graphics.RectF; 8 import java.util.List; 9 import org.robolectric.annotation.Implementation; 10 import org.robolectric.annotation.Implements; 11 import org.robolectric.nativeruntime.DefaultNativeRuntimeLoader; 12 import org.robolectric.nativeruntime.PathNatives; 13 import org.robolectric.versioning.AndroidVersions.U; 14 import org.robolectric.versioning.AndroidVersions.V; 15 16 /** Shadow for {@link Path} that is backed by native code */ 17 @Implements( 18 value = Path.class, 19 minSdk = O, 20 isInAndroidSdk = false, 21 callNativeMethodsByDefault = true) 22 public class ShadowNativePath extends ShadowPath { 23 /** 24 * The {@link Path} static initializer invokes its own native methods. This has to be deferred 25 * starting in Android V. 26 */ 27 @Implementation(minSdk = V.SDK_INT) __staticInitializer__()28 protected static void __staticInitializer__() { 29 // deferred 30 } 31 32 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nInit()33 protected static long nInit() { 34 DefaultNativeRuntimeLoader.injectAndLoad(); 35 return PathNatives.nInit(); 36 } 37 38 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nInit(long nPath)39 protected static long nInit(long nPath) { 40 // Required for pre-P. 41 DefaultNativeRuntimeLoader.injectAndLoad(); 42 return PathNatives.nInit(nPath); 43 } 44 45 @Implementation(minSdk = P, maxSdk = U.SDK_INT) nGetFinalizer()46 protected static long nGetFinalizer() { 47 // Required for pre-P. 48 DefaultNativeRuntimeLoader.injectAndLoad(); 49 return PathNatives.nGetFinalizer(); 50 } 51 52 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nSet(long nativeDst, long nSrc)53 protected static void nSet(long nativeDst, long nSrc) { 54 PathNatives.nSet(nativeDst, nSrc); 55 } 56 57 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nComputeBounds(long nPath, RectF bounds)58 protected static void nComputeBounds(long nPath, RectF bounds) { 59 PathNatives.nComputeBounds(nPath, bounds); 60 } 61 62 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nIncReserve(long nPath, int extraPtCount)63 protected static void nIncReserve(long nPath, int extraPtCount) { 64 PathNatives.nIncReserve(nPath, extraPtCount); 65 } 66 67 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nMoveTo(long nPath, float x, float y)68 protected static void nMoveTo(long nPath, float x, float y) { 69 PathNatives.nMoveTo(nPath, x, y); 70 } 71 72 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nRMoveTo(long nPath, float dx, float dy)73 protected static void nRMoveTo(long nPath, float dx, float dy) { 74 PathNatives.nRMoveTo(nPath, dx, dy); 75 } 76 77 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nLineTo(long nPath, float x, float y)78 protected static void nLineTo(long nPath, float x, float y) { 79 PathNatives.nLineTo(nPath, x, y); 80 } 81 82 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nRLineTo(long nPath, float dx, float dy)83 protected static void nRLineTo(long nPath, float dx, float dy) { 84 PathNatives.nRLineTo(nPath, dx, dy); 85 } 86 87 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nQuadTo(long nPath, float x1, float y1, float x2, float y2)88 protected static void nQuadTo(long nPath, float x1, float y1, float x2, float y2) { 89 PathNatives.nQuadTo(nPath, x1, y1, x2, y2); 90 } 91 92 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2)93 protected static void nRQuadTo(long nPath, float dx1, float dy1, float dx2, float dy2) { 94 PathNatives.nRQuadTo(nPath, dx1, dy1, dx2, dy2); 95 } 96 97 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nConicTo(long nPath, float x1, float y1, float x2, float y2, float weight)98 protected static void nConicTo(long nPath, float x1, float y1, float x2, float y2, float weight) { 99 PathNatives.nConicTo(nPath, x1, y1, x2, y2, weight); 100 } 101 102 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nRConicTo( long nPath, float dx1, float dy1, float dx2, float dy2, float weight)103 protected static void nRConicTo( 104 long nPath, float dx1, float dy1, float dx2, float dy2, float weight) { 105 PathNatives.nRConicTo(nPath, dx1, dy1, dx2, dy2, weight); 106 } 107 108 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nCubicTo( long nPath, float x1, float y1, float x2, float y2, float x3, float y3)109 protected static void nCubicTo( 110 long nPath, float x1, float y1, float x2, float y2, float x3, float y3) { 111 PathNatives.nCubicTo(nPath, x1, y1, x2, y2, x3, y3); 112 } 113 114 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nRCubicTo( long nPath, float x1, float y1, float x2, float y2, float x3, float y3)115 protected static void nRCubicTo( 116 long nPath, float x1, float y1, float x2, float y2, float x3, float y3) { 117 PathNatives.nRCubicTo(nPath, x1, y1, x2, y2, x3, y3); 118 } 119 120 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nArcTo( long nPath, float left, float top, float right, float bottom, float startAngle, float sweepAngle, boolean forceMoveTo)121 protected static void nArcTo( 122 long nPath, 123 float left, 124 float top, 125 float right, 126 float bottom, 127 float startAngle, 128 float sweepAngle, 129 boolean forceMoveTo) { 130 PathNatives.nArcTo(nPath, left, top, right, bottom, startAngle, sweepAngle, forceMoveTo); 131 } 132 133 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nClose(long nPath)134 protected static void nClose(long nPath) { 135 PathNatives.nClose(nPath); 136 } 137 138 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddRect( long nPath, float left, float top, float right, float bottom, int dir)139 protected static void nAddRect( 140 long nPath, float left, float top, float right, float bottom, int dir) { 141 PathNatives.nAddRect(nPath, left, top, right, bottom, dir); 142 } 143 144 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddOval( long nPath, float left, float top, float right, float bottom, int dir)145 protected static void nAddOval( 146 long nPath, float left, float top, float right, float bottom, int dir) { 147 PathNatives.nAddOval(nPath, left, top, right, bottom, dir); 148 } 149 150 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddCircle(long nPath, float x, float y, float radius, int dir)151 protected static void nAddCircle(long nPath, float x, float y, float radius, int dir) { 152 PathNatives.nAddCircle(nPath, x, y, radius, dir); 153 } 154 155 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddArc( long nPath, float left, float top, float right, float bottom, float startAngle, float sweepAngle)156 protected static void nAddArc( 157 long nPath, 158 float left, 159 float top, 160 float right, 161 float bottom, 162 float startAngle, 163 float sweepAngle) { 164 PathNatives.nAddArc(nPath, left, top, right, bottom, startAngle, sweepAngle); 165 } 166 167 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddRoundRect( long nPath, float left, float top, float right, float bottom, float rx, float ry, int dir)168 protected static void nAddRoundRect( 169 long nPath, float left, float top, float right, float bottom, float rx, float ry, int dir) { 170 PathNatives.nAddRoundRect(nPath, left, top, right, bottom, rx, ry, dir); 171 } 172 173 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddRoundRect( long nPath, float left, float top, float right, float bottom, float[] radii, int dir)174 protected static void nAddRoundRect( 175 long nPath, float left, float top, float right, float bottom, float[] radii, int dir) { 176 PathNatives.nAddRoundRect(nPath, left, top, right, bottom, radii, dir); 177 } 178 179 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddPath(long nPath, long src, float dx, float dy)180 protected static void nAddPath(long nPath, long src, float dx, float dy) { 181 PathNatives.nAddPath(nPath, src, dx, dy); 182 } 183 184 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddPath(long nPath, long src)185 protected static void nAddPath(long nPath, long src) { 186 PathNatives.nAddPath(nPath, src); 187 } 188 189 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nAddPath(long nPath, long src, long matrix)190 protected static void nAddPath(long nPath, long src, long matrix) { 191 PathNatives.nAddPath(nPath, src, matrix); 192 } 193 194 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nOffset(long nPath, float dx, float dy)195 protected static void nOffset(long nPath, float dx, float dy) { 196 PathNatives.nOffset(nPath, dx, dy); 197 } 198 199 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nSetLastPoint(long nPath, float dx, float dy)200 protected static void nSetLastPoint(long nPath, float dx, float dy) { 201 PathNatives.nSetLastPoint(nPath, dx, dy); 202 } 203 204 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nTransform(long nPath, long matrix, long dstPath)205 protected static void nTransform(long nPath, long matrix, long dstPath) { 206 PathNatives.nTransform(nPath, matrix, dstPath); 207 } 208 209 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nTransform(long nPath, long matrix)210 protected static void nTransform(long nPath, long matrix) { 211 PathNatives.nTransform(nPath, matrix); 212 } 213 214 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nOp(long path1, long path2, int op, long result)215 protected static boolean nOp(long path1, long path2, int op, long result) { 216 return PathNatives.nOp(path1, path2, op, result); 217 } 218 219 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nIsRect(long nPath, RectF rect)220 protected static boolean nIsRect(long nPath, RectF rect) { 221 return PathNatives.nIsRect(nPath, rect); 222 } 223 224 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nReset(long nPath)225 protected static void nReset(long nPath) { 226 PathNatives.nReset(nPath); 227 } 228 229 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nRewind(long nPath)230 protected static void nRewind(long nPath) { 231 PathNatives.nRewind(nPath); 232 } 233 234 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nIsEmpty(long nPath)235 protected static boolean nIsEmpty(long nPath) { 236 return PathNatives.nIsEmpty(nPath); 237 } 238 239 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nIsConvex(long nPath)240 protected static boolean nIsConvex(long nPath) { 241 return PathNatives.nIsConvex(nPath); 242 } 243 244 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nGetFillType(long nPath)245 protected static int nGetFillType(long nPath) { 246 return PathNatives.nGetFillType(nPath); 247 } 248 249 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nSetFillType(long nPath, int ft)250 protected static void nSetFillType(long nPath, int ft) { 251 PathNatives.nSetFillType(nPath, ft); 252 } 253 254 @Implementation(minSdk = O, maxSdk = U.SDK_INT) nApproximate(long nPath, float error)255 protected static float[] nApproximate(long nPath, float error) { 256 return PathNatives.nApproximate(nPath, error); 257 } 258 259 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nInterpolate( long startPath, long endPath, float t, long interpolatedPath)260 protected static boolean nInterpolate( 261 long startPath, long endPath, float t, long interpolatedPath) { 262 return PathNatives.nInterpolate(startPath, endPath, t, interpolatedPath); 263 } 264 265 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nGetGenerationID(long nativePath)266 protected static int nGetGenerationID(long nativePath) { 267 return PathNatives.nGetGenerationID(nativePath); 268 } 269 270 @Implementation(minSdk = U.SDK_INT, maxSdk = U.SDK_INT) nIsInterpolatable(long startPath, long endPath)271 protected static boolean nIsInterpolatable(long startPath, long endPath) { 272 return PathNatives.nIsInterpolatable(startPath, endPath); 273 } 274 275 @Override getPoints()276 public List<Point> getPoints() { 277 throw new UnsupportedOperationException("Legacy ShadowPath description APIs are not supported"); 278 } 279 280 @Override fillBounds(RectF bounds)281 public void fillBounds(RectF bounds) { 282 throw new UnsupportedOperationException("Legacy ShadowPath description APIs are not supported"); 283 } 284 } 285