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    sp<IServiceManager> sm = defaultServiceManager();
7294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    fflush(stdout);
7394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (sm == NULL) {
7494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        aerr << "service: Unable to get default service manager!" << endl;
7594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return 20;
7694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
7794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
7894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    bool wantsUsage = false;
7994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    int result = 0;
8094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    while (1) {
8294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        int ic = getopt(argc, argv, "h?");
8394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (ic < 0)
8494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
8594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
8694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        switch (ic) {
8794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        case 'h':
8894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        case '?':
8994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
9094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
9194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        default:
9294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aerr << "service: Unknown option -" << ic << endl;
9394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
9494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            result = 10;
9594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            break;
9694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
9794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
9894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
9994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (optind >= argc) {
10094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        wantsUsage = true;
10194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    } else if (!wantsUsage) {
10294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        if (strcmp(argv[optind], "check") == 0) {
10394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            optind++;
10494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            if (optind < argc) {
10594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(String16(argv[optind]));
10694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aout << "Service " << argv[optind] <<
10794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    (service == NULL ? ": not found" : ": found") << endl;
10894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            } else {
10994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aerr << "service: No service specified for check" << endl;
11094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                wantsUsage = true;
11194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                result = 10;
11294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
11394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
11494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        else if (strcmp(argv[optind], "list") == 0) {
11594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            Vector<String16> services = sm->listServices();
11694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aout << "Found " << services.size() << " services:" << endl;
11794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            for (unsigned i = 0; i < services.size(); i++) {
11894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                String16 name = services[i];
11994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(name);
12094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                aout << i
12194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << "\t" << good_old_string(name)
12294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << ": [" << good_old_string(get_interface_name(service)) << "]"
12394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                     << endl;
12494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
12594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        } else if (strcmp(argv[optind], "call") == 0) {
12694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            optind++;
12794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            if (optind+1 < argc) {
12894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                int serviceArg = optind;
12994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                sp<IBinder> service = sm->checkService(String16(argv[optind++]));
13094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                String16 ifName = get_interface_name(service);
13194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                int32_t code = atoi(argv[optind++]);
13294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                if (service != NULL && ifName.size() > 0) {
13394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    Parcel data, reply;
13494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
13594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    // the interface name is first
13694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    data.writeInterfaceToken(ifName);
13794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
13894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    // then the rest of the call arguments
13994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    while (optind < argc) {
14094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        if (strcmp(argv[optind], "i32") == 0) {
14194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
14294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (optind >= argc) {
14394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                aerr << "service: no integer supplied for 'i32'" << endl;
14494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                wantsUsage = true;
14594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                result = 10;
14694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                break;
14794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
14894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeInt32(atoi(argv[optind++]));
14994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "s16") == 0) {
15094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
15194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (optind >= argc) {
15294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                aerr << "service: no string supplied for 's16'" << endl;
15394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                wantsUsage = true;
15494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                result = 10;
15594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                break;
15694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
15794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeString16(String16(argv[optind++]));
15894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "null") == 0) {
15994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
16094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            data.writeStrongBinder(NULL);
16194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else if (strcmp(argv[optind], "intent") == 0) {
16294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
16394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* action = NULL;
16494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* dataArg = NULL;
16594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* type = NULL;
16694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	int launchFlags = 0;
16794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* component = NULL;
16894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	int categoryCount = 0;
16994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* categories[16];
17094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
17194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	char* context1 = NULL;
17294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
17394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            optind++;
17494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
17594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	while (optind < argc)
17694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	{
17794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		char* key = strtok_r(argv[optind], "=", &context1);
17894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		char* value = strtok_r(NULL, "=", &context1);
17994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
18094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                // we have reached the end of the XXX=XXX args.
18194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                if (key == NULL) break;
18294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
18394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		if (strcmp(key, "action") == 0)
18494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
18594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			action = value;
18694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
18794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "data") == 0)
18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			dataArg = value;
19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "type") == 0)
19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
19394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			type = value;
19494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
19594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "launchFlags") == 0)
19694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
19794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			launchFlags = atoi(value);
19894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
19994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "component") == 0)
20094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
20194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			component = value;
20294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
20394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		else if (strcmp(key, "categories") == 0)
20494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		{
20594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			char* context2 = NULL;
20694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			int categoryCount = 0;
20794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			categories[categoryCount] = strtok_r(value, ",", &context2);
20894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
20994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			while (categories[categoryCount] != NULL)
21094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			{
21194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        				categoryCount++;
21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        			}
21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        		}
21594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                optind++;
21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        	}
21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
21994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, action);
22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, dataArg);
22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, type);
22294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                       		data.writeInt32(launchFlags);
22394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            writeString16(data, component);
22494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
22594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            if (categoryCount > 0)
22694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            {
22794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                data.writeInt32(categoryCount);
22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                for (int i = 0 ; i < categoryCount ; i++)
22994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                {
23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                    writeString16(data, categories[i]);
23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                }
23294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            else
23494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            {
23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                                data.writeInt32(0);
23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            }
23794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            // for now just set the extra field to be null.
23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                       		data.writeInt32(-1);
24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        } else {
24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            aerr << "service: unknown option " << argv[optind] << endl;
24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            wantsUsage = true;
24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            result = 10;
24494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                            break;
24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        }
24694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    }
24794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
24894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    service->transact(code, data, &reply);
24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aout << "Result: " << reply << endl;
25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                } else {
25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: Service " << argv[serviceArg]
25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                        << " does not exist" << endl;
25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    result = 10;
25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                }
25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            } else {
25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                if (optind < argc) {
25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: No service specified for call" << endl;
25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                } else {
25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                    aerr << "service: No code specified for call" << endl;
26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                }
26194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                wantsUsage = true;
26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                result = 10;
26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            }
26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        } else {
26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            aerr << "service: Unknown command " << argv[optind] << endl;
26694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            wantsUsage = true;
26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood            result = 10;
26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        }
26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    if (wantsUsage) {
27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        aout << "Usage: service [-h|-?]\n"
27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "       service list\n"
27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "       service check SERVICE\n"
27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "       service call SERVICE CODE [i32 INT | s16 STR] ...\n"
27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "Options:\n"
27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "   i32: Write the integer INT into the send parcel.\n"
27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood                "   s16: Write the UTF-16 string STR into the send parcel.\n";
27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//                "   intent: Write and Intent int the send parcel. ARGS can be\n"
28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood//                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood        return result;
28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    }
28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood    return result;
28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}
28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood
287