用户空间应用程序如何控制Android中的硬件(位置/网络/ Wifi)?

时间:2015-06-22 16:04:14

标签: android kernel android-service hardware android-binder

我一直在阅读所有我能找到的东西,试图弄清楚Android的BINDER IPC机制背后的软件架构。据我所知,BINDER位于内核空间,暂时为用户空间应用程序提供共享内存分配,通过它可以在进程之间中继消息。

我开始失去控制力的是实际实施的工作方式 - 特别是与 parcels 有关。

我正在网上查找并发现了Android提供的任意服务的实现,例如Network / Wifi / Notificaiton / Battery,ect(Docs)。从我的阅读中我了解到,用户空间程序本身不应该实例化服务类,而是通过Context.getSystemService(Context.X)获取对它的引用。因此,我认为这是间接说明Android 已经运行的服务,或者至少有资源在需要时启动它。实施基本上是这样的:

Battery.class

BatteryManager.setBatteryState(){
    Parcel parcelLocal = Parcel.obtain();
    parcelLocal.writeInterfaceToken("android.power.BatteryManager");
    parcelLocal.writeInt(1/0); //Depending on requested state
    BinderObject.transact      //Send the data using BINDER
    CheckForExceptions();      //Upon return, check for exceptions 
    ReadResponse();            //If none, read the response from the target
    DoAppropriateAction();     //Whatever we need to do after setting the state
    parcelLocal.recycle();     //Return the parcel resource
}

起初看起来很简单:当用户执行以下操作时:

BatteryMonitor bMonitor = Context.getSystemService(Context.POWER_SERVICE);
bMonitor.setBatteryStatus(1); 

然后user's实例将使用BINDER机制与system's实际服务控制器(哪个是同一个类的实例?)进行通信。但是,上面显示的代码 IS 是系统电池监控服务的实现,那么谁实际上正在接收BINDER数据呢?

TL; DR :如果这一切都非常令人困惑,这很可能就像我试图将一千行代码压缩成10行一样,摘要是:当用户打算控制时硬件的状态 - 例如网络/ Wifi /位置/通知(触摸屏) - 在Android中实际是什么 >控制与这些抽象服务相关的硬件?

注意:上述代码完全是伪造的,仅用于显示一般结构。

1 个答案:

答案 0 :(得分:1)

大多数系统服务在system_server进程中作为线程运行。在启动时,他们会将来电邀请(请参阅addService()SystemServer.java的来电)传递给servicemanager,然后getSystemService可以将邀请分发给正在呼叫LocationManagerService的应用。

一旦滚动,您可以将整个设置视为一种客户端 - 服务器架构,其中您的应用程序是客户端(远程或代理端),服务器(本地或存根端)是您的系统服务在说话。客户端和服务器通过称为binder的进程间通信(IPC)子系统进行通信。绑定器有不同的部分:框架组件执行包裹的编组和解组,而内核驱动程序向/从ioctl调用执行实际的内存复制,并跟踪谁被邀请在进程和线程级别调用。

通过代理与活页夹的应用程序界面。例如,当您使用android.location.ILocationManager时,您会获得getLastLocation()的实例。 Proxy类中的一个方法是... @Override public android.location.Location getLastLocation(android.location.LocationRequest request, java.lang.String packageName) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); android.location.Location _result; try { _data.writeInterfaceToken(DESCRIPTOR); if ((request!=null)) { _data.writeInt(1); request.writeToParcel(_data, 0); } else { _data.writeInt(0); } _data.writeString(packageName); mRemote.transact(Stub.TRANSACTION_getLastLocation, _data, _reply, 0); _reply.readException(); if ((0!=_reply.readInt())) { _result = android.location.Location.CREATOR.createFromParcel(_reply); } else { _result = null; } } finally { _reply.recycle(); _data.recycle(); } return _result; } ...

TRANSACTION_getLastLocation

在这里,您可以看到事务代码onTransact()与任何必要的数据一起写入接口,并读取结果。在存根端,有一个... case TRANSACTION_getLastLocation: { data.enforceInterface(DESCRIPTOR); android.location.LocationRequest _arg0; if ((0!=data.readInt())) { _arg0 = android.location.LocationRequest.CREATOR.createFromParcel(data); } else { _arg0 = null; } java.lang.String _arg1; _arg1 = data.readString(); android.location.Location _result = this.getLastLocation(_arg0, _arg1); reply.writeNoException(); if ((_result!=null)) { reply.writeInt(1); _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } ... 方法在服务的进程空间中运行,它根据事务代码处理所有传入的事务:

system_service

简而言之,service_manager进程代表调用者行事。这允许它在硬件或其他系统资源上执行通常特权操作。安全性基于1)应用程序具有调用邀请(通过getSystemServiceACCESS_COARSE_LOCATION获得)和2)传递服务本身实现的任何检查,例如检查ACCESS_FINE_LOCATION或{ {1}} LocationManagerService(在清单中声明并在最终用户安装时批准)。

更新:在位置服务的情况下,这些硬件操作需要从GPS硬件获取实际的NMEA数据。目前这种方式是通过GpsLocationProvider类实现的,该类通过JNI与本机代码连接。此本机代码(com_android_server_location_GpsLocationProvider.cpp)是打开硬件设备的位置(通过hw_module_t结构中保存的抽象层),进行位置回调(例如,location_callback())等。所有这在具有特权UID system_server的{​​{1}}进程空间内运行。您可以通过运行启用位置的应用程序来验证这一点,在logcat中查找system标记并确认记录的PID是GpsLocationProvider的PID。例如:

system_server

$ adb logcat | grep -i gps
...
D/GpsLocationProvider(  731): Reset GPS properties, previous size = 8
...

最后,我强烈推荐视频教程Deep Dive Into Android IPC/Binder Framework以了解有关此内容的更多信息。可以找到谈话的幻灯片here