1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2008 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker import java.lang.annotation.Annotation; 18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationHandler; 19*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.InvocationTargetException; 20*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Constructor; 21*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Field; 22*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method; 23*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Proxy; 24*795d594fSAndroid Build Coastguard Worker import java.util.Arrays; 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker /** 27*795d594fSAndroid Build Coastguard Worker * Do some basic tests. 28*795d594fSAndroid Build Coastguard Worker */ 29*795d594fSAndroid Build Coastguard Worker public class BasicTest { 30*795d594fSAndroid Build Coastguard Worker main(String[] args)31*795d594fSAndroid Build Coastguard Worker public static void main(String[] args) { 32*795d594fSAndroid Build Coastguard Worker Mix proxyMe = new Mix(); 33*795d594fSAndroid Build Coastguard Worker Object proxy = createProxy(proxyMe); 34*795d594fSAndroid Build Coastguard Worker 35*795d594fSAndroid Build Coastguard Worker if (!Proxy.isProxyClass(proxy.getClass())) 36*795d594fSAndroid Build Coastguard Worker System.out.println("not a proxy class?"); 37*795d594fSAndroid Build Coastguard Worker if (Proxy.getInvocationHandler(proxy) == null) 38*795d594fSAndroid Build Coastguard Worker System.out.println("ERROR: Proxy.getInvocationHandler is null"); 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker /* take it for a spin; verifies instanceof constraint */ 41*795d594fSAndroid Build Coastguard Worker Shapes shapes = (Shapes) proxy; 42*795d594fSAndroid Build Coastguard Worker shapes.circle(3); 43*795d594fSAndroid Build Coastguard Worker shapes.rectangle(10, 20); 44*795d594fSAndroid Build Coastguard Worker shapes.blob(); 45*795d594fSAndroid Build Coastguard Worker Quads quads = (Quads) proxy; 46*795d594fSAndroid Build Coastguard Worker quads.rectangle(15, 25); 47*795d594fSAndroid Build Coastguard Worker quads.trapezoid(6, 81.18, 4); 48*795d594fSAndroid Build Coastguard Worker Colors colors = (Colors) proxy; 49*795d594fSAndroid Build Coastguard Worker colors.red(1.0f); 50*795d594fSAndroid Build Coastguard Worker colors.blue(777); 51*795d594fSAndroid Build Coastguard Worker colors.mauve("sorry"); 52*795d594fSAndroid Build Coastguard Worker colors.blob(); 53*795d594fSAndroid Build Coastguard Worker Trace trace = (Trace) proxy; 54*795d594fSAndroid Build Coastguard Worker trace.getTrace(); 55*795d594fSAndroid Build Coastguard Worker 56*795d594fSAndroid Build Coastguard Worker // Test the proxy spec: These Object functions are supposed to be given to the handler. 57*795d594fSAndroid Build Coastguard Worker int unusedHashCode = ((Object)trace).hashCode(); 58*795d594fSAndroid Build Coastguard Worker boolean unusedEquals = ((Object)trace).equals(trace); 59*795d594fSAndroid Build Coastguard Worker String unusedString = ((Object)trace).toString(); 60*795d594fSAndroid Build Coastguard Worker 61*795d594fSAndroid Build Coastguard Worker try { 62*795d594fSAndroid Build Coastguard Worker shapes.upChuck(); 63*795d594fSAndroid Build Coastguard Worker System.out.println("Didn't get expected exception"); 64*795d594fSAndroid Build Coastguard Worker } catch (IndexOutOfBoundsException ioobe) { 65*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected ioobe"); 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker try { 68*795d594fSAndroid Build Coastguard Worker shapes.upCheck(); 69*795d594fSAndroid Build Coastguard Worker System.out.println("Didn't get expected exception"); 70*795d594fSAndroid Build Coastguard Worker } catch (InterruptedException ie) { 71*795d594fSAndroid Build Coastguard Worker System.out.println("Got expected ie"); 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker 74*795d594fSAndroid Build Coastguard Worker /* 75*795d594fSAndroid Build Coastguard Worker * Exercise annotations on Proxy classes. This is mostly to ensure 76*795d594fSAndroid Build Coastguard Worker * that annotation calls work correctly on generated classes. 77*795d594fSAndroid Build Coastguard Worker */ 78*795d594fSAndroid Build Coastguard Worker System.out.println(""); 79*795d594fSAndroid Build Coastguard Worker Method[] methods = proxy.getClass().getDeclaredMethods(); 80*795d594fSAndroid Build Coastguard Worker Arrays.sort(methods, new MethodComparator()); 81*795d594fSAndroid Build Coastguard Worker System.out.println("Proxy interfaces: " + 82*795d594fSAndroid Build Coastguard Worker Arrays.deepToString(proxy.getClass().getInterfaces())); 83*795d594fSAndroid Build Coastguard Worker System.out.println("Proxy methods: " + 84*795d594fSAndroid Build Coastguard Worker Main.replaceProxyClassNamesForOutput(Arrays.deepToString(methods))); 85*795d594fSAndroid Build Coastguard Worker Method meth = methods[methods.length -1]; 86*795d594fSAndroid Build Coastguard Worker System.out.println("Decl annos: " + Arrays.deepToString(meth.getDeclaredAnnotations())); 87*795d594fSAndroid Build Coastguard Worker Annotation[][] paramAnnos = meth.getParameterAnnotations(); 88*795d594fSAndroid Build Coastguard Worker System.out.println("Param annos (" + paramAnnos.length + ") : " 89*795d594fSAndroid Build Coastguard Worker + Arrays.deepToString(paramAnnos)); 90*795d594fSAndroid Build Coastguard Worker System.out.println("Modifiers: " + meth.getModifiers()); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker createProxy(Object proxyMe)93*795d594fSAndroid Build Coastguard Worker static Object createProxy(Object proxyMe) { 94*795d594fSAndroid Build Coastguard Worker /* declare an object that will handle the method calls */ 95*795d594fSAndroid Build Coastguard Worker InvocationHandler handler = new MyInvocationHandler(proxyMe); 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker /* create the proxy class */ 98*795d594fSAndroid Build Coastguard Worker Class<?> proxyClass = Proxy.getProxyClass(Shapes.class.getClassLoader(), 99*795d594fSAndroid Build Coastguard Worker Quads.class, Colors.class, Trace.class); 100*795d594fSAndroid Build Coastguard Worker Main.registerProxyClassName(proxyClass.getCanonicalName()); 101*795d594fSAndroid Build Coastguard Worker 102*795d594fSAndroid Build Coastguard Worker /* create a proxy object, passing the handler object in */ 103*795d594fSAndroid Build Coastguard Worker Object proxy = null; 104*795d594fSAndroid Build Coastguard Worker try { 105*795d594fSAndroid Build Coastguard Worker Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class); 106*795d594fSAndroid Build Coastguard Worker //System.out.println("Constructor is " + cons); 107*795d594fSAndroid Build Coastguard Worker proxy = cons.newInstance(handler); 108*795d594fSAndroid Build Coastguard Worker } catch (NoSuchMethodException nsme) { 109*795d594fSAndroid Build Coastguard Worker System.out.println("failed: " + nsme); 110*795d594fSAndroid Build Coastguard Worker } catch (InstantiationException ie) { 111*795d594fSAndroid Build Coastguard Worker System.out.println("failed: " + ie); 112*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException ie) { 113*795d594fSAndroid Build Coastguard Worker System.out.println("failed: " + ie); 114*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ite) { 115*795d594fSAndroid Build Coastguard Worker System.out.println("failed: " + ite); 116*795d594fSAndroid Build Coastguard Worker } 117*795d594fSAndroid Build Coastguard Worker 118*795d594fSAndroid Build Coastguard Worker return proxy; 119*795d594fSAndroid Build Coastguard Worker } 120*795d594fSAndroid Build Coastguard Worker } 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker /* 123*795d594fSAndroid Build Coastguard Worker * Some interfaces. 124*795d594fSAndroid Build Coastguard Worker */ 125*795d594fSAndroid Build Coastguard Worker interface Shapes { circle(int r)126*795d594fSAndroid Build Coastguard Worker public void circle(int r); rectangle(int x, int y)127*795d594fSAndroid Build Coastguard Worker public int rectangle(int x, int y); 128*795d594fSAndroid Build Coastguard Worker blob()129*795d594fSAndroid Build Coastguard Worker public String blob(); 130*795d594fSAndroid Build Coastguard Worker checkMe()131*795d594fSAndroid Build Coastguard Worker public R0base checkMe(); upChuck()132*795d594fSAndroid Build Coastguard Worker public void upChuck(); upCheck()133*795d594fSAndroid Build Coastguard Worker public void upCheck() throws InterruptedException; 134*795d594fSAndroid Build Coastguard Worker } 135*795d594fSAndroid Build Coastguard Worker 136*795d594fSAndroid Build Coastguard Worker interface Quads extends Shapes { rectangle(int x, int y)137*795d594fSAndroid Build Coastguard Worker public int rectangle(int x, int y); square(int x, int y)138*795d594fSAndroid Build Coastguard Worker public int square(int x, int y); trapezoid(int x, double off, int y)139*795d594fSAndroid Build Coastguard Worker public int trapezoid(int x, double off, int y); 140*795d594fSAndroid Build Coastguard Worker checkMe()141*795d594fSAndroid Build Coastguard Worker public R0a checkMe(); 142*795d594fSAndroid Build Coastguard Worker } 143*795d594fSAndroid Build Coastguard Worker 144*795d594fSAndroid Build Coastguard Worker /* 145*795d594fSAndroid Build Coastguard Worker * More interfaces. 146*795d594fSAndroid Build Coastguard Worker */ 147*795d594fSAndroid Build Coastguard Worker interface Colors { red(float howRed)148*795d594fSAndroid Build Coastguard Worker public int red(float howRed); green(double howGreen)149*795d594fSAndroid Build Coastguard Worker public int green(double howGreen); blue(int howBlue)150*795d594fSAndroid Build Coastguard Worker public double blue(int howBlue); mauve(String apology)151*795d594fSAndroid Build Coastguard Worker public int mauve(String apology); 152*795d594fSAndroid Build Coastguard Worker blob()153*795d594fSAndroid Build Coastguard Worker public String blob(); 154*795d594fSAndroid Build Coastguard Worker checkMe()155*795d594fSAndroid Build Coastguard Worker public R0aa checkMe(); 156*795d594fSAndroid Build Coastguard Worker } 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker interface Trace { getTrace()159*795d594fSAndroid Build Coastguard Worker public void getTrace(); 160*795d594fSAndroid Build Coastguard Worker } 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker /* 163*795d594fSAndroid Build Coastguard Worker * Some return types. 164*795d594fSAndroid Build Coastguard Worker */ 165*795d594fSAndroid Build Coastguard Worker class R0base { int mBlah; } 166*795d594fSAndroid Build Coastguard Worker class R0a extends R0base { int mBlah_a; } 167*795d594fSAndroid Build Coastguard Worker class R0aa extends R0a { int mBlah_aa; } 168*795d594fSAndroid Build Coastguard Worker 169*795d594fSAndroid Build Coastguard Worker 170*795d594fSAndroid Build Coastguard Worker /* 171*795d594fSAndroid Build Coastguard Worker * A class that implements them all. 172*795d594fSAndroid Build Coastguard Worker */ 173*795d594fSAndroid Build Coastguard Worker class Mix implements Quads, Colors { circle(int r)174*795d594fSAndroid Build Coastguard Worker public void circle(int r) { 175*795d594fSAndroid Build Coastguard Worker System.out.println("--- circle " + r); 176*795d594fSAndroid Build Coastguard Worker } rectangle(int x, int y)177*795d594fSAndroid Build Coastguard Worker public int rectangle(int x, int y) { 178*795d594fSAndroid Build Coastguard Worker System.out.println("--- rectangle " + x + "," + y); 179*795d594fSAndroid Build Coastguard Worker return 4; 180*795d594fSAndroid Build Coastguard Worker } square(int x, int y)181*795d594fSAndroid Build Coastguard Worker public int square(int x, int y) { 182*795d594fSAndroid Build Coastguard Worker System.out.println("--- square " + x + "," + y); 183*795d594fSAndroid Build Coastguard Worker return 4; 184*795d594fSAndroid Build Coastguard Worker } trapezoid(int x, double off, int y)185*795d594fSAndroid Build Coastguard Worker public int trapezoid(int x, double off, int y) { 186*795d594fSAndroid Build Coastguard Worker System.out.println("--- trap " + x + "," + y + "," + off); 187*795d594fSAndroid Build Coastguard Worker return 8; 188*795d594fSAndroid Build Coastguard Worker } blob()189*795d594fSAndroid Build Coastguard Worker public String blob() { 190*795d594fSAndroid Build Coastguard Worker System.out.println("--- blob"); 191*795d594fSAndroid Build Coastguard Worker return "mix"; 192*795d594fSAndroid Build Coastguard Worker } 193*795d594fSAndroid Build Coastguard Worker red(float howRed)194*795d594fSAndroid Build Coastguard Worker public int red(float howRed) { 195*795d594fSAndroid Build Coastguard Worker System.out.println("--- red " + howRed); 196*795d594fSAndroid Build Coastguard Worker return 0; 197*795d594fSAndroid Build Coastguard Worker } green(double howGreen)198*795d594fSAndroid Build Coastguard Worker public int green(double howGreen) { 199*795d594fSAndroid Build Coastguard Worker System.out.println("--- green " + howGreen); 200*795d594fSAndroid Build Coastguard Worker return 1; 201*795d594fSAndroid Build Coastguard Worker } blue(int howBlue)202*795d594fSAndroid Build Coastguard Worker public double blue(int howBlue) { 203*795d594fSAndroid Build Coastguard Worker System.out.println("--- blue " + howBlue); 204*795d594fSAndroid Build Coastguard Worker return 2.54; 205*795d594fSAndroid Build Coastguard Worker } mauve(String apology)206*795d594fSAndroid Build Coastguard Worker public int mauve(String apology) { 207*795d594fSAndroid Build Coastguard Worker System.out.println("--- mauve " + apology); 208*795d594fSAndroid Build Coastguard Worker return 3; 209*795d594fSAndroid Build Coastguard Worker } 210*795d594fSAndroid Build Coastguard Worker checkMe()211*795d594fSAndroid Build Coastguard Worker public R0aa checkMe() { 212*795d594fSAndroid Build Coastguard Worker return null; 213*795d594fSAndroid Build Coastguard Worker } upChuck()214*795d594fSAndroid Build Coastguard Worker public void upChuck() { 215*795d594fSAndroid Build Coastguard Worker throw new IndexOutOfBoundsException("upchuck"); 216*795d594fSAndroid Build Coastguard Worker } upCheck()217*795d594fSAndroid Build Coastguard Worker public void upCheck() throws InterruptedException { 218*795d594fSAndroid Build Coastguard Worker throw new InterruptedException("upcheck"); 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker } 221*795d594fSAndroid Build Coastguard Worker 222*795d594fSAndroid Build Coastguard Worker /* 223*795d594fSAndroid Build Coastguard Worker * Invocation handler, defining the implementation of the proxy functions. 224*795d594fSAndroid Build Coastguard Worker */ 225*795d594fSAndroid Build Coastguard Worker class MyInvocationHandler implements InvocationHandler { 226*795d594fSAndroid Build Coastguard Worker Object mObj; 227*795d594fSAndroid Build Coastguard Worker MyInvocationHandler(Object obj)228*795d594fSAndroid Build Coastguard Worker public MyInvocationHandler(Object obj) { 229*795d594fSAndroid Build Coastguard Worker mObj = obj; 230*795d594fSAndroid Build Coastguard Worker } 231*795d594fSAndroid Build Coastguard Worker 232*795d594fSAndroid Build Coastguard Worker /* 233*795d594fSAndroid Build Coastguard Worker * This is called when anything gets invoked in the proxy object. 234*795d594fSAndroid Build Coastguard Worker */ invoke(Object proxy, Method method, Object[] args)235*795d594fSAndroid Build Coastguard Worker public Object invoke(Object proxy, Method method, Object[] args) 236*795d594fSAndroid Build Coastguard Worker throws Throwable { 237*795d594fSAndroid Build Coastguard Worker 238*795d594fSAndroid Build Coastguard Worker System.out.println("Invoke " + method); 239*795d594fSAndroid Build Coastguard Worker 240*795d594fSAndroid Build Coastguard Worker Object result = null; 241*795d594fSAndroid Build Coastguard Worker 242*795d594fSAndroid Build Coastguard Worker // Trap Object calls. This is important here to avoid a recursive 243*795d594fSAndroid Build Coastguard Worker // invocation of toString() in the print statements below. 244*795d594fSAndroid Build Coastguard Worker if (method.getDeclaringClass() == java.lang.Object.class) { 245*795d594fSAndroid Build Coastguard Worker //System.out.println("!!! object " + method.getName()); 246*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("toString")) { 247*795d594fSAndroid Build Coastguard Worker return super.toString(); 248*795d594fSAndroid Build Coastguard Worker } else if (method.getName().equals("hashCode")) { 249*795d594fSAndroid Build Coastguard Worker return Integer.valueOf(super.hashCode()); 250*795d594fSAndroid Build Coastguard Worker } else if (method.getName().equals("equals")) { 251*795d594fSAndroid Build Coastguard Worker return Boolean.valueOf(super.equals(args[0])); 252*795d594fSAndroid Build Coastguard Worker } else { 253*795d594fSAndroid Build Coastguard Worker throw new RuntimeException("huh?"); 254*795d594fSAndroid Build Coastguard Worker } 255*795d594fSAndroid Build Coastguard Worker } 256*795d594fSAndroid Build Coastguard Worker 257*795d594fSAndroid Build Coastguard Worker if (method.getDeclaringClass() == Trace.class) { 258*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("getTrace")) { 259*795d594fSAndroid Build Coastguard Worker StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 260*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < stackTrace.length; i++) { 261*795d594fSAndroid Build Coastguard Worker StackTraceElement ste = stackTrace[i]; 262*795d594fSAndroid Build Coastguard Worker if (ste.getMethodName().equals("getTrace")) { 263*795d594fSAndroid Build Coastguard Worker String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName()); 264*795d594fSAndroid Build Coastguard Worker System.out.println(outputClassName + "." + ste.getMethodName() + " " + 265*795d594fSAndroid Build Coastguard Worker ste.getFileName() + ":" + ste.getLineNumber()); 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker } 268*795d594fSAndroid Build Coastguard Worker return null; 269*795d594fSAndroid Build Coastguard Worker } 270*795d594fSAndroid Build Coastguard Worker } 271*795d594fSAndroid Build Coastguard Worker 272*795d594fSAndroid Build Coastguard Worker if (method.getDeclaringClass() == Trace.class) { 273*795d594fSAndroid Build Coastguard Worker if (method.getName().equals("getTrace")) { 274*795d594fSAndroid Build Coastguard Worker StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); 275*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < stackTrace.length; i++) { 276*795d594fSAndroid Build Coastguard Worker StackTraceElement ste = stackTrace[i]; 277*795d594fSAndroid Build Coastguard Worker if (ste.getMethodName().equals("getTrace")) { 278*795d594fSAndroid Build Coastguard Worker String outputClassName = Main.replaceProxyClassNamesForOutput(ste.getClassName()); 279*795d594fSAndroid Build Coastguard Worker System.out.println(outputClassName + "." + ste.getMethodName() + " " + 280*795d594fSAndroid Build Coastguard Worker ste.getFileName() + ":" + ste.getLineNumber()); 281*795d594fSAndroid Build Coastguard Worker } 282*795d594fSAndroid Build Coastguard Worker } 283*795d594fSAndroid Build Coastguard Worker return null; 284*795d594fSAndroid Build Coastguard Worker } 285*795d594fSAndroid Build Coastguard Worker } 286*795d594fSAndroid Build Coastguard Worker 287*795d594fSAndroid Build Coastguard Worker if (args == null || args.length == 0) { 288*795d594fSAndroid Build Coastguard Worker System.out.println(" (no args)"); 289*795d594fSAndroid Build Coastguard Worker } else { 290*795d594fSAndroid Build Coastguard Worker for (int i = 0; i < args.length; i++) 291*795d594fSAndroid Build Coastguard Worker System.out.println(" " + i + ": " + args[i]); 292*795d594fSAndroid Build Coastguard Worker } 293*795d594fSAndroid Build Coastguard Worker 294*795d594fSAndroid Build Coastguard Worker try { 295*795d594fSAndroid Build Coastguard Worker if (true) { 296*795d594fSAndroid Build Coastguard Worker result = method.invoke(mObj, args); 297*795d594fSAndroid Build Coastguard Worker } else { 298*795d594fSAndroid Build Coastguard Worker result = -1; 299*795d594fSAndroid Build Coastguard Worker } 300*795d594fSAndroid Build Coastguard Worker System.out.println("Success: method " + method.getName() 301*795d594fSAndroid Build Coastguard Worker + " res=" + result); 302*795d594fSAndroid Build Coastguard Worker } catch (InvocationTargetException ite) { 303*795d594fSAndroid Build Coastguard Worker throw ite.getTargetException(); 304*795d594fSAndroid Build Coastguard Worker } catch (IllegalAccessException iae) { 305*795d594fSAndroid Build Coastguard Worker throw new RuntimeException(iae); 306*795d594fSAndroid Build Coastguard Worker } 307*795d594fSAndroid Build Coastguard Worker return result; 308*795d594fSAndroid Build Coastguard Worker } 309*795d594fSAndroid Build Coastguard Worker } 310