diff options
13 files changed, 90 insertions, 778 deletions
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index 4bc3dbedeb94..97e9f34064ba 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -21,6 +21,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.AppOpsManager; import android.compat.annotation.UnsupportedAppUsage; +import android.ravenwood.annotation.RavenwoodClassLoadHook; +import android.ravenwood.annotation.RavenwoodKeepWholeClass; import android.util.ExceptionUtils; import android.util.Log; import android.util.Slog; @@ -30,11 +32,9 @@ import com.android.internal.os.BinderCallHeavyHitterWatcher; import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener; import com.android.internal.os.BinderInternal; import com.android.internal.os.BinderInternal.CallSession; -import com.android.internal.os.SomeArgs; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FunctionalUtils.ThrowingRunnable; import com.android.internal.util.FunctionalUtils.ThrowingSupplier; -import com.android.internal.util.Preconditions; import dalvik.annotation.optimization.CriticalNative; @@ -48,7 +48,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Modifier; import java.util.concurrent.atomic.AtomicReferenceArray; -import java.util.function.Supplier; /** * Base class for a remotable object, the core part of a lightweight @@ -82,6 +81,8 @@ import java.util.function.Supplier; * * @see IBinder */ +@RavenwoodKeepWholeClass +@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK) public class Binder implements IBinder { /* * Set this flag to true to detect anonymous, local or member classes @@ -292,33 +293,6 @@ public class Binder implements IBinder { sWarnOnBlockingOnCurrentThread.set(sWarnOnBlocking); } - private static volatile ThreadLocal<SomeArgs> sIdentity$ravenwood; - - @android.ravenwood.annotation.RavenwoodKeepWholeClass - private static class IdentitySupplier implements Supplier<SomeArgs> { - @Override - public SomeArgs get() { - final SomeArgs args = SomeArgs.obtain(); - // Match IPCThreadState behavior - args.arg1 = Boolean.FALSE; - args.argi1 = android.os.Process.myUid(); - args.argi2 = android.os.Process.myPid(); - return args; - } - } - - /** @hide */ - @android.ravenwood.annotation.RavenwoodKeep - public static void init$ravenwood() { - sIdentity$ravenwood = ThreadLocal.withInitial(new IdentitySupplier()); - } - - /** @hide */ - @android.ravenwood.annotation.RavenwoodKeep - public static void reset$ravenwood() { - sIdentity$ravenwood = null; - } - /** * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null. */ @@ -346,14 +320,8 @@ public class Binder implements IBinder { * 0 for a synchronous call. */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace public static final native int getCallingPid(); - /** @hide */ - public static final int getCallingPid$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi2; - } - /** * Return the Linux UID assigned to the process that sent you the * current transaction that is being processed. This UID can be used with @@ -362,14 +330,8 @@ public class Binder implements IBinder { * incoming transaction, then its own UID is returned. */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace public static final native int getCallingUid(); - /** @hide */ - public static final int getCallingUid$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi1; - } - /** * Returns {@code true} if the current thread is currently executing an * incoming transaction. @@ -377,21 +339,13 @@ public class Binder implements IBinder { * @hide */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace public static final native boolean isDirectlyHandlingTransactionNative(); - /** @hide */ - public static final boolean isDirectlyHandlingTransactionNative$ravenwood() { - // Ravenwood doesn't support IPC - return false; - } - private static boolean sIsHandlingBinderTransaction = false; /** * @hide */ - @android.ravenwood.annotation.RavenwoodKeep public static final boolean isDirectlyHandlingTransaction() { return sIsHandlingBinderTransaction || isDirectlyHandlingTransactionNative(); } @@ -400,7 +354,6 @@ public class Binder implements IBinder { * This is Test API which will be used to override output of isDirectlyHandlingTransactionNative * @hide */ - @android.ravenwood.annotation.RavenwoodKeep public static void setIsDirectlyHandlingTransactionOverride(boolean isInTransaction) { sIsHandlingBinderTransaction = isInTransaction; } @@ -412,15 +365,8 @@ public class Binder implements IBinder { * @hide */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace private static native boolean hasExplicitIdentity(); - /** @hide */ - private static boolean hasExplicitIdentity$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().arg1 - == Boolean.TRUE; - } - /** * Return the Linux UID assigned to the process that sent the transaction * currently being processed. @@ -429,7 +375,6 @@ public class Binder implements IBinder { * executing an incoming transaction and the calling identity has not been * explicitly set with {@link #clearCallingIdentity()} */ - @android.ravenwood.annotation.RavenwoodKeep public static final int getCallingUidOrThrow() { if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) { throw new IllegalStateException( @@ -491,26 +436,8 @@ public class Binder implements IBinder { * @see #restoreCallingIdentity(long) */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace public static final native long clearCallingIdentity(); - /** @hide */ - public static final long clearCallingIdentity$ravenwood() { - final SomeArgs args = Preconditions.requireNonNullViaRavenwoodRule( - sIdentity$ravenwood).get(); - long res = ((long) args.argi1 << 32) | args.argi2; - if (args.arg1 == Boolean.TRUE) { - res |= (0x1 << 30); - } else { - res &= ~(0x1 << 30); - } - // Match IPCThreadState behavior - args.arg1 = Boolean.TRUE; - args.argi1 = android.os.Process.myUid(); - args.argi2 = android.os.Process.myPid(); - return res; - } - /** * Restore the identity of the incoming IPC on the current thread * back to a previously identity that was returned by {@link @@ -522,18 +449,8 @@ public class Binder implements IBinder { * @see #clearCallingIdentity */ @CriticalNative - @android.ravenwood.annotation.RavenwoodReplace public static final native void restoreCallingIdentity(long token); - /** @hide */ - public static final void restoreCallingIdentity$ravenwood(long token) { - final SomeArgs args = Preconditions.requireNonNullViaRavenwoodRule( - sIdentity$ravenwood).get(); - args.arg1 = ((token & (0x1 << 30)) != 0) ? Boolean.TRUE : Boolean.FALSE; - args.argi1 = (int) (token >> 32); - args.argi2 = (int) (token & ~(0x1 << 30)); - } - /** * Convenience method for running the provided action enclosed in * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity}. @@ -708,16 +625,9 @@ public class Binder implements IBinder { * * @hide */ - @android.ravenwood.annotation.RavenwoodReplace @SystemApi(client = SystemApi.Client.PRIVILEGED_APPS) public final native void markVintfStability(); - /** @hide */ - private void markVintfStability$ravenwood() { - // This is not useful for Ravenwood which uses local binder. - // TODO(b/361785059): Use real native libbinder. - } - /** * Use a VINTF-stability binder w/o VINTF requirements. Should be called * on a binder before it is sent out of process. @@ -736,14 +646,8 @@ public class Binder implements IBinder { * in order to prevent the process from holding on to objects longer than * it needs to. */ - @android.ravenwood.annotation.RavenwoodReplace public static final native void flushPendingCommands(); - /** @hide */ - public static final void flushPendingCommands$ravenwood() { - // Ravenwood doesn't support IPC; ignored - } - /** * Add the calling thread to the IPC thread pool. This function does * not return until the current process is exiting. @@ -801,7 +705,6 @@ public class Binder implements IBinder { * <p>If you're creating a Binder token (a Binder object without an attached interface), * you should use {@link #Binder(String)} instead. */ - @android.ravenwood.annotation.RavenwoodKeep public Binder() { this(null); } @@ -818,12 +721,9 @@ public class Binder implements IBinder { * Instead of creating multiple tokens with the same descriptor, consider adding a suffix to * help identify them. */ - @android.ravenwood.annotation.RavenwoodKeep public Binder(@Nullable String descriptor) { mObject = getNativeBBinderHolder(); - if (mObject != 0L) { - NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject); - } + NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject); if (FIND_POTENTIAL_LEAKS) { final Class<? extends Binder> klass = getClass(); @@ -842,7 +742,6 @@ public class Binder implements IBinder { * will be implemented for you to return the given owner IInterface when * the corresponding descriptor is requested. */ - @android.ravenwood.annotation.RavenwoodKeep public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) { mOwner = owner; mDescriptor = descriptor; @@ -851,7 +750,6 @@ public class Binder implements IBinder { /** * Default implementation returns an empty interface name. */ - @android.ravenwood.annotation.RavenwoodKeep public @Nullable String getInterfaceDescriptor() { return mDescriptor; } @@ -860,7 +758,6 @@ public class Binder implements IBinder { * Default implementation always returns true -- if you got here, * the object is alive. */ - @android.ravenwood.annotation.RavenwoodKeep public boolean pingBinder() { return true; } @@ -871,7 +768,6 @@ public class Binder implements IBinder { * Note that if you're calling on a local binder, this always returns true * because your process is alive if you're calling it. */ - @android.ravenwood.annotation.RavenwoodKeep public boolean isBinderAlive() { return true; } @@ -881,7 +777,6 @@ public class Binder implements IBinder { * to return the associated {@link IInterface} if it matches the requested * descriptor. */ - @android.ravenwood.annotation.RavenwoodKeep public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) { if (mDescriptor != null && mDescriptor.equals(descriptor)) { return mOwner; @@ -1080,7 +975,6 @@ public class Binder implements IBinder { * * @hide */ - @android.ravenwood.annotation.RavenwoodKeep public @Nullable String getTransactionName(int transactionCode) { return null; } @@ -1089,7 +983,6 @@ public class Binder implements IBinder { * @hide */ @VisibleForTesting - @android.ravenwood.annotation.RavenwoodKeep public final @Nullable String getTransactionTraceName(int transactionCode) { final boolean isInterfaceUserDefined = getMaxTransactionId() == 0; if (mTransactionTraceNames == null) { @@ -1127,7 +1020,6 @@ public class Binder implements IBinder { return transactionTraceName; } - @android.ravenwood.annotation.RavenwoodKeep private @NonNull String getSimpleDescriptor() { String descriptor = mDescriptor; if (descriptor == null) { @@ -1147,7 +1039,6 @@ public class Binder implements IBinder { * @return The highest user-defined transaction id of all transactions. * @hide */ - @android.ravenwood.annotation.RavenwoodKeep public int getMaxTransactionId() { return 0; } @@ -1359,14 +1250,12 @@ public class Binder implements IBinder { /** * Local implementation is a no-op. */ - @android.ravenwood.annotation.RavenwoodKeep public void linkToDeath(@NonNull DeathRecipient recipient, int flags) { } /** * Local implementation is a no-op. */ - @android.ravenwood.annotation.RavenwoodKeep public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) { return true; } @@ -1394,13 +1283,8 @@ public class Binder implements IBinder { } } - @android.ravenwood.annotation.RavenwoodReplace private static native long getNativeBBinderHolder(); - private static long getNativeBBinderHolder$ravenwood() { - return 0L; - } - /** * By default, we use the calling UID since we can always trust it. */ diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java index 2ac2ae916e58..f7285523c01a 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -27,9 +27,8 @@ import android.annotation.SuppressLint; import android.annotation.TestApi; import android.app.AppOpsManager; import android.compat.annotation.UnsupportedAppUsage; +import android.ravenwood.annotation.RavenwoodClassLoadHook; import android.ravenwood.annotation.RavenwoodKeepWholeClass; -import android.ravenwood.annotation.RavenwoodRedirect; -import android.ravenwood.annotation.RavenwoodRedirectionClass; import android.ravenwood.annotation.RavenwoodReplace; import android.ravenwood.annotation.RavenwoodThrow; import android.text.TextUtils; @@ -234,7 +233,7 @@ import java.util.function.IntFunction; * {@link #readSparseArray(ClassLoader, Class)}. */ @RavenwoodKeepWholeClass -@RavenwoodRedirectionClass("Parcel_host") +@RavenwoodClassLoadHook(RavenwoodClassLoadHook.LIBANDROID_LOADING_HOOK) public final class Parcel { private static final boolean DEBUG_RECYCLE = false; @@ -387,148 +386,98 @@ public final class Parcel { private static final int SIZE_COMPLEX_TYPE = 1; @CriticalNative - @RavenwoodRedirect private static native void nativeMarkSensitive(long nativePtr); @FastNative - @RavenwoodThrow private static native void nativeMarkForBinder(long nativePtr, IBinder binder); @CriticalNative - @RavenwoodThrow private static native boolean nativeIsForRpc(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native int nativeDataSize(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native int nativeDataAvail(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native int nativeDataPosition(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native int nativeDataCapacity(long nativePtr); @FastNative - @RavenwoodRedirect private static native void nativeSetDataSize(long nativePtr, int size); @CriticalNative - @RavenwoodRedirect private static native void nativeSetDataPosition(long nativePtr, int pos); @FastNative - @RavenwoodRedirect private static native void nativeSetDataCapacity(long nativePtr, int size); @CriticalNative - @RavenwoodRedirect private static native boolean nativePushAllowFds(long nativePtr, boolean allowFds); @CriticalNative - @RavenwoodRedirect private static native void nativeRestoreAllowFds(long nativePtr, boolean lastValue); - @RavenwoodRedirect private static native void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len); - @RavenwoodRedirect private static native void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len); @CriticalNative - @RavenwoodRedirect private static native int nativeWriteInt(long nativePtr, int val); @CriticalNative - @RavenwoodRedirect private static native int nativeWriteLong(long nativePtr, long val); @CriticalNative - @RavenwoodRedirect private static native int nativeWriteFloat(long nativePtr, float val); @CriticalNative - @RavenwoodRedirect private static native int nativeWriteDouble(long nativePtr, double val); - @RavenwoodThrow private static native void nativeSignalExceptionForError(int error); @FastNative - @RavenwoodRedirect private static native void nativeWriteString8(long nativePtr, String val); @FastNative - @RavenwoodRedirect private static native void nativeWriteString16(long nativePtr, String val); @FastNative - @RavenwoodThrow private static native void nativeWriteStrongBinder(long nativePtr, IBinder val); @FastNative - @RavenwoodRedirect private static native void nativeWriteFileDescriptor(long nativePtr, FileDescriptor val); - @RavenwoodRedirect private static native byte[] nativeCreateByteArray(long nativePtr); - @RavenwoodRedirect private static native boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen); - @RavenwoodRedirect private static native byte[] nativeReadBlob(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native int nativeReadInt(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native long nativeReadLong(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native float nativeReadFloat(long nativePtr); @CriticalNative - @RavenwoodRedirect private static native double nativeReadDouble(long nativePtr); @FastNative - @RavenwoodRedirect private static native String nativeReadString8(long nativePtr); @FastNative - @RavenwoodRedirect private static native String nativeReadString16(long nativePtr); @FastNative - @RavenwoodThrow private static native IBinder nativeReadStrongBinder(long nativePtr); @FastNative - @RavenwoodRedirect private static native FileDescriptor nativeReadFileDescriptor(long nativePtr); - @RavenwoodRedirect private static native long nativeCreate(); - @RavenwoodRedirect private static native void nativeFreeBuffer(long nativePtr); - @RavenwoodRedirect private static native void nativeDestroy(long nativePtr); - @RavenwoodRedirect private static native byte[] nativeMarshall(long nativePtr); - @RavenwoodRedirect private static native void nativeUnmarshall( long nativePtr, byte[] data, int offset, int length); - @RavenwoodRedirect private static native int nativeCompareData(long thisNativePtr, long otherNativePtr); - @RavenwoodRedirect private static native boolean nativeCompareDataInRange( long ptrA, int offsetA, long ptrB, int offsetB, int length); - @RavenwoodRedirect private static native void nativeAppendFrom( long thisNativePtr, long otherNativePtr, int offset, int length); @CriticalNative - @RavenwoodRedirect private static native boolean nativeHasFileDescriptors(long nativePtr); - @RavenwoodRedirect private static native boolean nativeHasFileDescriptorsInRange( long nativePtr, int offset, int length); - @RavenwoodRedirect private static native boolean nativeHasBinders(long nativePtr); - @RavenwoodRedirect private static native boolean nativeHasBindersInRange( long nativePtr, int offset, int length); - @RavenwoodThrow private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName); - @RavenwoodThrow private static native void nativeEnforceInterface(long nativePtr, String interfaceName); @CriticalNative - @RavenwoodThrow private static native boolean nativeReplaceCallingWorkSourceUid( long nativePtr, int workSourceUid); @CriticalNative - @RavenwoodThrow private static native int nativeReadCallingWorkSourceUid(long nativePtr); /** Last time exception with a stack trace was written */ @@ -537,7 +486,6 @@ public final class Parcel { private static final int WRITE_EXCEPTION_STACK_TRACE_THRESHOLD_MS = 1000; @CriticalNative - @RavenwoodThrow private static native long nativeGetOpenAshmemSize(long nativePtr); public final static Parcelable.Creator<String> STRING_CREATOR @@ -701,12 +649,10 @@ public final class Parcel { /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @RavenwoodThrow public static native long getGlobalAllocSize(); /** @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @RavenwoodThrow public static native long getGlobalAllocCount(); /** @@ -1298,6 +1244,7 @@ public final class Parcel { * @hide */ @UnsupportedAppUsage + @RavenwoodThrow(blockedBy = android.text.Spanned.class) public final void writeCharSequence(@Nullable CharSequence val) { TextUtils.writeToParcel(val, this, 0); } @@ -3037,7 +2984,7 @@ public final class Parcel { * @see #writeNoException * @see #readException */ - @RavenwoodReplace + @RavenwoodReplace(blockedBy = AppOpsManager.class) public final void writeException(@NonNull Exception e) { AppOpsManager.prefixParcelWithAppOpsIfNeeded(this); @@ -3076,10 +3023,15 @@ public final class Parcel { } } - /** @hide */ - public final void writeException$ravenwood(@NonNull Exception e) { - // Ravenwood doesn't support IPC, no transaction headers needed - writeInt(getExceptionCode(e)); + private void writeException$ravenwood(@NonNull Exception e) { + int code = getExceptionCode(e); + writeInt(code); + if (code == 0) { + if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw new RuntimeException(e); + } writeString(e.getMessage()); writeInt(0); } @@ -3137,7 +3089,7 @@ public final class Parcel { * @see #writeException * @see #readException */ - @RavenwoodReplace + @RavenwoodReplace(blockedBy = AppOpsManager.class) public final void writeNoException() { AppOpsManager.prefixParcelWithAppOpsIfNeeded(this); @@ -3168,9 +3120,7 @@ public final class Parcel { } } - /** @hide */ - public final void writeNoException$ravenwood() { - // Ravenwood doesn't support IPC, no transaction headers needed + private void writeNoException$ravenwood() { writeInt(0); } diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 50b73a9d3f66..81dc46ecbd3a 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -2605,10 +2605,15 @@ public final class StrictMode { * (Java) thread-local policy value. */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) + @android.ravenwood.annotation.RavenwoodReplace private static void onBinderStrictModePolicyChange(@ThreadPolicyMask int newPolicy) { setBlockGuardPolicy(newPolicy); } + private static void onBinderStrictModePolicyChange$ravenwood(@ThreadPolicyMask int newPolicy) { + /* no-op */ + } + /** * A tracked, critical time span. (e.g. during an animation.) * diff --git a/core/java/android/util/Slog.java b/core/java/android/util/Slog.java index 9ecb4cbb283d..b2017a5fa868 100644 --- a/core/java/android/util/Slog.java +++ b/core/java/android/util/Slog.java @@ -224,7 +224,6 @@ public final class Slog { /** * Similar to {@link #wtf(String, String)}, but does not output anything to the log. */ - @android.ravenwood.annotation.RavenwoodThrow public static void wtfQuiet(@Nullable String tag, @NonNull String msg) { Log.wtfQuiet(Log.LOG_ID_SYSTEM, tag, msg, true); } @@ -243,7 +242,6 @@ public final class Slog { * @see Log#wtfStack(String, String) */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - @android.ravenwood.annotation.RavenwoodThrow public static int wtfStack(@Nullable String tag, @NonNull String msg) { return Log.wtf(Log.LOG_ID_SYSTEM, tag, msg, null, true, true); } diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp index 584ebaa221fc..dec724b6a7ff 100644 --- a/core/jni/android_os_Parcel.cpp +++ b/core/jni/android_os_Parcel.cpp @@ -90,7 +90,7 @@ void recycleJavaParcelObject(JNIEnv* env, jobject parcelObj) env->CallVoidMethod(parcelObj, gParcelOffsets.recycle); } -static void android_os_Parcel_markSensitive(jlong nativePtr) +static void android_os_Parcel_markSensitive(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel) { @@ -116,30 +116,30 @@ static void android_os_Parcel_markForBinder(JNIEnv* env, jclass clazz, jlong nat } } -static jboolean android_os_Parcel_isForRpc(jlong nativePtr) { +static jboolean android_os_Parcel_isForRpc(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->isForRpc() : false; } -static jint android_os_Parcel_dataSize(jlong nativePtr) +static jint android_os_Parcel_dataSize(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataSize() : 0; } -static jint android_os_Parcel_dataAvail(jlong nativePtr) +static jint android_os_Parcel_dataAvail(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataAvail() : 0; } -static jint android_os_Parcel_dataPosition(jlong nativePtr) +static jint android_os_Parcel_dataPosition(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataPosition() : 0; } -static jint android_os_Parcel_dataCapacity(jlong nativePtr) +static jint android_os_Parcel_dataCapacity(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return parcel ? parcel->dataCapacity() : 0; @@ -156,7 +156,7 @@ static void android_os_Parcel_setDataSize(JNIEnv* env, jclass clazz, jlong nativ } } -static void android_os_Parcel_setDataPosition(jlong nativePtr, jint pos) +static void android_os_Parcel_setDataPosition(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr, jint pos) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -175,7 +175,8 @@ static void android_os_Parcel_setDataCapacity(JNIEnv* env, jclass clazz, jlong n } } -static jboolean android_os_Parcel_pushAllowFds(jlong nativePtr, jboolean allowFds) +static jboolean android_os_Parcel_pushAllowFds(CRITICAL_JNI_PARAMS_COMMA + jlong nativePtr, jboolean allowFds) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); jboolean ret = JNI_TRUE; @@ -185,7 +186,8 @@ static jboolean android_os_Parcel_pushAllowFds(jlong nativePtr, jboolean allowFd return ret; } -static void android_os_Parcel_restoreAllowFds(jlong nativePtr, jboolean lastValue) +static void android_os_Parcel_restoreAllowFds(CRITICAL_JNI_PARAMS_COMMA + jlong nativePtr, jboolean lastValue) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -259,22 +261,22 @@ static void android_os_Parcel_writeBlob(JNIEnv* env, jclass clazz, jlong nativeP blob.release(); } -static int android_os_Parcel_writeInt(jlong nativePtr, jint val) { +static int android_os_Parcel_writeInt(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr, jint val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return (parcel != NULL) ? parcel->writeInt32(val) : OK; } -static int android_os_Parcel_writeLong(jlong nativePtr, jlong val) { +static int android_os_Parcel_writeLong(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr, jlong val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return (parcel != NULL) ? parcel->writeInt64(val) : OK; } -static int android_os_Parcel_writeFloat(jlong nativePtr, jfloat val) { +static int android_os_Parcel_writeFloat(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr, jfloat val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return (parcel != NULL) ? parcel->writeFloat(val) : OK; } -static int android_os_Parcel_writeDouble(jlong nativePtr, jdouble val) { +static int android_os_Parcel_writeDouble(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr, jdouble val) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); return (parcel != NULL) ? parcel->writeDouble(val) : OK; } @@ -446,7 +448,7 @@ static jbyteArray android_os_Parcel_readBlob(JNIEnv* env, jclass clazz, jlong na return ret; } -static jint android_os_Parcel_readInt(jlong nativePtr) +static jint android_os_Parcel_readInt(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -455,7 +457,7 @@ static jint android_os_Parcel_readInt(jlong nativePtr) return 0; } -static jlong android_os_Parcel_readLong(jlong nativePtr) +static jlong android_os_Parcel_readLong(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -464,7 +466,7 @@ static jlong android_os_Parcel_readLong(jlong nativePtr) return 0; } -static jfloat android_os_Parcel_readFloat(jlong nativePtr) +static jfloat android_os_Parcel_readFloat(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -473,7 +475,7 @@ static jfloat android_os_Parcel_readFloat(jlong nativePtr) return 0; } -static jdouble android_os_Parcel_readDouble(jlong nativePtr) +static jdouble android_os_Parcel_readDouble(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -690,7 +692,7 @@ static jboolean android_os_Parcel_hasBindersInRange(JNIEnv* env, jclass clazz, j return JNI_FALSE; } -static jboolean android_os_Parcel_hasFileDescriptors(jlong nativePtr) +static jboolean android_os_Parcel_hasFileDescriptors(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { jboolean ret = JNI_FALSE; Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); @@ -807,7 +809,7 @@ static jlong android_os_Parcel_getGlobalAllocCount(JNIEnv* env, jclass clazz) return Parcel::getGlobalAllocCount(); } -static jlong android_os_Parcel_getOpenAshmemSize(jlong nativePtr) +static jlong android_os_Parcel_getOpenAshmemSize(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -816,7 +818,7 @@ static jlong android_os_Parcel_getOpenAshmemSize(jlong nativePtr) return 0; } -static jint android_os_Parcel_readCallingWorkSourceUid(jlong nativePtr) +static jint android_os_Parcel_readCallingWorkSourceUid(CRITICAL_JNI_PARAMS_COMMA jlong nativePtr) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { @@ -825,7 +827,8 @@ static jint android_os_Parcel_readCallingWorkSourceUid(jlong nativePtr) return IPCThreadState::kUnsetWorkSource; } -static jboolean android_os_Parcel_replaceCallingWorkSourceUid(jlong nativePtr, jint uid) +static jboolean android_os_Parcel_replaceCallingWorkSourceUid(CRITICAL_JNI_PARAMS_COMMA + jlong nativePtr, jint uid) { Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr); if (parcel != NULL) { diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 921b77d61f4d..f2c70b5f41d4 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -1152,60 +1152,60 @@ void signalExceptionForError(JNIEnv* env, jobject obj, status_t err, // ---------------------------------------------------------------------------- -static jint android_os_Binder_getCallingPid() +static jint android_os_Binder_getCallingPid(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->getCallingPid(); } -static jint android_os_Binder_getCallingUid() +static jint android_os_Binder_getCallingUid(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->getCallingUid(); } -static jboolean android_os_Binder_isDirectlyHandlingTransactionNative() { +static jboolean android_os_Binder_isDirectlyHandlingTransactionNative(CRITICAL_JNI_PARAMS) { return getCurrentServingCall() == BinderCallType::BINDER; } -static jlong android_os_Binder_clearCallingIdentity() +static jlong android_os_Binder_clearCallingIdentity(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->clearCallingIdentity(); } -static void android_os_Binder_restoreCallingIdentity(jlong token) +static void android_os_Binder_restoreCallingIdentity(CRITICAL_JNI_PARAMS_COMMA jlong token) { IPCThreadState::self()->restoreCallingIdentity(token); } -static jboolean android_os_Binder_hasExplicitIdentity() { +static jboolean android_os_Binder_hasExplicitIdentity(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->hasExplicitIdentity(); } -static void android_os_Binder_setThreadStrictModePolicy(jint policyMask) +static void android_os_Binder_setThreadStrictModePolicy(CRITICAL_JNI_PARAMS_COMMA jint policyMask) { IPCThreadState::self()->setStrictModePolicy(policyMask); } -static jint android_os_Binder_getThreadStrictModePolicy() +static jint android_os_Binder_getThreadStrictModePolicy(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->getStrictModePolicy(); } -static jlong android_os_Binder_setCallingWorkSourceUid(jint workSource) +static jlong android_os_Binder_setCallingWorkSourceUid(CRITICAL_JNI_PARAMS_COMMA jint workSource) { return IPCThreadState::self()->setCallingWorkSourceUid(workSource); } -static jlong android_os_Binder_getCallingWorkSourceUid() +static jlong android_os_Binder_getCallingWorkSourceUid(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->getCallingWorkSourceUid(); } -static jlong android_os_Binder_clearCallingWorkSource() +static jlong android_os_Binder_clearCallingWorkSource(CRITICAL_JNI_PARAMS) { return IPCThreadState::self()->clearCallingWorkSource(); } -static void android_os_Binder_restoreCallingWorkSource(jlong token) +static void android_os_Binder_restoreCallingWorkSource(CRITICAL_JNI_PARAMS_COMMA jlong token) { IPCThreadState::self()->restoreCallingWorkSource(token); } diff --git a/core/tests/coretests/src/android/os/BinderTest.java b/core/tests/coretests/src/android/os/BinderTest.java index 9767d677807d..90ec93e46418 100644 --- a/core/tests/coretests/src/android/os/BinderTest.java +++ b/core/tests/coretests/src/android/os/BinderTest.java @@ -24,18 +24,16 @@ import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyInt; import static org.testng.Assert.assertThrows; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import androidx.test.filters.SmallTest; import com.android.internal.os.BinderInternal; - import org.junit.Rule; import org.junit.Test; -@IgnoreUnderRavenwood(blockedBy = WorkSource.class) public class BinderTest { private static final int UID = 100; @@ -89,6 +87,7 @@ public class BinderTest { @SmallTest @Test(expected = java.lang.SecurityException.class) + @DisabledOnRavenwood(blockedBy = ServiceManagerNative.class) public void testServiceManagerNativeSecurityException() throws RemoteException { // Find the service manager IServiceManager sServiceManager = ServiceManagerNative @@ -101,6 +100,7 @@ public class BinderTest { @SmallTest @Test(expected = java.lang.NullPointerException.class) + @DisabledOnRavenwood(blockedBy = ServiceManagerNative.class) public void testServiceManagerNativeNullptrException() throws RemoteException { // Find the service manager IServiceManager sServiceManager = ServiceManagerNative diff --git a/core/tests/coretests/src/android/os/BundleTest.java b/core/tests/coretests/src/android/os/BundleTest.java index ded6fc5de2e5..31e07524d777 100644 --- a/core/tests/coretests/src/android/os/BundleTest.java +++ b/core/tests/coretests/src/android/os/BundleTest.java @@ -25,7 +25,6 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import android.platform.test.annotations.DisabledOnRavenwood; -import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -131,7 +130,6 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = ParcelFileDescriptor.class) public void testCreateFromParcel() throws Exception { boolean withFd; Parcel p; @@ -312,7 +310,7 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) + @DisabledOnRavenwood(reason = "Ravenwood tests run on the BCP") public void kindofEquals_lazyValuesAndDifferentClassLoaders_returnsFalse() { Parcelable p1 = new CustomParcelable(13, "Tiramisu"); Parcelable p2 = new CustomParcelable(13, "Tiramisu"); @@ -368,7 +366,6 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void readWriteLengthMismatch_logsWtf() throws Exception { mWtfHandler = Log.setWtfHandler((tag, e, system) -> { throw new RuntimeException(e); @@ -383,7 +380,7 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) + @DisabledOnRavenwood(reason = "Ravenwood tests run on the BCP") public void getParcelable_whenThrowingAndNotDefusing_throws() throws Exception { Bundle.setShouldDefuse(false); Bundle bundle = new Bundle(); @@ -396,7 +393,7 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) + @DisabledOnRavenwood(reason = "Ravenwood tests run on the BCP") public void getParcelable_whenThrowingAndDefusing_returnsNull() throws Exception { Bundle.setShouldDefuse(true); Bundle bundle = new Bundle(); @@ -412,7 +409,7 @@ public class BundleTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) + @DisabledOnRavenwood(reason = "Ravenwood tests run on the BCP") public void getParcelable_whenThrowingAndDefusing_leavesElement() throws Exception { Bundle.setShouldDefuse(true); Bundle bundle = new Bundle(); @@ -447,7 +444,6 @@ public class BundleTest { } @Test - @DisabledOnRavenwood(blockedBy = Parcel.class) public void parcelledBundleWithBinder_shouldReturnHasBindersTrue() throws Exception { Bundle bundle = new Bundle(); bundle.putParcelable("test", new CustomParcelable(13, "Tiramisu")); @@ -470,7 +466,6 @@ public class BundleTest { } @Test - @DisabledOnRavenwood(blockedBy = Parcel.class) public void parcelledBundleWithoutBinder_shouldReturnHasBindersFalse() throws Exception { Bundle bundle = new Bundle(); bundle.putParcelable("test", new CustomParcelable(13, "Tiramisu")); diff --git a/core/tests/coretests/src/android/os/ParcelNullabilityTest.java b/core/tests/coretests/src/android/os/ParcelNullabilityTest.java index 09395f15a57b..96316c436d61 100644 --- a/core/tests/coretests/src/android/os/ParcelNullabilityTest.java +++ b/core/tests/coretests/src/android/os/ParcelNullabilityTest.java @@ -20,7 +20,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import android.platform.test.annotations.IgnoreUnderRavenwood; +import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; import android.util.ArrayMap; @@ -67,7 +67,7 @@ public final class ParcelNullabilityTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) + @DisabledOnRavenwood(blockedBy = android.text.Spanned.class) public void nullCharSequence() { Parcel p = Parcel.obtain(); p.writeCharSequence(null); @@ -76,7 +76,6 @@ public final class ParcelNullabilityTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void nullStrongBinder() { Parcel p = Parcel.obtain(); p.writeStrongBinder(null); @@ -85,7 +84,6 @@ public final class ParcelNullabilityTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void nullStringInterface() { Parcel p = Parcel.obtain(); p.writeStrongInterface(null); diff --git a/core/tests/coretests/src/android/os/ParcelTest.java b/core/tests/coretests/src/android/os/ParcelTest.java index 037323111e9f..da9d687ee2b0 100644 --- a/core/tests/coretests/src/android/os/ParcelTest.java +++ b/core/tests/coretests/src/android/os/ParcelTest.java @@ -23,7 +23,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import android.platform.test.annotations.IgnoreUnderRavenwood; import android.platform.test.annotations.Presubmit; import android.platform.test.ravenwood.RavenwoodRule; import android.util.Log; @@ -48,7 +47,6 @@ public class ParcelTest { private static final String INTERFACE_TOKEN_2 = "Another IBinder interface token"; @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testIsForRpc() { Parcel p = Parcel.obtain(); assertEquals(false, p.isForRpc()); @@ -56,7 +54,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testCallingWorkSourceUidAfterWrite() { Parcel p = Parcel.obtain(); // Method does not throw if replaceCallingWorkSourceUid is called before requests headers @@ -77,7 +74,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testCallingWorkSourceUidAfterEnforce() { Parcel p = Parcel.obtain(); p.writeInterfaceToken(INTERFACE_TOKEN_1); @@ -95,7 +91,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testParcelWithMultipleHeaders() { Parcel p = Parcel.obtain(); Binder.setCallingWorkSourceUid(WORK_SOURCE_1); @@ -153,7 +148,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testCompareDataInRange_whenSameDataWithBinder() { Binder binder = new Binder(); Parcel pA = Parcel.obtain(); @@ -313,7 +307,6 @@ public class ParcelTest { * and 1M length for complex objects are allowed. */ @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testAllocations_whenWithinLimit() { Binder.setIsDirectlyHandlingTransactionOverride(true); Parcel p = Parcel.obtain(); @@ -398,7 +391,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testHasBinders_AfterWritingBinderToParcel() { Binder binder = new Binder(); Parcel pA = Parcel.obtain(); @@ -410,7 +402,6 @@ public class ParcelTest { } @Test - @IgnoreUnderRavenwood(blockedBy = Parcel.class) public void testHasBindersInRange_AfterWritingBinderToParcel() { Binder binder = new Binder(); Parcel pA = Parcel.obtain(); 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 0059360a0a29..c4336762c0b8 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java @@ -26,6 +26,7 @@ import android.app.ActivityManager; import android.app.Instrumentation; import android.app.ResourcesManager; import android.content.res.Resources; +import android.os.Binder; import android.os.Build; import android.os.Bundle; import android.os.HandlerThread; @@ -67,6 +68,8 @@ public class RavenwoodRuleImpl { private static ScheduledFuture<?> sPendingTimeout; + private static long sOriginalIdentityToken = -1; + /** * When enabled, attempt to detect uncaught exceptions from background threads. */ @@ -85,6 +88,19 @@ public class RavenwoodRuleImpl { sPendingUncaughtException.compareAndSet(null, throwable); }; + // TODO: expose packCallingIdentity function in libbinder and use it directly + // See: packCallingIdentity in frameworks/native/libs/binder/IPCThreadState.cpp + private static long packBinderIdentityToken( + boolean hasExplicitIdentity, int callingUid, int callingPid) { + long res = ((long) callingUid << 32) | callingPid; + if (hasExplicitIdentity) { + res |= (0x1 << 30); + } else { + res &= ~(0x1 << 30); + } + return res; + } + public static void init(RavenwoodRule rule) throws IOException { if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) { maybeThrowPendingUncaughtException(false); @@ -92,7 +108,8 @@ public class RavenwoodRuleImpl { } android.os.Process.init$ravenwood(rule.mUid, rule.mPid); - android.os.Binder.init$ravenwood(); + sOriginalIdentityToken = Binder.clearCallingIdentity(); + Binder.restoreCallingIdentity(packBinderIdentityToken(false, rule.mUid, rule.mPid)); setSystemProperties(rule.mSystemProperties); ServiceManager.init$ravenwood(); @@ -173,7 +190,7 @@ public class RavenwoodRuleImpl { ServiceManager.reset$ravenwood(); setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES); - android.os.Binder.reset$ravenwood(); + Binder.restoreCallingIdentity(sOriginalIdentityToken); android.os.Process.reset$ravenwood(); ResourcesManager.setInstance(null); // Better structure needed. diff --git a/ravenwood/runtime-helper-src/framework/android/os/Parcel_host.java b/ravenwood/runtime-helper-src/framework/android/os/Parcel_host.java deleted file mode 100644 index 720f1d227326..000000000000 --- a/ravenwood/runtime-helper-src/framework/android/os/Parcel_host.java +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package android.os; - -import android.system.ErrnoException; -import android.system.Os; -import android.util.Log; - -import java.io.FileDescriptor; -import java.nio.ByteBuffer; -import java.nio.charset.StandardCharsets; -import java.util.Arrays; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicLong; - -/** - * Tentative, partial implementation of the Parcel native methods, using Java's - * {@code byte[]}. - * (We don't use a {@link ByteBuffer} because there's enough semantics differences between Parcel - * and {@link ByteBuffer}, and it didn't work out. - * e.g. Parcel seems to allow moving the data position to be beyond its size? Which - * {@link ByteBuffer} wouldn't allow...) - */ -public class Parcel_host { - private static final String TAG = "Parcel"; - - private Parcel_host() { - } - - private static final AtomicLong sNextId = new AtomicLong(1); - - private static final Map<Long, Parcel_host> sInstances = new ConcurrentHashMap<>(); - - private boolean mDeleted = false; - - private byte[] mBuffer; - private int mSize; - private int mPos; - - private boolean mSensitive; - private boolean mAllowFds; - - // TODO Use the actual value from Parcel.java. - private static final int OK = 0; - - private final Map<Integer, FileDescriptor> mFdMap = new ConcurrentHashMap<>(); - - private static final int FD_PLACEHOLDER = 0xDEADBEEF; - private static final int FD_PAYLOAD_SIZE = 8; - - private void validate() { - if (mDeleted) { - // TODO: Put more info - throw new RuntimeException("Parcel already destroyed"); - } - } - - private static Parcel_host getInstance(long id) { - Parcel_host p = sInstances.get(id); - if (p == null) { - // TODO: Put more info - throw new RuntimeException("Parcel doesn't exist with id=" + id); - } - p.validate(); - return p; - } - - /** Native method substitution */ - public static long nativeCreate() { - final long id = sNextId.getAndIncrement(); - final Parcel_host p = new Parcel_host(); - sInstances.put(id, p); - p.init(); - return id; - } - - private void init() { - mBuffer = new byte[0]; - mSize = 0; - mPos = 0; - mSensitive = false; - mAllowFds = true; - mFdMap.clear(); - } - - private void updateSize() { - if (mSize < mPos) { - mSize = mPos; - } - } - - /** Native method substitution */ - public static void nativeDestroy(long nativePtr) { - getInstance(nativePtr).mDeleted = true; - sInstances.remove(nativePtr); - } - - /** Native method substitution */ - public static void nativeFreeBuffer(long nativePtr) { - getInstance(nativePtr).freeBuffer(); - } - - /** Native method substitution */ - private void freeBuffer() { - init(); - } - - private int getCapacity() { - return mBuffer.length; - } - - private void ensureMoreCapacity(int size) { - ensureCapacity(mPos + size); - } - - private void ensureCapacity(int targetSize) { - if (targetSize <= getCapacity()) { - return; - } - var newSize = getCapacity() * 2; - if (newSize < targetSize) { - newSize = targetSize; - } - forceSetCapacity(newSize); - } - - private void forceSetCapacity(int newSize) { - var newBuf = new byte[newSize]; - - // Copy - System.arraycopy(mBuffer, 0, newBuf, 0, Math.min(newSize, getCapacity())); - - this.mBuffer = newBuf; - } - - private void ensureDataAvailable(int requestSize) { - if (mSize - mPos < requestSize) { - throw new RuntimeException(String.format( - "Pacel data underflow. size=%d, pos=%d, request=%d", mSize, mPos, requestSize)); - } - } - - /** Native method substitution */ - public static void nativeMarkSensitive(long nativePtr) { - getInstance(nativePtr).mSensitive = true; - } - - /** Native method substitution */ - public static int nativeDataSize(long nativePtr) { - return getInstance(nativePtr).mSize; - } - - /** Native method substitution */ - public static int nativeDataAvail(long nativePtr) { - var p = getInstance(nativePtr); - return p.mSize - p.mPos; - } - - /** Native method substitution */ - public static int nativeDataPosition(long nativePtr) { - return getInstance(nativePtr).mPos; - } - - /** Native method substitution */ - public static int nativeDataCapacity(long nativePtr) { - return getInstance(nativePtr).mBuffer.length; - } - - /** Native method substitution */ - public static void nativeSetDataSize(long nativePtr, int size) { - var p = getInstance(nativePtr); - p.ensureCapacity(size); - getInstance(nativePtr).mSize = size; - } - - /** Native method substitution */ - public static void nativeSetDataPosition(long nativePtr, int pos) { - var p = getInstance(nativePtr); - // TODO: Should this change the size or the capacity?? - p.mPos = pos; - } - - /** Native method substitution */ - public static void nativeSetDataCapacity(long nativePtr, int size) { - if (size < 0) { - throw new IllegalArgumentException("size < 0: size=" + size); - } - var p = getInstance(nativePtr); - if (p.getCapacity() < size) { - p.forceSetCapacity(size); - } - } - - /** Native method substitution */ - public static boolean nativePushAllowFds(long nativePtr, boolean allowFds) { - var p = getInstance(nativePtr); - var prev = p.mAllowFds; - p.mAllowFds = allowFds; - return prev; - } - - /** Native method substitution */ - public static void nativeRestoreAllowFds(long nativePtr, boolean lastValue) { - getInstance(nativePtr).mAllowFds = lastValue; - } - - /** Native method substitution */ - public static void nativeWriteByteArray(long nativePtr, byte[] b, int offset, int len) { - nativeWriteBlob(nativePtr, b, offset, len); - } - - /** Native method substitution */ - public static void nativeWriteBlob(long nativePtr, byte[] b, int offset, int len) { - var p = getInstance(nativePtr); - - if (b == null) { - nativeWriteInt(nativePtr, -1); - } else { - final var alignedSize = align4(len); - - nativeWriteInt(nativePtr, len); - - p.ensureMoreCapacity(alignedSize); - - System.arraycopy(b, offset, p.mBuffer, p.mPos, len); - p.mPos += alignedSize; - p.updateSize(); - } - } - - /** Native method substitution */ - public static int nativeWriteInt(long nativePtr, int value) { - var p = getInstance(nativePtr); - p.ensureMoreCapacity(Integer.BYTES); - - p.mBuffer[p.mPos++] = (byte) ((value >> 24) & 0xff); - p.mBuffer[p.mPos++] = (byte) ((value >> 16) & 0xff); - p.mBuffer[p.mPos++] = (byte) ((value >> 8) & 0xff); - p.mBuffer[p.mPos++] = (byte) ((value >> 0) & 0xff); - - p.updateSize(); - - return OK; - } - - /** Native method substitution */ - public static int nativeWriteLong(long nativePtr, long value) { - nativeWriteInt(nativePtr, (int) (value >>> 32)); - nativeWriteInt(nativePtr, (int) (value)); - return OK; - } - - /** Native method substitution */ - public static int nativeWriteFloat(long nativePtr, float val) { - return nativeWriteInt(nativePtr, Float.floatToIntBits(val)); - } - - /** Native method substitution */ - public static int nativeWriteDouble(long nativePtr, double val) { - return nativeWriteLong(nativePtr, Double.doubleToLongBits(val)); - } - - private static int align4(int val) { - return ((val + 3) / 4) * 4; - } - - /** Native method substitution */ - public static void nativeWriteString8(long nativePtr, String val) { - if (val == null) { - nativeWriteBlob(nativePtr, null, 0, 0); - } else { - var bytes = val.getBytes(StandardCharsets.UTF_8); - nativeWriteBlob(nativePtr, bytes, 0, bytes.length); - } - } - - /** Native method substitution */ - public static void nativeWriteString16(long nativePtr, String val) { - // Just reuse String8 - nativeWriteString8(nativePtr, val); - } - - /** Native method substitution */ - public static byte[] nativeCreateByteArray(long nativePtr) { - return nativeReadBlob(nativePtr); - } - - /** Native method substitution */ - public static boolean nativeReadByteArray(long nativePtr, byte[] dest, int destLen) { - if (dest == null) { - return false; - } - var data = nativeReadBlob(nativePtr); - if (data == null) { - System.err.println("Percel has NULL, which is unexpected."); // TODO: Is this correct? - return false; - } - // TODO: Make sure the check logic is correct. - if (data.length != destLen) { - System.err.println("Byte array size mismatch: expected=" - + data.length + " given=" + destLen); - return false; - } - System.arraycopy(data, 0, dest, 0, data.length); - return true; - } - - /** Native method substitution */ - public static byte[] nativeReadBlob(long nativePtr) { - var p = getInstance(nativePtr); - if (p.mSize - p.mPos < 4) { - // Match native impl that returns "null" when not enough data - return null; - } - final var size = nativeReadInt(nativePtr); - if (size == -1) { - return null; - } - try { - p.ensureDataAvailable(align4(size)); - } catch (Exception e) { - System.err.println(e.toString()); - return null; - } - - var bytes = new byte[size]; - System.arraycopy(p.mBuffer, p.mPos, bytes, 0, size); - - p.mPos += align4(size); - - return bytes; - } - - /** Native method substitution */ - public static int nativeReadInt(long nativePtr) { - var p = getInstance(nativePtr); - - if (p.mSize - p.mPos < 4) { - // Match native impl that returns "0" when not enough data - return 0; - } - - var ret = (((p.mBuffer[p.mPos++] & 0xff) << 24) - | ((p.mBuffer[p.mPos++] & 0xff) << 16) - | ((p.mBuffer[p.mPos++] & 0xff) << 8) - | ((p.mBuffer[p.mPos++] & 0xff) << 0)); - - return ret; - } - - /** Native method substitution */ - public static long nativeReadLong(long nativePtr) { - return (((long) nativeReadInt(nativePtr)) << 32) - | (((long) nativeReadInt(nativePtr)) & 0xffff_ffffL); - } - - /** Native method substitution */ - public static float nativeReadFloat(long nativePtr) { - return Float.intBitsToFloat(nativeReadInt(nativePtr)); - } - - /** Native method substitution */ - public static double nativeReadDouble(long nativePtr) { - return Double.longBitsToDouble(nativeReadLong(nativePtr)); - } - - /** Native method substitution */ - public static String nativeReadString8(long nativePtr) { - final var bytes = nativeReadBlob(nativePtr); - if (bytes == null) { - return null; - } - return new String(bytes, StandardCharsets.UTF_8); - } - public static String nativeReadString16(long nativePtr) { - return nativeReadString8(nativePtr); - } - - /** Native method substitution */ - public static byte[] nativeMarshall(long nativePtr) { - var p = getInstance(nativePtr); - return Arrays.copyOf(p.mBuffer, p.mSize); - } - - /** Native method substitution */ - public static void nativeUnmarshall( - long nativePtr, byte[] data, int offset, int length) { - var p = getInstance(nativePtr); - p.ensureMoreCapacity(length); - System.arraycopy(data, offset, p.mBuffer, p.mPos, length); - p.mPos += length; - p.updateSize(); - } - - /** Native method substitution */ - public static int nativeCompareData(long thisNativePtr, long otherNativePtr) { - var a = getInstance(thisNativePtr); - var b = getInstance(otherNativePtr); - if ((a.mSize == b.mSize) && Arrays.equals(a.mBuffer, b.mBuffer)) { - return 0; - } else { - return -1; - } - } - - /** Native method substitution */ - public static boolean nativeCompareDataInRange( - long ptrA, int offsetA, long ptrB, int offsetB, int length) { - var a = getInstance(ptrA); - var b = getInstance(ptrB); - if (offsetA < 0 || offsetA + length > a.mSize) { - throw new IllegalArgumentException(); - } - if (offsetB < 0 || offsetB + length > b.mSize) { - throw new IllegalArgumentException(); - } - return Arrays.equals(Arrays.copyOfRange(a.mBuffer, offsetA, offsetA + length), - Arrays.copyOfRange(b.mBuffer, offsetB, offsetB + length)); - } - - /** Native method substitution */ - public static void nativeAppendFrom( - long thisNativePtr, long otherNativePtr, int srcOffset, int length) { - var dst = getInstance(thisNativePtr); - var src = getInstance(otherNativePtr); - - dst.ensureMoreCapacity(length); - - System.arraycopy(src.mBuffer, srcOffset, dst.mBuffer, dst.mPos, length); - dst.mPos += length; // TODO: 4 byte align? - dst.updateSize(); - - // TODO: Update the other's position? - } - - /** Native method substitution */ - public static boolean nativeHasBinders(long nativePtr) { - // Assume false for now, because we don't support adding binders. - return false; - } - - /** Native method substitution */ - public static boolean nativeHasBindersInRange( - long nativePtr, int offset, int length) { - // Assume false for now, because we don't support writing FDs yet. - return false; - } - - /** Native method substitution */ - public static void nativeWriteFileDescriptor(long nativePtr, java.io.FileDescriptor val) { - var p = getInstance(nativePtr); - - if (!p.mAllowFds) { - // Simulate the FDS_NOT_ALLOWED case in frameworks/base/core/jni/android_util_Binder.cpp - throw new RuntimeException("Not allowed to write file descriptors here"); - } - - FileDescriptor dup = null; - try { - dup = Os.dup(val); - } catch (ErrnoException e) { - throw new RuntimeException(e); - } - p.mFdMap.put(p.mPos, dup); - - // Parcel.cpp writes two int32s for a FD. - // Make sure FD_PAYLOAD_SIZE is in sync with this code. - nativeWriteInt(nativePtr, FD_PLACEHOLDER); - nativeWriteInt(nativePtr, FD_PLACEHOLDER); - } - - /** Native method substitution */ - public static java.io.FileDescriptor nativeReadFileDescriptor(long nativePtr) { - var p = getInstance(nativePtr); - - var pos = p.mPos; - var fd = p.mFdMap.get(pos); - - if (fd == null) { - Log.w(TAG, "nativeReadFileDescriptor: Not a FD at pos #" + pos); - return null; - } - nativeReadInt(nativePtr); - nativeReadInt(nativePtr); - return fd; - } - - /** Native method substitution */ - public static boolean nativeHasFileDescriptors(long nativePtr) { - var p = getInstance(nativePtr); - return p.mFdMap.size() > 0; - } - - /** Native method substitution */ - public static boolean nativeHasFileDescriptorsInRange(long nativePtr, int offset, int length) { - var p = getInstance(nativePtr); - - // Original code: hasFileDescriptorsInRange() in frameworks/native/libs/binder/Parcel.cpp - if (offset < 0 || length < 0) { - throw new IllegalArgumentException("Negative value not allowed: offset=" + offset - + " length=" + length); - } - long limit = (long) offset + (long) length; - if (limit > p.mSize) { - throw new IllegalArgumentException("Out of range: offset=" + offset - + " length=" + length + " dataSize=" + p.mSize); - } - - for (var pos : p.mFdMap.keySet()) { - if (offset <= pos && (pos + FD_PAYLOAD_SIZE - 1) < (offset + length)) { - return true; - } - } - return false; - } -} 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 01e19a70eece..790bb1c2373b 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 @@ -166,6 +166,7 @@ public class ClassLoadHook { private static final Class<?>[] sLibandroidClasses = { android.util.Log.class, android.os.Parcel.class, + android.os.Binder.class, android.content.res.ApkAssets.class, android.content.res.AssetManager.class, android.content.res.StringBlock.class, |