aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.cpp69
-rw-r--r--src/request.hpp1
-rw-r--r--src/util.cpp17
-rw-r--r--src/util.hpp14
-rw-r--r--src/window_manager.cpp97
-rw-r--r--src/window_manager.hpp2
-rw-r--r--src/wm_client.cpp3
-rw-r--r--src/wm_client.hpp4
-rw-r--r--src/wm_layer.cpp17
-rw-r--r--src/wm_layer.hpp2
-rw-r--r--src/wm_layer_control.cpp45
-rw-r--r--src/wm_layer_control.hpp4
12 files changed, 269 insertions, 6 deletions
diff --git a/src/main.cpp b/src/main.cpp
index cc4386c..6483655 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -413,6 +413,73 @@ void windowmanager_getareainfo_thunk(afb_req_t req) noexcept
}
}
+void windowmanager_get_area_list(afb_req_t req) noexcept
+{
+ std::lock_guard<std::mutex> guard(binding_m);
+ json_object* ret = g_afb_instance->wmgr.api_get_area_list();
+ afb_req_success(req, ret, nullptr);
+}
+
+void windowmanager_change_area_size(afb_req_t req) noexcept
+{
+ std::lock_guard<std::mutex> guard(binding_m);
+ if (g_afb_instance == nullptr)
+ {
+ afb_req_fail(req, "failed", "Binding not initialized, did the compositor die?");
+ return;
+ }
+
+ char* appid = afb_req_get_application_id(req);
+ if(appid)
+ {
+ ChangeAreaReq change_req;
+ change_req.appname = appid;
+ change_req.save = false;
+ json_object *jreq = afb_req_json(req);
+ json_object *jsave, *jareas;
+ HMI_INFO("json_check, %s", json_object_get_string(jreq));
+ if(json_object_object_get_ex(jreq, "save", &jsave))
+ {
+ change_req.save = json_object_get_boolean(jsave);
+ }
+ if (json_object_object_get_ex(jreq, "areas", &jareas))
+ {
+ int size = json_object_array_length(jareas);
+ for(int i = 0; i < size; i++)
+ {
+ json_object* elem = json_object_array_get_idx(jareas, i);
+ struct rect rect;
+ std::string name = jh::getStringFromJson(elem, "name");
+ json_object* jrect;
+ if(json_object_object_get_ex(elem, "rect", &jrect))
+ {
+ rect.x = jh::getIntFromJson(jrect, "x");
+ rect.y = jh::getIntFromJson(jrect, "y");
+ rect.w = jh::getIntFromJson(jrect, "w");
+ rect.h = jh::getIntFromJson(jrect, "h");
+ }
+ else
+ {
+ HMI_ERROR("bad request @area name :%s", name.c_str());
+ afb_req_fail(req, "failed", "bad request");
+ return;
+ }
+ change_req.area_req[name] = rect;
+ }
+ if(change_req.area_req.size() != 0)
+ {
+ g_afb_instance->wmgr.api_change_area_size(change_req);
+ }
+ afb_req_success(req, nullptr, nullptr);
+ }
+ free(appid);
+ }
+ else
+ {
+ afb_req_fail(req, "failed", nullptr);
+ }
+}
+
void windowmanager_wm_subscribe(afb_req_t req) noexcept
{
std::lock_guard<std::mutex> guard(binding_m);
@@ -498,6 +565,8 @@ const afb_verb_t windowmanager_verbs[] = {
{ .verb = "endDraw", .callback = windowmanager_enddraw },
{ .verb = "getDisplayInfo", .callback = windowmanager_getdisplayinfo_thunk },
{ .verb = "getAreaInfo", .callback = windowmanager_getareainfo_thunk },
+ { .verb = "changeAreaSize", .callback = windowmanager_change_area_size },
+ { .verb = "getAreaList", .callback = windowmanager_get_area_list },
{ .verb = "wm_subscribe", .callback = windowmanager_wm_subscribe },
{ .verb = "ping", .callback = windowmanager_ping },
{ .verb = "debug_terminate", .callback = windowmanager_debug_terminate },
diff --git a/src/request.hpp b/src/request.hpp
index 073dd27..0f0e199 100644
--- a/src/request.hpp
+++ b/src/request.hpp
@@ -30,6 +30,7 @@ enum Task
{
TASK_ALLOCATE,
TASK_RELEASE,
+ TASK_CHANGE_AREA,
TASK_INVALID
};
diff --git a/src/util.cpp b/src/util.cpp
index f26a4a1..0591d55 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -176,3 +176,20 @@ std::string get_file_path(const char *file_name, const char *root_path)
HMI_INFO("Using %s", path.c_str());
return path;
}
+
+void ChangeAreaReq::dump()
+{
+ DUMP("=== change request dump ===");
+ DUMP("request from : %s", this->appname.c_str());
+ DUMP("save : %s", this->save ? "true" : "false");
+ for(const auto& req : this->area_req)
+ {
+ DUMP("area change req : %s", req.first.c_str());
+ DUMP(" x:%d y:%d w:%d h:%d",req.second.x, req.second.y, req.second.w, req.second.h);
+ }
+ for(const auto& req : this->update_app2area)
+ {
+ DUMP("update change app : %s, area:%s", req.first.c_str(), req.second.c_str());
+ }
+ DUMP("======== dump end =========");
+}
diff --git a/src/util.hpp b/src/util.hpp
index 36e556c..9540772 100644
--- a/src/util.hpp
+++ b/src/util.hpp
@@ -20,6 +20,7 @@
#include <functional>
#include <thread>
+#include <unordered_map>
#include <sys/poll.h>
#include <string.h>
@@ -121,4 +122,15 @@ class rectangle
// Configuration file path helper
std::string get_file_path(const char *file_name, const char *root_path = NULL);
-#endif // !WM_UTIL_HPP
+typedef struct ChangeAreaReq {
+ std::string appname;
+ std::unordered_map<std::string, struct rect> area_req;
+ bool save;
+ std::unordered_map<std::string, std::string> update_app2area;
+ ChangeAreaReq() = default;
+ ~ChangeAreaReq() = default;
+ ChangeAreaReq(const ChangeAreaReq& val) = default;
+ void dump();
+} ChangeAreaReq;
+
+#endif // WM_UTIL_HPP
diff --git a/src/window_manager.cpp b/src/window_manager.cpp
index 288c967..22f1e22 100644
--- a/src/window_manager.cpp
+++ b/src/window_manager.cpp
@@ -28,6 +28,7 @@ extern "C"
using std::string;
using std::vector;
+using std::unordered_map;
namespace wm
{
@@ -69,6 +70,9 @@ static const vector<string> kListEventName{
static sd_event_source *g_timer_ev_src = nullptr;
static AppList g_app_list;
static WindowManager *g_context;
+static vector<string> white_list_area_size_change = {
+ "homescreen", "settings"
+};
namespace
{
@@ -380,6 +384,99 @@ void WindowManager::api_enddraw(char const *appid, char const *drawing_name)
}
}
+json_object* WindowManager::api_get_area_list()
+{
+ json_object* ret = json_object_new_object();
+ json_object* jarray = json_object_new_array();
+ unordered_map<string, struct rect> area2size = this->lc->getAreaList();
+ for(const auto& area : area2size)
+ {
+ json_object* j = json_object_new_object();
+ json_object_object_add(j, "name", json_object_new_string(area.first.c_str()));
+ json_object* jrect = json_object_new_object();
+ json_object_object_add(jrect, "x", json_object_new_int(area.second.x));
+ json_object_object_add(jrect, "y", json_object_new_int(area.second.y));
+ json_object_object_add(jrect, "w", json_object_new_int(area.second.w));
+ json_object_object_add(jrect, "h", json_object_new_int(area.second.h));
+ json_object_object_add(j, "rect", jrect);
+ json_object_array_add(jarray, j);
+ }
+ json_object_object_add(ret, "areas", jarray);
+ HMI_DEBUG("area_list: %s", json_object_get_string(ret));
+ return ret;
+}
+
+void WindowManager::api_change_area_size(ChangeAreaReq &areas)
+{
+ // Error check
+ areas.dump();
+ auto client = g_app_list.lookUpClient(areas.appname);
+ WMError ret;
+ if(client == nullptr)
+ {
+ HMI_ERROR("Call register your role with setRole or requestSurface");
+ return;
+ }
+ if(std::find(white_list_area_size_change.begin(),
+ white_list_area_size_change.end(), client->role()) == white_list_area_size_change.end())
+ {
+ HMI_ERROR("Application %s which has the role %s is not allowed to change area size", client->appID().c_str(), client->role().c_str());
+ return;
+ }
+
+ // Update
+ ret = this->lc->updateAreaList(areas);
+ if(ret != WMError::SUCCESS)
+ {
+ HMI_ERROR("%d : %s", ret, errorDescription(ret));
+ return;
+ }
+ ret = this->lc->getUpdateAreaList(&areas);
+ areas.dump();
+ if(ret != WMError::SUCCESS)
+ {
+ HMI_ERROR("%d : %s", ret, errorDescription(ret));
+ return;
+ }
+
+ // Create Action
+ unsigned req_num;
+ bool found = false;
+ ret = this->setRequest(client->appID(), client->role(), "-", Task::TASK_CHANGE_AREA, &req_num); // area is null
+ if(ret != WMError::SUCCESS)
+ {
+ HMI_SEQ_ERROR(req_num, "%d : %s", ret, errorDescription(ret));
+ return;
+ }
+ for(const auto &update: areas.update_app2area)
+ {
+ // create action
+ auto client = g_app_list.lookUpClient(update.first);
+ if(client == nullptr)
+ {
+ HMI_SEQ_ERROR(req_num, "%s : %s", update.first.c_str(), errorDescription(ret));
+ g_app_list.removeRequest(req_num);
+ this->processNextRequest();
+ return;
+ }
+ ret = g_app_list.setAction(req_num, client, client->role(), update.second, TaskVisible::VISIBLE);
+ if(ret != WMError::SUCCESS)
+ {
+ HMI_SEQ_ERROR(req_num, "Failed to set request");
+ return;
+ }
+ }
+ HMI_SEQ_INFO(req_num, "Area change request");
+ g_app_list.reqDump();
+
+ // Request change size to applications
+ for(const auto &action : g_app_list.getActions(req_num, &found))
+ {
+ struct rect r = this->lc->getAreaSize(action.area);
+ action.client->emitSyncDraw(action.area, r);
+ }
+}
+
bool WindowManager::api_subscribe(afb_req_t req, EventType event_id)
{
bool ret = false;
diff --git a/src/window_manager.hpp b/src/window_manager.hpp
index e9caf7e..eac6576 100644
--- a/src/window_manager.hpp
+++ b/src/window_manager.hpp
@@ -176,6 +176,8 @@ class WindowManager
void api_activate_window(char const *appid, char const *role, char const *drawing_area, const reply_func &reply);
void api_deactivate_window(char const *appid, char const *role, const reply_func &reply);
void api_enddraw(char const *appid, char const *role);
+ json_object* api_get_area_list();
+ void api_change_area_size(ChangeAreaReq &areas);
bool api_subscribe(afb_req_t req, EventType event_id);
result<json_object *> api_get_display_info();
result<json_object *> api_get_area_info(char const *role);
diff --git a/src/wm_client.cpp b/src/wm_client.cpp
index fdf7919..ff08a00 100644
--- a/src/wm_client.cpp
+++ b/src/wm_client.cpp
@@ -197,7 +197,6 @@ void WMClient::emitVisible(bool visible)
}
if(allow_send)
{
- this->area = area;
json_object* j = json_object_new_object();
json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
@@ -231,7 +230,6 @@ void WMClient::emitActive(bool active)
}
if(allow_send)
{
- this->area = area;
json_object* j = json_object_new_object();
json_object_object_add(j, kKeyRole, json_object_new_string(this->role().c_str()));
json_object_object_add(j, kKeyDrawingName, json_object_new_string(this->role().c_str()));
@@ -256,7 +254,6 @@ void WMClient::emitSyncDraw(const string& area, struct rect& r)
HMI_NOTICE("trace");
if(afb_event_is_valid(this->evname2afb_event[kSyncDraw]))
{
- this->area = area;
json_object *j_rect = json_object_new_object();
json_object_object_add(j_rect, kKeyX, json_object_new_int(r.x));
json_object_object_add(j_rect, kKeyY, json_object_new_int(r.y));
diff --git a/src/wm_client.hpp b/src/wm_client.hpp
index 99ae499..3ffa786 100644
--- a/src/wm_client.hpp
+++ b/src/wm_client.hpp
@@ -48,6 +48,8 @@ class WMClient
unsigned layerID() const;
unsigned surfaceID() const;
void registerSurface(unsigned surface);
+ std::string area() const {return this->app_area;};
+ void setArea(const std::string area) {this->app_area = area;}
WMError addSurface(unsigned surface);
bool isSourceSizeSet();
void setSurfaceSizeCorrectly();
@@ -67,7 +69,7 @@ class WMClient
unsigned layer;
bool is_source_set;
std::string main_role;
- std::string area;
+ std::string app_area;
unsigned surface; // currently, main application has only one surface.
//std::vector<std::string> role_list;
std::unordered_map<std::string, unsigned> role2surface;
diff --git a/src/wm_layer.cpp b/src/wm_layer.cpp
index 294e356..66fb0a2 100644
--- a/src/wm_layer.cpp
+++ b/src/wm_layer.cpp
@@ -36,6 +36,11 @@ LayerState::LayerState()
area2appid()
{}
+const unordered_map<string, string> LayerState::getCurrentState()
+{
+ return this->area2appid;
+}
+
const vector<unsigned> LayerState::getIviIdList()
{
return this->render_order;
@@ -183,6 +188,18 @@ void WMLayer::attachAppToArea(const string& app, const string& area)
this->tmp_state.attachAppToArea(app, area);
}
+string WMLayer::attachedApp(const string& area)
+{
+ string ret;
+ auto list = this->state.getCurrentState();
+ auto app = list.find(area);
+ if(app != list.end())
+ {
+ ret = app->second;
+ }
+ return ret;
+}
+
void WMLayer::appendArea(const string& area)
{
this->area_list.push_back(area);
diff --git a/src/wm_layer.hpp b/src/wm_layer.hpp
index 83a5e74..97cf8a8 100644
--- a/src/wm_layer.hpp
+++ b/src/wm_layer.hpp
@@ -34,6 +34,7 @@ class LayerState
public:
LayerState();
~LayerState() = default;
+ const std::unordered_map<std::string, std::string> getCurrentState();
const std::vector<unsigned> getIviIdList();
void addLayer(unsigned layer);
void removeLayer(unsigned layer);
@@ -69,6 +70,7 @@ class WMLayer
void addLayerToState(unsigned layer);
void removeLayerFromState(unsigned layer);
void attachAppToArea(const std::string& app, const std::string& area);
+ std::string attachedApp(const std::string& area);
void update();
void undo();
diff --git a/src/wm_layer_control.cpp b/src/wm_layer_control.cpp
index 6c9aa6c..28d409f 100644
--- a/src/wm_layer_control.cpp
+++ b/src/wm_layer_control.cpp
@@ -394,7 +394,7 @@ WMError LayerControl::layoutChange(const WMAction& action)
unsigned surface = action.client->surfaceID();
auto rect = this->getAreaSize(action.area);
- HMI_DEBUG("Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
+ HMI_SEQ_INFO(action.req_num, "Set layout %d, %d, %d, %d",rect.x, rect.y, rect.w, rect.h);
// Sometimes, ivi_wm_surface_size signal doesn't reach window manager,
// then, Window Manager set set source size = 0.
@@ -413,6 +413,7 @@ WMError LayerControl::layoutChange(const WMAction& action)
ilm_surfaceSetDestinationRectangle(surface, rect.x, rect.y, rect.w, rect.h);
ilm_commitChanges();
+ action.client->setArea(action.area);
for(auto &wm_layer: this->wm_layers)
{
// Store the state who is assigned to the area
@@ -450,6 +451,48 @@ WMError LayerControl::visibilityChange(const WMAction& action)
return ret;
}
+WMError LayerControl::updateAreaList(const ChangeAreaReq& req)
+{
+ // error check
+ for(const auto& elem : req.area_req)
+ {
+ if(this->area2size.find(elem.first) == this->area2size.end())
+ {
+ HMI_ERROR("requested area %s is not registered in area list", elem.first.c_str());
+ return WMError::NOT_REGISTERED;
+ }
+ }
+ // update list
+ for(const auto& elem : req.area_req)
+ {
+ this->area2size[elem.first] = elem.second;
+ }
+ if(req.save)
+ {
+ HMI_NOTICE("Not implemented");
+ // TODO
+ }
+ return WMError::SUCCESS;
+}
+
+WMError LayerControl::getUpdateAreaList(ChangeAreaReq *req)
+{
+ for(const auto& wm_layer : this->wm_layers)
+ {
+ // get area name and compare it with elem
+ for(const auto& area : req->area_req)
+ {
+ string app = wm_layer->attachedApp(area.first);
+ if(!app.empty())
+ {
+ HMI_INFO("app %s changes area %s", app.c_str(), area.first.c_str());
+ req->update_app2area[app] = area.first;
+ }
+ }
+ }
+ return WMError::SUCCESS;
+}
+
void LayerControl::appTerminated(const shared_ptr<WMClient> client)
{
for(auto& l : this->wm_layers)
diff --git a/src/wm_layer_control.hpp b/src/wm_layer_control.hpp
index 25d71fd..68acd66 100644
--- a/src/wm_layer_control.hpp
+++ b/src/wm_layer_control.hpp
@@ -76,6 +76,10 @@ class LayerControl
void undoUpdate();
WMError layoutChange(const WMAction& action);
WMError visibilityChange(const WMAction &action);
+ const std::unordered_map<std::string, struct rect>& getAreaList() {return this->area2size;}
+ WMError updateAreaList(const ChangeAreaReq& req);
+ WMError getUpdateAreaList(ChangeAreaReq* req);
+ WMError changeAreaSize(std::shared_ptr<WMClient> client, const std::string& area);
void appTerminated(const std::shared_ptr<WMClient> client);
// Don't use this function.