Monitor visibility status of viewer windows 74/180874/1
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 5 Jun 2018 06:05:46 +0000 (15:05 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Tue, 5 Jun 2018 06:05:46 +0000 (15:05 +0900)
To use visibilty status of viewer window, screen connector monitors
ecore events.

Change-Id: I8604b47e38bba1a1167ae5e95e10b51674c7acac
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
screen_connector_remote_surface/ecore_event_handler_internal.h [new file with mode: 0644]
screen_connector_remote_surface/window_context.cc [new file with mode: 0644]
screen_connector_remote_surface/window_context.h [new file with mode: 0644]
screen_connector_remote_surface_evas/remote_surface_evas.cc
screen_connector_remote_surface_evas/remote_surface_evas.h

diff --git a/screen_connector_remote_surface/ecore_event_handler_internal.h b/screen_connector_remote_surface/ecore_event_handler_internal.h
new file mode 100644 (file)
index 0000000..dff7a03
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2018 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 SCREEN_CONNECTOR_ECORE_EVENT_HANDLER_INTERNAL_H_
+#define SCREEN_CONNECTOR_ECORE_EVENT_HANDLER_INTERNAL_H_
+
+#include <Ecore_Wl2.h>
+
+#include <string>
+#include <memory>
+
+#include "screen_connector_remote_surface/common.h"
+
+namespace screen_connector {
+
+class EcoreEventHandler {
+ public:
+  class IEventListener {
+   public:
+    virtual void OnWindowShow(unsigned int win) = 0;
+    virtual void OnWindowHide(unsigned int win) = 0;
+    virtual void OnWindowVisibilityChange(unsigned int win,
+                                          bool fully_obscured) = 0;
+    virtual void OnWindowPreVisibilityChange(unsigned int win,
+                                             bool fully_obscured) = 0;
+  };
+
+  explicit EcoreEventHandler(IEventListener* listener) : listener_(listener) {
+    show_ = ecore_event_handler_add(
+        ECORE_WL2_EVENT_WINDOW_SHOW,
+        EcoreEventCB, listener_);
+    hide_ = ecore_event_handler_add(
+        ECORE_WL2_EVENT_WINDOW_HIDE,
+        EcoreEventCB, listener_);
+    visibility_change_ = ecore_event_handler_add(
+        ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE,
+       EcoreEventCB, listener_);
+    pre_visibility_change_ = ecore_event_handler_add(
+        ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE,
+        EcoreEventCB, listener_);
+  }
+
+  virtual ~EcoreEventHandler() {
+    if (pre_visibility_change_)
+      ecore_event_handler_del(pre_visibility_change_);
+    if (visibility_change_)
+      ecore_event_handler_del(visibility_change_);
+    if (hide_)
+      ecore_event_handler_del(hide_);
+    if (show_)
+      ecore_event_handler_del(show_);
+  }
+
+ private:
+  static Eina_Bool EcoreEventCB(void* data, int type, void* event) {
+    IEventListener* rs = static_cast<IEventListener*>(data);
+
+    if (type == ECORE_WL2_EVENT_WINDOW_SHOW) {
+      Ecore_Wl2_Event_Window_Show* ev =
+          static_cast<Ecore_Wl2_Event_Window_Show*>(event);
+      rs->OnWindowShow(ev->win);
+    } else if (type == ECORE_WL2_EVENT_WINDOW_HIDE) {
+      Ecore_Wl2_Event_Window_Hide* ev =
+          static_cast<Ecore_Wl2_Event_Window_Hide*>(event);
+      rs->OnWindowHide(ev->win);
+    } else if (type == ECORE_WL2_EVENT_WINDOW_VISIBILITY_CHANGE) {
+      Ecore_Wl2_Event_Window_Visibility_Change* ev =
+          static_cast<Ecore_Wl2_Event_Window_Visibility_Change*>(event);
+      rs->OnWindowVisibilityChange(ev->win, ev->fully_obscured);
+    } else if (type == ECORE_WL2_EVENT_WINDOW_PRE_VISIBILITY_CHANGE) {
+      Ecore_Wl2_Event_Window_Pre_Visibility_Change* ev =
+          static_cast<Ecore_Wl2_Event_Window_Pre_Visibility_Change*>(event);
+      if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_PRE_UNOBSCURED) {
+        rs->OnWindowPreVisibilityChange(ev->win, false);
+      } else if (ev->type == ECORE_WL2_WINDOW_VISIBILITY_TYPE_FULLY_OBSCURED) {
+        rs->OnWindowPreVisibilityChange(ev->win, true);
+      }
+    }
+    return ECORE_CALLBACK_RENEW;
+  }
+
+ private:
+  IEventListener* listener_;
+  Ecore_Event_Handler* show_ = nullptr;
+  Ecore_Event_Handler* hide_ = nullptr;
+  Ecore_Event_Handler* visibility_change_ = nullptr;
+  Ecore_Event_Handler* pre_visibility_change_ = nullptr;
+};
+
+}  // namespace screen_connector
+
+#endif  // SCREEN_CONNECTOR_ECORE_EVENT_HANDLER_INTERNAL_H_
diff --git a/screen_connector_remote_surface/window_context.cc b/screen_connector_remote_surface/window_context.cc
new file mode 100644 (file)
index 0000000..bff8a09
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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 <dlog.h>
+
+#include <string>
+#include <memory>
+#include <map>
+
+#include "screen_connector_remote_surface/window_context.h"
+#include "screen_connector_remote_surface/common.h"
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+
+#define LOG_TAG "SC_WINDOW_CONTEXT"
+
+namespace screen_connector {
+
+WindowContext::WindowContext() :
+  ecore_event_handler_(new EcoreEventHandler(this)) {
+}
+
+void WindowContext::UpdateWindow(unsigned int win, bool fully_obscured) {
+  win_map_[win] = fully_obscured;
+}
+
+void WindowContext::RemoveWindow(unsigned int win) {
+  if (win_map_.find(win) == win_map_.end())
+    return;
+  win_map_.erase(win);
+}
+
+void WindowContext::OnWindowShow(unsigned int win) {
+  UpdateWindow(win, false);
+  LOGD("[__WINDOW_SHOW__] win(%u)", win);
+}
+
+void WindowContext::OnWindowHide(unsigned int win) {
+  RemoveWindow(win);
+  LOGD("[__WINDOW_HIDE__] win(%u)", win);
+}
+
+void WindowContext::OnWindowVisibilityChange(unsigned int win,
+                                             bool fully_obscured) {
+  UpdateWindow(win, fully_obscured);
+  LOGD("[__WINDOW_VISIBILITY_CHANGE__] win(%u), fully_obscured(%d)",
+      win, fully_obscured);
+}
+
+void WindowContext::OnWindowPreVisibilityChange(unsigned int win,
+                                                bool fully_obscured) {
+  UpdateWindow(win, fully_obscured);
+  LOGD("[__WINDOW_PRE_VISIBILITY_CHANGE__] win(%u), fully_obscured(%d)",
+      win, fully_obscured);
+}
+
+}  // namespace screen_connector
diff --git a/screen_connector_remote_surface/window_context.h b/screen_connector_remote_surface/window_context.h
new file mode 100644 (file)
index 0000000..e6a2bac
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 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 SCREEN_CONNECTOR_WINDOW_CONTEXT_H_
+#define SCREEN_CONNECTOR_WINDOW_CONTEXT_H_
+
+#include <string>
+#include <memory>
+#include <map>
+
+#include "screen_connector_remote_surface/ecore_event_handler_internal.h"
+#include "screen_connector_remote_surface/common.h"
+
+namespace screen_connector {
+
+class EXPORT_API WindowContext : public EcoreEventHandler::IEventListener {
+ public:
+  WindowContext();
+  virtual ~WindowContext() = default;
+
+  bool IsFullyObscured(unsigned int win) {
+    if (win_map_.find(win) == win_map_.end())
+      return false;
+    return win_map_[win];
+  }
+
+  unsigned int FindWindow(unsigned int win) {
+    if (win_map_.find(win) == win_map_.end())
+      return 0;
+    return win;
+  }
+
+ private:
+  void OnWindowShow(unsigned int win) override;
+  void OnWindowHide(unsigned int win) override;
+  void OnWindowVisibilityChange(unsigned int win,
+                                bool fully_obscured) override;
+  void OnWindowPreVisibilityChange(unsigned int win,
+                                   bool fully_obscured) override;
+
+ private:
+  void UpdateWindow(unsigned int win, bool fully_obscured);
+  void RemoveWindow(unsigned int win);
+
+ private:
+  std::unique_ptr<EcoreEventHandler> ecore_event_handler_;
+  std::map<unsigned int, bool> win_map_;
+};
+
+}  // namespace screen_connector
+
+#endif  // SCREEN_CONNECTOR_WINDOW_CONTEXT_H_
index e51c92c..56edaaa 100644 (file)
@@ -37,7 +37,8 @@ RemoteSurfaceEvas::RemoteSurfaceEvas(const std::string& id,
                                      std::shared_ptr<EvasObject> viewerWin,
                                      bool mock)
     : RemoteSurface(id, type, mock),
