1 // Copyright 2020 Samsung Electronics. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "wrt/src/browser/tv/wrt_native_window_tv.h"
7 #include <aul-extension.h>
8 #include <cursor_module.h>
9 #include <display-rotator-api.h>
10 #include <json/json.h>
11 #include <screensaver.h>
12 #include <tzplatform_config.h>
13 #include <wayland-client.h>
15 #include <Ecore_Wl2.h>
17 #include <SettingsAPI.h>
19 #include "base/base_switches.h"
20 #include "base/metrics/field_trial.h"
21 #include "base/strings/utf_string_conversions.h"
22 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
23 #include "content/browser/web_contents/web_contents_view_aura.h"
24 #include "content/public/browser/browser_task_traits.h"
25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/render_process_host.h"
28 #include "content/public/browser/storage_partition.h"
29 #include "content/public/common/content_switches.h"
30 #include "electron/shell/browser/browser.h"
31 #include "electron/shell/browser/web_contents_zoom_controller.h"
32 #include "gpu/config/gpu_switches.h"
33 #include "media/base/media_switches.h"
34 #include "third_party/blink/public/common/page/page_zoom.h"
35 #if !defined(WRT_JS_BRINGUP)
36 #include "tizen_src/chromium_impl/chrome/browser/net/proxy_config_monitor.h"
38 #include "tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension_manager.h"
39 #include "tizen_src/chromium_impl/tizen/vconf_handle.h"
40 #include "ui/ozone/platform/efl/efl_screen.h"
41 #include "ui/platform_window/platform_window.h"
42 #include "wrt/src/base/platform_info.h"
43 #include "wrt/src/browser/native_web_runtime.h"
44 #include "wrt/src/browser/tv/ambient_mode.h"
45 #include "wrt/src/browser/tv/decorator_window.h"
46 #include "wrt/src/browser/tv/input_device_manager.h"
47 #include "wrt/src/browser/tv/native_web_runtime_delegate_tv.h"
48 #include "wrt/src/browser/tv/tv_window_manager.h"
49 #include "wrt/src/browser/tv/video_splash_screen.h"
50 #include "wrt/src/browser/tv/widget_state.h"
51 #include "wrt/src/browser/wrt_browser_context.h"
52 #include "wrt/src/browser/wrt_native_window_delegate.h"
53 #include "wrt/src/browser/wrt_web_contents.h"
54 #include "wrt/src/browser/wrt_window_tree_host.h"
55 #include "wrt/src/common/tv/application_data_tv.h"
56 #include "wrt/src/common/tv/wrt_lib_wrapper.h"
57 #include "wrt/src/service/wrt_service.h"
59 #if defined(TIZEN_ATK_SUPPORT)
60 #include "tizen_src/ewk/efl_integration/eweb_accessibility_util.h"
63 #if defined(THREAD_BOOSTER_SERVICE)
64 #include "services/suspend_resume/public/cpp/suspend_resume.h"
72 #define SUSPEND_DELAY_TIME_MAX 3000 // ms
75 const char* kBGChannelChange = "memory/VDWebApp/bg_channel_change";
76 const char* kMostRecentApp = "memory/wrt/most_recent_foreground";
77 const char* kMultiScreenInfoVconfKey = "memory/multiscreen/info";
78 const char* kProxyExceptionList =
79 "db/menu/network/server_network_settings/proxy_exceptional_address";
80 const char* kProxyVconfKey = "memory/dnet/proxy";
81 const char* kWebAppProxyVconfKey = "db/webapp/proxy";
84 const char* kDualDecodingWebRTC =
85 "http://samsung.com/tv/metadata/dual.decoding.support";
86 const char* kContentZoomFill =
87 "http://samsung.com/tv/metadata/settings/content.zoom.fill";
88 const char* kFrameRawDataCopy =
89 "http://samsung.com/tv/metadata/mm.frame.rawdata";
90 const char* kChannelBound = "http://samsung.com/tv/metadata/channelnumber";
91 const char* kDisableScreenSaver =
92 "http://samsung.com/tv/metadata/disable.screensaver.partialvideo";
93 const char* kErrorPagePath = "http://samsung.com/tv/metadata/error.page";
94 const char* kForceHideWindow =
95 "http://samsung.com/tv/metadata/force.hide.window";
96 const char* kGameMode = "http://samsung.com/tv/metadata/use.game.mode";
97 const char* kLegacyGameMode =
98 "http://samsung.com/tv/metadata/use.legacy.game.mode";
99 const char* kUpstreamArchitecture =
100 "http://samsung.com/tv/metadata/use.upstream.architecture";
101 const char* kNDecoding =
102 "http://samsung.com/tv/metadata/use.n.decoding";
103 const char* kGpuRasterization =
104 "http://samsung.com/tv/metadata/gpu.rasterization.support";
105 const char* kGraphicPlaneSupport =
106 "http://samsung.com/tv/metadata/graphic.plane.support";
107 const char* kKeyboardFunc =
108 "http://samsung.com/tv/metadata/use.keyboardfunckey";
109 const char* kMenuOrientation =
110 "db/menu/onscreendisplay/display_orientation/onscreen_menu_orientation";
111 const char* kOpaqueSupport =
112 "http://samsung.com/tv/metadata/transparent.opaque.support";
113 const char* kPartial = "http://samsung.com/tv/metadata/partial.overlay.support";
114 const char* kScreenOrientation =
115 "http://samsung.com/tv/metadata/screen/orientation";
116 const char* kScreenOrientationMultiView =
117 "http://samsung.com/tv/metadata/screen/orientation/multiview";
118 const char* kScreenResolution =
119 "http://samsung.com/tv/metadata/screen.resolution";
120 const char* kSetCookie = "http://samsung.com/tv/metadata/enable.setcookie";
121 const char* kFloatingNavigation =
122 "http://samsung.com/tv/metadata/floating.navigation";
123 const char* kSkipDisable = "http://samsung.com/tv/metadata/skip.disable.tvmenu";
124 const char* kStateByRotation =
125 "http://samsung.com/tv/metadata/application/state.by.rotation";
126 const char* kTransparent = "http://samsung.com/tv/metadata/transparent.support";
127 const char* kUseConformant = "http://samsung.com/tv/metadata/use.conformant";
128 const char* kUseDimScreen = "http://samsung.com/tv/metadata/use.dimscreen";
129 const char* kUseFocus = "http://samsung.com/tv/metadata/use.focus";
130 const char* kUseIME = "http://samsung.com/tv/metadata/use.ime";
131 const char* kUseKeyPad =
132 "http://samsung.com/tv/metadata/use.keypad.without.useraction";
133 const char* kUseNativePcmdataDisclaimer =
134 "http://samsung.com/tv/metadata/use.native.pcmdata.disclaimer";
135 const char* kUseTension = "http://samsung.com/tv/metadata/use.tension";
136 const char* kUseTVWindow = "http://samsung.com/tv/metadata/use.tvwindow";
137 const char* kUseWebappProxy = "http://samsung.com/tv/metadata/use.webapp.proxy";
138 const char* kVoiceGuide = "http://samsung.com/tv/metadata/use.voiceguide";
139 const char* kVideoFlipMode = "http://samsung.com/tv/metadata/video.flip.mode";
140 const char* kWASMCachingSupport =
141 "http://samsung.com/tv/metadata/wasm.caching.support";
142 const char* kSuspendDelayTime =
143 "http://samsung.com/tv/metadata/suspend.delay"; // max value 3000ms
145 #if !TIZEN_VERSION_AT_LEAST(8, 0, 0)
146 const char* kPointingDeviceSupport = "wm.cursormanager.pointing.device.support";
148 const char* kScreenshotPath = "/home/owner/apps_rw/xwalk-service/screenshot/";
150 const char* kMultiPlayerSupport =
151 "http://samsung.com/tv/metadata/multiplayer.support";
153 const int kPannelToGraphicSize = 2;
154 const int kRotationDelayMS = 500;
155 const int kMaxWidgetPosition = 4;
156 const double kScaleFactorDefault = 1.0;
157 const double kScaleFactorLandscapeScale = 0.5625;
159 unsigned int global_resource_id = 0;
160 unsigned int wayland_window_id = 0;
162 void HandleResourceId(
163 void* data, struct tizen_resource* tizen_resource, uint32_t id) {
164 global_resource_id = id;
165 LOG(INFO) << "got global resource id(" << id << ") from server ";
166 auto resource_id = std::to_string(id);
167 setenv("global_resource_id", resource_id.c_str(), true);
170 void GetScreenResolution(int& width, int& height) {
171 auto bounds = ui::EflScreen::GetDisplaySize();
172 width = bounds.width();
173 height = bounds.height();
174 LOG(INFO) << "screen resolution = " << width << "x" << height;
177 void MultiviewStateChangedCb(keynode_t* keynodeName, void* data) {
178 if (!data || !keynodeName) {
179 LOG(ERROR) << "keynodeName | data is NULL";
182 std::string multiview_state = vconf_keynode_get_str(keynodeName);
183 LOG(INFO) << "MultiviewState change[" << multiview_state << "]";
185 WRTNativeWindowTV* native_window_tv =
186 static_cast<WRTNativeWindowTV*>(data);
187 int width = 1920, height = 1080;
188 GetScreenResolution(width, height);
189 if (native_window_tv->IsMultiScreenShowed(multiview_state))
190 native_window_tv->SetScreenResolution(width * 0.3165, height);
192 native_window_tv->SetScreenResolution(width, height);
195 #if defined(TIZEN_PEPPER_EXTENSIONS)
196 bool AddNewElementToDictionary(Ewk_Value dictionary,
197 const char* key_string,
198 const char* value_string) {
199 LOG(ERROR) << "Adding [" << key_string << "] -> [" << value_string << "]";
200 Ewk_Value key = ewk_value_string_new(key_string);
201 if (key == nullptr) {
202 LOG(ERROR) << "ewk_value_string_new with key string: " << key_string
206 Ewk_Value value = ewk_value_string_new(value_string);
207 if (value == nullptr) {
208 LOG(ERROR) << "ewk_value_string_new with value string: " << value_string
210 ewk_value_unref(key);
214 bool result = ewk_value_dictionary_add(dictionary, key, value, &new_entry);
215 ewk_value_unref(key);
216 ewk_value_unref(value);
218 LOG(ERROR) << "ewk_value_dictionary_add with key: " << key_string
219 << ", value: " << value_string << " failed";
220 return result && new_entry;
224 void SetDiskCacheEnableOnIOThread(
225 content::StoragePartition* storage_partition) {
226 if (!storage_partition)
229 auto network_context = storage_partition->GetNetworkContext();
230 if (!network_context)
233 LOG(INFO) << "Set diskCache mode to net::HttpCache::NORMAL";
234 #if !defined(WRT_JS_BRINGUP)
235 network_context->SetCacheMode(true);
239 void OnScreenshotCapturedCB(Evas_Object* image, void* user_data) {
240 auto file_name = static_cast<const char*>(user_data);
241 auto& app_data = ApplicationData::GetInstance();
242 auto file_path = base::FilePath(kScreenshotPath)
243 .Append(app_data.GetPackageID())
245 base::CreateDirectory(file_path.DirName());
246 LOG(INFO) << "screenshot is saved at " << file_path.value();
247 evas_object_image_save(image, file_path.value().c_str(), NULL, NULL);
251 WRTNativeWindow::ScreenOrientation ConvertRotatorOrientation(
252 display_rotator_orientation_e rotator_orientation) {
253 switch (rotator_orientation) {
254 case DISPLAY_ROTATOR_ORIENTATION_PORTRAIT:
255 case DISPLAY_ROTATOR_ORIENTATION_PORTRAIT_R:
256 return WRTNativeWindow::ScreenOrientation::PORTRAIT_PRIMARY;
257 case DISPLAY_ROTATOR_ORIENTATION_LANDSCAPE:
258 case DISPLAY_ROTATOR_ORIENTATION_LANDSCAPE_R:
259 return WRTNativeWindow::ScreenOrientation::LANDSCAPE_PRIMARY;
263 return WRTNativeWindow::ScreenOrientation::NONE;
266 WRTNativeWindow::ScreenOrientation ConvertSensorOrientation(
267 float sensor_orientation) {
268 auto orientation = static_cast<SensorOrientation>(sensor_orientation);
269 switch (orientation) {
270 case SensorOrientation::PORTRAIT:
271 case SensorOrientation::PORTRAIT_REVERSED:
272 return WRTNativeWindow::ScreenOrientation::PORTRAIT_PRIMARY;
273 case SensorOrientation::LANDSCAPE:
274 case SensorOrientation::LANDSCAPE_REVERSED:
275 return WRTNativeWindow::ScreenOrientation::LANDSCAPE_PRIMARY;
279 return WRTNativeWindow::ScreenOrientation::NONE;
282 bool CanSupportLandscapeScale() {
283 auto is_signage = IsSignageProduct();
286 auto rotate_status = VconfHandle(kMenuOrientation).Int();
287 auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
288 auto is_landscape_scale =
289 "landscape_scale" == meta_data_info.GetValue(kScreenOrientation);
290 return is_signage && is_landscape_scale && (rotate_status == 1);
293 #if TIZEN_VERSION_AT_LEAST(6, 0, 0)
294 bool OnDisplayRotatorAddCB(display_rotator_status_t* rotator_status,
296 LOG(INFO) << "display rotator callback is invoked!";
300 auto orientation = ConvertRotatorOrientation(rotator_status->orientation);
301 auto native_window_tv = WRTNativeWindowTV::GetMainNativeWindow();
302 if (native_window_tv)
303 native_window_tv->SetScreenOrientation(orientation);
311 std::string WRTNativeWindowTV::menu_zoom_fill_ = "";
314 WRTNativeWindowTV* WRTNativeWindowTV::GetMainNativeWindow() {
315 return static_cast<WRTNativeWindowTV*>(WRTNativeWindow::GetMainNativeWindow());
319 void WRTNativeWindowTV::NotifyWindowShowIfVisible() {
320 auto native_window_tv = GetMainNativeWindow();
321 if (!native_window_tv)
324 auto visibility_state = native_window_tv->GetVisibilityState();
325 LOG(INFO) << "visible state = " << visibility_state;
326 // for modal window, JSD / popup / tvwindow
327 if ("visible" == visibility_state)
328 native_window_tv->NotifyWindowShow();
332 void WRTNativeWindowTV::SetWindowBorderAlpha() {
333 auto* delegate = GetNativeWindowDelegate();
335 delegate->SetWindowBorderAlpha();
338 unsigned int WRTNativeWindowTV::GetGlobalResourceId() {
339 return global_resource_id;
342 int WRTNativeWindowTV::GetWindowLayer() {
343 auto* ee = GetPlatformCanvas();
345 return ecore_evas_layer_get(ee);
350 WRTNativeWindowTV::WRTNativeWindowTV(const gin_helper::Dictionary& options,
351 electron::NativeWindow* parent)
352 : WRTNativeWindow::WRTNativeWindow(options, parent),
355 channel_changeable_(false),
356 use_tv_window_(false),
357 graphic_plane_support_(false),
358 skip_disable_tvmenu_(false),
359 window_user_geometry_(false),
360 rotation_listener_(nullptr) {}
362 WRTNativeWindowTV::~WRTNativeWindowTV() {
366 void WRTNativeWindowTV::SetWebContents(content::WebContents* web_contents) {
367 LOG(INFO) << "WRTNativeWindowTV::SetWebContents()";
368 WRTNativeWindow::SetWebContents(web_contents);
370 SetAppMetaDataInfoRelatedWindow();
371 auto* ewk_view = view_evas();
373 InputDeviceManager::GetInstance()->Initialize(ewk_view);
375 if (!is_main_native_window_)
378 top_window_ = GetTopWindow();
379 SetGlobalResourceId(GetPlatformCanvas());
381 #if defined(TIZEN_PEPPER_EXTENSIONS)
382 InitializePepperExtensionSystem();
384 #if defined(TIZEN_ATK_FEATURE_VD)
385 EWebAccessibilityUtil::GetInstance();
387 if (GetProductType() == "IWB")
388 DecoratorWindow::GetInstance()->SetDecoratorWindow(top_window_);
389 TvWindowManager::GetInstance()->Initialize(top_window_);
390 if (!IsVisualControllerSupported())
391 SetDisplayRotatorCallback();
392 SetAppMetaDataInfo();
393 SetRuntimeVariables();
396 UnsetSuspendDelayForNonMultitasking();
399 void WRTNativeWindowTV::Finalize() {
400 LOG(INFO) << "WRTNativeWindowTV::Finalize()";
401 if (!is_main_native_window_)
404 InputDeviceManager::GetInstance()->Finalize();
405 TvWindowManager::GetInstance()->Finalize();
406 if (suspend_timer_.IsRunning())
407 suspend_timer_.Stop();
408 if (screensaver_reset_timer_.IsRunning())
409 screensaver_reset_timer_.Stop();
410 #if TIZEN_VERSION_AT_LEAST(6, 0, 0)
411 display_rotator_remove_cb(OnDisplayRotatorAddCB);
413 display_rotator_unregister_cb();
415 UnRegisterRotateSensorListener();
416 vconf_ignore_key_changed(kMultiScreenInfoVconfKey, MultiviewStateChangedCb);
419 void WRTNativeWindowTV::CloseImmediately() {
420 if (is_main_native_window_) {
421 if ("visible" == visibility_state_) {
422 LOG(INFO) << "window will be lower before close";
425 #if defined(TIZEN_PEPPER_EXTENSIONS)
426 UnregisterPepperExtensionDelegate();
428 DisableVisibilitySetting();
430 WRTNativeWindow::CloseImmediately();
433 bool WRTNativeWindowTV::IsRunningAsBackground() {
434 return AmbientMode::IsRunningAsBackground();
438 bool WRTNativeWindowTV::SetRotation() {
439 if (IsSignageProduct())
442 auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
443 if (meta_data_info.GetValue(kScreenOrientation) == "portrait") {
444 int angle = GetScreenAngleForPortraitMode();
445 LOG(INFO) << "ScreenOrientation is PORTRAIT angle=" << angle;
446 SetRotationState(false, angle);
448 if (meta_data_info.GetValue(kStateByRotation) == "lock") {
450 "kStateByRotation is lock add hint screencontrol.transform disable";
451 ecore_evas_aux_hint_add(GetPlatformCanvas(),
452 "wm.policy.win.screencontrol.transform", "disable");
453 } else if (meta_data_info.GetValue(kScreenOrientation) == "all") {
454 LOG(INFO) << "ScreenOrientation is all";
455 SetRotationState(true);
460 std::string WRTNativeWindowTV::GetPointDeviceOptionValue() {
461 static std::string pointing_device_support;
462 if (!pointing_device_support.empty())
463 return pointing_device_support;
465 pointing_device_support =
466 ApplicationDataTV::GetInstance().PointDeviceOption();
468 // for LFD or IWB, default mouse cursor is enable, for example if
469 // point_device_option value is empty, means support mouse cursor
470 if (IsSignageProduct() && pointing_device_support.empty())
471 pointing_device_support = "enable";
473 LOG(INFO) << "pointing_device_support = " << pointing_device_support;
474 return pointing_device_support;
477 bool WRTNativeWindowTV::NeedSetCursorPointer() {
478 // for System default support mouse
479 if (IsMouseCursorSupportedModel())
482 std::string point_device_option = GetPointDeviceOptionValue();
484 // for normal products, default mouse cursor is disable, for example if
485 // point_device_option value is empty, means not support mouse cursor
486 return (point_device_option == "enable" ||
487 point_device_option == "mouse-no-hide");
490 void WRTNativeWindowTV::CreateMouseCursor(Evas_Object* window) {
491 static absl::optional<bool> mouse_initialize = false;
492 if (mouse_initialize.value())
495 if (!NeedSetCursorPointer()) {
496 mouse_initialize = true;
500 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(nullptr);
501 struct wl_display* display = ecore_wl2_display_get(wl2_display);
502 Eina_Iterator* globals = ecore_wl2_display_globals_get(wl2_display);
503 struct wl_registry* registry = ecore_wl2_display_registry_get(wl2_display);
504 Ecore_Wl2_Input* input = ecore_wl2_input_default_input_get(wl2_display);
505 struct wl_seat* seat = ecore_wl2_input_seat_get(input);
507 Ecore_Wl2_Global* global;
508 EINA_ITERATOR_FOREACH(globals, global) {
509 if (!strcmp(global->interface, "tizen_cursor"))
510 if (!CursorModule_Initialize(display, registry, seat, global->id))
511 LOG(ERROR) << "cursor module initial failed";
513 eina_iterator_free(globals);
514 struct wl_surface* const surface =
515 ecore_wl2_window_surface_get(ecore_evas_wayland2_window_get(
516 ecore_evas_ecore_evas_get(evas_object_evas_get(window))));
519 std::string floating_navigation =
520 ApplicationData::GetInstance().GetMetadata(kFloatingNavigation);
521 LOG(INFO) << "floating_navigation = " << floating_navigation;
523 std::string pointing_device_support = GetPointDeviceOptionValue();
525 if (IsMouseCursorSupportedModel() && (pointing_device_support.empty() ||
526 pointing_device_support == "disable")) {
527 LOG(INFO) << "System default support mouse, but app unsupport mouse.";
528 #if TIZEN_VERSION_AT_LEAST(8, 0, 0)
529 Ecore_Wl2_Window* ecore_wl2_win = ecore_evas_wayland2_window_get(
530 ecore_evas_ecore_evas_get(evas_object_evas_get(window)));
531 if (floating_navigation == "false")
532 Mouse_Pointer_Not_Allow(ENABLE, ecore_wl2_win);
534 Mouse_Pointer_Support(DISABLE, ecore_wl2_win);
536 ecore_evas_aux_hint_add(GetPlatformCanvas(), kPointingDeviceSupport, "0");
537 ecore_wl2_input_cursor_theme_name_set(input, "vd-cursors");
538 ecore_wl2_input_cursor_from_name_set(input, "normal_transparent");
540 if (auto* rwhva = GetRenderWidgetHostView()) {
541 rwhva->aura_efl_helper()->SetMouseEventsEnabled(false);
543 LOG(WARNING) << "rwhva is null, cannot set cursor by client";
545 #if !TIZEN_VERSION_AT_LEAST(8, 0, 0)
546 ecore_evas_aux_hint_add(GetPlatformCanvas(), kPointingDeviceSupport, "1");
549 if (IsMouseCursorSupportedModel() && floating_navigation == "false") {
550 ecore_evas_aux_hint_add(GetPlatformCanvas(),
551 "wm.cursormanager.floating.menu.support", "0");
553 if (Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE,
555 if (pointing_device_support == "mouse-no-hide") {
556 if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_NOT_HIDE_CURSOR,
558 LOG(ERROR) << "set cursor config no hide failed";
561 LOG(ERROR) << "set cursor config avaiable failed";
565 CursorModule_Finalize();
566 mouse_initialize = true;
570 void WRTNativeWindowTV::SetGlobalResourceId(Ecore_Evas* ee) {
571 if (global_resource_id)
574 Ecore_Wl2_Window* wl_window = ecore_evas_wayland2_window_get(ee);
576 static_cast<unsigned int>(ecore_wl2_window_id_get(wl_window));
577 LOG(INFO) << "ee = " << ee << ", wl_window = " << wl_window
578 << ", windowid = " << wayland_window_id;
579 struct wl_surface* wl_surface =
580 (struct wl_surface*)ecore_wl2_window_surface_get(wl_window);
581 Ecore_Wl2_Display* wl2_display = ecore_wl2_connected_display_get(nullptr);
582 struct wl_display* wl_display = ecore_wl2_display_get(wl2_display);
584 LOG(ERROR) << "error to find display (wl_display is null)";
589 LOG(ERROR) << "error to find display (wl_surface is null)";
593 struct wl_registry* wl_registry = wl_display_get_registry(wl_display);
595 LOG(ERROR) << "error to find display (wl_registry is null)";
599 struct wl_event_queue* wl_queue = wl_display_create_queue(wl_display);
601 LOG(ERROR) << "error to find display (wl_queue is null)";
604 static const struct tizen_resource_listener tz_resource_listener = {
608 Eina_Iterator* l = ecore_wl2_display_globals_get(wl2_display);
609 struct tizen_surface* tz_surface = nullptr;
610 Ecore_Wl2_Global* global;
611 EINA_ITERATOR_FOREACH(l, global) {
612 if (strcmp(global->interface, "tizen_surface") == 0) {
613 tz_surface = static_cast<tizen_surface*>(wl_registry_bind(wl_registry,
614 global->id, &tizen_surface_interface, global->version));
616 LOG(ERROR) << "error to find display";
620 eina_iterator_free(l);
622 struct tizen_resource* tz_resource =
623 tizen_surface_get_tizen_resource(tz_surface, wl_surface);
626 wl_proxy_set_queue((struct wl_proxy*)tz_resource, wl_queue);
627 tizen_resource_add_listener(tz_resource, &tz_resource_listener, nullptr);
628 wl_display_roundtrip_queue(wl_display, wl_queue);
630 LOG(ERROR) << "error to find tz_resource";
633 tizen_resource_destroy(tz_resource);
635 tizen_surface_destroy(tz_surface);
637 wl_registry_destroy(wl_registry);
639 wl_event_queue_destroy(wl_queue);
642 void WRTNativeWindowTV::SetAppMetaDataInfo() {
643 auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
645 if (meta_data_info.GetValue(kUseNativePcmdataDisclaimer) == "true") {
646 auto& widget_info = ApplicationData::GetInstance().widget_info();
647 auto app_title = widget_info.name_set().cbegin()->second;
648 NativeWebRuntimeDelegateTV::GetInstance().SetAppTitleForPcm(app_title);
649 LOG(INFO) << "PCMDataDisClaimerAppTitle, app title: " << app_title;
652 if (!meta_data_info.GetValue(kChannelBound).empty()) {
653 LOG(INFO) << "channelnumber is " << meta_data_info.GetValue(kChannelBound);
654 SetWindowAlpha(true);
657 if (meta_data_info.GetValue(kGpuRasterization) == "true") {
658 LOG(ERROR) << "gpu.rasterization.support!!";
659 auto current_command_line = base::CommandLine::ForCurrentProcess();
660 current_command_line->AppendSwitch(switches::kEnableGpuRasterization);
663 if (meta_data_info.GetValue(kUseTVWindow) == "true") {
664 LOG(INFO) << "use.tvwindow is true!!";
665 SetInvisibleDelivery();
668 if (meta_data_info.GetValue(kKeyboardFunc) == "true") {
669 LOG(INFO) << "use.keyboardfunckey is true!!";
670 SetKeyboardFuncKey();
673 if (meta_data_info.GetValue(kKeyboardFunc) == "convertOriginalKey") {
674 LOG(INFO) << "use.keyboardfunckey value is convertOriginalKey!!";
675 SetKeyboardFuncKey();
676 InputDeviceManager::GetInstance()->SetKeyboardFuncKey();
679 if (meta_data_info.GetValue(kGraphicPlaneSupport) == "true") {
680 LOG(INFO) << "graphic.plane.support is true!!";
681 SetUseGraphicPlane();
684 if (meta_data_info.GetValue(kScreenResolution) == "uhd_subwindow") {
687 if (GetPanelResolution(&width, &height))
688 SetScreenResolution(width > 0 ? width / 4 : 0, height);
690 SetScreenResolution(960, 2160);
691 } else if (meta_data_info.GetValue(kScreenResolution) == "uhd_window")
692 SetScreenResolution(3840, 2160);
694 if (meta_data_info.GetValue(kOpaqueSupport) == "true") {
695 LOG(INFO) << "transparent.opaque.support is true!!";
699 if (meta_data_info.GetValue(kUseDimScreen) == "true") {
700 LOG(INFO) << "use.dimscreen is true!!";
704 if (meta_data_info.GetValue(kPartial) == "true") {
705 LOG(INFO) << "partial.overlay.support is true!!";
709 if ((meta_data_info.GetValue(kTransparent) == "true" ||
710 meta_data_info.GetValue(kTransparent) == "tv")) {
711 LOG(INFO) << "transparent.support is true/tv!!";
712 SetWindowAlpha(true);
713 channel_changeable_ = true;
716 if (meta_data_info.GetValue(kSkipDisable) == "true") {
717 LOG(INFO) << "skip.disable.tvmenu is true!!";
718 skip_disable_tvmenu_ = true;
721 if (meta_data_info.GetValue(kUseTension) == "false") {
722 LOG(INFO) << "use.tension is false!!";
723 SetWindowEffect(false);
726 if (meta_data_info.GetValue(kVoiceGuide) == "false") {
727 LOG(INFO) << "use.voiceguide is false!!";
728 #if defined(TIZEN_ATK_FEATURE_VD)
729 EWebAccessibilityUtil::GetInstance()->Deactivate(true);
733 #if !defined(WRT_JS_BRINGUP)
734 if (meta_data_info.GetValue(kSetCookie) == "true") {
735 LOG(INFO) << "enable.setcookie is true!!";
736 net::HttpResponseHeaders::SetDiscloseSetCookieEnabled(true);
740 if (meta_data_info.GetValue(kVideoFlipMode) == "true") {
741 LOG(INFO) << "video.flip.mode is true!!";
742 ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.video.flip.mode", "1");
745 if (meta_data_info.GetValue(kWASMCachingSupport) == "true") {
746 LOG(INFO) << "wasm.caching.support is true!!";
747 auto app_id = ApplicationData::GetInstance().app_id();
748 WRTService::StopBuiltinService("wasm_builder", app_id);
751 if (meta_data_info.GetValue(kDualDecodingWebRTC) == "true") {
752 auto current_command_line = base::CommandLine::ForCurrentProcess();
753 current_command_line->AppendSwitch(switches::kDualDecodingWebRTC);
756 if (meta_data_info.GetValue(kMultiPlayerSupport) == "true") {
757 auto current_command_line = base::CommandLine::ForCurrentProcess();
758 current_command_line->AppendSwitch(switches::kEnableMultiPlayerForWebapp);
761 const bool enable_game_mode = (meta_data_info.GetValue(kGameMode) == "true");
762 const bool legacy_game_mode =
763 (meta_data_info.GetValue(kLegacyGameMode) == "true");
764 const bool enable_upstream_architecture =
765 (meta_data_info.GetValue(kUpstreamArchitecture) == "true");
767 if (enable_game_mode || legacy_game_mode) {
768 auto current_command_line = base::CommandLine::ForCurrentProcess();
769 current_command_line->AppendSwitch(switches::kEnableGameMode);
770 base::FieldTrialList::CreateFieldTrial("WebRTC-ForceZeroDelayInGameMode",
772 base::FieldTrialList::CreateFieldTrial("WebRTC-ForceNackBeforeRtt",
776 if (meta_data_info.GetValue(kNDecoding) == "true") {
777 auto current_command_line = base::CommandLine::ForCurrentProcess();
778 current_command_line->AppendSwitch(switches::kEnableNDecoding);
781 if (legacy_game_mode) {
782 auto current_command_line = base::CommandLine::ForCurrentProcess();
783 current_command_line->AppendSwitch(switches::kEnableLegacyGameMode);
786 if (enable_upstream_architecture || enable_game_mode) {
787 auto current_command_line = base::CommandLine::ForCurrentProcess();
788 LOG(INFO) << "Use upstream architecture";
789 current_command_line->AppendSwitch(switches::kEnableUpstreamArchitecture);
792 if (meta_data_info.GetValue(kScreenOrientationMultiView) == "portrait") {
793 SetWinUserGeometry();
794 ecore_evas_aux_hint_add(
795 GetPlatformCanvas(), "wm.policy.win.transform.mode", "ratiofit");
797 auto multi_screen_showed = VconfHandle(kMultiScreenInfoVconfKey).Str();
798 if (IsMultiScreenShowed(multi_screen_showed)) {
799 int width = 1920, height = 1080;
800 GetScreenResolution(width, height);
801 SetScreenResolution(width * 0.3165, height);
803 vconf_notify_key_changed(kMultiScreenInfoVconfKey,
804 MultiviewStateChangedCb, this);
807 if (meta_data_info.GetValue(kFrameRawDataCopy) == "true") {
808 auto current_command_line = base::CommandLine::ForCurrentProcess();
809 current_command_line->AppendSwitch(switches::kEnableFrameRawDataCopy);
812 if (meta_data_info.HasKey(kErrorPagePath)) {
813 error_page_path_ = ApplicationData::GetInstance().application_path() +
814 meta_data_info.GetValue(kErrorPagePath);
817 if (meta_data_info.GetValue(kDisableScreenSaver) == "true") {
818 LOG(INFO) << "disable.screensaver.partialvideo is true";
819 ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.screensaver.reset.allowed",
821 ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.luminescence.mode",
825 auto use_conformant = meta_data_info.GetValue(kUseConformant);
826 if (!use_conformant.empty()) {
827 LOG(INFO) << "use.conformant is " << use_conformant;
828 auto* delegate = GetNativeWindowDelegate();
829 if (use_conformant == "false") {
830 delegate->SetConformantObject(true);
831 } else if (use_conformant == "floating") {
832 use_floating_ime_ = true;
833 delegate->SetConformantObject(true);
838 LOG(INFO) << "use.focus is false!!";
842 auto zoom_fill = meta_data_info.GetValue(kContentZoomFill);
843 if ((zoom_fill == "enable") || (zoom_fill == "disable")) {
844 LOG(INFO) << "zoom fill is " << zoom_fill;
845 menu_zoom_fill_ = meta_data_info.GetValue(kContentZoomFill);
849 void WRTNativeWindowTV::SetAppMetaDataInfoRelatedWindow() {
850 auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
851 if (meta_data_info.HasKey(kSuspendDelayTime)) {
852 auto delay_time = atoi(meta_data_info.GetValue(kSuspendDelayTime).c_str());
853 SetSuspendDelay(delay_time);
854 LOG(INFO) << "app config suspend delay time is " << delay_time
855 << " ms(range need in [0,1000]ms)";
858 use_focus_ = !(meta_data_info.GetValue(kUseFocus) == "false");
861 void WRTNativeWindowTV::GetImeAndKeyPadConfig(
862 bool& show_ime_panel,
863 bool& ime_is_floating,
864 bool& keypad_without_user_action) {
865 auto& app_data = ApplicationData::GetInstance();
866 if (app_data.GetMetadata(kUseIME) == "false") {
867 LOG(INFO) << "use.ime is false!!";
868 show_ime_panel = false;
870 ime_is_floating = use_floating_ime_;
871 if (!(app_data.GetMetadata(kUseKeyPad) == "false")) {
872 LOG(INFO) << "use.keypad.without.useraction is not false!!";
873 keypad_without_user_action = true;
877 bool WRTNativeWindowTV::IsMultiScreenShowed(const std::string& multiview_config) {
880 if (!reader.parse(multiview_config, root)) {
881 LOG(ERROR) << "Fail to parse vconf value [" << multiview_config << "]";
884 std::string mode = root["mode"].asString();
885 LOG(INFO) << "MultiviewState [" << mode << "]";
889 void WRTNativeWindowTV::SetRuntimeVariables() {
890 auto& runtime = NativeWebRuntime::GetInstance();
892 LOG(INFO) << "global_resource_id : " << global_resource_id;
893 runtime.SetRuntimeVariable("global_resource_id",
894 std::to_string(global_resource_id));
896 std::ostringstream ostr_window_id;
897 ostr_window_id << top_window_;
898 LOG(INFO) << "window_id : " << ostr_window_id.str();
899 runtime.SetRuntimeVariable("window_id", ostr_window_id.str());
901 auto& app_data = ApplicationData::GetInstance();
902 std::string app_version = app_data.widget_info().version();
903 LOG(INFO) << "widget_version : " << app_version;
904 runtime.SetRuntimeVariable("widget_version", app_version);
907 void WRTNativeWindowTV::SetProxyInfo() {
908 auto* browser_context = WRTBrowserContext::GetInstance();
909 DCHECK(browser_context);
910 std::string proxy_info;
911 auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
912 if (meta_data_info.GetValue(kUseWebappProxy) == "true") {
913 LOG(INFO) << "use.webapp.proxy is true";
914 proxy_info = VconfHandle(kWebAppProxyVconfKey).Str();
916 proxy_info = VconfHandle(kProxyVconfKey).Str();
918 if (proxy_info.empty() || proxy_info.find("://") == std::string::npos) {
919 LOG(INFO) << "proxy address : " << proxy_info;
922 NativeWebRuntimeDelegateTV::GetInstance().SetProxyInfo(proxy_info);
924 #if !defined(WRT_JS_BRINGUP)
925 char protocol[10], usrname[64], password[64], uri[64];
926 std::size_t found = proxy_info.find_last_of("@");
927 if (found != std::string::npos) {
928 sscanf(proxy_info.substr(0, found).c_str(),
929 "%9[^:/]://%63[^:]:%63s", protocol, usrname, password);
930 sscanf(proxy_info.substr(found + 1).c_str(), "%63s", uri);
931 browser_context->SetProxyUsername(usrname);
932 browser_context->SetProxyPassword(password);
934 sscanf(proxy_info.c_str(), "%9[^:/]://%63s", protocol, uri);
936 browser_context->SetProxyURI(uri);
937 browser_context->SetProxyProtocol(protocol);
939 std::string bypass_rule = VconfHandle(kProxyExceptionList).Str();
941 // Add proxy settings
942 browser::ProxyConfigMonitor::GetInstance()->UpdateProxyConfig(
943 std::string(uri), bypass_rule);
947 void WRTNativeWindowTV::SetDiskCacheMode() {
948 auto* browser_context = NativeWebRuntime::GetBrowserContext();
949 if (!browser_context) {
950 LOG(ERROR) << "browser context is null, not set diskcache mode";
953 if (!NativeWebRuntimeDelegateTV::GetInstance().GetDiskCachePath().empty()) {
954 content::GetIOThreadTaskRunner({})->PostTask(
956 base::BindOnce(&SetDiskCacheEnableOnIOThread,
957 browser_context->GetDefaultStoragePartition()));
961 void WRTNativeWindowTV::SetUseGraphicPlane() {
962 LOG(INFO) << "called : wm.policy.win.user.geometry and wm.epop.window";
963 auto* ee = GetPlatformCanvas();
964 ecore_evas_aux_hint_add(ee, "wm.epop.window", "1");
965 ecore_evas_aux_hint_add(ee, "wm.policy.win.user.geometry", "1");
966 graphic_plane_support_ = true;
969 void WRTNativeWindowTV::SetWindowAlpha(bool alpha) {
970 LOG(INFO) << "Setting window Alpha : " << alpha;
973 Eina_Bool alpha_enable = alpha ? EINA_TRUE : EINA_FALSE;
974 ecore_evas_alpha_set(GetPlatformCanvas(), alpha_enable);
977 void WRTNativeWindowTV::SetUseFocus(bool use_focus) {
978 LOG(INFO) << "SetUseFocus : " << use_focus;
979 ecore_evas_focus_skip_set(GetPlatformCanvas(), !use_focus);
981 InputDeviceManager::GetInstance()->Initialize(view_evas());
985 void WRTNativeWindowTV::SetDimScreen() {
986 LOG(INFO) << "SetDimScreen, alphaset is " << alphaset_;
988 ecore_evas_aux_hint_add(
989 GetPlatformCanvas(), "wm.policy.win.accept.dim", "1");
993 void WRTNativeWindowTV::SetWindowOpaque() {
994 // opaque The value that indicates whether the window has set a visual state
995 // to opaque (0: unset, 1: set)
996 efl_util_set_window_opaque_state(top_window_, true);
999 void WRTNativeWindowTV::SetScreenResolution(unsigned int width,
1000 unsigned int height) {
1001 LOG(INFO) << "called : width(" << width << "), height(" << height << ")";
1003 evas_object_geometry_get(view_evas(), &x, &y, nullptr, nullptr);
1004 gfx::Rect bounds(x, y, width, height);
1006 auto* efl_window = GetWindowTreeHost()->platform_window();
1007 efl_window->SetBoundsInPixels(bounds);
1009 bounds.set_origin({0, 0});
1013 void WRTNativeWindowTV::HalfWindowSupport(std::string position) {
1014 int w = 0, h = 0, x = 0, y = 0;
1015 GetScreenResolution(w, h);
1017 if (position == "LEFT")
1019 else if (position == "RIGHT") {
1022 } else if (position == "TOP")
1024 else if (position == "BOTTOM") {
1027 } else if (position == "RWI") { // quator size window and right and center
1032 } else if (position != "RESET")
1035 LOG(INFO) << "x:" << x << ", y:" << y << ", w:" << w << ", h:" << h;
1036 ecore_evas_aux_hint_add(
1037 GetPlatformCanvas(), "wm.policy.win.user.geometry", "1");
1038 gfx::Rect bounds(x, y, w, h);
1039 auto* efl_window = GetWindowTreeHost()->platform_window();
1040 efl_window->SetBoundsInPixels(bounds);
1041 ecore_evas_move(GetPlatformCanvas(), x, y);
1044 void WRTNativeWindowTV::Hide() {
1045 WRTNativeWindow::Hide();
1047 if (electron::Browser::Get()->is_quitting()) {
1048 LOG(ERROR) << "App is quitting, hide backexecution app's window is skipped";
1051 auto& app_data = wrt::ApplicationData::GetInstance();
1052 if (app_data.GetMetadata(kForceHideWindow) == "true") {
1053 auto* top_window = WRTNativeWindow::GetTopWindow();
1056 LOG(INFO) << "Will hide window forcely";
1057 evas_object_hide(top_window);
1061 void WRTNativeWindowTV::SetKeyboardFuncKey() {
1062 Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(top_window_));
1063 Ecore_Wl2_Window* wl_win = ecore_evas_wayland2_window_get(ee);
1064 struct wl_surface* surface = ecore_wl2_window_surface_get(wl_win);
1066 KeyRouter_Set_InputConfig(
1067 +surface, TIZEN_TV_KEYROUTER_CONFIG_MODE_USE_KEYBOARD_FUNC_KEY, nullptr);
1070 void WRTNativeWindowTV::SetInvisibleDelivery() {
1071 Ecore_Evas* ee = ecore_evas_ecore_evas_get(evas_object_evas_get(top_window_));
1072 Ecore_Wl2_Window* wl_win = ecore_evas_wayland2_window_get(ee);
1073 struct wl_surface* surface = ecore_wl2_window_surface_get(wl_win);
1075 KeyRouter_Set_InputConfig(surface, TIZEN_KEYROUTER_CONFIG_MODE_INVISIBLE_SET,
1077 use_tv_window_ = true;
1080 void WRTNativeWindowTV::SetMenuZoomFill(const std::string& enable) {
1081 if (menu_zoom_fill_.empty())
1082 menu_zoom_fill_ = enable;
1085 void WRTNativeWindowTV::SetWindowEffect(bool enable) {
1086 ecore_evas_aux_hint_add(
1087 GetPlatformCanvas(), "wm.comp.win.effect.enable", (enable ? "1" : "0"));
1090 void WRTNativeWindowTV::EnableVisibilitySetting() {
1091 std::string app_id = ApplicationData::GetInstance().app_id();
1092 VconfHandle(kMostRecentApp).Set(app_id);
1094 if (channel_changeable_)
1095 VconfHandle(kBGChannelChange).Set(true);
1097 bool opt = (alphaset_ || use_tv_window_)
1098 ? (!graphic_plane_support_ && !partial_)
1100 VconfHandle("memory/VDWebApp/partial").Set(opt);
1101 LOG(INFO) << "memory/VDWebApp/partial set as " << opt;
1104 activateScreenSaver(const_cast<char*>("DEFAULT"),
1111 if (!skip_disable_tvmenu_) {
1112 std::list<std::string> disableItems;
1113 disableItems.push_back("broadcasting");
1114 disableItems.push_back("osd-language");
1115 disableItems.push_back("picturesize");
1116 disableItems.push_back("pip");
1117 disableItems.push_back("self-diagnosis");
1118 disableItems.push_back("setup");
1119 if (menu_zoom_fill_ == "disable") {
1120 disableItems.push_back("sm-zoom-to-fill");
1121 LOG(INFO) << "disable menu";
1123 SettingsAPI* settings = SettingsAPI::Get();
1125 settings->DisableItemsByList(disableItems, app_id);
1129 void WRTNativeWindowTV::DisableVisibilitySetting() {
1130 std::string app_id = ApplicationData::GetInstance().app_id();
1131 std::string most_recent_app = VconfHandle(kMostRecentApp).Str();
1133 if (app_id == most_recent_app)
1134 VconfHandle(kMostRecentApp).Set("none");
1136 if (channel_changeable_)
1137 VconfHandle(kBGChannelChange).Set(false);
1139 if (!skip_disable_tvmenu_) {
1140 SettingsAPI* settings = SettingsAPI::Get();
1142 settings->RemoveDisabledItemsByAppname(app_id);
1144 char json_str[512] = {0,};
1145 std::snprintf(json_str, sizeof(json_str),
1146 "{'app_id': '%s'}", app_id.c_str());
1147 LOG(INFO) << "Set apps_recent_changed as " << json_str;
1148 VconfHandle("memory/eden/apps/apps_recent_changed").Set(json_str);
1151 void WRTNativeWindowTV::VisibilityChangedAsBackground() {
1152 std::string app_id = ApplicationData::GetInstance().app_id();
1153 LOG(ERROR) << app_id << " is hidden from the screen";
1156 DisableVisibilitySetting();
1157 if (visibility_state_.empty() && !VideoSplashScreen::IsVSSPlaying())
1158 WidgetStateProvider::OnStatusChanged("behind");
1160 visibility_state_ = "hidden";
1161 OnVisibilityChange(false);
1162 VideoSplashScreen::FinalizeVSS();
1165 void WRTNativeWindowTV::VisibilityChangedAsForeground() {
1166 std::string app_id = ApplicationData::GetInstance().app_id();
1167 LOG(ERROR) << app_id << " has shown on the screen";
1169 SuspendMedia(false);
1170 CreateMouseCursor(top_window_);
1172 EnableVisibilitySetting();
1173 visibility_state_ = "visible";
1174 OnVisibilityChange(true);
1175 TvWindowManager::GetInstance()->SetMuteAudioVideo(false);
1178 void WRTNativeWindowTV::SetPageVisibility(bool visible) {
1182 WRTNativeWindow::SetPageVisibility(visible);
1185 VisibilityChangedAsForeground();
1187 VisibilityChangedAsBackground();
1189 auto* extension_manager = XWalkExtensionManager::GetInstance();
1190 extension_manager->NotifyWindowEvent("visibility", visibility_state_);
1192 #if defined(THREAD_BOOSTER_SERVICE)
1194 suspend_resume::NotifyStateChange(suspend_resume::State::RESUMED);
1196 suspend_resume::NotifyStateChange(suspend_resume::State::SUSPENDED);
1200 void WRTNativeWindowTV::OnVisibilityChange(bool visible) {
1201 std::stringstream script_format;
1203 << "(() => {var __event = new CustomEvent('tizenvisibilitychange', {"
1204 << "detail: { visible: " << visible << "}});"
1205 << "document.dispatchEvent(__event);"
1206 << "for (var i=0; i < window.frames.length; i++) {"
1207 << "window.frames[i].document.dispatchEvent(__event);}})()";
1208 ExecuteJavaScript(script_format.str());
1211 bool WRTNativeWindowTV::WillHandleConformantChange() {
1212 if (orientation_ == ScreenOrientation::NONE)
1215 int preferred_rotation =
1216 ecore_evas_wm_rotation_preferred_rotation_get(GetPlatformCanvas());
1217 if (preferred_rotation == 0 &&
1218 orientation_ != ScreenOrientation::LANDSCAPE_PRIMARY)
1223 bool WRTNativeWindowTV::ShouldHandleConformantChange() {
1224 return !use_floating_ime_;
1227 void WRTNativeWindowTV::ExecuteJavaScript(const std::string& script) {
1228 auto* rfh = GetRenderFrameHost();
1232 std::u16string script_converted;
1233 base::UTF8ToUTF16(script.c_str(), script.size(), &script_converted);
1234 rfh->ExecuteJavaScriptWithUserGestureForTests(
1235 script_converted, base::NullCallback());
1238 void WRTNativeWindowTV::SetWinUserGeometry() {
1239 LOG(INFO) << "called : wm.policy.win.user.geometry";
1240 if (window_user_geometry_)
1242 ecore_evas_aux_hint_add(
1243 GetPlatformCanvas(), "wm.policy.win.user.geometry", "1");
1244 window_user_geometry_ = true;
1247 void WRTNativeWindowTV::SetWindowPosition(unsigned int x, unsigned int y) {
1248 LOG(INFO) << "called : x(" << x << "), y(" << y << ")";
1249 ecore_evas_move(GetPlatformCanvas(), x, y);
1252 bool WRTNativeWindowTV::SetQuarterPosition(
1253 const std::string& position) {
1254 if (position.empty())
1257 LOG(INFO) << "SetQuarterPosition : " << position;
1258 int quarter_position = 0;
1259 base::StringToInt(position, &quarter_position);
1260 if (quarter_position > kMaxWidgetPosition) {
1262 } else if (quarter_position <= 0) {
1263 quarter_position = 1;
1265 int screen_width = 0, screen_height = 0;
1266 GetPanelResolution(&screen_width, &screen_height);
1270 screen_width /= kPannelToGraphicSize;
1271 int widget_left = ((screen_width / 4) * (quarter_position - 1));
1272 SetWinUserGeometry();
1273 SetWindowPosition(widget_left, 0);
1278 bool WRTNativeWindowTV::MoveWindow(const std::string& coordinate) {
1279 if (coordinate.empty())
1282 LOG(INFO) << "MoveWindow : " << coordinate;
1283 auto coordinate_vector = base::SplitString(coordinate, ",",
1284 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1285 if (coordinate_vector.size() != 2)
1288 int widget_left, widget_top;
1289 base::StringToInt(coordinate_vector[0], &widget_left);
1290 base::StringToInt(coordinate_vector[1], &widget_top);
1291 SetWinUserGeometry();
1292 SetWindowPosition(widget_left, widget_top);
1297 bool WRTNativeWindowTV::ResizeWindow(const std::string& resolution) {
1298 if (resolution.empty())
1301 LOG(INFO) << "ResizeWindow : " << resolution;
1302 auto resolution_vector = base::SplitString(resolution, ",",
1303 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
1304 if (resolution_vector.size() != 2)
1307 int widget_width, widget_height;
1308 base::StringToInt(resolution_vector[0], &widget_width);
1309 base::StringToInt(resolution_vector[1], &widget_height);
1310 SetWinUserGeometry();
1312 evas_object_resize(view_evas(), widget_width, widget_height);
1313 SetScreenResolution(widget_width, widget_height);
1318 #if defined(TIZEN_PEPPER_EXTENSIONS)
1319 void WRTNativeWindowTV::InitializePepperExtensionSystem() {
1320 RegisterPepperExtensionDelegate();
1322 SetPepperExtensionCallback();
1323 SetPepperExtensionWidgetInfo();
1324 widget_extension_sync_call_handlers_["RegisterKey"] =
1325 &WRTNativeWindowTV::RegisterKey;
1326 widget_extension_sync_call_handlers_["UnRegisterKey"] =
1327 &WRTNativeWindowTV::UnRegisterKey;
1330 EwkExtensionSystemDelegate* WRTNativeWindowTV::GetExtensionDelegate() {
1331 auto* render_frame_host = GetRenderFrameHost();
1332 if (!render_frame_host)
1335 return static_cast<EwkExtensionSystemDelegate*>(
1336 content::ExtensionSystemDelegateManager::GetInstance()
1337 ->GetDelegateForFrame(render_frame_id_));
1340 void WRTNativeWindowTV::SetWindowId() {
1341 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1343 LOG(ERROR) << "No delegate is available to set window id";
1346 if (global_resource_id)
1347 delegate->SetWindowId(global_resource_id);
1349 delegate->SetWindowId(top_window_);
1352 void WRTNativeWindowTV::RegisterPepperExtensionDelegate() {
1353 auto* render_frame_host = GetRenderFrameHost();
1354 if (!render_frame_host || !render_frame_host->GetProcess()) {
1355 LOG(ERROR) << "render_frame_host is nullptr, can't register delegate";
1359 render_frame_id_.render_process_id =
1360 render_frame_host->GetProcess()->GetID();
1361 render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
1363 EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
1364 content::ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
1365 render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
1368 void WRTNativeWindowTV::UnregisterPepperExtensionDelegate() {
1369 if (!GetRenderFrameHost()) {
1370 LOG(ERROR) << "web_contents_ is nullptr, can't unregister delegate";
1374 if (!content::ExtensionSystemDelegateManager::GetInstance()
1375 ->UnregisterDelegate(render_frame_id_))
1376 LOG(ERROR) << "Unregistering pepper extension delegate failed";
1379 void WRTNativeWindowTV::SetPepperExtensionWidgetInfo() {
1380 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1382 LOG(WARNING) << "No delegate is available to set extension info";
1385 Ewk_Value dictionary = ewk_value_dictionary_new();
1387 LOG(ERROR) << "Failed to create pepper extension info dictionary";
1390 auto& app_data = ApplicationData::GetInstance();
1391 std::string app_id = app_data.app_id();
1392 std::string app_path = app_data.application_path();
1393 std::string pkg_id = app_data.GetPackageID();
1394 std::string temp_path =
1395 std::string(tzplatform_getenv(TZ_SYS_VAR)) + "/tmp/pepper";
1396 std::string pers_path = app_data.GetUserDataPath() + "pepper";
1397 std::string version = app_data.widget_info().version();
1400 result && AddNewElementToDictionary(dictionary, "id", app_id.c_str());
1402 AddNewElementToDictionary(dictionary, "packageId", pkg_id.c_str());
1403 result = result && AddNewElementToDictionary(dictionary, "installPath",
1405 result = result && AddNewElementToDictionary(
1406 dictionary, "temporaryStoragePath", temp_path.c_str());
1408 result && AddNewElementToDictionary(dictionary, "persistentStoragePath",
1410 result = result && AddNewElementToDictionary(dictionary, "widgetVersion",
1412 LOG(ERROR) << "widgetVersion = " << version;
1415 LOG(ERROR) << "Failed to build pepper extension info dictionary";
1416 delegate->SetExtensionInfo(dictionary);
1417 ewk_value_unref(dictionary);
1420 void WRTNativeWindowTV::SetPepperExtensionCallback() {
1421 EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1423 LOG(WARNING) << "No delegate is available to set generic callback";
1426 auto callback = [](const char* operation_name, Ewk_Value operation_data,
1427 void* user_data) -> Ewk_Value {
1428 if (user_data == nullptr) {
1429 LOG(ERROR) << "User data is null, leaving callback";
1432 auto* self = static_cast<WRTNativeWindowTV*>(user_data);
1433 std::string operation_name_string{operation_name};
1435 self->widget_extension_sync_call_handlers_.find(operation_name_string);
1436 if (it == self->widget_extension_sync_call_handlers_.end())
1438 return (self->*(it->second))(operation_data);
1440 delegate->SetGenericSyncCallback(callback, this);
1443 Ewk_Value WRTNativeWindowTV::RegisterKey(Ewk_Value keyname) {
1444 if (InputDeviceManager::GetInstance()->RegisterKey(
1445 std::string(ewk_value_string_value_get(keyname)))) {
1446 return ewk_value_boolean_new(EINA_TRUE);
1448 return ewk_value_boolean_new(EINA_FALSE);
1451 Ewk_Value WRTNativeWindowTV::UnRegisterKey(Ewk_Value keyname) {
1452 if (InputDeviceManager::GetInstance()->UnregisterKey(
1453 std::string(ewk_value_string_value_get(keyname))))
1454 return ewk_value_boolean_new(EINA_TRUE);
1456 return ewk_value_boolean_new(EINA_FALSE);
1458 #endif // TIZEN_PEPPER_EXTENSIONS
1460 void WRTNativeWindowTV::SetScreenOrientation(ScreenOrientation orientation) {
1461 auto prev_orientation = orientation_;
1462 orientation_ = orientation;
1463 LOG(INFO) << "ScreenOrientation : " << static_cast<int>(orientation);
1464 if (orientation == ScreenOrientation::NONE)
1467 auto* delegate = GetNativeWindowDelegate();
1471 if (prev_orientation == ScreenOrientation::NONE)
1472 delegate->OnConformantChange();
1473 delegate->SetScreenOrientation(this, orientation);
1476 void WRTNativeWindowTV::SetDisplayRotatorCallback() {
1477 if (IsDisplayRotatorSupported()) {
1478 LOG(INFO) << "display_rotator_is_supported!";
1479 display_rotator_status_t status;
1480 if (display_rotator_get_status(&status) != DISPLAY_ROTATOR_OK)
1481 LOG(ERROR) << "display_rotator_get_status failed";
1483 auto orientation = ConvertRotatorOrientation(status.orientation);
1484 SetScreenOrientation(orientation);
1486 #if TIZEN_VERSION_AT_LEAST(6, 0, 0)
1487 if (DISPLAY_ROTATOR_OK !=
1488 display_rotator_add_cb(OnDisplayRotatorAddCB, nullptr))
1489 LOG(ERROR) << "display_rotator_add_cb failed.";
1491 auto callback = [](display_rotator_status_t* rotator_status, void* data) {
1492 LOG(INFO) << "display rotator callback is invoked!";
1493 if (!rotator_status)
1496 auto orientation = ConvertRotatorOrientation(rotator_status->orientation);
1497 auto native_window_tv = WRTNativeWindowTV::GetMainNativeWindow();
1498 if (native_window_tv)
1499 native_window_tv->SetScreenOrientation(orientation);
1501 if (DISPLAY_ROTATOR_OK != display_rotator_register_cb(0, callback, nullptr))
1502 LOG(ERROR) << "display_rotator_register_cb failed.";
1504 } else if (IsSensorSupported() && RegisterRotateSensorListener()) {
1505 sensor_event_s data = {0,};
1506 if (sensor_listener_read_data(rotation_listener_, &data) == SENSOR_ERROR_NONE) {
1507 LOG(INFO) << "set orientation from sendor listener.";
1508 auto orientation = ConvertSensorOrientation(data.values[0]);
1509 SetScreenOrientation(orientation);
1514 bool WRTNativeWindowTV::RegisterRotateSensorListener() {
1516 if (sensor_get_default_sensor(SENSOR_AUTO_ROTATION, &sensor)
1517 != SENSOR_ERROR_NONE) {
1518 LOG(ERROR) << "sensor_get_default_sensor is error!";
1521 if (sensor_create_listener(sensor, &rotation_listener_) != SENSOR_ERROR_NONE) {
1522 LOG(ERROR) << "sensor_create_listener is error!";
1526 auto callback = [](sensor_h sensor, sensor_event_s* event, void* data) {
1527 LOG(INFO) << "sensor listener callback is invoked!";
1528 if (!event || !sensor)
1532 sensor_get_type(sensor, &type);
1533 if (type != SENSOR_AUTO_ROTATION ) {
1534 LOG(INFO) << "not Rotation type!";
1538 auto orientation = ConvertSensorOrientation(event->values[0]);
1539 auto native_window_tv = WRTNativeWindowTV::GetMainNativeWindow();
1540 if (native_window_tv)
1541 native_window_tv->SetScreenOrientation(orientation);
1544 if (sensor_listener_set_event_cb(rotation_listener_, kRotationDelayMS,
1545 callback, nullptr) != SENSOR_ERROR_NONE) {
1546 LOG(ERROR) << "sensor_listener_set_event_cb is error!";
1549 if (sensor_listener_start(rotation_listener_) != SENSOR_ERROR_NONE) {
1550 LOG(ERROR) << "sensor_listener_start is error!";
1553 LOG(INFO) << "reigster rotate sensor listener successfully.";
1557 bool WRTNativeWindowTV::UnRegisterRotateSensorListener() {
1558 if (!rotation_listener_) {
1559 LOG(ERROR) << "rotation_listener_ is null!";
1562 if (sensor_listener_unset_event_cb(rotation_listener_) != SENSOR_ERROR_NONE) {
1563 LOG(ERROR) << "sensor_listener_unset_event_cb is error!";
1566 if (sensor_listener_stop(rotation_listener_) != SENSOR_ERROR_NONE) {
1567 LOG(ERROR) << "sensor_listener_stop is error!";
1570 if (sensor_destroy_listener(rotation_listener_) != SENSOR_ERROR_NONE) {
1571 LOG(ERROR) << "sensor_destroy_listener is error!";
1574 rotation_listener_ = nullptr;
1578 void WRTNativeWindowTV::SetKeyEventChecker() {
1579 auto* efl_window = GetWindowTreeHost()->platform_window();
1580 LOG(INFO) << "efl_window : " << efl_window;
1581 InputDeviceManager::GetInstance()->SetKeyEventChecker(
1582 efl_window->GetEventHandler());
1585 void WRTNativeWindowTV::DidFinishNavigation(const std::string& url) {
1586 LOG(INFO) << "FinishNavigation, url = " << url.c_str();
1587 WidgetStateProvider::OnURLChanged(url);
1588 SetKeyEventChecker();
1589 SetUpgradeWebapiJson();
1590 auto* delegate = GetNativeWindowDelegate();
1592 delegate->DidFinishNavigation();
1595 void WRTNativeWindowTV::SetUpgradeWebapiJson() {
1596 auto upgrade_webapis_json_path =
1597 NativeWebRuntimeDelegateTV::GetInstance().GetUpgradeWebapiJsonPath();
1599 std::string json_str;
1600 base::ReadFileToString(base::FilePath(upgrade_webapis_json_path), &json_str);
1601 if (!json_str.empty()) {
1602 auto pkg_id = ApplicationData::GetInstance().GetPackageID();
1603 auto app_id = ApplicationData::GetInstance().app_id();
1604 std::stringstream uwa;
1605 uwa << "var uwa = {};"
1606 << "Object.defineProperties(uwa, {'json': {"
1607 << "value: " << json_str << ", writable: false, enumerable: false },"
1608 << "'currentPackageId' : {"
1609 << "value: '" << pkg_id << "', writable: false, enumerable: false },"
1610 << "'currentApplicationId' : {"
1611 << "value: '" << app_id << "', writable: false, enumerable: false }});";
1612 ExecuteJavaScript(uwa.str());
1616 bool WRTNativeWindowTV::IsSameWindowId(const unsigned int window_id) {
1617 return (wayland_window_id == window_id);
1620 void WRTNativeWindowTV::TakeScreenshot(
1621 const std::string& file_name, double scale_factor) {
1622 auto* rwhva = GetRenderWidgetHostView();
1624 LOG(ERROR) << "rwhva is null";
1627 int screen_width = 1920, screen_height = 1080;
1628 GetScreenResolution(screen_width, screen_height);
1629 rwhva->aura_efl_helper()->RequestSnapshotAsyncOnscreen(
1630 gfx::Rect(0, 0, screen_width, screen_height), OnScreenshotCapturedCB,
1631 strdup(file_name.c_str()), scale_factor);
1634 void WRTNativeWindowTV::Suspend() {
1635 LOG(INFO) << "suspend_timer is timeout";
1636 SetScheduledTasks(false);
1639 void WRTNativeWindowTV::SuspendMedia(bool suspend) {
1640 auto* wrt_web_contents = WRTWebContents::FromNativeWindow(this);
1641 if (!wrt_web_contents) {
1642 LOG(ERROR) << "WebContents is not created";
1645 auto* render_interface = wrt_web_contents->GetRendererInterface();
1646 if (!render_interface) {
1647 LOG(ERROR) << "Frame is not created";
1651 render_interface->SuspendMediaTasks(suspend);
1654 bool WRTNativeWindowTV::IsJavaScriptDialogShowing() {
1655 auto dialog_manager = GetJavaScriptDialogManager();
1656 return dialog_manager && dialog_manager->IsShowing();
1659 void WRTNativeWindowTV::SetEnabled(bool enable) {
1660 if (is_enabled_ == enable)
1663 LOG(INFO) << "Renderer scheduled-task will be " << enable;
1664 is_enabled_ = enable;
1666 if (IsJavaScriptDialogShowing()) {
1667 LOG(INFO) << "Modal dialog is showing, skip SetScheduledTasks()";
1671 if (enable || !suspend_delay_) {
1672 if (suspend_timer_.IsRunning()) {
1673 LOG(INFO) << "stop suspend_timer";
1674 suspend_timer_.Stop();
1677 SetScheduledTasks(enable);
1681 LOG(INFO) << "suspend_delay : " << suspend_delay_;
1682 suspend_timer_.Start(FROM_HERE,
1683 base::Milliseconds(suspend_delay_),
1684 this, &WRTNativeWindowTV::Suspend);
1687 void WRTNativeWindowTV::SetSuspendDelay(int delay) {
1688 suspend_delay_ = delay;
1689 if (delay > SUSPEND_DELAY_TIME_MAX)
1690 suspend_delay_ = SUSPEND_DELAY_TIME_MAX;
1694 LOG(INFO) << "suspend delay time is " << suspend_delay_ << " ms";
1697 void WRTNativeWindowTV::OnRotation(int degree) {
1698 int origin_degree = GetWebContentsViewAura()->GetOrientation();
1699 LOG(INFO) << "degree:" << degree << ", origin_degree : " << origin_degree;
1701 WRTNativeWindow::OnRotation(degree);
1702 if (!is_main_native_window_)
1705 auto* wrt_web_contents = WRTWebContents::FromNativeWindow(this);
1706 if (wrt_web_contents)
1707 wrt_web_contents->HidePopupMenuImpl();
1709 if (CanSupportLandscapeScale()) {
1710 LOG(INFO) << "Will handle for landscape_scale";
1711 zoom_factor_ = kScaleFactorLandscapeScale;
1712 SetZoomLevel(blink::PageZoomFactorToZoomLevel(zoom_factor_));
1713 } else if (zoom_factor_ != kScaleFactorDefault) {
1714 zoom_factor_ = kScaleFactorDefault;
1715 SetZoomLevel(blink::PageZoomFactorToZoomLevel(zoom_factor_));
1718 RotateWindow(degree);
1721 void WRTNativeWindowTV::LowerWindow() {
1722 if (visibility_state_ == "hidden") {
1723 LOG(ERROR) << "window is already hidden, lower will be ignored.";
1726 ecore_evas_lower(GetPlatformCanvas());
1729 void WRTNativeWindowTV::Focus(bool focus) {
1730 if (!is_main_native_window_)
1734 ecore_evas_focus_set(GetPlatformCanvas(), focus);
1737 void WRTNativeWindowTV::SetZoomLevel(double level) {
1738 if (!web_contents_) {
1739 LOG(INFO) << "web_contents_ is nullptr";
1742 if (!zoom_controller_) {
1743 electron::WebContentsZoomController::CreateForWebContents(web_contents_);
1745 electron::WebContentsZoomController::FromWebContents(web_contents_);
1747 LOG(INFO) << "SetZoomLevel : " << level;
1748 zoom_controller_->SetZoomLevel(level);
1750 const char* style_type = (zoom_factor_ == 1.0 ? "default" : "portrait");
1751 auto* delegate = WRTNativeWindow::GetNativeWindowDelegate();
1753 delegate->SetZoomLevel(level, style_type);
1756 gfx::OverlayTransform WRTNativeWindowTV::GetOverlayTransform(int degree) {
1759 return gfx::OVERLAY_TRANSFORM_ROTATE_270; // 270 is correct, not 90
1761 return gfx::OVERLAY_TRANSFORM_ROTATE_180;
1763 return gfx::OVERLAY_TRANSFORM_ROTATE_90;
1765 return gfx::OVERLAY_TRANSFORM_NONE;
1769 int WRTNativeWindowTV::GetScreenDegree() {
1770 int degree = ecore_evas_rotation_get(GetPlatformCanvas());
1771 LOG(INFO) << "GetScreenDegree degree:" << degree;
1775 bool WRTNativeWindowTV::SetScreenDegree(const std::string& degree) {
1776 LOG(INFO) << "SetScreenDegree degree: " << degree;
1780 int screen_degree = 0;
1781 base::StringToInt(degree, &screen_degree);
1782 if (screen_degree < 0 || screen_degree % 90 != 0)
1785 ecore_evas_rotation_set(GetPlatformCanvas(), screen_degree);
1786 RotateWindow(screen_degree);
1791 bool WRTNativeWindowTV::SetFlipMode(const std::string& value) {
1792 LOG(INFO) << "SetFlipMode value: " << value;
1796 if (value == "true")
1797 ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.video.flip.mode", "1");
1799 ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.video.flip.mode", "0");
1804 void WRTNativeWindowTV::RotateWindow(int degree) {
1805 int screen_width = 1920, screen_height = 1080;
1806 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
1807 switches::kEnableOffscreenRendering)) {
1808 evas_object_geometry_get(top_window_, nullptr, nullptr, &screen_width,
1810 if (screen_width == 0 || screen_height == 0)
1813 evas_object_resize(top_window_, screen_width, screen_height);
1814 gfx::Rect bounds(0, 0, screen_width, screen_height);
1815 GetNativeView()->SetBounds(bounds);
1817 auto* host = GetWindowTreeHost();
1818 host->SetDisplayTransformHint(GetOverlayTransform(degree));
1820 GetScreenResolution(screen_width, screen_height);
1821 // ecore_wl2_egl_window_resize_with_rotation require (width:1920,
1822 // height:1080, degree:0) as param, so call SetBoundsInPixels before swap
1823 // screen_width and screen_height
1824 host->SetBoundsInPixels(gfx::Rect(0, 0, screen_width, screen_height));
1825 if (degree == 90 || degree == 270)
1826 std::swap(screen_width, screen_height);
1827 gfx::Rect bounds(0, 0, screen_width, screen_height);
1828 evas_object_resize(top_window_, screen_width, screen_height);
1830 // rotate all aura window
1831 auto* rwhv = GetRenderWidgetHostView();
1832 aura::Window* aura_window = rwhv ? rwhv->GetNativeView() : nullptr;
1833 while (aura_window) {
1834 aura_window->SetBounds(bounds);
1835 aura_window = aura_window->parent();
1838 LOG(INFO) << "degree : " << degree << " (" << screen_width << "x"
1839 << screen_height << ")";
1841 auto* extension_manager = XWalkExtensionManager::GetInstance();
1842 extension_manager->NotifyWindowEvent("orientation", std::to_string(degree));
1845 void WRTNativeWindowTV::ScreenSaverResetTimeout(void) {
1846 screensaver_reset_timeout();
1849 void WRTNativeWindowTV::SetScreenSaver(const std::string& state) {
1851 screensaver_reset();
1852 if (!screensaver_reset_timer_.IsRunning()) {
1853 ecore_evas_aux_hint_add(GetPlatformCanvas(),
1854 "wm.screensaver.reset.allowed", "true");
1855 screensaver_reset_timer_.Start(
1856 FROM_HERE, base::Minutes(30), this,
1857 &WRTNativeWindowTV::ScreenSaverResetTimeout);
1860 activateScreenSaver(const_cast<char*>("DEFAULT"), 0, 0, DEFAULT_BLANKING,
1862 if (screensaver_reset_timer_.IsRunning())
1863 screensaver_reset_timer_.Stop();
1867 void WRTNativeWindowTV::UnsetSuspendDelayForNonMultitasking() {
1868 if (!NativeWebRuntimeDelegateTV::GetInstance().IsMultitaskingSupport()) {
1870 LOG(INFO) << "app doesn't support multitasking, so no suspend delay "
1871 "feature, will suspend app immediately";