Android 框架层为IMountService 增长新接口

 在为Android 增长多分区的支持时,可能会须要得到当前 USB 链接的挂载口,可能标准的Android 框架并未提供这样的接口给开发者,这时就须要咱们本身为它提供接口了。先来看一下上层(应用)如何获得一个IMountService 的。html

复制代码
  private  synchronized IMountService getMountService() {
        if (mMountService ==  null) {
            IBinder service = ServiceManager.getService("mount");
            if (service !=  null) {
               mMountService = IMountService.Stub.asInterface(service);
           }  else {
               Log.e(TAG, "Can't get mount service");
           }
       }
        return mMountService;
    }
复制代码

 关于Binder 能够参考下这篇文章:Android深刻浅出之Binder机制 。java

Android 2.2新增接口 

Android 2.2为IMountService 新增接口很是容易,在frameworks/base/core/java/android/os/storage 有一个IMountService.aidl 文件,能够直接在这个文件里面新增一个接口提供给上层,如:android

/*add by terry*/
    String getUsbMountPointPath() ;

该文件负责生成IMountService.java文件,接着进入frameworks/base/services/java/com/android/server ,打开MountService.java 该文件继承于IMountService.aidl生成的类框架

class MountService  extends IMountService.Stub

在这个类里面实现咱们为IMountService.aidl 新增的接口ide

public String getUsbMountPointPath(){
        return usbMountPointPath;
    }

OK。经过上面的操做, StorageManage  就能够很方便的获得这个为其新增的接口,上层即可以访问了。this

编译步骤:spa

1):编译framework/base (生成IMountService.java)code

 2):编译framework/base/service (编译MountService)orm

3):编译framework/base  (编译StorageManage以提供给上层调用)server

 

Android 4.0 以上新增接口

相比于Android 2.2,在Android 4.0框架层 为IMountService 新增一个接口就显得比较复杂了。

 按照Android 2.2 新增接口的方法,咱们会先进入frameworks/base/core/java/android/os/storage 查找IMountService.aidl文件,进入目录,ls 一下,会发现并无该文件,取而代之的是IMountService.java。这是怎么回事?打开该文件:映入眼帘首先会看到该警告:

 

复制代码
 /**
 * WARNING! Update IMountService.h and IMountService.cpp if you change this
 * file. In particular, the ordering of the methods below must match the
 * _TRANSACTION enum in IMountService.cpp
 *
 * @hide - Applications should use android.os.storage.StorageManager to access
 *       storage functions.
 */
复制代码

 

该警告提示咱们,若是要修改这个文件,必须先修改IMountService.h 头文件和 IMountService.cpp 文件 ,而且还须要注意枚举里面的顺序。按照警告能够一步步修改了。

进入frameworks/base/include/storage 打开IMountService.h ,新增这个方法:

  virtual int32_t getUsbMountPointPath() =  0 ;

完成后进入frameworks/base/libs/storage  打开IMountService.cpp ,在枚举里面新增方法枚举:

复制代码
enum {
    TRANSACTION_registerListener = IBinder::FIRST_CALL_TRANSACTION,
    TRANSACTION_unregisterListener,
    TRANSACTION_isUsbMassStorageConnected,
    TRANSACTION_setUsbMassStorageEnabled,
    TRANSACTION_isUsbMassStorageEnabled,
    TRANSACTION_mountVolume,
    TRANSACTION_unmountVolume,
    TRANSACTION_formatVolume,
    TRANSACTION_getStorageUsers,
    TRANSACTION_getVolumeState,
    TRANSACTION_createSecureContainer,
    TRANSACTION_finalizeSecureContainer,
    TRANSACTION_destroySecureContainer,
    TRANSACTION_mountSecureContainer,
    TRANSACTION_unmountSecureContainer,
    TRANSACTION_isSecureContainerMounted,
    TRANSACTION_renameSecureContainer,
    TRANSACTION_getSecureContainerPath,
    TRANSACTION_getSecureContainerList,
    TRANSACTION_shutdown,
    TRANSACTION_finishMediaUpdate,
    TRANSACTION_mountObb,
    TRANSACTION_unmountObb,
    TRANSACTION_isObbMounted,
    TRANSACTION_getMountedObbPath,
    TRANSACTION_isExternalStorageEmulated,
    TRANSACTION_decryptStorage,
    TRANSACTION_encryptStorage,
     TRANSACTION_getUsbMountPointPath,
};
复制代码

 

 接着新增要实现的方法

复制代码
   int32_t getUsbMountPointPath()
    {
      Parcel data, reply;
        data.writeInterfaceToken(IMountService::getInterfaceDescriptor());
         if (remote()->transact( TRANSACTION_getUsbMountPointPath, data, &reply) != NO_ERROR) {
            LOGD( " getVolumeState could not contact remote\n ");
             return - 1;
        }
        int32_t err = reply.readExceptionCode();
         if (err <  0) {
            LOGD( " getVolumeState caught exception %d\n ", err);
             return err;
        }
         return reply.readInt32();

    }


复制代码

 OK,这个方法到了这里,CPP部分就算完成了。接下来能够为IMountService.java加接口了。

 

 再次进入frameworks/base/core/java/android/os/storage ,打开IMountService.java 文件。

实现该接口,增长如下方法:

 

复制代码
  public String  getUsbMountPointPath()  throws RemoteException {

                Parcel _data = Parcel.obtain();
                Parcel _reply = Parcel.obtain();
                String _result;
                 try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact( Stub.TRANSACTION_getUsbMountPointPath, _data, _reply, 0);
                    _reply.readException();
                    _result = _reply.readString();
                }  finally {
                    _reply.recycle();
                    _data.recycle();
                }
                 return _result;
           }
复制代码

 

 增长这个常量:static final int TRANSACTION_getUsbMountPointPath = IBinder.FIRST_CALL_TRANSACTION + 28;

 

 在onTransact方法里面增长一个case 判断:

复制代码
case  TRANSACTION_getUsbMountPointPath:{
                   data.enforceInterface(DESCRIPTOR);
                    String state =  getUsbMountPointPath();
                    reply.writeNoException();
                    reply.writeString(state);
                    return  true;
               }
复制代码

 

最后,再增长一个该接口的方法

public String getUsbMountPointPath()  throws RemoteException;

到此为止,为IMountService  增长接口所要作的必要步骤就算完成了。

编译步骤:

1):编译framework/base/libs/storage ,产生libstorage.a静态文件。

2):编译framework/base/native/android 产生libandroid.so动态库文件,该文件最终会被IMountService.java 使用。必须经过push 到 system/lib 目录下 。

3) :编译framework/base/service 让getUsbMountPointPath 接口生效。

4):编译framework/base 这样咱们就能够在使用StorageManage 来读取IMountService 的新接口了。 

 

 

注:StorageManage 部分就不写了,能够借鉴其余的方法,添加一个可供上层访问的方法,这部分比较简单。StorageManage在2.2是隐藏的不被开发者使用的,在4.0后则能够正常使用。 

相关文章
相关标签/搜索