summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/LocaleConfig.java6
-rw-r--r--core/java/android/app/ResourcesManager.java6
-rw-r--r--core/java/android/app/WindowConfiguration.java2
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/res/ApkAssets.java4
-rw-r--r--core/java/android/content/res/AssetFileDescriptor.java29
-rw-r--r--core/java/android/content/res/AssetManager.java60
-rw-r--r--core/java/android/content/res/DrawableCache.java4
-rw-r--r--core/java/android/content/res/Element.java2
-rw-r--r--core/java/android/content/res/ResourceId.java2
-rw-r--r--core/java/android/content/res/Resources.java17
-rw-r--r--core/java/android/content/res/ResourcesImpl.java7
-rw-r--r--core/java/android/content/res/ResourcesKey.java2
-rw-r--r--core/java/android/content/res/StringBlock.java4
-rw-r--r--core/java/android/content/res/TagCounter.java3
-rw-r--r--core/java/android/content/res/TypedArray.java9
-rw-r--r--core/java/android/content/res/Validator.java2
-rw-r--r--core/java/android/content/res/XmlBlock.java4
-rw-r--r--core/java/android/hardware/display/DisplayManagerGlobal.java4
-rw-r--r--core/java/android/text/TextUtils.java15
-rw-r--r--core/java/android/util/DisplayMetrics.java2
-rw-r--r--core/java/android/util/TypedValue.java3
-rw-r--r--core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java64
-rw-r--r--core/jni/android_content_res_ApkAssets.cpp2
-rw-r--r--core/jni/android_util_AssetManager.cpp53
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java101
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java40
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java3
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java2
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java15
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java32
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java2
-rw-r--r--ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java19
-rw-r--r--ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/runtimehelper/ClassLoadHook.java5
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java24
-rw-r--r--ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java10
-rw-r--r--ravenwood/texts/ravenwood-annotation-allowed-classes.txt24
-rw-r--r--ravenwood/texts/ravenwood-framework-policies.txt26
38 files changed, 561 insertions, 60 deletions
diff --git a/core/java/android/app/LocaleConfig.java b/core/java/android/app/LocaleConfig.java
index 4a06f7d1a1c3..f56bf4d434e7 100644
--- a/core/java/android/app/LocaleConfig.java
+++ b/core/java/android/app/LocaleConfig.java
@@ -28,6 +28,8 @@ import android.content.res.XmlResourceParser;
import android.os.LocaleList;
import android.os.Parcel;
import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.AttributeSet;
import android.util.Slog;
import android.util.Xml;
@@ -64,6 +66,7 @@ import java.util.Set;
// Add following to last Note: when guide is written:
// For more information about the LocaleConfig overridden by the application, see TODO(b/261528306):
// add link to guide
+@RavenwoodKeepWholeClass
public class LocaleConfig implements Parcelable {
private static final String TAG = "LocaleConfig";
public static final String TAG_LOCALE_CONFIG = "locale-config";
@@ -104,6 +107,7 @@ public class LocaleConfig implements Parcelable {
*
* @see Context#createPackageContext(String, int).
*/
+ @RavenwoodThrow(blockedBy = LocaleManager.class)
public LocaleConfig(@NonNull Context context) {
this(context, true);
}
@@ -117,10 +121,12 @@ public class LocaleConfig implements Parcelable {
* @see Context#createPackageContext(String, int).
*/
@NonNull
+ @RavenwoodThrow(blockedBy = LocaleManager.class)
public static LocaleConfig fromContextIgnoringOverride(@NonNull Context context) {
return new LocaleConfig(context, false);
}
+ @RavenwoodThrow(blockedBy = LocaleManager.class)
private LocaleConfig(@NonNull Context context, boolean allowOverride) {
if (allowOverride) {
LocaleManager localeManager = context.getSystemService(LocaleManager.class);
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 0cc210b7db41..2d5dad05f54e 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -40,6 +40,8 @@ import android.os.IBinder;
import android.os.LocaleList;
import android.os.Process;
import android.os.Trace;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -70,6 +72,7 @@ import java.util.WeakHashMap;
import java.util.function.Function;
/** @hide */
+@RavenwoodKeepWholeClass
public class ResourcesManager {
static final String TAG = "ResourcesManager";
private static final boolean DEBUG = false;
@@ -149,6 +152,7 @@ public class ResourcesManager {
* This will collect the package resources' paths from its ApplicationInfo and add them to all
* existing and future contexts while the application is running.
*/
+ @RavenwoodThrow(reason = "FLAG_REGISTER_RESOURCE_PATHS is unsupported")
public void registerResourcePaths(@NonNull String uniqueId, @NonNull ApplicationInfo appInfo) {
if (!Flags.registerResourcePaths()) {
return;
@@ -1877,6 +1881,7 @@ public class ResourcesManager {
* instance uses.
*/
@Override
+ @RavenwoodThrow(blockedBy = ResourcesLoader.class)
public void onLoadersChanged(@NonNull Resources resources,
@NonNull List<ResourcesLoader> newLoader) {
synchronized (mLock) {
@@ -1906,6 +1911,7 @@ public class ResourcesManager {
* {@code loader} to apply any changes of the set of {@link ApkAssets}.
**/
@Override
+ @RavenwoodThrow(blockedBy = ResourcesLoader.class)
public void onLoaderUpdated(@NonNull ResourcesLoader loader) {
synchronized (mLock) {
final ArrayMap<ResourcesImpl, ResourcesKey> updatedResourceImplKeys =
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index a12faca71bf6..c6d0f61b529e 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -34,6 +34,7 @@ import android.content.res.Configuration;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;
import android.util.proto.WireTypeMismatchException;
@@ -55,6 +56,7 @@ import java.util.Objects;
* @hide
*/
@TestApi
+@RavenwoodKeepWholeClass
public class WindowConfiguration implements Parcelable, Comparable<WindowConfiguration> {
/**
* bounds that can differ from app bounds, which may include things such as insets.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 9dccc9ae7145..ffcb1cbec94e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -87,6 +87,8 @@ import android.os.UserManager;
import android.os.storage.StorageManager;
import android.provider.E2eeContactKeysManager;
import android.provider.MediaStore;
+import android.ravenwood.annotation.RavenwoodKeep;
+import android.ravenwood.annotation.RavenwoodKeepPartialClass;
import android.telephony.TelephonyRegistryManager;
import android.util.AttributeSet;
import android.view.Display;
@@ -128,6 +130,7 @@ import java.util.function.IntConsumer;
* up-calls for application-level operations such as launching activities,
* broadcasting and receiving intents, etc.
*/
+@RavenwoodKeepPartialClass
public abstract class Context {
/**
* After {@link Build.VERSION_CODES#TIRAMISU},
@@ -931,6 +934,7 @@ public abstract class Context {
* @param resId Resource id for the CharSequence text
*/
@NonNull
+ @RavenwoodKeep
public final CharSequence getText(@StringRes int resId) {
return getResources().getText(resId);
}
@@ -944,6 +948,7 @@ public abstract class Context {
* text information.
*/
@NonNull
+ @RavenwoodKeep
public final String getString(@StringRes int resId) {
return getResources().getString(resId);
}
@@ -960,6 +965,7 @@ public abstract class Context {
* stripped of styled text information.
*/
@NonNull
+ @RavenwoodKeep
public final String getString(@StringRes int resId, Object... formatArgs) {
return getResources().getString(resId, formatArgs);
}
@@ -976,6 +982,7 @@ public abstract class Context {
* does not exist.
*/
@ColorInt
+ @RavenwoodKeep
public final int getColor(@ColorRes int id) {
return getResources().getColor(id, getTheme());
}
@@ -1043,6 +1050,7 @@ public abstract class Context {
* @see android.content.res.Resources.Theme#obtainStyledAttributes(int[])
*/
@NonNull
+ @RavenwoodKeep
public final TypedArray obtainStyledAttributes(@NonNull @StyleableRes int[] attrs) {
return getTheme().obtainStyledAttributes(attrs);
}
@@ -1055,6 +1063,7 @@ public abstract class Context {
* @see android.content.res.Resources.Theme#obtainStyledAttributes(int, int[])
*/
@NonNull
+ @RavenwoodKeep
public final TypedArray obtainStyledAttributes(@StyleRes int resid,
@NonNull @StyleableRes int[] attrs) throws Resources.NotFoundException {
return getTheme().obtainStyledAttributes(resid, attrs);
@@ -1068,6 +1077,7 @@ public abstract class Context {
* @see android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
*/
@NonNull
+ @RavenwoodKeep
public final TypedArray obtainStyledAttributes(
@Nullable AttributeSet set, @NonNull @StyleableRes int[] attrs) {
return getTheme().obtainStyledAttributes(set, attrs, 0, 0);
@@ -1081,6 +1091,7 @@ public abstract class Context {
* @see android.content.res.Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
*/
@NonNull
+ @RavenwoodKeep
public final TypedArray obtainStyledAttributes(@Nullable AttributeSet set,
@NonNull @StyleableRes int[] attrs, @AttrRes int defStyleAttr,
@StyleRes int defStyleRes) {
@@ -4530,6 +4541,7 @@ public abstract class Context {
* <b>never</b> throw a {@link RuntimeException} if the name is not supported.
*/
@SuppressWarnings("unchecked")
+ @RavenwoodKeep
// TODO(b/347269120): Re-add @Nullable
public final <T> T getSystemService(@NonNull Class<T> serviceClass) {
// Because subclasses may override getSystemService(String) we cannot
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 653e243f5e06..68b5d782bfbf 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -22,6 +22,8 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.om.OverlayableInfo;
import android.content.res.loader.AssetsProvider;
import android.content.res.loader.ResourcesProvider;
+import android.ravenwood.annotation.RavenwoodClassLoadHook;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.text.TextUtils;
import com.android.internal.annotations.GuardedBy;
@@ -45,6 +47,8 @@ import java.util.Objects;
* making the creation of AssetManagers very cheap.
* @hide
*/
+@RavenwoodKeepWholeClass
+@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK)
public final class ApkAssets {
/**
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
index afddc7798244..986d88103ac3 100644
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ b/core/java/android/content/res/AssetFileDescriptor.java
@@ -24,6 +24,8 @@ import android.os.Bundle;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodReplace;
import android.system.ErrnoException;
import android.system.Os;
import android.system.StructStat;
@@ -45,6 +47,7 @@ import java.nio.channels.WritableByteChannel;
* opened FileDescriptor that can be used to read the data, as well as the
* offset and length of that entry's data in the file.
*/
+@RavenwoodKeepWholeClass
public class AssetFileDescriptor implements Parcelable, Closeable {
/**
* Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)}
@@ -300,10 +303,30 @@ public class AssetFileDescriptor implements Parcelable, Closeable {
NonSeekableAutoCloseInputStream(AssetFileDescriptor fd) throws IOException {
super(fd.getParcelFileDescriptor());
- super.skip(fd.getStartOffset());
+ skipRaw(fd.getStartOffset());
mRemaining = (int) fd.getLength();
}
+ @RavenwoodReplace
+ private long skipRaw(long count) throws IOException {
+ return super.skip(count);
+ }
+
+ private long skipRaw$ravenwood(long count) throws IOException {
+ // OpenJDK doesn't allow skip on pipes, so just use read.
+ final byte[] buf = new byte[(int) Math.min(1024, count)];
+ long totalRead = 0;
+ while (totalRead < count) {
+ final int toRead = (int) Math.min(count - totalRead, buf.length);
+ final int read = super.read(buf, 0, toRead);
+ if (read == -1) {
+ break;
+ }
+ totalRead += read;
+ }
+ return totalRead;
+ }
+
@Override
public int available() throws IOException {
return mRemaining >= 0
@@ -341,12 +364,12 @@ public class AssetFileDescriptor implements Parcelable, Closeable {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
if (count > mRemaining) count = mRemaining;
- long res = super.skip(count);
+ long res = skipRaw(count);
if (res >= 0) mRemaining -= res;
return res;
}
- return super.skip(count);
+ return skipRaw(count);
}
@Override
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 899c2d6eec74..6fd4d0141977 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -16,8 +16,8 @@
package android.content.res;
-import static android.content.res.Resources.ID_NULL;
import static android.app.ResourcesManager.ApkKey;
+import static android.content.res.Resources.ID_NULL;
import android.annotation.AnyRes;
import android.annotation.ArrayRes;
@@ -34,6 +34,9 @@ import android.content.res.Configuration.NativeConfig;
import android.content.res.loader.ResourcesLoader;
import android.os.Build;
import android.os.ParcelFileDescriptor;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodReplace;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -43,6 +46,7 @@ import android.util.TypedValue;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.om.OverlayConfig;
+import com.android.internal.ravenwood.RavenwoodEnvironment;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -66,11 +70,14 @@ import java.util.Objects;
* files that have been bundled with the application as a simple stream of
* bytes.
*/
+@RavenwoodKeepWholeClass
public final class AssetManager implements AutoCloseable {
private static final String TAG = "AssetManager";
private static final boolean DEBUG_REFS = false;
- private static final String FRAMEWORK_APK_PATH = "/system/framework/framework-res.apk";
+ private static final String FRAMEWORK_APK_PATH = getFrameworkApkPath();
+ private static final String FRAMEWORK_APK_PATH_DEVICE = "/system/framework/framework-res.apk";
+ private static final String FRAMEWORK_APK_PATH_RAVENWOOD = "ravenwood-data/framework-res.apk";
private static final Object sSync = new Object();
@@ -147,6 +154,7 @@ public final class AssetManager implements AutoCloseable {
return this;
}
+ @RavenwoodThrow(blockedBy = ResourcesLoader.class)
public Builder addLoader(ResourcesLoader loader) {
mLoaders.add(loader);
return this;
@@ -206,6 +214,16 @@ public final class AssetManager implements AutoCloseable {
}
}
+ @RavenwoodReplace
+ private static String getFrameworkApkPath() {
+ return FRAMEWORK_APK_PATH_DEVICE;
+ }
+
+ private static String getFrameworkApkPath$ravenwood() {
+ return RavenwoodEnvironment.getInstance().getRavenwoodRuntimePath()
+ + FRAMEWORK_APK_PATH_RAVENWOOD;
+ }
+
/**
* Create a new AssetManager containing only the basic system assets.
* Applications will not generally use this method, instead retrieving the
@@ -260,7 +278,9 @@ public final class AssetManager implements AutoCloseable {
final ArrayList<ApkAssets> apkAssets = new ArrayList<>();
apkAssets.add(ApkAssets.loadFromPath(frameworkPath, ApkAssets.PROPERTY_SYSTEM));
+ // TODO(Ravenwood): overlay support?
final String[] systemIdmapPaths =
+ RavenwoodEnvironment.getInstance().isRunningOnRavenwood() ? new String[0] :
OverlayConfig.getZygoteInstance().createImmutableFrameworkIdmapsInZygote();
for (String idmapPath : systemIdmapPaths) {
apkAssets.add(ApkAssets.loadOverlayFromPath(idmapPath, ApkAssets.PROPERTY_SYSTEM));
@@ -351,6 +371,7 @@ public final class AssetManager implements AutoCloseable {
* Changes the {@link ResourcesLoader ResourcesLoaders} used in this AssetManager.
* @hide
*/
+ @RavenwoodThrow(blockedBy = ResourcesLoader.class)
void setLoaders(@NonNull List<ResourcesLoader> newLoaders) {
Objects.requireNonNull(newLoaders, "newLoaders");
@@ -578,6 +599,7 @@ public final class AssetManager implements AutoCloseable {
/** @hide */
@NonNull
+ @RavenwoodThrow(blockedBy = ResourcesLoader.class)
public List<ResourcesLoader> getLoaders() {
return mLoaders == null ? Collections.emptyList() : Arrays.asList(mLoaders);
}
@@ -1216,6 +1238,7 @@ public final class AssetManager implements AutoCloseable {
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RavenwoodReplace
void applyStyle(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
@Nullable XmlBlock.Parser parser, @NonNull int[] inAttrs, long outValuesAddress,
long outIndicesAddress) {
@@ -1799,4 +1822,37 @@ public final class AssetManager implements AutoCloseable {
*/
@UnsupportedAppUsage
public static native int getGlobalAssetManagerCount();
+
+ // Ravenwood Workarounds
+
+ /**
+ * ART has explicit support for allocating pinned (non-movable) array objects.
+ * On Ravenwood we allocate regular arrays and use critical array access in
+ * JNI as a best effort to reduce memory copying.
+ * TODO(b/359983716): Remove when Ravenwood switch to ART
+ */
+ void applyStyle$ravenwood(long themePtr, @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
+ @Nullable XmlBlock.Parser parser, @NonNull int[] inAttrs, long outValuesAddress,
+ long outIndicesAddress) {
+ Objects.requireNonNull(inAttrs, "inAttrs");
+ var runtime = RavenwoodEnvironment.getInstance();
+ final int[] outValues = runtime.fromAddress(outValuesAddress);
+ final int[] outIndices = runtime.fromAddress(outIndicesAddress);
+ synchronized (this) {
+ // Need to synchronize on AssetManager because we will be accessing
+ // the native implementation of AssetManager.
+ ensureValidLocked();
+ nativeApplyStyleWithArray(mObject, themePtr, defStyleAttr, defStyleRes,
+ parser != null ? parser.mParseState : 0, inAttrs, outValues,
+ outIndices);
+ }
+ }
+
+ /**
+ * A variant of nativeApplyStyle(), accepting java arrays instead of raw pointers.
+ * TODO(b/359983716): Remove when Ravenwood switch to ART
+ */
+ private static native void nativeApplyStyleWithArray(long ptr, long themePtr,
+ @AttrRes int defStyleAttr, @StyleRes int defStyleRes,
+ long xmlParserPtr, @NonNull int[] inAttrs, int[] outData, int[] outIndices);
}
diff --git a/core/java/android/content/res/DrawableCache.java b/core/java/android/content/res/DrawableCache.java
index d0ebe3304065..c139de6685c8 100644
--- a/core/java/android/content/res/DrawableCache.java
+++ b/core/java/android/content/res/DrawableCache.java
@@ -19,13 +19,17 @@ package android.content.res;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.ravenwood.annotation.RavenwoodKeep;
+import android.ravenwood.annotation.RavenwoodKeepPartialClass;
/**
* Class which can be used to cache Drawable resources against a theme.
*/
+@RavenwoodKeepPartialClass
class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> {
@UnsupportedAppUsage
+ @RavenwoodKeep
DrawableCache() {
}
diff --git a/core/java/android/content/res/Element.java b/core/java/android/content/res/Element.java
index 6ff96f42e433..798f9062a7e4 100644
--- a/core/java/android/content/res/Element.java
+++ b/core/java/android/content/res/Element.java
@@ -19,6 +19,7 @@ package android.content.res;
import static android.os.SystemProperties.PROP_VALUE_MAX;
import android.annotation.NonNull;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.Pools.SimplePool;
import android.util.Slog;
@@ -33,6 +34,7 @@ import java.util.Set;
*
* {@hide}
*/
+@RavenwoodKeepWholeClass
public class Element {
private static final int DEFAULT_MAX_STRING_ATTR_LENGTH = 32_768;
private static final int MAX_POOL_SIZE = 128;
diff --git a/core/java/android/content/res/ResourceId.java b/core/java/android/content/res/ResourceId.java
index 3c7b5fc11164..c9e900f8ecb6 100644
--- a/core/java/android/content/res/ResourceId.java
+++ b/core/java/android/content/res/ResourceId.java
@@ -16,11 +16,13 @@
package android.content.res;
import android.annotation.AnyRes;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
/**
* Provides a set of utility methods for dealing with Resource IDs.
* @hide
*/
+@RavenwoodKeepWholeClass
public final class ResourceId {
/**
* Checks whether the integer {@code id} is a valid resource ID, as generated by AAPT.
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 248ef1d4d9c4..bf4d97d602d8 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -58,6 +58,8 @@ import android.graphics.drawable.DrawableInflater;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
@@ -124,6 +126,7 @@ import java.util.WeakHashMap;
* <p>For more information about using resources, see the documentation about <a
* href="{@docRoot}guide/topics/resources/index.html">Application Resources</a>.</p>
*/
+@RavenwoodKeepWholeClass
public class Resources {
/**
* The {@code null} resource ID. This denotes an invalid resource ID that is returned by the
@@ -417,6 +420,7 @@ public class Resources {
* @hide Pending API finalization.
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RavenwoodThrow(blockedBy = DrawableInflater.class)
public final DrawableInflater getDrawableInflater() {
if (mDrawableInflater == null) {
mDrawableInflater = new DrawableInflater(this, mClassLoader);
@@ -478,6 +482,7 @@ public class Resources {
*
* @return Typeface The Typeface data associated with the resource.
*/
+ @RavenwoodThrow(blockedBy = Typeface.class)
@NonNull public Typeface getFont(@FontRes int id) throws NotFoundException {
final TypedValue value = obtainTempTypedValue();
try {
@@ -502,6 +507,7 @@ public class Resources {
/**
* @hide
*/
+ @RavenwoodThrow(blockedBy = Typeface.class)
public void preloadFonts(@ArrayRes int id) {
final TypedArray array = obtainTypedArray(id);
try {
@@ -915,6 +921,7 @@ public class Resources {
* @deprecated Use {@link #getDrawable(int, Theme)} instead.
*/
@Deprecated
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
final Drawable d = getDrawable(id, null);
if (d != null && d.canApplyTheme()) {
@@ -939,6 +946,7 @@ public class Resources {
* @throws NotFoundException Throws NotFoundException if the given ID does
* not exist.
*/
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawable(@DrawableRes int id, @Nullable Theme theme)
throws NotFoundException {
return getDrawableForDensity(id, 0, theme);
@@ -974,6 +982,7 @@ public class Resources {
*/
@Nullable
@Deprecated
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawableForDensity(@DrawableRes int id, int density)
throws NotFoundException {
return getDrawableForDensity(id, density, null);
@@ -997,6 +1006,7 @@ public class Resources {
* not exist.
*/
@Nullable
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawableForDensity(@DrawableRes int id, int density, @Nullable Theme theme) {
final TypedValue value = obtainTempTypedValue();
try {
@@ -1025,6 +1035,7 @@ public class Resources {
* @deprecated Prefer {@link android.graphics.drawable.AnimatedImageDrawable}.
*/
@Deprecated
+ @RavenwoodThrow(blockedBy = Movie.class)
public Movie getMovie(@RawRes int id) throws NotFoundException {
final InputStream is = openRawResource(id);
final Movie movie = Movie.decodeStream(is);
@@ -1113,6 +1124,7 @@ public class Resources {
*/
@NonNull
@Deprecated
+ @RavenwoodThrow(blockedBy = ColorStateList.class)
public ColorStateList getColorStateList(@ColorRes int id) throws NotFoundException {
final ColorStateList csl = getColorStateList(id, null);
if (csl != null && csl.canApplyTheme()) {
@@ -1143,6 +1155,7 @@ public class Resources {
* color or multiple colors that can be selected based on a state.
*/
@NonNull
+ @RavenwoodThrow(blockedBy = ColorStateList.class)
public ColorStateList getColorStateList(@ColorRes int id, @Nullable Theme theme)
throws NotFoundException {
final TypedValue value = obtainTempTypedValue();
@@ -1156,6 +1169,7 @@ public class Resources {
}
@NonNull
+ @RavenwoodThrow(blockedBy = ColorStateList.class)
ColorStateList loadColorStateList(@NonNull TypedValue value, int id, @Nullable Theme theme)
throws NotFoundException {
return mResourcesImpl.loadColorStateList(this, value, id, theme);
@@ -1165,6 +1179,7 @@ public class Resources {
* @hide
*/
@NonNull
+ @RavenwoodThrow(blockedBy = ComplexColor.class)
public ComplexColor loadComplexColor(@NonNull TypedValue value, int id, @Nullable Theme theme) {
return mResourcesImpl.loadComplexColor(this, value, id, theme);
}
@@ -1783,6 +1798,7 @@ public class Resources {
* @throws NotFoundException Throws NotFoundException if the given ID
* does not exist.
*/
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawable(@DrawableRes int id) throws NotFoundException {
return Resources.this.getDrawable(id, this);
}
@@ -2845,6 +2861,7 @@ public class Resources {
* @param appInfo The ApplicationInfo that contains resources paths of the package.
*/
@FlaggedApi(android.content.res.Flags.FLAG_REGISTER_RESOURCE_PATHS)
+ @RavenwoodThrow(reason = "FLAG_REGISTER_RESOURCE_PATHS is unsupported")
public static void registerResourcePaths(@NonNull String uniqueId,
@NonNull ApplicationInfo appInfo) {
if (Flags.registerResourcePaths()) {
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index d874270b4653..90420dec64d1 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -47,6 +47,8 @@ import android.os.Build;
import android.os.LocaleList;
import android.os.ParcelFileDescriptor;
import android.os.Trace;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -82,6 +84,7 @@ import java.util.Locale;
*
* @hide
*/
+@RavenwoodKeepWholeClass
public class ResourcesImpl {
static final String TAG = "Resources";
@@ -689,6 +692,7 @@ public class ResourcesImpl {
}
@Nullable
+ @RavenwoodThrow(blockedBy = Drawable.class)
Drawable loadDrawable(@NonNull Resources wrapper, @NonNull TypedValue value, int id,
int density, @Nullable Resources.Theme theme)
throws NotFoundException {
@@ -1035,6 +1039,7 @@ public class ResourcesImpl {
* Loads a font from XML or resources stream.
*/
@Nullable
+ @RavenwoodThrow(blockedBy = Typeface.class)
public Typeface loadFont(Resources wrapper, TypedValue value, int id) {
if (value.string == null) {
throw new NotFoundException("Resource \"" + getResourceName(id) + "\" ("
@@ -1121,6 +1126,7 @@ public class ResourcesImpl {
}
@Nullable
+ @RavenwoodThrow(blockedBy = ComplexColor.class)
ComplexColor loadComplexColor(Resources wrapper, @NonNull TypedValue value, int id,
Resources.Theme theme) {
if (TRACE_FOR_PRELOAD) {
@@ -1162,6 +1168,7 @@ public class ResourcesImpl {
}
@NonNull
+ @RavenwoodThrow(blockedBy = ColorStateList.class)
ColorStateList loadColorStateList(Resources wrapper, TypedValue value, int id,
Resources.Theme theme)
throws NotFoundException {
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index 99b56a82173e..99a9d89689db 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -22,12 +22,14 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.loader.ResourcesLoader;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.text.TextUtils;
import java.util.Arrays;
import java.util.Objects;
/** @hide */
+@RavenwoodKeepWholeClass
public final class ResourcesKey {
@Nullable
@UnsupportedAppUsage
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index 0070a6f920db..290bc10b64a6 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -25,6 +25,8 @@ import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.text.LineBreakConfig;
+import android.ravenwood.annotation.RavenwoodClassLoadHook;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.text.Annotation;
import android.text.Spannable;
import android.text.SpannableString;
@@ -60,6 +62,8 @@ import java.util.Arrays;
*
* {@hide}
*/
+@RavenwoodKeepWholeClass
+@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK)
public final class StringBlock implements Closeable {
private static final String TAG = "AssetManager";
private static final boolean localLOGV = false;
diff --git a/core/java/android/content/res/TagCounter.java b/core/java/android/content/res/TagCounter.java
index 94deee7ab55c..c69a133e214b 100644
--- a/core/java/android/content/res/TagCounter.java
+++ b/core/java/android/content/res/TagCounter.java
@@ -16,11 +16,14 @@
package android.content.res;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+
/**
* Counter used to track the number of tags seen during manifest validation.
*
* {@hide}
*/
+@RavenwoodKeepWholeClass
public class TagCounter {
private static final int DEFAULT_MAX_COUNT = 512;
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
index bb2d2a0cc5c6..f8eeaa93872a 100644
--- a/core/java/android/content/res/TypedArray.java
+++ b/core/java/android/content/res/TypedArray.java
@@ -27,6 +27,9 @@ import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.StrictMode;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
+import android.ravenwood.annotation.RavenwoodReplace;
+import android.ravenwood.annotation.RavenwoodThrow;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
@@ -46,6 +49,7 @@ import java.util.Arrays;
* The indices used to retrieve values from this structure correspond to
* the positions of the attributes given to obtainStyledAttributes.
*/
+@RavenwoodKeepWholeClass
public class TypedArray implements AutoCloseable {
static TypedArray obtain(Resources res, int len) {
@@ -557,6 +561,7 @@ public class TypedArray implements AutoCloseable {
* @hide
*/
@Nullable
+ @RavenwoodThrow(blockedBy = ComplexColor.class)
public ComplexColor getComplexColor(@StyleableRes int index) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
@@ -593,6 +598,7 @@ public class TypedArray implements AutoCloseable {
* not an integer color or color state list.
*/
@Nullable
+ @RavenwoodThrow(blockedBy = ColorStateList.class)
public ColorStateList getColorStateList(@StyleableRes int index) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
@@ -991,6 +997,7 @@ public class TypedArray implements AutoCloseable {
* not a color or drawable resource.
*/
@Nullable
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawable(@StyleableRes int index) {
return getDrawableForDensity(index, 0);
}
@@ -1000,6 +1007,7 @@ public class TypedArray implements AutoCloseable {
* @hide
*/
@Nullable
+ @RavenwoodThrow(blockedBy = Drawable.class)
public Drawable getDrawableForDensity(@StyleableRes int index, int density) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
@@ -1037,6 +1045,7 @@ public class TypedArray implements AutoCloseable {
* not a font resource.
*/
@Nullable
+ @RavenwoodThrow(blockedBy = Typeface.class)
public Typeface getFont(@StyleableRes int index) {
if (mRecycled) {
throw new RuntimeException("Cannot make calls to a recycled instance!");
diff --git a/core/java/android/content/res/Validator.java b/core/java/android/content/res/Validator.java
index f72f3c49ee48..152076887f2c 100644
--- a/core/java/android/content/res/Validator.java
+++ b/core/java/android/content/res/Validator.java
@@ -18,6 +18,7 @@ package android.content.res;
import android.annotation.NonNull;
import android.annotation.StyleableRes;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import com.android.internal.R;
@@ -32,6 +33,7 @@ import java.util.ArrayDeque;
*
* {@hide}
*/
+@RavenwoodKeepWholeClass
public class Validator {
private final ArrayDeque<Element> mElements = new ArrayDeque<>();
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
index 7649b32a6c7a..40c532498fbc 100644
--- a/core/java/android/content/res/XmlBlock.java
+++ b/core/java/android/content/res/XmlBlock.java
@@ -24,6 +24,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
+import android.ravenwood.annotation.RavenwoodClassLoadHook;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.util.TypedValue;
import com.android.internal.annotations.VisibleForTesting;
@@ -44,6 +46,8 @@ import java.io.Reader;
* {@hide}
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+@RavenwoodKeepWholeClass
+@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK)
public final class XmlBlock implements AutoCloseable {
private static final boolean DEBUG=false;
diff --git a/core/java/android/hardware/display/DisplayManagerGlobal.java b/core/java/android/hardware/display/DisplayManagerGlobal.java
index cae33d05b6ed..85e33a8b4496 100644
--- a/core/java/android/hardware/display/DisplayManagerGlobal.java
+++ b/core/java/android/hardware/display/DisplayManagerGlobal.java
@@ -174,10 +174,14 @@ public final class DisplayManagerGlobal {
/**
* Gets an instance of the display manager global singleton.
*
+ * This method is actually unsupported on Ravenwood, however to support
+ * {@link android.app.ResourcesManager} we make this method always return null.
+ *
* @return The display manager instance, may be null early in system startup
* before the display manager has been fully initialized.
*/
@UnsupportedAppUsage
+ // @RavenwoodIgnore(value = "null")
public static DisplayManagerGlobal getInstance() {
synchronized (DisplayManagerGlobal.class) {
if (sInstance == null) {
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 6ea462eb969f..032f5923d3f2 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -84,6 +84,8 @@ import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
+@android.ravenwood.annotation.RavenwoodKeepStaticInitializer
+@android.ravenwood.annotation.RavenwoodKeepPartialClass
public class TextUtils {
private static final String TAG = "TextUtils";
@@ -1704,7 +1706,7 @@ public class TextUtils {
return true;
}
- @android.ravenwood.annotation.RavenwoodReplace
+ @android.ravenwood.annotation.RavenwoodKeep
/* package */ static char[] obtain(int len) {
char[] buf;
@@ -1719,11 +1721,7 @@ public class TextUtils {
return buf;
}
- /* package */ static char[] obtain$ravenwood(int len) {
- return new char[len];
- }
-
- @android.ravenwood.annotation.RavenwoodReplace
+ @android.ravenwood.annotation.RavenwoodKeep
/* package */ static void recycle(char[] temp) {
if (temp.length > 1000)
return;
@@ -1733,10 +1731,6 @@ public class TextUtils {
}
}
- /* package */ static void recycle$ravenwood(char[] temp) {
- // Handled by typical GC
- }
-
/**
* Html-encode the string.
* @param s the string to be encoded
@@ -2161,6 +2155,7 @@ public class TextUtils {
*
* Be careful: this code will need to be updated when vertical scripts will be supported
*/
+ @android.ravenwood.annotation.RavenwoodKeep
public static int getLayoutDirectionFromLocale(Locale locale) {
return ((locale != null && !locale.equals(Locale.ROOT)
&& ULocale.forLocale(locale).isRightToLeft())
diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java
index f14485b09424..c5d3c1d1f349 100644
--- a/core/java/android/util/DisplayMetrics.java
+++ b/core/java/android/util/DisplayMetrics.java
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.FontScaleConverter;
import android.os.SystemProperties;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.view.WindowManager;
import java.lang.annotation.Retention;
@@ -45,6 +46,7 @@ import java.lang.annotation.RetentionPolicy;
* </p>
*
*/
+@RavenwoodKeepWholeClass
public class DisplayMetrics {
@IntDef(prefix = { "DENSITY_" }, value = {
diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java
index 9668b6ad1f72..26ab5885c9ea 100644
--- a/core/java/android/util/TypedValue.java
+++ b/core/java/android/util/TypedValue.java
@@ -22,6 +22,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.content.pm.ActivityInfo.Config;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -30,6 +31,7 @@ import java.lang.annotation.RetentionPolicy;
* Container for a dynamically typed data value. Primarily used with
* {@link android.content.res.Resources} for holding resource values.
*/
+@RavenwoodKeepWholeClass
public class TypedValue {
/** The value contains no data. */
public static final int TYPE_NULL = 0x00;
@@ -827,4 +829,3 @@ public class TypedValue {
return sb.toString();
}
}
-
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
index 8fe1813b7ba0..ee3a3c27ca77 100644
--- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -15,24 +15,33 @@
*/
package com.android.internal.ravenwood;
+import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodNativeSubstitutionClass;
+import android.ravenwood.annotation.RavenwoodReplace;
/**
* Class to interact with the Ravenwood environment.
*/
-@android.ravenwood.annotation.RavenwoodKeepWholeClass
+@RavenwoodKeepWholeClass
@RavenwoodNativeSubstitutionClass(
"com.android.platform.test.ravenwood.nativesubstitution.RavenwoodEnvironment_host")
public final class RavenwoodEnvironment {
public static final String TAG = "RavenwoodEnvironment";
- private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment();
- private static Workaround sWorkaround = new Workaround();
+ private static final RavenwoodEnvironment sInstance;
+ private static final Workaround sWorkaround;
private RavenwoodEnvironment() {
- if (isRunningOnRavenwood()) {
- ensureRavenwoodInitializedInternal();
- }
+ }
+
+ static {
+ sInstance = new RavenwoodEnvironment();
+ sWorkaround = new Workaround();
+ ensureRavenwoodInitialized();
+ }
+
+ private static RuntimeException notSupportedOnDevice() {
+ return new UnsupportedOperationException("This method can only be used on Ravenwood");
}
/**
@@ -47,15 +56,11 @@ public final class RavenwoodEnvironment {
*
* No-op if called on the device side.
*/
+ @RavenwoodReplace
public static void ensureRavenwoodInitialized() {
}
- private static void ensureRavenwoodInitialized$ravenwood() {
- getInstance(); // This is enough to initialize the environment.
- }
-
- /** Initialize the ravenwood environment */
- private static native void ensureRavenwoodInitializedInternal();
+ private static native void ensureRavenwoodInitialized$ravenwood();
/**
* USE IT SPARINGLY! Returns true if it's running on Ravenwood, hostside test environment.
@@ -69,7 +74,7 @@ public final class RavenwoodEnvironment {
* <p>If someone needs it without having access to the SDK, the following hack would work too.
* <code>System.getProperty("java.class.path").contains("ravenwood")</code>
*/
- @android.ravenwood.annotation.RavenwoodReplace
+ @RavenwoodReplace
public boolean isRunningOnRavenwood() {
return false;
}
@@ -79,16 +84,39 @@ public final class RavenwoodEnvironment {
}
/**
- * See {@link Workaround}. It's only usablke on Ravenwood.
+ * Get the object back from the address obtained from
+ * {@link dalvik.system.VMRuntime#addressOf(Object)}.
+ */
+ @RavenwoodReplace
+ public <T> T fromAddress(long address) {
+ throw notSupportedOnDevice();
+ }
+
+ private native <T> T fromAddress$ravenwood(long address);
+
+ /**
+ * See {@link Workaround}. It's only usable on Ravenwood.
*/
+ @RavenwoodReplace
public static Workaround workaround() {
- if (getInstance().isRunningOnRavenwood()) {
- return sWorkaround;
- }
- throw new IllegalStateException("Workaround can only be used on Ravenwood");
+ throw notSupportedOnDevice();
+ }
+
+ private static Workaround workaround$ravenwood() {
+ return sWorkaround;
}
/**
+ * @return the "ravenwood-runtime" directory.
+ */
+ @RavenwoodReplace
+ public String getRavenwoodRuntimePath() {
+ throw notSupportedOnDevice();
+ }
+
+ private native String getRavenwoodRuntimePath$ravenwood();
+
+ /**
* A set of APIs used to work around missing features on Ravenwood. Ideally, this class should
* be empty, and all its APIs should be able to be implemented properly.
*/
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index 52a9578466d8..0b801b96afaa 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -428,7 +428,7 @@ static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr)
return reinterpret_cast<jlong>(apk_assets->GetLoadedArsc()->GetStringPool());
}
-static jboolean NativeIsUpToDate(jlong ptr) {
+static jboolean NativeIsUpToDate(CRITICAL_JNI_PARAMS_COMMA jlong ptr) {
auto scoped_apk_assets = ScopedLock(ApkAssetsFromLong(ptr));
auto apk_assets = scoped_apk_assets->get();
return apk_assets->IsUpToDate() ? JNI_TRUE : JNI_FALSE;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 3d0ab4ef0981..7fe6731b7116 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -36,7 +36,6 @@
#include "android-base/stringprintf.h"
#include "android_content_res_ApkAssets.h"
#include "android_runtime/AndroidRuntime.h"
-#include "android_util_Binder.h"
#include "androidfw/Asset.h"
#include "androidfw/AssetManager.h"
#include "androidfw/AssetManager2.h"
@@ -104,6 +103,11 @@ static struct arraymap_offsets_t {
jmethodID put;
} gArrayMapOffsets;
+static struct parcel_file_descriptor_offsets_t {
+ jclass mClass;
+ jmethodID mAdoptFd;
+} gParcelFileDescriptorOffsets;
+
static jclass g_stringClass = nullptr;
// ----------------------------------------------------------------------------
@@ -244,7 +248,6 @@ static jstring NativeGetOverlayablesToString(JNIEnv* env, jclass /*clazz*/, jlon
return env->NewStringUTF(result.c_str());
}
-#ifdef __ANDROID__ // Layoutlib does not support parcel
static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset,
jlongArray out_offsets) {
off64_t start_offset, length;
@@ -269,22 +272,10 @@ static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> as
env->ReleasePrimitiveArrayCritical(out_offsets, offsets, 0);
- jobject file_desc = jniCreateFileDescriptor(env, fd);
- if (file_desc == nullptr) {
- close(fd);
- return nullptr;
- }
- return newParcelFileDescriptor(env, file_desc);
-}
-#else
-static jobject ReturnParcelFileDescriptor(JNIEnv* env, std::unique_ptr<Asset> asset,
- jlongArray out_offsets) {
- jniThrowException(env, "java/lang/UnsupportedOperationException",
- "Implement me");
- // never reached
- return nullptr;
+ return env->CallStaticObjectMethod(gParcelFileDescriptorOffsets.mClass,
+ gParcelFileDescriptorOffsets.mAdoptFd,
+ fd);
}
-#endif
static jint NativeGetGlobalAssetCount(JNIEnv* /*env*/, jobject /*clazz*/) {
return Asset::getGlobalCount();
@@ -1202,6 +1193,28 @@ static void NativeApplyStyle(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong the
env->ReleasePrimitiveArrayCritical(java_attrs, attrs, JNI_ABORT);
}
+// This version is compatible with standard JVMs, however slower without ART optimizations
+static void NativeApplyStyleWithArray(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
+ jint def_style_attr, jint def_style_resid,
+ jlong xml_parser_ptr, jintArray java_attrs,
+ jintArray java_values, jintArray java_indices) {
+ auto assetmanager = LockAndStartAssetManager(ptr);
+ Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
+ CHECK(theme->GetAssetManager() == &(*assetmanager));
+ (void) assetmanager;
+
+ ResXMLParser* xml_parser = reinterpret_cast<ResXMLParser*>(xml_parser_ptr);
+ ScopedIntCriticalArrayRW out_values(env, java_values);
+ ScopedIntCriticalArrayRW out_indices(env, java_indices);
+ ScopedIntCriticalArrayRO attrs(env, java_attrs);
+
+ ApplyStyle(theme, xml_parser, static_cast<uint32_t>(def_style_attr),
+ static_cast<uint32_t>(def_style_resid),
+ reinterpret_cast<const uint32_t*>(attrs.get()), attrs.size(),
+ reinterpret_cast<uint32_t*>(out_values.get()),
+ reinterpret_cast<uint32_t*>(out_indices.get()));
+}
+
static jboolean NativeResolveAttrs(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlong theme_ptr,
jint def_style_attr, jint def_style_resid, jintArray java_values,
jintArray java_attrs, jintArray out_java_values,
@@ -1581,6 +1594,7 @@ static const JNINativeMethod gAssetManagerMethods[] = {
// Style attribute related methods.
{"nativeAttributeResolutionStack", "(JJIII)[I", (void*)NativeAttributeResolutionStack},
{"nativeApplyStyle", "(JJIIJ[IJJ)V", (void*)NativeApplyStyle},
+ {"nativeApplyStyleWithArray", "(JJIIJ[I[I[I)V", (void*)NativeApplyStyleWithArray},
{"nativeResolveAttrs", "(JJII[I[I[I[I)Z", (void*)NativeResolveAttrs},
{"nativeRetrieveAttributes", "(JJ[I[I[I)Z", (void*)NativeRetrieveAttributes},
@@ -1666,6 +1680,11 @@ int register_android_content_AssetManager(JNIEnv* env) {
GetMethodIDOrDie(env, gArrayMapOffsets.classObject, "put",
"(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+ jclass pfdClass = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
+ gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, pfdClass);
+ gParcelFileDescriptorOffsets.mAdoptFd =
+ GetStaticMethodIDOrDie(env, pfdClass, "adoptFd", "(I)Landroid/os/ParcelFileDescriptor;");
+
return RegisterMethodsOrDie(env, "android/content/res/AssetManager", gAssetManagerMethods,
NELEM(gAssetManagerMethods));
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
index 1dd5e1ddd630..48bed7942cdf 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodContext.java
@@ -16,8 +16,13 @@
package android.platform.test.ravenwood;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
+
import android.content.ClipboardManager;
import android.content.Context;
+import android.content.res.AssetManager;
+import android.content.res.Resources;
+import android.content.res.Resources.Theme;
import android.hardware.ISerialManager;
import android.hardware.SerialManager;
import android.os.Handler;
@@ -31,11 +36,18 @@ import android.ravenwood.example.RedManager;
import android.util.ArrayMap;
import android.util.Singleton;
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.File;
+import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
public class RavenwoodContext extends RavenwoodBaseContext {
+ private static final String TAG = "Ravenwood";
+
+ private final Object mLock = new Object();
private final String mPackageName;
private final HandlerThread mMainThread;
@@ -44,15 +56,29 @@ public class RavenwoodContext extends RavenwoodBaseContext {
private final ArrayMap<Class<?>, String> mClassToName = new ArrayMap<>();
private final ArrayMap<String, Supplier<?>> mNameToFactory = new ArrayMap<>();
+ private final File mFilesDir;
+ private final File mCacheDir;
+ private final Supplier<Resources> mResourcesSupplier;
+
+ @GuardedBy("mLock")
+ private Resources mResources;
+
+ @GuardedBy("mLock")
+ private Resources.Theme mTheme;
+
private void registerService(Class<?> serviceClass, String serviceName,
Supplier<?> serviceSupplier) {
mClassToName.put(serviceClass, serviceName);
mNameToFactory.put(serviceName, serviceSupplier);
}
- public RavenwoodContext(String packageName, HandlerThread mainThread) {
+ public RavenwoodContext(String packageName, HandlerThread mainThread,
+ Supplier<Resources> resourcesSupplier) throws IOException {
mPackageName = packageName;
mMainThread = mainThread;
+ mResourcesSupplier = resourcesSupplier;
+ mFilesDir = createTempDir("files-dir");
+ mCacheDir = createTempDir("cache-dir");
// Services provided by a typical shipping device
registerService(ClipboardManager.class,
@@ -85,6 +111,11 @@ public class RavenwoodContext extends RavenwoodBaseContext {
}
}
+ void cleanUp() {
+ deleteDir(mFilesDir);
+ deleteDir(mCacheDir);
+ }
+
@Override
public String getSystemServiceName(Class<?> serviceClass) {
// TODO: pivot to using SystemServiceRegistry
@@ -150,6 +181,52 @@ public class RavenwoodContext extends RavenwoodBaseContext {
return Context.DEVICE_ID_DEFAULT;
}
+ @Override
+ public File getFilesDir() {
+ return mFilesDir;
+ }
+
+ @Override
+ public File getCacheDir() {
+ return mCacheDir;
+ }
+
+ @Override
+ public boolean deleteFile(String name) {
+ File f = new File(name);
+ return f.delete();
+ }
+
+ @Override
+ public Resources getResources() {
+ synchronized (mLock) {
+ if (mResources == null) {
+ mResources = mResourcesSupplier.get();
+ }
+ return mResources;
+ }
+ }
+
+ @Override
+ public AssetManager getAssets() {
+ return getResources().getAssets();
+ }
+
+ @Override
+ public Theme getTheme() {
+ synchronized (mLock) {
+ if (mTheme == null) {
+ mTheme = getResources().newTheme();
+ }
+ return mTheme;
+ }
+ }
+
+ @Override
+ public String getPackageResourcePath() {
+ return new File(RAVENWOOD_RESOURCE_APK).getAbsolutePath();
+ }
+
/**
* Wrap the given {@link Supplier} to become memoized.
*
@@ -175,4 +252,26 @@ public class RavenwoodContext extends RavenwoodBaseContext {
public interface ThrowingSupplier<T> {
T get() throws Exception;
}
+
+
+ static File createTempDir(String prefix) throws IOException {
+ // Create a temp file, delete it and recreate it as a directory.
+ final File dir = File.createTempFile(prefix + "-", "");
+ dir.delete();
+ dir.mkdirs();
+ return dir;
+ }
+
+ static void deleteDir(File dir) {
+ File[] children = dir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ if (child.isDirectory()) {
+ deleteDir(child);
+ } else {
+ child.delete();
+ }
+ }
+ }
+ }
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
index 4357f2b8660a..3ea4cb7fb69f 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java
@@ -16,16 +16,23 @@
package android.platform.test.ravenwood;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
+
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import android.app.ActivityManager;
import android.app.Instrumentation;
+import android.app.ResourcesManager;
+import android.content.res.Resources;
import android.os.Build;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.ServiceManager;
import android.util.Log;
+import android.view.DisplayAdjustments;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -42,6 +49,8 @@ import org.junit.runner.Description;
import org.junit.runner.RunWith;
import org.junit.runners.model.Statement;
+import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
@@ -55,6 +64,7 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
public class RavenwoodRuleImpl {
private static final String MAIN_THREAD_NAME = "RavenwoodMain";
@@ -89,7 +99,7 @@ public class RavenwoodRuleImpl {
sPendingUncaughtException.compareAndSet(null, throwable);
};
- public static void init(RavenwoodRule rule) {
+ public static void init(RavenwoodRule rule) throws IOException {
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
maybeThrowPendingUncaughtException(false);
Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
@@ -119,7 +129,28 @@ public class RavenwoodRuleImpl {
main = null;
}
- rule.mContext = new RavenwoodContext(rule.mPackageName, main);
+ // TODO This should be integrated into LoadedApk
+ final Supplier<Resources> resourcesSupplier = () -> {
+ final var resApkFile = new File(RAVENWOOD_RESOURCE_APK).getAbsoluteFile();
+ assertTrue(resApkFile.isFile());
+
+ final var res = resApkFile.getAbsolutePath();
+
+ final var emptyPaths = new String[0];
+
+ ResourcesManager.getInstance().initializeApplicationPaths(res, emptyPaths);
+
+ final var ret = ResourcesManager.getInstance().getResources(null, res,
+ emptyPaths, emptyPaths, emptyPaths,
+ emptyPaths, null, null,
+ new DisplayAdjustments().getCompatibilityInfo(),
+ RavenwoodRuleImpl.class.getClassLoader(), null);
+
+ assertNotNull(ret);
+ return ret;
+ };
+
+ rule.mContext = new RavenwoodContext(rule.mPackageName, main, resourcesSupplier);
rule.mInstrumentation = new Instrumentation();
rule.mInstrumentation.basicInit(rule.mContext);
InstrumentationRegistry.registerInstance(rule.mInstrumentation, Bundle.EMPTY);
@@ -145,6 +176,9 @@ public class RavenwoodRuleImpl {
InstrumentationRegistry.registerInstance(null, Bundle.EMPTY);
rule.mInstrumentation = null;
+ if (rule.mContext != null) {
+ ((RavenwoodContext) rule.mContext).cleanUp();
+ }
rule.mContext = null;
if (rule.mProvideMainThread) {
@@ -161,6 +195,8 @@ public class RavenwoodRuleImpl {
android.os.Binder.reset$ravenwood();
android.os.Process.reset$ravenwood();
+ ResourcesManager.setInstance(null); // Better structure needed.
+
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
maybeThrowPendingUncaughtException(true);
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index 825c91a1b6dc..19ee56ecee9e 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -36,6 +36,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -362,7 +363,7 @@ public class RavenwoodRule implements TestRule {
}
}
- private void commonPrologue(Statement base, Description description) {
+ private void commonPrologue(Statement base, Description description) throws IOException {
RavenwoodRuleImpl.logTestRunner("started", description);
RavenwoodRuleImpl.validate(base, description, ENABLE_OPTIONAL_VALIDATION);
RavenwoodRuleImpl.init(RavenwoodRule.this);
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 5f1b0c2c929f..ef8f5840f949 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -48,11 +48,13 @@ public class RavenwoodSystemProperties {
switch (key) {
case "gsm.version.baseband":
case "no.such.thing":
+ case "qemu.sf.lcd_density":
case "ro.bootloader":
case "ro.debuggable":
case "ro.hardware":
case "ro.hw_timeout_multiplier":
case "ro.odm.build.media_performance_class":
+ case "ro.sf.lcd_density":
case "ro.treble.enabled":
case "ro.vndk.version":
return true;
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
index 0238baa2dcbf..02153a757cd8 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/JvmWorkaround.java
@@ -38,7 +38,6 @@ public abstract class JvmWorkaround {
*/
public abstract void setFdInt(FileDescriptor fd, int fdInt);
-
/**
* Equivalent to Android's FileDescriptor.getInt$().
*/
@@ -49,6 +48,10 @@ public abstract class JvmWorkaround {
*/
public abstract void closeFd(FileDescriptor fd) throws IOException;
+ public abstract long addressOf(Object o);
+
+ public abstract <T> T fromAddress(long address);
+
/**
* Placeholder implementation for the host side.
*
@@ -75,5 +78,15 @@ public abstract class JvmWorkaround {
public void closeFd(FileDescriptor fd) {
throw calledOnHostside();
}
+
+ @Override
+ public long addressOf(Object o) {
+ throw calledOnHostside();
+ }
+
+ @Override
+ public <T> T fromAddress(long address) {
+ throw calledOnHostside();
+ }
}
}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
index a260147654cd..2323c65de5cf 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/OpenJdkWorkaround.java
@@ -18,8 +18,16 @@ package com.android.ravenwood.common;
import java.io.FileDescriptor;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.WeakHashMap;
class OpenJdkWorkaround extends JvmWorkaround {
+
+ // @GuardedBy("sAddressMap")
+ private static final Map<Object, Long> sAddressMap = new WeakHashMap<>();
+ // @GuardedBy("sAddressMap")
+ private static long sCurrentAddress = 1;
+
@Override
public void setFdInt(FileDescriptor fd, int fdInt) {
try {
@@ -60,4 +68,28 @@ class OpenJdkWorkaround extends JvmWorkaround {
+ " perhaps JRE has changed?", e);
}
}
+
+ @Override
+ public long addressOf(Object o) {
+ synchronized (sAddressMap) {
+ Long address = sAddressMap.get(o);
+ if (address == null) {
+ address = sCurrentAddress++;
+ sAddressMap.put(o, address);
+ }
+ return address;
+ }
+ }
+
+ @Override
+ public <T> T fromAddress(long address) {
+ synchronized (sAddressMap) {
+ for (var e : sAddressMap.entrySet()) {
+ if (e.getValue() == address) {
+ return (T) e.getKey();
+ }
+ }
+ }
+ return null;
+ }
}
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
index c8cc8d9fe273..129802378cd4 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -46,6 +46,8 @@ public class RavenwoodCommonUtils {
public static final String RAVENWOOD_SYSPROP = "ro.is_on_ravenwood";
+ public static final String RAVENWOOD_RESOURCE_APK = "ravenwood-res-apks/ravenwood-res.apk";
+
// @GuardedBy("sLock")
private static boolean sIntegrityChecked = false;
diff --git a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java
index b00cee02f611..706a055c9faf 100644
--- a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java
+++ b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java
@@ -19,6 +19,7 @@ import android.platform.test.ravenwood.RavenwoodSystemProperties;
import android.util.Log;
import com.android.internal.ravenwood.RavenwoodEnvironment;
+import com.android.ravenwood.common.JvmWorkaround;
import com.android.ravenwood.common.RavenwoodCommonUtils;
public class RavenwoodEnvironment_host {
@@ -35,7 +36,7 @@ public class RavenwoodEnvironment_host {
/**
* Called from {@link RavenwoodEnvironment#ensureRavenwoodInitialized()}.
*/
- public static void ensureRavenwoodInitializedInternal() {
+ public static void ensureRavenwoodInitialized() {
synchronized (sInitializeLock) {
if (sInitialized) {
return;
@@ -55,4 +56,18 @@ public class RavenwoodEnvironment_host {
sInitialized = true;
}
}
-} \ No newline at end of file
+
+ /**
+ * Called from {@link RavenwoodEnvironment#getRavenwoodRuntimePath()}.
+ */
+ public static String getRavenwoodRuntimePath(RavenwoodEnvironment env) {
+ return RavenwoodCommonUtils.getRavenwoodRuntimePath();
+ }
+
+ /**
+ * Called from {@link RavenwoodEnvironment#fromAddress(long)}.
+ */
+ public static <T> T fromAddress(RavenwoodEnvironment env, long address) {
+ return JvmWorkaround.getInstance().fromAddress(address);
+ }
+}
diff --git a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/runtimehelper/ClassLoadHook.java b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/runtimehelper/ClassLoadHook.java
index e198646d4e27..0f955e772445 100644
--- a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/runtimehelper/ClassLoadHook.java
+++ b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/runtimehelper/ClassLoadHook.java
@@ -151,6 +151,11 @@ public class ClassLoadHook {
*/
private static final Class<?>[] sLibandroidClasses = {
android.util.Log.class,
+ android.os.Parcel.class,
+ android.content.res.ApkAssets.class,
+ android.content.res.AssetManager.class,
+ android.content.res.StringBlock.class,
+ android.content.res.XmlBlock.class,
};
/**
diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
index ecaa8161ee46..7371d0a029b9 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java
@@ -19,7 +19,11 @@ import com.android.ravenwood.common.JvmWorkaround;
import com.android.ravenwood.common.RavenwoodRuntimeNative;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.AsynchronousCloseException;
/**
* OS class replacement used on Ravenwood. For now, we just implement APIs as we need them...
@@ -36,6 +40,11 @@ public final class Os {
return RavenwoodRuntimeNative.pipe2(flags);
}
+ /** Ravenwood version of the OS API. */
+ public static FileDescriptor[] pipe() throws ErrnoException {
+ return RavenwoodRuntimeNative.pipe2(0);
+ }
+
public static FileDescriptor dup(FileDescriptor fd) throws ErrnoException {
return RavenwoodRuntimeNative.dup(fd);
}
@@ -69,4 +78,19 @@ public final class Os {
public static FileDescriptor open(String path, int flags, int mode) throws ErrnoException {
return RavenwoodRuntimeNative.open(path, flags, mode);
}
+
+ /** Ravenwood version of the OS API. */
+ public static int pread(FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount,
+ long offset) throws ErrnoException, InterruptedIOException {
+ var channel = new FileInputStream(fd).getChannel();
+ var buf = ByteBuffer.wrap(bytes, byteOffset, byteCount);
+ try {
+ return channel.read(buf, offset);
+ } catch (AsynchronousCloseException e) {
+ throw new InterruptedIOException(e.getMessage());
+ } catch (IOException e) {
+ // Most likely EIO
+ throw new ErrnoException("pread", OsConstants.EIO, e);
+ }
+ }
}
diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
index 7d2b00d9420d..ed5a587cdccc 100644
--- a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
+++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java
@@ -19,6 +19,8 @@ package dalvik.system;
// The original is here:
// $ANDROID_BUILD_TOP/libcore/libart/src/main/java/dalvik/system/VMRuntime.java
+import com.android.ravenwood.common.JvmWorkaround;
+
import java.lang.reflect.Array;
public class VMRuntime {
@@ -42,4 +44,12 @@ public class VMRuntime {
public Object newUnpaddedArray(Class<?> componentType, int minLength) {
return Array.newInstance(componentType, minLength);
}
+
+ public Object newNonMovableArray(Class<?> componentType, int length) {
+ return Array.newInstance(componentType, length);
+ }
+
+ public long addressOf(Object obj) {
+ return JvmWorkaround.getInstance().addressOf(obj);
+ }
}
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 639ebab4515b..231179b53ce8 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -39,6 +39,7 @@ android.util.ContainerHelpers
android.util.DataUnit
android.util.DayOfMonthCursor
android.util.DebugUtils
+android.util.DisplayMetrics
android.util.Dumpable
android.util.DumpableContainer
android.util.EmptyArray
@@ -102,6 +103,7 @@ android.util.StringBuilderPrinter
android.util.TeeWriter
android.util.TimeUtils
android.util.TimingsTraceLog
+android.util.TypedValue
android.util.UtilConfig
android.util.Xml
@@ -193,6 +195,7 @@ android.content.ClipboardManager
android.content.ComponentName
android.content.ContentUris
android.content.ContentValues
+android.content.Context
android.content.ContextWrapper
android.content.Intent
android.content.IntentFilter
@@ -215,6 +218,23 @@ android.content.pm.ServiceInfo
android.content.pm.Signature
android.content.pm.UserInfo
+android.content.res.ApkAssets
+android.content.res.AssetFileDescriptor
+android.content.res.AssetManager
+android.content.res.AssetManager$Builder
+android.content.res.DrawableCache
+android.content.res.Element
+android.content.res.Resources
+android.content.res.Resources$Theme
+android.content.res.ResourceId
+android.content.res.ResourcesImpl
+android.content.res.ResourcesKey
+android.content.res.StringBlock
+android.content.res.TagCounter
+android.content.res.TypedArray
+android.content.res.Validator
+android.content.res.XmlBlock
+
android.database.AbstractCursor
android.database.CharArrayBuffer
android.database.ContentObservable
@@ -258,6 +278,10 @@ android.app.ActivityOptions
android.app.BroadcastOptions
android.app.ComponentOptions
android.app.Instrumentation
+android.app.LocaleConfig
+android.app.ResourcesManager
+android.app.ResourcesManager$UpdateHandler
+android.app.WindowConfiguration
android.metrics.LogMaker
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index 4012bdc5be62..3062863052d2 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -9,8 +9,11 @@ class :feature_flags keepclass
# Keep all sysprops generated code implementations
class :sysprops keepclass
+# Keep all resource R classes
+class :r keepclass
+
# To avoid VerifyError on nano proto files (b/324063814), we rename nano proto classes.
-# Note: The "rename" directive must use shashes (/) as a package name separator.
+# Note: The "rename" directive must use slashes (/) as a package name separator.
rename com/.*/nano/ devicenano/
rename android/.*/nano/ devicenano/
@@ -62,3 +65,24 @@ class android.content.pm.PackageManager keep
method <init> ()V keep
class android.text.ClipboardManager keep
method <init> ()V keep
+
+# Just enough to allow ResourcesManager to run
+class android.hardware.display.DisplayManagerGlobal keep
+ method getInstance ()Landroid/hardware/display/DisplayManagerGlobal; ignore
+
+# These classes will be properly enabled in follow-up CLs
+
+class android.content.res.FontResourcesParser keepclass
+class android.content.res.FontResourcesParser.FamilyResourceEntry keepclass
+class android.content.res.FontResourcesParser.ProviderResourceEntry keepclass
+class android.content.res.FontResourcesParser.FontFamilyFilesResourceEntry keepclass
+class android.content.res.FontResourcesParser.FontFileResourceEntry keepclass
+class android.content.res.FontScaleConverter keepclass
+class android.content.res.FontScaleConverterImpl keepclass
+class android.content.res.FontScaleConverterFactory keepclass
+class android.content.res.ThemedResourceCache keepclass
+class android.content.res.ConfigurationBoundResourceCache keepclass
+class android.content.res.Configuration keepclass
+class android.content.res.CompatibilityInfo keepclass
+class android.content.res.ConstantState keepclass
+class android.view.DisplayAdjustments keepclass