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                     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                 }
     98             }
     99         } catch (RemoteException e) {
    100         }
    101 
    102         return false;
    103     }
    104 
    105     public IBinder asBinder()
    106     {
    107         return this;
    108     }
    109 }
    110 
    111 class ServiceManagerProxy implements IServiceManager {
    112     public ServiceManagerProxy(IBinder remote) {
    113         mRemote = remote;
    114     }
    115 
    116     public IBinder asBinder() {
    117         return mRemote;
    118     }
    119 
    120     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 
    144     public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
    145             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);
    151         data.writeInt(allowIsolated ? 1 : 0);
    152         data.writeInt(dumpPriority);
    153         mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    154         reply.recycle();
    155         data.recycle();
    156     }
    157 
    158     public String[] listServices(int dumpPriority) throws RemoteException {
    159         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);
    166             data.writeInt(dumpPriority);
    167             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;
    186     }
    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 }
    201