Merge "Add CarFragmentActivity"
diff --git a/car-libs/car-core/src/android/support/car/annotation/VersionDef.java b/car-libs/car-core/src/android/support/car/annotation/VersionDef.java
new file mode 100644
index 0000000..21ad653
--- /dev/null
+++ b/car-libs/car-core/src/android/support/car/annotation/VersionDef.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.car.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for specifying supported version of member for a Parcelable.
+ * Version defaults to 1 if only @VersionDef is used without specifying version.
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.SOURCE)
+public @interface VersionDef {
+ int version() default 1;
+}
diff --git a/car-libs/car-core/src/android/support/car/app/CarProxyActivity.java b/car-libs/car-core/src/android/support/car/app/CarProxyActivity.java
index 3084366..de9be23 100644
--- a/car-libs/car-core/src/android/support/car/app/CarProxyActivity.java
+++ b/car-libs/car-core/src/android/support/car/app/CarProxyActivity.java
@@ -308,6 +308,11 @@
}
}
+ // TODO: eventually we should get CarActivity to directly host fragment, see b/25935686.
+ public CarActivity getCarActivity() {
+ return mCarActivity;
+ }
+
private static Integer[] convertArray(int[] array) {
Integer[] grantResults = new Integer[array.length];
for (int i = 0; i < array.length; i++) {
diff --git a/car-libs/car-core/src/android/support/car/input/CarRestrictedEditText.java b/car-libs/car-core/src/android/support/car/input/CarRestrictedEditText.java
index 2d4d900..37533bb 100644
--- a/car-libs/car-core/src/android/support/car/input/CarRestrictedEditText.java
+++ b/car-libs/car-core/src/android/support/car/input/CarRestrictedEditText.java
@@ -46,8 +46,8 @@
private KeyListener mListener;
public interface KeyListener {
- void onKeyDown(char key);
- void onKeyUp(char key);
+ void onKeyDown(int keyCode);
+ void onKeyUp(int keyCode);
void onCommitText(String input);
void onCloseKeyboard();
void onDelete();
@@ -112,9 +112,17 @@
public boolean sendKeyEvent(android.view.KeyEvent event) {
if (mListener != null) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
- mListener.onKeyDown((char) event.getKeyCode());
+ mListener.onKeyDown(event.getKeyCode());
} else if (event.getAction() == KeyEvent.ACTION_UP) {
- mListener.onKeyUp((char) event.getKeyCode());
+ mListener.onKeyUp(event.getKeyCode());
+
+ // InputMethodService#sendKeyChar doesn't call
+ // InputConnection#commitText for digit chars.
+ // TODO: fix projected IME to be in coherence with system IME.
+ char unicodeChar = (char) event.getUnicodeChar();
+ if (Character.isDigit(unicodeChar)) {
+ commitText(String.valueOf(unicodeChar), 1);
+ }
}
return true;
} else {
diff --git a/car-libs/car-core/src/android/support/car/os/ExtendableParcelable.java b/car-libs/car-core/src/android/support/car/os/ExtendableParcelable.java
new file mode 100644
index 0000000..e107102
--- /dev/null
+++ b/car-libs/car-core/src/android/support/car/os/ExtendableParcelable.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.support.car.os;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.support.car.annotation.VersionDef;
+
+/**
+ * ExtendableParcelable helps extending Parcelable in future in safe way.
+ * Basic idea is to write version code and payload length when writing to Parcel.
+ * Reader side reads version and do following actions:
+ * - if writer version <= reader version: Reader should know up to which element is supported by
+ * writer and read only up to that portion.
+ * - if writer version > reader version: Reader reads all members it knows and throw away remaing
+ * data so that additional Parcel reading can be done safely.
+ *
+ * For reader side:
+ * - In constructor with Parcel, call super(Parcel) first so that version number and payload length
+ * is read properly.
+ * - Call {@link #readHeader(Parcel)}.
+ * - After finishing all recognized or available members, call
+ * {@link #completeReading(Parcel, int)} with second argument set to return value from
+ * {@link #readHeader(Parcel)}. This will throw away any unread data.
+ *
+ * For writer side, when implementing writeToParcel:
+ * - call {@link #writeHeader(Parcel)} before writing anything else.
+ * - call {@link #completeWriting(Parcel, int)} with second argument set to return value from
+ * {@link #writeHeader(Parcel)}.
+ */
+public abstract class ExtendableParcelable implements Parcelable {
+ /**
+ * Version of this Parcelable. Reader side needs to read only up to the version written.
+ * This does not represent class version but contents version. For example, original
+ * Parcelable (=V1) passed to V2 supporting Parcelable will have version 1 even if
+ * V2 supporting Parcelable may have additional member variables added in V2.
+ */
+ @VersionDef(version = 1)
+ public final int version;
+
+ /**
+ * Constructor for reading parcel. Always call this first before reading anything else.
+ * @param in
+ * @param maxVersion
+ */
+ protected ExtendableParcelable(Parcel in, int version) {
+ int writerVersion = in.readInt();
+ if (version < writerVersion) { // version limited by reader
+ this.version = version;
+ } else { // version limited by writer
+ this.version = writerVersion;
+ }
+ }
+
+ /**
+ * Constructor for writer side. Version should be always set.
+ * @param version
+ */
+ protected ExtendableParcelable(int version) {
+ this.version = version;
+ }
+
+ /**
+ * Read header of Parcelable from Pacel. This should be done after super(Parcel, int) and
+ * before reading any Parcel. After all reading is done, {@link #completeReading(Parcel, int)}
+ * should be called.
+ *
+ * @param in
+ * @return last position. This should be passed to {@link #completeReading(Parcel, int)}.
+ */
+ protected int readHeader(Parcel in) {
+ int payloadLength = in.readInt();
+ int startingPosition = in.dataPosition();
+ return startingPosition + payloadLength;
+ }
+
+ /**
+ * Complete reading and safely throw away any unread data.
+ * @param in
+ * @param lastPosition Last position of of this Parcelable in the passed Parcel.
+ * The value is passed from {@link #readHeader(Parcel)}.
+ */
+ protected void completeReading(Parcel in, int lastPosition) {
+ in.setDataPosition(lastPosition);
+ }
+
+ /**
+ * Write header for writing to Parcel. This should be done before writing anything else.
+ * Code to use ths can look like:
+ * int pos = writeHeader(dest);
+ * dest.writeInt(0); // whatever relevant data
+ * ...
+ * completeWrite(dest, pos);
+ *
+ * @param dest
+ * @return startingPosition which should be passed when calling completeWrite.
+ */
+ protected int writeHeader(Parcel dest) {
+ dest.writeInt(version);
+ // temporary value for playload length. will be replaced in completeWrite
+ dest.writeInt(0);
+ // previous int is 4 bytes before this.
+ return dest.dataPosition();
+ }
+
+ /**
+ * Complete writing the current Parcelable. No more write to Parcel should be done after
+ * this call.
+ * @param dest
+ * @param startingPosition startingPosition returned from writeHeader
+ */
+ protected void completeWriting(Parcel dest, int startingPosition) {
+ int currentPosition = dest.dataPosition();
+ dest.setDataPosition(startingPosition - 4);
+ int payloadLength = currentPosition - startingPosition;
+ dest.writeInt(payloadLength);
+ dest.setDataPosition(currentPosition);
+ }
+}
diff --git a/tests/api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java b/tests/api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java
new file mode 100644
index 0000000..d6a3264
--- /dev/null
+++ b/tests/api_test/src/com/android/support/car/apitest/ExtendableParcelableTest.java
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.support.car.apitest;
+
+import android.os.Parcel;
+import android.support.car.annotation.VersionDef;
+import android.support.car.os.ExtendableParcelable;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.Arrays;
+
+public class ExtendableParcelableTest extends AndroidTestCase {
+
+ private static final String TAG = ExtendableParcelableTest.class.getSimpleName();
+
+ public static class V1Parcelable extends ExtendableParcelable {
+ @VersionDef(version = 1)
+ public final byte[] byteData0;
+ @VersionDef(version = 1)
+ public final int intData0;
+ @VersionDef(version = 1)
+ public final String stringData0;
+ @VersionDef(version = 1)
+ public final int intData1;
+
+ private static final int VERSION = 1;
+
+ public V1Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1) {
+ super(VERSION);
+ this.byteData0 = byteData0;
+ this.intData0 = intData0;
+ this.stringData0 = stringData0;
+ this.intData1 = intData1;
+ }
+
+ public V1Parcelable(Parcel in) {
+ super(in, VERSION);
+ int lastPosition = readHeader(in);
+ byteData0 = in.createByteArray();
+ intData0 = in.readInt();
+ stringData0 = in.readString();
+ intData1 = in.readInt();
+ completeReading(in, lastPosition);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ int pos = writeHeader(dest);
+ dest.writeByteArray(byteData0);
+ dest.writeInt(intData0);
+ dest.writeString(stringData0);
+ dest.writeInt(intData1);
+ completeWriting(dest, pos);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof V1Parcelable) {
+ V1Parcelable other = (V1Parcelable) o;
+ return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 &&
+ (stringData0 == null ? other.stringData0 == null :
+ stringData0.equals(other.stringData0)) &&
+ intData1 == other.intData1;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "V1Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0
+ + ",stringData0:" + stringData0 + ",intData1:" + intData1;
+ }
+ }
+
+ public static class V2Parcelable extends ExtendableParcelable {
+ @VersionDef(version = 1)
+ public final byte[] byteData0;
+ @VersionDef(version = 1)
+ public final int intData0;
+ @VersionDef(version = 1)
+ public final String stringData0;
+ @VersionDef(version = 1)
+ public final int intData1;
+ @VersionDef(version = 2)
+ public final byte[] byteData1;
+ @VersionDef(version = 2)
+ public final int intData2;
+
+ private static final int VERSION = 2;
+
+ public V2Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1,
+ byte[] byteData1, int intData2) {
+ super(VERSION);
+ this.byteData0 = byteData0;
+ this.intData0 = intData0;
+ this.stringData0 = stringData0;
+ this.intData1 = intData1;
+ this.byteData1 = byteData1;
+ this.intData2 = intData2;
+ }
+
+ public V2Parcelable(Parcel in) {
+ super(in, VERSION);
+ int lastPosition = readHeader(in);
+ byteData0 = in.createByteArray();
+ intData0 = in.readInt();
+ stringData0 = in.readString();
+ intData1 = in.readInt();
+ if (version >= 2) { // do not use VERSION here as VERSION will become 3 in next revision
+ byteData1 = in.createByteArray();
+ intData2 = in.readInt();
+ } else {
+ byteData1 = null;
+ intData2 = 0;
+ }
+ completeReading(in, lastPosition);
+ }
+
+ /** provide has method if null check is not possible. */
+ public boolean hasIntData1() {
+ return version >= 2;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ int pos = writeHeader(dest);
+ dest.writeByteArray(byteData0);
+ dest.writeInt(intData0);
+ dest.writeString(stringData0);
+ dest.writeInt(intData1);
+ dest.writeByteArray(byteData1);
+ dest.writeInt(intData2);
+ completeWriting(dest, pos);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof V2Parcelable) {
+ V2Parcelable other = (V2Parcelable) o;
+ return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 &&
+ (stringData0 == null ? other.stringData0 == null :
+ stringData0.equals(other.stringData0)) &&
+ intData1 == other.intData1 && Arrays.equals(byteData1, other.byteData1)
+ && intData2 == other.intData2;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "V2Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0
+ + ",stringData0:" + stringData0 + ",intData1:" + intData1 +
+ ",byteData1:" + Arrays.toString(byteData1) + ",intData2:" + intData2;
+ }
+ }
+
+ public static class V3Parcelable extends ExtendableParcelable {
+ @VersionDef(version = 1)
+ public final byte[] byteData0;
+ @VersionDef(version = 1)
+ public final int intData0;
+ @VersionDef(version = 1)
+ public final String stringData0;
+ @VersionDef(version = 1)
+ public final int intData1;
+ @VersionDef(version = 2)
+ public final byte[] byteData1;
+ @VersionDef(version = 2)
+ public final int intData2;
+ @VersionDef(version = 3)
+ public final String stringData1;
+ @VersionDef(version = 3)
+ public final int intData3;
+
+ private static final int VERSION = 3;
+
+ public V3Parcelable(byte[] byteData0, int intData0, String stringData0, int intData1,
+ byte[] byteData1, int intData2, String stringData1, int intData3) {
+ super(VERSION);
+ this.byteData0 = byteData0;
+ this.intData0 = intData0;
+ this.stringData0 = stringData0;
+ this.intData1 = intData1;
+ this.byteData1 = byteData1;
+ this.intData2 = intData2;
+ this.stringData1 = stringData1;
+ this.intData3 = intData3;
+ }
+
+ public V3Parcelable(Parcel in) {
+ super(in, VERSION);
+ int lastPosition = readHeader(in);
+ byteData0 = in.createByteArray();
+ intData0 = in.readInt();
+ stringData0 = in.readString();
+ intData1 = in.readInt();
+ if (version >= 2) {
+ byteData1 = in.createByteArray();
+ intData2 = in.readInt();
+ } else {
+ byteData1 = null;
+ intData2 = 0;
+ }
+ if (version >= 3) {
+ stringData1 = in.readString();
+ intData3 = in.readInt();
+ } else {
+ stringData1 = null;
+ intData3 = 0;
+ }
+ completeReading(in, lastPosition);
+ }
+
+ /** provide has method if null check is not possible. */
+ public boolean hasIntData1() {
+ return version >= 2;
+ }
+
+ /** provide has method if null check is not possible. */
+ public boolean hasIntData2() {
+ return version >= 3;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ int pos = writeHeader(dest);
+ dest.writeByteArray(byteData0);
+ dest.writeInt(intData0);
+ dest.writeString(stringData0);
+ dest.writeInt(intData1);
+ dest.writeByteArray(byteData1);
+ dest.writeInt(intData2);
+ dest.writeString(stringData1);
+ dest.writeInt(intData3);
+ completeWriting(dest, pos);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof V3Parcelable) {
+ V3Parcelable other = (V3Parcelable) o;
+ return Arrays.equals(byteData0, other.byteData0) && intData0 == other.intData0 &&
+ (stringData0 == null ? other.stringData0 == null :
+ stringData0.equals(other.stringData0)) &&
+ intData1 == other.intData1 && Arrays.equals(byteData1, other.byteData1)
+ && intData2 == other.intData2 &&
+ (stringData1 == null ? other.stringData1 == null :
+ stringData1.equals(other.stringData1)) &&
+ intData3 == other.intData3;
+ }
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "V3Parcelable byteData0:" + Arrays.toString(byteData0) + ",intData0:" + intData0
+ + ",stringData0:" + stringData0 + ",intData1:" + intData1 +
+ ",byteData1:" + Arrays.toString(byteData1) + ",intData2:" + intData2 +
+ ",stringData1:" + stringData1 + ",intData3:" + intData3;
+ }
+ }
+
+ public void testV1ToV3() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ V1Parcelable v1 = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ // expected after reading parcel
+ V3Parcelable v3Expected = new V3Parcelable(byteData0, intData0, stringData0, intData1,
+ null, 0, null, 0);
+ v1.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V3Parcelable v3 = new V3Parcelable(p);
+ Log.i(TAG, "v1:" + v1);
+ Log.i(TAG, "v3 expected:" + v3Expected);
+ Log.i(TAG, "v3 read:" + v3);
+ assertTrue(v3Expected.equals(v3));
+ assertEquals(1, v3.version);
+ assertFalse(v3.hasIntData1());
+ assertFalse(v3.hasIntData2());
+ assertEquals(additionalData, p.readInt());
+ }
+
+ public void testV2ToV3() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 };
+ int intData2 = 9012;
+ V2Parcelable v2 = new V2Parcelable(byteData0, intData0, stringData0, intData1, byteData1,
+ intData2);
+ // expected after reading parcel
+ V3Parcelable v3Expected = new V3Parcelable(byteData0, intData0, stringData0, intData1,
+ byteData1, intData2, null, 0);
+ v2.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V3Parcelable v3 = new V3Parcelable(p);
+ Log.i(TAG, "v2:" + v2);
+ Log.i(TAG, "v3 expected:" + v3Expected);
+ Log.i(TAG, "v3 read:" + v3);
+ assertTrue(v3Expected.equals(v3));
+ assertEquals(2, v3.version);
+ assertTrue(v3.hasIntData1());
+ assertFalse(v3.hasIntData2());
+ assertEquals(additionalData, p.readInt());
+ }
+
+ public void testV3ToV1() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 };
+ int intData2 = 9012;
+ // v3
+ String stringData1 = "Hello";
+ int intData3 = -1;
+ V3Parcelable v3 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1,
+ intData2, stringData1, intData3);
+ // expected after reading parcel
+ V1Parcelable v1Expected = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ v3.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V1Parcelable v1 = new V1Parcelable(p);
+ Log.i(TAG, "v3:" + v3);
+ Log.i(TAG, "v1 expected:" + v1Expected);
+ Log.i(TAG, "v1 read:" + v1);
+ assertTrue(v1Expected.equals(v1));
+ assertEquals(1, v1.version);
+ assertEquals(additionalData, p.readInt());
+ }
+
+ public void testV2ToV2() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 };
+ int intData2 = 9012;
+ V2Parcelable v2 = new V2Parcelable(byteData0, intData0, stringData0, intData1, byteData1,
+ intData2);
+ v2.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V2Parcelable v2Read = new V2Parcelable(p);
+ Log.i(TAG, "v2:" + v2);
+ Log.i(TAG, "v2 read:" + v2Read);
+ assertTrue(v2.equals(v2Read));
+ assertEquals(2, v2.version);
+ assertTrue(v2.hasIntData1());
+ assertEquals(additionalData, p.readInt());
+ }
+
+ public void testV3ToV1Array() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ byte[] byteData1 = new byte[] { 0x3, 0x4, 0x5 };
+ int intData2 = 9012;
+ // v3
+ String stringData1 = "Hello";
+ int intData3 = -1;
+ V3Parcelable v3_0 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1,
+ intData2, stringData1, intData3);
+ V1Parcelable v1Expected0 = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ byteData0 = null;
+ intData0 = 1;
+ stringData0 = "world";
+ V3Parcelable v3_1 = new V3Parcelable(byteData0, intData0, stringData0, intData1, byteData1,
+ intData2, stringData1, intData3);
+ V1Parcelable v1Expected1 = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ // test write of arrays without initial length portion
+ v3_0.writeToParcel(p, 0);
+ v3_1.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V1Parcelable v1_0 = new V1Parcelable(p);
+ V1Parcelable v1_1 = new V1Parcelable(p);
+ Log.i(TAG, "v3_1:" + v3_1);
+ Log.i(TAG, "v1 expected 1:" + v1Expected1);
+ Log.i(TAG, "v1_1 read:" + v1_1);
+ assertTrue(v1Expected0.equals(v1_0));
+ assertTrue(v1Expected1.equals(v1_1));
+ assertEquals(1, v1_0.version);
+ assertEquals(1, v1_1.version);
+ assertEquals(additionalData, p.readInt());
+ }
+
+ public void testV1ToV3Array() throws Exception {
+ Parcel p = Parcel.obtain();
+ int startPos = p.dataPosition();
+ byte[] byteData0 = new byte[] { 0x0, 0x1, 0x2 };
+ int intData0 = 1234;
+ String stringData0 = null;
+ int intData1 = 5678;
+ V1Parcelable v1_0 = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ // expected after reading parcel
+ V3Parcelable v3Expected0 = new V3Parcelable(byteData0, intData0, stringData0, intData1,
+ null, 0, null, 0);
+ byteData0 = null;
+ intData0 = 4567;
+ stringData0 = "Hi";
+ V1Parcelable v1_1 = new V1Parcelable(byteData0, intData0, stringData0, intData1);
+ // expected after reading parcel
+ V3Parcelable v3Expected1 = new V3Parcelable(byteData0, intData0, stringData0, intData1,
+ null, 0, null, 0);
+ v1_0.writeToParcel(p, 0);
+ v1_1.writeToParcel(p, 0);
+ final int additionalData = 0x8fffffff;
+ p.writeInt(additionalData);
+
+ p.setDataPosition(startPos);
+ V3Parcelable v3_0 = new V3Parcelable(p);
+ V3Parcelable v3_1 = new V3Parcelable(p);
+ Log.i(TAG, "v1:" + v1_1);
+ Log.i(TAG, "v3 expected:" + v3Expected1);
+ Log.i(TAG, "v3 read:" + v3_1);
+ assertTrue(v3Expected0.equals(v3_0));
+ assertFalse(v3_0.hasIntData1());
+ assertFalse(v3_0.hasIntData2());
+ assertFalse(v3_1.hasIntData1());
+ assertFalse(v3_1.hasIntData2());
+ assertEquals(1, v3_0.version);
+ assertEquals(1, v3_1.version);
+ assertEquals(additionalData, p.readInt());
+ }
+}