1fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include "generate_java.h" 2fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include "Type.h" 3fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <string.h> 4fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <stdio.h> 5fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <stdlib.h> 6fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <string.h> 7fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 8fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// ================================================= 9fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoclass StubClass : public Class 10fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 11fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratopublic: 12fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato StubClass(Type* type, Type* interfaceType); 13fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato virtual ~StubClass(); 14fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 15fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* transact_code; 16fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* transact_data; 17fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* transact_reply; 18fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* transact_flags; 19fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato SwitchStatement* transact_switch; 20fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoprivate: 21fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato void make_as_interface(Type* interfaceType); 22fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}; 23fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 24fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::StubClass(Type* type, Type* interfaceType) 25fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato :Class() 26fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 27fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->comment = "/** Local-side IPC implementation stub class. */"; 28fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->modifiers = PUBLIC | ABSTRACT | STATIC; 29fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->what = Class::CLASS; 30fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->type = type; 31fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->extends = BINDER_NATIVE_TYPE; 32fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->interfaces.push_back(interfaceType); 33fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 34fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // descriptor 35fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Field* descriptor = new Field(STATIC | FINAL | PRIVATE, 36fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new Variable(STRING_TYPE, "DESCRIPTOR")); 37fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato descriptor->value = "\"" + interfaceType->QualifiedName() + "\""; 38fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(descriptor); 39fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 40fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // ctor 41fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* ctor = new Method; 42fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->modifiers = PUBLIC; 43fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->comment = "/** Construct the stub at attach it to the " 44fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato "interface. */"; 45fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->name = "Stub"; 46fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->statements = new StatementBlock; 47fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface", 48fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 2, THIS_VALUE, new LiteralExpression("DESCRIPTOR")); 49fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->statements->Add(attach); 50fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(ctor); 51fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 52fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // asInterface 53fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato make_as_interface(interfaceType); 54fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 55fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // asBinder 56fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* asBinder = new Method; 57b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes asBinder->modifiers = PUBLIC | OVERRIDE; 58fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->returnType = IBINDER_TYPE; 59fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->name = "asBinder"; 60fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->statements = new StatementBlock; 61fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->statements->Add(new ReturnStatement(THIS_VALUE)); 62fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(asBinder); 63fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 64fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // onTransact 65fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_code = new Variable(INT_TYPE, "code"); 66fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_data = new Variable(PARCEL_TYPE, "data"); 67fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_reply = new Variable(PARCEL_TYPE, "reply"); 68fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_flags = new Variable(INT_TYPE, "flags"); 69fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* onTransact = new Method; 70fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->modifiers = PUBLIC | OVERRIDE; 71fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->returnType = BOOLEAN_TYPE; 72fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->name = "onTransact"; 73fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->parameters.push_back(this->transact_code); 74fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->parameters.push_back(this->transact_data); 75fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->parameters.push_back(this->transact_reply); 76fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->parameters.push_back(this->transact_flags); 77fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->statements = new StatementBlock; 78fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 79fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(onTransact); 80fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_switch = new SwitchStatement(this->transact_code); 81fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 82fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->statements->Add(this->transact_switch); 83fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4, 84fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_code, this->transact_data, 85fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->transact_reply, this->transact_flags); 86fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato onTransact->statements->Add(new ReturnStatement(superCall)); 87fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 88fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 89fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::~StubClass() 90fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 91fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 92fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 93fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratovoid 94fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::make_as_interface(Type *interfaceType) 95fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 96fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* obj = new Variable(IBINDER_TYPE, "obj"); 97fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 98fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* m = new Method; 99fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->comment = "/**\n * Cast an IBinder object into an "; 100fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->comment += interfaceType->QualifiedName(); 101fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->comment += " interface,\n"; 102fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->comment += " * generating a proxy if needed.\n */"; 103fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->modifiers = PUBLIC | STATIC; 104fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->returnType = interfaceType; 105fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->name = "asInterface"; 106fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->parameters.push_back(obj); 107fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->statements = new StatementBlock; 108fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 109fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato IfStatement* ifstatement = new IfStatement(); 110fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ifstatement->expression = new Comparison(obj, "==", NULL_VALUE); 111fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ifstatement->statements = new StatementBlock; 112fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ifstatement->statements->Add(new ReturnStatement(NULL_VALUE)); 113fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->statements->Add(ifstatement); 114fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 115fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // IInterface iin = obj.queryLocalInterface(DESCRIPTOR) 116fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface"); 117fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR")); 118fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato IInterfaceType* iinType = new IInterfaceType(); 119fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable *iin = new Variable(iinType, "iin"); 120b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL); 121fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->statements->Add(iinVd); 122fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 123fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // Ensure the instance type of the local object is as expected. 124fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // One scenario where this is needed is if another package (with a 125fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // different class loader) runs in the same process as the service. 126fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 127fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin; 128fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE); 129fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Comparison* instOfCheck = new Comparison(iin, " instanceof ", 130fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new LiteralExpression(interfaceType->QualifiedName())); 131fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato IfStatement* instOfStatement = new IfStatement(); 132fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck); 133fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato instOfStatement->statements = new StatementBlock; 134fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin))); 135fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->statements->Add(instOfStatement); 136fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 137fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato string proxyType = interfaceType->QualifiedName(); 138fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxyType += ".Stub.Proxy"; 139fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NewExpression* ne = new NewExpression(NAMES.Find(proxyType)); 140fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ne->arguments.push_back(obj); 141fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato m->statements->Add(new ReturnStatement(ne)); 142fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 143fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(m); 144fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 145fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 146fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 147fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 148fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// ================================================= 149fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoclass ProxyClass : public Class 150fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 151fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratopublic: 152fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ProxyClass(Type* type, InterfaceType* interfaceType); 153fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato virtual ~ProxyClass(); 154fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 155fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* mRemote; 156fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato bool mOneWay; 157fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}; 158fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 159fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType) 160fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato :Class() 161fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 162fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->modifiers = PRIVATE | STATIC; 163fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->what = Class::CLASS; 164fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->type = type; 165fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->interfaces.push_back(interfaceType); 166fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 167fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato mOneWay = interfaceType->OneWay(); 168fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 169fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // IBinder mRemote 170fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato mRemote = new Variable(IBINDER_TYPE, "mRemote"); 171fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(new Field(PRIVATE, mRemote)); 172fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 173fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // Proxy() 174fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* remote = new Variable(IBINDER_TYPE, "remote"); 175fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* ctor = new Method; 176fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->name = "Proxy"; 177fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->statements = new StatementBlock; 178fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->parameters.push_back(remote); 179fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ctor->statements->Add(new Assignment(mRemote, remote)); 180fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(ctor); 181fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 182fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // IBinder asBinder() 183fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* asBinder = new Method; 184b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes asBinder->modifiers = PUBLIC | OVERRIDE; 185fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->returnType = IBINDER_TYPE; 186fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->name = "asBinder"; 187fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->statements = new StatementBlock; 188fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato asBinder->statements->Add(new ReturnStatement(mRemote)); 189fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato this->elements.push_back(asBinder); 190fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 191fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 192fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoProxyClass::~ProxyClass() 193fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 194fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 195fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 196fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// ================================================= 197fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 198fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_new_array(Type* t, StatementBlock* addTo, Variable* v, 199fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* parcel) 200fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 201fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* len = new Variable(INT_TYPE, v->name + "_length"); 202fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt"))); 203fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato IfStatement* lencheck = new IfStatement(); 204fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato lencheck->expression = new Comparison(len, "<", new LiteralExpression("0")); 205fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato lencheck->statements->Add(new Assignment(v, NULL_VALUE)); 206fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato lencheck->elseif = new IfStatement(); 207fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato lencheck->elseif->statements->Add(new Assignment(v, 208fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new NewArrayExpression(t, len))); 209fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato addTo->Add(lencheck); 210fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 211fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 212fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 213fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v, 214fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* parcel, int flags) 215fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 216fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 0) { 217fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->WriteToParcel(addTo, v, parcel, flags); 218fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 219fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 1) { 220fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->WriteArrayToParcel(addTo, v, parcel, flags); 221fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 222fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 223fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 224fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 225fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v, 226fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* parcel, Variable** cl) 227fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 228fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 0) { 229fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->CreateFromParcel(addTo, v, parcel, cl); 230fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 231fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 1) { 232fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->CreateArrayFromParcel(addTo, v, parcel, cl); 233fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 234fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 235fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 236fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 237fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v, 238fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* parcel, Variable** cl) 239fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 240fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 0) { 241fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->ReadFromParcel(addTo, v, parcel, cl); 242fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 243fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (v->dimension == 1) { 244fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato t->ReadArrayFromParcel(addTo, v, parcel, cl); 245fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 246fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 247fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 248fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 249fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 250fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_method(const method_type* method, Class* interface, 251fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato StubClass* stubClass, ProxyClass* proxyClass, int index) 252fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 253fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg_type* arg; 254fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato int i; 255fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato bool hasOutParams = false; 256fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 257fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato const bool oneway = proxyClass->mOneWay || method->oneway; 258fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 259fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // == the TRANSACT_ constant ============================================= 260fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato string transactCodeName = "TRANSACTION_"; 261fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato transactCodeName += method->name.data; 262fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 26302822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu char transactCodeValue[60]; 264fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index); 265fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 266fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Field* transactCode = new Field(STATIC | FINAL, 267fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new Variable(INT_TYPE, transactCodeName)); 268fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato transactCode->value = transactCodeValue; 269fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->elements.push_back(transactCode); 270fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 271fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // == the declaration in the interface =================================== 272fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* decl = new Method; 273fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->comment = gather_comments(method->comments_token->extra); 274fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->modifiers = PUBLIC; 275fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->returnType = NAMES.Search(method->type.type.data); 276fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->returnTypeDimension = method->type.dimension; 277fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->name = method->name.data; 278fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 279fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 280fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 281fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->parameters.push_back(new Variable( 282fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NAMES.Search(arg->type.type.data), arg->name.data, 283fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg->type.dimension)); 284fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 285fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 286fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 287fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 288fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 289fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->elements.push_back(decl); 290fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 291fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // == the stub method ==================================================== 292fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 293fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Case* c = new Case(transactCodeName); 294fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 295fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data); 296fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 297fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // interface token validation is the very first thing we do 298fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new MethodCall(stubClass->transact_data, 299fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato "enforceInterface", 1, new LiteralExpression("DESCRIPTOR"))); 300fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 301fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // args 302fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* cl = NULL; 303fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato VariableFactory stubArgs("_arg"); 304fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 305fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 306fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type* t = NAMES.Search(arg->type.type.data); 307fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* v = stubArgs.Get(t); 308fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato v->dimension = arg->type.dimension; 309fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 310fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new VariableDeclaration(v)); 311fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 312fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (convert_direction(arg->direction.data) & IN_PARAMETER) { 313fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_create_from_parcel(t, c->statements, v, 314fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->transact_data, &cl); 315fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } else { 316fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (arg->type.dimension == 0) { 317fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new Assignment(v, new NewExpression(v->type))); 318fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 319fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato else if (arg->type.dimension == 1) { 320fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_new_array(v->type, c->statements, v, 321fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->transact_data); 322fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 323fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato else { 324fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, 325fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato __LINE__); 326fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 327fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 328fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 329fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato realCall->arguments.push_back(v); 330fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 331fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 332fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 333fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 334fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the real call 335fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* _result = NULL; 336fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (0 == strcmp(method->type.type.data, "void")) { 337fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(realCall); 338fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 339fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (!oneway) { 340fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // report that there were no exceptions 341fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* ex = new MethodCall(stubClass->transact_reply, 342fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato "writeNoException", 0); 343fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(ex); 344fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 345fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } else { 346fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato _result = new Variable(decl->returnType, "_result", 347fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato decl->returnTypeDimension); 348fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new VariableDeclaration(_result, realCall)); 349fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 350fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (!oneway) { 351fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // report that there were no exceptions 352fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* ex = new MethodCall(stubClass->transact_reply, 353fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato "writeNoException", 0); 354fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(ex); 355fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 356fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 357fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // marshall the return value 358fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_write_to_parcel(decl->returnType, c->statements, _result, 359fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->transact_reply, 360fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type::PARCELABLE_WRITE_RETURN_VALUE); 361fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 362fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 363fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // out parameters 364fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato i = 0; 365fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 366fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 367fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type* t = NAMES.Search(arg->type.type.data); 368fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* v = stubArgs.Get(i++); 369fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 370fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (convert_direction(arg->direction.data) & OUT_PARAMETER) { 371fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_write_to_parcel(t, c->statements, v, 372fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->transact_reply, 373fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type::PARCELABLE_WRITE_RETURN_VALUE); 374fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato hasOutParams = true; 375fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 376fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 377fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 378fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 379fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 380fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // return true 381fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new ReturnStatement(TRUE_VALUE)); 382fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stubClass->transact_switch->cases.push_back(c); 383fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 384fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // == the proxy method =================================================== 385fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* proxy = new Method; 386fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->comment = gather_comments(method->comments_token->extra); 387b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes proxy->modifiers = PUBLIC | OVERRIDE; 388fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->returnType = NAMES.Search(method->type.type.data); 389fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->returnTypeDimension = method->type.dimension; 390fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->name = method->name.data; 391fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements = new StatementBlock; 392fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 393fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 394fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->parameters.push_back(new Variable( 395fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NAMES.Search(arg->type.type.data), arg->name.data, 396fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg->type.dimension)); 397fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 398fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 399fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 400fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxyClass->elements.push_back(proxy); 401fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 402fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the parcels 403fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* _data = new Variable(PARCEL_TYPE, "_data"); 404fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(new VariableDeclaration(_data, 405fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new MethodCall(PARCEL_TYPE, "obtain"))); 406fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* _reply = NULL; 407fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (!oneway) { 408fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato _reply = new Variable(PARCEL_TYPE, "_reply"); 409fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(new VariableDeclaration(_reply, 410fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new MethodCall(PARCEL_TYPE, "obtain"))); 411fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 412fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 413fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the return value 414fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato _result = NULL; 415fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (0 != strcmp(method->type.type.data, "void")) { 416fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato _result = new Variable(proxy->returnType, "_result", 417fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato method->type.dimension); 418fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(new VariableDeclaration(_result)); 419fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 420fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 421fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // try and finally 422fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato TryStatement* tryStatement = new TryStatement(); 423fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(tryStatement); 424fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato FinallyStatement* finallyStatement = new FinallyStatement(); 425fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(finallyStatement); 426fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 427fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the interface identifier token: the DESCRIPTOR constant, marshalled as a string 428fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken", 429fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 1, new LiteralExpression("DESCRIPTOR"))); 430fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 431fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the parameters 432fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 433fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 434fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type* t = NAMES.Search(arg->type.type.data); 435fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* v = new Variable(t, arg->name.data, arg->type.dimension); 436fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato int dir = convert_direction(arg->direction.data); 437fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (dir == OUT_PARAMETER && arg->type.dimension != 0) { 438fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato IfStatement* checklen = new IfStatement(); 439fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato checklen->expression = new Comparison(v, "==", NULL_VALUE); 440fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato checklen->statements->Add(new MethodCall(_data, "writeInt", 1, 441fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new LiteralExpression("-1"))); 442fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato checklen->elseif = new IfStatement(); 443fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato checklen->elseif->statements->Add(new MethodCall(_data, "writeInt", 444fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 1, new FieldVariable(v, "length"))); 445fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato tryStatement->statements->Add(checklen); 446fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 447fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato else if (dir & IN_PARAMETER) { 448fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_write_to_parcel(t, tryStatement->statements, v, _data, 0); 449fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 450fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 451fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 452fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 453fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the transact call 454fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4, 455fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new LiteralExpression("Stub." + transactCodeName), 456fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato _data, _reply ? _reply : NULL_VALUE, 457fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato new LiteralExpression( 458fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")); 459fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato tryStatement->statements->Add(call); 460fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 461fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // throw back exceptions. 462fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (_reply) { 463fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato MethodCall* ex = new MethodCall(_reply, "readException", 0); 464fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato tryStatement->statements->Add(ex); 465fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 466fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 467fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // returning and cleanup 468fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (_reply != NULL) { 469fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (_result != NULL) { 470fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_create_from_parcel(proxy->returnType, 471fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato tryStatement->statements, _result, _reply, &cl); 472fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 473fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 474fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the out/inout parameters 475fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = method->args; 476fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (arg != NULL) { 477fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Type* t = NAMES.Search(arg->type.type.data); 478fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Variable* v = new Variable(t, arg->name.data, arg->type.dimension); 479fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (convert_direction(arg->direction.data) & OUT_PARAMETER) { 480fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_read_from_parcel(t, tryStatement->statements, 481fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato v, _reply, &cl); 482fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 483fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato arg = arg->next; 484fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 485fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 486fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato finallyStatement->statements->Add(new MethodCall(_reply, "recycle")); 487fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 488fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato finallyStatement->statements->Add(new MethodCall(_data, "recycle")); 489fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 490fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (_result != NULL) { 491fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->statements->Add(new ReturnStatement(_result)); 492fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 493fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 494fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 495fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void 496fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_interface_descriptors(StubClass* stub, ProxyClass* proxy) 497fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 498fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the interface descriptor transaction handler 499fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Case* c = new Case("INTERFACE_TRANSACTION"); 500fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 501fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 1, new LiteralExpression("DESCRIPTOR"))); 502fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato c->statements->Add(new ReturnStatement(TRUE_VALUE)); 503fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stub->transact_switch->cases.push_back(c); 504fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 505fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // and the proxy-side method returning the descriptor directly 506fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Method* getDesc = new Method; 507fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->modifiers = PUBLIC; 508fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->returnType = STRING_TYPE; 509fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->returnTypeDimension = 0; 510fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->name = "getInterfaceDescriptor"; 511fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->statements = new StatementBlock; 512fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR"))); 513fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato proxy->elements.push_back(getDesc); 514fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 515fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 516fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoClass* 517fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_binder_interface_class(const interface_type* iface) 518fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{ 519fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato InterfaceType* interfaceType = static_cast<InterfaceType*>( 520fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NAMES.Find(iface->package, iface->name.data)); 521fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 522fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the interface class 523fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato Class* interface = new Class; 524fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->comment = gather_comments(iface->comments_token->extra); 525fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->modifiers = PUBLIC; 526fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->what = Class::INTERFACE; 527fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->type = interfaceType; 528fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->interfaces.push_back(IINTERFACE_TYPE); 529fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 530fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the stub inner class 531fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato StubClass* stub = new StubClass( 532fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()), 533fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interfaceType); 534fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface->elements.push_back(stub); 535fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 536fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // the proxy inner class 537fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato ProxyClass* proxy = new ProxyClass( 538fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato NAMES.Find(iface->package, 539fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato append(iface->name.data, ".Stub.Proxy").c_str()), 540fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interfaceType); 541fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato stub->elements.push_back(proxy); 542fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 543fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // stub and proxy support for getInterfaceDescriptor() 544fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato generate_interface_descriptors(stub, proxy); 545fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 546fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato // all the declared methods of the interface 547fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato int index = 0; 548fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato interface_item_type* item = iface->interface_items; 549fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato while (item != NULL) { 550fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato if (item->item_type == METHOD_TYPE) { 55102822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu method_type * method_item = (method_type*) item; 55202822d059031d539f4b4b69ae0ee6c4ad52388f2Maurice Chu generate_method(method_item, interface, stub, proxy, method_item->assigned_id); 553fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 554fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato item = item->next; 555fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato index++; 556fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato } 557fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 558fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato return interface; 559fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato} 560fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato 561