1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.databinding; 18 19 import android.os.Parcel; 20 import android.os.Parcelable; 21 import android.test.AndroidTestCase; 22 23 import java.io.ByteArrayInputStream; 24 import java.io.ByteArrayOutputStream; 25 import java.io.Closeable; 26 import java.io.IOException; 27 import java.io.ObjectInputStream; 28 import java.io.ObjectOutputStream; 29 import java.io.Serializable; 30 import java.util.UUID; 31 32 public class ObservableParcelTest extends AndroidTestCase { testParcelInt()33 public void testParcelInt() { 34 ObservableInt observableInt = new ObservableInt(); 35 observableInt.set(Integer.MAX_VALUE - 1); 36 ObservableInt read = parcelAndUnparcel(observableInt, ObservableInt.class); 37 assertEquals(Integer.MAX_VALUE - 1, read.get()); 38 } 39 testParcelBoolean()40 public void testParcelBoolean() { 41 ObservableBoolean obj = new ObservableBoolean(false); 42 ObservableBoolean read = parcelAndUnparcel(obj, ObservableBoolean.class); 43 assertFalse(read.get()); 44 45 ObservableBoolean obj2 = new ObservableBoolean(true); 46 ObservableBoolean read2 = parcelAndUnparcel(obj2, ObservableBoolean.class); 47 assertTrue(read2.get()); 48 } 49 testParcelByte()50 public void testParcelByte() { 51 ObservableByte obj = new ObservableByte((byte) 7); 52 ObservableByte read = parcelAndUnparcel(obj, ObservableByte.class); 53 assertEquals((byte) 7, read.get()); 54 } 55 testParcelChar()56 public void testParcelChar() { 57 ObservableChar obj = new ObservableChar('y'); 58 ObservableChar read = parcelAndUnparcel(obj, ObservableChar.class); 59 assertEquals('y', read.get()); 60 } 61 testParcelDouble()62 public void testParcelDouble() { 63 ObservableDouble obj = new ObservableDouble(Double.MAX_VALUE); 64 ObservableDouble read = parcelAndUnparcel(obj, ObservableDouble.class); 65 assertEquals(Double.MAX_VALUE, read.get()); 66 } 67 testParcelFloat()68 public void testParcelFloat() { 69 ObservableFloat obj = new ObservableFloat(Float.MIN_VALUE); 70 ObservableFloat read = parcelAndUnparcel(obj, ObservableFloat.class); 71 assertEquals(Float.MIN_VALUE, read.get()); 72 } 73 testParcelParcel()74 public void testParcelParcel() { 75 MyParcelable myParcelable = new MyParcelable(5, "foo"); 76 ObservableParcelable<MyParcelable> obj = new ObservableParcelable<>(myParcelable); 77 ObservableParcelable read = parcelAndUnparcel(obj, 78 ObservableParcelable.class); 79 assertEquals(myParcelable, read.get()); 80 } 81 testParcelLong()82 public void testParcelLong() { 83 ObservableLong obj = new ObservableLong(Long.MAX_VALUE - 1); 84 ObservableLong read = parcelAndUnparcel(obj, ObservableLong.class); 85 assertEquals(Long.MAX_VALUE - 1, read.get()); 86 } 87 testParcelShort()88 public void testParcelShort() { 89 ObservableShort obj = new ObservableShort(Short.MIN_VALUE); 90 ObservableShort read = parcelAndUnparcel(obj, ObservableShort.class); 91 assertEquals(Short.MIN_VALUE, read.get()); 92 } 93 testSerializeInt()94 public void testSerializeInt() throws IOException, ClassNotFoundException { 95 ObservableInt observableInt = new ObservableInt(); 96 observableInt.set(Integer.MAX_VALUE - 1); 97 ObservableInt read = serializeAndDeserialize(observableInt, ObservableInt.class); 98 assertEquals(Integer.MAX_VALUE - 1, read.get()); 99 } 100 testSerializeBoolean()101 public void testSerializeBoolean() throws IOException, ClassNotFoundException { 102 ObservableBoolean obj = new ObservableBoolean(false); 103 ObservableBoolean read = serializeAndDeserialize(obj, ObservableBoolean.class); 104 assertFalse(read.get()); 105 ObservableBoolean obj2 = new ObservableBoolean(true); 106 ObservableBoolean read2 = serializeAndDeserialize(obj2, ObservableBoolean.class); 107 assertTrue(read2.get()); 108 } 109 testSerializeByte()110 public void testSerializeByte() throws IOException, ClassNotFoundException { 111 ObservableByte obj = new ObservableByte((byte) 7); 112 ObservableByte read = serializeAndDeserialize(obj, ObservableByte.class); 113 assertEquals((byte) 7, read.get()); 114 } 115 testSerializeChar()116 public void testSerializeChar() throws IOException, ClassNotFoundException { 117 ObservableChar obj = new ObservableChar('y'); 118 ObservableChar read = serializeAndDeserialize(obj, ObservableChar.class); 119 assertEquals('y', read.get()); 120 } 121 testSerializeDouble()122 public void testSerializeDouble() throws IOException, ClassNotFoundException { 123 ObservableDouble obj = new ObservableDouble(Double.MAX_VALUE); 124 ObservableDouble read = serializeAndDeserialize(obj, ObservableDouble.class); 125 assertEquals(Double.MAX_VALUE, read.get()); 126 } 127 testSerializeFloat()128 public void testSerializeFloat() throws IOException, ClassNotFoundException { 129 ObservableFloat obj = new ObservableFloat(Float.MIN_VALUE); 130 ObservableFloat read = serializeAndDeserialize(obj, ObservableFloat.class); 131 assertEquals(Float.MIN_VALUE, read.get()); 132 } 133 testSerializeParcel()134 public void testSerializeParcel() throws IOException, ClassNotFoundException { 135 MyParcelable myParcelable = new MyParcelable(5, "foo"); 136 ObservableParcelable<MyParcelable> obj = new ObservableParcelable<>(myParcelable); 137 ObservableParcelable read = serializeAndDeserialize(obj, 138 ObservableParcelable.class); 139 assertEquals(myParcelable, read.get()); 140 } 141 testSerializeField()142 public void testSerializeField() throws IOException, ClassNotFoundException { 143 MyParcelable myParcelable = new MyParcelable(5, "foo"); 144 ObservableField<MyParcelable> obj = new ObservableField<>(myParcelable); 145 ObservableField read = serializeAndDeserialize(obj, ObservableField.class); 146 assertEquals(myParcelable, read.get()); 147 } 148 testSerializeLong()149 public void testSerializeLong() throws IOException, ClassNotFoundException { 150 ObservableLong obj = new ObservableLong(Long.MAX_VALUE - 1); 151 ObservableLong read = serializeAndDeserialize(obj, ObservableLong.class); 152 assertEquals(Long.MAX_VALUE - 1, read.get()); 153 } 154 testSerializeShort()155 public void testSerializeShort() throws IOException, ClassNotFoundException { 156 ObservableShort obj = new ObservableShort(Short.MIN_VALUE); 157 ObservableShort read = serializeAndDeserialize(obj, ObservableShort.class); 158 assertEquals(Short.MIN_VALUE, read.get()); 159 } 160 parcelAndUnparcel(T t, Class<T> klass)161 private <T extends Parcelable> T parcelAndUnparcel(T t, Class<T> klass) { 162 Parcel parcel = Parcel.obtain(); 163 parcel.writeParcelable(t, 0); 164 // we append a suffix to the parcelable to test out of bounds 165 String parcelSuffix = UUID.randomUUID().toString(); 166 parcel.writeString(parcelSuffix); 167 // get ready to read 168 parcel.setDataPosition(0); 169 Parcelable parcelable = parcel.readParcelable(getClass().getClassLoader()); 170 assertNotNull(parcelable); 171 assertEquals(klass, parcelable.getClass()); 172 assertEquals(parcelSuffix, parcel.readString()); 173 return (T) parcelable; 174 } 175 serializeAndDeserialize(T t, Class<T> klass)176 private <T> T serializeAndDeserialize(T t, Class<T> klass) 177 throws IOException, ClassNotFoundException { 178 ObjectOutputStream oos = null; 179 ByteArrayOutputStream bos = null; 180 String suffix = UUID.randomUUID().toString(); 181 try { 182 bos = new ByteArrayOutputStream(); 183 oos = new ObjectOutputStream(bos); 184 oos.writeObject(t); 185 oos.writeObject(suffix); 186 } finally { 187 closeQuietly(bos); 188 closeQuietly(oos); 189 } 190 ByteArrayInputStream bis = null; 191 ObjectInputStream ois = null; 192 try { 193 bis = new ByteArrayInputStream(bos.toByteArray()); 194 ois = new ObjectInputStream(bis); 195 Object o = ois.readObject(); 196 assertEquals(klass, o.getClass()); 197 assertEquals(suffix, ois.readObject()); 198 return (T) o; 199 } finally { 200 closeQuietly(bis); 201 closeQuietly(ois); 202 } 203 } 204 closeQuietly(Closeable closeable)205 private static void closeQuietly(Closeable closeable) { 206 try { 207 if (closeable != null) { 208 closeable.close(); 209 } 210 } catch (IOException ignored) { 211 } 212 } 213 214 public static class MyParcelable implements Parcelable, Serializable { 215 int x; 216 String y; 217 MyParcelable()218 public MyParcelable() { 219 } 220 MyParcelable(int x, String y)221 public MyParcelable(int x, String y) { 222 this.x = x; 223 this.y = y; 224 } 225 226 @Override describeContents()227 public int describeContents() { 228 return 0; 229 } 230 231 @Override writeToParcel(Parcel dest, int flags)232 public void writeToParcel(Parcel dest, int flags) { 233 dest.writeInt(x); 234 dest.writeString(y); 235 } 236 237 @Override equals(Object o)238 public boolean equals(Object o) { 239 if (this == o) { 240 return true; 241 } 242 if (o == null || getClass() != o.getClass()) { 243 return false; 244 } 245 246 MyParcelable that = (MyParcelable) o; 247 248 if (x != that.x) { 249 return false; 250 } 251 if (y != null ? !y.equals(that.y) : that.y != null) { 252 return false; 253 } 254 255 return true; 256 } 257 258 @Override hashCode()259 public int hashCode() { 260 int result = x; 261 result = 31 * result + (y != null ? y.hashCode() : 0); 262 return result; 263 } 264 265 public static final Parcelable.Creator<MyParcelable> CREATOR 266 = new Parcelable.Creator<MyParcelable>() { 267 268 @Override 269 public MyParcelable createFromParcel(Parcel source) { 270 return new MyParcelable(source.readInt(), source.readString()); 271 } 272 273 @Override 274 public MyParcelable[] newArray(int size) { 275 return new MyParcelable[size]; 276 } 277 }; 278 } 279 } 280