Support using recent window position 29/289229/9
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 3 Mar 2023 03:32:59 +0000 (03:32 +0000)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 7 Mar 2023 09:34:25 +0000 (09:34 +0000)
When the application is started with the setting window position option,
the application core saves the position information to the file.
And then, the application will use the recent window poisition when it is
restarted.

Change-Id: I3e9a5c3760a2fd56e66db135d14d6e73027ed1ba
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
tizen-cpp/app-core-ui-cpp/app_core_ui_base.cc
tizen-cpp/app-core-ui-cpp/window_position_private.cc [new file with mode: 0644]
tizen-cpp/app-core-ui-cpp/window_position_private.hh [new file with mode: 0644]

index cfc6e6c..e7f8c0e 100644 (file)
@@ -32,6 +32,7 @@
 #include <memory>
 #include <string>
 #include <thread>
+#include <utility>
 
 #include "app-core-cpp/app_core_base.hh"
 #include "app-core-ui-cpp/api/app_core_ui_base.h"
@@ -39,6 +40,7 @@
 #include "app-core-ui-cpp/app_core_ui_delegator_private.hh"
 #include "app-core-ui-cpp/app_core_ui_plugin_private.hh"
 #include "app-core-ui-cpp/wayland_handler_private.hh"
+#include "app-core-ui-cpp/window_position_private.hh"
 #include "common/ecore_handler.hh"
 #include "common/glib_private.hh"
 #include "common/log_private.hh"
