Merge changes I6b247672,I9ef52453 into oreo-cts-dev
* changes:
RESTRICT AUTOMERGE Strict SQLiteQueryBuilder needs to be stricter.
DO NOT MERGE CTS: Test column name with spaces
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index c99e236..31b83ff 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -39,7 +39,8 @@
src/android/os/cts/IParcelFileDescriptorPeer.aidl \
src/android/os/cts/IEmptyService.aidl \
src/android/os/cts/ISeccompIsolatedService.aidl \
- src/android/os/cts/ISecondary.aidl
+ src/android/os/cts/ISecondary.aidl \
+ src/android/os/cts/IParcelExceptionService.aidl \
LOCAL_PACKAGE_NAME := CtsOsTestCases
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index 846251f..835022c 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -76,6 +76,14 @@
android:name="android.os.cts.CrossProcessExceptionService"
android:process=":green"
android:exported="true" />
+ <service
+ android:name="android.os.cts.ParcelExceptionService"
+ android:process=":remote"
+ android:exported="true" />
+ <service
+ android:name="android.os.cts.ParcelTest$ParcelObjectFreeService"
+ android:process=":remote"
+ android:exported="true" />
<service android:name="android.os.cts.LocalService">
<intent-filter>
diff --git a/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl
new file mode 100644
index 0000000..7d09693
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 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.os.cts;
+
+parcelable ExceptionalParcelable;
\ No newline at end of file
diff --git a/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java
new file mode 100644
index 0000000..333cf57
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ExceptionalParcelable.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 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.os.cts;
+
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+
+public class ExceptionalParcelable implements Parcelable {
+ private final IBinder mBinder;
+
+ ExceptionalParcelable(IBinder binder) {
+ mBinder = binder;
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * Write a binder to the Parcel and then throw an exception
+ */
+ public void writeToParcel(Parcel out, int flags) {
+ // Write a binder for the exception to overwrite
+ out.writeStrongBinder(mBinder);
+
+ // Throw an exception
+ throw new IllegalArgumentException("A truly exceptional message");
+ }
+
+ public static final Creator<ExceptionalParcelable> CREATOR =
+ new Creator<ExceptionalParcelable>() {
+ @Override
+ public ExceptionalParcelable createFromParcel(Parcel source) {
+ return new ExceptionalParcelable(source.readStrongBinder());
+ }
+
+ @Override
+ public ExceptionalParcelable[] newArray(int size) {
+ return new ExceptionalParcelable[size];
+ }
+ };
+}
diff --git a/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
new file mode 100644
index 0000000..ce7af6d
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 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.os.cts;
+import android.os.cts.ExceptionalParcelable;
+
+interface IParcelExceptionService {
+//parcelable android.os.cts.ExceptionalParcelable;
+ ExceptionalParcelable writeBinderThrowException();
+}
diff --git a/tests/tests/os/src/android/os/cts/ParcelExceptionService.java b/tests/tests/os/src/android/os/cts/ParcelExceptionService.java
new file mode 100644
index 0000000..d8387e3
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ParcelExceptionService.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 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.os.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+public class ParcelExceptionService extends Service {
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new ParcelExceptionServiceImpl();
+ }
+
+ private static class ParcelExceptionServiceImpl extends IParcelExceptionService.Stub {
+ private final IBinder mBinder = new Binder();
+
+
+ @Override
+ public ExceptionalParcelable writeBinderThrowException() throws RemoteException {
+ return new ExceptionalParcelable(mBinder);
+ }
+ }
+}
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 8a221e6..c49fcca 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -24,7 +24,15 @@
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.content.pm.Signature;
import android.os.BadParcelableException;
import android.os.Binder;
@@ -39,6 +47,8 @@
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import com.google.common.util.concurrent.AbstractFuture;
+
public class ParcelTest extends AndroidTestCase {
public void testObtain() {
@@ -3216,4 +3226,119 @@
// good
}
}
+
+ public static class ParcelExceptionConnection extends AbstractFuture<IParcelExceptionService>
+ implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(IParcelExceptionService.Stub.asInterface(service));
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public IParcelExceptionService get() throws InterruptedException, ExecutionException {
+ try {
+ return get(5, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public void testExceptionOverwritesObject() throws Exception {
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "android.os.cts", "android.os.cts.ParcelExceptionService"));
+
+ final ParcelExceptionConnection connection = new ParcelExceptionConnection();
+
+ mContext.startService(intent);
+ assertTrue(mContext.bindService(intent, connection,
+ Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
+
+
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken("android.os.cts.IParcelExceptionService");
+ IParcelExceptionService service = connection.get();
+ try {
+ assertTrue("Transaction failed", service.asBinder().transact(
+ IParcelExceptionService.Stub.TRANSACTION_writeBinderThrowException, data, reply,
+ 0));
+ } catch (Exception e) {
+ fail("Exception caught from transaction: " + e);
+ }
+ reply.setDataPosition(0);
+ assertTrue("Exception should have occurred on service-side",
+ reply.readExceptionCode() != 0);
+ assertNull("Binder should have been overwritten by the exception",
+ reply.readStrongBinder());
+ }
+
+ public static class ParcelObjectFreeService extends Service {
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new Binder();
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+
+ Parcel parcel = Parcel.obtain();
+
+ // Construct parcel with object in it.
+ parcel.writeInt(1);
+ final int pos = parcel.dataPosition();
+ parcel.writeStrongBinder(new Binder());
+
+ // wipe out the object by setting data size
+ parcel.setDataSize(pos);
+
+ // recycle the parcel. This should not cause a native segfault
+ parcel.recycle();
+ }
+
+ public static class Connection extends AbstractFuture<IBinder>
+ implements ServiceConnection {
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ set(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ }
+
+ @Override
+ public IBinder get() throws InterruptedException, ExecutionException {
+ try {
+ return get(5, TimeUnit.SECONDS);
+ } catch (TimeoutException e) {
+ return null;
+ }
+ }
+ }
+ }
+
+ public void testObjectDoubleFree() throws Exception {
+
+ final Intent intent = new Intent();
+ intent.setComponent(new ComponentName(
+ "android.os.cts", "android.os.cts.ParcelTest$ParcelObjectFreeService"));
+
+ final ParcelObjectFreeService.Connection connection =
+ new ParcelObjectFreeService.Connection();
+
+ mContext.startService(intent);
+ assertTrue(mContext.bindService(intent, connection,
+ Context.BIND_ABOVE_CLIENT | Context.BIND_EXTERNAL_SERVICE));
+
+ assertNotNull("Service should have started without crashing.", connection.get());
+ }
}