aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKazumasa Mitsunari <knimitz@witz-inc.co.jp>2018-05-15 11:37:39 +0900
committerKazumasa Mitsunari <knimitz@witz-inc.co.jp>2018-05-15 18:11:56 +0900
commite624fd6eb09dbe5729389437263e1e116e58fdbd (patch)
tree63e24c981eee276ee306e17417525ffd90610a93
parentd31270592190870d13c98460d351697350c67cc2 (diff)
[Local]:2nd step for blocking sequence
Change-Id: I267b9cdbc4a95b80a0b6cada688ed251e3093611 Signed-off-by: Kazumasa Mitsunari <knimitz@witz-inc.co.jp>
-rw-r--r--src/allocate_queue.hpp13
-rw-r--r--src/app.cpp102
-rw-r--r--src/app.hpp8
-rw-r--r--src/windowmanager-client.hpp7
4 files changed, 124 insertions, 6 deletions
diff --git a/src/allocate_queue.hpp b/src/allocate_queue.hpp
index 2a977b1..68b9008 100644
--- a/src/allocate_queue.hpp
+++ b/src/allocate_queue.hpp
@@ -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);
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) {
diff --git a/src/app.hpp b/src/app.hpp
index 5cfd78f..e7a9ae0 100644
--- a/src/app.hpp
+++ b/src/app.hpp
@@ -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();
diff --git a/src/windowmanager-client.hpp b/src/windowmanager-client.hpp
index 6aec0f3..bf0a9d7 100644
--- a/src/windowmanager-client.hpp
+++ b/src/windowmanager-client.hpp
@@ -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;
};
}