Skip to content

Commit 32d7f8c

Browse files
Maurice ChuAndroid (Google) Code Review
authored andcommitted
Merge "Enhance AIDL to take an explicit id for methods"
2 parents f991659 + 02822d0 commit 32d7f8c

File tree

5 files changed

+132
-4
lines changed

5 files changed

+132
-4
lines changed

tools/aidl/aidl.cpp

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323
# define O_BINARY 0
2424
#endif
2525

26+
// The following are gotten as the offset from the allowable id's between
27+
// android.os.IBinder.FIRST_CALL_TRANSACTION=1 and
28+
// android.os.IBinder.LAST_CALL_TRANSACTION=16777215
29+
#define MIN_USER_SET_METHOD_ID 0
30+
#define MAX_USER_SET_METHOD_ID 16777214
31+
2632
using namespace std;
2733

2834
static void
@@ -847,6 +853,72 @@ parse_preprocessed_file(const string& filename)
847853
return 0;
848854
}
849855

856+
static int
857+
check_and_assign_method_ids(const char * filename, interface_item_type* first_item)
858+
{
859+
// Check whether there are any methods with manually assigned id's and any that are not.
860+
// Either all method id's must be manually assigned or all of them must not.
861+
// Also, check for duplicates of user set id's and that the id's are within the proper bounds.
862+
set<int> usedIds;
863+
interface_item_type* item = first_item;
864+
bool hasUnassignedIds = false;
865+
bool hasAssignedIds = false;
866+
while (item != NULL) {
867+
if (item->item_type == METHOD_TYPE) {
868+
method_type* method_item = (method_type*)item;
869+
if (method_item->hasId) {
870+
hasAssignedIds = true;
871+
method_item->assigned_id = atoi(method_item->id.data);
872+
// Ensure that the user set id is not duplicated.
873+
if (usedIds.find(method_item->assigned_id) != usedIds.end()) {
874+
// We found a duplicate id, so throw an error.
875+
fprintf(stderr,
876+
"%s:%d Found duplicate method id (%d) for method: %s\n",
877+
filename, method_item->id.lineno,
878+
method_item->assigned_id, method_item->name.data);
879+
return 1;
880+
}
881+
// Ensure that the user set id is within the appropriate limits
882+
if (method_item->assigned_id < MIN_USER_SET_METHOD_ID ||
883+
method_item->assigned_id > MAX_USER_SET_METHOD_ID) {
884+
fprintf(stderr, "%s:%d Found out of bounds id (%d) for method: %s\n",
885+
filename, method_item->id.lineno,
886+
method_item->assigned_id, method_item->name.data);
887+
fprintf(stderr, " Value for id must be between %d and %d inclusive.\n",
888+
MIN_USER_SET_METHOD_ID, MAX_USER_SET_METHOD_ID);
889+
return 1;
890+
}
891+
usedIds.insert(method_item->assigned_id);
892+
} else {
893+
hasUnassignedIds = true;
894+
}
895+
if (hasAssignedIds && hasUnassignedIds) {
896+
fprintf(stderr,
897+
"%s: You must either assign id's to all methods or to none of them.\n",
898+
filename);
899+
return 1;
900+
}
901+
}
902+
item = item->next;
903+
}
904+
905+
// In the case that all methods have unassigned id's, set a unique id for them.
906+
if (hasUnassignedIds) {
907+
int newId = 0;
908+
item = first_item;
909+
while (item != NULL) {
910+
if (item->item_type == METHOD_TYPE) {
911+
method_type* method_item = (method_type*)item;
912+
method_item->assigned_id = newId++;
913+
}
914+
item = item->next;
915+
}
916+
}
917+
918+
// success
919+
return 0;
920+
}
921+
850922
// ==========================================================
851923
static int
852924
compile_aidl(Options& options)
@@ -937,6 +1009,12 @@ compile_aidl(Options& options)
9371009
bool onlyParcelable = false;
9381010
err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable);
9391011

