Skip to content

Commit ffc7e8a

Browse files
authored
Support pointing device setting (#112)
1 parent 4b75ec4 commit ffc7e8a

File tree

6 files changed

+229
-5
lines changed

6 files changed

+229
-5
lines changed

flutter/shell/platform/tizen/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ template("embedder") {
129129
"capi-appfw-application",
130130
"capi-appfw-app-common",
131131
"capi-appfw-app-control",
132+
"capi-appfw-preference",
132133
"capi-base-common",
133134
"capi-system-info",
134135
"capi-system-system-settings",

flutter/shell/platform/tizen/flutter_tizen.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ FlutterDesktopViewRef FlutterDesktopViewCreateFromNewWindow(
209209
window = std::make_unique<flutter::TizenWindowEcoreWl2>(
210210
window_geometry, window_properties.transparent,
211211
window_properties.focusable, window_properties.top_level,
212+
window_properties.pointing_device_support,
213+
window_properties.floating_menu_support,
212214
window_properties.window_handle);
213215
}
214216

flutter/shell/platform/tizen/public/flutter_tizen.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ typedef struct {
6767
double user_pixel_ratio;
6868
// The precreated window handle.
6969
void* window_handle;
70+
// Whether the app should be supported pointing device(mouse) or not.
71+
bool pointing_device_support;
72+
// Whether the app should be supported floating menu or not.
73+
bool floating_menu_support;
7074
} FlutterDesktopWindowProperties;
7175

7276
// Properties for configuring the initial settings of a Flutter view.

flutter/shell/platform/tizen/tizen_window_ecore_wl2.cc

Lines changed: 204 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@
55
#include "tizen_window_ecore_wl2.h"
66

77
#ifdef TV_PROFILE
8+
#include <app.h>
9+
#include <app_preference.h>
810
#include <dlfcn.h>
11+
#include <time.h>
912
#include <vconf.h>
13+
#include <sstream>
1014
#endif
1115

1216
#include "flutter/shell/platform/embedder/embedder.h"
@@ -23,6 +27,8 @@ constexpr int kScrollDirectionHorizontal = 1;
2327
#ifdef TV_PROFILE
2428
constexpr char kSysMouseCursorPointerSizeVConfKey[] =
2529
"db/menu/system/mouse-pointer-size";
30+
constexpr char kSysPointingDeviceSupportToastSharedPreferenceKey[] =
31+
"flutter-tizen/preference/pointing-device-support-toast";
2632
constexpr char kEcoreWL2InputCursorThemeName[] = "vd-cursors";
2733
#endif
2834

@@ -47,14 +53,109 @@ FlutterPointerDeviceKind ToFlutterDeviceKind(const Ecore_Device* dev) {
4753
}
4854
}
4955

56+
#ifdef TV_PROFILE
57+
time_t GetBootTimeEpoch() {
58+
struct timespec now, boot_time;
59+
if (clock_gettime(CLOCK_REALTIME, &now) != 0) {
60+
FT_LOG(Error) << "Fail to get clock_gettime(CLOCK_REALTIME).";
61+
return -1;
62+
}
63+
if (clock_gettime(CLOCK_BOOTTIME, &boot_time) != 0) {
64+
FT_LOG(Error) << "Fail to get clock_gettime(CLOCK_BOOTTIME).";
65+
return -1;
66+
}
67+
time_t boot_time_epoch = now.tv_sec - boot_time.tv_sec;
68+
return (boot_time_epoch / 10) * 10;
69+
}
70+
71+
bool PreferenceItemCallback(const char* key, void* user_data) {
72+
char* app_id = (char*)user_data;
73+
if (!app_id || !key) {
74+
return true;
75+
}
76+
77+
std::string preference_key =
78+
std::string(kSysPointingDeviceSupportToastSharedPreferenceKey) + "/" +
79+
app_id;
80+
if (!strncmp(key, preference_key.c_str(), preference_key.length())) {
81+
preference_remove(key);
82+
}
83+
return true;
84+
}
85+
86+
std::string GetPreferenceKey(bool clear_exist_key) {
87+
time_t boot_time = GetBootTimeEpoch();
88+
if (boot_time == -1) {
89+
return "";
90+
}
91+
92+
char* id = nullptr;
93+
int ret = app_get_id(&id);
94+
if (ret != APP_CONTROL_ERROR_NONE || !id) {
95+
FT_LOG(Error) << "Fail to get app id.";
96+
return std::string();
97+
}
98+
99+
std::string app_id = id;
100+
free(id);
101+
102+
std::ostringstream boot_time_buffer;
103+
boot_time_buffer << boot_time;
104+
105+
std::string preference_key =
106+
std::string(kSysPointingDeviceSupportToastSharedPreferenceKey) + "/" +
107+
app_id + "/" + boot_time_buffer.str();
108+
109+
if (clear_exist_key) {
110+
preference_foreach_item(PreferenceItemCallback, (void*)app_id.c_str());
111+
}
112+
return preference_key;
113+
}
114+
115+
bool GetPointingDeviceToastPreference() {
116+
bool show_unsupported_toast = false;
117+
std::string preference_key = GetPreferenceKey(false);
118+
if (preference_key.empty()) {
119+
return false;
120+
}
121+
122+
int ret =
123+
preference_get_boolean(preference_key.c_str(), &show_unsupported_toast);
124+
if (ret != PREFERENCE_ERROR_NONE) {
125+
return false;
126+
}
127+
return show_unsupported_toast;
128+
}
129+
130+
void SetPointingDevicePreference() {
131+
std::string preference_key = GetPreferenceKey(true);
132+
if (preference_key.empty()) {
133+
return;
134+
}
135+
136+
int ret = preference_set_boolean(preference_key.c_str(), true);
137+
if (ret != PREFERENCE_ERROR_NONE) {
138+
FT_LOG(Error) << "Fail to set toasted preference.";
139+
}
140+
}
141+
#endif
142+
50143
} // namespace
51144