-      impl_(new Impl(this, viewerWin, mock)) {
+      impl_(new Impl(this, viewerWin, mock)),
+      win_ctx_(new WindowContext()) {
 }
 
 RemoteSurfaceEvas::RemoteSurfaceEvas(int rid, const std::string& id,
@@ -45,7 +46,8 @@ RemoteSurfaceEvas::RemoteSurfaceEvas(int rid, const std::string& id,
                                      std::shared_ptr<EvasObject> viewerWin,
                                      bool mock)
     : RemoteSurface(rid, id, type, mock),
-      impl_(new Impl(this, viewerWin, mock)) {
+      impl_(new Impl(this, viewerWin, mock)),
+      win_ctx_(new WindowContext()) {
 }
 
 RemoteSurfaceEvas::~RemoteSurfaceEvas() = default;
@@ -471,10 +473,12 @@ void RemoteSurfaceEvas::OnBufferChanged(int type, std::shared_ptr<WlBuffer> tbm,
     Ecore_Evas *ee = ecore_evas_ecore_evas_get(
       evas_object_evas_get(impl_->viewer_win_->GetRaw()));
     Ecore_Wl2_Window* wlWin = ecore_evas_wayland2_window_get(ee);
-    if (!wlWin)
+    if (!wlWin) {
       LOGE("Failed to get wlWin");
-    else
-      impl_->winVisibility_map_[ecore_wl2_window_id_get(wlWin)] = UNKNOWN;
+    } else {
+      unsigned int win_id = ecore_wl2_window_id_get(wlWin);
+      impl_->winVisibility_map_[win_id] = GetVisibility(win_id);
+    }
     isAdded = true;
   }
 
@@ -520,7 +524,7 @@ void RemoteSurfaceEvas::Bind(const EvasObject& win) {
   }
 
   bind_win_id = ecore_wl2_window_id_get(wl_win);
-  impl_->winVisibility_map_[bind_win_id] = UNKNOWN;
+  impl_->winVisibility_map_[bind_win_id] = GetVisibility(bind_win_id);
   impl_->bind_win_id_ = bind_win_id;
 
   RemoteSurface::Bind(std::shared_ptr<WlSurface>(
@@ -598,4 +602,17 @@ RemoteSurfaceEvas::Visibility RemoteSurfaceEvas::GetVisibility() const {
   return impl_->visibility_;
 }
 
+RemoteSurfaceEvas::Visibility RemoteSurfaceEvas::GetVisibility(
+    unsigned int win) {
+  if (!win_ctx_->FindWindow(win)) {
+    LOGE("Failed to find window(%u)", win);
+    return RemoteSurfaceEvas::UNKNOWN;
+  }
+
+  if (win_ctx_->IsFullyObscured(win))
+    return RemoteSurfaceEvas::FULLY_OBSCURED;
+
+  return RemoteSurfaceEvas::UNOBSCURED;
+}
+
 }  // namespace screen_connector
index 14f2f75..55acd13 100644 (file)
@@ -24,6 +24,7 @@
 #include "screen_connector_remote_surface_evas/evas_object.h"
 #include "screen_connector_remote_surface_evas/evas_event_interface.h"
 #include "screen_connector_remote_surface/remote_surface.h"
+#include "screen_connector_remote_surface/window_context.h"
 
 namespace screen_connector {
 
@@ -69,8 +70,12 @@ class EXPORT_API RemoteSurfaceEvas : public RemoteSurface, public IEvasEvent {
                      int pid, const EvasObject& image) override;
 
  private:
+  Visibility GetVisibility(unsigned int win);
+
+ private:
   class Impl;
   std::unique_ptr<Impl> impl_;
+  std::unique_ptr<WindowContext> win_ctx_;
 };
 
 }  // namespace screen_connector