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 62 @Before setUp()63 public void setUp() { 64 IBinder binder = ServiceManager.waitForService(ITestService.class.getName()); 65 assertNotNull(binder); 66 mService = ITestService.Stub.asInterface(binder); 67 assertNotNull(mService); 68 69 vep = new VintfExtendableParcelable(); 70 vp = new VintfParcelable(); 71 72 sep = new NonVintfExtendableParcelable(); 73 sp = new NonVintfParcelable(); 74 75 uep = new UnstableExtendableParcelable(); 76 up = new UnstableParcelable(); 77 } 78 79 @Test testRepeatExtendableParcelable()80 public void testRepeatExtendableParcelable() throws RemoteException { 81 MyExt ext = new MyExt(); 82 ext.a = 42; 83 ext.b = "EXT"; 84 85 ExtendableParcelable ep = new ExtendableParcelable(); 86 ep.a = 1; 87 ep.b = "a"; 88 ep.c = 42L; 89 90 ep.ext.setParcelable(ext); 91 92 ExtendableParcelable ep2 = new ExtendableParcelable(); 93 mService.RepeatExtendableParcelable(ep, ep2); 94 assertThat(ep2.a, is(ep.a)); 95 assertThat(ep2.b, is(ep.b)); 96 97 MyExt retExt = ep2.ext.getParcelable(MyExt.class); 98 assertThat(retExt.a, is(ext.a)); 99 assertThat(retExt.b, is(ext.b)); 100 } 101 102 @Test testVintfParcelableHolderCanContainVintfParcelable()103 public void testVintfParcelableHolderCanContainVintfParcelable() { 104 vep.ext.setParcelable(vp); 105 assertThat(vep.ext.getParcelable(VintfParcelable.class), is(vp)); 106 } 107 108 @Test testVintfParcelableHolderCannotContainNonVintfParcelable()109 public void testVintfParcelableHolderCannotContainNonVintfParcelable() { 110 assertThrows(BadParcelableException.class, () -> { vep.ext.setParcelable(sp); }); 111 assertThat(vep.ext.getParcelable(VintfParcelable.class), is(nullValue())); 112 } 113 114 @Test testVintfParcelableHolderCannotContainUnstableParcelable()115 public void testVintfParcelableHolderCannotContainUnstableParcelable() { 116 assertThrows(BadParcelableException.class, () -> { vep.ext.setParcelable(up); }); 117 assertThat(vep.ext.getParcelable(UnstableParcelable.class), is(nullValue())); 118 } 119 120 @Test testStableParcelableHolderCanContainVintfParcelable()121 public void testStableParcelableHolderCanContainVintfParcelable() { 122 sep.ext.setParcelable(vp); 123 assertThat(sep.ext.getParcelable(VintfParcelable.class), is(vp)); 124 } 125 126 @Test testStableParcelableHolderCanContainNonVintfParcelable()127 public void testStableParcelableHolderCanContainNonVintfParcelable() { 128 sep.ext.setParcelable(sp); 129 assertThat(sep.ext.getParcelable(NonVintfParcelable.class), is(sp)); 130 } 131 132 @Test testStableParcelableHolderCanContainUnstableParcelable()133 public void testStableParcelableHolderCanContainUnstableParcelable() { 134 sep.ext.setParcelable(up); 135 assertThat(sep.ext.getParcelable(UnstableParcelable.class), is(up)); 136 } 137 138 @Test testUnstableParcelableHolderCanContainVintfParcelable()139 public void testUnstableParcelableHolderCanContainVintfParcelable() { 140 uep.ext.setParcelable(vp); 141 assertThat(uep.ext.getParcelable(VintfParcelable.class), is(vp)); 142 } 143 144 @Test testUnstableParcelableHolderCanContainNonVintfParcelable()145 public void testUnstableParcelableHolderCanContainNonVintfParcelable() { 146 uep.ext.setParcelable(sp); 147 assertThat(uep.ext.getParcelable(NonVintfParcelable.class), is(sp)); 148 } 149 150 @Test testUnstableParcelableHolderCanContainUnstableParcelable()151 public void testUnstableParcelableHolderCanContainUnstableParcelable() { 152 uep.ext.setParcelable(up); 153 assertThat(uep.ext.getParcelable(UnstableParcelable.class), is(up)); 154 } 155 156 @Test testReadWriteExtension()157 public void testReadWriteExtension() { 158 MyExt ext = new MyExt(); 159 ext.a = 42; 160 ext.b = "EXT"; 161 162 MyExt2 ext2 = new MyExt2(); 163 ext2.a = 42; 164 ext2.b = new MyExt(); 165 ext2.b.a = 24; 166 ext2.b.b = "INEXT"; 167 ext2.c = "EXT2"; 168 169 Parcel parcel = Parcel.obtain(); 170 { 171 ExtendableParcelable ep = new ExtendableParcelable(); 172 ep.a = 1; 173 ep.b = "a"; 174 ep.c = 42L; 175 176 ep.ext.setParcelable(ext); 177 178 ep.ext2.setParcelable(ext2); 179 // The extension type must be MyExt, so it has to fail 180 // even though MyExtLike has the same structure as MyExt. 181 assertThrows(BadParcelableException.class, 182 () -> { MyExtLike extLike = ep.ext.<MyExtLike>getParcelable(MyExtLike.class); }); 183 184 MyExt actualExt = ep.ext.getParcelable(MyExt.class); 185 MyExt2 actualExt2 = ep.ext2.getParcelable(MyExt2.class); 186 187 checkContent(ep, ext, ext2); 188 189 ep.writeToParcel(parcel, 0); 190 } 191 192 parcel.setDataPosition(0); 193 { 194 ExtendableParcelable ep1 = new ExtendableParcelable(); 195 ep1.readFromParcel(parcel); 196 197 parcel.setDataPosition(0); 198 ep1.writeToParcel(parcel, 0); 199 parcel.setDataPosition(0); 200 201 ExtendableParcelable ep2 = new ExtendableParcelable(); 202 203 ep2.readFromParcel(parcel); 204 205 // The extension type must be MyExt, so it has to fail 206 // even though MyExtLike has the same structure as MyExt. 207 assertThrows(BadParcelableException.class, 208 () -> { MyExtLike extLike = ep2.ext.<MyExtLike>getParcelable(MyExtLike.class); }); 209 210 MyExt actualExt = ep2.ext.getParcelable(MyExt.class); 211 212 MyExt2 newExt2 = new MyExt2(); 213 newExt2.a = 79; 214 newExt2.b = new MyExt(); 215 newExt2.b.a = 42; 216 newExt2.b.b = "INNEWEXT"; 217 newExt2.c = "NEWEXT2"; 218 ep2.ext2.setParcelable(newExt2); 219 checkContent(ep1, ext, ext2); 220 checkContent(ep2, ext, newExt2); 221 } 222 } 223 checkContent(ExtendableParcelable ep, MyExt ext, MyExt2 ext2)224 private void checkContent(ExtendableParcelable ep, MyExt ext, MyExt2 ext2) { 225 assertThat(ep.a, is(1)); 226 assertThat(ep.b, is("a")); 227 assertThat(ep.c, is(42L)); 228 229 MyExt actualExt = ep.ext.getParcelable(MyExt.class); 230 assertThat(dumpMyExt(actualExt), is(dumpMyExt(ext))); 231 232 MyExt2 actualExt2 = ep.ext2.getParcelable(MyExt2.class); 233 assertThat(dumpMyExt2(actualExt2), is(dumpMyExt2(ext2))); 234 } 235 dumpMyExt(MyExt ext)236 private static String dumpMyExt(MyExt ext) { 237 if (ext == null) { 238 return null; 239 } 240 return "{a: " + ext.a + ", b: " + ext.b + "}"; 241 } 242 dumpMyExt2(MyExt2 ext2)243 private static String dumpMyExt2(MyExt2 ext2) { 244 if (ext2 == null) { 245 return null; 246 } 247 return "{a: " + ext2.a + ", b: " + dumpMyExt(ext2.b) + ", " + ext2.c + "}"; 248 } 249 } 250