[input] Check LCD state
authorHwankyu Jhun <h.jhun@samsung.com>
Fri, 19 Mar 2021 00:13:07 +0000 (09:13 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 19 Mar 2021 05:08:07 +0000 (14:08 +0900)
If LCD is off, AMD doesn't block the input. While the display status is
changed to off, AMD unblocks the input.

Change-Id: I1ec1f29e5fa7f83a950ee08423e0796f77ce2092
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/modules/input/src/amd_input.c
src/modules/input/src/amd_lcd_monitor.cc [new file with mode: 0644]
src/modules/input/src/amd_lcd_monitor.h [new file with mode: 0644]
src/modules/input/src/lcd_monitor.cc [new file with mode: 0644]
src/modules/input/src/lcd_monitor.hh [new file with mode: 0644]
src/modules/input/src/log_private.hh [new file with mode: 0644]

index d9389ff1104060641442c7945410636b3bb7ff38..5e9bd5f67471242d7737143a854e792d3789183f 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "amd_input_config.h"
 #include "amd_input_private.h"
+#include "amd_lcd_monitor.h"
 
 static bool locked;
 static bool init_done;
@@ -328,6 +329,11 @@ static int __on_lock(const char *msg, int arg1, int arg2, void *arg3,
        int caller_app_type;
 
        if (TIZEN_FEATURE_BLOCK_INPUT) {
+               if (_lcd_monitor_is_lcd_off()) {
+                       LOGW("LCD is off");
+                       return 0;
+               }
+
                caller_app_status = amd_app_status_find_by_pid(caller_pid);
                if (!caller_app_status)
                        return 0;
@@ -499,11 +505,19 @@ static int __input_init(void)
        return 0;
 }
 
+static void __on_lcd_state_changed_cb(bool lcd_off, void *user_data)
+{
+       if (lcd_off)
+               __input_unlock();
+}
+
 EXPORT int AMD_MOD_INIT(void)
 {
        LOGD("input init");
 
        _input_config_init();
+       _lcd_monitor_init();
+       _lcd_monitor_set_lcd_state_changed_cb(__on_lcd_state_changed_cb, NULL);
        timeout_val = _input_config_get_timeout_interval();
 
        amd_noti_listen(AMD_NOTI_MSG_WAYLAND_LISTENER_TIZEN_INPUT_DEVICE_MANAGER,
@@ -534,6 +548,7 @@ EXPORT void AMD_MOD_FINI(void)
                g_source_remove(sid);
                sid = 0;
        }
+       _lcd_monitor_fini();
        _input_config_fini();
 }
 
diff --git a/src/modules/input/src/amd_lcd_monitor.cc b/src/modules/input/src/amd_lcd_monitor.cc
new file mode 100644 (file)
index 0000000..26f0782
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 <amd.h>
+
+#include "amd_lcd_monitor.h"
+#include "lcd_monitor.hh"
+#include "log_private.hh"
+
+namespace {
+using namespace amd;
+
+class LcdMonitorExt : public LcdMonitor,
+                      public LcdMonitor::IEvent {
+ private:
+  LcdMonitorExt() : LcdMonitor(this) { }
+  ~LcdMonitorExt() {
+    if (!disposed_)
+      Dispose();
+  }
+
+ public:
+  static LcdMonitorExt& GetInst() {
+    static LcdMonitorExt inst;
+    return inst;
+  }
+
+  bool IsLcdOff() {
+    return lcd_off_;
+  }
+
+  void SetStateChangedCb(lcd_monitor_lcd_state_changed_cb cb, void* user_data) {
+    cb_ = cb;
+    user_data_ = user_data;
+  }
+
+  void Dispose() {
+    Unsubscribe();
+    disposed_ = true;
+  }
+
+  void Init() {
+    amd_signal_add_ready_cb([](void* user_data) -> int {
+          auto& inst = LcdMonitorExt::GetInst();
+          return inst.Subscribe();
+        }, this);
+    disposed_ = false;
+  }
+
+ private:
+  void OnLcdStateChanged(bool lcd_off) {
+    if (lcd_off_ != lcd_off) {
+      _W("LCD: %s -> %s", lcd_off_ ? "off" : "on", lcd_off ? "off" : "on");
+      lcd_off_ = lcd_off;
+      if (cb_)
+        cb_(lcd_off_, user_data_);
+    }
+  }
+
+ private:
+  bool disposed_ = true;
+  bool lcd_off_ = false;
+  lcd_monitor_lcd_state_changed_cb cb_ = nullptr;
+  void* user_data_ = nullptr;
+};
+
+}  // namespace
+
+void _lcd_monitor_set_lcd_state_changed_cb(
+    lcd_monitor_lcd_state_changed_cb callback, void* user_data) {
+  LcdMonitorExt::GetInst().SetStateChangedCb(callback, user_data);
+}
+
+bool _lcd_monitor_is_lcd_off(void) {
+  return LcdMonitorExt::GetInst().IsLcdOff();
+}
+
+int _lcd_monitor_init(void) {
+  _W("LCD_MONITOR_INIT");
+  LcdMonitorExt::GetInst().Init();
+  return 0;
+}
+
+void _lcd_monitor_fini(void) {
+  _W("LCD_MONITOR_FINI");
+  LcdMonitorExt::GetInst().Dispose();
+}
diff --git a/src/modules/input/src/amd_lcd_monitor.h b/src/modules/input/src/amd_lcd_monitor.h
new file mode 100644 (file)
index 0000000..da77690
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 __AMD_LCD_MONITOR_H__
+#define __AMD_LCD_MONITOR_H__
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*lcd_monitor_lcd_state_changed_cb)(bool lcd_off, void *user_data);
+
+void _lcd_monitor_set_lcd_state_changed_cb(lcd_monitor_lcd_state_changed_cb callback, void *user_data);
+
+bool _lcd_monitor_is_lcd_off(void);
+
+int _lcd_monitor_init(void);
+
+void _lcd_monitor_fini(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __AMD_LCD_MONITOR_H__ */
diff --git a/src/modules/input/src/lcd_monitor.cc b/src/modules/input/src/lcd_monitor.cc
new file mode 100644 (file)
index 0000000..8a1e2f3
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "lcd_monitor.hh"
+#include "log_private.hh"
+
+namespace amd {
+namespace {
+
+constexpr char DEVICED_PATH_DISPLAY[] = "/Org/Tizen/System/DeviceD/Display";
+constexpr char DEVICED_INTERFACE_DISPLAY[] = "org.tizen.system.deviced.display";
+constexpr char SIGNAL_DEVICED_LCDON[] = "LCDOn";
+constexpr char SIGNAL_DEVICED_LCDOFF[] = "LCDOff";
+
+}  // namespace
+
+LcdMonitor::LcdMonitor(IEvent* listener) : listener_(listener) {
+}
+
+LcdMonitor::~LcdMonitor() {
+  Unsubscribe();
+}
+
+int LcdMonitor::Subscribe() {
+  _W("Subscribe");
+  if (conn_ == nullptr) {
+    GError* err = nullptr;
+    conn_ = g_bus_get_sync(G_BUS_TYPE_SYSTEM, nullptr, &err);
+    if (conn_ == nullptr) {
+      _E("g_bus_get_sync() is failed. error(%s)",
+          err ? err->message : "Unknonw");
+      g_clear_error(&err);
+      return -1;
+    }
+  }
+
+  if (lcd_on_tag_ == 0) {
+    lcd_on_tag_ = g_dbus_connection_signal_subscribe(conn_,
+        nullptr,
+        DEVICED_INTERFACE_DISPLAY,
+        SIGNAL_DEVICED_LCDON,
+        DEVICED_PATH_DISPLAY,
+        nullptr,
+        G_DBUS_SIGNAL_FLAGS_NONE,
+        GDBusSignalCb,
+        this,
+        nullptr);
+    if (lcd_on_tag_ == 0) {
+      _E("g_dbus_connection_signal_subscribe() is failed");
+      return -1;
+    }
+  }
+
+  if (lcd_off_tag_ == 0) {
+    lcd_off_tag_ = g_dbus_connection_signal_subscribe(conn_,
+        nullptr,
+        DEVICED_INTERFACE_DISPLAY,
+        SIGNAL_DEVICED_LCDOFF,
+        DEVICED_PATH_DISPLAY,
+        nullptr,
+        G_DBUS_SIGNAL_FLAGS_NONE,
+        GDBusSignalCb,
+        this,
+        nullptr);
+    if (lcd_off_tag_ == 0) {
+      _E("g_dbus_connection_signal_subscribe() is failed");
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+void LcdMonitor::Unsubscribe() {
+  _W("Unsubscribe");
+  if (lcd_off_tag_) {
+    g_dbus_connection_signal_unsubscribe(conn_, lcd_off_tag_);
+    lcd_off_tag_ = 0;
+  }
+
+  if (lcd_on_tag_) {
+    g_dbus_connection_signal_unsubscribe(conn_, lcd_on_tag_);
+    lcd_on_tag_ = 0;
+  }
+
+  if (conn_) {
+    g_object_unref(conn_);
+    conn_ = nullptr;
+  }
+}
+
+void LcdMonitor::GDBusSignalCb(GDBusConnection* connection,
+    const gchar* sender_name,
+    const gchar* object_path,
+    const gchar* interface_name,
+    const gchar* signal_name,
+    GVariant* parameters,
+    gpointer user_data) {
+  auto* handle = static_cast<LcdMonitor*>(user_data);
+  auto* listener = handle->listener_;
+  if (g_strcmp0(signal_name, SIGNAL_DEVICED_LCDON) == 0) {
+    _W("LCD on");
+    listener->OnLcdStateChanged(false);
+  } else if (g_strcmp0(signal_name, SIGNAL_DEVICED_LCDOFF) == 0) {
+    _W("LCD off");
+    listener->OnLcdStateChanged(true);
+  } else {
+    _W("Unknown signal(%s)", signal_name);
+  }
+}
+
+}  // namespace amd
diff --git a/src/modules/input/src/lcd_monitor.hh b/src/modules/input/src/lcd_monitor.hh
new file mode 100644 (file)
index 0000000..3cf11ff
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LCD_MONITOR_HH_
+#define LCD_MONITOR_HH_
+
+#include <gio/gio.h>
+#include <glib.h>
+
+namespace amd {
+
+class LcdMonitor {
+ public:
+  class IEvent {
+   public:
+    virtual void OnLcdStateChanged(bool lcd_off) = 0;
+  };
+
+  LcdMonitor(IEvent* listener);
+  virtual ~LcdMonitor();
+
+  int Subscribe();
+  void Unsubscribe();
+
+ private:
+  static void GDBusSignalCb(GDBusConnection* connection,
+      const gchar* sender_name,
+      const gchar* object_path,
+      const gchar* interface_name,
+      const gchar* signal_name,
+      GVariant* parameters,
+      gpointer user_data);
+
+ private:
+  IEvent* listener_;
+  GDBusConnection* conn_ = nullptr;
+  guint lcd_on_tag_ = 0;
+  guint lcd_off_tag_ = 0;
+};
+
+}  // namespace amd
+
+#endif  // LCD_MONITOR_HH_
diff --git a/src/modules/input/src/log_private.hh b/src/modules/input/src/log_private.hh
new file mode 100644 (file)
index 0000000..cd17b9b
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 LOG_PRIVATE_HH_
+#define LOG_PRIVATE_HH_
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AMD_INPUT"
+
+#undef _E
+#define _E LOGE
+
+#undef _W
+#define _W LOGW
+
+#undef _I
+#define _I LOGI
+
+#undef _D
+#define _D LOGD
+
+#endif  // LOG_PRIVATE_HH_