1 /* 2 * Copyright (C) 2020, 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.aidl.tests; 18 19 import static org.hamcrest.core.Is.is; 20 import static org.hamcrest.core.IsNull.nullValue; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertThat; 23 import static org.junit.Assume.assumeTrue; 24 import static org.testng.Assert.assertThrows; 25 26 import android.aidl.tests.extension.ExtendableParcelable; 27 import android.aidl.tests.extension.MyExt; 28 import android.aidl.tests.extension.MyExt2; 29 import android.aidl.tests.extension.MyExtLike; 30 import android.aidl.tests.nonvintf.NonVintfExtendableParcelable; 31 import android.aidl.tests.nonvintf.NonVintfParcelable; 32 import android.aidl.tests.unstable.UnstableExtendableParcelable; 33 import android.aidl.tests.unstable.UnstableParcelable; 34 import android.aidl.tests.vintf.VintfExtendableParcelable; 35 import android.aidl.tests.vintf.VintfParcelable; 36 import android.os.BadParcelableException; 37 import android.os.IBinder; 38 import android.os.Parcel; 39 import android.os.ParcelableHolder; 40 import android.os.RemoteException; 41 import android.os.ServiceManager; 42 import java.util.Arrays; 43 import java.util.HashMap; 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.junit.runners.JUnit4; 48 49 @RunWith(JUnit4.class) 50 public class ExtensionTests { 51 private VintfExtendableParcelable vep; 52 private VintfParcelable vp; 53 54 private NonVintfExtendableParcelable sep; 55 private NonVintfParcelable sp; 56 57 private UnstableExtendableParcelable uep; 58 private UnstableParcelable up; 59 60 private ITestService mService; 61 private ICppJavaTests mCppJavaTests; 62 63 @Before setUp()64 public void setUp() throws RemoteException { 65 IBinder binder = ServiceManager.waitForService(ITestService.class.getName()); 66 assertNotNull(binder); 67 mService = ITestService.Stub.asInterface(binder); 68 assertNotNull(mService); 69 70 IBinder binder2 = mService.GetCppJavaTests(); 71 if (binder2 != null) { 72 mCppJavaTests = ICppJavaTests.Stub.asInterface(binder2); 73 } 74 75 vep = new VintfExtendableParcelable(); 76 vp = new VintfParcelable(); 77 78 sep = new NonVintfExtendableParcelable(); 79 sp = new NonVintfParcelable(); 80 81 uep = new UnstableExtendableParcelable(); 82 up = new UnstableParcelable(); 83 } 84 85 @Test testRepeatExtendableParcelable()86 public void testRepeatExtendableParcelable() throws RemoteException { 87 assumeTrue(mCppJavaTests != null); 88 89 MyExt ext = new MyExt(); 90 ext.a = 42; 91 ext.b = "EXT"; 92 93 ExtendableParcelable ep = new ExtendableParcelable(); 94 ep.a = 1; 95 ep.b = "a"; 96 ep.c = 42L; 97 98 ep.ext.setParcelable(ext); 99 100 ExtendableParcelable ep2 = new ExtendableParcelable(); 101 mCppJavaTests.RepeatExtendableParcelable(ep, ep2); 102 assertThat(ep2.a, is(ep.a)); 103 assertThat(ep2.b, is(ep.b)); 104 105 MyExt retExt = ep2.ext.getParcelable(MyExt.class); 106 assertThat(retExt.a, is(ext.a)); 107 assertThat(retExt.b, is(ext.b)); 108 } 109 110 @Test testVintfParcelableHolderCanContainVintfParcelable()111 public void testVintfParcelableHolderCanContainVintfParcelable() { 112 vep.ext.setParcelable(vp); 113 assertThat(vep.ext.getParcelable(VintfParcelable.class), is(vp)); 114 } 115 116 @Test testVintfParcelableHolderCannotContainNonVintfParcelable()117 public void testVintfParcelableHolderCannotContainNonVintfParcelable() { 118 assertThrows(BadParcelableException.class, () -> { vep.ext.setParcelable(sp); }); 119 assertThat(vep.ext.getParcelable(VintfParcelable.class), is(nullValue())); 120 } 121 122 @Test testVintfParcelableHolderCannotContainUnstableParcelable()123 public void testVintfParcelableHolderCannotContainUnstableParcelable() { 124 assertThrows(BadParcelableException.class, () -> { vep.ext.setParcelable(up); }); 125 assertThat(vep.ext.getParcelable(UnstableParcelable.class), is(nullValue())); 126 } 127 128 @Test testStableParcelableHolderCanContainVintfParcelable()129 public void testStableParcelableHolderCanContainVintfParcelable() { 130 sep.ext.setParcelable(vp); 131 assertThat(sep.ext.getParcelable(VintfParcelable.class), is(vp)); 132 } 133 134 @Test testStableParcelableHolderCanContainNonVintfParcelable()135 public void testStableParcelableHolderCanContainNonVintfParcelable() { 136 sep.ext.setParcelable(sp); 137 assertThat(sep.ext.getParcelable(NonVintfParcelable.class), is(sp)); 138 } 139 140 @Test testStableParcelableHolderCanContainUnstableParcelable()141 public void testStableParcelableHolderCanContainUnstableParcelable() { 142 sep.ext.setParcelable(up); 143 assertThat(sep.ext.getParcelable(UnstableParcelable.class), is(up)); 144 } 145 146 @Test testUnstableParcelableHolderCanContainVintfParcelable()147 public void testUnstableParcelableHolderCanContainVintfParcelable() { 148 uep.ext.setParcelable(vp); 149 assertThat(uep.ext.getParcelable(VintfParcelable.class), is(vp)); 150 } 151 152 @Test testUnstableParcelableHolderCanContainNonVintfParcelable()153 public void testUnstableParcelableHolderCanContainNonVintfParcelable() { 154 uep.ext.setParcelable(sp); 155 assertThat(uep.ext.getParcelable(NonVintfParcelable.class), is(sp)); 156 } 157 158 @Test testUnstableParcelableHolderCanContainUnstableParcelable()159 public void testUnstableParcelableHolderCanContainUnstableParcelable() { 160 uep.ext.setParcelable(up); 161 assertThat(uep.ext.getParcelable(UnstableParcelable.class), is(up)); 162 } 163 164 @Test testReadWriteExtension()165 public void testReadWriteExtension() { 166 MyExt ext = new MyExt(); 167 ext.a = 42; 168 ext.b = "EXT"; 169 170 MyExt2 ext2 = new MyExt2(); 171 ext2.a = 42; 172 ext2.b = new MyExt(); 173 ext2.b.a = 24; 174 ext2.b.b = "INEXT"; 175 ext2.c = "EXT2"; 176 177 Parcel parcel = Parcel.obtain(); 178 { 179 ExtendableParcelable ep = new ExtendableParcelable(); 180 ep.a = 1; 181 ep.b = "a"; 182 ep.c = 42L; 183 184 ep.ext.setParcelable(ext); 185 186 ep.ext2.setParcelable(ext2); 187 // The extension type must be MyExt, so it has to fail 188 // even though MyExtLike has the same structure as MyExt. 189 assertThrows(BadParcelableException.class, 190 () -> { MyExtLike extLike = ep.ext.<MyExtLike>getParcelable(MyExtLike.class); }); 191 192 MyExt actualExt = ep.ext.getParcelable(MyExt.class); 193 MyExt2 actualExt2 = ep.ext2.getParcelable(MyExt2.class); 194 195 checkContent(ep, ext, ext2); 196 197 ep.writeToParcel(parcel, 0); 198 } 199 200 parcel.setDataPosition(0); 201 { 202 ExtendableParcelable ep1 = new ExtendableParcelable(); 203 ep1.readFromParcel(parcel); 204 205 parcel.setDataPosition(0); 206 ep1.writeToParcel(parcel, 0); 207 parcel.setDataPosition(0); 208 209 ExtendableParcelable ep2 = new ExtendableParcelable(); 210 211 ep2.readFromParcel(parcel); 212 213 // The extension type must be MyExt, so it has to fail 214 // even though MyExtLike has the same structure as MyExt. 215 assertThrows(BadParcelableException.class, 216 () -> { MyExtLike extLike = ep2.ext.<MyExtLike>getParcelable(MyExtLike.class); }); 217 218 MyExt actualExt = ep2.ext.getParcelable(MyExt.class); 219 220 MyExt2 newExt2 = new MyExt2(); 221 newExt2.a = 79; 222 newExt2.b = new MyExt(); 223 newExt2.b.a = 42; 224 newExt2.b.b = "INNEWEXT"; 225 newExt2.c = "NEWEXT2"; 226 ep2.ext2.setParcelable(newExt2); 227 checkContent(ep1, ext, ext2); 228 checkContent(ep2, ext, newExt2); 229 } 230 } 231 checkContent(ExtendableParcelable ep, MyExt ext, MyExt2 ext2)232 private void checkContent(ExtendableParcelable ep, MyExt ext, MyExt2 ext2) { 233 assertThat(ep.a, is(1)); 234 assertThat(ep.b, is("a")); 235 assertThat(ep.c, is(42L)); 236 237 MyExt actualExt = ep.ext.getParcelable(MyExt.class); 238 assertThat(dumpMyExt(actualExt), is(dumpMyExt(ext))); 239 240 MyExt2 actualExt2 = ep.ext2.getParcelable(MyExt2.class); 241 assertThat(dumpMyExt2(actualExt2), is(dumpMyExt2(ext2))); 242 } 243 dumpMyExt(MyExt ext)244 private static String dumpMyExt(MyExt ext) { 245 if (ext == null) { 246 return null; 247 } 248 return "{a: " + ext.a + ", b: " + ext.b + "}"; 249 } 250 dumpMyExt2(MyExt2 ext2)251 private static String dumpMyExt2(MyExt2 ext2) { 252 if (ext2 == null) { 253 return null; 254 } 255 return "{a: " + ext2.a + ", b: " + dumpMyExt(ext2.b) + ", " + ext2.c + "}"; 256 } 257 } 258