1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "generate_java.h" 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "Type.h" 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <string.h> 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h> 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdlib.h> 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <string.h> 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ================================================= 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass StubClass : public Class 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubClass(Type* type, Type* interfaceType); 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski virtual ~StubClass(); 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* transact_code; 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* transact_data; 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* transact_reply; 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* transact_flags; 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski SwitchStatement* transact_switch; 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiprivate: 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski void make_as_interface(Type* interfaceType); 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiStubClass::StubClass(Type* type, Type* interfaceType) 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :Class() 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->comment = "/** Local-side IPC implementation stub class. */"; 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->modifiers = PUBLIC | ABSTRACT | STATIC; 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->what = Class::CLASS; 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->type = type; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->extends = BINDER_NATIVE_TYPE; 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->interfaces.push_back(interfaceType); 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // descriptor 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Field* descriptor = new Field(STATIC | FINAL | PRIVATE, 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new Variable(STRING_TYPE, "DESCRIPTOR")); 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski descriptor->value = "\"" + interfaceType->QualifiedName() + "\""; 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(descriptor); 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // ctor 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* ctor = new Method; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->modifiers = PUBLIC; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->comment = "/** Construct the stub at attach it to the " 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "interface. */"; 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->name = "Stub"; 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->statements = new StatementBlock; 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface", 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 2, THIS_VALUE, new LiteralExpression("DESCRIPTOR")); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->statements->Add(attach); 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(ctor); 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asInterface 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski make_as_interface(interfaceType); 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // asBinder 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* asBinder = new Method; 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->modifiers = PUBLIC | OVERRIDE; 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->returnType = IBINDER_TYPE; 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->name = "asBinder"; 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->statements = new StatementBlock; 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->statements->Add(new ReturnStatement(THIS_VALUE)); 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(asBinder); 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // onTransact 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_code = new Variable(INT_TYPE, "code"); 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_data = new Variable(PARCEL_TYPE, "data"); 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_reply = new Variable(PARCEL_TYPE, "reply"); 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_flags = new Variable(INT_TYPE, "flags"); 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* onTransact = new Method; 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->modifiers = PUBLIC | OVERRIDE; 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->returnType = BOOLEAN_TYPE; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->name = "onTransact"; 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->parameters.push_back(this->transact_code); 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->parameters.push_back(this->transact_data); 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->parameters.push_back(this->transact_reply); 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->parameters.push_back(this->transact_flags); 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->statements = new StatementBlock; 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(onTransact); 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_switch = new SwitchStatement(this->transact_code); 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->statements->Add(this->transact_switch); 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4, 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_code, this->transact_data, 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->transact_reply, this->transact_flags); 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski onTransact->statements->Add(new ReturnStatement(superCall)); 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiStubClass::~StubClass() 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiStubClass::make_as_interface(Type *interfaceType) 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* obj = new Variable(IBINDER_TYPE, "obj"); 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* m = new Method; 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->comment = "/**\n * Cast an IBinder object into an "; 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->comment += interfaceType->QualifiedName(); 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->comment += " interface,\n"; 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->comment += " * generating a proxy if needed.\n */"; 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->modifiers = PUBLIC | STATIC; 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->returnType = interfaceType; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->name = "asInterface"; 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->parameters.push_back(obj); 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->statements = new StatementBlock; 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IfStatement* ifstatement = new IfStatement(); 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ifstatement->expression = new Comparison(obj, "==", NULL_VALUE); 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ifstatement->statements = new StatementBlock; 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ifstatement->statements->Add(new ReturnStatement(NULL_VALUE)); 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->statements->Add(ifstatement); 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // IInterface iin = obj.queryLocalInterface(DESCRIPTOR) 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface"); 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR")); 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IInterfaceType* iinType = new IInterfaceType(); 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable *iin = new Variable(iinType, "iin"); 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->statements->Add(iinVd); 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Ensure the instance type of the local object is as expected. 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // One scenario where this is needed is if another package (with a 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // different class loader) runs in the same process as the service. 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin; 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE); 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Comparison* instOfCheck = new Comparison(iin, " instanceof ", 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new LiteralExpression(interfaceType->QualifiedName())); 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IfStatement* instOfStatement = new IfStatement(); 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck); 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski instOfStatement->statements = new StatementBlock; 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin))); 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->statements->Add(instOfStatement); 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski string proxyType = interfaceType->QualifiedName(); 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxyType += ".Stub.Proxy"; 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NewExpression* ne = new NewExpression(NAMES.Find(proxyType)); 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ne->arguments.push_back(obj); 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski m->statements->Add(new ReturnStatement(ne)); 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(m); 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ================================================= 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiclass ProxyClass : public Class 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic: 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ProxyClass(Type* type, InterfaceType* interfaceType); 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski virtual ~ProxyClass(); 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* mRemote; 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool mOneWay; 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}; 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType) 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski :Class() 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->modifiers = PRIVATE | STATIC; 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->what = Class::CLASS; 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->type = type; 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->interfaces.push_back(interfaceType); 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mOneWay = interfaceType->OneWay(); 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // IBinder mRemote 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mRemote = new Variable(IBINDER_TYPE, "mRemote"); 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(new Field(PRIVATE, mRemote)); 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // Proxy() 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* remote = new Variable(IBINDER_TYPE, "remote"); 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* ctor = new Method; 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->name = "Proxy"; 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->statements = new StatementBlock; 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->parameters.push_back(remote); 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ctor->statements->Add(new Assignment(mRemote, remote)); 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(ctor); 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // IBinder asBinder() 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* asBinder = new Method; 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->modifiers = PUBLIC | OVERRIDE; 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->returnType = IBINDER_TYPE; 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->name = "asBinder"; 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->statements = new StatementBlock; 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski asBinder->statements->Add(new ReturnStatement(mRemote)); 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski this->elements.push_back(asBinder); 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiProxyClass::~ProxyClass() 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ================================================= 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_new_array(Type* t, StatementBlock* addTo, Variable* v, 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* parcel) 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* len = new Variable(INT_TYPE, v->name + "_length"); 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt"))); 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IfStatement* lencheck = new IfStatement(); 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lencheck->expression = new Comparison(len, "<", new LiteralExpression("0")); 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lencheck->statements->Add(new Assignment(v, NULL_VALUE)); 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lencheck->elseif = new IfStatement(); 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski lencheck->elseif->statements->Add(new Assignment(v, 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new NewArrayExpression(t, len))); 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski addTo->Add(lencheck); 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v, 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* parcel, int flags) 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 0) { 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->WriteToParcel(addTo, v, parcel, flags); 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 1) { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->WriteArrayToParcel(addTo, v, parcel, flags); 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v, 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* parcel, Variable** cl) 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 0) { 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->CreateFromParcel(addTo, v, parcel, cl); 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 1) { 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->CreateArrayFromParcel(addTo, v, parcel, cl); 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v, 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* parcel, Variable** cl) 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 0) { 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->ReadFromParcel(addTo, v, parcel, cl); 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (v->dimension == 1) { 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski t->ReadArrayFromParcel(addTo, v, parcel, cl); 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_method(const method_type* method, Class* interface, 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubClass* stubClass, ProxyClass* proxyClass, int index) 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg_type* arg; 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int i; 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasOutParams = false; 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const bool oneway = proxyClass->mOneWay || method->oneway; 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // == the TRANSACT_ constant ============================================= 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski string transactCodeName = "TRANSACTION_"; 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski transactCodeName += method->name.data; 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski char transactCodeValue[60]; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index); 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Field* transactCode = new Field(STATIC | FINAL, 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new Variable(INT_TYPE, transactCodeName)); 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski transactCode->value = transactCodeValue; 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->elements.push_back(transactCode); 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // == the declaration in the interface =================================== 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* decl = new Method; 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->comment = gather_comments(method->comments_token->extra); 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->modifiers = PUBLIC; 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->returnType = NAMES.Search(method->type.type.data); 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->returnTypeDimension = method->type.dimension; 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->name = method->name.data; 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->parameters.push_back(new Variable( 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAMES.Search(arg->type.type.data), arg->name.data, 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg->type.dimension)); 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->elements.push_back(decl); 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // == the stub method ==================================================== 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Case* c = new Case(transactCodeName); 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data); 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // interface token validation is the very first thing we do 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new MethodCall(stubClass->transact_data, 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "enforceInterface", 1, new LiteralExpression("DESCRIPTOR"))); 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // args 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* cl = NULL; 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski VariableFactory stubArgs("_arg"); 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type* t = NAMES.Search(arg->type.type.data); 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* v = stubArgs.Get(t); 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v->dimension = arg->type.dimension; 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new VariableDeclaration(v)); 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (convert_direction(arg->direction.data) & IN_PARAMETER) { 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_create_from_parcel(t, c->statements, v, 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->transact_data, &cl); 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (arg->type.dimension == 0) { 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new Assignment(v, new NewExpression(v->type))); 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (arg->type.dimension == 1) { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_new_array(v->type, c->statements, v, 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->transact_data); 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else { 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__, 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski __LINE__); 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski realCall->arguments.push_back(v); 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the real call 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* _result = NULL; 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (0 == strcmp(method->type.type.data, "void")) { 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(realCall); 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!oneway) { 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // report that there were no exceptions 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* ex = new MethodCall(stubClass->transact_reply, 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "writeNoException", 0); 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(ex); 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _result = new Variable(decl->returnType, "_result", 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski decl->returnTypeDimension); 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new VariableDeclaration(_result, realCall)); 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!oneway) { 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // report that there were no exceptions 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* ex = new MethodCall(stubClass->transact_reply, 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski "writeNoException", 0); 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(ex); 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // marshall the return value 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_write_to_parcel(decl->returnType, c->statements, _result, 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->transact_reply, 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type::PARCELABLE_WRITE_RETURN_VALUE); 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // out parameters 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski i = 0; 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type* t = NAMES.Search(arg->type.type.data); 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* v = stubArgs.Get(i++); 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (convert_direction(arg->direction.data) & OUT_PARAMETER) { 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_write_to_parcel(t, c->statements, v, 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->transact_reply, 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type::PARCELABLE_WRITE_RETURN_VALUE); 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasOutParams = true; 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // return true 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new ReturnStatement(TRUE_VALUE)); 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stubClass->transact_switch->cases.push_back(c); 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // == the proxy method =================================================== 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* proxy = new Method; 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->comment = gather_comments(method->comments_token->extra); 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->modifiers = PUBLIC | OVERRIDE; 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->returnType = NAMES.Search(method->type.type.data); 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->returnTypeDimension = method->type.dimension; 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->name = method->name.data; 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements = new StatementBlock; 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->parameters.push_back(new Variable( 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAMES.Search(arg->type.type.data), arg->name.data, 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg->type.dimension)); 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE); 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxyClass->elements.push_back(proxy); 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the parcels 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* _data = new Variable(PARCEL_TYPE, "_data"); 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(new VariableDeclaration(_data, 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new MethodCall(PARCEL_TYPE, "obtain"))); 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* _reply = NULL; 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!oneway) { 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _reply = new Variable(PARCEL_TYPE, "_reply"); 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(new VariableDeclaration(_reply, 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new MethodCall(PARCEL_TYPE, "obtain"))); 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the return value 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _result = NULL; 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (0 != strcmp(method->type.type.data, "void")) { 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _result = new Variable(proxy->returnType, "_result", 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski method->type.dimension); 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(new VariableDeclaration(_result)); 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // try and finally 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski TryStatement* tryStatement = new TryStatement(); 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(tryStatement); 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski FinallyStatement* finallyStatement = new FinallyStatement(); 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(finallyStatement); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the interface identifier token: the DESCRIPTOR constant, marshalled as a string 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken", 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1, new LiteralExpression("DESCRIPTOR"))); 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the parameters 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type* t = NAMES.Search(arg->type.type.data); 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* v = new Variable(t, arg->name.data, arg->type.dimension); 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int dir = convert_direction(arg->direction.data); 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (dir == OUT_PARAMETER && arg->type.dimension != 0) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski IfStatement* checklen = new IfStatement(); 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checklen->expression = new Comparison(v, "==", NULL_VALUE); 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checklen->statements->Add(new MethodCall(_data, "writeInt", 1, 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new LiteralExpression("-1"))); 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checklen->elseif = new IfStatement(); 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski checklen->elseif->statements->Add(new MethodCall(_data, "writeInt", 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1, new FieldVariable(v, "length"))); 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tryStatement->statements->Add(checklen); 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski else if (dir & IN_PARAMETER) { 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_write_to_parcel(t, tryStatement->statements, v, _data, 0); 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the transact call 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4, 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new LiteralExpression("Stub." + transactCodeName), 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski _data, _reply ? _reply : NULL_VALUE, 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski new LiteralExpression( 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0")); 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tryStatement->statements->Add(call); 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // throw back exceptions. 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_reply) { 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski MethodCall* ex = new MethodCall(_reply, "readException", 0); 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tryStatement->statements->Add(ex); 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // returning and cleanup 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_reply != NULL) { 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_result != NULL) { 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_create_from_parcel(proxy->returnType, 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski tryStatement->statements, _result, _reply, &cl); 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the out/inout parameters 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = method->args; 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (arg != NULL) { 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Type* t = NAMES.Search(arg->type.type.data); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Variable* v = new Variable(t, arg->name.data, arg->type.dimension); 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (convert_direction(arg->direction.data) & OUT_PARAMETER) { 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_read_from_parcel(t, tryStatement->statements, 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski v, _reply, &cl); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski arg = arg->next; 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finallyStatement->statements->Add(new MethodCall(_reply, "recycle")); 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski finallyStatement->statements->Add(new MethodCall(_data, "recycle")); 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (_result != NULL) { 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->statements->Add(new ReturnStatement(_result)); 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic void 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_interface_descriptors(StubClass* stub, ProxyClass* proxy) 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the interface descriptor transaction handler 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Case* c = new Case("INTERFACE_TRANSACTION"); 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new MethodCall(stub->transact_reply, "writeString", 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 1, new LiteralExpression("DESCRIPTOR"))); 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski c->statements->Add(new ReturnStatement(TRUE_VALUE)); 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stub->transact_switch->cases.push_back(c); 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // and the proxy-side method returning the descriptor directly 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Method* getDesc = new Method; 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->modifiers = PUBLIC; 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->returnType = STRING_TYPE; 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->returnTypeDimension = 0; 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->name = "getInterfaceDescriptor"; 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->statements = new StatementBlock; 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR"))); 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski proxy->elements.push_back(getDesc); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiClass* 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskigenerate_binder_interface_class(const interface_type* iface) 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski InterfaceType* interfaceType = static_cast<InterfaceType*>( 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAMES.Find(iface->package, iface->name.data)); 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the interface class 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski Class* interface = new Class; 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->comment = gather_comments(iface->comments_token->extra); 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->modifiers = PUBLIC; 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->what = Class::INTERFACE; 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->type = interfaceType; 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->interfaces.push_back(IINTERFACE_TYPE); 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the stub inner class 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski StubClass* stub = new StubClass( 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()), 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interfaceType); 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface->elements.push_back(stub); 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the proxy inner class 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ProxyClass* proxy = new ProxyClass( 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski NAMES.Find(iface->package, 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski append(iface->name.data, ".Stub.Proxy").c_str()), 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interfaceType); 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski stub->elements.push_back(proxy); 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // stub and proxy support for getInterfaceDescriptor() 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_interface_descriptors(stub, proxy); 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // all the declared methods of the interface 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int index = 0; 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski interface_item_type* item = iface->interface_items; 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski while (item != NULL) { 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (item->item_type == METHOD_TYPE) { 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski method_type * method_item = (method_type*) item; 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski generate_method(method_item, interface, stub, proxy, method_item->assigned_id); 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski item = item->next; 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski index++; 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return interface; 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 561