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 android.annotation.UnsupportedAppUsage;
     20 import java.util.ArrayList;
     21 
     22 
     23 /**
     24  * Native implementation of the service manager.  Most clients will only
     25  * care about getDefault() and possibly asInterface().
     26  * @hide
     27  */
     28 public abstract class ServiceManagerNative extends Binder implements IServiceManager
     29 {
     30     /**
     31      * Cast a Binder object into a service manager interface, generating
     32      * a proxy if needed.
     33      */
     34     @UnsupportedAppUsage
     35     static public IServiceManager asInterface(IBinder obj)
     36     {
     37         if (obj == null) {
     38             return null;
     39         }
     40         IServiceManager in =
     41             (IServiceManager)obj.queryLocalInterface(descriptor);
     42         if (in != null) {
     43             return in;
     44         }
     45 
     46         return new ServiceManagerProxy(obj);
     47     }
     48 
     49     public ServiceManagerNative()
     50     {
     51         attachInterface(this, descriptor);
     52     }
     53 
     54     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
     55     {
     56         try {
     57             switch (code) {
     58                 case IServiceManager.GET_SERVICE_TRANSACTION: {
     59                     data.enforceInterface(IServiceManager.descriptor);
     60                     String name = data.readString();
     61                     IBinder service = getService(name);
     62                     reply.writeStrongBinder(service);
     63                     return true;
     64                 }
     65 
     66                 case IServiceManager.CHECK_SERVICE_TRANSACTION: {
     67                     data.enforceInterface(IServiceManager.descriptor);
     68                     String name = data.readString();
     69                     IBinder service = checkService(name);
     70                     reply.writeStrongBinder(service);
     71                     return true;
     72                 }
     73 
     74                 case IServiceManager.ADD_SERVICE_TRANSACTION: {
     75                     data.enforceInterface(IServiceManager.descriptor);
     76                     String name = data.readString();
     77                     IBinder service = data.readStrongBinder();
     78                     boolean allowIsolated = data.readInt() != 0;
     79                     int dumpPriority = data.readInt();
     80                     addService(name, service, allowIsolated, dumpPriority);
     81                     return true;
     82                 }
     83 
     84                 case IServiceManager.LIST_SERVICES_TRANSACTION: {
     85                     data.enforceInterface(IServiceManager.descriptor);
     86                     int dumpPriority = data.readInt();
     87                     String[] list = listServices(dumpPriority);
     88                     reply.writeStringArray(list);
     89                     return true;
     90                 }
     91 
     92                 case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
     93                     data.enforceInterface(IServiceManager.descriptor);
     94                     IPermissionController controller =
     95                             IPermissionController.Stub.asInterface(
     96                                     data.readStrongBinder());
     97                     setPermissionController(controller);
     98                     return true;
     99                 }
    100             }
    101         } catch (RemoteException e) {
    102         }
    103 
    104         return false;
    105     }
    106 
    107     public IBinder asBinder()
    108     {
    109         return this;
    110     }
    111 }
    112 
    113 class ServiceManagerProxy implements IServiceManager {
    114     public ServiceManagerProxy(IBinder remote) {
    115         mRemote = remote;
    116     }
    117 
    118     public IBinder asBinder() {
    119         return mRemote;
    120     }
    121 
    122     @UnsupportedAppUsage
    123     public IBinder getService(String name) throws RemoteException {
    124         Parcel data = Parcel.obtain();
    125         Parcel reply = Parcel.obtain();
    126         data.writeInterfaceToken(IServiceManager.descriptor);
    127         data.writeString(name);
    128         mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    129         IBinder binder = reply.readStrongBinder();
    130         reply.recycle();
    131         data.recycle();
    132         return binder;
    133     }
    134 
    135     public IBinder checkService(String name) throws RemoteException {
    136         Parcel data = Parcel.obtain();
    137         Parcel reply = Parcel.obtain();
    138         data.writeInterfaceToken(IServiceManager.descriptor);
    139         data.writeString(name);
    140         mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);
    141         IBinder binder = reply.readStrongBinder();
    142         reply.recycle();
    143         data.recycle();
    144         return binder;
    145     }
    146 
    147     public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
    148             throws RemoteException {
    149         Parcel data = Parcel.obtain();
    150         Parcel reply = Parcel.obtain();
    151         data.writeInterfaceToken(IServiceManager.descriptor);
    152         data.writeString(name);
    153         data.writeStrongBinder(service);
    154         data.writeInt(allowIsolated ? 1 : 0);
    155         data.writeInt(dumpPriority);
    156         mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    157         reply.recycle();
    158         data.recycle();
    159     }
    160 
    161     public String[] listServices(int dumpPriority) throws RemoteException {
    162         ArrayList<String> services = new ArrayList<String>();
    163         int n = 0;
    164         while (true) {
    165             Parcel data = Parcel.obtain();
    166             Parcel reply = Parcel.obtain();
    167             data.writeInterfaceToken(IServiceManager.descriptor);
    168             data.writeInt(n);
    169             data.writeInt(dumpPriority);
    170             n++;
    171             try {
    172                 boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
    173                 if (!res) {
    174                     break;
    175                 }
    176             } catch (RuntimeException e) {
    177                 // The result code that is returned by the C++ code can
    178                 // cause the call to throw an exception back instead of
    179                 // returning a nice result...  so eat it here and go on.
    180                 break;
    181             }
    182             services.add(reply.readString());
    183             reply.recycle();
    184             data.recycle();
    185         }
    186         String[] array = new String[services.size()];
    187         services.toArray(array);
    188         return array;
    189     }
    190 
    191     public void setPermissionController(IPermissionController controller)
    192             throws RemoteException {
    193         Parcel data = Parcel.obtain();
    194         Parcel reply = Parcel.obtain();
    195         data.writeInterfaceToken(IServiceManager.descriptor);
    196         data.writeStrongBinder(controller.asBinder());
    197         mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
    198         reply.recycle();
    199         data.recycle();
    200     }
    201 
    202     @UnsupportedAppUsage
    203     private IBinder mRemote;
    204 }
    205