在android O之後google爲了更好的管理以及方便OTA的升級,加入了HIDL,將Android Framework和Hal進行分離
每個模塊流程大致都一樣,我主要從hwcomposer流程入手分析學習一下,本文沒有涉及到HIDL的啓動以及通訊,主要談到hotplug的傳遞流程以及註冊過程
首先看看hotplug的註冊流程
查看framework native部分
frameworks\native\services\surfaceflinger\surfaceflinger.h頭文件裏面可以看到
我們目前使用的是hwc2,所以SurfaceFlinger 繼承了ComposerCallback類
class SurfaceFlinger : public BnSurfaceComposer,
private IBinder::DeathRecipient,
#ifdef USE_HWC2
private HWC2::ComposerCallback
#else
private HWComposer::EventHandler
#endif
看看ComposerCallback這個類
在frameworks\native\services\surfaceflinger\DisplayHardware\hwc2.h中
class ComposerCallback {
public:
virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
Connection connection,
bool primaryDisplay) = 0;
virtual void onRefreshReceived(int32_t sequenceId,
hwc2_display_t display) = 0;
virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
int64_t timestamp) = 0;
virtual ~ComposerCallback() = default;
};
在hwc2.h的頭文件裏面ComposerCallback 類中定義了,主要有同步,熱拔插,刷新三個虛方法,目前猜測在surfaceflinger.cpp中應該會實現這三個方法,然而你的猜測是對的
frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
void SurfaceFlinger::onHotplugReceived(int32_t sequenceId,
hwc2_display_t display, HWC2::Connection connection,
bool primaryDisplay) {
ALOGV("onHotplugReceived(%d, %" PRIu64 ", %s, %s)",
sequenceId, display,
connection == HWC2::Connection::Connected ?
"connected" : "disconnected",
primaryDisplay ? "primary" : "external");
ConditionalLock lock(mStateLock,
std::this_thread::get_id() != mMainThreadId);
if (primaryDisplay) {
mHwc->onHotplug(display, connection);
if (!mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY].get()) {
createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
}
createDefaultDisplayDevice();
} else {
if (sequenceId != mComposerSequenceId) {
return;
}
if (mHwc->isUsingVrComposer()) {
ALOGE("External displays are not supported by the vr hardware composer.");
return;
}
mHwc->onHotplug(display, connection);
auto type = DisplayDevice::DISPLAY_EXTERNAL;
if (connection == HWC2::Connection::Connected) {
createBuiltinDisplayLocked(type);
} else {
mCurrentState.displays.removeItem(mBuiltinDisplays[type]);
mBuiltinDisplays[type].clear();
}
setTransactionFlags(eDisplayTransactionNeeded);
// Defer EventThread notification until SF has updated mDisplays.
}
}
好了,我們現在知道了這三個方法的實現,但是是如何註冊的呢?以及hal層是如何實現回調的呢?
那麼下面來看看具體的註冊方式以及回調方法
在surfaceflinger.cpp文件中,SurfaceFlinger的init() 的函數裏面有調用registerCallback函數代碼
void SurfaceFlinger::init() {
.....
mHwc.reset(new HWComposer(false));
mHwc->registerCallback(this, mComposerSequenceId);
.....
}
//其中mHwc在surfaceflinger.h中定義
std::unique_ptr<HWComposer> mHwc;
於是調用frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.cpp
void HWComposer::registerCallback(HWC2::ComposerCallback* callback,int32_t sequenceId)
{
mHwcDevice->registerCallback(callback, sequenceId);
}
mHwcDevice變量在frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.cpp中定義
std::unique_ptr<HWC2::Device> mHwcDevice;
frameworks\native\services\surfaceflinger\DisplayHardware\hwc2.cpp
void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
if (mRegisteredCallback) {
ALOGW("Callback already registered. Ignored extra registration "
"attempt.");
return;
}
mRegisteredCallback = true;
sp<ComposerCallbackBridge> callbackBridge(
new ComposerCallbackBridge(callback, sequenceId));
mComposer->registerCallback(callbackBridge);
LOG_ALWAYS_FATAL_IF(!callbackBridge->HasPrimaryDisplay(),
"Registered composer callback but didn't get primary display");
}
在上面的函數中涉及到ComposerCallbackBridge類,調用了ComposerCallbackBridge構造函數,將callback賦值了mCallback,並初始化了callbackBridge對象,而且onHotplug函數裏面進行了surfaceflinger類裏面onHotplugReceived回調
class ComposerCallbackBridge : public Hwc2::IComposerCallback {
public:
ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
: mCallback(callback), mSequenceId(sequenceId),
mHasPrimaryDisplay(false) {}
Return<void> onHotplug(Hwc2::Display display,
IComposerCallback::Connection conn) override
{
HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
if (!mHasPrimaryDisplay) {
LOG_ALWAYS_FATAL_IF(connection != HWC2::Connection::Connected,
"Initial onHotplug callback should be "
"primary display connected");
mHasPrimaryDisplay = true;
mCallback->onHotplugReceived(mSequenceId, display,
connection, true);
} else {
mCallback->onHotplugReceived(mSequenceId, display,
connection, false);
}
return Void();
}
......
}
繼續註冊調用frameworks\native\services\surfaceflinger\DisplayHardware\ComposerHal.cpp
注意現在變了變成了callbackBridge
void Composer::registerCallback(const sp<IComposerCallback>& callback)
{
auto ret = mClient->registerCallback(callback);
if (!ret.isOk()) {
ALOGE("failed to register IComposerCallback");
}
}
frameworks\native\services\surfaceflinger\DisplayHardware\ComposerHal.h
````c++
sp<IComposer> mComposer;
sp<IComposerClient> mClient;
對接了Treble架構的Hal,接着來到Treble層
hardware\interfaces\graphics\composer\2.1\default\ComposerClient.cpp
Return<void> ComposerClient::registerCallback(
const sp<IComposerCallback>& callback)
{
// no locking as we require this function to be called only once
mCallback = callback;
mHal.enableCallback(callback != nullptr);
return Void();
}
hardware\interfaces\graphics\composer\2.1\default\ComposerClient.h中申明如下
sp<IComposerCallback> mCallback;
ComposerBase& mHal;
查看ComposerBase類中虛函數
class ComposerBase {
public:
virtual ~ComposerBase() {};
virtual void removeClient() = 0;
virtual void enableCallback(bool enable) = 0;
......
}
Hwchal類繼承了ComposerBase ,並實現了接口函數
hardware\interfaces\graphics\composer\2.1\default\hwc.h
class HwcHal : public IComposer, public ComposerBase {
hardware\interfaces\graphics\composer\2.1\default\hwc.cpp
void HwcHal::enableCallback(bool enable)
{
if (enable) {
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
} else {
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
nullptr);
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
nullptr);
mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
nullptr);
}
}
這裏有個mDispatch是個什麼東東?而且也看到有註冊hotplugHook,refreshHook,vsyncHook函數
接着跟到頭文件hardware\interfaces\graphics\composer\2.1\default\hwc.h發現mDispatch是一個結構體
struct {
....
HWC2_PFN_REGISTER_CALLBACK registerCallback;
....
} mDispatch;
hardware\libhardware\include\hardware\Hwcomposer2.h
HWC2_PFN_REGISTER_CALLBACK 是一個自定義函數指針類型
typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_REGISTER_CALLBACK)(
hwc2_device_t* device,
int32_t /*hwc2_callback_descriptor_t*/ descriptor,
hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer);
那這個是如何讓實現調用的呢,
其實在HwcHal結構函數中進行結構體初始化
HwcHal::HwcHal(const hw_module_t* module)
: mDevice(nullptr), mDispatch(), mAdapter()
{
....
initDispatch();
}
template<typename T>
void HwcHal::initDispatch(hwc2_function_descriptor_t desc, T* outPfn)
{
auto pfn = mDevice->getFunction(mDevice, desc);
if (!pfn) {
LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
}
*outPfn = reinterpret_cast<T>(pfn);
}
void HwcHal::initDispatch()
{
....
initDispatch(HWC2_FUNCTION_REGISTER_CALLBACK,
&mDispatch.registerCallback);
.....
}
看到這裏是不是有一種柳暗花明的感覺
通過mDevice->getFunction(mDevice, desc);函數結構調用hal層函數,各函數結構由各廠商自己完成,可以看到
hardware\libhardware\include\hardware\Hwcomposer2.h
typedef struct hwc2_device {
/* Must be the first member of this struct, since a pointer to this struct
* will be generated by casting from a hw_device_t* */
struct hw_device_t common;
/* getCapabilities(..., outCount, outCapabilities)
*
* Provides a list of capabilities (described in the definition of
* hwc2_capability_t above) supported by this device. This list must
* not change after the device has been loaded.
*
* Parameters:
* outCount - if outCapabilities was NULL, the number of capabilities
* which would have been returned; if outCapabilities was not NULL,
* the number of capabilities returned, which must not exceed the
* value stored in outCount prior to the call
* outCapabilities - a list of capabilities supported by this device; may
* be NULL, in which case this function must write into outCount the
* number of capabilities which would have been written into
* outCapabilities
*/
void (*getCapabilities)(struct hwc2_device* device, uint32_t* outCount,
int32_t* /*hwc2_capability_t*/ outCapabilities);
/* getFunction(..., descriptor)
*
* Returns a function pointer which implements the requested description.
*
* Parameters:
* descriptor - the function to return
*
* Returns either a function pointer implementing the requested descriptor
* or NULL if the described function is not supported by this device.
*/
hwc2_function_pointer_t (*getFunction)(struct hwc2_device* device,
int32_t /*hwc2_function_descriptor_t*/ descriptor);
} hwc2_device_t;
看到註冊的函數hotplugHook函數
void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
hwc2_display_t display, int32_t connected)
{
auto hal = reinterpret_cast<HwcHal*>(callbackData);
auto client = hal->getClient();
if (client != nullptr) {
client->onHotplug(display,
static_cast<IComposerCallback::Connection>(connected));
}
}
void ComposerClient::onHotplug(Display display,
IComposerCallback::Connection connected)
{
....
auto ret = mCallback->onHotplug(display, connected);
ALOGE_IF(!ret.isOk(), "failed to send onHotplug: %s",
ret.description().c_str());
}
到此三個註冊回調接口就完成了,hotplugHook函數調用有hal完成,當hal檢測到有device接入的時候,產生中斷從而回調hotplugHook這樣整個流程就完成了!
關於HIDL的通訊,服務相關的內容後續在分析