19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.os;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
19a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackbornimport java.util.ArrayList;
20a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Native implementation of the service manager.  Most clients will only
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * care about getDefault() and possibly asInterface().
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @hide
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class ServiceManagerNative extends Binder implements IServiceManager
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Cast a Binder object into a service manager interface, generating
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a proxy if needed.
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    static public IServiceManager asInterface(IBinder obj)
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (obj == null) {
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return null;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IServiceManager in =
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            (IServiceManager)obj.queryLocalInterface(descriptor);
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (in != null) {
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return in;
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return new ServiceManagerProxy(obj);
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ServiceManagerNative()
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        attachInterface(this, descriptor);
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            switch (code) {
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case IServiceManager.GET_SERVICE_TRANSACTION: {
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                data.enforceInterface(IServiceManager.descriptor);
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String name = data.readString();
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IBinder service = getService(name);
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                reply.writeStrongBinder(service);
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case IServiceManager.CHECK_SERVICE_TRANSACTION: {
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                data.enforceInterface(IServiceManager.descriptor);
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String name = data.readString();
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IBinder service = checkService(name);
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                reply.writeStrongBinder(service);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case IServiceManager.ADD_SERVICE_TRANSACTION: {
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                data.enforceInterface(IServiceManager.descriptor);
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String name = data.readString();
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IBinder service = data.readStrongBinder();
76a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn                boolean allowIsolated = data.readInt() != 0;
77a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn                addService(name, service, allowIsolated);
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case IServiceManager.LIST_SERVICES_TRANSACTION: {
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                data.enforceInterface(IServiceManager.descriptor);
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                String[] list = listServices();
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                reply.writeStringArray(list);
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                data.enforceInterface(IServiceManager.descriptor);
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                IPermissionController controller
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        = IPermissionController.Stub.asInterface(
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                                data.readStrongBinder());
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                setPermissionController(controller);
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                return true;
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } catch (RemoteException e) {
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return false;
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IBinder asBinder()
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    {
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return this;
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass ServiceManagerProxy implements IServiceManager {
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public ServiceManagerProxy(IBinder remote) {
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRemote = remote;
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IBinder asBinder() {
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return mRemote;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IBinder getService(String name) throws RemoteException {
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel data = Parcel.obtain();
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel reply = Parcel.obtain();
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeInterfaceToken(IServiceManager.descriptor);
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeString(name);
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder binder = reply.readStrongBinder();
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        reply.recycle();
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.recycle();
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return binder;
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public IBinder checkService(String name) throws RemoteException {
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel data = Parcel.obtain();
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel reply = Parcel.obtain();
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeInterfaceToken(IServiceManager.descriptor);
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeString(name);
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        IBinder binder = reply.readStrongBinder();
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        reply.recycle();
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.recycle();
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return binder;
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
142a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn    public void addService(String name, IBinder service, boolean allowIsolated)
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws RemoteException {
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel data = Parcel.obtain();
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel reply = Parcel.obtain();
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeInterfaceToken(IServiceManager.descriptor);
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeString(name);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeStrongBinder(service);
149a573f6a1d9b12393fbdfd2c0850499973849854bDianne Hackborn        data.writeInt(allowIsolated ? 1 : 0);
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        reply.recycle();
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.recycle();
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public String[] listServices() throws RemoteException {
156a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        ArrayList<String> services = new ArrayList<String>();
157a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        int n = 0;
158a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        while (true) {
159a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            Parcel data = Parcel.obtain();
160a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            Parcel reply = Parcel.obtain();
161a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            data.writeInterfaceToken(IServiceManager.descriptor);
162a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            data.writeInt(n);
163a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            n++;
164a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            try {
165a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
166a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                if (!res) {
167a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                    break;
168a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                }
169a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            } catch (RuntimeException e) {
170a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                // The result code that is returned by the C++ code can
171a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                // cause the call to throw an exception back instead of
172a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                // returning a nice result...  so eat it here and go on.
173a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn                break;
174a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            }
175a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            services.add(reply.readString());
176a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            reply.recycle();
177a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn            data.recycle();
178a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        }
179a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        String[] array = new String[services.size()];
180a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        services.toArray(array);
181a53de0629f3b94472c0f160f5bbe1090b020feabDianne Hackborn        return array;
1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setPermissionController(IPermissionController controller)
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            throws RemoteException {
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel data = Parcel.obtain();
1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        Parcel reply = Parcel.obtain();
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeInterfaceToken(IServiceManager.descriptor);
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.writeStrongBinder(controller.asBinder());
1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        reply.recycle();
1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        data.recycle();
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private IBinder mRemote;
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
197