赞
踩
在Android O之前,HAL是一个个的.so库,通过dlopen来进行打开,库和framework位于同一个进程。如下图所示:
在Android O之后,framework和hal运行于不同的进程,所有的HAL采用新的HIDL技术来完成。
HIDL是Android8.0新出的一个技能,以service和client的方式实现hal接口,目的是想使Android系统和BSP解绑,使系统升级更加方便。HIDL的使用方法一般是先提供.hal文件,然后使用hidl-gen工具生成 框架源文件和Android.bp编译工具文件,之后填充生成的源文件和定制Android.bp编译文件
官方介绍
这是一个完整的 HIDL 接口的实现:
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java
/**
* Makes a callback to HIDL to getMacAddress from supplicant
*
* @param ifaceName Name of the interface.
* @return string containing the MAC address, or null on a failed call
*/
public String getMacAddress(@NonNull String ifaceName) {
return mSupplicantStaIfaceHal.getMacAddress(ifaceName);
}
/frameworks/opt/net/wifi/service/java/com/android/server/wifi/SupplicantStaIfaceHal.java
/** * Makes a callback to HIDL to getMacAddress from supplicant * * @param ifaceName Name of the interface. * @return string containing the MAC address, or null on a failed call */ public String getMacAddress(@NonNull String ifaceName) { synchronized (mLock) { final String methodStr = "getMacAddress"; ISupplicantStaIface iface = checkSupplicantStaIfaceAndLogFailure(ifaceName, methodStr); if (iface == null) return null; Mutable<String> gotMac = new Mutable<>(); try { iface.getMacAddress((SupplicantStatus status, byte[/* 6 */] macAddr) -> { if (checkStatusAndLogFailure(status, methodStr)) { gotMac.value = NativeUtil.macAddressFromByteArray(macAddr); } }); } catch (RemoteException e) { handleRemoteException(e, methodStr); } return gotMac.value; } }
/hardware/interfaces/wifi/supplicant/1.0/ISupplicantStaIface.hal
/**
* Send driver command to get MAC address of the device.
*
* @return status Status of the operation.
* Possible status codes:
* |SupplicantStatusCode.SUCCESS|,
* |SupplicantStatusCode.FAILURE_UNKNOWN|,
* |SupplicantStatusCode.FAILURE_IFACE_INVALID|
* @return macAddr MAC address of the device.
*/
getMacAddress()
generates (SupplicantStatus status, MacAddress macAddr);
/external/wpa_supplicant_8/wpa_supplicant/hidl/1.0/sta_iface.cpp
Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&StaIface::getMacAddressInternal, _hidl_cb);
}
StaIface::getMacAddressInternal() { struct wpa_supplicant *wpa_s = retrieveIfacePtr(); std::vector<char> cmd( kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress)); char driver_cmd_reply_buf[4096] = {}; int ret = wpa_drv_driver_cmd( wpa_s, cmd.data(), driver_cmd_reply_buf, sizeof(driver_cmd_reply_buf)); // Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX" std::string reply_str = driver_cmd_reply_buf; if (ret < 0 || reply_str.empty() || reply_str.find("=") == std::string::npos) { return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; } // Remove all whitespace first and then split using the delimiter "=". reply_str.erase( remove_if(reply_str.begin(), reply_str.end(), isspace), reply_str.end()); std::string mac_addr_str = reply_str.substr(reply_str.find("=") + 1, reply_str.size()); std::array<uint8_t, 6> mac_addr; if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) { return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}}; } return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr}; }
关注公众号,获取更多开发必备知识
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。