From d084d8753d6b48c930b99d73078370eac9f4204a Mon Sep 17 00:00:00 2001 From: zheng_wenlong Date: Fri, 2 Aug 2019 15:40:02 +0900 Subject: fix als2019 for 8.0.0 --- src/libwindowmanager.cpp | 263 ++++++++++++++++++++++++++++++++++++++++------- src/libwindowmanager.h | 26 ++++- 2 files changed, 246 insertions(+), 43 deletions(-) diff --git a/src/libwindowmanager.cpp b/src/libwindowmanager.cpp index 65684f1..915500b 100644 --- a/src/libwindowmanager.cpp +++ b/src/libwindowmanager.cpp @@ -76,6 +76,7 @@ class LibWindowmanager::Impl { int api_call(const char *verb, json_object *object, const std::function &onReply); void event(char const *et, json_object *object); + void event(char const *et); private: int runEventLoop(); @@ -94,6 +95,14 @@ private: std::string("syncDraw"), std::string("flushDraw"), std::string("screenUpdated"), + std::string("headlampOff"), + std::string("headlampOn"), + std::string("parkingBrakeOff"), + std::string("parkingBrakeOn"), + std::string("lightstatusBrakeOff"), + std::string("lightstatusBrakeOn"), + std::string("carStop"), + std::string("carRun"), std::string("error") }; @@ -153,7 +162,7 @@ void onEvent(void *closure, const char *event, afb_wsj1_msg *msg) { static_cast(closure)->event(event, val); } else { - HMI_ERROR("libwm", "Not found key \"data\""); + static_cast(closure)->event(event); } } @@ -212,7 +221,7 @@ int LibWindowmanager::Impl::init(int port, char const *token) { } /* get the default event loop */ - rc = sd_event_new(&this->loop); + rc = sd_event_default(&this->loop); if (rc < 0) { HMI_ERROR("libwm", "Connection to default event loop failed: %s", strerror(-rc)); @@ -384,6 +393,7 @@ int LibWindowmanager::Impl::endDraw(json_object *object) { int LibWindowmanager::Impl::getAreaList(ChangeAreaReq* req) { TRACE(); + json_object* obj = json_object_new_object(); int rc = -1; /* send the request */ int rc2 = @@ -394,7 +404,7 @@ int LibWindowmanager::Impl::getAreaList(ChangeAreaReq* req) { if (json_object_object_get_ex(j, g_kKeyResponse, &val)) { HMI_DEBUG("libwm", "responce:%s", json_object_get_string(val)); if (json_object_object_get_ex(val, "areas", &jarea)) { - int size = json_object_array_length(jarea); + int size = json_object_array_length(val); for(int i = 0; i < size; i++) { json_object* elem = json_object_array_get_idx(jarea, i); @@ -688,6 +698,14 @@ std::pair make_event_type(char const *et) { ET("syncdraw", SyncDraw); ET("flushdraw", FlushDraw); ET("screenUpdated", ScreenUpdated); + ET("headlampOff", HeadlampOff); + ET("headlampOn", HeadlampOn); + ET("parkingBrakeOff", ParkingBrakeOff); + ET("parkingBrakeOn", ParkingBrakeOn); + ET("lightstatusBrakeOff", LightstatusBrakeOff); + ET("lightstatusBrakeOn", LightstatusBrakeOn); + ET("carStop", CarStop); + ET("carRun", CarRun); ET("error", Error); #undef ET @@ -696,40 +714,6 @@ std::pair make_event_type(char const *et) { } } // namespace -#include -#include -class callsync { -private: - const std::function &onReply_; - std::condition_variable cond_; - std::mutex mutex_; - bool ok_; -private: - static void on_reply(void *closure, afb_wsj1_msg *msg) { - callsync *call = reinterpret_cast(closure); - call->onReply_(call->ok_ = afb_wsj1_msg_is_reply_ok(msg), afb_wsj1_msg_object_j(msg)); - call->cond_.notify_one(); - } -public: - callsync( - struct afb_wsj1 *wsj1, - const char *api, - const char *verb, - json_object *args, - const std::function &onReply - ) - : onReply_(onReply), cond_(), mutex_(), ok_(false) { - std::unique_lock ulock(mutex_); - int rc = afb_wsj1_call_j(wsj1, api, verb, args, on_reply, this); - if (rc < 0) - onReply(false, nullptr); - else - cond_.wait(ulock); - } - operator bool() const { return ok_; } - operator int() const { return int(ok_) - 1; } -}; - /// object will be json_object_put int LibWindowmanager::Impl::api_call( const char *verb, json_object *object, @@ -741,7 +725,51 @@ int LibWindowmanager::Impl::api_call( (0 == strcmp("GetDisplayInfo", verb)) || (0 == strcmp("getAreaList", verb)) || (0 == strcmp("GetAreaInfo", verb))) { - rc = callsync(this->wsj1, wmAPI, verb, object, onReply); + // We need to wrap the actual onReply call once in order to + // *look* like a normal functions pointer (std::functions<> + // with captures cannot convert to function pointers). + // Alternatively we could setup a local struct and use it as + // closure, but I think it is cleaner this way. + int call_rc = 0; + std::atomic returned{}; + returned.store(false, std::memory_order_relaxed); + std::function wrappedOnReply = + [&returned, &call_rc, &onReply](bool ok, json_object *j) { + TRACEN(wrappedOnReply); + call_rc = ok ? 0 : -EINVAL; + // We know it failed, but there may be an explanation in the + // json object. + { + TRACEN(onReply); + onReply(ok, j); + } + returned.store(true, std::memory_order_release); + }; + + // make the actual call, use wrappedOnReply as closure + rc = afb_wsj1_call_j( + this->wsj1, wmAPI, verb, object, + [](void *closure, afb_wsj1_msg *msg) { + TRACEN(callClosure); + auto *onReply = + reinterpret_cast *>( + closure); + (*onReply)(!(afb_wsj1_msg_is_reply_ok(msg) == 0), + afb_wsj1_msg_object_j(msg)); + }, + &wrappedOnReply); + + if (0 == rc) { + // We need to wait until "returned" got set, this is necessary + // if events get triggered by the call (and would be dispatched before + // the actual call-reply). + while (!returned.load(std::memory_order_consume)) { + sd_event_run(loop, 16); + } + + // return the actual API call result + rc = call_rc; + } } else { rc = afb_wsj1_call_j(this->wsj1, wmAPI, verb, object, _on_reply_static, this); @@ -820,12 +848,100 @@ void LibWindowmanager::Impl::setEventHandler(const WMHandler &wmh) } } + if(wmh.on_headlamp_off != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_HeadlampOff)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_headlamp_on != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_HeadlampOn)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_parking_brake_off != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_ParkingBrakeOff)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_parking_brake_on != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_ParkingBrakeOn)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_lightstatus_brake_off != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_LightstatusBrakeOff)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_lightstatus_brake_on != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_LightstatusBrakeOn)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_car_stop != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_CarStop)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + + if(wmh.on_car_run != nullptr) { + struct json_object* j = json_object_new_object(); + json_object_object_add(j, ev, json_object_new_int(Event_CarRun)); + + int ret = afb_wsj1_call_j(this->wsj1, wmAPI, "wm_subscribe", j, _on_reply_static, this); + if (0 > ret) { + HMI_ERROR("libwm", "Failed to subscribe event active"); + } + } + // Register this->_wmh.on_visible = wmh.on_visible; this->_wmh.on_active = wmh.on_active; this->_wmh.on_sync_draw = wmh.on_sync_draw; this->_wmh.on_flush_draw = wmh.on_flush_draw; this->_wmh.on_screen_updated = wmh.on_screen_updated; + this->_wmh.on_headlamp_off = wmh.on_headlamp_off; + this->_wmh.on_headlamp_on = wmh.on_headlamp_on; + this->_wmh.on_parking_brake_off = wmh.on_parking_brake_off; + this->_wmh.on_parking_brake_on = wmh.on_parking_brake_on; + this->_wmh.on_lightstatus_brake_off = wmh.on_lightstatus_brake_off; + this->_wmh.on_lightstatus_brake_on = wmh.on_lightstatus_brake_on; + this->_wmh.on_car_stop = wmh.on_car_stop; + this->_wmh.on_car_run = wmh.on_car_run; } void LibWindowmanager::Impl::event(char const *et, json_object *object) { @@ -923,6 +1039,65 @@ void LibWindowmanager::Impl::event(char const *et, json_object *object) { } } +void LibWindowmanager::Impl::event(char const *et) { + TRACE(); + auto oet = make_event_type(et); + if (!oet.first) { + HMI_ERROR("libwm", "Unknown event type string '%s'", et); + return; + } + + switch(oet.second) { + case Event_HeadlampOff: + if(this->_wmh.on_headlamp_off) { + return this->_wmh.on_headlamp_off(nullptr); + } + break; + case Event_HeadlampOn: + if(this->_wmh.on_headlamp_on) { + return this->_wmh.on_headlamp_on(nullptr); + } + break; + case Event_ParkingBrakeOff: + if(this->_wmh.on_parking_brake_off) { + return this->_wmh.on_parking_brake_off(nullptr); + } + break; + case Event_ParkingBrakeOn: + if(this->_wmh.on_parking_brake_on) { + return this->_wmh.on_parking_brake_on(nullptr); + } + break; + case Event_LightstatusBrakeOff: + if(this->_wmh.on_lightstatus_brake_off) { + return this->_wmh.on_lightstatus_brake_off(nullptr); + } + break; + case Event_LightstatusBrakeOn: + if(this->_wmh.on_lightstatus_brake_on) { + return this->_wmh.on_lightstatus_brake_on(nullptr); + } + break; + case Event_CarStop: + if(this->_wmh.on_car_stop) { + return this->_wmh.on_car_stop(nullptr); + } + break; + case Event_CarRun: + if(this->_wmh.on_car_run) { + return this->_wmh.on_car_run(nullptr); + } + break; + default : + break; + } + + auto i = this->handlers.find(oet.second); + if (i != this->handlers.end()) { + i->second(nullptr); + } +} + static void *event_loop_run(void *args){ struct sd_event* loop = (struct sd_event*)(args); for(;;) @@ -1018,7 +1193,7 @@ int LibWindowmanager::deactivateWindow(json_object *object) { int LibWindowmanager::deactivateWindow(const char* role) { json_object* object = json_object_new_object(); json_object_object_add(object, kKeyDrawingName, json_object_new_string(role)); - return this->d->deactivateWindow(object); + return this->d->deactivateWindow(nullptr); } // This API is deprecated, please use new API @@ -1134,5 +1309,13 @@ WMHandler::WMHandler() on_active(nullptr), on_sync_draw(nullptr), on_flush_draw(nullptr), - on_screen_updated(nullptr) + on_screen_updated(nullptr), + on_headlamp_off(nullptr), + on_headlamp_on(nullptr), + on_parking_brake_off(nullptr), + on_parking_brake_on(nullptr), + on_lightstatus_brake_off(nullptr), + on_lightstatus_brake_on(nullptr), + on_car_stop(nullptr), + on_car_run(nullptr) {} diff --git a/src/libwindowmanager.h b/src/libwindowmanager.h index c9da4ca..1b2bfae 100644 --- a/src/libwindowmanager.h +++ b/src/libwindowmanager.h @@ -62,17 +62,26 @@ class WMHandler { using sync_draw_handler = std::function; using flush_draw_handler= std::function; using screen_updated_handler = std::function&)>; + using car_event_handler= std::function; visible_handler on_visible; active_handler on_active; sync_draw_handler on_sync_draw; flush_draw_handler on_flush_draw; screen_updated_handler on_screen_updated; + car_event_handler on_headlamp_off; + car_event_handler on_headlamp_on; + car_event_handler on_parking_brake_off; + car_event_handler on_parking_brake_on; + car_event_handler on_lightstatus_brake_off; + car_event_handler on_lightstatus_brake_on; + car_event_handler on_car_stop; + car_event_handler on_car_run; }; class ChangeAreaReq { public: - ChangeAreaReq() {} + ChangeAreaReq() : _save(false) {} ~ChangeAreaReq() = default; void setAreaReq(const std::unordered_map &area_req) { this->_area_req = area_req; } void addAreaReq(const std::string& area_name, const Rect& area_size) { this->_area_req[area_name] = area_size; } @@ -80,11 +89,10 @@ class ChangeAreaReq { bool getSave() const { return this->_save; } void addAreaList(const std::string& area_name, const Rect& area_size){ this->_area_list[area_name] = area_size; } const std::unordered_map& getReq() const { return this->_area_req; } - const std::unordered_map& getList() const { return this->_area_list; } private: std::unordered_map _area_req; std::unordered_map _area_list; - bool _save = false; + bool _save; }; class LibWindowmanager { @@ -123,6 +131,18 @@ public: Event_ScreenUpdated, + Event_HeadlampOff, + Event_HeadlampOn, + + Event_ParkingBrakeOff, + Event_ParkingBrakeOn, + + Event_LightstatusBrakeOff, + Event_LightstatusBrakeOn, + + Event_CarStop, + Event_CarRun, + Event_Error, Event_Val_Max = Event_Error -- cgit 1.2.3-korg