@@ -46,6 +48,8 @@
 namespace tizen_cpp {
 
 constexpr const char K_SERVICE_THREAD[] = "__K_SERVICE_THREAD";
+constexpr const char K_HINT_RECENT_SCREEN_POSITION[] =
+    "__K_HINT_RECENT_SCREEN_POSITION";
 
 void SetComm(const std::string& name) {
   pid_t tid = syscall(__NR_gettid);
@@ -69,7 +73,8 @@ class AppCoreUiBase::Impl {
       : parent_(parent),
         hint_(hint),
         handler_(std::make_shared<EcoreHandler>(parent)),
-        wl_handler_(new WaylandHandler()) {
+        wl_handler_(new WaylandHandler()),
+        wp_manager_(new WindowPositionManager()) {
   }
 
  private:
@@ -105,24 +110,6 @@ class AppCoreUiBase::Impl {
     }
   };
 
-  class WindowPosition {
-   public:
-    WindowPosition(int x, int y, int w, int h)
-      : x_(x), y_(y), w_(w), h_(h){
-    }
-
-    int GetPositionX() const { return x_; }
-    int GetPositionY() const { return y_; }
-    int GetScreenWidth() const { return w_; }
-    int GetScreenHeight() const { return h_; }
-
-   private:
-    int x_;
-    int y_;
-    int w_;
-    int h_;
-  };
-
   void ExitFromSuspend();
   void PrepareToSuspend();
   void DoStart(tizen_base::Bundle b);
@@ -143,6 +130,9 @@ class AppCoreUiBase::Impl {
   void PluginInit(int argc, char** argv);
   void PluginFini();
   void SetWindowPosition(const tizen_base::Bundle& b);
+  void SetWindowPosition();
+  void SetWindow(unsigned int wid);
+  Ecore_Wl2_Window* GetWindow() const;
   void Run(int argc, char** argv);
   void Exit();
 
@@ -164,6 +154,8 @@ class AppCoreUiBase::Impl {
   GMainContext* context_ = nullptr;
   std::thread thread_;
   std::unique_ptr<WindowPosition> position_;
+  Ecore_Wl2_Window* window_ = nullptr;
+  std::unique_ptr<WindowPositionManager> wp_manager_;
 };
 
 AppCoreUiBase::AppCoreUiBase(unsigned int hint)
@@ -190,6 +182,7 @@ bool AppCoreUiBase::Impl::AddWin(unsigned int win, unsigned int surf) {
     return false;
   }
 
+  SetWindow(win);
   winnode_list_.emplace_back(new WinNode(win, surf));
   return true;
 }
@@ -201,6 +194,7 @@ bool AppCoreUiBase::Impl::DeleteWin(unsigned int win) {
     return false;
   }
 
+  SetWindow(0);
   winnode_list_.remove_if(
       [win](std::shared_ptr<struct AppCoreUiBase::Impl::WinNode> node) {
         return node->win_ == win;
@@ -222,6 +216,10 @@ bool AppCoreUiBase::Impl::UpdateWin(unsigned int win, unsigned int surf,
   if (vis != VT_NONE)
     node->vis_ = vis;
 
+  if (GetWindow() == nullptr)
+    SetWindow(win);
+
+  SetWindowPosition();
   return true;
 }
 
@@ -417,24 +415,72 @@ void AppCoreUiBase::Impl::PluginFini() {
 }
 
 void AppCoreUiBase::Impl::SetWindowPosition(const tizen_base::Bundle& b) {
-  std::string x_str = b.GetString(AUL_K_HINT_SCREEN_POS_X);
-  if (x_str.empty())
+  position_ = wp_manager_->ReadFromBundle(b);
+  if (position_) {
+    _D("x: %d, y: %d, w: %d, h: %d",
+        position_->GetPositionX(), position_->GetPositionY(),
+        position_->GetScreenWidth(), position_->GetScreenHeight());
+  }
+
+  auto recent_screen_position = b.GetString(K_HINT_RECENT_SCREEN_POSITION);
+  if (!recent_screen_position.empty()) {
+    auto position = wp_manager_->ReadFromFile();
+    if (position) {
+      _D("x: %d, y: %d, w: %d, h: %d",
+          position->GetPositionX(), position->GetPositionY(),
+          position->GetScreenWidth(), position->GetScreenHeight());
+      position_ = std::move(position);
+    } else {
+      _D("There is no window position");
+    }
+  }
+
+  if (position_)
+    wp_manager_->WriteToFile(position_);
+}
+
+void AppCoreUiBase::Impl::SetWindowPosition() {
+  if (!position_)
     return;
 
-  std::string y_str = b.GetString(AUL_K_HINT_SCREEN_POS_Y);
-  if (y_str.empty())
+  if (GetWindow() == nullptr) {
+    _E("window is nullptr");
     return;
+  }
+
+  int x = 0;
+  int y = 0;
+  int w = 0;
+  int h = 0;
+  ecore_wl2_window_geometry_get(GetWindow(), &x, &y, &w, &h);
+
+  _W("x: %d, y: %d, w: %d, h: %d", w, y, w, h);
+  if (position_->GetPositionX() != x ||
+      position_->GetPositionY() != y ||
+      position_->GetScreenWidth() != w ||
+      position_->GetScreenHeight() != h) {
+    position_.reset(new WindowPosition(x, y, w, h));
+    wp_manager_->WriteToFile(position_);
+  }
+}
 
-  std::string w_str = b.GetString(AUL_K_HINT_SCREEN_WIDTH);
-  if (w_str.empty())
+void AppCoreUiBase::Impl::SetWindow(unsigned int wid) {
+  if (wid == 0) {
+    window_ = nullptr;
     return;
+  }
 
-  std::string h_str = b.GetString(AUL_K_HINT_SCREEN_HEIGHT);
-  if (h_str.empty())
+  window_ = ecore_wl2_window_find(wid);
+  if (window_ == nullptr) {
+    _E("ecore_wl2_window_find() is failed. wid(%u)", wid);
     return;
+  }
+
+  _D("wid(%u), window(%p)", wid, window_);
+}
 
-  position_ = std::make_unique<AppCoreUiBase::Impl::WindowPosition>(
-      std::stoi(x_str), std::stoi(y_str), std::stoi(w_str), std::stoi(h_str));
+Ecore_Wl2_Window* AppCoreUiBase::Impl::GetWindow() const {
+  return window_;
 }
 
 void AppCoreUiBase::DoRun(int argc, char** argv) {
@@ -481,7 +527,7 @@ void AppCoreUiBase::DoExit() {
 void AppCoreUiBase::Impl::Run(int argc, char** argv) {
   if (hint_ & HINT_DUAL_THREAD) {
     // For the loader case
-    while (ecore_shutdown() != 0);
+    while (ecore_shutdown() != 0) {}
 
     service_ = parent_->CreateTask();
     context_ = g_main_context_new();
@@ -816,8 +862,9 @@ void AppCoreUiBase::OnShow(int type, void* event) {
   else
     impl_->UpdateWin(win, surf, Impl::VT_NONE);
 
-  if (surf != 0)
+  if (surf != 0) {
     GroupAdd();
+  }
 }
 
 bool AppCoreUiBase::Impl::CheckVisible() {
diff --git a/tizen-cpp/app-core-ui-cpp/window_position_private.cc b/tizen-cpp/app-core-ui-cpp/window_position_private.cc
new file mode 100644 (file)
index 0000000..ffdb5ac
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "app-core-ui-cpp/window_position_private.hh"
+
+#include <aul.h>
+#include <bundle_cpp.h>
+#include <unistd.h>
+
+#include <fstream>
+#include <sstream>
+#include <string>
+
+#include "common/log_private.hh"
+
+namespace tizen_cpp {
+namespace {
+
+constexpr const char PATH_AUL[] = "/run/aul/apps/";
+constexpr uid_t REGULAR_UID_MIN = 5000;
+
+std::string WindowPositionToRaw(
+    const std::unique_ptr<WindowPosition>& win_pos) {
+  tizen_base::Bundle b {
+    { AUL_K_HINT_SCREEN_POS_X, std::to_string(win_pos->GetPositionX()) },
+    { AUL_K_HINT_SCREEN_POS_Y, std::to_string(win_pos->GetPositionY()) },
+    { AUL_K_HINT_SCREEN_WIDTH, std::to_string(win_pos->GetScreenWidth()) },
+    { AUL_K_HINT_SCREEN_HEIGHT, std::to_string(win_pos->GetScreenHeight()) },
+  };
+
+  return std::string(reinterpret_cast<char*>(b.ToRaw().first.get()));
+}
+
+std::unique_ptr<WindowPosition> WindowPositionFromBundle(
+    const tizen_base::Bundle& b) {
+  auto x_str = b.GetString(AUL_K_HINT_SCREEN_POS_X);
+  if (x_str.empty())
+    return nullptr;
+
+  auto y_str = b.GetString(AUL_K_HINT_SCREEN_POS_Y);
+  if (y_str.empty())
+    return nullptr;
+
+  auto w_str = b.GetString(AUL_K_HINT_SCREEN_WIDTH);
+  if (w_str.empty())
+    return nullptr;
+
+  auto h_str = b.GetString(AUL_K_HINT_SCREEN_HEIGHT);
+  if (h_str.empty())
+    return nullptr;
+
+  return std::make_unique<WindowPosition>(std::stoi(x_str),
+      std::stoi(y_str), std::stoi(w_str), std::stoi(h_str));
+}
+
+std::unique_ptr<WindowPosition> WindowPositionFromRaw(
+    const std::string& raw) {
+  tizen_base::Bundle b(raw);
+  return WindowPositionFromBundle(b);
+}
+
+std::string GetAulAppPath() {
+  static std::string path;
+
+  if (!path.empty() || getuid() < REGULAR_UID_MIN)
+    return path;
+
+  char appid[256] = { 0, };
+  int ret = aul_app_get_appid_bypid(getpid(), appid, sizeof(appid));
+  if (ret != AUL_R_OK) {
+    _E("aul_app_get_appid_bypid() is failed. error(%d)", ret);
+    return {};
+  }
+
+  path = PATH_AUL + std::to_string(getuid()) + "/." + std::string(appid);
+  return path;
+}
+
+}  // namespace
+
+WindowPosition::WindowPosition(int x, int y, int w, int h)
+    : x_(x), y_(y), w_(w), h_(h) {
+}
+
+int WindowPosition::GetPositionX() const {
+  return x_;
+}
+
+int WindowPosition::GetPositionY() const {
+  return y_;
+}
+
+int WindowPosition::GetScreenWidth() const {
+  return w_;
+}
+
+int WindowPosition::GetScreenHeight() const {
+  return h_;
+}
+
+void WindowPositionManager::WriteToFile(
+    const std::unique_ptr<WindowPosition>& win_pos) {
+  std::string raw = WindowPositionToRaw(win_pos);
+  std::ofstream stream(GetAulAppPath());
+  stream << raw;
+  stream.close();
+}
+
+std::unique_ptr<WindowPosition> WindowPositionManager::ReadFromFile() {
+  std::ifstream stream(GetAulAppPath());
+  if (!stream.good()) {
+    _W("There is no files");
+    stream.close();
+    return nullptr;
+  }
+
+  std::string raw;
+  stream >> raw;
+  stream.close();
+  if (raw.empty())
+    return nullptr;
+
+  return WindowPositionFromRaw(raw);
+}
+
+std::unique_ptr<WindowPosition> WindowPositionManager::ReadFromBundle(
+    const tizen_base::Bundle& b) {
+  return WindowPositionFromBundle(b);
+}
+
+}  // namespace tizen_cpp
diff --git a/tizen-cpp/app-core-ui-cpp/window_position_private.hh b/tizen-cpp/app-core-ui-cpp/window_position_private.hh
new file mode 100644 (file)
index 0000000..a7066be
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_
+#define TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_
+
+#include <bundle_cpp.h>
+
+#include <memory>
+
+namespace tizen_cpp {
+
+class WindowPosition {
+ public:
+  WindowPosition(int x, int y, int w, int h);
+
+  int GetPositionX() const;
+  int GetPositionY() const;
+  int GetScreenWidth() const;
+  int GetScreenHeight() const;
+
+ private:
+  int x_;
+  int y_;
+  int w_;
+  int h_;
+};
+
+class WindowPositionManager {
+ public:
+  WindowPositionManager() = default;
+
+  void WriteToFile(const std::unique_ptr<WindowPosition>& win_pos);
+  std::unique_ptr<WindowPosition> ReadFromFile();
+  std::unique_ptr<WindowPosition> ReadFromBundle(const tizen_base::Bundle& b);
+};
+
+}  // namespace tizen_cpp
+
+#endif  // TIZEN_CPP_APP_CORE_UI_CPP_WINDOW_POSITION_PRIVATE_HH_