52145
TizenWindowEcoreWl2::TizenWindowEcoreWl2(TizenGeometry geometry,
53146
bool transparent,
54147
bool focusable,
55148
bool top_level,
149+
bool pointing_device_support,
150+
bool floating_menu_support,
56151
void* window_handle = nullptr)
57-
: TizenWindow(geometry, transparent, focusable, top_level) {
152+
: TizenWindow(geometry, transparent, focusable, top_level)
153+
#ifdef TV_PROFILE
154+
,
155+
pointing_device_support_(pointing_device_support),
156+
floating_menu_support_(floating_menu_support)
157+
#endif
158+
{
58159
if (!CreateWindow(window_handle)) {
59160
FT_LOG(Error) << "Failed to create a platform window.";
60161
return;
@@ -64,7 +165,7 @@ TizenWindowEcoreWl2::TizenWindowEcoreWl2(TizenGeometry geometry,
64165
RegisterEventHandlers();
65166
PrepareInputMethod();
66167
Show();
67-
}
168+
} // namespace flutter
68169

69170
TizenWindowEcoreWl2::~TizenWindowEcoreWl2() {
70171
UnregisterEventHandlers();
@@ -155,7 +256,6 @@ void TizenWindowEcoreWl2::SetWindowOptions() {
155256
#endif
156257
ecore_wl2_window_available_rotations_set(ecore_wl2_window_, rotations,
157258
sizeof(rotations) / sizeof(int));
158-
159259
EnableCursor();
160260
}
161261

@@ -223,6 +323,84 @@ void TizenWindowEcoreWl2::EnableCursor() {
223323
#endif
224324
}
225325

326+
#ifdef TV_PROFILE
327+
typedef enum _MouseSupport { DISABLE = 0, ENABLE } MouseSupport;
328+
typedef enum _Device_Type { MOUSE_DEVICE = 3, TOUCH_DEVICE } Device_Type;
329+
330+
void TizenWindowEcoreWl2::SetPointingDeviceSupport() {
331+
// dlopen is used here because the TV-specific library libvd-win-util.so
332+
// and the relevant headers are not present in the rootstrap.
333+
void* handle = dlopen("libvd-win-util.so", RTLD_LAZY);
334+
if (!handle) {
335+
FT_LOG(Error) << "Could not open a shared library libvd-win-util.so.";
336+
return;
337+
}
338+
339+
// These functions are defined in vd-win-util's cursor_module.h.
340+
int (*Mouse_Pointer_Support)(MouseSupport type, void* ecore_wl2_win);
341+
*(void**)(&Mouse_Pointer_Support) = dlsym(handle, "Mouse_Pointer_Support");
342+
343+
if (!Mouse_Pointer_Support) {
344+
FT_LOG(Error) << "Could not load symbols from the library.";
345+
dlclose(handle);
346+
return;
347+
}
348+
349+
Mouse_Pointer_Support(pointing_device_support_ ? ENABLE : DISABLE,
350+
ecore_wl2_window_);
351+
dlclose(handle);
352+
}
353+
354+
void TizenWindowEcoreWl2::SetFloatingMenuSupport() {
355+
// dlopen is used here because the TV-specific library libvd-win-util.so
356+
// and the relevant headers are not present in the rootstrap.
357+
void* handle = dlopen("libvd-win-util.so", RTLD_LAZY);
358+
if (!handle) {
359+
FT_LOG(Error) << "Could not open a shared library libvd-win-util.so.";
360+
return;
361+
}
362+
363+
// These functions are defined in vd-win-util's cursor_module.h.
364+
int (*Mouse_Pointer_Not_Allow)(int enable, void* ecore_wl2_win);
365+
*(void**)(&Mouse_Pointer_Not_Allow) =
366+
dlsym(handle, "Mouse_Pointer_Not_Allow");
367+
368+
if (!Mouse_Pointer_Not_Allow) {
369+
FT_LOG(Error) << "Could not load symbols from the library.";
370+
dlclose(handle);
371+
return;
372+
}
373+
374+
Mouse_Pointer_Not_Allow(!floating_menu_support_, ecore_wl2_window_);
375+
dlclose(handle);
376+
}
377+
378+
void TizenWindowEcoreWl2::ShowUnsupportedToast() {
379+
// dlopen is used here because the TV-specific library libvd-win-util.so
380+
// and the relevant headers are not present in the rootstrap.
381+
void* handle = dlopen("libvd-win-util.so", RTLD_LAZY);
382+
if (!handle) {
383+
FT_LOG(Error) << "Could not open a shared library libvd-win-util.so.";
384+
return;
385+
}
386+
387+
// These functions are defined in vd-win-util's cursor_module.h.
388+
void (*Unsupported_Toast_Launch)(Device_Type type, int show, int enable,
389+
void* ecore_wl2_win);
390+
*(void**)(&Unsupported_Toast_Launch) =
391+
dlsym(handle, "Unsupported_Toast_Launch");
392+
393+
if (!Unsupported_Toast_Launch) {
394+
FT_LOG(Error) << "Could not load symbols from the library.";
395+
dlclose(handle);
396+
return;
397+
}
398+
399+
Unsupported_Toast_Launch(MOUSE_DEVICE, 1, 1, ecore_wl2_window_);
400+
dlclose(handle);
401+
}
402+
#endif
403+
226404
void TizenWindowEcoreWl2::RegisterEventHandlers() {
227405
ecore_event_handlers_.push_back(ecore_event_handler_add(
228406
ECORE_WL2_EVENT_WINDOW_ROTATE,
@@ -273,6 +451,27 @@ void TizenWindowEcoreWl2::RegisterEventHandlers() {
273451
ECORE_EVENT_MOUSE_BUTTON_DOWN,
274452
[](void* data, int type, void* event) -> Eina_Bool {
275453
auto* self = static_cast<TizenWindowEcoreWl2*>(data);
454+
#ifdef TV_PROFILE
455+
if ((!self->pointing_device_support_ ||
456+
!self->floating_menu_support_) &&
457+
!self->show_unsupported_toast_) {
458+
bool shown = GetPointingDeviceToastPreference();
459+
if (!self->floating_menu_support_) {
460+
self->SetFloatingMenuSupport();
461+
}
462+
if (!shown) {
463+
// Toast popup should be called first to set up D-PAD.
464+
self->ShowUnsupportedToast();
465+
SetPointingDevicePreference();
466+
}
467+
self->show_unsupported_toast_ = true;
468+
if (self->floating_menu_support_ && !self->pointing_device_support_) {
469+
self->SetPointingDeviceSupport();
470+
}
471+
return ECORE_CALLBACK_PASS_ON;
472+
}
473+
#endif
474+
276475
if (self->view_delegate_) {
277476
auto* button_event =
278477
reinterpret_cast<Ecore_Event_Mouse_Button*>(event);
@@ -440,8 +639,8 @@ bool TizenWindowEcoreWl2::SetGeometry(TizenGeometry geometry) {
440639
geometry.left, geometry.top,
441640
geometry.width, geometry.height);
442641
// FIXME: The changes set in `ecore_wl2_window_geometry_set` seems to apply
443-
// only after calling `ecore_wl2_window_position_set`. Call a more appropriate
444-
// API that flushes geometry settings to the compositor.
642+
// only after calling `ecore_wl2_window_position_set`. Call a more
643+
// appropriate API that flushes geometry settings to the compositor.
445644
ecore_wl2_window_position_set(ecore_wl2_window_, geometry.left, geometry.top);
446645
return true;
447646
}

flutter/shell/platform/tizen/tizen_window_ecore_wl2.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ class TizenWindowEcoreWl2 : public TizenWindow {
2323
bool transparent,
2424
bool focusable,
2525
bool top_level,
26+
bool pointing_device_support,
27+
bool floating_menu_support,
2628
void* window_handle);
2729

2830
~TizenWindowEcoreWl2();
@@ -64,6 +66,14 @@ class TizenWindowEcoreWl2 : public TizenWindow {
6466

6567
void EnableCursor();
6668

69+
#ifdef TV_PROFILE
70+
void SetPointingDeviceSupport();
71+
72+
void SetFloatingMenuSupport();
73+
74+
void ShowUnsupportedToast();
75+
#endif
76+
6777
void RegisterEventHandlers();
6878

6979
void UnregisterEventHandlers();
@@ -81,6 +91,12 @@ class TizenWindowEcoreWl2 : public TizenWindow {
8191

8292
tizen_policy* tizen_policy_ = nullptr;
8393
uint32_t resource_id_ = 0;
94+
95+
#ifdef TV_PROFILE
96+
bool pointing_device_support_ = true;
97+
bool floating_menu_support_ = true;
98+
bool show_unsupported_toast_ = false;
99+
#endif
84100
};
85101

86102
} // namespace flutter

tools/generate_sysroot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
'capi-appfw-app-common-devel',
3434
'capi-appfw-app-control',
3535
'capi-appfw-app-control-devel',
36+
'capi-appfw-preference',
37+
'capi-appfw-preference-devel',
3638
'capi-base-common',
3739
'capi-base-common-devel',
3840
'capi-base-utils',

0 commit comments

Comments
 (0)