1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.annotation.UnsupportedAppUsage; 20 import java.util.ArrayList; 21 22 23 /** 24 * Native implementation of the service manager. Most clients will only 25 * care about getDefault() and possibly asInterface(). 26 * @hide 27 */ 28 public abstract class ServiceManagerNative extends Binder implements IServiceManager 29 { 30 /** 31 * Cast a Binder object into a service manager interface, generating 32 * a proxy if needed. 33 */ 34 @UnsupportedAppUsage asInterface(IBinder obj)35 static public IServiceManager asInterface(IBinder obj) 36 { 37 if (obj == null) { 38 return null; 39 } 40 IServiceManager in = 41 (IServiceManager)obj.queryLocalInterface(descriptor); 42 if (in != null) { 43 return in; 44 } 45 46 return new ServiceManagerProxy(obj); 47 } 48 ServiceManagerNative()49 public ServiceManagerNative() 50 { 51 attachInterface(this, descriptor); 52 } 53 onTransact(int code, Parcel data, Parcel reply, int flags)54 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 55 { 56 try { 57 switch (code) { 58 case IServiceManager.GET_SERVICE_TRANSACTION: { 59 data.enforceInterface(IServiceManager.descriptor); 60 String name = data.readString(); 61 IBinder service = getService(name); 62 reply.writeStrongBinder(service); 63 return true; 64 } 65 66 case IServiceManager.CHECK_SERVICE_TRANSACTION: { 67 data.enforceInterface(IServiceManager.descriptor); 68 String name = data.readString(); 69 IBinder service = checkService(name); 70 reply.writeStrongBinder(service); 71 return true; 72 } 73 74 case IServiceManager.ADD_SERVICE_TRANSACTION: { 75 data.enforceInterface(IServiceManager.descriptor); 76 String name = data.readString(); 77 IBinder service = data.readStrongBinder(); 78 boolean allowIsolated = data.readInt() != 0; 79 int dumpPriority = data.readInt(); 80 addService(name, service, allowIsolated, dumpPriority); 81 return true; 82 } 83 84 case IServiceManager.LIST_SERVICES_TRANSACTION: { 85 data.enforceInterface(IServiceManager.descriptor); 86 int dumpPriority = data.readInt(); 87 String[] list = listServices(dumpPriority); 88 reply.writeStringArray(list); 89 return true; 90 } 91 92 case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: { 93 data.enforceInterface(IServiceManager.descriptor); 94 IPermissionController controller = 95 IPermissionController.Stub.asInterface( 96 data.readStrongBinder()); 97 setPermissionController(controller); 98 return true; 99 } 100 } 101 } catch (RemoteException e) { 102 } 103 104 return false; 105 } 106 asBinder()107 public IBinder asBinder() 108 { 109 return this; 110 } 111 } 112 113 class ServiceManagerProxy implements IServiceManager { ServiceManagerProxy(IBinder remote)114 public ServiceManagerProxy(IBinder remote) { 115 mRemote = remote; 116 } 117 asBinder()118 public IBinder asBinder() { 119 return mRemote; 120 } 121 122 @UnsupportedAppUsage getService(String name)123 public IBinder getService(String name) throws RemoteException { 124 Parcel data = Parcel.obtain(); 125 Parcel reply = Parcel.obtain(); 126 data.writeInterfaceToken(IServiceManager.descriptor); 127 data.writeString(name); 128 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); 129 IBinder binder = reply.readStrongBinder(); 130 reply.recycle(); 131 data.recycle(); 132 return binder; 133 } 134 checkService(String name)135 public IBinder checkService(String name) throws RemoteException { 136 Parcel data = Parcel.obtain(); 137 Parcel reply = Parcel.obtain(); 138 data.writeInterfaceToken(IServiceManager.descriptor); 139 data.writeString(name); 140 mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0); 141 IBinder binder = reply.readStrongBinder(); 142 reply.recycle(); 143 data.recycle(); 144 return binder; 145 } 146 addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)147 public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) 148 throws RemoteException { 149 Parcel data = Parcel.obtain(); 150 Parcel reply = Parcel.obtain(); 151 data.writeInterfaceToken(IServiceManager.descriptor); 152 data.writeString(name); 153 data.writeStrongBinder(service); 154 data.writeInt(allowIsolated ? 1 : 0); 155 data.writeInt(dumpPriority); 156 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); 157 reply.recycle(); 158 data.recycle(); 159 } 160 listServices(int dumpPriority)161 public String[] listServices(int dumpPriority) throws RemoteException { 162 ArrayList<String> services = new ArrayList<String>(); 163 int n = 0; 164 while (true) { 165 Parcel data = Parcel.obtain(); 166 Parcel reply = Parcel.obtain(); 167 data.writeInterfaceToken(IServiceManager.descriptor); 168 data.writeInt(n); 169 data.writeInt(dumpPriority); 170 n++; 171 try { 172 boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0); 173 if (!res) { 174 break; 175 } 176 } catch (RuntimeException e) { 177 // The result code that is returned by the C++ code can 178 // cause the call to throw an exception back instead of 179 // returning a nice result... so eat it here and go on. 180 break; 181 } 182 services.add(reply.readString()); 183 reply.recycle(); 184 data.recycle(); 185 } 186 String[] array = new String[services.size()]; 187 services.toArray(array); 188 return array; 189 } 190 setPermissionController(IPermissionController controller)191 public void setPermissionController(IPermissionController controller) 192 throws RemoteException { 193 Parcel data = Parcel.obtain(); 194 Parcel reply = Parcel.obtain(); 195 data.writeInterfaceToken(IServiceManager.descriptor); 196 data.writeStrongBinder(controller.asBinder()); 197 mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0); 198 reply.recycle(); 199 data.recycle(); 200 } 201 202 @UnsupportedAppUsage 203 private IBinder mRemote; 204 } 205