1 /* 2 * Copyright (C) 2011 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 import java.lang.reflect.*; 17 18 public class ReturnsAndArgPassing { 19 20 public static final String testName = "ReturnsAndArgPassing"; 21 22 static void check(boolean x) { 23 if (!x) { 24 throw new AssertionError(testName + " Check failed"); 25 } 26 } 27 28 interface MyInterface { 29 void voidFoo(); 30 void voidBar(); 31 boolean booleanFoo(); 32 boolean booleanBar(); 33 byte byteFoo(); 34 byte byteBar(); 35 char charFoo(); 36 char charBar(); 37 short shortFoo(); 38 short shortBar(); 39 int intFoo(); 40 int intBar(); 41 long longFoo(); 42 long longBar(); 43 float floatFoo(); 44 float floatBar(); 45 double doubleFoo(); 46 double doubleBar(); 47 Object selectArg(int select, int a, long b, float c, double d, Object x); 48 } 49 50 static int fooInvocations = 0; 51 static int barInvocations = 0; 52 53 static class MyInvocationHandler implements InvocationHandler { 54 boolean causeNpeOnReturn = false; 55 Class<?> returnType = null; 56 public Object invoke(Object proxy, Method method, Object[] args) { 57 check(proxy instanceof Proxy); 58 check(method.getDeclaringClass() == MyInterface.class); 59 String name = method.getName(); 60 if (name.endsWith("Foo")) { 61 check(args == null); 62 fooInvocations++; 63 } else if (name.endsWith("Bar")) { 64 check(args == null); 65 barInvocations++; 66 } 67 if (causeNpeOnReturn) { 68 return null; 69 } else if (name.equals("voidFoo") || name.equals("voidBar")) { 70 return null; 71 } else if (name.equals("booleanFoo")) { 72 return true; 73 } else if (name.equals("booleanBar")) { 74 return false; 75 } else if (name.equals("selectArg")) { 76 check(args.length == 6); 77 int select = (Integer)args[0]; 78 return args[select]; 79 } else { 80 try { 81 if (name.endsWith("Foo")) { 82 return returnType.getField("MAX_VALUE").get(null); 83 } else { 84 check(name.endsWith("Bar")); 85 return returnType.getField("MIN_VALUE").get(null); 86 } 87 } catch (Exception e) { 88 throw new Error("return type = " + returnType, e); 89 } 90 } 91 } 92 } 93 94 static void testProxyReturns() { 95 System.out.println(testName + ".testProxyReturns RUNNING"); 96 MyInvocationHandler myHandler = new MyInvocationHandler(); 97 MyInterface proxyMyInterface = 98 (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(), 99 new Class[] { MyInterface.class }, 100 myHandler); 101 check(fooInvocations == 0); 102 proxyMyInterface.voidFoo(); 103 check(fooInvocations == 1); 104 105 check(barInvocations == 0); 106 proxyMyInterface.voidBar(); 107 check(barInvocations == 1); 108 109 check(fooInvocations == 1); 110 myHandler.returnType = Boolean.class; 111 check(proxyMyInterface.booleanFoo() == true); 112 check(fooInvocations == 2); 113 114 check(barInvocations == 1); 115 check(proxyMyInterface.booleanBar() == false); 116 check(barInvocations == 2); 117 118 check(fooInvocations == 2); 119 myHandler.returnType = Byte.class; 120 check(proxyMyInterface.byteFoo() == Byte.MAX_VALUE); 121 check(fooInvocations == 3); 122 123 check(barInvocations == 2); 124 check(proxyMyInterface.byteBar() == Byte.MIN_VALUE); 125 check(barInvocations == 3); 126 127 check(fooInvocations == 3); 128 myHandler.returnType = Character.class; 129 check(proxyMyInterface.charFoo() == Character.MAX_VALUE); 130 check(fooInvocations == 4); 131 132 check(barInvocations == 3); 133 check(proxyMyInterface.charBar() == Character.MIN_VALUE); 134 check(barInvocations == 4); 135 136 check(fooInvocations == 4); 137 myHandler.returnType = Short.class; 138 check(proxyMyInterface.shortFoo() == Short.MAX_VALUE); 139 check(fooInvocations == 5); 140 141 check(barInvocations == 4); 142 check(proxyMyInterface.shortBar() == Short.MIN_VALUE); 143 check(barInvocations == 5); 144 145 check(fooInvocations == 5); 146 myHandler.returnType = Integer.class; 147 check(proxyMyInterface.intFoo() == Integer.MAX_VALUE); 148 check(fooInvocations == 6); 149 150 check(barInvocations == 5); 151 check(proxyMyInterface.intBar() == Integer.MIN_VALUE); 152 check(barInvocations == 6); 153 154 check(fooInvocations == 6); 155 myHandler.returnType = Long.class; 156 check(proxyMyInterface.longFoo() == Long.MAX_VALUE); 157 check(fooInvocations == 7); 158 159 check(barInvocations == 6); 160 check(proxyMyInterface.longBar() == Long.MIN_VALUE); 161 check(barInvocations == 7); 162 163 check(fooInvocations == 7); 164 myHandler.returnType = Float.class; 165 check(proxyMyInterface.floatFoo() == Float.MAX_VALUE); 166 check(fooInvocations == 8); 167 168 check(barInvocations == 7); 169 check(proxyMyInterface.floatBar() == Float.MIN_VALUE); 170 check(barInvocations == 8); 171 172 check(fooInvocations == 8); 173 myHandler.returnType = Double.class; 174 check(proxyMyInterface.doubleFoo() == Double.MAX_VALUE); 175 check(fooInvocations == 9); 176 177 check(barInvocations == 8); 178 check(proxyMyInterface.doubleBar() == Double.MIN_VALUE); 179 check(barInvocations == 9); 180 181 // Toggle flag to get return values to cause NPEs 182 myHandler.causeNpeOnReturn = true; 183 184 check(fooInvocations == 9); 185 try { 186 proxyMyInterface.booleanFoo(); 187 throw new AssertionError("Expected NPE"); 188 } catch (NullPointerException e) { 189 } 190 check(fooInvocations == 10); 191 192 check(barInvocations == 9); 193 try { 194 proxyMyInterface.booleanBar(); 195 throw new AssertionError("Expected NPE"); 196 } catch (NullPointerException e) { 197 } 198 check(barInvocations == 10); 199 200 check(fooInvocations == 10); 201 try { 202 proxyMyInterface.byteFoo(); 203 throw new AssertionError("Expected NPE"); 204 } catch (NullPointerException e) { 205 } 206 check(fooInvocations == 11); 207 208 check(barInvocations == 10); 209 try { 210 proxyMyInterface.byteBar(); 211 throw new AssertionError("Expected NPE"); 212 } catch (NullPointerException e) { 213 } 214 check(barInvocations == 11); 215 216 check(fooInvocations == 11); 217 try { 218 proxyMyInterface.charFoo(); 219 throw new AssertionError("Expected NPE"); 220 } catch (NullPointerException e) { 221 } 222 check(fooInvocations == 12); 223 224 check(barInvocations == 11); 225 try { 226 proxyMyInterface.charBar(); 227 throw new AssertionError("Expected NPE"); 228 } catch (NullPointerException e) { 229 } 230 check(barInvocations == 12); 231 232 check(fooInvocations == 12); 233 try { 234 proxyMyInterface.shortFoo(); 235 throw new AssertionError("Expected NPE"); 236 } catch (NullPointerException e) { 237 } 238 check(fooInvocations == 13); 239 240 check(barInvocations == 12); 241 try { 242 proxyMyInterface.shortBar(); 243 throw new AssertionError("Expected NPE"); 244 } catch (NullPointerException e) { 245 } 246 check(barInvocations == 13); 247 248 check(fooInvocations == 13); 249 try { 250 proxyMyInterface.intFoo(); 251 throw new AssertionError("Expected NPE"); 252 } catch (NullPointerException e) { 253 } 254 check(fooInvocations == 14); 255 256 check(barInvocations == 13); 257 try { 258 proxyMyInterface.intBar(); 259 throw new AssertionError("Expected NPE"); 260 } catch (NullPointerException e) { 261 } 262 check(barInvocations == 14); 263 264 check(fooInvocations == 14); 265 try { 266 proxyMyInterface.longFoo(); 267 throw new AssertionError("Expected NPE"); 268 } catch (NullPointerException e) { 269 } 270 check(fooInvocations == 15); 271 272 check(barInvocations == 14); 273 try { 274 proxyMyInterface.longBar(); 275 throw new AssertionError("Expected NPE"); 276 } catch (NullPointerException e) { 277 } 278 check(barInvocations == 15); 279 280 check(fooInvocations == 15); 281 try { 282 proxyMyInterface.floatFoo(); 283 throw new AssertionError("Expected NPE"); 284 } catch (NullPointerException e) { 285 } 286 check(fooInvocations == 16); 287 288 check(barInvocations == 15); 289 try { 290 proxyMyInterface.floatBar(); 291 throw new AssertionError("Expected NPE"); 292 } catch (NullPointerException e) { 293 } 294 check(barInvocations == 16); 295 296 check(fooInvocations == 16); 297 try { 298 proxyMyInterface.doubleFoo(); 299 throw new AssertionError("Expected NPE"); 300 } catch (NullPointerException e) { 301 } 302 check(fooInvocations == 17); 303 304 check(barInvocations == 16); 305 try { 306 proxyMyInterface.doubleBar(); 307 throw new AssertionError("Expected NPE"); 308 } catch (NullPointerException e) { 309 } 310 check(barInvocations == 17); 311 312 // Toggle flag to stop NPEs 313 myHandler.causeNpeOnReturn = false; 314 315 check(fooInvocations == 17); 316 myHandler.returnType = Double.class; // Double -> byte == fail 317 try { 318 proxyMyInterface.byteFoo(); 319 throw new AssertionError("Expected ClassCastException"); 320 } catch (ClassCastException e) { 321 } 322 check(fooInvocations == 18); 323 324 check(barInvocations == 17); 325 try { 326 proxyMyInterface.byteBar(); 327 throw new AssertionError("Expected NPE"); 328 } catch (ClassCastException e) { 329 } 330 check(barInvocations == 18); 331 332 check(fooInvocations == 18); 333 myHandler.returnType = Float.class; // Float -> byte == fail 334 try { 335 proxyMyInterface.byteFoo(); 336 throw new AssertionError("Expected ClassCastException"); 337 } catch (ClassCastException e) { 338 } 339 check(fooInvocations == 19); 340 341 check(barInvocations == 18); 342 try { 343 proxyMyInterface.byteBar(); 344 throw new AssertionError("Expected NPE"); 345 } catch (ClassCastException e) { 346 } 347 check(barInvocations == 19); 348 349 check(fooInvocations == 19); 350 myHandler.returnType = Long.class; // Long -> byte == fail 351 try { 352 proxyMyInterface.byteFoo(); 353 throw new AssertionError("Expected ClassCastException"); 354 } catch (ClassCastException e) { 355 } 356 check(fooInvocations == 20); 357 358 check(barInvocations == 19); 359 try { 360 proxyMyInterface.byteBar(); 361 throw new AssertionError("Expected NPE"); 362 } catch (ClassCastException e) { 363 } 364 check(barInvocations == 20); 365 366 check(fooInvocations == 20); 367 myHandler.returnType = Integer.class; // Int -> byte == fail 368 try { 369 proxyMyInterface.byteFoo(); 370 throw new AssertionError("Expected ClassCastException"); 371 } catch (ClassCastException e) { 372 } 373 check(fooInvocations == 21); 374 375 check(barInvocations == 20); 376 try { 377 proxyMyInterface.byteBar(); 378 throw new AssertionError("Expected NPE"); 379 } catch (ClassCastException e) { 380 } 381 check(barInvocations == 21); 382 383 check(fooInvocations == 21); 384 myHandler.returnType = Short.class; // Short -> byte == fail 385 try { 386 proxyMyInterface.byteFoo(); 387 throw new AssertionError("Expected ClassCastException"); 388 } catch (ClassCastException e) { 389 } 390 check(fooInvocations == 22); 391 392 check(barInvocations == 21); 393 try { 394 proxyMyInterface.byteBar(); 395 throw new AssertionError("Expected NPE"); 396 } catch (ClassCastException e) { 397 } 398 check(barInvocations == 22); 399 400 check(fooInvocations == 22); 401 myHandler.returnType = Character.class; // Char -> byte == fail 402 try { 403 proxyMyInterface.byteFoo(); 404 throw new AssertionError("Expected ClassCastException"); 405 } catch (ClassCastException e) { 406 } 407 check(fooInvocations == 23); 408 409 check(barInvocations == 22); 410 try { 411 proxyMyInterface.byteBar(); 412 throw new AssertionError("Expected NPE"); 413 } catch (ClassCastException e) { 414 } 415 check(barInvocations == 23); 416 417 check(fooInvocations == 23); 418 myHandler.returnType = Character.class; // Char -> short == fail 419 try { 420 proxyMyInterface.shortFoo(); 421 throw new AssertionError("Expected ClassCastException"); 422 } catch (ClassCastException e) { 423 } 424 check(fooInvocations == 24); 425 426 check(barInvocations == 23); 427 try { 428 proxyMyInterface.shortBar(); 429 throw new AssertionError("Expected NPE"); 430 } catch (ClassCastException e) { 431 } 432 check(barInvocations == 24); 433 434 System.out.println(testName + ".testProxyReturns PASSED"); 435 } 436 437 static void testProxyArgPassing() { 438 System.out.println(testName + ".testProxyArgPassing RUNNING"); 439 MyInvocationHandler myHandler = new MyInvocationHandler(); 440 MyInterface proxyMyInterface = 441 (MyInterface)Proxy.newProxyInstance(ReturnsAndArgPassing.class.getClassLoader(), 442 new Class[] { MyInterface.class }, 443 myHandler); 444 445 check((Integer)proxyMyInterface.selectArg(0, Integer.MAX_VALUE, Long.MAX_VALUE, 446 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == 0); 447 check((Integer)proxyMyInterface.selectArg(1, Integer.MAX_VALUE, Long.MAX_VALUE, 448 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Integer.MAX_VALUE); 449 check((Long)proxyMyInterface.selectArg(2, Integer.MAX_VALUE, Long.MAX_VALUE, 450 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Long.MAX_VALUE); 451 check((Float)proxyMyInterface.selectArg(3, Integer.MAX_VALUE, Long.MAX_VALUE, 452 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Float.MAX_VALUE); 453 check((Double)proxyMyInterface.selectArg(4, Integer.MAX_VALUE, Long.MAX_VALUE, 454 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Double.MAX_VALUE); 455 check(proxyMyInterface.selectArg(5, Integer.MAX_VALUE, Long.MAX_VALUE, 456 Float.MAX_VALUE, Double.MAX_VALUE, Object.class) == Object.class); 457 458 System.out.println(testName + ".testProxyArgPassing PASSED"); 459 } 460 461 public static void main(String args[]) { 462 testProxyReturns(); 463 testProxyArgPassing(); 464 } 465 } 466