[Local]:2nd step for blocking sequence
[apps/agl-service-windowmanager.git] / src / app.cpp
index 53a645e..6d3f1bb 100644 (file)
@@ -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) {