display: config: handle client destroy sequence gracefully
- Split the IDisplayConfigCallback implementation to a separate class. - Notify the device when a client is getting destroyed and perform cleanup on device side. Change-Id: I020a3a9cac7f31195e0072540e2145cdd3da274c
This commit is contained in:
@@ -47,13 +47,25 @@ int ClientImpl::Init(std::string client_name, ConfigCallback *callback) {
|
|||||||
handle = client_handle;
|
handle = client_handle;
|
||||||
};
|
};
|
||||||
int pid = getpid();
|
int pid = getpid();
|
||||||
display_config_->registerClient(client_name + std::to_string(pid), this, hidl_callback);
|
android::sp<ClientCallback> client_cb(new ClientCallback(callback));
|
||||||
|
display_config_->registerClient(client_name + std::to_string(pid), client_cb,
|
||||||
|
hidl_callback);
|
||||||
client_handle_ = handle;
|
client_handle_ = handle;
|
||||||
callback_ = callback;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClientImpl::DeInit() {
|
||||||
|
int32_t error = 0;
|
||||||
|
auto hidl_cb = [&error] (int32_t err, ByteStream params, HandleStream handles) {
|
||||||
|
error = err;
|
||||||
|
};
|
||||||
|
|
||||||
|
display_config_->perform(client_handle_, kDestroy, {}, {}, hidl_cb);
|
||||||
|
display_config_.clear();
|
||||||
|
display_config_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
int ClientImpl::IsDisplayConnected(DisplayType dpy, bool *connected) {
|
int ClientImpl::IsDisplayConnected(DisplayType dpy, bool *connected) {
|
||||||
ByteStream input_params;
|
ByteStream input_params;
|
||||||
input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
|
input_params.setToExternal(reinterpret_cast<uint8_t*>(&dpy), sizeof(DisplayType));
|
||||||
@@ -623,10 +635,6 @@ int ClientImpl::IsBuiltInDisplay(uint32_t disp_id, bool *is_builtin) {
|
|||||||
|
|
||||||
int ClientImpl::SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
|
int ClientImpl::SetCWBOutputBuffer(uint32_t disp_id, const Rect rect, bool post_processed,
|
||||||
const native_handle_t *buffer) {
|
const native_handle_t *buffer) {
|
||||||
if (callback_ == nullptr) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CwbBufferParams input = {disp_id, rect, post_processed};
|
struct CwbBufferParams input = {disp_id, rect, post_processed};
|
||||||
ByteStream input_params;
|
ByteStream input_params;
|
||||||
input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct CwbBufferParams));
|
input_params.setToExternal(reinterpret_cast<uint8_t*>(&input), sizeof(struct CwbBufferParams));
|
||||||
@@ -834,11 +842,11 @@ int ClientImpl::SendTUIEvent(DisplayType dpy, TUIEventType event_type) {
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientImpl::ParseNotifyCWBBufferDone(const ByteStream &input_params,
|
void ClientCallback::ParseNotifyCWBBufferDone(const ByteStream &input_params,
|
||||||
const HandleStream &input_handles) {
|
const HandleStream &input_handles) {
|
||||||
const int *error;
|
const int *error;
|
||||||
|
|
||||||
if (input_params.size() == 0 || input_handles.size() == 0) {
|
if (callback_ == nullptr || input_params.size() == 0 || input_handles.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -848,10 +856,10 @@ void ClientImpl::ParseNotifyCWBBufferDone(const ByteStream &input_params,
|
|||||||
callback_->NotifyCWBBufferDone(*error, buffer.getNativeHandle());
|
callback_->NotifyCWBBufferDone(*error, buffer.getNativeHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientImpl::ParseNotifyQsyncChange(const ByteStream &input_params) {
|
void ClientCallback::ParseNotifyQsyncChange(const ByteStream &input_params) {
|
||||||
const struct QsyncCallbackParams *qsync_data;
|
const struct QsyncCallbackParams *qsync_data;
|
||||||
|
|
||||||
if (input_params.size() == 0) {
|
if (callback_ == nullptr || input_params.size() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -861,8 +869,8 @@ void ClientImpl::ParseNotifyQsyncChange(const ByteStream &input_params) {
|
|||||||
qsync_data->qsync_refresh_rate);
|
qsync_data->qsync_refresh_rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> ClientImpl::perform(uint32_t op_code, const ByteStream &input_params,
|
Return<void> ClientCallback::perform(uint32_t op_code, const ByteStream &input_params,
|
||||||
const HandleStream &input_handles) {
|
const HandleStream &input_handles) {
|
||||||
switch (op_code) {
|
switch (op_code) {
|
||||||
case kSetCwbOutputBuffer:
|
case kSetCwbOutputBuffer:
|
||||||
ParseNotifyCWBBufferDone(input_params, input_handles);
|
ParseNotifyCWBBufferDone(input_params, input_handles);
|
||||||
|
|||||||
@@ -50,9 +50,24 @@ using ::android::hardware::hidl_vec;
|
|||||||
typedef hidl_vec<uint8_t> ByteStream;
|
typedef hidl_vec<uint8_t> ByteStream;
|
||||||
typedef hidl_vec<hidl_handle> HandleStream;
|
typedef hidl_vec<hidl_handle> HandleStream;
|
||||||
|
|
||||||
class ClientImpl : public ClientInterface, public IDisplayConfigCallback {
|
class ClientCallback: public IDisplayConfigCallback {
|
||||||
|
public:
|
||||||
|
ClientCallback(ConfigCallback *cb) {
|
||||||
|
callback_ = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual Return<void> perform(uint32_t op_code, const ByteStream &input_params,
|
||||||
|
const HandleStream &input_handles);
|
||||||
|
void ParseNotifyCWBBufferDone(const ByteStream &input_params, const HandleStream &input_handles);
|
||||||
|
void ParseNotifyQsyncChange(const ByteStream &input_params);
|
||||||
|
ConfigCallback *callback_ = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ClientImpl : public ClientInterface {
|
||||||
public:
|
public:
|
||||||
int Init(std::string client_name, ConfigCallback *callback);
|
int Init(std::string client_name, ConfigCallback *callback);
|
||||||
|
void DeInit();
|
||||||
|
|
||||||
virtual int IsDisplayConnected(DisplayType dpy, bool *connected);
|
virtual int IsDisplayConnected(DisplayType dpy, bool *connected);
|
||||||
virtual int SetDisplayStatus(DisplayType dpy, ExternalStatus status);
|
virtual int SetDisplayStatus(DisplayType dpy, ExternalStatus status);
|
||||||
@@ -102,12 +117,7 @@ class ClientImpl : public ClientInterface, public IDisplayConfigCallback {
|
|||||||
virtual int SendTUIEvent(DisplayType dpy, TUIEventType event_type);
|
virtual int SendTUIEvent(DisplayType dpy, TUIEventType event_type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual Return<void> perform(uint32_t op_code, const ByteStream &input_params,
|
|
||||||
const HandleStream &input_handles);
|
|
||||||
void ParseNotifyCWBBufferDone(const ByteStream &input_params, const HandleStream &input_handles);
|
|
||||||
void ParseNotifyQsyncChange(const ByteStream &input_params);
|
|
||||||
android::sp<IDisplayConfig> display_config_ = nullptr;
|
android::sp<IDisplayConfig> display_config_ = nullptr;
|
||||||
ConfigCallback *callback_ = nullptr;
|
|
||||||
uint64_t client_handle_ = 0;
|
uint64_t client_handle_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,9 @@ int ClientInterface::Create(std::string client_name, ConfigCallback *callback,
|
|||||||
|
|
||||||
void ClientInterface::Destroy(ClientInterface *intf) {
|
void ClientInterface::Destroy(ClientInterface *intf) {
|
||||||
if (intf) {
|
if (intf) {
|
||||||
delete static_cast<ClientImpl *>(intf);
|
ClientImpl *impl = static_cast<ClientImpl *>(intf);
|
||||||
|
impl->DeInit();
|
||||||
|
delete impl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,8 +96,11 @@ void DeviceImpl::serviceDied(uint64_t client_handle,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceImpl::DeviceClientContext::DeviceClientContext(const sp<IDisplayConfigCallback> callback) {
|
DeviceImpl::DeviceClientContext::DeviceClientContext(
|
||||||
callback_ = callback;
|
const sp<IDisplayConfigCallback> callback) : callback_(callback) { }
|
||||||
|
|
||||||
|
sp<IDisplayConfigCallback> DeviceImpl::DeviceClientContext::GetDeviceConfigCallback() {
|
||||||
|
return callback_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeviceImpl::DeviceClientContext::SetDeviceConfigIntf(ConfigInterface *intf) {
|
void DeviceImpl::DeviceClientContext::SetDeviceConfigIntf(ConfigInterface *intf) {
|
||||||
@@ -700,6 +703,26 @@ void DeviceImpl::DeviceClientContext::ParseSendTUIEvent(const ByteStream &input_
|
|||||||
_hidl_cb(error, {}, {});
|
_hidl_cb(error, {}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceImpl::ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb) {
|
||||||
|
auto itr = display_config_map_.find(client_handle);
|
||||||
|
if (itr == display_config_map_.end()) {
|
||||||
|
_hidl_cb(-EINVAL, {}, {});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<DeviceClientContext> client = itr->second;
|
||||||
|
if (client != NULL) {
|
||||||
|
sp<IDisplayConfigCallback> callback = client->GetDeviceConfigCallback();
|
||||||
|
callback->unlinkToDeath(this);
|
||||||
|
ConfigInterface *intf = client->GetDeviceConfigIntf();
|
||||||
|
intf_->UnRegisterClientContext(intf);
|
||||||
|
client.reset();
|
||||||
|
display_config_map_.erase(itr);
|
||||||
|
}
|
||||||
|
|
||||||
|
_hidl_cb(0, {}, {});
|
||||||
|
}
|
||||||
|
|
||||||
Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
|
Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
|
||||||
const ByteStream &input_params, const HandleStream &input_handles,
|
const ByteStream &input_params, const HandleStream &input_handles,
|
||||||
perform_cb _hidl_cb) {
|
perform_cb _hidl_cb) {
|
||||||
@@ -847,6 +870,9 @@ Return<void> DeviceImpl::perform(uint64_t client_handle, uint32_t op_code,
|
|||||||
case kSendTUIEvent:
|
case kSendTUIEvent:
|
||||||
client->ParseSendTUIEvent(input_params, _hidl_cb);
|
client->ParseSendTUIEvent(input_params, _hidl_cb);
|
||||||
break;
|
break;
|
||||||
|
case kDestroy:
|
||||||
|
ParseDestroy(client_handle, _hidl_cb);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ class DeviceImpl : public IDisplayConfig, public android::hardware::hidl_death_r
|
|||||||
|
|
||||||
void SetDeviceConfigIntf(ConfigInterface *intf);
|
void SetDeviceConfigIntf(ConfigInterface *intf);
|
||||||
ConfigInterface* GetDeviceConfigIntf();
|
ConfigInterface* GetDeviceConfigIntf();
|
||||||
|
sp<IDisplayConfigCallback> GetDeviceConfigCallback();
|
||||||
|
|
||||||
virtual void NotifyCWBBufferDone(int32_t error, const native_handle_t *buffer);
|
virtual void NotifyCWBBufferDone(int32_t error, const native_handle_t *buffer);
|
||||||
virtual void NotifyQsyncChange(bool qsync_enabled, int32_t refresh_rate,
|
virtual void NotifyQsyncChange(bool qsync_enabled, int32_t refresh_rate,
|
||||||
@@ -119,7 +120,7 @@ class DeviceImpl : public IDisplayConfig, public android::hardware::hidl_death_r
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ConfigInterface *intf_ = nullptr;
|
ConfigInterface *intf_ = nullptr;
|
||||||
sp<IDisplayConfigCallback> callback_;
|
const sp<IDisplayConfigCallback> callback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
Return<void> registerClient(const hidl_string &client_name, const sp<IDisplayConfigCallback>& cb,
|
Return<void> registerClient(const hidl_string &client_name, const sp<IDisplayConfigCallback>& cb,
|
||||||
@@ -128,6 +129,7 @@ class DeviceImpl : public IDisplayConfig, public android::hardware::hidl_death_r
|
|||||||
const HandleStream &input_handles, perform_cb _hidl_cb) override;
|
const HandleStream &input_handles, perform_cb _hidl_cb) override;
|
||||||
void serviceDied(uint64_t client_handle,
|
void serviceDied(uint64_t client_handle,
|
||||||
const android::wp<::android::hidl::base::V1_0::IBase>& callback);
|
const android::wp<::android::hidl::base::V1_0::IBase>& callback);
|
||||||
|
void ParseDestroy(uint64_t client_handle, perform_cb _hidl_cb);
|
||||||
|
|
||||||
ClientContext *intf_ = nullptr;
|
ClientContext *intf_ = nullptr;
|
||||||
std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
|
std::map<uint64_t, std::shared_ptr<DeviceClientContext>> display_config_map_;
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ enum OpCode {
|
|||||||
kIsRotatorSupportedFormat = 40,
|
kIsRotatorSupportedFormat = 40,
|
||||||
kControlQsyncCallback = 41,
|
kControlQsyncCallback = 41,
|
||||||
kSendTUIEvent = 42,
|
kSendTUIEvent = 42,
|
||||||
|
|
||||||
|
kDestroy = 0xFFFF, // Destroy sequence execution
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace DisplayConfig
|
} // namespace DisplayConfig
|
||||||
|
|||||||
Reference in New Issue
Block a user