19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Command line access to services.
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
60795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/Parcel.h>
70795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/ProcessState.h>
80795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IServiceManager.h>
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/TextOutput.h>
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <getopt.h>
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h>
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h>
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h>
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h>
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h>
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android;
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid writeString16(Parcel& parcel, const char* string)
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (string != NULL)
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeString16(String16(string));
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    else
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        parcel.writeInt32(-1);
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// get the name of the generic interface we hold a reference to
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String16 get_interface_name(sp<IBinder> service)
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (service != NULL) {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel data, reply;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        status_t err = service->transact(IBinder::INTERFACE_TRANSACTION, data, &reply);
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (err == NO_ERROR) {
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return reply.readString16();
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return String16();
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic String8 good_old_string(const String16& src)
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 name8;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char ch8[2];
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ch8[1] = 0;
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (unsigned j = 0; j < src.size(); j++) {
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        char16_t ch = src[j];
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ch < 128) ch8[0] = (char)ch;
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        name8.append(ch8);
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return name8;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint main(int argc, char* const argv[])
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    sp<IServiceManager> sm = defaultServiceManager();
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    fflush(stdout);
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (sm == NULL) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        aerr << "service: Unable to get default service manager!" << endl;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return 20;
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool wantsUsage = false;
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int result = 0;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (1) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        int ic = getopt(argc, argv, "h?");
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (ic < 0)
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        switch (ic) {
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case 'h':
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        case '?':
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            wantsUsage = true;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        default:
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            aerr << "service: Unknown option -" << ic << endl;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            wantsUsage = true;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = 10;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            break;
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (optind >= argc) {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        wantsUsage = true;
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else if (!wantsUsage) {
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (strcmp(argv[optind], "check") == 0) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            optind++;
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (optind < argc) {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<IBinder> service = sm->checkService(String16(argv[optind]));
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                aout << "Service " << argv[optind] <<
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    (service == NULL ? ": not found" : ": found") << endl;
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                aerr << "service: No service specified for check" << endl;
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                wantsUsage = true;
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                result = 10;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        else if (strcmp(argv[optind], "list") == 0) {
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Vector<String16> services = sm->listServices();
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            aout << "Found " << services.size() << " services:" << endl;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (unsigned i = 0; i < services.size(); i++) {
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 name = services[i];
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<IBinder> service = sm->checkService(name);
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                aout << i
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     << "\t" << good_old_string(name)
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     << ": [" << good_old_string(get_interface_name(service)) << "]"
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                     << endl;
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else if (strcmp(argv[optind], "call") == 0) {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            optind++;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (optind+1 < argc) {
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int serviceArg = optind;
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sp<IBinder> service = sm->checkService(String16(argv[optind++]));
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String16 ifName = get_interface_name(service);
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                int32_t code = atoi(argv[optind++]);
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (service != NULL && ifName.size() > 0) {
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    Parcel data, reply;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // the interface name is first
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    data.writeInterfaceToken(ifName);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    // then the rest of the call arguments
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    while (optind < argc) {
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        if (strcmp(argv[optind], "i32") == 0) {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            optind++;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (optind >= argc) {
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                aerr << "service: no integer supplied for 'i32'" << endl;
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                wantsUsage = true;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                result = 10;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                break;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            data.writeInt32(atoi(argv[optind++]));
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp(argv[optind], "s16") == 0) {
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            optind++;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (optind >= argc) {
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                aerr << "service: no string supplied for 's16'" << endl;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                wantsUsage = true;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                result = 10;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                break;
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            data.writeString16(String16(argv[optind++]));
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp(argv[optind], "null") == 0) {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            optind++;
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            data.writeStrongBinder(NULL);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else if (strcmp(argv[optind], "intent") == 0) {
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* action = NULL;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* dataArg = NULL;
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* type = NULL;
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	int launchFlags = 0;
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* component = NULL;
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	int categoryCount = 0;
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* categories[16];
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	char* context1 = NULL;
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            optind++;
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	while (optind < argc)
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	{
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		char* key = strtok_r(argv[optind], "=", &context1);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		char* value = strtok_r(NULL, "=", &context1);
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                // we have reached the end of the XXX=XXX args.
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                if (key == NULL) break;
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		if (strcmp(key, "action") == 0)
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			action = value;
1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		else if (strcmp(key, "data") == 0)
1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			dataArg = value;
1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		else if (strcmp(key, "type") == 0)
1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			type = value;
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		else if (strcmp(key, "launchFlags") == 0)
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			launchFlags = atoi(value);
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		else if (strcmp(key, "component") == 0)
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			component = value;
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		else if (strcmp(key, "categories") == 0)
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		{
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			char* context2 = NULL;
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			int categoryCount = 0;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			categories[categoryCount] = strtok_r(value, ",", &context2);
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			while (categories[categoryCount] != NULL)
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			{
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        				categoryCount++;
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        			}
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        		}
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                optind++;
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        	}
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            writeString16(data, action);
2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            writeString16(data, dataArg);
2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            writeString16(data, type);
2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       		data.writeInt32(launchFlags);
2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            writeString16(data, component);
2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            if (categoryCount > 0)
2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            {
2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                data.writeInt32(categoryCount);
2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                for (int i = 0 ; i < categoryCount ; i++)
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                {
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                    writeString16(data, categories[i]);
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                }
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            else
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            {
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                data.writeInt32(0);
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            }
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            // for now just set the extra field to be null.
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                       		data.writeInt32(-1);
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        } else {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            aerr << "service: unknown option " << argv[optind] << endl;
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            wantsUsage = true;
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            result = 10;
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            break;
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    service->transact(code, data, &reply);
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    aout << "Result: " << reply << endl;
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    aerr << "service: Service " << argv[serviceArg]
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        << " does not exist" << endl;
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    result = 10;
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            } else {
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                if (optind < argc) {
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    aerr << "service: No service specified for call" << endl;
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                } else {
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    aerr << "service: No code specified for call" << endl;
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                wantsUsage = true;
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                result = 10;
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            aerr << "service: Unknown command " << argv[optind] << endl;
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            wantsUsage = true;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            result = 10;
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (wantsUsage) {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        aout << "Usage: service [-h|-?]\n"
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "       service list\n"
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "       service check SERVICE\n"
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "       service call SERVICE CODE [i32 INT | s16 STR] ...\n"
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "Options:\n"
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "   i32: Write the integer INT into the send parcel.\n"
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                "   s16: Write the UTF-16 string STR into the send parcel.\n";
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                "   intent: Write and Intent int the send parcel. ARGS can be\n"
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//                "       action=STR data=STR type=STR launchFlags=INT component=STR categories=STR[,STR,...]\n";
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return result;
2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return result;
2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
276