Verify Parcel object list does not get double freed after a setDataSize

Also clean up a commented out line in IParcelExceptionService.aidl

Bug: 134168436
Test: atest CtsOsTestCases:ParcelTest#testObjectDoubleFree
Change-Id: I8300423fd4351add8db27d1c4586577c98773c8a
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index d706470..765c8ef 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -88,6 +88,10 @@
             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/IParcelExceptionService.aidl b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
index ce7af6d..58d791c 100644
--- a/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
+++ b/tests/tests/os/src/android/os/cts/IParcelExceptionService.aidl
@@ -18,6 +18,5 @@
 import android.os.cts.ExceptionalParcelable;
 
 interface IParcelExceptionService {
-//parcelable android.os.cts.ExceptionalParcelable;
     ExceptionalParcelable writeBinderThrowException();
 }
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 77d325c..0287b7a 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -28,6 +28,7 @@
 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;
@@ -3368,4 +3369,68 @@
         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());
+    }
 }