Import Android SDK Platform P [4697573]
/google/data/ro/projects/android/fetch_artifact \
--bid 4697573 \
--target sdk_phone_armv7-win_sdk \
sdk-repo-linux-sources-4697573.zip
AndroidVersion.ApiLevel has been modified to appear as 28
Change-Id: If80578c3c657366cc9cf75f8db13d46e2dd4e077
diff --git a/java/io/FileInputStream.java b/java/io/FileInputStream.java
index b44bc5a..db7ba65 100644
--- a/java/io/FileInputStream.java
+++ b/java/io/FileInputStream.java
@@ -28,6 +28,7 @@
import java.nio.channels.FileChannel;
+import dalvik.annotation.optimization.ReachabilitySensitive;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
import sun.nio.ch.FileChannelImpl;
@@ -55,6 +56,8 @@
class FileInputStream extends InputStream
{
/* File Descriptor - handle to the open file */
+ // Android-added: @ReachabilitySensitive
+ @ReachabilitySensitive
private final FileDescriptor fd;
/**
@@ -72,6 +75,7 @@
private final boolean isFdOwner;
// Android-added: CloseGuard support.
+ @ReachabilitySensitive
private final CloseGuard guard = CloseGuard.get();
// Android-added: Tracking of unbuffered I/O.
diff --git a/java/io/FileOutputStream.java b/java/io/FileOutputStream.java
index 79e7690..f29a741 100644
--- a/java/io/FileOutputStream.java
+++ b/java/io/FileOutputStream.java
@@ -28,6 +28,7 @@
import java.nio.channels.FileChannel;
+import dalvik.annotation.optimization.ReachabilitySensitive;
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
import sun.nio.ch.FileChannelImpl;
@@ -60,6 +61,8 @@
/**
* The system dependent file descriptor.
*/
+ // Android-added: @ReachabilitySensitive
+ @ReachabilitySensitive
private final FileDescriptor fd;
/**
@@ -82,6 +85,7 @@
private volatile boolean closed = false;
// Android-added: CloseGuard support: Log if the stream is not closed.
+ @ReachabilitySensitive
private final CloseGuard guard = CloseGuard.get();
// Android-added: Field for tracking whether the stream owns the underlying FileDescriptor.
@@ -422,6 +426,8 @@
* @exception IOException if an I/O error occurs.
* @see java.io.FileDescriptor
*/
+ // Android-added: @ReachabilitySensitive
+ @ReachabilitySensitive
public final FileDescriptor getFD() throws IOException {
if (fd != null) {
return fd;
diff --git a/java/io/ObjectInputStream.java b/java/io/ObjectInputStream.java
index 17001c5..f722df0 100644
--- a/java/io/ObjectInputStream.java
+++ b/java/io/ObjectInputStream.java
@@ -208,7 +208,6 @@
public class ObjectInputStream
extends InputStream implements ObjectInput, ObjectStreamConstants
{
-
/** handle value representing null */
private static final int NULL_HANDLE = -1;
@@ -2021,11 +2020,13 @@
throw new InternalError();
}
clear();
+ // BEGIN Android-changed: Fix SerializationStressTest#test_2_writeReplace.
IOException e = (IOException) readObject0(false);
- // BEGIN Android-changed
+ // If we want to continue reading from same stream after fatal exception, we
+ // need to clear internal data structures.
clear();
- // END Android-changed
return e;
+ // END Android-changed: Fix SerializationStressTest#test_2_writeReplace.
}
/**
@@ -2069,6 +2070,7 @@
* corresponding modifications to the above class.
*/
private static ClassLoader latestUserDefinedLoader() {
+ // Android-changed: Use VMStack on Android.
return VMStack.getClosestUserClassLoader();
}
diff --git a/java/io/ObjectOutputStream.java b/java/io/ObjectOutputStream.java
index 632f2d3..7c4f0ca 100644
--- a/java/io/ObjectOutputStream.java
+++ b/java/io/ObjectOutputStream.java
@@ -37,7 +37,6 @@
import java.util.concurrent.ConcurrentMap;
import static java.io.ObjectStreamClass.processQueue;
import java.io.SerialCallbackContext;
-
import sun.reflect.misc.ReflectUtil;
/**
@@ -211,7 +210,15 @@
* value of "sun.io.serialization.extendedDebugInfo" property,
* as true or false for extended information about exception's place
*/
+ // BEGIN Android-changed: Do not support extendedDebugInfo on Android.
+ /*
+ private static final boolean extendedDebugInfo =
+ java.security.AccessController.doPrivileged(
+ new sun.security.action.GetBooleanAction(
+ "sun.io.serialization.extendedDebugInfo")).booleanValue();
+ */
private static final boolean extendedDebugInfo = false;
+ // END Android-changed: Do not support extendedDebugInfo on Android.
/**
* Creates an ObjectOutputStream that writes to the specified OutputStream.
@@ -347,7 +354,7 @@
writeObject0(obj, false);
} catch (IOException ex) {
if (depth == 0) {
- // BEGIN Android-changed
+ // BEGIN Android-changed: Ignore secondary exceptions during writeObject().
// writeFatalException(ex);
try {
writeFatalException(ex);
@@ -357,7 +364,7 @@
// is no need to propagate the second exception or generate a third exception,
// both of which might obscure details of the root cause.
}
- // END Android-changed
+ // END Android-changed: Ignore secondary exceptions during writeObject().
}
throw ex;
}
@@ -378,12 +385,12 @@
* @since 1.2
*/
protected void writeObjectOverride(Object obj) throws IOException {
- // BEGIN Android-changed
+ // BEGIN Android-added: Let writeObjectOverride throw IOException if !enableOverride.
if (!enableOverride) {
// Subclasses must override.
throw new IOException();
}
- // END Android-changed
+ // END Android-added: Let writeObjectOverride throw IOException if !enableOverride.
}
/**
@@ -753,7 +760,7 @@
*/
public void close() throws IOException {
flush();
- // http://b/28159133
+ // Android-removed: Don't clear() during close(), keep the handle table. http://b/28159133
// clear();
bout.close();
}
@@ -1132,7 +1139,7 @@
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
- // BEGIN Android-changed
+ // BEGIN Android-changed: Make Class and ObjectStreamClass replaceable.
/*
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
@@ -1141,7 +1148,7 @@
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
*/
- // END Android-changed
+ // END Android-changed: Make Class and ObjectStreamClass replaceable.
}
// check for replacement object
@@ -1149,7 +1156,7 @@
Class<?> cl = obj.getClass();
ObjectStreamClass desc;
- // BEGIN Android-changed
+ // BEGIN Android-changed: Make only one call to writeReplace.
/*
for (;;) {
// REMIND: skip this check for strings/arrays?
@@ -1177,7 +1184,7 @@
cl = repCl;
desc = ObjectStreamClass.lookup(cl, true);
}
- // END Android-changed
+ // END Android-changed: Make only one call to writeReplace.
if (enableReplace) {
Object rep = replaceObject(obj);
@@ -1197,7 +1204,7 @@
} else if (!unshared && (h = handles.lookup(obj)) != -1) {
writeHandle(h);
return;
-// BEGIN Android-changed
+// BEGIN Android-changed: Make Class and ObjectStreamClass replaceable.
/*
} else if (obj instanceof Class) {
writeClass((Class) obj, unshared);
@@ -1206,17 +1213,17 @@
writeClassDesc((ObjectStreamClass) obj, unshared);
return;
*/
-// END Android-changed
+// END Android-changed: Make Class and ObjectStreamClass replaceable.
}
}
// remaining cases
- // BEGIN Android-changed
+ // BEGIN Android-changed: Make Class and ObjectStreamClass replaceable.
if (obj instanceof Class) {
writeClass((Class) obj, unshared);
} else if (obj instanceof ObjectStreamClass) {
writeClassDesc((ObjectStreamClass) obj, unshared);
- // END Android-changed
+ // END Android-changed: Make Class and ObjectStreamClass replaceable.
} else if (obj instanceof String) {
writeString((String) obj, unshared);
} else if (cl.isArray()) {
@@ -1812,6 +1819,7 @@
/** loopback stream (for data writes that span data blocks) */
private final DataOutputStream dout;
+ // BEGIN Android-added: Warning if writing to a closed ObjectOutputStream.
/**
* Indicates that this stream was closed and that a warning must be logged once if an
* attempt is made to write to it and the underlying stream does not throw an exception.
@@ -1822,6 +1830,7 @@
* http://b/28159133
*/
private boolean warnOnceWhenWriting;
+ // END Android-added: Warning if writing to a closed ObjectOutputStream.
/**
* Creates new BlockDataOutputStream on top of given underlying stream.
@@ -1856,6 +1865,7 @@
return blkmode;
}
+ // BEGIN Android-added: Warning about writing to closed ObjectOutputStream
/**
* Warns if the stream has been closed.
*
@@ -1874,6 +1884,7 @@
warnOnceWhenWriting = false;
}
}
+ // END Android-added: Warning about writing to closed ObjectOutputStream
/* ----------------- generic output stream methods ----------------- */
/*
@@ -1905,6 +1916,7 @@
public void close() throws IOException {
flush();
out.close();
+ // Android-added: Warning about writing to closed ObjectOutputStream
warnOnceWhenWriting = true;
}
@@ -1920,6 +1932,7 @@
if (!(copy || blkmode)) { // write directly
drain();
out.write(b, off, len);
+ // Android-added: Warning about writing to closed ObjectOutputStream
warnIfClosed();
return;
}
@@ -1942,6 +1955,7 @@
len -= wlen;
}
}
+ // Android-added: Warning about writing to closed ObjectOutputStream
warnIfClosed();
}
@@ -1958,6 +1972,7 @@
}
out.write(buf, 0, pos);
pos = 0;
+ // Android-added: Warning about writing to closed ObjectOutputStream
warnIfClosed();
}
@@ -1976,6 +1991,7 @@
Bits.putInt(hbuf, 1, len);
out.write(hbuf, 0, 5);
}
+ // Android-added: Warning about writing to closed ObjectOutputStream
warnIfClosed();
}
diff --git a/java/io/ObjectStreamClass.java b/java/io/ObjectStreamClass.java
index ff1cf82..b2651b8 100644
--- a/java/io/ObjectStreamClass.java
+++ b/java/io/ObjectStreamClass.java
@@ -79,7 +79,14 @@
private static final ObjectStreamField[] serialPersistentFields =
NO_FIELDS;
- /** reflection factory for obtaining serialization constructors */
+ // BEGIN Android-removed: ReflectionFactory not used on Android.
+ /*
+ /** reflection factory for obtaining serialization constructors *
+ private static final ReflectionFactory reflFactory =
+ AccessController.doPrivileged(
+ new ReflectionFactory.GetReflectionFactoryAction());
+ */
+ // END Android-removed: ReflectionFactory not used on Android.
private static class Caches {
/** cache mapping local classes -> descriptors */
@@ -186,6 +193,21 @@
/** superclass descriptor appearing in stream */
private ObjectStreamClass superDesc;
+ /** true if, and only if, the object has been correctly initialized */
+ private boolean initialized;
+
+ // BEGIN Android-removed: Initialization not required on Android.
+ /*
+ /**
+ * Initializes native code.
+ *
+ private static native void initNative();
+ static {
+ initNative();
+ }
+ */
+ // END Android-removed: Initialization not required on Android.
+
/**
* Find the descriptor for a class that can be serialized. Creates an
* ObjectStreamClass instance if one does not exist yet for class. Null is
@@ -255,7 +277,9 @@
if (cl == null) {
return null;
}
+ requireInitialized();
if (System.getSecurityManager() != null) {
+ // Android-changed: Class loader obtained from VMStack
if (ReflectUtil.needsPackageAccessCheck(VMStack.getCallingClassLoader(),
cl.getClassLoader())) {
ReflectUtil.checkPackageAccess(cl);
@@ -522,6 +546,7 @@
name, "unmatched serializable field(s) declared");
}
}
+ initialized = true;
}
/**
@@ -539,6 +564,14 @@
ObjectStreamClass superDesc)
throws InvalidClassException
{
+ ObjectStreamClass osc = null;
+ if (cl != null) {
+ osc = lookup(cl, true);
+ if (!osc.isProxy) {
+ throw new InvalidClassException(
+ "cannot bind proxy descriptor to a non-proxy class");
+ }
+ }
this.cl = cl;
this.resolveEx = resolveEx;
this.superDesc = superDesc;
@@ -546,21 +579,17 @@
serializable = true;
suid = Long.valueOf(0);
fields = NO_FIELDS;
-
- if (cl != null) {
- localDesc = lookup(cl, true);
- if (!localDesc.isProxy) {
- throw new InvalidClassException(
- "cannot bind proxy descriptor to a non-proxy class");
- }
+ if (osc != null) {
+ localDesc = osc;
name = localDesc.name;
externalizable = localDesc.externalizable;
- cons = localDesc.cons;
writeReplaceMethod = localDesc.writeReplaceMethod;
readResolveMethod = localDesc.readResolveMethod;
deserializeEx = localDesc.deserializeEx;
+ cons = localDesc.cons;
}
fieldRefl = getReflector(fields, localDesc);
+ initialized = true;
}
/**
@@ -572,11 +601,57 @@
ObjectStreamClass superDesc)
throws InvalidClassException
{
+ long suid = Long.valueOf(model.getSerialVersionUID());
+ ObjectStreamClass osc = null;
+ if (cl != null) {
+ osc = lookup(cl, true);
+ if (osc.isProxy) {
+ throw new InvalidClassException(
+ "cannot bind non-proxy descriptor to a proxy class");
+ }
+ if (model.isEnum != osc.isEnum) {
+ throw new InvalidClassException(model.isEnum ?
+ "cannot bind enum descriptor to a non-enum class" :
+ "cannot bind non-enum descriptor to an enum class");
+ }
+
+ if (model.serializable == osc.serializable &&
+ !cl.isArray() &&
+ suid != osc.getSerialVersionUID()) {
+ throw new InvalidClassException(osc.name,
+ "local class incompatible: " +
+ "stream classdesc serialVersionUID = " + suid +
+ ", local class serialVersionUID = " +
+ osc.getSerialVersionUID());
+ }
+
+ if (!classNamesEqual(model.name, osc.name)) {
+ throw new InvalidClassException(osc.name,
+ "local class name incompatible with stream class " +
+ "name \"" + model.name + "\"");
+ }
+
+ if (!model.isEnum) {
+ if ((model.serializable == osc.serializable) &&
+ (model.externalizable != osc.externalizable)) {
+ throw new InvalidClassException(osc.name,
+ "Serializable incompatible with Externalizable");
+ }
+
+ if ((model.serializable != osc.serializable) ||
+ (model.externalizable != osc.externalizable) ||
+ !(model.serializable || model.externalizable)) {
+ deserializeEx = new ExceptionInfo(
+ osc.name, "class invalid for deserialization");
+ }
+ }
+ }
+
this.cl = cl;
this.resolveEx = resolveEx;
this.superDesc = superDesc;
name = model.name;
- suid = Long.valueOf(model.getSerialVersionUID());
+ this.suid = suid;
isProxy = false;
isEnum = model.isEnum;
serializable = model.serializable;
@@ -587,53 +662,8 @@
primDataSize = model.primDataSize;
numObjFields = model.numObjFields;
- if (cl != null) {
- localDesc = lookup(cl, true);
- if (localDesc.isProxy) {
- throw new InvalidClassException(
- "cannot bind non-proxy descriptor to a proxy class");
- }
- if (isEnum != localDesc.isEnum) {
- throw new InvalidClassException(isEnum ?
- "cannot bind enum descriptor to a non-enum class" :
- "cannot bind non-enum descriptor to an enum class");
- }
-
- if (serializable == localDesc.serializable &&
- !cl.isArray() &&
- suid.longValue() != localDesc.getSerialVersionUID())
- {
- throw new InvalidClassException(localDesc.name,
- "local class incompatible: " +
- "stream classdesc serialVersionUID = " + suid +
- ", local class serialVersionUID = " +
- localDesc.getSerialVersionUID());
- }
-
- if (!classNamesEqual(name, localDesc.name)) {
- throw new InvalidClassException(localDesc.name,
- "local class name incompatible with stream class " +
- "name \"" + name + "\"");
- }
-
- if (!isEnum) {
- if ((serializable == localDesc.serializable) &&
- (externalizable != localDesc.externalizable))
- {
- throw new InvalidClassException(localDesc.name,
- "Serializable incompatible with Externalizable");
- }
-
- if ((serializable != localDesc.serializable) ||
- (externalizable != localDesc.externalizable) ||
- !(serializable || externalizable))
- {
- deserializeEx = new ExceptionInfo(
- localDesc.name, "class invalid for deserialization");
- }
- }
-
- cons = localDesc.cons;
+ if (osc != null) {
+ localDesc = osc;
writeObjectMethod = localDesc.writeObjectMethod;
readObjectMethod = localDesc.readObjectMethod;
readObjectNoDataMethod = localDesc.readObjectNoDataMethod;
@@ -642,10 +672,13 @@
if (deserializeEx == null) {
deserializeEx = localDesc.deserializeEx;
}
+ cons = localDesc.cons;
}
+
fieldRefl = getReflector(fields, localDesc);
// reassign to matched fields so as to reflect local unshared settings
fields = fieldRefl.getFields();
+ initialized = true;
}
/**
@@ -748,11 +781,20 @@
}
/**
+ * Throws InternalError if not initialized.
+ */
+ private final void requireInitialized() {
+ if (!initialized)
+ throw new InternalError("Unexpected call when not initialized");
+ }
+
+ /**
* Throws an InvalidClassException if object instances referencing this
* class descriptor should not be allowed to deserialize. This method does
* not apply to deserialization of enum constants.
*/
void checkDeserialize() throws InvalidClassException {
+ requireInitialized();
if (deserializeEx != null) {
throw deserializeEx.newInvalidClassException();
}
@@ -764,6 +806,7 @@
* not apply to serialization of enum constants.
*/
void checkSerialize() throws InvalidClassException {
+ requireInitialized();
if (serializeEx != null) {
throw serializeEx.newInvalidClassException();
}
@@ -777,6 +820,7 @@
* does not apply to deserialization of enum constants.
*/
void checkDefaultSerialize() throws InvalidClassException {
+ requireInitialized();
if (defaultSerializeEx != null) {
throw defaultSerializeEx.newInvalidClassException();
}
@@ -788,6 +832,7 @@
* of the subclass descriptor's bound class.
*/
ObjectStreamClass getSuperDesc() {
+ requireInitialized();
return superDesc;
}
@@ -798,6 +843,7 @@
* associated with this descriptor.
*/
ObjectStreamClass getLocalDesc() {
+ requireInitialized();
return localDesc;
}
@@ -840,6 +886,7 @@
* otherwise.
*/
boolean isProxy() {
+ requireInitialized();
return isProxy;
}
@@ -848,6 +895,7 @@
* otherwise.
*/
boolean isEnum() {
+ requireInitialized();
return isEnum;
}
@@ -856,6 +904,7 @@
* otherwise.
*/
boolean isExternalizable() {
+ requireInitialized();
return externalizable;
}
@@ -864,6 +913,7 @@
* otherwise.
*/
boolean isSerializable() {
+ requireInitialized();
return serializable;
}
@@ -872,6 +922,7 @@
* has written its data in 1.2 (block data) format, false otherwise.
*/
boolean hasBlockExternalData() {
+ requireInitialized();
return hasBlockExternalData;
}
@@ -881,6 +932,7 @@
* writeObject() method, false otherwise.
*/
boolean hasWriteObjectData() {
+ requireInitialized();
return hasWriteObjectData;
}
@@ -892,6 +944,7 @@
* accessible no-arg constructor. Otherwise, returns false.
*/
boolean isInstantiable() {
+ requireInitialized();
return (cons != null);
}
@@ -901,6 +954,7 @@
* returns false.
*/
boolean hasWriteObjectMethod() {
+ requireInitialized();
return (writeObjectMethod != null);
}
@@ -910,6 +964,7 @@
* returns false.
*/
boolean hasReadObjectMethod() {
+ requireInitialized();
return (readObjectMethod != null);
}
@@ -919,6 +974,7 @@
* Otherwise, returns false.
*/
boolean hasReadObjectNoDataMethod() {
+ requireInitialized();
return (readObjectNoDataMethod != null);
}
@@ -927,6 +983,7 @@
* defines a conformant writeReplace method. Otherwise, returns false.
*/
boolean hasWriteReplaceMethod() {
+ requireInitialized();
return (writeReplaceMethod != null);
}
@@ -935,6 +992,7 @@
* defines a conformant readResolve method. Otherwise, returns false.
*/
boolean hasReadResolveMethod() {
+ requireInitialized();
return (readResolveMethod != null);
}
@@ -951,6 +1009,7 @@
throws InstantiationException, InvocationTargetException,
UnsupportedOperationException
{
+ requireInitialized();
if (cons != null) {
try {
return cons.newInstance();
@@ -972,6 +1031,7 @@
void invokeWriteObject(Object obj, ObjectOutputStream out)
throws IOException, UnsupportedOperationException
{
+ requireInitialized();
if (writeObjectMethod != null) {
try {
writeObjectMethod.invoke(obj, new Object[]{ out });
@@ -1001,6 +1061,7 @@
throws ClassNotFoundException, IOException,
UnsupportedOperationException
{
+ requireInitialized();
if (readObjectMethod != null) {
try {
readObjectMethod.invoke(obj, new Object[]{ in });
@@ -1031,6 +1092,7 @@
void invokeReadObjectNoData(Object obj)
throws IOException, UnsupportedOperationException
{
+ requireInitialized();
if (readObjectNoDataMethod != null) {
try {
readObjectNoDataMethod.invoke(obj, (Object[]) null);
@@ -1059,6 +1121,7 @@
Object invokeWriteReplace(Object obj)
throws IOException, UnsupportedOperationException
{
+ requireInitialized();
if (writeReplaceMethod != null) {
try {
return writeReplaceMethod.invoke(obj, (Object[]) null);
@@ -1088,6 +1151,7 @@
Object invokeReadResolve(Object obj)
throws IOException, UnsupportedOperationException
{
+ requireInitialized();
if (readResolveMethod != null) {
try {
return readResolveMethod.invoke(obj, (Object[]) null);
@@ -1362,9 +1426,12 @@
{
return null;
}
+ // BEGIN Android-changed: Serialization constructor obtained differently
+ // cons = reflFactory.newConstructorForSerialization(cl, cons);
if (cons.getDeclaringClass() != cl) {
cons = cons.serializationCopy(cons.getDeclaringClass(), cl);
}
+ // END Android-changed: Serialization constructor obtained differently
cons.setAccessible(true);
return cons;
} catch (NoSuchMethodException ex) {
@@ -1731,6 +1798,7 @@
}
}
+ // Android-changed: Clinit serialization workaround b/29064453
boolean checkSuperclass = !(VMRuntime.getRuntime().getTargetSdkVersion()
<= MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND);
if (hasStaticInitializer(cl, checkSuperclass)) {
@@ -1806,6 +1874,7 @@
}
}
+ // BEGIN Android-changed: Clinit serialization workaround b/29064453
/** Max SDK target version for which we use buggy hasStaticIntializier implementation. */
static final int MAX_SDK_TARGET_FOR_CLINIT_UIDGEN_WORKAROUND = 23;
@@ -1816,7 +1885,7 @@
* will return true even if only the superclass has a static initializer method.
*/
private native static boolean hasStaticInitializer(Class<?> cl, boolean checkSuperclass);
-
+ // END Android-changed: Clinit serialization workaround b/29064453
/**
* Class for computing and caching field/constructor/method signatures
@@ -2267,7 +2336,7 @@
}
return matches;
}
-
+ // BEGIN Android-added: Keep some private API for app compat. b/28283540.
// NOTE: The following couple of methods are left here because frameworks such as objenesis
// use them.
//
@@ -2305,6 +2374,7 @@
throw new UnsupportedOperationException("ObjectStreamClass.newInstance(Class<?>, long) " +
"is not supported on SDK " + targetSdkVersion);
}
+ // END Android-added: Keep some private API for app compat. b/28283540.
/**
* Removes from the specified map any keys that have been enqueued
diff --git a/java/io/ObjectStreamField.java b/java/io/ObjectStreamField.java
index c49bcac..957972e 100644
--- a/java/io/ObjectStreamField.java
+++ b/java/io/ObjectStreamField.java
@@ -29,7 +29,6 @@
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
-import dalvik.system.VMStack;
/**
* A description of a Serializable field from a Serializable class. An array
@@ -163,6 +162,14 @@
*/
@CallerSensitive
public Class<?> getType() {
+ /* BEGIN Android-removed: Security manager is always null on Android.
+ if (System.getSecurityManager() != null) {
+ Class<?> caller = Reflection.getCallerClass();
+ if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) {
+ ReflectUtil.checkPackageAccess(type);
+ }
+ }
+ END Android-removed: Security manager is always null on Android. */
return type;
}
diff --git a/java/io/RandomAccessFile.java b/java/io/RandomAccessFile.java
index 985f8ed..a83829f 100644
--- a/java/io/RandomAccessFile.java
+++ b/java/io/RandomAccessFile.java
@@ -26,6 +26,7 @@
package java.io;
+import dalvik.annotation.optimization.ReachabilitySensitive;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
import android.system.Os;
@@ -67,6 +68,7 @@
public class RandomAccessFile implements DataOutput, DataInput, Closeable {
// BEGIN Android-added: CloseGuard and some helper fields for Android changes in this file.
+ @ReachabilitySensitive
private final CloseGuard guard = CloseGuard.get();
private final byte[] scratch = new byte[8];
@@ -78,6 +80,8 @@
private int mode;
// END Android-added: CloseGuard and some helper fields for Android changes in this file.
+ // Android-added: @ReachabilitySensitive
+ @ReachabilitySensitive
private FileDescriptor fd;
private FileChannel channel = null;
private boolean rw;