1012+
// If this includes an interface definition, then assign method ids and validate.
1013+
if (!onlyParcelable) {
1014+
err |= check_and_assign_method_ids(options.inputFileName.c_str(),
1015+
((interface_type*)mainDoc)->interface_items);
1016+
}
1017+
9401018
// after this, there shouldn't be any more errors because of the
9411019
// input.
9421020
if (err != 0 || mainDoc == NULL) {

tools/aidl/aidl_language.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,13 @@ typedef struct method_type {
5757
buffer_type open_paren_token;
5858
arg_type* args;
5959
buffer_type close_paren_token;
60+
bool hasId;
61+
buffer_type equals_token;
62+
buffer_type id;
6063
// XXX missing comments/copy text here
6164
buffer_type semicolon_token;
6265
buffer_type* comments_token; // points into this structure, DO NOT DELETE
66+
int assigned_id;
6367
} method_type;
6468

6569
enum {

tools/aidl/aidl_language_l.l

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static void do_package_statement(const char* importText);
3636
identifier [_a-zA-Z][_a-zA-Z0-9\.]*
3737
whitespace ([ \t\n\r]+)
3838
brackets \[{whitespace}?\]
39+
idvalue (0|[1-9][0-9]*)
3940

4041
%%
4142

@@ -77,6 +78,7 @@ brackets \[{whitespace}?\]
7778
\( { SET_BUFFER('('); return '('; }
7879
\) { SET_BUFFER(')'); return ')'; }
7980
, { SET_BUFFER(','); return ','; }
81+
= { SET_BUFFER('='); return '='; }
8082

8183
/* keywords */
8284
parcelable { SET_BUFFER(PARCELABLE); return PARCELABLE; }
@@ -89,7 +91,7 @@ inout { SET_BUFFER(INOUT); return INOUT; }
8991
oneway { SET_BUFFER(ONEWAY); return ONEWAY; }
9092

9193
{brackets}+ { SET_BUFFER(ARRAY); return ARRAY; }
92-
94+
{idvalue} { SET_BUFFER(IDVALUE); return IDVALUE; }
9395
{identifier} { SET_BUFFER(IDENTIFIER); return IDENTIFIER; }
9496
{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> {
9597
SET_BUFFER(GENERIC); return GENERIC; }

tools/aidl/aidl_language_y.y

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ static int count_brackets(const char*);
1515
%token IMPORT
1616
%token PACKAGE
1717
%token IDENTIFIER
18+
%token IDVALUE
1819
%token GENERIC
1920
%token ARRAY
2021
%token PARCELABLE
@@ -211,13 +212,16 @@ method_decl:
211212
method_type *method = (method_type*)malloc(sizeof(method_type));
212213
method->interface_item.item_type = METHOD_TYPE;
213214
method->interface_item.next = NULL;
214-
method->type = $1.type;
215215
method->oneway = false;
216+
method->type = $1.type;
216217
memset(&method->oneway_token, 0, sizeof(buffer_type));
217218
method->name = $2.buffer;
218219
method->open_paren_token = $3.buffer;
219220
method->args = $4.arg;
220221
method->close_paren_token = $5.buffer;
222+
method->hasId = false;
223+
memset(&method->equals_token, 0, sizeof(buffer_type));
224+
memset(&method->id, 0, sizeof(buffer_type));
221225
method->semicolon_token = $6.buffer;
222226
method->comments_token = &method->type.type;
223227
$$.method = method;
@@ -233,10 +237,49 @@ method_decl:
233237
method->open_paren_token = $4.buffer;
234238
method->args = $5.arg;
235239
method->close_paren_token = $6.buffer;
240+
method->hasId = false;
241+
memset(&method->equals_token, 0, sizeof(buffer_type));
242+
memset(&method->id, 0, sizeof(buffer_type));
236243
method->semicolon_token = $7.buffer;
237244
method->comments_token = &method->oneway_token;
238245
$$.method = method;
239246
}
247+
| type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
248+
method_type *method = (method_type*)malloc(sizeof(method_type));
249+
method->interface_item.item_type = METHOD_TYPE;
250+
method->interface_item.next = NULL;
251+
method->oneway = false;
252+
memset(&method->oneway_token, 0, sizeof(buffer_type));
253+
method->type = $1.type;
254+
method->name = $2.buffer;
255+
method->open_paren_token = $3.buffer;
256+
method->args = $4.arg;
257+
method->close_paren_token = $5.buffer;
258+
method->hasId = true;
259+
method->equals_token = $6.buffer;
260+
method->id = $7.buffer;
261+
method->semicolon_token = $8.buffer;
262+
method->comments_token = &method->type.type;
263+
$$.method = method;
264+
}
265+
| ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
266+
method_type *method = (method_type*)malloc(sizeof(method_type));
267+
method->interface_item.item_type = METHOD_TYPE;
268+
method->interface_item.next = NULL;
269+
method->oneway = true;
270+
method->oneway_token = $1.buffer;
271+
method->type = $2.type;
272+
method->name = $3.buffer;
273+
method->open_paren_token = $4.buffer;
274+
method->args = $5.arg;
275+
method->close_paren_token = $6.buffer;
276+
method->hasId = true;
277+
method->equals_token = $7.buffer;
278+
method->id = $8.buffer;
279+
method->semicolon_token = $9.buffer;
280+
method->comments_token = &method->oneway_token;
281+
$$.method = method;
282+
}
240283
;
241284

242285
arg_list:

tools/aidl/generate_java_binder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ generate_method(const method_type* method, Class* interface,
260260
string transactCodeName = "TRANSACTION_";
261261
transactCodeName += method->name.data;
262262

263-
char transactCodeValue[50];
263+
char transactCodeValue[60];
264264
sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
265265

266266
Field* transactCode = new Field(STATIC | FINAL,
@@ -548,7 +548,8 @@ generate_binder_interface_class(const interface_type* iface)
548548
interface_item_type* item = iface->interface_items;
549549
while (item != NULL) {
550550
if (item->item_type == METHOD_TYPE) {
551-
generate_method((method_type*)item, interface, stub, proxy, index);
551+
method_type * method_item = (method_type*) item;
552+
generate_method(method_item, interface, stub, proxy, method_item->assigned_id);
552553
}
553554
item = item->next;
554555
index++;

0 commit comments

Comments
 (0)