xref: /aosp_15_r20/frameworks/native/cmds/service/service.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright 2013 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
18*38e8c45fSAndroid Build Coastguard Worker #include <binder/ProcessState.h>
19*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/TextOutput.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <cutils/ashmem.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker #include <getopt.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <libgen.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <stdlib.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <stdio.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <string.h>
28*38e8c45fSAndroid Build Coastguard Worker #include <unistd.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <sys/mman.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <sys/time.h>
31*38e8c45fSAndroid Build Coastguard Worker #include <sys/types.h>
32*38e8c45fSAndroid Build Coastguard Worker #include <sys/stat.h>
33*38e8c45fSAndroid Build Coastguard Worker #include <fcntl.h>
34*38e8c45fSAndroid Build Coastguard Worker 
35*38e8c45fSAndroid Build Coastguard Worker using namespace android;
36*38e8c45fSAndroid Build Coastguard Worker 
writeString16(Parcel & parcel,const char * string)37*38e8c45fSAndroid Build Coastguard Worker void writeString16(Parcel& parcel, const char* string)
38*38e8c45fSAndroid Build Coastguard Worker {
39*38e8c45fSAndroid Build Coastguard Worker     if (string != nullptr)
40*38e8c45fSAndroid Build Coastguard Worker     {
41*38e8c45fSAndroid Build Coastguard Worker         parcel.writeString16(String16(string));
42*38e8c45fSAndroid Build Coastguard Worker     }
43*38e8c45fSAndroid Build Coastguard Worker     else
44*38e8c45fSAndroid Build Coastguard Worker     {
45*38e8c45fSAndroid Build Coastguard Worker         parcel.writeInt32(-1);
46*38e8c45fSAndroid Build Coastguard Worker     }
47*38e8c45fSAndroid Build Coastguard Worker }
48*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char * const argv[])49*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char* const argv[])
50*38e8c45fSAndroid Build Coastguard Worker {
51*38e8c45fSAndroid Build Coastguard Worker     bool wantsUsage = false;
52*38e8c45fSAndroid Build Coastguard Worker     int result = 0;
53*38e8c45fSAndroid Build Coastguard Worker 
54*38e8c45fSAndroid Build Coastguard Worker     /* Strip path off the program name. */
55*38e8c45fSAndroid Build Coastguard Worker     char* prog_name = basename(argv[0]);
56*38e8c45fSAndroid Build Coastguard Worker 
57*38e8c45fSAndroid Build Coastguard Worker     while (1) {
58*38e8c45fSAndroid Build Coastguard Worker         int ic = getopt(argc, argv, "h?");
59*38e8c45fSAndroid Build Coastguard Worker         if (ic < 0)
60*38e8c45fSAndroid Build Coastguard Worker             break;
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker         switch (ic) {
63*38e8c45fSAndroid Build Coastguard Worker         case 'h':
64*38e8c45fSAndroid Build Coastguard Worker         case '?':
65*38e8c45fSAndroid Build Coastguard Worker             wantsUsage = true;
66*38e8c45fSAndroid Build Coastguard Worker             break;
67*38e8c45fSAndroid Build Coastguard Worker         default:
68*38e8c45fSAndroid Build Coastguard Worker             aerr << prog_name << ": Unknown option -" << ic << endl;
69*38e8c45fSAndroid Build Coastguard Worker             wantsUsage = true;
70*38e8c45fSAndroid Build Coastguard Worker             result = 10;
71*38e8c45fSAndroid Build Coastguard Worker             break;
72*38e8c45fSAndroid Build Coastguard Worker         }
73*38e8c45fSAndroid Build Coastguard Worker     }
74*38e8c45fSAndroid Build Coastguard Worker #ifdef VENDORSERVICES
75*38e8c45fSAndroid Build Coastguard Worker     ProcessState::initWithDriver("/dev/vndbinder");
76*38e8c45fSAndroid Build Coastguard Worker #endif
77*38e8c45fSAndroid Build Coastguard Worker #ifndef __ANDROID__
78*38e8c45fSAndroid Build Coastguard Worker     setDefaultServiceManager(createRpcDelegateServiceManager({.maxOutgoingConnections = 1}));
79*38e8c45fSAndroid Build Coastguard Worker #endif
80*38e8c45fSAndroid Build Coastguard Worker     sp<IServiceManager> sm = defaultServiceManager();
81*38e8c45fSAndroid Build Coastguard Worker     fflush(stdout);
82*38e8c45fSAndroid Build Coastguard Worker     if (sm == nullptr) {
83*38e8c45fSAndroid Build Coastguard Worker         aerr << prog_name << ": Unable to get default service manager!" << endl;
84*38e8c45fSAndroid Build Coastguard Worker         return 20;
85*38e8c45fSAndroid Build Coastguard Worker     }
86*38e8c45fSAndroid Build Coastguard Worker 
87*38e8c45fSAndroid Build Coastguard Worker     if (optind >= argc) {
88*38e8c45fSAndroid Build Coastguard Worker         wantsUsage = true;
89*38e8c45fSAndroid Build Coastguard Worker     } else if (!wantsUsage) {
90*38e8c45fSAndroid Build Coastguard Worker         if (strcmp(argv[optind], "check") == 0) {
91*38e8c45fSAndroid Build Coastguard Worker             optind++;
92*38e8c45fSAndroid Build Coastguard Worker             if (optind < argc) {
93*38e8c45fSAndroid Build Coastguard Worker                 sp<IBinder> service = sm->checkService(String16(argv[optind]));
94*38e8c45fSAndroid Build Coastguard Worker                 aout << "Service " << argv[optind] <<
95*38e8c45fSAndroid Build Coastguard Worker                     (service == nullptr ? ": not found" : ": found") << endl;
96*38e8c45fSAndroid Build Coastguard Worker             } else {
97*38e8c45fSAndroid Build Coastguard Worker                 aerr << prog_name << ": No service specified for check" << endl;
98*38e8c45fSAndroid Build Coastguard Worker                 wantsUsage = true;
99*38e8c45fSAndroid Build Coastguard Worker                 result = 10;
100*38e8c45fSAndroid Build Coastguard Worker             }
101*38e8c45fSAndroid Build Coastguard Worker         }
102*38e8c45fSAndroid Build Coastguard Worker         else if (strcmp(argv[optind], "list") == 0) {
103*38e8c45fSAndroid Build Coastguard Worker             Vector<String16> services = sm->listServices();
104*38e8c45fSAndroid Build Coastguard Worker             aout << "Found " << services.size() << " services:" << endl;
105*38e8c45fSAndroid Build Coastguard Worker             for (unsigned i = 0; i < services.size(); i++) {
106*38e8c45fSAndroid Build Coastguard Worker                 String16 name = services[i];
107*38e8c45fSAndroid Build Coastguard Worker                 sp<IBinder> service = sm->checkService(name);
108*38e8c45fSAndroid Build Coastguard Worker                 aout << i
109*38e8c45fSAndroid Build Coastguard Worker                      << "\t" << name
110*38e8c45fSAndroid Build Coastguard Worker                      << ": [" << (service ? service->getInterfaceDescriptor() : String16()) << "]"
111*38e8c45fSAndroid Build Coastguard Worker                      << endl;
112*38e8c45fSAndroid Build Coastguard Worker             }
113*38e8c45fSAndroid Build Coastguard Worker         } else if (strcmp(argv[optind], "call") == 0) {
114*38e8c45fSAndroid Build Coastguard Worker             optind++;
115*38e8c45fSAndroid Build Coastguard Worker             if (optind+1 < argc) {
116*38e8c45fSAndroid Build Coastguard Worker                 int serviceArg = optind;
117*38e8c45fSAndroid Build Coastguard Worker                 sp<IBinder> service = sm->checkService(String16(argv[optind++]));
118*38e8c45fSAndroid Build Coastguard Worker                 String16 ifName = (service ? service->getInterfaceDescriptor() : String16());
119*38e8c45fSAndroid Build Coastguard Worker                 int32_t code = atoi(argv[optind++]);
120*38e8c45fSAndroid Build Coastguard Worker                 if (service != nullptr && ifName.size() > 0) {
121*38e8c45fSAndroid Build Coastguard Worker                     Parcel data, reply;
122*38e8c45fSAndroid Build Coastguard Worker                     data.markForBinder(service);
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker                     // the interface name is first
125*38e8c45fSAndroid Build Coastguard Worker                     data.writeInterfaceToken(ifName);
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker                     // then the rest of the call arguments
128*38e8c45fSAndroid Build Coastguard Worker                     while (optind < argc) {
129*38e8c45fSAndroid Build Coastguard Worker                         if (strcmp(argv[optind], "i32") == 0) {
130*38e8c45fSAndroid Build Coastguard Worker                             optind++;
131*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
132*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no integer supplied for 'i32'" << endl;
133*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
134*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
135*38e8c45fSAndroid Build Coastguard Worker                                 break;
136*38e8c45fSAndroid Build Coastguard Worker                             }
137*38e8c45fSAndroid Build Coastguard Worker                             data.writeInt32(atoi(argv[optind++]));
138*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "i64") == 0) {
139*38e8c45fSAndroid Build Coastguard Worker                             optind++;
140*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
141*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no integer supplied for 'i64'" << endl;
142*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
143*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
144*38e8c45fSAndroid Build Coastguard Worker                                 break;
145*38e8c45fSAndroid Build Coastguard Worker                             }
146*38e8c45fSAndroid Build Coastguard Worker                             data.writeInt64(atoll(argv[optind++]));
147*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "s16") == 0) {
148*38e8c45fSAndroid Build Coastguard Worker                             optind++;
149*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
150*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no string supplied for 's16'" << endl;
151*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
152*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
153*38e8c45fSAndroid Build Coastguard Worker                                 break;
154*38e8c45fSAndroid Build Coastguard Worker                             }
155*38e8c45fSAndroid Build Coastguard Worker                             data.writeString16(String16(argv[optind++]));
156*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "f") == 0) {
157*38e8c45fSAndroid Build Coastguard Worker                             optind++;
158*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
159*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no number supplied for 'f'" << endl;
160*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
161*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
162*38e8c45fSAndroid Build Coastguard Worker                                 break;
163*38e8c45fSAndroid Build Coastguard Worker                             }
164*38e8c45fSAndroid Build Coastguard Worker                             data.writeFloat(atof(argv[optind++]));
165*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "d") == 0) {
166*38e8c45fSAndroid Build Coastguard Worker                             optind++;
167*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
168*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no number supplied for 'd'" << endl;
169*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
170*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
171*38e8c45fSAndroid Build Coastguard Worker                                 break;
172*38e8c45fSAndroid Build Coastguard Worker                             }
173*38e8c45fSAndroid Build Coastguard Worker                             data.writeDouble(atof(argv[optind++]));
174*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "null") == 0) {
175*38e8c45fSAndroid Build Coastguard Worker                             optind++;
176*38e8c45fSAndroid Build Coastguard Worker                             data.writeStrongBinder(nullptr);
177*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "fd") == 0) {
178*38e8c45fSAndroid Build Coastguard Worker                             optind++;
179*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
180*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no path supplied for 'fd'" << endl;
181*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
182*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
183*38e8c45fSAndroid Build Coastguard Worker                                 break;
184*38e8c45fSAndroid Build Coastguard Worker                             }
185*38e8c45fSAndroid Build Coastguard Worker                             const char *path = argv[optind++];
186*38e8c45fSAndroid Build Coastguard Worker                             int fd = open(path, O_RDONLY);
187*38e8c45fSAndroid Build Coastguard Worker                             if (fd < 0) {
188*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": could not open '" << path << "'" << endl;
189*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
190*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
191*38e8c45fSAndroid Build Coastguard Worker                                 break;
192*38e8c45fSAndroid Build Coastguard Worker                             }
193*38e8c45fSAndroid Build Coastguard Worker                             data.writeFileDescriptor(fd, true /* take ownership */);
194*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "afd") == 0) {
195*38e8c45fSAndroid Build Coastguard Worker                             optind++;
196*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
197*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no path supplied for 'afd'" << endl;
198*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
199*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
200*38e8c45fSAndroid Build Coastguard Worker                                 break;
201*38e8c45fSAndroid Build Coastguard Worker                             }
202*38e8c45fSAndroid Build Coastguard Worker                             const char *path = argv[optind++];
203*38e8c45fSAndroid Build Coastguard Worker                             int fd = open(path, O_RDONLY);
204*38e8c45fSAndroid Build Coastguard Worker                             struct stat statbuf;
205*38e8c45fSAndroid Build Coastguard Worker                             if (fd < 0 || fstat(fd, &statbuf) != 0) {
206*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": could not open or stat"
207*38e8c45fSAndroid Build Coastguard Worker                                     << " '" << path << "'" << endl;
208*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
209*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
210*38e8c45fSAndroid Build Coastguard Worker                                 break;
211*38e8c45fSAndroid Build Coastguard Worker                             }
212*38e8c45fSAndroid Build Coastguard Worker                             int afd = ashmem_create_region("test", statbuf.st_size);
213*38e8c45fSAndroid Build Coastguard Worker                             void* ptr = mmap(NULL, statbuf.st_size,
214*38e8c45fSAndroid Build Coastguard Worker                                    PROT_READ | PROT_WRITE, MAP_SHARED, afd, 0);
215*38e8c45fSAndroid Build Coastguard Worker                             (void)read(fd, ptr, statbuf.st_size);
216*38e8c45fSAndroid Build Coastguard Worker                             close(fd);
217*38e8c45fSAndroid Build Coastguard Worker                             data.writeFileDescriptor(afd, true /* take ownership */);
218*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "nfd") == 0) {
219*38e8c45fSAndroid Build Coastguard Worker                             optind++;
220*38e8c45fSAndroid Build Coastguard Worker                             if (optind >= argc) {
221*38e8c45fSAndroid Build Coastguard Worker                                 aerr << prog_name << ": no file descriptor supplied for"
222*38e8c45fSAndroid Build Coastguard Worker                                     << " 'nfd'" << endl;
223*38e8c45fSAndroid Build Coastguard Worker                                 wantsUsage = true;
224*38e8c45fSAndroid Build Coastguard Worker                                 result = 10;
225*38e8c45fSAndroid Build Coastguard Worker                                 break;
226*38e8c45fSAndroid Build Coastguard Worker                             }
227*38e8c45fSAndroid Build Coastguard Worker                             data.writeFileDescriptor(
228*38e8c45fSAndroid Build Coastguard Worker                                     atoi(argv[optind++]), true /* take ownership */);
229*38e8c45fSAndroid Build Coastguard Worker 
230*38e8c45fSAndroid Build Coastguard Worker                         } else if (strcmp(argv[optind], "intent") == 0) {
231*38e8c45fSAndroid Build Coastguard Worker 
232*38e8c45fSAndroid Build Coastguard Worker                             char* action = nullptr;
233*38e8c45fSAndroid Build Coastguard Worker                             char* dataArg = nullptr;
234*38e8c45fSAndroid Build Coastguard Worker                             char* type = nullptr;
235*38e8c45fSAndroid Build Coastguard Worker                             int launchFlags = 0;
236*38e8c45fSAndroid Build Coastguard Worker                             char* component = nullptr;
237*38e8c45fSAndroid Build Coastguard Worker                             int categoryCount = 0;
238*38e8c45fSAndroid Build Coastguard Worker                             char* categories[16];
239*38e8c45fSAndroid Build Coastguard Worker 
240*38e8c45fSAndroid Build Coastguard Worker                             char* context1 = nullptr;
241*38e8c45fSAndroid Build Coastguard Worker 
242*38e8c45fSAndroid Build Coastguard Worker                             optind++;
243*38e8c45fSAndroid Build Coastguard Worker 
244*38e8c45fSAndroid Build Coastguard Worker                             while (optind < argc)
245*38e8c45fSAndroid Build Coastguard Worker                             {
246*38e8c45fSAndroid Build Coastguard Worker                                 char* key = strtok_r(argv[optind], "=", &context1);
247*38e8c45fSAndroid Build Coastguard Worker                                 char* value = strtok_r(nullptr, "=", &context1);
248*38e8c45fSAndroid Build Coastguard Worker 
249*38e8c45fSAndroid Build Coastguard Worker                                 // we have reached the end of the XXX=XXX args.
250*38e8c45fSAndroid Build Coastguard Worker                                 if (key == nullptr) break;
251*38e8c45fSAndroid Build Coastguard Worker 
252*38e8c45fSAndroid Build Coastguard Worker                                 if (strcmp(key, "action") == 0)
253*38e8c45fSAndroid Build Coastguard Worker                                 {
254*38e8c45fSAndroid Build Coastguard Worker                                     action = value;
255*38e8c45fSAndroid Build Coastguard Worker                                 }
256*38e8c45fSAndroid Build Coastguard Worker                                 else if (strcmp(key, "data") == 0)
257*38e8c45fSAndroid Build Coastguard Worker                                 {
258*38e8c45fSAndroid Build Coastguard Worker                                     dataArg = value;
259*38e8c45fSAndroid Build Coastguard Worker                                 }
260*38e8c45fSAndroid Build Coastguard Worker                                 else if (strcmp(key, "type") == 0)
261*38e8c45fSAndroid Build Coastguard Worker                                 {
262*38e8c45fSAndroid Build Coastguard Worker                                     type = value;
263*38e8c45fSAndroid Build Coastguard Worker                                 }
264*38e8c45fSAndroid Build Coastguard Worker                                 else if (strcmp(key, "launchFlags") == 0)
265*38e8c45fSAndroid Build Coastguard Worker                                 {
266*38e8c45fSAndroid Build Coastguard Worker                                     launchFlags = atoi(value);
267*38e8c45fSAndroid Build Coastguard Worker                                 }
268*38e8c45fSAndroid Build Coastguard Worker                                 else if (strcmp(key, "component") == 0)
269*38e8c45fSAndroid Build Coastguard Worker                                 {
270*38e8c45fSAndroid Build Coastguard Worker                                     component = value;
271*38e8c45fSAndroid Build Coastguard Worker                                 }
272*38e8c45fSAndroid Build Coastguard Worker                                 else if (strcmp(key, "categories") == 0)
273*38e8c45fSAndroid Build Coastguard Worker                                 {
274*38e8c45fSAndroid Build Coastguard Worker                                     char* context2 = nullptr;
275*38e8c45fSAndroid Build Coastguard Worker                                     categories[categoryCount] = strtok_r(value, ",", &context2);
276*38e8c45fSAndroid Build Coastguard Worker 
277*38e8c45fSAndroid Build Coastguard Worker                                     while (categories[categoryCount] != nullptr)
278*38e8c45fSAndroid Build Coastguard Worker                                     {
279*38e8c45fSAndroid Build Coastguard Worker                                         categoryCount++;
280*38e8c45fSAndroid Build Coastguard Worker                                         categories[categoryCount] = strtok_r(nullptr, ",", &context2);
281*38e8c45fSAndroid Build Coastguard Worker                                     }
282*38e8c45fSAndroid Build Coastguard Worker                                 }
283*38e8c45fSAndroid Build Coastguard Worker 
284*38e8c45fSAndroid Build Coastguard Worker                                 optind++;
285*38e8c45fSAndroid Build Coastguard Worker                             }
286*38e8c45fSAndroid Build Coastguard Worker 
287*38e8c45fSAndroid Build Coastguard Worker                             writeString16(data, action);
288*38e8c45fSAndroid Build Coastguard Worker                             writeString16(data, dataArg);
289*38e8c45fSAndroid Build Coastguard Worker                             writeString16(data, type);
290*38e8c45fSAndroid Build Coastguard Worker                             data.writeInt32(launchFlags);
291*38e8c45fSAndroid Build Coastguard Worker                             writeString16(data, component);
292*38e8c45fSAndroid Build Coastguard Worker 
293*38e8c45fSAndroid Build Coastguard Worker                             if (categoryCount > 0)
294*38e8c45fSAndroid Build Coastguard Worker                             {
295*38e8c45fSAndroid Build Coastguard Worker                                 data.writeInt32(categoryCount);
296*38e8c45fSAndroid Build Coastguard Worker                                 for (int i = 0 ; i < categoryCount ; i++)
297*38e8c45fSAndroid Build Coastguard Worker                                 {
298*38e8c45fSAndroid Build Coastguard Worker                                     writeString16(data, categories[i]);
299*38e8c45fSAndroid Build Coastguard Worker                                 }
300*38e8c45fSAndroid Build Coastguard Worker                             }
301*38e8c45fSAndroid Build Coastguard Worker                             else
302*38e8c45fSAndroid Build Coastguard Worker                             {
303*38e8c45fSAndroid Build Coastguard Worker                                 data.writeInt32(0);
304*38e8c45fSAndroid Build Coastguard Worker                             }
305*38e8c45fSAndroid Build Coastguard Worker 
306*38e8c45fSAndroid Build Coastguard Worker                             // for now just set the extra field to be null.
307*38e8c45fSAndroid Build Coastguard Worker                             data.writeInt32(-1);
308*38e8c45fSAndroid Build Coastguard Worker                         } else {
309*38e8c45fSAndroid Build Coastguard Worker                             aerr << prog_name << ": unknown option " << argv[optind] << endl;
310*38e8c45fSAndroid Build Coastguard Worker                             wantsUsage = true;
311*38e8c45fSAndroid Build Coastguard Worker                             result = 10;
312*38e8c45fSAndroid Build Coastguard Worker                             break;
313*38e8c45fSAndroid Build Coastguard Worker                         }
314*38e8c45fSAndroid Build Coastguard Worker                     }
315*38e8c45fSAndroid Build Coastguard Worker 
316*38e8c45fSAndroid Build Coastguard Worker                     service->transact(code, data, &reply);
317*38e8c45fSAndroid Build Coastguard Worker                     aout << "Result: " << reply << endl;
318*38e8c45fSAndroid Build Coastguard Worker                 } else {
319*38e8c45fSAndroid Build Coastguard Worker                     aerr << prog_name << ": Service " << argv[serviceArg]
320*38e8c45fSAndroid Build Coastguard Worker                         << " does not exist" << endl;
321*38e8c45fSAndroid Build Coastguard Worker                     result = 10;
322*38e8c45fSAndroid Build Coastguard Worker                 }
323*38e8c45fSAndroid Build Coastguard Worker             } else {
324*38e8c45fSAndroid Build Coastguard Worker                 if (optind < argc) {
325*38e8c45fSAndroid Build Coastguard Worker                     aerr << prog_name << ": No service specified for call" << endl;
326*38e8c45fSAndroid Build Coastguard Worker                 } else {
327*38e8c45fSAndroid Build Coastguard Worker                     aerr << prog_name << ": No code specified for call" << endl;
328*38e8c45fSAndroid Build Coastguard Worker                 }
329*38e8c45fSAndroid Build Coastguard Worker                 wantsUsage = true;
330*38e8c45fSAndroid Build Coastguard Worker                 result = 10;
331*38e8c45fSAndroid Build Coastguard Worker             }
332*38e8c45fSAndroid Build Coastguard Worker         } else {
333*38e8c45fSAndroid Build Coastguard Worker             aerr << prog_name << ": Unknown command " << argv[optind] << endl;
334*38e8c45fSAndroid Build Coastguard Worker             wantsUsage = true;
335*38e8c45fSAndroid Build Coastguard Worker             result = 10;
336*38e8c45fSAndroid Build Coastguard Worker         }
337*38e8c45fSAndroid Build Coastguard Worker     }
338*38e8c45fSAndroid Build Coastguard Worker 
339*38e8c45fSAndroid Build Coastguard Worker     if (wantsUsage) {
340*38e8c45fSAndroid Build Coastguard Worker         aout << "Usage: " << prog_name << " [-h|-?]\n"
341*38e8c45fSAndroid Build Coastguard Worker                 "       " << prog_name << " list\n"
342*38e8c45fSAndroid Build Coastguard Worker                 "       " << prog_name << " check SERVICE\n"
343*38e8c45fSAndroid Build Coastguard Worker                 "       " << prog_name << " call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR"
344*38e8c45fSAndroid Build Coastguard Worker                 " | null | fd f | nfd n | afd f ] ...\n"
345*38e8c45fSAndroid Build Coastguard Worker                 "Options:\n"
346*38e8c45fSAndroid Build Coastguard Worker                 "   i32: Write the 32-bit integer N into the send parcel.\n"
347*38e8c45fSAndroid Build Coastguard Worker                 "   i64: Write the 64-bit integer N into the send parcel.\n"
348*38e8c45fSAndroid Build Coastguard Worker                 "     f: Write the 32-bit single-precision number N into the send parcel.\n"
349*38e8c45fSAndroid Build Coastguard Worker                 "     d: Write the 64-bit double-precision number N into the send parcel.\n"
350*38e8c45fSAndroid Build Coastguard Worker                 "   s16: Write the UTF-16 string STR into the send parcel.\n"
351*38e8c45fSAndroid Build Coastguard Worker                 "  null: Write a null binder into the send parcel.\n"
352*38e8c45fSAndroid Build Coastguard Worker                 "    fd: Write a file descriptor for the file f into the send parcel.\n"
353*38e8c45fSAndroid Build Coastguard Worker                 "   nfd: Write the file descriptor n into the send parcel.\n"
354*38e8c45fSAndroid Build Coastguard Worker                 "   afd: Write an ashmem file descriptor for a region containing the data from\n"
355*38e8c45fSAndroid Build Coastguard Worker                 "          file f into the send parcel.\n";
356*38e8c45fSAndroid Build Coastguard Worker //                "   intent: Write an Intent into the send parcel. ARGS can be\n"
357*38e8c45fSAndroid Build Coastguard Worker //                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
358*38e8c45fSAndroid Build Coastguard Worker         return result;
359*38e8c45fSAndroid Build Coastguard Worker     }
360*38e8c45fSAndroid Build Coastguard Worker 
361*38e8c45fSAndroid Build Coastguard Worker     return result;
362*38e8c45fSAndroid Build Coastguard Worker }
363*38e8c45fSAndroid Build Coastguard Worker 
364