blob: be244264875e0570e6051b43fab7bb9a3aef99f7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.os;
18
Dianne Hackborna53de062012-05-08 18:53:51 -070019import java.util.ArrayList;
20
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021
22/**
23 * Native implementation of the service manager. Most clients will only
24 * care about getDefault() and possibly asInterface().
25 * @hide
26 */
27public abstract class ServiceManagerNative extends Binder implements IServiceManager
28{
29 /**
30 * Cast a Binder object into a service manager interface, generating
31 * a proxy if needed.
32 */
33 static public IServiceManager asInterface(IBinder obj)
34 {
35 if (obj == null) {
36 return null;
37 }
38 IServiceManager in =
39 (IServiceManager)obj.queryLocalInterface(descriptor);
40 if (in != null) {
41 return in;
42 }
43
44 return new ServiceManagerProxy(obj);
45 }
46
47 public ServiceManagerNative()
48 {
49 attachInterface(this, descriptor);
50 }
51
52 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
53 {
54 try {
55 switch (code) {
56 case IServiceManager.GET_SERVICE_TRANSACTION: {
57 data.enforceInterface(IServiceManager.descriptor);
58 String name = data.readString();
59 IBinder service = getService(name);
60 reply.writeStrongBinder(service);
61 return true;
62 }
63
64 case IServiceManager.CHECK_SERVICE_TRANSACTION: {
65 data.enforceInterface(IServiceManager.descriptor);
66 String name = data.readString();
67 IBinder service = checkService(name);
68 reply.writeStrongBinder(service);
69 return true;
70 }
71
72 case IServiceManager.ADD_SERVICE_TRANSACTION: {
73 data.enforceInterface(IServiceManager.descriptor);
74 String name = data.readString();
75 IBinder service = data.readStrongBinder();
Dianne Hackborna573f6a2012-02-09 16:12:18 -080076 boolean allowIsolated = data.readInt() != 0;
77 addService(name, service, allowIsolated);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078 return true;
79 }
80
81 case IServiceManager.LIST_SERVICES_TRANSACTION: {
82 data.enforceInterface(IServiceManager.descriptor);
83 String[] list = listServices();
84 reply.writeStringArray(list);
85 return true;
86 }
87
88 case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
89 data.enforceInterface(IServiceManager.descriptor);
90 IPermissionController controller
91 = IPermissionController.Stub.asInterface(
92 data.readStrongBinder());
93 setPermissionController(controller);
94 return true;
95 }
96 }
97 } catch (RemoteException e) {
98 }
99
100 return false;
101 }
102
103 public IBinder asBinder()
104 {
105 return this;
106 }
107}
108
109class ServiceManagerProxy implements IServiceManager {
110 public ServiceManagerProxy(IBinder remote) {
111 mRemote = remote;
112 }
113
114 public IBinder asBinder() {
115 return mRemote;
116 }
117
118 public IBinder getService(String name) throws RemoteException {
119 Parcel data = Parcel.obtain();
120 Parcel reply = Parcel.obtain();
121 data.writeInterfaceToken(IServiceManager.descriptor);
122 data.writeString(name);
123 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
124 IBinder binder = reply.readStrongBinder();
125 reply.recycle();
126 data.recycle();
127 return binder;
128 }
129
130 public IBinder checkService(String name) throws RemoteException {
131 Parcel data = Parcel.obtain();
132 Parcel reply = Parcel.obtain();
133 data.writeInterfaceToken(IServiceManager.descriptor);
134 data.writeString(name);
135 mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
136 IBinder binder = reply.readStrongBinder();
137 reply.recycle();
138 data.recycle();
139 return binder;
140 }
141
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800142 public void addService(String name, IBinder service, boolean allowIsolated)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 throws RemoteException {
144 Parcel data = Parcel.obtain();
145 Parcel reply = Parcel.obtain();
146 data.writeInterfaceToken(IServiceManager.descriptor);
147 data.writeString(name);
148 data.writeStrongBinder(service);
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800149 data.writeInt(allowIsolated ? 1 : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
151 reply.recycle();
152 data.recycle();
153 }
154
155 public String[] listServices() throws RemoteException {
Dianne Hackborna53de062012-05-08 18:53:51 -0700156 ArrayList<String> services = new ArrayList<String>();
157 int n = 0;
158 while (true) {
159 Parcel data = Parcel.obtain();
160 Parcel reply = Parcel.obtain();
161 data.writeInterfaceToken(IServiceManager.descriptor);
162 data.writeInt(n);
163 n++;
164 try {
165 boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
166 if (!res) {
167 break;
168 }
169 } catch (RuntimeException e) {
170 // The result code that is returned by the C++ code can
171 // cause the call to throw an exception back instead of
172 // returning a nice result... so eat it here and go on.
173 break;
174 }
175 services.add(reply.readString());
176 reply.recycle();
177 data.recycle();
178 }
179 String[] array = new String[services.size()];
180 services.toArray(array);
181 return array;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 }
183
184 public void setPermissionController(IPermissionController controller)
185 throws RemoteException {
186 Parcel data = Parcel.obtain();
187 Parcel reply = Parcel.obtain();
188 data.writeInterfaceToken(IServiceManager.descriptor);
189 data.writeStrongBinder(controller.asBinder());
190 mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
191 reply.recycle();
192 data.recycle();
193 }
194
195 private IBinder mRemote;
196}