194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/*
2002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * Copyright 2013 The Android Open Source Project
394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *
4002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * you may not use this file except in compliance with the License.
6002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * You may obtain a copy of the License at
7002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian *
8002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian *
10002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * Unless required by applicable law or agreed to in writing, software
11002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * See the License for the specific language governing permissions and
14002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian * limitations under the License.
1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */
16002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian
1794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <binder/Parcel.h>
1894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <binder/ProcessState.h>
1994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <binder/IServiceManager.h>
20002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/TextOutput.h>
2194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
2294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <getopt.h>
2394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdlib.h>
2494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <stdio.h>
2594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <string.h>
2694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <unistd.h>
2794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#include <sys/time.h>
2894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
2994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodusing namespace android;
3094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
3194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodvoid writeString16(Parcel& parcel, const char* string)
3294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
3394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (string != NULL)
3494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    {
3594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        parcel.writeString16(String16(string));
3694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
3794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    else
3894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    {
3994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        parcel.writeInt32(-1);
4094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
4194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
4294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood// get the name of the generic interface we hold a reference to
4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic String16 get_interface_name(sp<IBinder> service)
4594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (service != NULL) {
4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        Parcel data, reply;
4894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
4994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (err == NO_ERROR) {
5094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            return reply.readString16();
5194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
5294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
5394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return String16();
5494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
5594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
5694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic String8 good_old_string(const String16& src)
5794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
5894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    String8 name8;
5994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    char ch8[2];
6094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    ch8[1] = 0;
6194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    for (unsigned j = 0; j < src.size(); j++) {
6294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        char16_t ch = src[j];
6394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (ch < 128) ch8[0] = (char)ch;
6494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        name8.append(ch8);
6594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
6694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return name8;
6794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
6894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
6994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodint main(int argc, char* const argv[])
7094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{
7194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool wantsUsage = false;
7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    int result = 0;
7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    while (1) {
753def1f2d8212d44527f5de0c22874326239a0a13Martijn Coenen        int ic = getopt(argc, argv, "h?");
7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (ic < 0)
7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        switch (ic) {
8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        case 'h':
8194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        case '?':
8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        default:
8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aerr << "service: Unknown option -" << ic << endl;
8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            result = 10;
8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
913def1f2d8212d44527f5de0c22874326239a0a13Martijn Coenen#ifdef VENDORSERVICES
923def1f2d8212d44527f5de0c22874326239a0a13Martijn Coenen    ProcessState::initWithDriver("/dev/vndbinder");
933def1f2d8212d44527f5de0c22874326239a0a13Martijn Coenen#endif
94d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen    sp<IServiceManager> sm = defaultServiceManager();
95d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen    fflush(stdout);
96d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen    if (sm == NULL) {
97d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen        aerr << "service: Unable to get default service manager!" << endl;
98d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen        return 20;
99d6480caf4d58ff5060fa2fb20a3384bd2bcd38dcMartijn Coenen    }
10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (optind >= argc) {
10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        wantsUsage = true;
10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else if (!wantsUsage) {
10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (strcmp(argv[optind], "check") == 0) {
10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            optind++;
10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            if (optind < argc) {
10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(String16(argv[optind]));
10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aout << "Service " << argv[optind] <<
10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    (service == NULL ? ": not found" : ": found") << endl;
11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            } else {
11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aerr << "service: No service specified for check" << endl;
11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                wantsUsage = true;
11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                result = 10;
11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        else if (strcmp(argv[optind], "list") == 0) {
11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            Vector<String16> services = sm->listServices();
11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aout << "Found " << services.size() << " services:" << endl;
11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            for (unsigned i = 0; i < services.size(); i++) {
12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                String16 name = services[i];
12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(name);
12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aout << i
12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << "\t" << good_old_string(name)
12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << ": [" << good_old_string(get_interface_name(service)) << "]"
12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << endl;
12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        } else if (strcmp(argv[optind], "call") == 0) {
12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            optind++;
12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            if (optind+1 < argc) {
13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                int serviceArg = optind;
13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(String16(argv[optind++]));
13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                String16 ifName = get_interface_name(service);
13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                int32_t code = atoi(argv[optind++]);
13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                if (service != NULL && ifName.size() > 0) {
13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    Parcel data, reply;
13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    // the interface name is first
13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    data.writeInterfaceToken(ifName);
13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    // then the rest of the call arguments
14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    while (optind < argc) {
14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        if (strcmp(argv[optind], "i32") == 0) {
14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (optind >= argc) {
14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                aerr << "service: no integer supplied for 'i32'" << endl;
14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                wantsUsage = true;
14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                result = 10;
14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                break;
14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeInt32(atoi(argv[optind++]));
151d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                        } else if (strcmp(argv[optind], "i64") == 0) {
152d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            optind++;
153d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            if (optind >= argc) {
154d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                aerr << "service: no integer supplied for 'i64'" << endl;
155d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                wantsUsage = true;
156d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                result = 10;
157d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                break;
158d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            }
159d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            data.writeInt64(atoll(argv[optind++]));
16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "s16") == 0) {
16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (optind >= argc) {
16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                aerr << "service: no string supplied for 's16'" << endl;
16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                wantsUsage = true;
16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                result = 10;
16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                break;
16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeString16(String16(argv[optind++]));
169d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                        } else if (strcmp(argv[optind], "f") == 0) {
170d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            optind++;
171d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            if (optind >= argc) {
172d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                aerr << "service: no number supplied for 'f'" << endl;
173d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                wantsUsage = true;
174d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                result = 10;
175d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                break;
176d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            }
177d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            data.writeFloat(atof(argv[optind++]));
178d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                        } else if (strcmp(argv[optind], "d") == 0) {
179d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            optind++;
180d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            if (optind >= argc) {
181d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                aerr << "service: no number supplied for 'd'" << endl;
182d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                wantsUsage = true;
183d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                result = 10;
184d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                                break;
185d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            }
186d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                            data.writeDouble(atof(argv[optind++]));
18794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "null") == 0) {
18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeStrongBinder(NULL);
19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "intent") == 0) {
19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* action = NULL;
19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* dataArg = NULL;
19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* type = NULL;
19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	int launchFlags = 0;
19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* component = NULL;
19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	int categoryCount = 0;
19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* categories[16];
19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* context1 = NULL;
20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	while (optind < argc)
20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	{
20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		char* key = strtok_r(argv[optind], "=", &context1);
20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		char* value = strtok_r(NULL, "=", &context1);
20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                // we have reached the end of the XXX=XXX args.
21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                if (key == NULL) break;
21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		if (strcmp(key, "action") == 0)
21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			action = value;
21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "data") == 0)
21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			dataArg = value;
21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "type") == 0)
22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			type = value;
22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "launchFlags") == 0)
22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			launchFlags = atoi(value);
22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "component") == 0)
22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			component = value;
23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "categories") == 0)
23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			char* context2 = NULL;
23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			int categoryCount = 0;
23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			categories[categoryCount] = strtok_r(value, ",", &context2);
23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			while (categories[categoryCount] != NULL)
23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			{
24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        				categoryCount++;
24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			}
24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                optind++;
24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	}
24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, action);
24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, dataArg);
25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, type);
25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                       		data.writeInt32(launchFlags);
25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, component);
25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (categoryCount > 0)
25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            {
25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                data.writeInt32(categoryCount);
25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                for (int i = 0 ; i < categoryCount ; i++)
25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                {
25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    writeString16(data, categories[i]);
26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                }
26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            else
26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            {
26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                data.writeInt32(0);
26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            // for now just set the extra field to be null.
26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                       		data.writeInt32(-1);
26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else {
27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            aerr << "service: unknown option " << argv[optind] << endl;
27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            wantsUsage = true;
27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            result = 10;
27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            break;
27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        }
27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    }
27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    service->transact(code, data, &reply);
27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aout << "Result: " << reply << endl;
27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                } else {
28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: Service " << argv[serviceArg]
28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        << " does not exist" << endl;
28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    result = 10;
28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                }
28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            } else {
28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                if (optind < argc) {
28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: No service specified for call" << endl;
28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                } else {
28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: No code specified for call" << endl;
28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                }
29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                wantsUsage = true;
29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                result = 10;
29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
29394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        } else {
29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aerr << "service: Unknown command " << argv[optind] << endl;
29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
29694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            result = 10;
29794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
29894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (wantsUsage) {
30194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        aout << "Usage: service [-h|-?]\n"
30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "       service list\n"
30394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "       service check SERVICE\n"
304d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                "       service call SERVICE CODE [i32 N | i64 N | f N | d N | s16 STR ] ...\n"
30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "Options:\n"
306d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                "   i32: Write the 32-bit integer N into the send parcel.\n"
307d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                "   i64: Write the 64-bit integer N into the send parcel.\n"
308d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                "   f:   Write the 32-bit single-precision number N into the send parcel.\n"
309d46898fed050b6e2b93ecd3a3da4143b5108024aJeff Brown                "   d:   Write the 64-bit double-precision number N into the send parcel.\n"
31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "   s16: Write the UTF-16 string STR into the send parcel.\n";
31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//                "   intent: Write and Intent int the send parcel. ARGS can be\n"
31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return result;
31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
31694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return result;
31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
319