blob: 589b8c492ab372ab1c8f0ebd733ace20e077b80a [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 }
Vishnu Nair05768192017-09-19 15:25:38 -070043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044 return new ServiceManagerProxy(obj);
45 }
Vishnu Nair05768192017-09-19 15:25:38 -070046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 public ServiceManagerNative()
48 {
49 attachInterface(this, descriptor);
50 }
Vishnu Nair05768192017-09-19 15:25:38 -070051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
53 {
54 try {
55 switch (code) {
Vishnu Nair05768192017-09-19 15:25:38 -070056 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();
76 boolean allowIsolated = data.readInt() != 0;
77 int dumpPriority = data.readInt();
78 addService(name, service, allowIsolated, dumpPriority);
79 return true;
80 }
81
82 case IServiceManager.LIST_SERVICES_TRANSACTION: {
83 data.enforceInterface(IServiceManager.descriptor);
84 int dumpPriority = data.readInt();
85 String[] list = listServices(dumpPriority);
86 reply.writeStringArray(list);
87 return true;
88 }
89
90 case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
91 data.enforceInterface(IServiceManager.descriptor);
92 IPermissionController controller =
93 IPermissionController.Stub.asInterface(
94 data.readStrongBinder());
95 setPermissionController(controller);
96 return true;
97 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098 }
99 } catch (RemoteException e) {
100 }
Vishnu Nair05768192017-09-19 15:25:38 -0700101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102 return false;
103 }
104
105 public IBinder asBinder()
106 {
107 return this;
108 }
109}
110
111class ServiceManagerProxy implements IServiceManager {
112 public ServiceManagerProxy(IBinder remote) {
113 mRemote = remote;
114 }
Vishnu Nair05768192017-09-19 15:25:38 -0700115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116 public IBinder asBinder() {
117 return mRemote;
118 }
Vishnu Nair05768192017-09-19 15:25:38 -0700119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120 public IBinder getService(String name) throws RemoteException {
121 Parcel data = Parcel.obtain();
122 Parcel reply = Parcel.obtain();
123 data.writeInterfaceToken(IServiceManager.descriptor);
124 data.writeString(name);
125 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
126 IBinder binder = reply.readStrongBinder();
127 reply.recycle();
128 data.recycle();
129 return binder;
130 }
131
132 public IBinder checkService(String name) throws RemoteException {
133 Parcel data = Parcel.obtain();
134 Parcel reply = Parcel.obtain();
135 data.writeInterfaceToken(IServiceManager.descriptor);
136 data.writeString(name);
137 mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
138 IBinder binder = reply.readStrongBinder();
139 reply.recycle();
140 data.recycle();
141 return binder;
142 }
143
Vishnu Nair05768192017-09-19 15:25:38 -0700144 public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 throws RemoteException {
146 Parcel data = Parcel.obtain();
147 Parcel reply = Parcel.obtain();
148 data.writeInterfaceToken(IServiceManager.descriptor);
149 data.writeString(name);
150 data.writeStrongBinder(service);
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800151 data.writeInt(allowIsolated ? 1 : 0);
Vishnu Nair05768192017-09-19 15:25:38 -0700152 data.writeInt(dumpPriority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
154 reply.recycle();
155 data.recycle();
156 }
Vishnu Nair05768192017-09-19 15:25:38 -0700157
158 public String[] listServices(int dumpPriority) throws RemoteException {
Dianne Hackborna53de062012-05-08 18:53:51 -0700159 ArrayList<String> services = new ArrayList<String>();
160 int n = 0;
161 while (true) {
162 Parcel data = Parcel.obtain();
163 Parcel reply = Parcel.obtain();
164 data.writeInterfaceToken(IServiceManager.descriptor);
165 data.writeInt(n);
Vishnu Nair05768192017-09-19 15:25:38 -0700166 data.writeInt(dumpPriority);
Dianne Hackborna53de062012-05-08 18:53:51 -0700167 n++;
168 try {
169 boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
170 if (!res) {
171 break;
172 }
173 } catch (RuntimeException e) {
174 // The result code that is returned by the C++ code can
175 // cause the call to throw an exception back instead of
176 // returning a nice result... so eat it here and go on.
177 break;
178 }
179 services.add(reply.readString());
180 reply.recycle();
181 data.recycle();
182 }
183 String[] array = new String[services.size()];
184 services.toArray(array);
185 return array;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 }
187
188 public void setPermissionController(IPermissionController controller)
189 throws RemoteException {
190 Parcel data = Parcel.obtain();
191 Parcel reply = Parcel.obtain();
192 data.writeInterfaceToken(IServiceManager.descriptor);
193 data.writeStrongBinder(controller.asBinder());
194 mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
195 reply.recycle();
196 data.recycle();
197 }
198
199 private IBinder mRemote;
200}