Home | History | Annotate | Download | only in os
      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 java.util.ArrayList;
     20 
     21 
     22 /**
     23  * Native implementation of the service manager.  Most clients will only
     24  * care about getDefault() and possibly asInterface().
     25  * @hide
     26  */
     27 public 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();
     76                 boolean allowIsolated = data.readInt() != 0;
     77                 addService(name, service, allowIsolated);
     78                 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 
    109 class 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 
    142     public void addService(String name, IBinder service, boolean allowIsolated)
    143             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);
    149         data.writeInt(allowIsolated ? 1 : 0);
    150         mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    151         reply.recycle();
    152         data.recycle();
    153     }
    154 
    155     public String[] listServices() throws RemoteException {
    156         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;
    182     }
    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 }
    197