Merge "Adding tests for OOM fix"
This commit is contained in:
@@ -325,7 +325,24 @@ public class Binder implements IBinder {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@CriticalNative
|
@CriticalNative
|
||||||
public static final native boolean isDirectlyHandlingTransaction();
|
public static final native boolean isDirectlyHandlingTransactionNative();
|
||||||
|
|
||||||
|
private static boolean sIsHandlingBinderTransaction = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final boolean isDirectlyHandlingTransaction() {
|
||||||
|
return sIsHandlingBinderTransaction || isDirectlyHandlingTransactionNative();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is Test API which will be used to override output of isDirectlyHandlingTransactionNative
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static void setIsDirectlyHandlingTransactionOverride(boolean isInTransaction) {
|
||||||
|
sIsHandlingBinderTransaction = isInTransaction;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the current thread has had its identity
|
* Returns {@code true} if the current thread has had its identity
|
||||||
|
|||||||
@@ -1584,7 +1584,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final boolean[] createBooleanArray() {
|
public final boolean[] createBooleanArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 4 byte for boolean.
|
|
||||||
ensureWithinMemoryLimit(SIZE_BOOLEAN, N);
|
ensureWithinMemoryLimit(SIZE_BOOLEAN, N);
|
||||||
// >>2 as a fast divide-by-4 works in the create*Array() functions
|
// >>2 as a fast divide-by-4 works in the create*Array() functions
|
||||||
// because dataAvail() will never return a negative number. 4 is
|
// because dataAvail() will never return a negative number. 4 is
|
||||||
@@ -1628,7 +1627,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public short[] createShortArray() {
|
public short[] createShortArray() {
|
||||||
int n = readInt();
|
int n = readInt();
|
||||||
// Assuming size of 2 byte for short.
|
|
||||||
ensureWithinMemoryLimit(SIZE_SHORT, n);
|
ensureWithinMemoryLimit(SIZE_SHORT, n);
|
||||||
if (n >= 0 && n <= (dataAvail() >> 2)) {
|
if (n >= 0 && n <= (dataAvail() >> 2)) {
|
||||||
short[] val = new short[n];
|
short[] val = new short[n];
|
||||||
@@ -1668,7 +1666,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final char[] createCharArray() {
|
public final char[] createCharArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 2 byte for char.
|
|
||||||
ensureWithinMemoryLimit(SIZE_CHAR, N);
|
ensureWithinMemoryLimit(SIZE_CHAR, N);
|
||||||
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
||||||
char[] val = new char[N];
|
char[] val = new char[N];
|
||||||
@@ -1707,7 +1704,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final int[] createIntArray() {
|
public final int[] createIntArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 4 byte for int.
|
|
||||||
ensureWithinMemoryLimit(SIZE_INT, N);
|
ensureWithinMemoryLimit(SIZE_INT, N);
|
||||||
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
||||||
int[] val = new int[N];
|
int[] val = new int[N];
|
||||||
@@ -1746,7 +1742,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final long[] createLongArray() {
|
public final long[] createLongArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 8 byte for long.
|
|
||||||
ensureWithinMemoryLimit(SIZE_LONG, N);
|
ensureWithinMemoryLimit(SIZE_LONG, N);
|
||||||
// >>3 because stored longs are 64 bits
|
// >>3 because stored longs are 64 bits
|
||||||
if (N >= 0 && N <= (dataAvail() >> 3)) {
|
if (N >= 0 && N <= (dataAvail() >> 3)) {
|
||||||
@@ -1786,7 +1781,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final float[] createFloatArray() {
|
public final float[] createFloatArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 4 byte for float.
|
|
||||||
ensureWithinMemoryLimit(SIZE_FLOAT, N);
|
ensureWithinMemoryLimit(SIZE_FLOAT, N);
|
||||||
// >>2 because stored floats are 4 bytes
|
// >>2 because stored floats are 4 bytes
|
||||||
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
if (N >= 0 && N <= (dataAvail() >> 2)) {
|
||||||
@@ -1826,7 +1820,6 @@ public final class Parcel {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public final double[] createDoubleArray() {
|
public final double[] createDoubleArray() {
|
||||||
int N = readInt();
|
int N = readInt();
|
||||||
// Assuming size of 8 byte for double.
|
|
||||||
ensureWithinMemoryLimit(SIZE_DOUBLE, N);
|
ensureWithinMemoryLimit(SIZE_DOUBLE, N);
|
||||||
// >>3 because stored doubles are 8 bytes
|
// >>3 because stored doubles are 8 bytes
|
||||||
if (N >= 0 && N <= (dataAvail() >> 3)) {
|
if (N >= 0 && N <= (dataAvail() >> 3)) {
|
||||||
|
|||||||
@@ -974,7 +974,7 @@ static jint android_os_Binder_getCallingUid()
|
|||||||
return IPCThreadState::self()->getCallingUid();
|
return IPCThreadState::self()->getCallingUid();
|
||||||
}
|
}
|
||||||
|
|
||||||
static jboolean android_os_Binder_isDirectlyHandlingTransaction() {
|
static jboolean android_os_Binder_isDirectlyHandlingTransactionNative() {
|
||||||
return getCurrentServingCall() == BinderCallType::BINDER;
|
return getCurrentServingCall() == BinderCallType::BINDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1082,7 +1082,8 @@ static const JNINativeMethod gBinderMethods[] = {
|
|||||||
// @CriticalNative
|
// @CriticalNative
|
||||||
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
|
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
|
||||||
// @CriticalNative
|
// @CriticalNative
|
||||||
{ "isDirectlyHandlingTransaction", "()Z", (void*)android_os_Binder_isDirectlyHandlingTransaction },
|
{ "isDirectlyHandlingTransactionNative", "()Z",
|
||||||
|
(void*)android_os_Binder_isDirectlyHandlingTransactionNative },
|
||||||
// @CriticalNative
|
// @CriticalNative
|
||||||
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
|
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
|
||||||
// @CriticalNative
|
// @CriticalNative
|
||||||
|
|||||||
@@ -246,4 +246,93 @@ public class ParcelTest {
|
|||||||
assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, -1, pB, iB, 0));
|
assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, -1, pB, iB, 0));
|
||||||
assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, 0, pB, -1, 0));
|
assertThrows(IllegalArgumentException.class, () -> Parcel.compareData(pA, 0, pB, -1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Tests for b/205282403
|
||||||
|
* This test checks if allocations made over limit of 1MB for primitive types
|
||||||
|
* and 1M length for complex objects are not allowed.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAllocationsOverLimit_whenOverLimit_throws() {
|
||||||
|
Binder.setIsDirectlyHandlingTransactionOverride(true);
|
||||||
|
Parcel p = Parcel.obtain();
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.writeInt(Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class, () ->p.createBooleanArray());
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class, () ->p.createCharArray());
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class, () ->p.createIntArray());
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class, () ->p.createLongArray());
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class, () ->p.createBinderArray());
|
||||||
|
|
||||||
|
int[] dimensions = new int[]{Integer.MAX_VALUE, 100, 100};
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class,
|
||||||
|
() -> p.createFixedArray(int[][][].class, dimensions));
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class,
|
||||||
|
() -> p.createFixedArray(String[][][].class, dimensions));
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
assertThrows(BadParcelableException.class,
|
||||||
|
() -> p.createFixedArray(IBinder[][][].class, dimensions));
|
||||||
|
|
||||||
|
p.recycle();
|
||||||
|
Binder.setIsDirectlyHandlingTransactionOverride(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Tests for b/205282403
|
||||||
|
* This test checks if allocations made under limit of 1MB for primitive types
|
||||||
|
* and 1M length for complex objects are allowed.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testAllocations_whenWithinLimit() {
|
||||||
|
Binder.setIsDirectlyHandlingTransactionOverride(true);
|
||||||
|
Parcel p = Parcel.obtain();
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.writeInt(100000);
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createByteArray();
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createCharArray();
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createIntArray();
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createLongArray();
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createBinderArray();
|
||||||
|
|
||||||
|
int[] dimensions = new int[]{ 100, 100, 100 };
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
int[][][] data = new int[100][100][100];
|
||||||
|
p.writeFixedArray(data, 0, dimensions);
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createFixedArray(int[][][].class, dimensions);
|
||||||
|
|
||||||
|
p.setDataPosition(0);
|
||||||
|
IBinder[][][] parcelables = new IBinder[100][100][100];
|
||||||
|
p.writeFixedArray(parcelables, 0, dimensions);
|
||||||
|
p.setDataPosition(0);
|
||||||
|
p.createFixedArray(IBinder[][][].class, dimensions);
|
||||||
|
|
||||||
|
p.recycle();
|
||||||
|
Binder.setIsDirectlyHandlingTransactionOverride(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user