kWinMr,
kOpenxr,
kWinWgi,
- kMaxValue = kWinWgi,
+ kTizenTv,
+ kMaxValue = kTizenTv,
};
struct PadState {
#include "device/gamepad/gamepad_platform_data_fetcher_mac.h"
#include "device/gamepad/nintendo_data_fetcher.h"
#include "device/gamepad/xbox_data_fetcher_mac.h"
+#elif BUILDFLAG(IS_TIZEN_TV) && defined(USE_TIZEN_TV_ACCESSORY)
+#include "tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h"
#elif (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV)
#include "device/gamepad/gamepad_platform_data_fetcher_linux.h"
#include "device/gamepad/nintendo_data_fetcher.h"
manager->AddFactory(new NintendoDataFetcher::Factory());
manager->AddFactory(new XboxDataFetcher::Factory());
+#elif BUILDFLAG(IS_TIZEN_TV) && defined(USE_TIZEN_TV_ACCESSORY)
+ manager->AddFactory(static_cast<device::GamepadDataFetcherFactory*>(
+ new GamepadPlatformDataFetcherTizenTV::Factory()));
#elif (BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)) && defined(USE_UDEV)
manager->AddFactory(new GamepadPlatformDataFetcherLinux::Factory(
BuildRequires: squashfs
%endif
+%if "%{?tizen_profile_name}" == "tv" && "%{_vd_cfg_product_type}" != "AUDIO" && "%{_vd_cfg_product_type}" != "AV"
+BuildRequires: pkgconfig(accessory)
+%endif
+
%if 0%{?__generate_tpk} || 0%{?__package_signing}
BuildRequires: hash-signer, zip
%endif
%if "%{?tizen_profile_name}" == "tv"
"tizen_product_tv=true" \
%endif
+%if "%{?tizen_profile_name}" == "tv" && "%{_vd_cfg_product_type}" != "AUDIO" && "%{_vd_cfg_product_type}" != "AV"
+ "tizen_vd_accessory=true" \
+%endif
%if 0%{?component_build}
"component=\"shared_library\"" \
%endif
}
}
+tizen_pkg_config("accessory") {
+ packages = []
+ if (tizen_vd_accessory) {
+ packages = [ "accessory" ]
+ }
+}
+
if (enable_wrt_js) {
tizen_pkg_config("appcore-agent") {
packages = [ "appcore-agent" ]
"TIZEN_PEPPER_EXTENSIONS"
]
}
+ if (tizen_vd_accessory) {
+ defines += [
+ "USE_TIZEN_TV_ACCESSORY",
+ "_LINUX",
+ ]
+ }
}
tizen_autofill = false
tizen_autofill_fw = false
+ tizen_vd_accessory = false
tizen_resource_manager = false
}
if (enable_basic_printing) {
deps += [ "//printing" ]
}
-
+ if (tizen_vd_accessory) {
+ configs += [ "//tizen_src/build:accessory" ]
+ }
chrome_version = exec_script(version_script,
[
"-f",
"trim string",
[])
defines = [ "CHROMIUM_VERSION=\"" + chrome_version + "\"" ]
-
ldflags = [
"-Wl,--no-undefined",
"-Wl,--version-script=" +
]
}
+ if (tizen_vd_accessory){
+ sources += [
+ # add tizen_tv gamepad platform data fetcher
+ "browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc",
+ "browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h",
+ "browser/gamepad/oci_gamepad_item.cc",
+ "browser/gamepad/oci_gamepad_item.h",
+ ]
+ }
+
sources -= exclude_source_set
# FIXME: Followings are guarded just for bringup.
--- /dev/null
+// Copyright 2016 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h"
+#include <string.h>
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/trace_event/trace_event.h"
+
+namespace device {
+
+void GamepadPlatformDataFetcherTizenTV::GetPidVid(const char* uid,
+ std::string* pid,
+ std::string* vid) {
+ // * @brief just get pid and vid from uid information
+ // * @param [in] - uid information char[]
+ // * @param [out] - pid
+ // * @param [out] - vid
+ //
+ // eg. id
+ // Microsoft Corporation Controller (STANDARD GAMEPAD Vendor: 045e Product:
+ // 028e)
+ // GetUID() : USB\VID_045e\PID_028e\-/75
+ // vid: 045e, pid: 028e
+ // GetGamepadName() : Microsoft Corporation Controller
+
+ int position_vid = 0;
+ int position_pid = 0;
+ int position_second = 0;
+ int position_third = 0;
+
+ std::string str_vp(uid);
+
+ position_vid = str_vp.find("VID_");
+ position_pid = str_vp.find("PID_");
+
+ position_second = str_vp.find("\\", position_vid);
+ position_third = str_vp.find("\\", position_pid);
+
+ (*vid) = str_vp.substr(position_vid + 4, position_second - position_vid - 4);
+ (*pid) = str_vp.substr(position_pid + 4, position_third - position_pid - 4);
+}
+
+void GamepadPlatformDataFetcherTizenTV::UTF8toUTF16(char16_t utf_16_str[],
+ size_t utf_16_str_size,
+ std::string str,
+ size_t str_length) {
+ base::TruncateUTF8ToByteSize(str, str_length - 1, &str);
+ std::u16string tmp16 = base::UTF8ToUTF16(str);
+ memset(utf_16_str, 0, utf_16_str_size);
+ tmp16.copy(utf_16_str, utf_16_str_size - 1);
+}
+
+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]);
+ 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];
+ mapped->buttons[BUTTON_INDEX_RIGHT_THUMBSTICK] = input.buttons[11];
+
+ mapped->buttons[BUTTON_INDEX_DPAD_UP] = AxisNegativeAsButton(input.axes[7]);
+ mapped->buttons[BUTTON_INDEX_DPAD_DOWN] = AxisPositiveAsButton(input.axes[7]);
+ mapped->buttons[BUTTON_INDEX_DPAD_LEFT] = AxisNegativeAsButton(input.axes[6]);
+ mapped->buttons[BUTTON_INDEX_DPAD_RIGHT] =
+ AxisPositiveAsButton(input.axes[6]);
+
+ mapped->buttons[BUTTON_INDEX_META] = input.buttons[14];
+ mapped->axes[AXIS_INDEX_RIGHT_STICK_X] = input.axes[3];
+ mapped->axes[AXIS_INDEX_RIGHT_STICK_Y] = input.axes[4];
+ mapped->buttons_length = BUTTON_INDEX_COUNT;
+ mapped->axes_length = AXIS_INDEX_COUNT;
+}
+
+GamepadPlatformDataFetcherTizenTV::GamepadPlatformDataFetcherTizenTV() {
+ gamepad_manager_ = nullptr;
+ if (Gamepad_Create()) {
+ Initialize();
+ } else {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::"
+ "GamepadPlatformDataFetcherTizenTV() Gamepad_Create() ERROR "
+ "!!!";
+ }
+}
+
+GamepadPlatformDataFetcherTizenTV::~GamepadPlatformDataFetcherTizenTV() {
+ CHECK(gamepad_manager_ != nullptr);
+ gamepad_manager_->UnregisterCallback(this);
+
+ // Need set gamepad_items_ to null before Gamepad_Destroy, caused by business
+ // logic
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
+ if (gamepad_items_[i] != nullptr) {
+ gamepad_items_[i]->Shutdown();
+ gamepad_items_[i] = nullptr;
+ }
+ }
+ Gamepad_Destroy();
+}
+
+void GamepadPlatformDataFetcherTizenTV::Initialize() {
+ gamepad_manager_ = Gamepad_GetManager();
+ if (gamepad_manager_ == nullptr) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::Initialize() "
+ "Gamepad_GetManager() handle get fail !!! ";
+ return;
+ }
+
+ InitTizenDevice();
+ EnumerateTizenDevices();
+ gamepad_manager_->RegisterCallback(this);
+}
+
+void GamepadPlatformDataFetcherTizenTV::InitTizenDevice() {
+ LOG(INFO) << "InitTizenDevice Gamepads::kItemsLengthCap "
+ << Gamepads::kItemsLengthCap;
+
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; ++i) {
+ Gamepad& pad = data_.items[i];
+ pad.connected = false;
+ }
+}
+
+void GamepadPlatformDataFetcherTizenTV::EnumerateTizenDevices() {
+ CHECK(gamepad_manager_ != nullptr);
+
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
+ OCIDevInfo dev_info;
+ bool bIsFree;
+
+ if (gamepad_manager_->GetConnectedDeviceInfo(dev_info, bIsFree, i) !=
+ OCI_OK) {
+ continue;
+ }
+ LOG(INFO) << " dev_info.deviceType " << dev_info.deviceType
+ << " dev_info.eventTyp " << dev_info.eventType
+ << " dev_info.profileType " << dev_info.profileType
+ << " dev_info.UID " << dev_info.UID << " dev_info.name "
+ << dev_info.name << " bIsFree " << bIsFree;
+
+ if (gamepad_items_[i] == nullptr) {
+ gamepad_items_[i] = OCIGamepadItem::Create(gamepad_manager_, &dev_info,
+ &data_.items[i], i);
+ if (gamepad_items_[i]) {
+ InitMapping(i);
+ }
+ }
+ }
+}
+
+void GamepadPlatformDataFetcherTizenTV::GetGamepadData(
+ bool devices_changed_hint) {
+ TRACE_EVENT0("GAMEPAD", "GetGamepadData");
+ // Update our internal state.
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; ++i) {
+ if (gamepad_items_[i] != nullptr) {
+ ReadTizenDeviceData(i);
+
+ PadState* state = GetPadState(i);
+ if (!state)
+ return;
+
+ Gamepad& pad = state->data;
+ MapperTizenStyleGamepad(data_.items[i], &pad);
+ }
+ }
+}
+
+GamepadSource GamepadPlatformDataFetcherTizenTV::source() {
+ return Factory::static_source();
+}
+
+void GamepadPlatformDataFetcherTizenTV::ReadTizenDeviceData(size_t index) {
+ // Linker does not like CHECK_LT(index, Gamepads::kItemsLengthCap). =/
+ if (index >= Gamepads::kItemsLengthCap) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::ReadTizenDeviceData() "
+ << "index >= Gamepads::kItemsLengthCap";
+ return;
+ }
+ CHECK(gamepad_items_[index] != nullptr);
+ gamepad_items_[index]->RefreshOCIGamepadData();
+}
+
+void GamepadPlatformDataFetcherTizenTV::InitMapping(size_t index) {
+ if (index >= Gamepads::kItemsLengthCap) {
+ LOG(ERROR)
+ << "[Gamepad_LOG] GamepadPlatformDataFetcherTizenTV::InitMapping() "
+ << "index >= Gamepads::kItemsLengthCap";
+ return;
+ }
+
+ Gamepad& pad = data_.items[index];
+
+ // reset memory to zero
+ memset(pad.buttons, 0, (sizeof(pad.buttons[0])) * Gamepad::kButtonsLengthCap);
+ memset(pad.axes, 0, (sizeof(pad.axes[0])) * Gamepad::kAxesLengthCap);
+ pad.axes[2] = -1.0;
+ pad.axes[5] = -1.0;
+ pad.buttons_length = 0;
+ pad.axes_length = 0;
+ pad.timestamp = 0;
+ pad.mapping = GamepadMapping::kStandard;
+
+ CHECK(gamepad_items_[index] != nullptr);
+
+ std::string vid = "";
+ std::string pid = "";
+
+ GetPidVid(gamepad_items_[index]->GetUID(), &pid, &vid);
+
+ std::string name_string(gamepad_items_[index]->GetGamepadName());
+
+ std::string id =
+ name_string + base::StringPrintf(" (%sVendor: %s Product: %s)",
+ "STANDARD GAMEPAD ", vid.c_str(),
+ pid.c_str());
+
+ UTF8toUTF16(pad.id, sizeof(pad.id), id, Gamepad::kIdLengthCap);
+}
+
+void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type,
+ void* pparam1,
+ void* pparam2,
+ void* pparam3) {
+ int evType = 0;
+ OCIDevInfo dev_info;
+ std::string sType = "";
+
+ if (type == OCI_EVENT_DEV_CONNECT)
+ sType = " CONNECT ";
+ else if (type == OCI_EVENT_DEV_DISCONNECT)
+ sType = " DISCONNECT ";
+
+ LOG(INFO) << sType << " pparam1 " << reinterpret_cast<char*>(pparam1);
+
+ if (t_GetDevManagerEventData(evType, dev_info,
+ reinterpret_cast<char*>(pparam1)) != OCI_OK) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::t_OnCallback() "
+ << sType << "error != OCI_OK";
+
+ return;
+ }
+ LOG(INFO) << " dev_info.deviceType " << dev_info.deviceType
+ << " dev_info.eventTyp " << dev_info.eventType
+ << " dev_info.profileType " << dev_info.profileType
+ << " dev_info.UID " << dev_info.UID << " dev_info.name "
+ << dev_info.name;
+
+ if (dev_info.deviceType != OCI_DEVICE_JOYSTICK) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::t_OnCallback() "
+ << sType << "error != OCI_DEVICE_JOYSTICK ";
+ return;
+ }
+
+ switch (type) {
+ case OCI_EVENT_DEV_CONNECT: {
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
+ if (gamepad_items_[i] == nullptr) {
+ LOG(INFO) << " connected";
+ gamepad_items_[i] = OCIGamepadItem::Create(
+ gamepad_manager_, &dev_info, &data_.items[i], i);
+ if (gamepad_items_[i]) {
+ InitMapping(i);
+ break;
+ }
+ } else {
+ continue;
+ }
+ }
+ break;
+ }
+
+ case OCI_EVENT_DEV_DISCONNECT: {
+ for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) {
+ if (gamepad_items_[i] != nullptr &&
+ (strcmp(gamepad_items_[i]->GetUID(), dev_info.UID) == 0)) {
+ LOG(INFO) << " gamepad_items_[" << i << "]->GetUID() "
+ << gamepad_items_[i]->GetUID();
+ LOG(INFO) << " disconnected";
+ gamepad_items_[i]->Shutdown();
+ gamepad_items_[i] = nullptr;
+ break;
+ }
+ }
+ break;
+ }
+ case OCI_EVENT_DEV_STATUS: {
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+}
+
+void GamepadPlatformDataFetcherTizenTV::PlayEffect(
+ int pad_id,
+ mojom::GamepadHapticEffectType type,
+ mojom::GamepadEffectParametersPtr params,
+ mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_runner) {
+ if (pad_id < 0 || pad_id >= Gamepads::kItemsLengthCap) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::PlayEffect() "
+ << "index >= Gamepads::kItemsLengthCap";
+ return;
+ }
+ if (gamepad_items_[pad_id] == nullptr) {
+ RunVibrationCallback(
+ std::move(callback), std::move(callback_runner),
+ mojom::GamepadHapticsResult::GamepadHapticsResultError);
+ return;
+ }
+ gamepad_items_[pad_id]->PlayEffect(
+ type, std::move(params), std::move(callback), std::move(callback_runner));
+}
+
+void GamepadPlatformDataFetcherTizenTV::ResetVibration(
+ int pad_id,
+ mojom::GamepadHapticsManager::ResetVibrationActuatorCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_runner) {
+ if (pad_id < 0 || pad_id >= Gamepads::kItemsLengthCap) {
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "GamepadPlatformDataFetcherTizenTV::ResetVibration() "
+ << "index >= Gamepads::kItemsLengthCap";
+ return;
+ }
+ if (gamepad_items_[pad_id] == nullptr) {
+ RunVibrationCallback(
+ std::move(callback), std::move(callback_runner),
+ mojom::GamepadHapticsResult::GamepadHapticsResultError);
+ return;
+ }
+
+ gamepad_items_[pad_id]->ResetVibration(std::move(callback),
+ std::move(callback_runner));
+}
+
+} // namespace device
\ No newline at end of file
--- /dev/null
+// Copyright 2016 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#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 "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"
+
+namespace device {
+
+class GamepadPlatformDataFetcherTizenTV
+ : public device::GamepadDataFetcher,
+ public gamepad::CGamepadManagerCallback {
+ public:
+ typedef device::GamepadDataFetcherFactoryImpl<
+ GamepadPlatformDataFetcherTizenTV,
+ device::GamepadSource::kTizenTv>
+ Factory;
+ GamepadPlatformDataFetcherTizenTV();
+ ~GamepadPlatformDataFetcherTizenTV() override;
+
+ // GamepadDataFetcher implementation.
+ void GetGamepadData(bool devices_changed_hint) override;
+ GamepadSource source() override;
+
+ void PlayEffect(int source_id,
+ mojom::GamepadHapticEffectType,
+ mojom::GamepadEffectParametersPtr,
+ mojom::GamepadHapticsManager::PlayVibrationEffectOnceCallback,
+ scoped_refptr<base::SequencedTaskRunner>) override;
+ void ResetVibration(
+ int source_id,
+ mojom::GamepadHapticsManager::ResetVibrationActuatorCallback,
+ scoped_refptr<base::SequencedTaskRunner>) override;
+
+ protected:
+ virtual void t_OnCallback(int type,
+ void* pparam1,
+ void* pparam2,
+ void* pparam3);
+
+ private:
+ void ReadTizenDeviceData(size_t index);
+ void EnumerateTizenDevices();
+
+ void InitTizenDevice();
+ void Initialize();
+ void InitMapping(size_t index);
+
+ // Notice: [in] uid, [out] pid, [out] vid
+ void GetPidVid(const char* uid, std::string* pid, std::string* vid);
+ void UTF8toUTF16(char16_t utf_16_str[],
+ size_t utf_16_str_size,
+ std::string str,
+ size_t str_length);
+
+ // Functions to map from device data to standard layout.
+ static void MapperTizenStyleGamepad(const Gamepad& input, Gamepad* mapped);
+
+ // Data that's returned to the consumer.
+ Gamepads data_;
+
+ gamepad::IGamepadManager* gamepad_manager_;
+ std::array<std::unique_ptr<OCIGamepadItem>, Gamepads::kItemsLengthCap>
+ gamepad_items_;
+};
+
+} // namespace device
+
+#endif // TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_GAMEPAD_PLATFORM_DATA_FETCHER_TIZEN_TV_H_
--- /dev/null
+// Copyright 2016 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h"
+#include <utility>
+#include "base/logging.h"
+
+namespace device {
+
+size_t OCIGamepadItem::s_oci_gamepaditem_num_ = 0;
+
+// static function
+std::unique_ptr<OCIGamepadItem> OCIGamepadItem::Create(IGamepadManager* manager,
+ OCIDevInfo* dev_info,
+ Gamepad* pad,
+ int index) {
+ if (manager == nullptr) {
+ return nullptr;
+ }
+ auto gamepad_item = std::unique_ptr<OCIGamepadItem>(
+ new OCIGamepadItem(manager, dev_info, pad));
+ if (!gamepad_item->CreateDevice()) {
+ return nullptr;
+ }
+ gamepad_item->SetOCIGamepadItemIndex(index);
+ return gamepad_item;
+}
+
+bool OCIGamepadItem::InitAxisRangeTizen(int code,
+ float* baseline,
+ float* range) {
+ if (gamepad_ == nullptr) {
+ LOG(ERROR) << "[Gamepad_LOG] OCIGamepadItem::InitAxisRangeTizen() "
+ "gamepad_ == nullptr return";
+ return false;
+ }
+
+ // 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;
+ return true;
+ } else {
+ LOG(ERROR) << "[Gamepad_LOG] OCIGamepadItem::InitAxisRangeTizen(int "
+ "code, float* range) init error, code = "
+ << code;
+ return false;
+ }
+}
+
+bool OCIGamepadItem::InitAxisRangeTizen() {
+ // OCI_ABS_X, OCI_ABS_Y, OCI_ABS_RX, OCI_ABS_RY has same range
+ // OCI_ABS_Z, OCI_ABS_RZ has same range
+
+ return InitAxisRangeTizen(OCI_ABS_X, &range_tizen_stick_baseline_,
+ &range_tizen_stick_range_) &&
+ InitAxisRangeTizen(OCI_ABS_Z, &range_tizen_trigger_baseline_,
+ &range_tizen_trigger_range_);
+}
+
+OCIGamepadItem::OCIGamepadItem(IGamepadManager* manager,
+ OCIDevInfo* info,
+ Gamepad* pad) {
+ CHECK(info != nullptr);
+ memcpy(&info_, info, sizeof(OCIDevInfo));
+ CHECK(manager != nullptr);
+ manager_ = manager;
+ gamepad_ = nullptr;
+ pad_ = pad;
+
+ range_tizen_stick_baseline_ = 0.0;
+ range_tizen_stick_range_ = 0.0;
+ range_tizen_trigger_baseline_ = 0.0;
+ range_tizen_trigger_range_ = 0.0;
+
+ s_oci_gamepaditem_num_++;
+}
+
+OCIGamepadItem::~OCIGamepadItem() {
+ if (gamepad_ == nullptr) // CreateDevice fail, need not destroy device.
+ return;
+ this->DestroyDevice();
+ s_oci_gamepaditem_num_--;
+}
+
+bool OCIGamepadItem::CreateDevice() {
+ CHECK(manager_ != nullptr);
+ gamepad_ = manager_->CreateDevice(info_.UID);
+ if (gamepad_ == nullptr) {
+ LOG(ERROR)
+ << "[Gamepad_LOG] OCIGamepadItem::Create() gamepad_ == nullptr return";
+ return false;
+ }
+
+ CHECK(pad_ != nullptr);
+ pad_->connected = true;
+ pad_->vibration_actuator.not_null = gamepad_->IsForceFeedbackSupported();
+ if (pad_->vibration_actuator.not_null)
+ pad_->vibration_actuator.type = GamepadHapticActuatorType::kDualRumble;
+
+ return InitAxisRangeTizen();
+}
+
+void OCIGamepadItem::DestroyDevice() {
+ CHECK(manager_ != nullptr);
+ CHECK(gamepad_ != nullptr);
+ CHECK(pad_ != nullptr);
+
+ manager_->DestroyDevice(gamepad_->GetID());
+ gamepad_ = nullptr;
+ pad_->connected = false;
+
+ return;
+}
+
+void OCIGamepadItem::t_OnCallback(int type,
+ void* pparam1,
+ void* pparam2,
+ void* pparam3) {
+ // used by parent class
+}
+
+const char* OCIGamepadItem::GetUID() {
+ LOG(INFO) << "GamePad " << info_.UID;
+ return info_.UID;
+}
+
+const char* OCIGamepadItem::GetGamepadName() {
+ LOG(INFO) << "GamePad " << info_.name;
+ return info_.name;
+}
+
+void OCIGamepadItem::SetOCIGamepadItemIndex(size_t index) {
+ index_ = index;
+}
+
+size_t OCIGamepadItem::GetItemIndex() {
+ return index_;
+}
+
+void OCIGamepadItem::RefreshOCIGamepadDataEachEvent(
+ const OCIControllerEvent& event,
+ const int index) {
+ Gamepad& pad = (*pad_);
+ size_t item = event.code;
+ if (event.type == OCI_EV_ABS) {
+ if (item >= Gamepad::kAxesLengthCap) {
+ // change the keycode index
+ // OCI_ABS_HAT0X & OCI_ABS_HAT0Y maybe [-1, 0, 1]
+
+ if (event.code == OCI_ABS_HAT0X) {
+ item = 6;
+ pad.axes[item] = event.value;
+ if (item >= pad.axes_length) {
+ pad.axes_length = item + 1;
+ }
+ } else if (event.code == OCI_ABS_HAT0Y) {
+ item = 7;
+ pad.axes[item] = event.value;
+ if (item >= pad.axes_length) {
+ pad.axes_length = item + 1;
+ }
+ } else {
+ LOG(ERROR)
+ << "[Gamepad_LOG] OCIGamepadItem::RefreshOCIGamepadDataEachEvent() "
+ << " set the keycode index Gamepad::axes Error 001 !!!";
+ return;
+ }
+ } else {
+ // convert [0, 255] / [-127, 127] -> [-1, 1]
+ switch (event.code) {
+ case OCI_ABS_X: // fallthrough
+ case OCI_ABS_Y: // fallthrough
+ case OCI_ABS_RX: // fallthrough
+ case OCI_ABS_RY:
+ pad.axes[item] = (event.value - range_tizen_stick_baseline_) /
+ range_tizen_stick_range_;
+ break;
+ case OCI_ABS_Z: // fallthrough
+ case OCI_ABS_RZ:
+ pad.axes[item] = (event.value - range_tizen_trigger_baseline_) /
+ range_tizen_trigger_range_;
+ break;
+ default:
+ LOG(ERROR) << "[Gamepad_LOG] "
+ "OCIGamepadItem::RefreshOCIGamepadDataEachEvent() "
+ << " set the keycode index Gamepad::axes Error 002 !!!";
+ break;
+ }
+
+ if (item >= pad.axes_length) {
+ pad.axes_length = item + 1;
+ }
+ }
+ } else if (event.type == OCI_EV_KEY) {
+ if (item >= Gamepad::kButtonsLengthCap) {
+ LOG(ERROR)
+ << "[Gamepad_LOG] OCIGamepadItem::RefreshOCIGamepadDataEachEvent() "
+ << " set the keycode index Gamepad::buttons Error !!!";
+ return;
+ }
+ pad.buttons[item].pressed = event.value;
+ pad.buttons[item].value = event.value ? 1.0 : 0.0;
+ if (item >= pad.buttons_length) {
+ pad.buttons_length = item + 1;
+ }
+ }
+ pad.timestamp = GamepadDataFetcher::CurrentTimeInMicroseconds();
+ return;
+}
+
+void OCIGamepadItem::RefreshOCIGamepadData() {
+ if (gamepad_ == nullptr) {
+ return;
+ }
+
+ 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);
+ }
+ }
+}
+
+void OCIGamepadItem::SetVibration(mojom::GamepadEffectParametersPtr params) {
+ if (gamepad_ == nullptr) {
+ return;
+ }
+
+ if (params->strong_magnitude > 0 || params->weak_magnitude > 0) {
+ // start dual-rumble
+
+ // scope of scaled_strong_magnitude and scaled_weak_magnitude: 0~100
+ int scaled_strong_magnitude = params->strong_magnitude * 100;
+ int scaled_weak_magnitude = params->weak_magnitude * 100;
+
+ // AbstractHapticGamepad will call SetZeroVibration when the effect is
+ // complete, so we don't need to set the duration here except to make sure
+ // it is at least as long as the maximum duration.
+ uint16_t duration_millis =
+ static_cast<uint16_t>(GamepadHapticActuator::kMaxEffectDurationMillis);
+
+ // duration is controlled by AbstractHapticGamepad, set max duration here.
+ gamepad_->PlayHapticForceFeedback(DUAL_RUMBLE_EFFECT_TYPE, duration_millis,
+ scaled_weak_magnitude,
+ scaled_strong_magnitude);
+ } else {
+ gamepad_->StopForceFeedback();
+ }
+}
+base::WeakPtr<AbstractHapticGamepad> OCIGamepadItem::GetWeakPtr() {
+ return weak_factory_.GetWeakPtr();
+}
+
+} // namespace device
--- /dev/null
+// Copyright 2016 Samsung Electronics. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#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 <memory>
+#include "base/memory/weak_ptr.h"
+#include "device/gamepad/abstract_haptic_gamepad.h"
+#include "device/gamepad/gamepad_data_fetcher.h"
+#include "device/gamepad/public/cpp/gamepad.h"
+
+namespace device {
+
+class OCIGamepadItem : public gamepad::CGamepadCallback,
+ public AbstractHapticGamepad {
+ public:
+ ~OCIGamepadItem() override;
+
+ // OCIGamepadItem implementation.
+ const char* GetUID();
+ const char* GetGamepadName();
+ size_t GetItemIndex();
+
+ // change the device data.
+ void RefreshOCIGamepadData();
+
+ // static function for create OCIGamepadItem, used by
+ // GamepadPlatformDataFetcherTizenTV
+ static std::unique_ptr<OCIGamepadItem> Create(IGamepadManager* manager,
+ OCIDevInfo* dev_info,
+ Gamepad* pad,
+ int index);
+
+ // Set the vibration magnitude for dual-rumble.
+ void SetVibration(mojom::GamepadEffectParametersPtr params) override;
+
+ base::WeakPtr<AbstractHapticGamepad> GetWeakPtr() override;
+
+ protected:
+ // Cannot follow google naming style, because it's override from
+ // CGamepadCallback
+ void t_OnCallback(int type,
+ void* pparam1,
+ void* pparam2,
+ void* pparam3) override;
+
+ private:
+ float range_tizen_stick_baseline_;
+ float range_tizen_stick_range_;
+ float range_tizen_trigger_baseline_;
+ float range_tizen_trigger_range_;
+
+ static const size_t kOCIGamepadItemsLength = 16;
+ OCIControllerEvent events_[kOCIGamepadItemsLength];
+
+ explicit OCIGamepadItem(IGamepadManager* manager,
+ OCIDevInfo* info,
+ Gamepad* pad);
+ bool CreateDevice();
+ void DestroyDevice();
+ void SetOCIGamepadItemIndex(size_t index);
+
+ bool InitAxisRangeTizen();
+ bool InitAxisRangeTizen(int code, float* baseline, float* range);
+ void RefreshOCIGamepadDataEachEvent(const OCIControllerEvent& event,
+ const int index);
+ static size_t s_oci_gamepaditem_num_;
+ static const float kRangeTizenAxisValueAbsZRz;
+ static const float kRangeTizenAxisValueAbsXYRxRy;
+
+ IGamepadManager* manager_;
+ OCIDevInfo info_;
+ IGamepad* gamepad_;
+ Gamepad* pad_;
+ size_t index_;
+ base::WeakPtrFactory<OCIGamepadItem> weak_factory_{this};
+};
+
+} // namespace device
+
+#endif // TIZEN_SRC_EWK_EFL_INTEGRATION_BROWSER_GAMEPAD_OCI_GAMEPAD_ITEM_H_