[M120 Migration]Changing code for re-factored accessory 65/306965/6
authorYu Yang <yangy.yu@samsung.com>
Fri, 1 Mar 2024 01:47:34 +0000 (09:47 +0800)
committeryang yu <yangy.yu@samsung.com>
Wed, 6 Mar 2024 03:05:49 +0000 (03:05 +0000)
Port new accessory and Nintendo Pro gamepad support patches from tizen_8.0:
https://review.tizen.org/gerrit/#/c/297678/
https://review.tizen.org/gerrit/#/c/297966/
https://review.tizen.org/gerrit/#/c/291195/
https://review.tizen.org/gerrit/#/c/290514/

Change-Id: I5e1403d6a313fc1b0ef9623f3f1ecf2641970c7c
Signed-off-by: Yu Yang <yangy.yu@samsung.com>
packaging/chromium-efl.spec
tizen_src/build/BUILD.gn
tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc
tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h
tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.cc
tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h

index 02b919f..a1100cc 100644 (file)
@@ -504,7 +504,7 @@ touch ./tizen_src/downloadable/ewk_api_wrapper_generator.py
   "tizen_product_tv=true" \
 %endif
 %if "%{?tizen_profile_name}" == "tv" && "%{_vd_cfg_product_type}" != "AUDIO" &&  "%{_vd_cfg_product_type}" != "AV"
-  "tizen_vd_accessory=false" \
+  "tizen_vd_accessory=true" \
 %endif
 %if 0%{?component_build}
  "component=\"shared_library\"" \
index f05af15..7d3f2a8 100644 (file)
@@ -866,9 +866,9 @@ tizen_pkg_config("privileged-service") {
   }
 }
 
