service.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. /*
  2. * Copyright 2013 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <binder/Parcel.h>
  17. #include <binder/ProcessState.h>
  18. #include <binder/IServiceManager.h>
  19. #include <binder/TextOutput.h>
  20. #include <getopt.h>
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #include <unistd.h>
  25. #include <sys/time.h>
  26. using namespace android;
  27. void writeString16(Parcel& parcel, const char* string)
  28. {
  29. if (string != NULL)
  30. {
  31. parcel.writeString16(String16(string));
  32. }
  33. else
  34. {
  35. parcel.writeInt32(-1);
  36. }
  37. }
  38. // get the name of the generic interface we hold a reference to
  39. static String16 get_interface_name(sp<IBinder> service)
  40. {
  41. if (service != NULL) {
  42. Parcel data, reply;
  43. status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
  44. if (err == NO_ERROR) {
  45. return reply.readString16();
  46. }
  47. }
  48. return String16();
  49. }
  50. static String8 good_old_string(const String16& src)
  51. {
  52. String8 name8;
  53. char ch8[2];
  54. ch8[1] = 0;
  55. for (unsigned j = 0; j < src.size(); j++) {
  56. char16_t ch = src[j];
  57. if (ch < 128) ch8[0] = (char)ch;
  58. name8.append(ch8);
  59. }
  60. return name8;
  61. }
  62. int main(int argc, char* const argv[])
  63. {
  64. sp<IServiceManager> sm = defaultServiceManager();
  65. fflush(stdout);
  66. if (sm == NULL) {
  67. aerr << "service: Unable to get default service manager!" << endl;
  68. return 20;
  69. }
  70. bool wantsUsage = false;
  71. int result = 0;
  72. while (1) {
  73. int ic = getopt(argc, argv, "h?");
  74. if (ic < 0)
  75. break;
  76. switch (ic) {
  77. case 'h':
  78. case '?':
  79. wantsUsage = true;
  80. break;
  81. default:
  82. aerr << "service: Unknown option -" << ic << endl;
  83. wantsUsage = true;
  84. result = 10;
  85. break;
  86. }
  87. }
  88. if (optind >= argc) {
  89. wantsUsage = true;
  90. } else if (!wantsUsage) {
  91. if (strcmp(argv[optind], "check") == 0) {
  92. optind++;
  93. if (optind < argc) {
  94. sp<IBinder> service = sm->checkService(String16(argv[optind]));
  95. aout << "Service " << argv[optind] <<
  96. (service == NULL ? ": not found" : ": found") << endl;
  97. } else {
  98. aerr << "service: No service specified for check" << endl;
  99. wantsUsage = true;
  100. result = 10;
  101. }
  102. }
  103. else if (strcmp(argv[optind], "list") == 0) {
  104. Vector<String16> services = sm->listServices();
  105. aout << "Found " << services.size() << " services:" << endl;
  106. for (unsigned i = 0; i < services.size(); i++) {
  107. String16 name = services[i];
  108. sp<IBinder> service = sm->checkService(name);
  109. aout << i
  110. << "\t" << good_old_string(name)
  111. << ": [" << good_old_string(get_interface_name(service)) << "]"
  112. << endl;
  113. }
  114. } else if (strcmp(argv[optind], "call") == 0) {
  115. optind++;
  116. if (optind+1 < argc) {
  117. int serviceArg = optind;
  118. sp<IBinder> service = sm->checkService(String16(argv[optind++]));
  119. String16 ifName = get_interface_name(service);
  120. int32_t code = atoi(argv[optind++]);
  121. if (service != NULL && ifName.size() > 0) {
  122. Parcel data, reply;
  123. // the interface name is first
  124. data.writeInterfaceToken(ifName);
  125. // then the rest of the call arguments
  126. while (optind < argc) {
  127. if (strcmp(argv[optind], "i32") == 0) {
  128. optind++;
  129. if (optind >= argc) {
  130. aerr << "service: no integer supplied for 'i32'" << endl;
  131. wantsUsage = true;
  132. result = 10;
  133. break;
  134. }
  135. data.writeInt32(atoi(argv[optind++]));
  136. } else if (strcmp(argv[optind], "i64") == 0) {
  137. optind++;
  138. if (optind >= argc) {
  139. aerr << "service: no integer supplied for 'i64'" << endl;
  140. wantsUsage = true;
  141. result = 10;
  142. break;
  143. }
  144. data.writeInt64(atoll(argv[optind++]));
  145. } else if (strcmp(argv[optind], "s16") == 0) {
  146. optind++;
  147. if (optind >= argc) {
  148. aerr << "service: no string supplied for 's16'" << endl;
  149. wantsUsage = true;
  150. result = 10;
  151. break;
  152. }
  153. data.writeString16(String16(argv[optind++]));
  154. } else if (strcmp(argv[optind], "f") == 0) {
  155. optind++;
  156. if (optind >= argc) {
  157. aerr << "service: no number supplied for 'f'" << endl;
  158. wantsUsage = true;
  159. result = 10;
  160. break;
  161. }
  162. data.writeFloat(atof(argv[optind++]));
  163. } else if (strcmp(argv[optind], "d") == 0) {
  164. optind++;
  165. if (optind >= argc) {
  166. aerr << "service: no number supplied for 'd'" << endl;
  167. wantsUsage = true;
  168. result = 10;
  169. break;
  170. }
  171. data.writeDouble(atof(argv[optind++]));
  172. } else if (strcmp(argv[optind], "null") == 0) {
  173. optind++;
  174. data.writeStrongBinder(NULL);
  175. } else if (strcmp(argv[optind], "intent") == 0) {
  176. char* action = NULL;
  177. char* dataArg = NULL;
  178. char* type = NULL;
  179. int launchFlags = 0;
  180. char* component = NULL;
  181. int categoryCount = 0;
  182. char* categories[16];
  183. char* context1 = NULL;
  184. optind++;
  185. while (optind < argc)
  186. {
  187. char* key = strtok_r(argv[optind], "=", &context1);
  188. char* value = strtok_r(NULL, "=", &context1);
  189. // we have reached the end of the XXX=XXX args.
  190. if (key == NULL) break;
  191. if (strcmp(key, "action") == 0)
  192. {
  193. action = value;
  194. }
  195. else if (strcmp(key, "data") == 0)
  196. {
  197. dataArg = value;
  198. }
  199. else if (strcmp(key, "type") == 0)
  200. {
  201. type = value;
  202. }
  203. else if (strcmp(key, "launchFlags") == 0)
  204. {
  205. launchFlags = atoi(value);
  206. }
  207. else if (strcmp(key, "component") == 0)
  208. {
  209. component = value;
  210. }
  211. else if (strcmp(key, "categories") == 0)
  212. {
  213. char* context2 = NULL;
  214. int categoryCount = 0;
  215. categories[categoryCount] = strtok_r(value, ",", &context2);
  216. while (categories[categoryCount] != NULL)
  217. {
  218. categoryCount++;
  219. categories[categoryCount] = strtok_r(NULL, ",", &context2);
  220. }
  221. }
  222. optind++;
  223. }
  224. writeString16(data, action);
  225. writeString16(data, dataArg);
  226. writeString16(data, type);
  227. data.writeInt32(launchFlags);
  228. writeString16(data, component);
  229. if (categoryCount > 0)
  230. {
  231. data.writeInt32(categoryCount);
  232. for (int i = 0 ; i < categoryCount ; i++)
  233. {
  234. writeString16(data, categories[i]);
  235. }
  236. }
  237. else
  238. {
  239. data.writeInt32(0);
  240. }
  241. // for now just set the extra field to be null.
  242. data.writeInt32(-1);
  243. } else {
  244. aerr << "service: unknown option " << argv[optind] << endl;
  245. wantsUsage = true;
  246. result = 10;
  247. break;
  248. }
  249. }
  250. service->transact(code, data, &reply);
  251. aout << "Result: " << reply << endl;
  252. } else {
  253. aerr << "service: Service " << argv[serviceArg]
  254. << " does not exist" << endl;
  255. result = 10;
  256. }
  257. } else {
  258. if (optind < argc) {
  259. aerr << "service: No service specified for call" << endl;
  260. } else {
  261. aerr << "service: No code specified for call" << endl;
  262. }
  263. wantsUsage = true;
  264. result = 10;
  265. }
  266. } else {
  267. aerr << "service: Unknown command " << argv[optind] << endl;
  268. wantsUsage = true;
  269. result = 10;
  270. }
  271. }
  272. if (wantsUsage) {
  273. aout << "Usage: service [-h|-?]\n"
  274. " service list\n"
  275. " service check SERVICE\n"
  276. " service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR ] ...\n"
  277. "Options:\n"
  278. " i32: Write the 32-bit integer N into the send parcel.\n"
  279. " i64: Write the 64-bit integer N into the send parcel.\n"
  280. " f: Write the 32-bit single-precision number N into the send parcel.\n"
  281. " d: Write the 64-bit double-precision number N into the send parcel.\n"
  282. " s16: Write the UTF-16 string STR into the send parcel.\n";
  283. // " intent: Write and Intent int the send parcel. ARGS can be\n"
  284. // " action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
  285. return result;
  286. }
  287. return result;
  288. }