| package org.robolectric.shadows; |
| |
| import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR2; |
| import static android.os.Build.VERSION_CODES.KITKAT; |
| import static android.os.Build.VERSION_CODES.KITKAT_WATCH; |
| import static android.os.Build.VERSION_CODES.LOLLIPOP; |
| import static android.os.Build.VERSION_CODES.M; |
| import static android.os.Build.VERSION_CODES.N; |
| import static android.os.Build.VERSION_CODES.N_MR1; |
| import static android.os.Build.VERSION_CODES.O; |
| import static android.os.Build.VERSION_CODES.O_MR1; |
| import static android.os.Build.VERSION_CODES.P; |
| |
| import android.content.res.AssetFileDescriptor; |
| import android.content.res.AssetManager; |
| import android.content.res.XmlResourceParser; |
| import android.os.ParcelFileDescriptor; |
| import android.util.SparseArray; |
| import android.util.TypedValue; |
| import dalvik.system.VMRuntime; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.Collection; |
| import org.robolectric.RuntimeEnvironment; |
| import org.robolectric.annotation.HiddenApi; |
| import org.robolectric.annotation.Implementation; |
| import org.robolectric.annotation.Implements; |
| import org.robolectric.annotation.RealObject; |
| import org.robolectric.annotation.Resetter; |
| import org.robolectric.res.FsFile; |
| import org.robolectric.shadow.api.Shadow; |
| import org.robolectric.shadow.api.ShadowFactory; |
| import org.robolectric.shadows.ShadowAssetManager.Factory; |
| |
| @Implements(value = AssetManager.class, looseSignatures = true, factory = Factory.class) |
| public abstract class ShadowAssetManager { |
| static final int STYLE_NUM_ENTRIES = 6; |
| static final int STYLE_TYPE = 0; |
| static final int STYLE_DATA = 1; |
| static final int STYLE_ASSET_COOKIE = 2; |
| static final int STYLE_RESOURCE_ID = 3; |
| static final int STYLE_CHANGING_CONFIGURATIONS = 4; |
| static final int STYLE_DENSITY = 5; |
| |
| public static class Factory implements ShadowFactory<ShadowAssetManager> { |
| @Override |
| public ShadowAssetManager newInstance() { |
| return useLegacy() |
| ? new ShadowLegacyAssetManager() |
| : new ShadowArscAssetManager(); |
| } |
| } |
| |
| /** |
| * @deprecated Avoid use. |
| */ |
| @Deprecated |
| public static boolean useLegacy() { |
| return RuntimeEnvironment.useLegacyResources(); |
| } |
| |
| /** |
| * @deprecated Avoid use. |
| */ |
| @Deprecated |
| static ShadowLegacyAssetManager legacyShadowOf(AssetManager assetManager) { |
| return (ShadowLegacyAssetManager) Shadow.extract(assetManager); |
| } |
| |
| @RealObject |
| protected AssetManager realObject; |
| |
| @Implementation |
| abstract protected void __constructor__(); |
| |
| @Implementation |
| abstract protected void __constructor__(boolean isSystem); |
| |
| |
| @Implementation(minSdk = P) |
| protected static long nativeCreate() { |
| // Return a fake pointer, must not be 0. |
| return 1; |
| } |
| |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT) |
| abstract protected void init(); |
| |
| @HiddenApi @Implementation(minSdk = KITKAT_WATCH, maxSdk = O_MR1) |
| abstract protected void init(boolean isSystem); |
| |
| @HiddenApi @Implementation |
| abstract public CharSequence getResourceText(int ident); |
| |
| @HiddenApi @Implementation |
| abstract public CharSequence getResourceBagText(int ident, int bagEntryId); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int getStringBlockCount(); |
| |
| @HiddenApi @Implementation |
| abstract public String[] getResourceStringArray(final int id); |
| |
| @HiddenApi @Implementation |
| abstract public int getResourceIdentifier(String name, String defType, String defPackage); |
| |
| @HiddenApi @Implementation |
| abstract public boolean getResourceValue(int ident, int density, TypedValue outValue, boolean resolveRefs); |
| |
| @HiddenApi @Implementation |
| abstract public CharSequence[] getResourceTextArray(int resId); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| abstract public boolean getThemeValue(int themePtr, int ident, TypedValue outValue, boolean resolveRefs); |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP) |
| abstract public boolean getThemeValue(long themePtr, int ident, TypedValue outValue, boolean resolveRefs); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Object ensureStringBlocks(); |
| |
| @Implementation |
| abstract public InputStream open(String fileName) throws IOException; |
| |
| @Implementation |
| abstract public InputStream open(String fileName, int accessMode) throws IOException; |
| |
| @Implementation |
| abstract public AssetFileDescriptor openFd(String fileName) throws IOException; |
| |
| @Implementation |
| abstract public String[] list(String path) throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Number openAsset(String fileName, int mode) throws FileNotFoundException; |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected ParcelFileDescriptor openAssetFd(String fileName, long[] outOffsets) |
| throws IOException; |
| |
| @HiddenApi @Implementation |
| abstract public InputStream openNonAsset(int cookie, String fileName, int accessMode) |
| throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Number openNonAssetNative(int cookie, String fileName, int accessMode) |
| throws FileNotFoundException; |
| |
| @HiddenApi @Implementation |
| abstract public AssetFileDescriptor openNonAssetFd(int cookie, String fileName) |
| throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected ParcelFileDescriptor openNonAssetFdNative(int cookie, |
| String fileName, long[] outOffsets) throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Number openXmlAssetNative(int cookie, String fileName) |
| throws FileNotFoundException; |
| |
| @Implementation |
| abstract public XmlResourceParser openXmlResourceParser(int cookie, String fileName) |
| throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final int readAssetChar(int asset) { |
| return readAssetChar((long) asset); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected int readAssetChar(long asset); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final int readAsset(int asset, byte[] b, int off, int len) throws IOException { |
| return readAsset((long) asset, b, off, len); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected int readAsset(long asset, byte[] bArray, int off, int len) throws IOException; |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final long seekAsset(int asset, long offset, int whence) { |
| return seekAsset((long) asset, offset, whence); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected long seekAsset(long asset, long offset, int whence); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final long getAssetLength(int asset) { |
| return getAssetLength((long) asset); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected long getAssetLength(long asset); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final long getAssetRemainingLength(int asset) { |
| return getAssetRemainingLength((long) asset); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected long getAssetRemainingLength(long assetHandle); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final void destroyAsset(int asset) { |
| destroyAsset((long) asset); |
| } |
| |
| |
| @HiddenApi @Implementation(minSdk = P) |
| abstract public void setApkAssets(Object apkAssetsObjects, Object invalidateCaches); |
| |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected void destroyAsset(long asset); |
| |
| @HiddenApi @Implementation |
| abstract public int addAssetPath(String path); |
| |
| @HiddenApi @Implementation(minSdk = JELLY_BEAN_MR2, maxSdk = M) |
| final protected int addAssetPathNative(String path) { |
| return addAssetPathNative(path, false); |
| } |
| |
| @HiddenApi @Implementation(minSdk = N, maxSdk = O_MR1) |
| protected abstract int addAssetPathNative(String path, boolean appAsLib); |
| |
| @HiddenApi @Implementation |
| abstract public boolean isUpToDate(); |
| |
| @HiddenApi @Implementation(maxSdk = M) |
| abstract public void setLocale(String locale); |
| |
| @Implementation |
| abstract public String[] getLocales(); |
| |
| @HiddenApi @Implementation(maxSdk = N_MR1) |
| final public void setConfiguration(int mcc, int mnc, String locale, |
| int orientation, int touchscreen, int density, int keyboard, |
| int keyboardHidden, int navigation, int screenWidth, int screenHeight, |
| int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, |
| int screenLayout, int uiMode, int sdkVersion) { |
| setConfiguration(mcc, mnc, locale, |
| orientation, touchscreen, density, keyboard, |
| keyboardHidden, navigation, screenWidth, screenHeight, |
| smallestScreenWidthDp, screenWidthDp, screenHeightDp, |
| screenLayout, uiMode, 0, sdkVersion); |
| } |
| |
| @HiddenApi @Implementation(minSdk = O) |
| abstract public void setConfiguration(int mcc, int mnc, String locale, |
| int orientation, int touchscreen, int density, int keyboard, |
| int keyboardHidden, int navigation, int screenWidth, int screenHeight, |
| int smallestScreenWidthDp, int screenWidthDp, int screenHeightDp, |
| int screenLayout, int uiMode, int colorMode, int majorVersion); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract public int[] getArrayIntResource(int resId); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected String[] getArrayStringResource(int arrayResId); |
| |
| |
| @HiddenApi @Implementation(minSdk = P) |
| protected int[] getResourceIntArray(int resId) { |
| return getArrayIntResource(resId); |
| } |
| |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int[] getArrayStringInfo(int arrayResId); |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP) |
| protected final int[] getStyleAttributes(int themeRes) { |
| throw new UnsupportedOperationException("not yet implemented"); |
| } |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Number newTheme(); |
| |
| @HiddenApi @Implementation |
| abstract public Number createTheme(); |
| |
| @HiddenApi @Implementation |
| protected static void dumpTheme(long theme, int priority, String tag, String prefix) { |
| throw new UnsupportedOperationException("not yet implemented"); |
| } |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| abstract public void releaseTheme(int themePtr); |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP) |
| abstract public void releaseTheme(long themePtr); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final void deleteTheme(int theme) { |
| deleteTheme((long) theme); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract protected void deleteTheme(long theme); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| public static void applyThemeStyle(int themePtr, int styleRes, boolean force) { |
| applyThemeStyle((long) themePtr, styleRes, force); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| public static void applyThemeStyle(long themePtr, int styleRes, boolean force) { |
| if (useLegacy()) { |
| ShadowLegacyAssetManager.applyThemeStyle(themePtr, styleRes, force); |
| } else { |
| ShadowArscAssetManager.applyThemeStyle(themePtr, styleRes, force); |
| } |
| } |
| |
| |
| @HiddenApi @Implementation(minSdk = P) |
| protected void applyStyleToTheme(long themePtr, int resId, boolean force) { |
| applyThemeStyle(themePtr, resId, force); |
| } |
| |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| public static void copyTheme(int destPtr, int sourcePtr) { |
| copyTheme((long) destPtr, (long) sourcePtr); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| public static void copyTheme(long destPtr, long sourcePtr) { |
| if (useLegacy()) { |
| ShadowLegacyAssetManager.copyTheme(destPtr, sourcePtr); |
| } else { |
| ShadowArscAssetManager.copyTheme(destPtr, sourcePtr); |
| } |
| } |
| |
| |
| @HiddenApi @Implementation(minSdk = P) |
| protected static void nativeThemeCopy(long destPtr, long sourcePtr) { |
| copyTheme(destPtr, sourcePtr); |
| } |
| |
| |
| @HiddenApi @Implementation(maxSdk = LOLLIPOP) |
| protected static boolean applyStyle(int themeToken, int defStyleAttr, int defStyleRes, |
| int xmlParserToken, int[] attrs, int[] outValues, int[] outIndices) { |
| return applyStyle((long)themeToken, defStyleAttr, defStyleRes, (long)xmlParserToken, attrs, |
| outValues, outIndices); |
| } |
| |
| @HiddenApi @Implementation(maxSdk = N_MR1) |
| protected static boolean applyStyle(long themeToken, int defStyleAttr, int defStyleRes, |
| long xmlParserToken, int[] attrs, int[] outValues, int[] outIndices) { |
| if (useLegacy()) { |
| return ShadowLegacyAssetManager |
| .applyStyle(themeToken, defStyleAttr, defStyleRes, xmlParserToken, attrs, outValues, |
| outIndices); |
| } else { |
| return ShadowArscAssetManager |
| .applyStyle(themeToken, defStyleAttr, defStyleRes, xmlParserToken, attrs, outValues, |
| outIndices); |
| } |
| } |
| |
| @HiddenApi @Implementation(minSdk = O, maxSdk = O_MR1) |
| protected static boolean applyStyle(long themeToken, int defStyleAttr, int defStyleRes, |
| long xmlParserToken, int[] inAttrs, int length, long outValuesAddress, |
| long outIndicesAddress) { |
| ShadowVMRuntime shadowVMRuntime = Shadow.extract(VMRuntime.getRuntime()); |
| int[] outValues = (int[])shadowVMRuntime.getObjectForAddress(outValuesAddress); |
| int[] outIndices = (int[])shadowVMRuntime.getObjectForAddress(outIndicesAddress); |
| return applyStyle(themeToken, defStyleAttr, defStyleRes, xmlParserToken, inAttrs, |
| outValues, outIndices); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP) |
| protected static boolean resolveAttrs(long themeToken, |
| int defStyleAttr, int defStyleRes, int[] inValues, |
| int[] attrs, int[] outValues, int[] outIndices) { |
| if (useLegacy()) { |
| return ShadowLegacyAssetManager |
| .resolveAttrs(themeToken, defStyleAttr, defStyleRes, inValues, attrs, outValues, |
| outIndices); |
| } else { |
| return ShadowArscAssetManager |
| .resolveAttrs(themeToken, defStyleAttr, defStyleRes, inValues, attrs, outValues, |
| outIndices); |
| } |
| } |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected final boolean retrieveAttributes( |
| int xmlParserToken, int[] attrs, int[] outValues, int[] outIndices) { |
| return retrieveAttributes((long)xmlParserToken, attrs, outValues, outIndices); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP) |
| abstract protected boolean retrieveAttributes( |
| long xmlParserToken, int[] attrs, int[] outValues, int[] outIndices); |
| |
| @Implementation |
| abstract public String getResourceName(int resid); |
| |
| @Implementation |
| abstract public String getResourcePackageName(int resid); |
| |
| @Implementation |
| abstract public String getResourceTypeName(int resid); |
| |
| @Implementation |
| abstract public String getResourceEntryName(int resid); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int getArraySize(int id); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int retrieveArray(int id, int[] outValues); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected Number getNativeStringBlock(int block); |
| |
| @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| abstract public SparseArray<String> getAssignedPackageIdentifiers(); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int loadResourceValue(int ident, short density, TypedValue outValue, |
| boolean resolve); |
| |
| @HiddenApi @Implementation(maxSdk = O_MR1) |
| abstract protected int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue, |
| boolean resolve); |
| |
| @HiddenApi @Implementation(maxSdk = KITKAT_WATCH) |
| protected static int loadThemeAttributeValue(int themeHandle, int ident, |
| TypedValue outValue, boolean resolve) { |
| return loadThemeAttributeValue((long) themeHandle, ident, outValue, resolve); |
| } |
| |
| @HiddenApi @Implementation(minSdk = LOLLIPOP, maxSdk = O_MR1) |
| protected static int loadThemeAttributeValue(long themeHandle, int ident, |
| TypedValue outValue, boolean resolve) { |
| if (useLegacy()) { |
| return ShadowLegacyAssetManager |
| .loadThemeAttributeValue(themeHandle, ident, outValue, resolve); |
| } else { |
| return ShadowArscAssetManager |
| .loadThemeAttributeValue(themeHandle, ident, outValue, resolve); |
| } |
| } |
| |
| abstract Collection<FsFile> getAllAssetDirs(); |
| |
| @Resetter |
| public static void reset() { |
| if (useLegacy()) { |
| ShadowLegacyAssetManager.reset(); |
| } else { |
| ShadowArscAssetManager.reset(); |
| } |
| } |
| } |