-#FIXME: dlopen error : libOCIController.so: cannot open shared object
-if (tizen_vd_accessory) {
-  tizen_pkg_config("accessory") {
+tizen_pkg_config("accessory") {
+  packages = []
+  if (tizen_vd_accessory) {
     packages = [ "accessory" ]
   }
 }
index c0689b8..fc0eaba 100644 (file)
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h"
+
+#include <autoinput.h>
 #include <string.h>
 #include "base/logging.h"
 #include "base/strings/string_number_conversions.h"
@@ -59,8 +61,15 @@ void GamepadPlatformDataFetcherTizenTV::MapperTizenStyleGamepad(
     const Gamepad& input,
     Gamepad* mapped) {
   *mapped = input;
-  mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
-  mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
+  if (fabs(input.axes[2] + 1.0) <= 0.000001 &&
+      fabs(input.axes[5] + 1.0) <= 0.000001) {
+    // Left Trigger & Right Trigger are Buttons not ABS Value
+    mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = input.buttons[6];
+    mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = input.buttons[7];
+  } else {
+    mapped->buttons[BUTTON_INDEX_LEFT_TRIGGER] = AxisToButton(input.axes[2]);
+    mapped->buttons[BUTTON_INDEX_RIGHT_TRIGGER] = AxisToButton(input.axes[5]);
+  }
   mapped->buttons[BUTTON_INDEX_BACK_SELECT] = input.buttons[12];
   mapped->buttons[BUTTON_INDEX_START] = input.buttons[13];
   mapped->buttons[BUTTON_INDEX_LEFT_THUMBSTICK] = input.buttons[10];
@@ -82,6 +91,10 @@ void GamepadPlatformDataFetcherTizenTV::MapperTizenStyleGamepad(
 GamepadPlatformDataFetcherTizenTV::GamepadPlatformDataFetcherTizenTV() {
   gamepad_manager_ = nullptr;
   if (Gamepad_Create()) {
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+    // initialize autoinput
+    VirtualKey_Initialize("gamepad-service");
+#endif
     Initialize();
   } else {
     LOG(ERROR) << "[Gamepad_LOG] "
@@ -94,7 +107,10 @@ GamepadPlatformDataFetcherTizenTV::GamepadPlatformDataFetcherTizenTV() {
 GamepadPlatformDataFetcherTizenTV::~GamepadPlatformDataFetcherTizenTV() {
   CHECK(gamepad_manager_ != nullptr);
   gamepad_manager_->UnregisterCallback(this);
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  vconf_ignore_key_changed(VCONF_GAMEHOME_STATUS,
+                           GameHomeAPPStatusChangeCallback);
+#endif
   // Need set gamepad_items_ to null before Gamepad_Destroy, caused by business
   // logic
   for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
@@ -104,6 +120,10 @@ GamepadPlatformDataFetcherTizenTV::~GamepadPlatformDataFetcherTizenTV() {
     }
   }
   Gamepad_Destroy();
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  // finalize autoinput module
+  VirtualKey_Finalize();
+#endif
 }
 
 void GamepadPlatformDataFetcherTizenTV::Initialize() {
@@ -118,6 +138,13 @@ void GamepadPlatformDataFetcherTizenTV::Initialize() {
   InitTizenDevice();
   EnumerateTizenDevices();
   gamepad_manager_->RegisterCallback(this);
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  // added for homekey long press
+  if (-1 == vconf_notify_key_changed(VCONF_GAMEHOME_STATUS,
+                                     GameHomeAPPStatusChangeCallback, this)) {
+    LOG(ERROR) << "RegisterGamehomeStatusCallback Err";
+  }
+#endif
 }
 
 void GamepadPlatformDataFetcherTizenTV::InitTizenDevice() {
@@ -156,7 +183,22 @@ void GamepadPlatformDataFetcherTizenTV::EnumerateTizenDevices() {
     }
   }
 }
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+void GamepadPlatformDataFetcherTizenTV::GameHomeAPPStatusChangeCallback(
+    keynode_t* key,
+    void* data) {
+  LOG(INFO) << " Got GameHomeAPPStatusChangeCallback";
+  if (data == nullptr)
+    return;
+  GamepadPlatformDataFetcherTizenTV* instance =
+      (GamepadPlatformDataFetcherTizenTV*)data;
+  for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
+    if (instance->gamepad_items_[i] != nullptr) {
+      instance->gamepad_items_[i]->UpdateGameHomeAppStatus(key);
+    }
+  }
+}
+#endif
 void GamepadPlatformDataFetcherTizenTV::GetGamepadData(
     bool devices_changed_hint) {
   TRACE_EVENT0("GAMEPAD", "GetGamepadData");
@@ -242,7 +284,12 @@ void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type,
     sType = " DISCONNECT ";
 
   LOG(INFO) << sType << " pparam1 " << reinterpret_cast<char*>(pparam1);
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  strncpy(dev_info.UID, (char*)pparam1, OCI_SIZE_ID - 1);
+  strncpy(dev_info.name, (char*)pparam2, OCI_SIZE_NAME - 1);
+  LOG(INFO) << sType << " dev_info.UID " << dev_info.UID << " dev_info.name "
+            << dev_info.name;
+#else
   if (t_GetDevManagerEventData(evType, dev_info,
                                reinterpret_cast<char*>(pparam1)) != OCI_OK) {
     LOG(ERROR) << "[Gamepad_LOG] "
@@ -263,6 +310,7 @@ void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type,
                << sType << "error != OCI_DEVICE_JOYSTICK ";
     return;
   }
+#endif
 
   switch (type) {
     case OCI_EVENT_DEV_CONNECT: {
index 0d6c747..61239c5 100644 (file)
@@ -5,24 +5,29 @@
 #ifndef TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_TIZEN_TV_H_
 #define TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_TIZEN_TV_H_
 
-#include <accessory/GamepadCallback.h>
-#include <accessory/GamepadEntry.h>
-#include <accessory/IGamepad.h>
-#include <accessory/OCICommon.h>
 #include <array>
 #include <memory>
 #include <string>
+#include "build/tizen_version.h"
 #include "device/gamepad/gamepad_data_fetcher.h"
 #include "device/gamepad/gamepad_pad_state_provider.h"
 #include "device/gamepad/gamepad_standard_mappings.h"
 #include "device/gamepad/public/cpp/gamepad.h"
 #include "tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h"
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+#include <accessory/OCICallback.h>
+namespace device {
+class GamepadPlatformDataFetcherTizenTV : public device::GamepadDataFetcher,
+                                          public OCICallback {
+#else
+#include <accessory/GamepadCallback.h>
 namespace device {
 
 class GamepadPlatformDataFetcherTizenTV
     : public device::GamepadDataFetcher,
       public gamepad::CGamepadManagerCallback {
+#endif
+
  public:
   typedef device::GamepadDataFetcherFactoryImpl<
       GamepadPlatformDataFetcherTizenTV,
@@ -44,12 +49,16 @@ class GamepadPlatformDataFetcherTizenTV
       int source_id,
       mojom::GamepadHapticsManager::ResetVibrationActuatorCallback,
       scoped_refptr<base::SequencedTaskRunner>) override;
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  /*gamehome vconf callback, monitor current running APP is gamehome game app or
+   * not.*/
+  static void GameHomeAPPStatusChangeCallback(keynode_t* key, void* data);
+#endif
  protected:
-  virtual void t_OnCallback(int type,
-                            void* pparam1,
-                            void* pparam2,
-                            void* pparam3);
+  void t_OnCallback(int type,
+                    void* pparam1,
+                    void* pparam2,
+                    void* pparam3) override;
 
  private:
   void ReadTizenDeviceData(size_t index);
index 9a9c478..bc271c8 100644 (file)
@@ -3,8 +3,11 @@
 // found in the LICENSE file.
 
 #include "tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h"
+#include <autoinput.h>
 #include <utility>
 #include "base/logging.h"
+#include "tizen_src/chromium_impl/build/tizen_version.h"
+#define VIRTUAL_KEY_GAMEHOME 572
 
 namespace device {
 
@@ -35,7 +38,44 @@ bool OCIGamepadItem::InitAxisRangeTizen(int code,
                   "gamepad_ == nullptr return";
     return false;
   }
-
+#if TIZEN_VERSION_AT_LEAST(7, 0, 0)
+  // Check whether gamepad support such key
+  GamepadKey gamepad_key_list[1];
+  gamepad_key_list[0].type = OCI_EV_ABS;
+  gamepad_key_list[0].code = code;
+  int* support_result = NULL;
+  bool ret = false;
+  do {
+    if (gamepad_->HaveKeys(gamepad_key_list, 1, &support_result) != OCI_OK) {
+      LOG(ERROR) << "Call[HaveKeys]err";
+      break;
+    }
+    if (!support_result[0]) {
+      LOG(ERROR)
+          << "key[%d] is not supported. Set [baseline=0.0][range=32767.0]";
+      *baseline = 0.0;
+      *range = 32767.0;
+      ret = true;
+      break;
+    }
+    // Do not need to modify, because GetABSValueRange(int, long&, long&) used
+    // by accessory.
+    long min = 0l;  // NOLINT(runtime/int)
+    long max = 0l;  // NOLINT(runtime/int)
+    if (gamepad_->GetABSValueRange(code, max, min) == OCI_OK) {
+      (*baseline) = (min + max) / 2.0;
+      (*range) = (max - min) / 2.0;
+      ret = true;
+      break;
+    } else {
+      LOG(ERROR) << "[Gamepad_LOG] OCIGamepadItem::InitAxisRangeTizen(int "
+                    "code, float* range) init error, code = "
+                 << code;
+    }
+  } while (0);
+  free(support_result);
+  return ret;
+#else
   // Do not need to modify, because GetABSValueRange(int, long&, long&) used by
   // accessory.
   long min = 0l;  // NOLINT(runtime/int)
@@ -51,6 +91,7 @@ bool OCIGamepadItem::InitAxisRangeTizen(int code,
                << code;
     return false;
   }
+#endif
 }
 
 bool OCIGamepadItem::InitAxisRangeTizen() {
@@ -79,6 +120,15 @@ OCIGamepadItem::OCIGamepadItem(IGamepadManager* manager,
   range_tizen_trigger_range_ = 0.0;
 
   s_oci_gamepaditem_num_++;
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  if (vconf_get_int(VCONF_GAMEHOME_STATUS, &home_key_long_press_setting_)) {
+    LOG(ERROR) << "Get GamehomeStatus Err";
+  }
+  home_key_long_press_status_ = LongPressStatus::kNone;
+  home_event_.code = OCI_BTN_15;
+  home_event_.type = OCI_EV_KEY;
+  home_event_.value = (long)HomekeyValue::kNoEvent;
+#endif
 }
 
 OCIGamepadItem::~OCIGamepadItem() {
@@ -96,7 +146,12 @@ bool OCIGamepadItem::CreateDevice() {
         << "[Gamepad_LOG] OCIGamepadItem::Create() gamepad_ == nullptr return";
     return false;
   }
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  // handle homekey seperately.
+  LOG(ERROR) << "[Gamepad_LOG] RegisterKeyHandler";
+  gamepad_->RegisterKeyHandler(OCI_BTN_15, OCI_EV_KEY, GamepadHomekeyCallback,
+                               this);
+#endif
   CHECK(pad_ != nullptr);
   pad_->connected = true;
   pad_->vibration_actuator.not_null = gamepad_->IsForceFeedbackSupported();
@@ -110,7 +165,10 @@ void OCIGamepadItem::DestroyDevice() {
   CHECK(manager_ != nullptr);
   CHECK(gamepad_ != nullptr);
   CHECK(pad_ != nullptr);
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  gamepad_->UnRegisterKeyHandler(OCI_BTN_15, OCI_EV_KEY,
+                                 GamepadHomekeyCallback);
+#endif
   manager_->DestroyDevice(gamepad_->GetID());
   gamepad_ = nullptr;
   pad_->connected = false;
@@ -118,12 +176,16 @@ void OCIGamepadItem::DestroyDevice() {
   return;
 }
 
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+// No Need
+#else
 void OCIGamepadItem::t_OnCallback(int type,
                                   void* pparam1,
                                   void* pparam2,
                                   void* pparam3) {
   // used by parent class
 }
+#endif
 
 const char* OCIGamepadItem::GetUID() {
   LOG(INFO) << "GamePad " << info_.UID;
@@ -144,8 +206,7 @@ size_t OCIGamepadItem::GetItemIndex() {
 }
 
 void OCIGamepadItem::RefreshOCIGamepadDataEachEvent(
-    const OCIControllerEvent& event,
-    const int index) {
+    const OCIControllerEvent& event) {
   Gamepad& pad = (*pad_);
   size_t item = event.code;
   if (event.type == OCI_EV_ABS) {
@@ -210,6 +271,30 @@ void OCIGamepadItem::RefreshOCIGamepadDataEachEvent(
       pad.buttons_length = item + 1;
     }
   }
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  /*for home key long press, we should use
+   *  pad.timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds()
+   *    + event.time - current_microseconds;
+   * instead of
+   *   pad.timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
+   * to make APP get home key's pressing hold time.
+   * for example, user press Home key for 500ms,
+   * APP could get the "home key pressing time" =
+   * "release time" - "press time" = 500ms.
+   * If using "pad.timestamp =
+   * GamepadDataFetcher::CurrentTimeInMicroseconds()",
+   * APP will get the "home
+   * key pressing time" = "release time" - "press time" = 3ms.
+   *  (poll thread interval time)
+   * */
+  struct timeval current_time;
+  gettimeofday(&current_time, NULL);
+  unsigned long long current_microseconds =
+      static_cast<unsigned long long>(current_time.tv_sec) * 1000000 +
+      current_time.tv_usec;
+  pad.timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds() + event.time -
+                  current_microseconds;
+#else
   /*
     event.time is unsigned long type exported from accessory.
     but the real time(us) will overflow if stored with unsigned long type.
@@ -249,6 +334,7 @@ void OCIGamepadItem::RefreshOCIGamepadDataEachEvent(
   */
   pad.timestamp = (GamepadDataFetcher::CurrentTimeInMicroseconds() +
                    pad.timestamp - current_microseconds);
+#endif
   return;
 }
 
@@ -256,16 +342,59 @@ void OCIGamepadItem::RefreshOCIGamepadData() {
   if (gamepad_ == nullptr) {
     return;
   }
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  // handle home key event seperately.
+  // there's homekey press event need to be handled.
+  if (home_event_.value == (long)HomekeyValue::kPressed) {
+    LOG(INFO) << "[Home key]Handle press event.";
+
+    // handle homekey press event first.
+    RefreshOCIGamepadDataEachEvent(home_event_);
+
+    if (home_key_long_press_status_ == LongPressStatus::kStarted) {
+      /* home key long press enable(1s) but home key press time is less than 1s
+      in such case, home key should be handled as the same as short press. The
+      home key press event will be sent when home key release, and should
+      regenerate home key release event immediately after that.*/
+      home_event_.value = (long)HomekeyValue::kReleased;
+
+      /*for the scenario support home key long press,
+       * the home key release event's timestamp using current timestamp*/
+      struct timeval current_time;
+      gettimeofday(&current_time, NULL);
+      unsigned long long current_microseconds =
+          static_cast<unsigned long long>(current_time.tv_sec) * 1000000 +
+          current_time.tv_usec;
+      home_event_.time = current_microseconds;
+      home_key_long_press_status_ = LongPressStatus::kEnd;
+    }
+  } else if (home_event_.value == (long)HomekeyValue::kReleased) {
+    /*there's homekey release event need to be handled.*/
+    LOG(INFO) << "[Home key]Handle release event.";
+    RefreshOCIGamepadDataEachEvent(home_event_);
+    home_event_.value = (long)HomekeyValue::kNoEvent;
+  }
 
   CHECK(OCIGamepadItem::kOCIGamepadItemsLength >= s_oci_gamepaditem_num_);
 
   int count = OCIGamepadItem::kOCIGamepadItemsLength;
   memset(events_, 0, sizeof(OCIControllerEvent) * count);
+  if (OCI_OK == gamepad_->GetInputEvents(events_, count)) {
+    for (int i = 0; i < count; i++) {
+      RefreshOCIGamepadDataEachEvent(events_[i]);
+    }
+  }
+#else
+  CHECK(OCIGamepadItem::kOCIGamepadItemsLength >= s_oci_gamepaditem_num_);
+
+  int count = OCIGamepadItem::kOCIGamepadItemsLength;
+  memset(events_, 0, sizeof(OCIControllerEvent) * count);
   if (OCI_OK == gamepad_->GetInputEventEx(events_, count)) {
     for (int i = 0; i < count; i++) {
-      RefreshOCIGamepadDataEachEvent(events_[i], count);
+      RefreshOCIGamepadDataEachEvent(events_[i]);
     }
   }
+#endif
 }
 
 void OCIGamepadItem::SetVibration(mojom::GamepadEffectParametersPtr params) {
@@ -298,4 +427,92 @@ base::WeakPtr<AbstractHapticGamepad> OCIGamepadItem::GetWeakPtr() {
   return weak_factory_.GetWeakPtr();
 }
 
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+void OCIGamepadItem::UpdateGameHomeAppStatus(keynode_t* key) {
+  base::AutoLock lock(home_key_long_press_setting_lock_);
+  home_key_long_press_setting_ = vconf_keynode_get_int(key);
+  LOG(INFO) << "Gamehome APP status changed to "
+            << home_key_long_press_setting_;
+}
+
+void OCIGamepadItem::GamepadHomekeyCallback(OCIControllerEvent event,
+                                            void* data) {
+  if (data == nullptr) {
+    return;
+  }
+
+  LOG(INFO) << "Enter GamepadHomekeyCallback with home key value "
+            << event.value;
+  OCIGamepadItem* pInstance = (OCIGamepadItem*)data;
+
+  base::AutoLock lock(pInstance->home_key_long_press_setting_lock_);
+  if (event.value == OCI_KEY_PRESSED) {
+    LOG(INFO) << "[Home key] press event.";
+    if (pInstance->home_key_long_press_setting_ >
+        GAMEHOME_STATUS_CLOUDGAME_IS_RUNNING_CONDITION) {
+      LOG(INFO) << "[Home key] GameAPP is running, start timer for long press";
+      pInstance->home_event_.time = event.time;
+      pInstance->home_key_long_press_status_ = LongPressStatus::kStarted;
+      pInstance->home_key_long_press_timer_.Start(
+          FROM_HERE,
+          base::Milliseconds(pInstance->home_key_long_press_setting_),
+          pInstance, &OCIGamepadItem::LongPressCallback);
+
+    } else if ((pInstance->home_key_long_press_setting_ ==
+                    GAMEHOME_STATUS_NO_CLOUDGAME_RUNNING ||
+                pInstance->home_key_long_press_setting_ ==
+                    GAMEHOME_STATUS_DEFAULT)) {
+      LOG(INFO)
+          << "[Home key]No GameAPP running, set press event to be handled.";
+      pInstance->home_event_.value = (long)HomekeyValue::kPressed;
+      /*for the scenario that not support homekey long press,
+       * home_event_ contains correct timestamp for press and release;
+       * for the scenario that support homekey long press,
+       * home_event_ contains correct press event timestamp,
+       * for release event timestamp, it use current timestamp*/
+      pInstance->home_event_.time = event.time;
+      pInstance->home_key_long_press_status_ = LongPressStatus::kNone;
+    }
+  } else if (event.value == OCI_KEY_RELEASED) {
+    LOG(INFO) << "[Home key] release event.";
+    if (pInstance->home_key_long_press_setting_ >
+        GAMEHOME_STATUS_CLOUDGAME_IS_RUNNING_CONDITION) {
+      if (pInstance->home_key_long_press_status_ == LongPressStatus::kStarted) {
+        /*long press enable case: home key press time is not more than long
+         * press setting time(1s currently)*/
+        LOG(INFO)
+            << "[Home key] GameAPP is running, short press' release event,"
+            << "stop timer and set press event to be handled.";
+        pInstance->home_key_long_press_timer_.Stop();
+        pInstance->home_event_.value = (long)HomekeyValue::kPressed;
+        /*release event's timestamp will be set in RefreshOCIGamepadData.
+         * because home_event_ current contains press event timestamp,
+         * there may be 3ms delay(thread poll interval)
+         */
+      }
+    } else if (pInstance->home_key_long_press_setting_ ==
+                   GAMEHOME_STATUS_NO_CLOUDGAME_RUNNING ||
+               pInstance->home_key_long_press_setting_ ==
+                   GAMEHOME_STATUS_DEFAULT) {
+      // gameapp is not running, set release status.
+      LOG(INFO)
+          << "[Home key]No GameAPP running, set release event to be handled.";
+      pInstance->home_event_.value = (long)HomekeyValue::kReleased;
+      pInstance->home_event_.time = event.time;
+      pInstance->home_key_long_press_status_ = LongPressStatus::kNone;
+    }
+  }
+}
+
+void OCIGamepadItem::LongPressCallback() {
+  LOG(ERROR) << "[Home key] LongPressCallback";
+  if (home_key_long_press_status_ == LongPressStatus::kStarted) {
+    LOG(INFO) << "[Home key] long pressed! sent gamehome virtualkey!";
+    VirtualKey_Send_KeyCode(VIRTUAL_KEY_GAMEHOME, AUTO_PRESS_RELEASE);
+    home_key_long_press_status_ = LongPressStatus::kEnd;
+  }
+
+  home_key_long_press_timer_.Stop();
+}
+#endif
 }  // namespace device
index e3db6ef..088adf7 100644 (file)
@@ -5,19 +5,38 @@
 #ifndef TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_OCI_GAMEPAD_ITEM_H_
 #define TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_OCI_GAMEPAD_ITEM_H_
 
-#include <accessory/GamepadEntry.h>
-#include <accessory/IGamepad.h>
-#include <accessory/OCICommon.h>
+#include <vconf/vconf.h>
 #include <memory>
 #include "base/memory/weak_ptr.h"
+#include "base/synchronization/lock.h"
+#include "base/timer/timer.h"
+#include "build/tizen_version.h"
 #include "device/gamepad/abstract_haptic_gamepad.h"
 #include "device/gamepad/gamepad_data_fetcher.h"
 #include "device/gamepad/public/cpp/gamepad.h"
 
-namespace device {
+#include <accessory/GamepadEntry.h>
+#include <accessory/IGamepad.h>
+#include <accessory/OCICommon.h>
+
+#define VCONF_GAMEHOME_STATUS "memory/accessory/gamehome_status"
+#define GAMEHOME_STATUS_DEFAULT 0  // default value, ghdaemon not exist
+#define GAMEHOME_STATUS_NO_CLOUDGAME_RUNNING 1
+#define GAMEHOME_STATUS_CLOUDGAME_IS_RUNNING_CONDITION 100
 
+enum class HomekeyValue { kReleased = 0, kPressed = 1, kNoEvent = -1 };
+enum class LongPressStatus {
+  kStarted = 0,  // start to handle long press event
+  kEnd = 1,      // long press event handle completed.
+  kNone = 2      // not enable long press
+};
+namespace device {
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+class OCIGamepadItem : public AbstractHapticGamepad {
+#else
 class OCIGamepadItem : public gamepad::CGamepadCallback,
                        public AbstractHapticGamepad {
+#endif
  public:
   ~OCIGamepadItem() override;
 
@@ -40,7 +59,17 @@ class OCIGamepadItem : public gamepad::CGamepadCallback,
   void SetVibration(mojom::GamepadEffectParametersPtr params) override;
 
   base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() override;
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  // since tizen8.0, home key long press feature
+  // of cloudgame app is handled in chromium side.
+  void UpdateGameHomeAppStatus(keynode_t* key);
+
+  // callback function to handle home key event.
+  static void GamepadHomekeyCallback(OCIControllerEvent event, void* data);
 
+  // callback function to handle home key long press
+  void LongPressCallback();
+#else
  protected:
   // Cannot follow google naming style, because it's override from
   // CGamepadCallback
@@ -48,6 +77,7 @@ class OCIGamepadItem : public gamepad::CGamepadCallback,
                     void* pparam1,
                     void* pparam2,
                     void* pparam3) override;
+#endif
 
  private:
   float range_tizen_stick_baseline_;
@@ -67,12 +97,28 @@ class OCIGamepadItem : public gamepad::CGamepadCallback,
 
   bool InitAxisRangeTizen();
   bool InitAxisRangeTizen(int code, float* baseline, float* range);
-  void RefreshOCIGamepadDataEachEvent(const OCIControllerEvent& event,
-                                      const int index);
+  void RefreshOCIGamepadDataEachEvent(const OCIControllerEvent& event);
   static size_t s_oci_gamepaditem_num_;
   static const float kRangeTizenAxisValueAbsZRz;
   static const float kRangeTizenAxisValueAbsXYRxRy;
-
+#if TIZEN_VERSION_AT_LEAST(8, 0, 0)
+  /*added for home key long press feature.
+  0: ghdaemon doesn't exist
+  1: ghdaemon exist
+  1000: ghdaemon exist and cloud game app in gamehub has been
+  running(background/forground) home key long press enable; press time = 1s*/
+  int home_key_long_press_setting_;
+
+  /* lock longpress_limit_time_, it will be changed in
+   GameHomeAPPStatusChangeCallback(mainthread) and accessed in
+   GamepadHomekeyCallback(poll thread)*/
+  base::Lock home_key_long_press_setting_lock_;
+
+  OCIControllerEvent home_event_;  // home key event to be handled
+  LongPressStatus home_key_long_press_status_;
+  base::OneShotTimer
+      home_key_long_press_timer_;  // timer to check home key long press
+#endif
   IGamepadManager* manager_;
   OCIDevInfo info_;
   IGamepad* gamepad_;