diff options
Diffstat (limited to 'src/app.cpp')
-rw-r--r-- | src/app.cpp | 102 |
1 files changed, 99 insertions, 3 deletions
diff --git a/src/app.cpp b/src/app.cpp index 53a645e..6d3f1bb 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -38,6 +38,8 @@ #include "windowmanager-client.hpp" #include "allocate_queue.hpp" +#define TIME_OUT 1000000UL /* 1s */ + namespace wm { /* DrawingArea name used by "{layout}.{area}" */ @@ -94,6 +96,16 @@ struct result<layer_map> load_layer_map(char const *filename) { } // namespace +static int App::processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata){ + HMI_NOTICE("Time out occurs because the client replys endDraw slow, so revert the request"); + reinterpret_cast<wm::App *>(userdata)->timerHandler(); +} + +void App::timerHandler(){ + // TODO: write reset process + unsigned seq = allocate_list.curerntSequenceNumber(); + allocate_list.resetRequest(seq); +} /** * App Impl @@ -336,15 +348,73 @@ void App::layout_commit() { this->display->flush(); } -void App::api_activate_surface(char const *drawing_name, char const *drawing_area, const reply_func &reply) { +void App::api_activate_surface(char const *appid, char const *drawing_name, char const *drawing_area, const reply_func &reply) { ST(); + /* + * Check Phase + */ + auto const &surface_id = this->lookup_id(drawing_name); + std::string role = std::string(drawing_name); + // newState = checkPolicy(role); + const WMClient* client = allocate_list.loopUpClient(appid); + if(client != nullptr){ + reply("client is not registered"); + return; + } + auto const &surface_id_tmp = client->surfaceID(role); + auto const &layer_id_tmp = client->layerID(); - if (!surface_id) { - reply("Surface does not exist"); + if(!surface_id_tmp && !layer_id_tmp){ + reply("invalid window manager client"); + HMI_DEBUG("appid:%s, requested_role:%s, surfaceID:%d in layer %d", + appid, role, surface_id_tmp, layer_id_tmp); + } + + /* + * Queueing Phase + */ + static unsigned ++sequence_number; + unsigned current = allocate_list.curerntSequenceNumber(); + + if(sequence_number != current){ + // Add request, then invoked after the previous task is finished + allocate_list.addAllocateRequest(client, sequence_number, tasks); + reply(nullptr); return; + } + + /* + * Do allocate tasks + */ + do { + // TODO: Tasks will be changed according to policy manager result + // do task(onTransition (activate)) + }while (!allocate_list.requestFinished()) + + // lm_.updateLayout(jobj); + // TODO: emit syncDraw with application + do{ + client->emit_syncdraw(role); + }while (!allocate_list.requestFinished()); + + if(timer_ev_src != nullptr){ + // firsttime set into sd_event + int ret = sd_event_add_time(afb_daemon_get_event_loop(), &timer_ev_src, + CLOCK_BOOTTIME, time(NULL) + TIME_OUT, 0, processTimerHandler, this); } + else{ + // update timer limitation after second time + sd_event_source_set_time(timer_ev_src, time(NULL) + TIME_OUT); + sd_event_source_set_enabled(timer_ev_src, SD_EVENT_ONESHOT); + } + + if (!surface_id) + { + reply("Surface does not exist"); + return; + } if (!this->controller->surface_exists(*surface_id)) { reply("Surface does not exist in controller!"); @@ -492,6 +562,7 @@ void App::api_activate_surface(char const *drawing_name, char const *drawing_are void App::api_deactivate_surface(char const *drawing_name, const reply_func &reply) { ST(); auto const &surface_id = this->lookup_id(drawing_name); + WMClient* client = allocate_list.lookupClient(appid); if (!surface_id) { reply ("Surface does not exist"); @@ -593,6 +664,31 @@ void App::check_flushdraw(int surface_id) { } void App::api_enddraw(char const *drawing_name) { + unsigned request_seq = allocate_list.searchAllocatingApp(appid); + unsigned current_seq = allocate_list.currentSequence(); + if(current_seq != request_seq){ + if(request_seq == 0){ + HMI_ERROR("[req_num:%d] You don't have Window Resource", request_seq); + } + else{ + HMI_ERROR("[req_num:%d] unknown error. Application may not obey the sequence manner. please call endDraw after syncDraw"); + } + return; + } + allocate_list.allocate(appid, request_seq); + if(allocate_list.endDrawFullfilled(request_seq)){ + // do task for endDraw + do{ + // visible application + }while(false); + do{ + // emit flush Draw + allocate_list.resetRequest(request_seq); + }while(false); + } + else{ + // wait other apps call endDraw + } for (unsigned i = 0, iend = this->pending_end_draw.size(); i < iend; i++) { auto n = this->lookup_name(this->pending_end_draw[i]); if (n && *n == drawing_name) { |