|
23 | 23 | # define O_BINARY 0 |
24 | 24 | #endif |
25 | 25 |
|
| 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 | + |
26 | 32 | using namespace std; |
27 | 33 |
|
28 | 34 | static void |
@@ -847,6 +853,72 @@ parse_preprocessed_file(const string& filename) |
847 | 853 | return 0; |
848 | 854 | } |
849 | 855 |
|
| 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 | + |
850 | 922 | // ========================================================== |
851 | 923 | static int |
852 | 924 | compile_aidl(Options& options) |
@@ -937,6 +1009,12 @@ compile_aidl(Options& options) |
937 | 1009 | bool onlyParcelable = false; |
938 | 1010 | err |= exactly_one_interface(options.inputFileName.c_str(), mainDoc, options, &onlyParcelable); |
939 | 1011 |
|
| 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 | + |
940 | 1018 | // after this, there shouldn't be any more errors because of the |
941 | 1019 | // input. |
942 | 1020 | if (err != 0 || mainDoc == NULL) { |
|
0 commit comments