ServiceManagerNative.java revision a573f6a1d9b12393fbdfd2c0850499973849854b
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
17package android.os;
18
19
20/**
21 * Native implementation of the service manager.  Most clients will only
22 * care about getDefault() and possibly asInterface().
23 * @hide
24 */
25public abstract class ServiceManagerNative extends Binder implements IServiceManager
26{
27    /**
28     * Cast a Binder object into a service manager interface, generating
29     * a proxy if needed.
30     */
31    static public IServiceManager asInterface(IBinder obj)
32    {
33        if (obj == null) {
34            return null;
35        }
36        IServiceManager in =
37            (IServiceManager)obj.queryLocalInterface(descriptor);
38        if (in != null) {
39            return in;
40        }
41
42        return new ServiceManagerProxy(obj);
43    }
44
45    public ServiceManagerNative()
46    {
47        attachInterface(this, descriptor);
48    }
49
50    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
51    {
52        try {
53            switch (code) {
54            case IServiceManager.GET_SERVICE_TRANSACTION: {
55                data.enforceInterface(IServiceManager.descriptor);
56                String name = data.readString();
57                IBinder service = getService(name);
58                reply.writeStrongBinder(service);
59                return true;
60            }
61
62            case IServiceManager.CHECK_SERVICE_TRANSACTION: {
63                data.enforceInterface(IServiceManager.descriptor);
64                String name = data.readString();
65                IBinder service = checkService(name);
66                reply.writeStrongBinder(service);
67                return true;
68            }
69
70            case IServiceManager.ADD_SERVICE_TRANSACTION: {
71                data.enforceInterface(IServiceManager.descriptor);
72                String name = data.readString();
73                IBinder service = data.readStrongBinder();
74                boolean allowIsolated = data.readInt() != 0;
75                addService(name, service, allowIsolated);
76                return true;
77            }
78
79            case IServiceManager.LIST_SERVICES_TRANSACTION: {
80                data.enforceInterface(IServiceManager.descriptor);
81                String[] list = listServices();
82                reply.writeStringArray(list);
83                return true;
84            }
85
86            case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
87                data.enforceInterface(IServiceManager.descriptor);
88                IPermissionController controller
89                        = IPermissionController.Stub.asInterface(
90                                data.readStrongBinder());
91                setPermissionController(controller);
92                return true;
93            }
94            }
95        } catch (RemoteException e) {
96        }
97
98        return false;
99    }
100
101    public IBinder asBinder()
102    {
103        return this;
104    }
105}
106
107class ServiceManagerProxy implements IServiceManager {
108    public ServiceManagerProxy(IBinder remote) {
109        mRemote = remote;
110    }
111
112    public IBinder asBinder() {
113        return mRemote;
114    }
115
116    public IBinder getService(String name) throws RemoteException {
117        Parcel data = Parcel.obtain();
118        Parcel reply = Parcel.obtain();
119        data.writeInterfaceToken(IServiceManager.descriptor);
120        data.writeString(name);
121        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
122        IBinder binder = reply.readStrongBinder();
123        reply.recycle();
124        data.recycle();
125        return binder;
126    }
127
128    public IBinder checkService(String name) throws RemoteException {
129        Parcel data = Parcel.obtain();
130        Parcel reply = Parcel.obtain();
131        data.writeInterfaceToken(IServiceManager.descriptor);
132        data.writeString(name);
133        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
134        IBinder binder = reply.readStrongBinder();
135        reply.recycle();
136        data.recycle();
137        return binder;
138    }
139
140    public void addService(String name, IBinder service, boolean allowIsolated)
141            throws RemoteException {
142        Parcel data = Parcel.obtain();
143        Parcel reply = Parcel.obtain();
144        data.writeInterfaceToken(IServiceManager.descriptor);
145        data.writeString(name);
146        data.writeStrongBinder(service);
147        data.writeInt(allowIsolated ? 1 : 0);
148        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
149        reply.recycle();
150        data.recycle();
151    }
152
153    public String[] listServices() throws RemoteException {
154        Parcel data = Parcel.obtain();
155        Parcel reply = Parcel.obtain();
156        data.writeInterfaceToken(IServiceManager.descriptor);
157        mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
158        String[] list = reply.readStringArray();
159        reply.recycle();
160        data.recycle();
161        return list;
162    }
163
164    public void setPermissionController(IPermissionController controller)
165            throws RemoteException {
166        Parcel data = Parcel.obtain();
167        Parcel reply = Parcel.obtain();
168        data.writeInterfaceToken(IServiceManager.descriptor);
169        data.writeStrongBinder(controller.asBinder());
170        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
171        reply.recycle();
172        data.recycle();
173    }
174
175    private IBinder mRemote;
176}
177