[Local]:2nd step for blocking sequence
authorKazumasa Mitsunari <knimitz@witz-inc.co.jp>
Tue, 15 May 2018 02:37:39 +0000 (11:37 +0900)
committerKazumasa Mitsunari <knimitz@witz-inc.co.jp>
Tue, 15 May 2018 09:11:56 +0000 (18:11 +0900)
Change-Id: I267b9cdbc4a95b80a0b6cada688ed251e3093611
Signed-off-by: Kazumasa Mitsunari <knimitz@witz-inc.co.jp>
src/allocate_queue.hpp
src/app.cpp
src/app.hpp
src/windowmanager-client.hpp

index 2a977b1..68b9008 100644 (file)
@@ -27,7 +27,20 @@ public:
     ~AllocateRequestList();
     AllocateRequestList(const AllocateRequestList &obj) = delete;
 
+    typedef std::function<void(const WMClient *)> onEndDraw;
+    typedef std::function<void(const WMClient *)> onReverted;
+
+    // Client Database Interface
     void addClient(WMClient* client);
+    WMClient* loopUpClient(const char* appid);
+
+    // Request Interface
+    bool hasRequestingApp(const char *appid);
+    void revertRequestingState();
+    void removeAllRequesting();
+    bool addRequest(WMClient *, onEndDraw, onReverted);
+
+    //void revertRequestingState();//???
 
     /* bool queue(int request_num);
     bool pushTop(int request_num);
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) {
index 5cfd78f..e7a9ae0 100644 (file)
@@ -203,7 +203,7 @@ struct App {
 
    result<int> api_request_surface(char const *drawing_name, char const *appid, int flag);
    char const *api_request_surface(char const *drawing_name, char const *ivi_id);
-   void api_activate_surface(char const *drawing_name, char const *drawing_area, const reply_func &reply);
+   void api_activate_surface(char const *appid, char const *drawing_name, char const *drawing_area, const reply_func &reply);
    void api_deactivate_surface(char const *drawing_name, const reply_func &reply);
    void api_enddraw(char const *drawing_name);
    result<json_object *> api_get_display_info();
@@ -216,7 +216,10 @@ struct App {
    void surface_created(uint32_t surface_id);
    void surface_removed(uint32_t surface_id);
 
-private:
+   // Do not use this function
+   static int processTimerHandler(sd_event_source *s, uint64_t usec, void *userdata);
+
+ private:
    optional<int> lookup_id(char const *name);
    optional<std::string> lookup_name(int id);
 
@@ -226,6 +229,7 @@ private:
    void check_flushdraw(int surface_id);
 
    int init_layers();
+   void timerHandler();
 
    void surface_set_layout(int surface_id, optional<int> sub_surface_id = nullopt);
    void layout_commit();
index 6aec0f3..bf0a9d7 100644 (file)
@@ -33,14 +33,19 @@ public:
     WMClient(const char* appid, unsigned layerID, unsigned surfaceID, const char* role);
     virtual ~WMClient();
     //WMClient::WMClient(const WMClient &obj);
+    const vector<optional<unsigned>> surfaceIDList();
+    optional<unsigned> surfaceID(role);
+    bool hasRequestingApp(appid);
+    void createNewRequest(int count, const vector<std::string> &applist);
 
-private:
+  private:
     unsigned layer;
     std::vector<unsigned> surfaces;
     std::string appid;
     std::vector<std::string> roles;
     std::unordered_map<std::string, struct afb_event> event_list;
     unsigned request_number;
+    std::vector<Task *> requestingTask;
 };
 }