1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 2056e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughesimport java.lang.ref.SoftReference; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Constructor; 22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Field; 23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Method; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Modifier; 25f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.lang.reflect.Proxy; 26b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughesimport java.nio.ByteOrder; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.MessageDigest; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchAlgorithmException; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Arrays; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Comparator; 327d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughesimport java.util.HashMap; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.WeakHashMap; 35f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughesimport libcore.io.Memory; 366186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Represents a descriptor for identifying a class during serialization and 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * deserialization. Information contained in the descriptor includes the name 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * and SUID of the class as well as field names and types. Information inherited 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * from the superclasses is also taken into account. 43f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectOutputStream 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see ObjectInputStream 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.Class 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class ObjectStreamClass implements Serializable { 49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // No need to compute the SUID for ObjectStreamClass, just use the value 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // below 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = -6120832682080437368L; 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Name of the field that contains the SUID value (if present) 55f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String UID_FIELD_NAME = "serialVersionUID"; 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 57f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson static final long CONSTRUCTOR_IS_NOT_RESOLVED = -1; 58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 59693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private static final int CLASS_MODIFIERS_MASK = Modifier.PUBLIC | Modifier.FINAL | 60693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes Modifier.INTERFACE | Modifier.ABSTRACT; 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 62693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private static final int FIELD_MODIFIERS_MASK = Modifier.PUBLIC | Modifier.PRIVATE | 63693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL | Modifier.VOLATILE | 64693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes Modifier.TRANSIENT; 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 66693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private static final int METHOD_MODIFIERS_MASK = Modifier.PUBLIC | Modifier.PRIVATE | 67693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes Modifier.PROTECTED | Modifier.STATIC | Modifier.FINAL | Modifier.SYNCHRONIZED | 68693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes Modifier.NATIVE | Modifier.ABSTRACT | Modifier.STRICT; 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private static final Class<?>[] READ_PARAM_TYPES = new Class[] { ObjectInputStream.class }; 71693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes private static final Class<?>[] WRITE_PARAM_TYPES = new Class[] { ObjectOutputStream.class }; 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constant indicating that the class has no Serializable fields. 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final ObjectStreamField[] NO_FIELDS = new ObjectStreamField[0]; 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * used to fetch field serialPersistentFields and checking its type 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final Class<?> ARRAY_OF_FIELDS; 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 85f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes ARRAY_OF_FIELDS = Class.forName("[Ljava.io.ObjectStreamField;"); 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (ClassNotFoundException e) { 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // This should not happen 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new AssertionError(e); 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 92f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String CLINIT_NAME = "<clinit>"; 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final int CLINIT_MODIFIERS = Modifier.STATIC; 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes private static final String CLINIT_SIGNATURE = "()V"; 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used to determine if an object is Serializable or Externalizable 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Class<Serializable> SERIALIZABLE = Serializable.class; 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final Class<Externalizable> EXTERNALIZABLE = Externalizable.class; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Used to test if the object is a String or a class. 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final Class<String> STRINGCLASS = String.class; 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final Class<?> CLASSCLASS = Class.class; 107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static final Class<ObjectStreamClass> OBJECTSTREAMCLASSCLASS = ObjectStreamClass.class; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient Method methodWriteReplace; 111f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 112f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient Method methodReadResolve; 113f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 114f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient Method methodWriteObject; 115f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient Method methodReadObject; 117f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 118f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient Method methodReadObjectNoData; 119f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 120f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 121f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Indicates whether the class properties resolved 122f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #resolveProperties() 124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 125f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient boolean arePropertiesResolved; 126f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Cached class properties 129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 130f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #resolveProperties() 131f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isSerializable() 132f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isExternalizable() 133f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isProxy() 134f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isEnum() 135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 136f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient boolean isSerializable; 137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient boolean isExternalizable; 138f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient boolean isProxy; 139f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient boolean isEnum; 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ClassDesc // 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Name of the class this descriptor represents 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient String className; 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Corresponding loaded class with the name above 14732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes private transient Class<?> resolvedClass; 14832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 14932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes private transient Class<?> resolvedConstructorClass; 150a40dc9f768eb02dcfd7b1a659333757b148f7becJoel Dice private transient long resolvedConstructorMethodId; 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Serial version UID of the class the descriptor represents 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient long svUID; 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ClassDescInfo // 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Any combination of SC_WRITE_METHOD, SC_SERIALIZABLE and SC_EXTERNALIZABLE 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // (see ObjectStreamConstants) 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient byte flags; 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Descriptor for the superclass of the class associated with this 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // descriptor 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient ObjectStreamClass superclass; 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Array of ObjectStreamField (see below) describing the fields of this 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // class 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient ObjectStreamField[] fields; 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Array of ObjectStreamField describing the serialized fields of this class 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private transient ObjectStreamField[] loadFields; 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1727d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes // ObjectStreamField doesn't override hashCode or equals, so this is equivalent to an 1737d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes // IdentityHashMap, which is fine for our purposes. 1747d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes private transient HashMap<ObjectStreamField, Field> reflectionFields = 1757d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes new HashMap<ObjectStreamField, Field>(); 1767d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes 177f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // MethodID for deserialization constructor 178f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private transient long constructor = CONSTRUCTOR_IS_NOT_RESOLVED; 179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 180f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson void setConstructor(long newConstructor) { 181f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson constructor = newConstructor; 182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 184f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson long getConstructor() { 185f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return constructor; 186f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 187f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1887d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes Field getReflectionField(ObjectStreamField osf) { 1897d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes synchronized (reflectionFields) { 1907d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes Field field = reflectionFields.get(osf); 1917d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes if (field != null) { 1927d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes return field; 1937d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } 1947d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } 1957d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes 1967d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes try { 1977d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes Class<?> declaringClass = forClass(); 1987d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes Field field = declaringClass.getDeclaredField(osf.getName()); 1997d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes field.setAccessible(true); 2007d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes synchronized (reflectionFields) { 2017d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes reflectionFields.put(osf, field); 2027d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } 2037d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes return reflectionFields.get(osf); 2047d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } catch (NoSuchFieldException ex) { 2057d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes // The caller messed up. We'll return null and won't try to resolve this again. 2067d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes return null; 2077d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } 2087d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes } 2097d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If an ObjectStreamClass describes an Externalizable class, it (the 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor) should not have field descriptors (ObjectStreamField) at all. 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ObjectStreamClass that gets saved should simply have no field info. 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is a footnote in page 1511 (class Serializable) of "The Java Class 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Libraries, Second Edition, Vol. I". 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new instance of this class. 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass() { 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 225f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Compute class descriptor for a given class <code>cl</code>. 226f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.langClass for which to compute the corresponding 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor 230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the computer class descriptor 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 232f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private static ObjectStreamClass createClassDesc(Class<?> cl) { 233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass result = new ObjectStreamClass(); 235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 236f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean isArray = cl.isArray(); 237f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean serializable = isSerializable(cl); 238f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean externalizable = isExternalizable(cl); 239f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 240f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result.isSerializable = serializable; 241f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result.isExternalizable = externalizable; 242f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Now we fill in the values 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.setName(cl.getName()); 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.setClass(cl); 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> superclass = cl.getSuperclass(); 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (superclass != null) { 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.setSuperclass(lookup(superclass)); 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Field[] declaredFields = null; 252f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 253f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Compute the SUID 2547d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes if (serializable || externalizable) { 255f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (result.isEnum() || result.isProxy()) { 256f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result.setSerialVersionUID(0L); 257f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 258f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson declaredFields = cl.getDeclaredFields(); 2597d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes result.setSerialVersionUID(computeSerialVersionUID(cl, declaredFields)); 260f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Serializables need field descriptors 264f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (serializable && !isArray) { 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (declaredFields == null) { 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project declaredFields = cl.getDeclaredFields(); 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.buildFieldDescriptors(declaredFields); 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Externalizables or arrays do not need FieldDesc info 271f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result.setFields(NO_FIELDS); 272f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 273f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 274f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Copy all fields to loadFields - they should be read by default in 275f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // ObjectInputStream.defaultReadObject() method 276f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson ObjectStreamField[] fields = result.getFields(); 277f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 278f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (fields != null) { 279f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson ObjectStreamField[] loadFields = new ObjectStreamField[fields.length]; 280f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 281f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int i = 0; i < fields.length; ++i) { 282f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson loadFields[i] = new ObjectStreamField(fields[i].getName(), 283f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson fields[i].getType(), fields[i].isUnshared()); 284f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 285f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve type string to init typeString field in 286f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // ObjectStreamField 287f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson loadFields[i].getTypeString(); 288f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 289f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result.setLoadFields(loadFields); 290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte flags = 0; 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (externalizable) { 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; 295f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson flags |= ObjectStreamConstants.SC_BLOCK_DATA; // use protocol version 2 by default 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (serializable) { 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flags |= ObjectStreamConstants.SC_SERIALIZABLE; 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 299f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result.methodWriteReplace = findMethod(cl, "writeReplace"); 300f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes result.methodReadResolve = findMethod(cl, "readResolve"); 301693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes result.methodWriteObject = findPrivateMethod(cl, "writeObject", WRITE_PARAM_TYPES); 302693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes result.methodReadObject = findPrivateMethod(cl, "readObject", READ_PARAM_TYPES); 303693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes result.methodReadObjectNoData = findPrivateMethod(cl, "readObjectNoData", EmptyArray.CLASS); 304f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (result.hasMethodWriteObject()) { 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flags |= ObjectStreamConstants.SC_WRITE_METHOD; 306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.setFlags(flags); 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Builds the collection of field descriptors for the receiver 314f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param declaredFields 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * collection of java.lang.reflect.Field for which to compute 317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * field descriptors 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void buildFieldDescriptors(Field[] declaredFields) { 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We could find the field ourselves in the collection, but calling 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // reflect is easier. Optimize if needed. 3227d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes final Field f = ObjectStreamClass.fieldSerialPersistentFields(this.forClass()); 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // If we could not find the emulated fields, we'll have to compute 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // dumpable fields from reflect fields 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean useReflectFields = f == null; // Assume we will compute the 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // fields to dump based on the 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // reflect fields 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] _fields = null; 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!useReflectFields) { 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // The user declared a collection of emulated fields. Use them. 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // We have to be able to fetch its value, even if it is private 333ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes f.setAccessible(true); 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // static field, pass null 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _fields = (ObjectStreamField[]) f.get(null); 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalAccessException ex) { 3387d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes throw new AssertionError(ex); 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Compute collection of dumpable fields based on reflect fields 3427d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes List<ObjectStreamField> serializableFields = 3437d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes new ArrayList<ObjectStreamField>(declaredFields.length); 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Filter, we are only interested in fields that are serializable 3457d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes for (Field declaredField : declaredFields) { 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = declaredField.getModifiers(); 3477d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) { 3487d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes ObjectStreamField field = new ObjectStreamField(declaredField.getName(), 3497d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes declaredField.getType()); 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project serializableFields.add(field); 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (serializableFields.size() == 0) { 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _fields = NO_FIELDS; // If no serializable fields, share the 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // special value so that users can test 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 3587d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes _fields = serializableFields.toArray(new ObjectStreamField[serializableFields.size()]); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3617d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes Arrays.sort(_fields); 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // assign offsets 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int primOffset = 0, objectOffset = 0; 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < _fields.length; i++) { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> type = _fields[i].getType(); 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (type.isPrimitive()) { 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _fields[i].offset = primOffset; 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project primOffset += primitiveSize(type); 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project _fields[i].offset = objectOffset++; 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fields = _fields; 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 375f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compute and return the Serial Version UID of the class {@code cl}. 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The value is computed based on the class name, superclass chain, field 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * names, method names, modifiers, etc. 380f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class for which to compute the SUID 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param fields 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * cl.getDeclaredFields(), pre-computed by the caller 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the value of SUID of this class 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static long computeSerialVersionUID(Class<?> cl, Field[] fields) { 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * First we should try to fetch the static slot 'static final long 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * serialVersionUID'. If it is defined, return it. If not defined, we 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * really need to compute SUID using SHAOutputStream 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < fields.length; i++) { 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project final Field field = fields[i]; 395e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (field.getType() == long.class) { 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = field.getModifiers(); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers)) { 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (UID_FIELD_NAME.equals(field.getName())) { 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * We need to be able to see it even if we have no 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * visibility. That is why we set accessible first (new 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * API in reflect 1.2) 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 404ad41624e761bcf1af9c8008eb45187fc13983717Elliott Hughes field.setAccessible(true); 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Static field, parameter is ignored 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return field.getLong(null); 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IllegalAccessException iae) { 409b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new RuntimeException("Error fetching SUID: " + iae); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project MessageDigest digest; 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 418f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes digest = MessageDigest.getInstance("SHA"); 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NoSuchAlgorithmException e) { 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new Error(e); 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ByteArrayOutputStream sha = new ByteArrayOutputStream(); 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DataOutputStream output = new DataOutputStream(sha); 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(cl.getName()); 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int classModifiers = CLASS_MODIFIERS_MASK & cl.getModifiers(); 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Workaround for 1F9LOQO. Arrays are ABSTRACT in JDK, but that is 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not in the specification. Since we want to be compatible for 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * X-loading, we have to pretend we have the same shape 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isArray = cl.isArray(); 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isArray) { 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classModifiers |= Modifier.ABSTRACT; 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Required for JDK UID compatibility 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (cl.isInterface() && !Modifier.isPublic(classModifiers)) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project classModifiers &= ~Modifier.ABSTRACT; 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeInt(classModifiers); 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * In JDK1.2 arrays implement Cloneable and Serializable but not in 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * JDK 1.1.7. So, JDK 1.2 "pretends" arrays have no interfaces when 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * computing SHA-1 to be compatible. 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isArray) { 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Interface information 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?>[] interfaces = cl.getInterfaces(); 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (interfaces.length > 1) { 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only attempt to sort if really needed (saves object 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // creation, etc) 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Comparator<Class<?>> interfaceComparator = new Comparator<Class<?>>() { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compare(Class<?> itf1, Class<?> itf2) { 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return itf1.getName().compareTo(itf2.getName()); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Arrays.sort(interfaces, interfaceComparator); 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Dump them 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < interfaces.length; i++) { 463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(interfaces[i].getName()); 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Field information 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (fields.length > 1) { 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only attempt to sort if really needed (saves object creation, 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // etc) 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Comparator<Field> fieldComparator = new Comparator<Field>() { 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compare(Field field1, Field field2) { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return field1.getName().compareTo(field2.getName()); 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Arrays.sort(fields, fieldComparator); 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Dump them 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < fields.length; i++) { 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Field field = fields[i]; 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = field.getModifiers() & FIELD_MODIFIERS_MASK; 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 48405895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes boolean skip = Modifier.isPrivate(modifiers) && 48505895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes (Modifier.isTransient(modifiers) || Modifier.isStatic(modifiers)); 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!skip) { 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // write name, modifier & "descriptor" of all but private 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // static and private transient 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(field.getName()); 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeInt(modifiers); 49105895faacf43e6fd2bcd57baed31832f6888cb31Elliott Hughes output.writeUTF(descriptorForFieldSignature(getFieldSignature(field))); 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Normally constructors come before methods (because <init> < 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * anyMethodName). However, <clinit> is an exception. Besides, 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * reflect will not let us get to it. 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (hasClinit(cl)) { 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // write name, modifier & "descriptor" 502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(CLINIT_NAME); 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeInt(CLINIT_MODIFIERS); 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(CLINIT_SIGNATURE); 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Constructor information 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Constructor<?>[] constructors = cl.getDeclaredConstructors(); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (constructors.length > 1) { 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Only attempt to sort if really needed (saves object creation, 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // etc) 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Comparator<Constructor<?>> constructorComparator = new Comparator<Constructor<?>>() { 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compare(Constructor<?> ctr1, Constructor<?> ctr2) { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // All constructors have same name, so we sort based on 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // signature 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (getConstructorSignature(ctr1) 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .compareTo(getConstructorSignature(ctr2))); 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Arrays.sort(constructors, constructorComparator); 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Dump them 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < constructors.length; i++) { 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Constructor<?> constructor = constructors[i]; 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = constructor.getModifiers() 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project & METHOD_MODIFIERS_MASK; 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isPrivate = Modifier.isPrivate(modifiers); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isPrivate) { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write name, modifier & "descriptor" of all but private 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ones 533f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * constructor.getName() returns the constructor name as 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * typed, not the VM name 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 537f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes output.writeUTF("<init>"); 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeInt(modifiers); 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(descriptorForSignature( 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getConstructorSignature(constructor)).replace('/', 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project '.')); 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Method information 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Method[] methods = cl.getDeclaredMethods(); 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (methods.length > 1) { 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Comparator<Method> methodComparator = new Comparator<Method>() { 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compare(Method m1, Method m2) { 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int result = m1.getName().compareTo(m2.getName()); 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == 0) { 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // same name, signature will tell which one comes 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // first 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return getMethodSignature(m1).compareTo( 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getMethodSignature(m2)); 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Arrays.sort(methods, methodComparator); 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Dump them 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < methods.length; i++) { 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Method method = methods[i]; 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = method.getModifiers() & METHOD_MODIFIERS_MASK; 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean isPrivate = Modifier.isPrivate(modifiers); 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!isPrivate) { 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // write name, modifier & "descriptor" of all but private 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // ones 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(method.getName()); 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeInt(modifiers); 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project output.writeUTF(descriptorForSignature( 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project getMethodSignature(method)).replace('/', '.')); 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (IOException e) { 578b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new RuntimeException(e + " computing SHA-1/SUID"); 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 580adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // now compute the UID based on the SHA 582adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte[] hash = digest.digest(sha.toByteArray()); 583f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes return Memory.peekLong(hash, 0, ByteOrder.LITTLE_ENDIAN); 584adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 587b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes * Returns what the serialization specification calls "descriptor" given a 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * field signature. 589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param signature 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a field signature 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return containing the descriptor 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static String descriptorForFieldSignature(String signature) { 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return signature.replace('.', '/'); 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 599b5bde2fd72189192b52e726a2d606d70c3c8a34bElliott Hughes * Return what the serialization specification calls "descriptor" given a 600adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method/constructor signature. 601f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param signature 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a method or constructor signature 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return containing the descriptor 605adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static String descriptorForSignature(String signature) { 607f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes return signature.substring(signature.indexOf("(")); 608adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 611adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return the java.lang.reflect.Field {@code serialPersistentFields} 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if class {@code cl} implements it. Return null otherwise. 613f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 614adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code java.lang.reflect.Field} if the class has 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * serialPersistentFields {@code null} if the class does not 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * have serialPersistentFields 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static Field fieldSerialPersistentFields(Class<?> cl) { 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 622f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes Field f = cl.getDeclaredField("serialPersistentFields"); 623adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int modifiers = f.getModifiers(); 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (Modifier.isStatic(modifiers) && Modifier.isPrivate(modifiers) 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && Modifier.isFinal(modifiers)) { 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (f.getType() == ARRAY_OF_FIELDS) { 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return f; 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NoSuchFieldException nsm) { 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Ignored 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 637adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the class (java.lang.Class) for this descriptor. 638f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the class in the local VM that this descriptor represents; 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} if there is no corresponding class. 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Class<?> forClass() { 64332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return resolvedClass; 64432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 64532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 6466523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes /** 6476523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * Create and return a new instance of class 'instantiationClass' 6486523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * using JNI to call the constructor chosen by resolveConstructorClass. 6496523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * 6506523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes * The returned instance may have uninitialized fields, including final fields. 6516523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes */ 6526523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes Object newInstance(Class<?> instantiationClass) throws InvalidClassException { 6536523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes resolveConstructorClass(instantiationClass); 6546523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes return newInstance(instantiationClass, resolvedConstructorMethodId); 6556523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes } 656a40dc9f768eb02dcfd7b1a659333757b148f7becJoel Dice private static native Object newInstance(Class<?> instantiationClass, long methodId); 6576523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes 6586523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes private Class<?> resolveConstructorClass(Class<?> objectClass) throws InvalidClassException { 65932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (resolvedConstructorClass != null) { 66032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return resolvedConstructorClass; 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 66232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 66332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // The class of the instance may not be the same as the class of the 66432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // constructor to run 66532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // This is the constructor to run if Externalizable 66632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes Class<?> constructorClass = objectClass; 66732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 66832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // WARNING - What if the object is serializable and externalizable ? 66932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Is that possible ? 67032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean wasSerializable = (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0; 67132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (wasSerializable) { 67232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Now we must run the constructor of the class just above the 67332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // one that implements Serializable so that slots that were not 67432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // dumped can be initialized properly 67532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes while (constructorClass != null && ObjectStreamClass.isSerializable(constructorClass)) { 67632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes constructorClass = constructorClass.getSuperclass(); 67732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 67832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 67932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 68032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Fetch the empty constructor, or null if none. 68132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes Constructor<?> constructor = null; 68232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (constructorClass != null) { 68332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes try { 68432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes constructor = constructorClass.getDeclaredConstructor(EmptyArray.CLASS); 68532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } catch (NoSuchMethodException ignored) { 68632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 68732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 68832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 68932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Has to have an empty constructor 69032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (constructor == null) { 69132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes String className = constructorClass != null ? constructorClass.getName() : null; 69232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes throw new InvalidClassException(className, "IllegalAccessException"); 69332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 69432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 69532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes int constructorModifiers = constructor.getModifiers(); 69632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean isPublic = Modifier.isPublic(constructorModifiers); 69732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean isProtected = Modifier.isProtected(constructorModifiers); 69832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean isPrivate = Modifier.isPrivate(constructorModifiers); 69932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 70032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Now we must check if the empty constructor is visible to the 70132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // instantiation class 70232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes boolean wasExternalizable = (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0; 70332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (isPrivate || (wasExternalizable && !isPublic)) { 70432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes throw new InvalidClassException(constructorClass.getName(), "IllegalAccessException"); 70532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 70632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 70732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // We know we are testing from a subclass, so the only other case 70832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // where the visibility is not allowed is when the constructor has 70932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // default visibility and the instantiation class is in a different 71032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // package than the constructor class 71132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (!isPublic && !isProtected) { 71232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // Not public, not private and not protected...means default 71332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes // visibility. Check if same package 71432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (!inSamePackage(constructorClass, objectClass)) { 71532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes throw new InvalidClassException(constructorClass.getName(), "IllegalAccessException"); 71632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 71732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 71832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 71932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes resolvedConstructorClass = constructorClass; 7206523532145f06d8c208ed7a9374d3ab6d8132e66Elliott Hughes resolvedConstructorMethodId = getConstructorId(resolvedConstructorClass); 72132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return constructorClass; 72232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 723a40dc9f768eb02dcfd7b1a659333757b148f7becJoel Dice private static native long getConstructorId(Class<?> c); 72432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes 72532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes /** 72632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * Checks if two classes belong to the same package. 72732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * 72832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * @param c1 72932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * one of the classes to test. 73032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * @param c2 73132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * the other class to test. 73232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * @return {@code true} if the two classes belong to the same package, 73332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes * {@code false} otherwise. 73432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes */ 73532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes private boolean inSamePackage(Class<?> c1, Class<?> c2) { 73632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes String nameC1 = c1.getName(); 73732ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes String nameC2 = c2.getName(); 73832ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes int indexDotC1 = nameC1.lastIndexOf('.'); 73932ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes int indexDotC2 = nameC2.lastIndexOf('.'); 74032ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (indexDotC1 != indexDotC2) { 74132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return false; // cannot be in the same package if indices are not the same 74232ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 74332ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes if (indexDotC1 == -1) { 74432ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return true; // both of them are in default package 74532ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes } 74632ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes return nameC1.regionMatches(0, nameC2, 0, indexDotC1); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return a String representing the signature for a Constructor {@code c}. 751f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.reflect.Constructor for which to compute the 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * signature 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the constructor's signature 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static native String getConstructorSignature(Constructor<?> c); 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a field descriptor of the class represented by this class 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 762f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the desired field. 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the field identified by {@code name} or {@code null} if there is 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * no such field. 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ObjectStreamField getField(String name) { 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] allFields = getFields(); 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < allFields.length; i++) { 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField f = allFields[i]; 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (f.getName().equals(name)) { 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return f; 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the collection of field descriptors for the fields of the 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corresponding class 782f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the receiver's collection of declared fields for the class it 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represents 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] fields() { 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (fields == null) { 788f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Class<?> forCl = forClass(); 789f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (forCl != null && isSerializable() && !forCl.isArray()) { 790f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson buildFieldDescriptors(forCl.getDeclaredFields()); 791f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 792f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Externalizables or arrays do not need FieldDesc info 793f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson setFields(NO_FIELDS); 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return fields; 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a collection of field descriptors for the serialized fields of 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the class represented by this class descriptor. 802f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of field descriptors or an array of length zero if there 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * are no fields in this descriptor's class. 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public ObjectStreamField[] getFields() { 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project copyFieldAttributes(); 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loadFields == null ? fields().clone() : loadFields.clone(); 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 81178b020b8412d212fa052b7ddf630ca6058c846beElliott Hughes private transient volatile List<ObjectStreamClass> cachedHierarchy; 81246241f2f67d7b90e20f3301861f807f330687821Elliott Hughes 81346241f2f67d7b90e20f3301861f807f330687821Elliott Hughes List<ObjectStreamClass> getHierarchy() { 81446241f2f67d7b90e20f3301861f807f330687821Elliott Hughes List<ObjectStreamClass> result = cachedHierarchy; 81546241f2f67d7b90e20f3301861f807f330687821Elliott Hughes if (result == null) { 81646241f2f67d7b90e20f3301861f807f330687821Elliott Hughes cachedHierarchy = result = makeHierarchy(); 81746241f2f67d7b90e20f3301861f807f330687821Elliott Hughes } 81846241f2f67d7b90e20f3301861f807f330687821Elliott Hughes return result; 81946241f2f67d7b90e20f3301861f807f330687821Elliott Hughes } 82046241f2f67d7b90e20f3301861f807f330687821Elliott Hughes 82146241f2f67d7b90e20f3301861f807f330687821Elliott Hughes private List<ObjectStreamClass> makeHierarchy() { 82246241f2f67d7b90e20f3301861f807f330687821Elliott Hughes ArrayList<ObjectStreamClass> result = new ArrayList<ObjectStreamClass>(); 82346241f2f67d7b90e20f3301861f807f330687821Elliott Hughes for (ObjectStreamClass osc = this; osc != null; osc = osc.getSuperclass()) { 82446241f2f67d7b90e20f3301861f807f330687821Elliott Hughes result.add(0, osc); 82546241f2f67d7b90e20f3301861f807f330687821Elliott Hughes } 82646241f2f67d7b90e20f3301861f807f330687821Elliott Hughes return result; 82746241f2f67d7b90e20f3301861f807f330687821Elliott Hughes } 82846241f2f67d7b90e20f3301861f807f330687821Elliott Hughes 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 830f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * If a Class uses "serialPersistentFields" to define the serialized fields, 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this.loadFields cannot get the "unshared" information when deserializing 832f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * fields using current implementation of ObjectInputStream. This method 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * provides a way to copy the "unshared" attribute from this.fields. 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void copyFieldAttributes() { 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((loadFields == null) || fields == null) { 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return; 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 840f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < loadFields.length; i++) { 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField loadField = loadFields[i]; 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = loadField.getName(); 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = 0; j < fields.length; j++) { 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField field = fields[j]; 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.equals(field.getName())) { 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loadField.setUnshared(field.isUnshared()); 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loadField.setOffset(field.getOffset()); 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the collection of field descriptors for the input fields of the 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corresponding class 858f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the receiver's collection of input fields for the class it 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represents 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamField[] getLoadFields() { 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return loadFields; 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return a String representing the signature for a field {@code f}. 868f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param f 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.reflect.Field for which to compute the signature 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the field's signature 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static native String getFieldSignature(Field f); 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the flags for this descriptor, where possible combined values are 877f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_WRITE_METHOD 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_SERIALIZABLE 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_EXTERNALIZABLE 881f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return byte the receiver's flags for the class it represents 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte getFlags() { 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return flags; 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return a String representing the signature for a method {@code m}. 890f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param m 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.reflect.Method for which to compute the signature 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the method's signature 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static native String getMethodSignature(Method m); 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the class represented by this descriptor. 899f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the fully qualified name of the class this descriptor represents. 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return className; 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 905adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 906adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 907adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the Serial Version User ID of the class represented by this 908adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 909f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 910adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the SUID for the class represented by this descriptor. 911adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 912adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getSerialVersionUID() { 913adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return svUID; 914adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 915adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 916adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 917adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the descriptor (ObjectStreamClass) of the superclass of the class 918adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represented by the receiver. 919f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 920adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an ObjectStreamClass representing the superclass of the class 921adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represented by the receiver. 922adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 923adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ObjectStreamClass getSuperclass() { 924adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return superclass; 925adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 926adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 927adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 928adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return true if the given class {@code cl} has the 929adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * compiler-generated method {@code clinit}. Even though it is 930adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * compiler-generated, it is used by the serialization code to compute SUID. 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is unfortunate, since it may depend on compiler optimizations in 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * some cases. 933f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the class has <clinit> {@code false} 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the class does not have <clinit> 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 939adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static native boolean hasClinit(Class<?> cl); 940adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 941adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 942adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return true if instances of class {@code cl} are Externalizable, 943adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false otherwise. 944f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 947adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if instances of the class are Externalizable 948adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} if instances of the class are not 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Externalizable 950f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 951adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Object#hashCode 952adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 953adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static boolean isExternalizable(Class<?> cl) { 954adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return EXTERNALIZABLE.isAssignableFrom(cl); 955adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 956adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 957adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 958adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return true if the type code 959adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <code>typecode<code> describes a primitive type 960adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 961adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param typecode a char describing the typecode 962f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @return {@code true} if the typecode represents a primitive type 963adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} if the typecode represents an Object type (including arrays) 964adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 965adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Object#hashCode 966adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 967adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static boolean isPrimitiveType(char typecode) { 968adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return !(typecode == '[' || typecode == 'L'); 969adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 970adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 971adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 972adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return true if instances of class {@code cl} are Serializable, 973adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * false otherwise. 974f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 975adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 976adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 977adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if instances of the class are Serializable 978adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} if instances of the class are not 979adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Serializable 980f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 981adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Object#hashCode 982adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 983adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static boolean isSerializable(Class<?> cl) { 984adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return SERIALIZABLE.isAssignableFrom(cl); 985adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 986adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 987adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 988f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Resolves the class properties, if they weren't already 989f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 990f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private void resolveProperties() { 991f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (arePropertiesResolved) { 992f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return; 993f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 994f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 995f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Class<?> cl = forClass(); 996f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson isProxy = Proxy.isProxyClass(cl); 997f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson isEnum = Enum.class.isAssignableFrom(cl); 998f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson isSerializable = isSerializable(cl); 999f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson isExternalizable = isExternalizable(cl); 1000f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1001f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson arePropertiesResolved = true; 1002f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1003f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1004f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean isSerializable() { 1005f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson resolveProperties(); 1006f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return isSerializable; 1007f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1008f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1009f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean isExternalizable() { 1010f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson resolveProperties(); 1011f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return isExternalizable; 1012f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1013f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1014f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean isProxy() { 1015f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson resolveProperties(); 1016f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return isProxy; 1017f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1018f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1019f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean isEnum() { 1020f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson resolveProperties(); 1021f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return isEnum; 1022f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1023f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1024f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /** 1025a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * Returns the descriptor for a serializable class. 1026a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * Returns null if the class doesn't implement {@code Serializable} or {@code Externalizable}. 1027f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1028adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 1029a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * a java.lang.Class for which to obtain the corresponding 1030adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor 1031a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * @return the corresponding descriptor if the class is serializable or 1032a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * externalizable; null otherwise. 1033adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static ObjectStreamClass lookup(Class<?> cl) { 1035f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson ObjectStreamClass osc = lookupStreamClass(cl); 10367d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes return (osc.isSerializable() || osc.isExternalizable()) ? osc : null; 1037adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1040a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * Returns the descriptor for any class, whether or not the class 1041a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * implements Serializable or Externalizable. 1042f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 1043a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * @param cl 1044a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * a java.lang.Class for which to obtain the corresponding 1045a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * descriptor 1046a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * @return the descriptor 1047a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes * @since 1.6 1048a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes */ 1049a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes public static ObjectStreamClass lookupAny(Class<?> cl) { 10507d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes return lookupStreamClass(cl); 1051a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes } 1052a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes 1053a845eec505ce5314b1a8be3d8dd6cc46bda782f7Elliott Hughes /** 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Return the descriptor (ObjectStreamClass) corresponding to the class 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code cl}. Returns an ObjectStreamClass even if instances of the 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class cannot be serialized 1057f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.langClass for which to obtain the corresponding 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the corresponding descriptor 1062adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static ObjectStreamClass lookupStreamClass(Class<?> cl) { 10647d0d108593ac30e19b8f2a5a157f697f3f46c041Elliott Hughes WeakHashMap<Class<?>, ObjectStreamClass> tlc = getCache(); 1065f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson ObjectStreamClass cachedValue = tlc.get(cl); 1066f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (cachedValue == null) { 1067f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson cachedValue = createClassDesc(cl); 1068f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tlc.put(cl, cachedValue); 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1070f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return cachedValue; 1071f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 107556e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes * A ThreadLocal cache for lookupStreamClass, with the possibility of discarding the thread 107656e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes * local storage content when the heap is exhausted. 107756e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes */ 107856e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes private static SoftReference<ThreadLocal<WeakHashMap<Class<?>, ObjectStreamClass>>> storage = 107956e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes new SoftReference<ThreadLocal<WeakHashMap<Class<?>, ObjectStreamClass>>>(null); 108056e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes 108156e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes private static WeakHashMap<Class<?>, ObjectStreamClass> getCache() { 108256e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes ThreadLocal<WeakHashMap<Class<?>, ObjectStreamClass>> tls = storage.get(); 108356e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes if (tls == null) { 108456e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes tls = new ThreadLocal<WeakHashMap<Class<?>, ObjectStreamClass>>() { 108556e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes public WeakHashMap<Class<?>, ObjectStreamClass> initialValue() { 108656e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes return new WeakHashMap<Class<?>, ObjectStreamClass>(); 108756e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes } 108856e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes }; 108956e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes storage = new SoftReference<ThreadLocal<WeakHashMap<Class<?>, ObjectStreamClass>>>(tls); 109056e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes } 109156e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes return tls.get(); 109256e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes } 109356e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes 109456e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes /** 1095f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Return the java.lang.reflect.Method if class <code>cl</code> implements 1096f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * <code>methodName</code> . Return null otherwise. 1097f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1098adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 1099adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 1100f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @return <code>java.lang.reflect.Method</code> if the class implements 1101f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * writeReplace <code>null</code> if the class does not implement 1102f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * writeReplace 1103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1104f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson static Method findMethod(Class<?> cl, String methodName) { 1105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Class<?> search = cl; 1106f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method method = null; 1107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (search != null) { 1108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1109f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson method = search.getDeclaredMethod(methodName, (Class[]) null); 1110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (search == cl 1111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project || (method.getModifiers() & Modifier.PRIVATE) == 0) { 1112f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson method.setAccessible(true); 1113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return method; 1114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NoSuchMethodException nsm) { 1116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project search = search.getSuperclass(); 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Return the java.lang.reflect.Method if class <code>cl</code> implements 1124f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * private <code>methodName</code> . Return null otherwise. 1125f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param cl 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a java.lang.Class which to test 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code java.lang.reflect.Method} if the class implements 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * writeReplace {@code null} if the class does not implement 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * writeReplace 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1132f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson static Method findPrivateMethod(Class<?> cl, String methodName, 1133f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Class<?>[] param) { 1134f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson try { 1135f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method method = cl.getDeclaredMethod(methodName, param); 1136e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (Modifier.isPrivate(method.getModifiers()) && method.getReturnType() == void.class) { 1137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson method.setAccessible(true); 1138f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return method; 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1140f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } catch (NoSuchMethodException nsm) { 1141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // Ignored 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1146f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean hasMethodWriteReplace() { 1147f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (methodWriteReplace != null); 1148f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1149f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1150f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method getMethodWriteReplace() { 1151f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return methodWriteReplace; 1152f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1153f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1154f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean hasMethodReadResolve() { 1155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (methodReadResolve != null); 1156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method getMethodReadResolve() { 1159f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return methodReadResolve; 1160f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1161f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1162f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean hasMethodWriteObject() { 1163f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (methodWriteObject != null); 1164f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1165f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1166f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method getMethodWriteObject() { 1167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return methodWriteObject; 1168f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1169f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1170f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean hasMethodReadObject() { 1171f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (methodReadObject != null); 1172f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1173f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1174f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method getMethodReadObject() { 1175f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return methodReadObject; 1176f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1177f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1178f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean hasMethodReadObjectNoData() { 1179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return (methodReadObjectNoData != null); 1180f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1181f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1182f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson Method getMethodReadObjectNoData() { 1183f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return methodReadObjectNoData; 1184f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1185f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1186f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson void initPrivateFields(ObjectStreamClass desc) { 1187f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson methodWriteReplace = desc.methodWriteReplace; 1188f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson methodReadResolve = desc.methodReadResolve; 1189f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson methodWriteObject = desc.methodWriteObject; 1190f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson methodReadObject = desc.methodReadObject; 1191f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson methodReadObjectNoData = desc.methodReadObjectNoData; 1192f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1193f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the class (java.lang.Class) that the receiver represents 1196f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 1198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * aClass, the new class that the receiver describes 1199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setClass(Class<?> c) { 120132ef29bcbfdce08d58ea72bd15a12a96065bdbb6Elliott Hughes resolvedClass = c; 1202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the collection of field descriptors for the fields of the 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corresponding class 1207f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param f 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamField[], the receiver's new collection of declared 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fields for the class it represents 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setFields(ObjectStreamField[] f) { 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project fields = f; 1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the collection of field descriptors for the input fields of the 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * corresponding class 1219f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param f 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamField[], the receiver's new collection of input 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * fields for the class it represents 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setLoadFields(ObjectStreamField[] f) { 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project loadFields = f; 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the flags for this descriptor, where possible combined values are 1230f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_WRITE_METHOD 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_SERIALIZABLE 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ObjectStreamConstants.SC_EXTERNALIZABLE 1234f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param b 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * byte, the receiver's new flags for the class it represents 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setFlags(byte b) { 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flags = b; 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the name of the class represented by the receiver 1244f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param newName 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a String, the new fully qualified name of the class the 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver represents 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setName(String newName) { 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project className = newName; 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the Serial Version User ID of the class represented by the receiver 1255f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param l 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a long, the new SUID for the class represented by the receiver 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setSerialVersionUID(long l) { 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project svUID = l; 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Set the descriptor for the superclass of the class described by the 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * receiver 1266f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param c 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * an ObjectStreamClass, the new ObjectStreamClass for the 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * superclass of the class represented by the receiver 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project void setSuperclass(ObjectStreamClass c) { 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project superclass = c; 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private int primitiveSize(Class<?> type) { 1276e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == byte.class || type == boolean.class) { 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 1; 1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1279e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == short.class || type == char.class) { 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 2; 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1282e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == int.class || type == float.class) { 1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 4; 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1285e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes if (type == long.class || type == double.class) { 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return 8; 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1288e26ba79900d471d02d656f686926918ef7dc751fElliott Hughes throw new AssertionError(); 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * descriptor. 1294f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation of this descriptor. 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 129956e742806ebb265e77de750cdb4575cff781fdf8Elliott Hughes return getName() + ": static final long serialVersionUID =" + getSerialVersionUID() + "L;"; 1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1302