IServiceManager.cpp revision 208059f67ed2dd9fa025e07fcb6954d3cb61c79e
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* 2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License. 6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at 7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and 14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License. 15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */ 16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define LOG_TAG "ServiceManager" 18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IServiceManager.h> 20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Debug.h> 22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/IPCThreadState.h> 23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Log.h> 24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Parcel.h> 25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/String8.h> 26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/SystemClock.h> 27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 28208059f67ed2dd9fa025e07fcb6954d3cb61c79eMathias Agopian#include <private/binder/Static.h> 29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <unistd.h> 31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android { 33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectsp<IServiceManager> defaultServiceManager() 35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (gDefaultServiceManager != NULL) return gDefaultServiceManager; 37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project AutoMutex _l(gDefaultServiceManagerLock); 40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (gDefaultServiceManager == NULL) { 41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManager = interface_cast<IServiceManager>( 42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project ProcessState::self()->getContextObject(NULL)); 43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return gDefaultServiceManager; 47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool checkCallingPermission(const String16& permission) 50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return checkCallingPermission(permission, NULL, NULL); 52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic String16 _permission("permission"); 55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool checkCallingPermission(const String16& permission, int32_t* outPid, int32_t* outUid) 57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project IPCThreadState* ipcState = IPCThreadState::self(); 59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t pid = ipcState->getCallingPid(); 60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int32_t uid = ipcState->getCallingUid(); 61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (outPid) *outPid = pid; 62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (outUid) *outUid= uid; 63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IPermissionController> pc; 65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.lock(); 66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project pc = gPermissionController; 67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.unlock(); 68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int64_t startTime = 0; 70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project while (true) { 72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (pc != NULL) { 73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project bool res = pc->checkPermission(permission, pid, uid); 74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (res) { 75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (startTime != 0) { 76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("Check passed after %d seconds for %s from uid=%d pid=%d", 77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project (int)((uptimeMillis()-startTime)/1000), 78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8(permission).string(), uid, pid); 79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Is this a permission failure, or did the controller go away? 84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (pc->asBinder()->isBinderAlive()) { 85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("Permission failure: %s from uid=%d pid=%d", 86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8(permission).string(), uid, pid); 87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return false; 88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Object is dead! 91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.lock(); 92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (gPermissionController == pc) { 93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gPermissionController = NULL; 94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.unlock(); 96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Need to retrieve the permission controller. 99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> binder = defaultServiceManager()->checkService(_permission); 100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (binder == NULL) { 101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Wait for the permission controller to come back... 102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (startTime == 0) { 103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project startTime = uptimeMillis(); 104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("Waiting to check permission %s from uid=%d pid=%d", 105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String8(permission).string(), uid, pid); 106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sleep(1); 108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } else { 109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project pc = interface_cast<IPermissionController>(binder); 110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project // Install the new permission controller, and try again. 111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.lock(); 112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gPermissionController = pc; 113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project gDefaultServiceManagerLock.unlock(); 114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------- 119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectclass BpServiceManager : public BpInterface<IServiceManager> 121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic: 123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project BpServiceManager(const sp<IBinder>& impl) 124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project : BpInterface<IServiceManager>(impl) 125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual sp<IBinder> getService(const String16& name) const 129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project unsigned n; 131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (n = 0; n < 5; n++){ 132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> svc = checkService(name); 133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (svc != NULL) return svc; 134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGI("Waiting for sevice %s...\n", String8(name).string()); 135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sleep(1); 136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NULL; 138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual sp<IBinder> checkService( const String16& name) const 141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeString16(name); 145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply); 146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return reply.readStrongBinder(); 147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual status_t addService(const String16& name, const sp<IBinder>& service) 150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeString16(name); 154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeStrongBinder(service); 155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply); 156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return err == NO_ERROR ? reply.readInt32() : err; 157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project virtual Vector<String16> listServices() 160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project { 161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Vector<String16> res; 162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project int n = 0; 163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (;;) { 165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Parcel data, reply; 166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor()); 167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project data.writeInt32(n++); 168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = remote()->transact(LIST_SERVICES_TRANSACTION, data, &reply); 169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project if (err != NO_ERROR) 170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project break; 171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project res.add(reply.readString16()); 172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return res; 174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; 176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectIMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager"); 178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// ---------------------------------------------------------------------- 180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define CHECK_INTERFACE(interface, data, reply) \ 182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \ 183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project LOGW("Call incorrectly routed to " #interface); \ 184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return PERMISSION_DENIED; \ 185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } } while (0) 186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatus_t BnServiceManager::onTransact( 188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{ 190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project //printf("ServiceManager received: "); data.print(); 191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project switch(code) { 192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case GET_SERVICE_TRANSACTION: { 193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IServiceManager, data, reply); 194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String16 which = data.readString16(); 195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> b = const_cast<BnServiceManager*>(this)->getService(which); 196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeStrongBinder(b); 197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case CHECK_SERVICE_TRANSACTION: { 200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IServiceManager, data, reply); 201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String16 which = data.readString16(); 202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> b = const_cast<BnServiceManager*>(this)->checkService(which); 203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeStrongBinder(b); 204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case ADD_SERVICE_TRANSACTION: { 207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IServiceManager, data, reply); 208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project String16 which = data.readString16(); 209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project sp<IBinder> b = data.readStrongBinder(); 210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project status_t err = addService(which, b); 211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(err); 212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project case LIST_SERVICES_TRANSACTION: { 215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project CHECK_INTERFACE(IServiceManager, data, reply); 216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project Vector<String16> list = listServices(); 217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project const size_t N = list.size(); 218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeInt32(N); 219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project for (size_t i=0; i<N; i++) { 220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project reply->writeString16(list[i]); 221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return NO_ERROR; 223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } break; 224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project default: 225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project return BBinder::onTransact(code, data, reply, flags); 226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project } 227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} 228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}; // namespace android 230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project 231