5684d27267dd98741ce387b00f2e2e2b0aeee5a6
[platform/framework/web/chromium-efl.git] / wrt / src / browser / tv / wrt_native_window_tv.cc
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.
4
5 #include "wrt/src/browser/tv/wrt_native_window_tv.h"
6
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>
14
15 #include <Ecore_Wl2.h>
16 #include <Key_Mode.h>
17 #include <SettingsAPI.h>
18
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"
37 #endif
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"
58
59 #if defined(TIZEN_ATK_SUPPORT)
60 #include "tizen_src/ewk/efl_integration/eweb_accessibility_util.h"
61 #endif
62
63 #if defined(THREAD_BOOSTER_SERVICE)
64 #include "services/suspend_resume/public/cpp/suspend_resume.h"
65 #endif
66
67 namespace wrt {
68
69 namespace {
70
71 // macro
72 #define SUSPEND_DELAY_TIME_MAX 3000  // ms
73
74 //vconf
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";
82
83 // metadata
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
144
145 #if !TIZEN_VERSION_AT_LEAST(8, 0, 0)
146 const char* kPointingDeviceSupport = "wm.cursormanager.pointing.device.support";
147 #endif
148 const char* kScreenshotPath = "/home/owner/apps_rw/xwalk-service/screenshot/";
149
150 const char* kMultiPlayerSupport =
151     "http://samsung.com/tv/metadata/multiplayer.support";
152
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;
158
159 unsigned int global_resource_id = 0;
160 unsigned int wayland_window_id = 0;
161
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);
168 }
169
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;
175 }
176
177 void MultiviewStateChangedCb(keynode_t* keynodeName, void* data) {
178   if (!data || !keynodeName) {
179     LOG(ERROR) << "keynodeName | data is NULL";
180     return;
181   }
182   std::string multiview_state = vconf_keynode_get_str(keynodeName);
183   LOG(INFO) << "MultiviewState change[" << multiview_state << "]";
184
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);
191   else
192     native_window_tv->SetScreenResolution(width, height);
193 }
194
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
203                << " failed";
204     return false;
205   }
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
209                << " failed";
210     ewk_value_unref(key);
211     return false;
212   }
213   Eina_Bool new_entry;
214   bool result = ewk_value_dictionary_add(dictionary, key, value, &new_entry);
215   ewk_value_unref(key);
216   ewk_value_unref(value);
217   if (!result)
218     LOG(ERROR) << "ewk_value_dictionary_add with key: " << key_string
219                << ", value: " << value_string << " failed";
220   return result && new_entry;
221 }
222 #endif
223
224 void SetDiskCacheEnableOnIOThread(
225     content::StoragePartition* storage_partition) {
226   if (!storage_partition)
227     return;
228
229   auto network_context = storage_partition->GetNetworkContext();
230   if (!network_context)
231     return;
232
233   LOG(INFO) << "Set diskCache mode to net::HttpCache::NORMAL";
234 #if !defined(WRT_JS_BRINGUP)
235   network_context->SetCacheMode(true);
236 #endif
237 }
238
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())
244                   .Append(file_name);
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);
248   delete file_name;
249 }
250
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;
260     default:
261       break;
262   }
263   return WRTNativeWindow::ScreenOrientation::NONE;
264 }
265
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;
276     default:
277       break;
278   }
279   return WRTNativeWindow::ScreenOrientation::NONE;
280 }
281
282 bool CanSupportLandscapeScale() {
283   auto is_signage = IsSignageProduct();
284   if (!is_signage)
285     return false;
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);
291 }
292
293 #if TIZEN_VERSION_AT_LEAST(6, 0, 0)
294 bool OnDisplayRotatorAddCB(display_rotator_status_t* rotator_status,
295                            void* data) {
296   LOG(INFO) << "display rotator callback is invoked!";
297   if (!rotator_status)
298     return false;
299
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);
304
305   return true;
306 }
307 #endif
308
309 }  // namespace
310
311 std::string WRTNativeWindowTV::menu_zoom_fill_ = "";
312
313 // static
314 WRTNativeWindowTV* WRTNativeWindowTV::GetMainNativeWindow() {
315   return static_cast<WRTNativeWindowTV*>(WRTNativeWindow::GetMainNativeWindow());
316 }
317
318 // static
319 void WRTNativeWindowTV::NotifyWindowShowIfVisible() {
320   auto native_window_tv = GetMainNativeWindow();
321   if (!native_window_tv)
322     return;
323
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();
329 }
330
331 // static
332 void WRTNativeWindowTV::SetWindowBorderAlpha() {
333   auto* delegate = GetNativeWindowDelegate();
334   if (delegate)
335     delegate->SetWindowBorderAlpha();
336 }
337
338 unsigned int WRTNativeWindowTV::GetGlobalResourceId() {
339   return global_resource_id;
340 }
341
342 int WRTNativeWindowTV::GetWindowLayer() {
343   auto* ee = GetPlatformCanvas();
344   if (ee)
345     return ecore_evas_layer_get(ee);
346
347   return 0;
348 }
349
350 WRTNativeWindowTV::WRTNativeWindowTV(const gin_helper::Dictionary& options,
351                                      electron::NativeWindow* parent)
352     : WRTNativeWindow::WRTNativeWindow(options, parent),
353       alphaset_(false),
354       partial_(false),
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) {}
361
362 WRTNativeWindowTV::~WRTNativeWindowTV() {
363   Finalize();
364 }
365
366 void WRTNativeWindowTV::SetWebContents(content::WebContents* web_contents) {
367   LOG(INFO) << "WRTNativeWindowTV::SetWebContents()";
368   WRTNativeWindow::SetWebContents(web_contents);
369
370   SetAppMetaDataInfoRelatedWindow();
371   auto* ewk_view = view_evas();
372   if (use_focus_)
373     InputDeviceManager::GetInstance()->Initialize(ewk_view);
374
375   if (!is_main_native_window_)
376     return;
377
378   top_window_ = GetTopWindow();
379   SetGlobalResourceId(GetPlatformCanvas());
380
381 #if defined(TIZEN_PEPPER_EXTENSIONS)
382   InitializePepperExtensionSystem();
383 #endif
384 #if defined(TIZEN_ATK_FEATURE_VD)
385   EWebAccessibilityUtil::GetInstance();
386 #endif
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();
394   SetProxyInfo();
395   SetDiskCacheMode();
396   UnsetSuspendDelayForNonMultitasking();
397 }
398
399 void WRTNativeWindowTV::Finalize() {
400   LOG(INFO) << "WRTNativeWindowTV::Finalize()";
401   if (!is_main_native_window_)
402     return;
403
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);
412 #else
413   display_rotator_unregister_cb();
414 #endif
415   UnRegisterRotateSensorListener();
416   vconf_ignore_key_changed(kMultiScreenInfoVconfKey, MultiviewStateChangedCb);
417 }
418
419 void WRTNativeWindowTV::CloseImmediately() {
420   if (is_main_native_window_) {
421     if ("visible" == visibility_state_) {
422       LOG(INFO) << "window will be lower before close";
423       LowerWindow();
424     }
425 #if defined(TIZEN_PEPPER_EXTENSIONS)
426     UnregisterPepperExtensionDelegate();
427 #endif
428     DisableVisibilitySetting();
429   }
430   WRTNativeWindow::CloseImmediately();
431 }
432
433 bool WRTNativeWindowTV::IsRunningAsBackground() {
434   return AmbientMode::IsRunningAsBackground();
435 }
436
437 // static
438 bool WRTNativeWindowTV::SetRotation() {
439   if (IsSignageProduct())
440     return false;
441
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);
447   }
448   if (meta_data_info.GetValue(kStateByRotation) == "lock") {
449     LOG(INFO) <<
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);
456   }
457   return true;
458 }
459
460 std::string WRTNativeWindowTV::GetPointDeviceOptionValue() {
461   static std::string pointing_device_support;
462   if (!pointing_device_support.empty())
463     return pointing_device_support;
464
465   pointing_device_support =
466       ApplicationDataTV::GetInstance().PointDeviceOption();
467
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";
472
473   LOG(INFO) << "pointing_device_support = " << pointing_device_support;
474   return pointing_device_support;
475 }
476
477 bool WRTNativeWindowTV::NeedSetCursorPointer() {
478   // for System default support mouse
479   if (IsMouseCursorSupportedModel())
480     return true;
481
482   std::string point_device_option = GetPointDeviceOptionValue();
483
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");
488 }
489
490 void WRTNativeWindowTV::CreateMouseCursor(Evas_Object* window) {
491   static absl::optional<bool> mouse_initialize = false;
492   if (mouse_initialize.value())
493     return;
494
495   if (!NeedSetCursorPointer()) {
496     mouse_initialize = true;
497     return;
498   }
499
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);
506
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";
512   }
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))));
517   ecore_wl2_sync();
518
519   std::string floating_navigation =
520       ApplicationData::GetInstance().GetMetadata(kFloatingNavigation);
521   LOG(INFO) << "floating_navigation = " << floating_navigation;
522
523   std::string pointing_device_support = GetPointDeviceOptionValue();
524
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);
533     else
534       Mouse_Pointer_Support(DISABLE, ecore_wl2_win);
535 #else
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");
539 #endif
540     if (auto* rwhva = GetRenderWidgetHostView()) {
541       rwhva->aura_efl_helper()->SetMouseEventsEnabled(false);
542     } else
543       LOG(WARNING) << "rwhva is null, cannot set cursor by client";
544   } else {
545 #if !TIZEN_VERSION_AT_LEAST(8, 0, 0)
546     ecore_evas_aux_hint_add(GetPlatformCanvas(), kPointingDeviceSupport, "1");
547 #endif
548
549     if (IsMouseCursorSupportedModel() && floating_navigation == "false") {
550       ecore_evas_aux_hint_add(GetPlatformCanvas(),
551                               "wm.cursormanager.floating.menu.support", "0");
552     }
553     if (Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_CURSOR_AVAILABLE,
554                           nullptr)) {
555       if (pointing_device_support == "mouse-no-hide") {
556         if (!Cursor_Set_Config(surface, TIZEN_CURSOR_CONFIG_NOT_HIDE_CURSOR,
557                                nullptr))
558           LOG(ERROR) << "set cursor config no hide failed";
559       }
560     } else {
561       LOG(ERROR) << "set cursor config avaiable failed";
562     }
563   }
564
565   CursorModule_Finalize();
566   mouse_initialize = true;
567 }
568
569 // static
570 void WRTNativeWindowTV::SetGlobalResourceId(Ecore_Evas* ee) {
571   if (global_resource_id)
572     return;
573
574   Ecore_Wl2_Window* wl_window = ecore_evas_wayland2_window_get(ee);
575   wayland_window_id =
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);
583   if (!wl_display) {
584     LOG(ERROR) << "error to find display (wl_display is null)";
585     return;
586   }
587
588   if (!wl_surface) {
589     LOG(ERROR) << "error to find display (wl_surface is null)";
590     return;
591   }
592
593   struct wl_registry* wl_registry = wl_display_get_registry(wl_display);
594   if (!wl_registry) {
595     LOG(ERROR) << "error to find display (wl_registry is null)";
596     return;
597   }
598
599   struct wl_event_queue* wl_queue = wl_display_create_queue(wl_display);
600   if (!wl_queue) {
601     LOG(ERROR) << "error to find display (wl_queue is null)";
602     return;
603   }
604   static const struct tizen_resource_listener tz_resource_listener = {
605     HandleResourceId
606   };
607
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));
615       if (!tz_surface) {
616         LOG(ERROR) << "error to find display";
617       }
618     }
619   }
620   eina_iterator_free(l);
621
622   struct tizen_resource* tz_resource =
623       tizen_surface_get_tizen_resource(tz_surface, wl_surface);
624
625   if (tz_resource) {
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);
629   } else
630     LOG(ERROR) << "error to find tz_resource";
631
632   if (tz_resource)
633     tizen_resource_destroy(tz_resource);
634   if (tz_surface)
635     tizen_surface_destroy(tz_surface);
636   if (wl_registry)
637     wl_registry_destroy(wl_registry);
638   if (wl_queue)
639     wl_event_queue_destroy(wl_queue);
640 }
641
642 void WRTNativeWindowTV::SetAppMetaDataInfo() {
643   auto& meta_data_info = ApplicationData::GetInstance().meta_data_info();
644
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;
650   }
651
652   if (!meta_data_info.GetValue(kChannelBound).empty()) {
653     LOG(INFO) << "channelnumber is " << meta_data_info.GetValue(kChannelBound);
654     SetWindowAlpha(true);
655   }
656
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);
661   }
662
663   if (meta_data_info.GetValue(kUseTVWindow) == "true") {
664     LOG(INFO) << "use.tvwindow is true!!";
665     SetInvisibleDelivery();
666   }
667
668   if (meta_data_info.GetValue(kKeyboardFunc) == "true") {
669     LOG(INFO) << "use.keyboardfunckey is true!!";
670     SetKeyboardFuncKey();
671   }
672
673   if (meta_data_info.GetValue(kKeyboardFunc) == "convertOriginalKey") {
674     LOG(INFO) << "use.keyboardfunckey value is convertOriginalKey!!";
675     SetKeyboardFuncKey();
676     InputDeviceManager::GetInstance()->SetKeyboardFuncKey();
677   }
678
679   if (meta_data_info.GetValue(kGraphicPlaneSupport) == "true") {
680     LOG(INFO) << "graphic.plane.support is true!!";
681     SetUseGraphicPlane();
682   }
683
684   if (meta_data_info.GetValue(kScreenResolution) == "uhd_subwindow") {
685     int width = 0;
686     int height = 0;
687     if (GetPanelResolution(&width, &height))
688       SetScreenResolution(width > 0 ? width / 4 : 0, height);
689     else
690       SetScreenResolution(960, 2160);
691   } else if (meta_data_info.GetValue(kScreenResolution) == "uhd_window")
692     SetScreenResolution(3840, 2160);
693
694   if (meta_data_info.GetValue(kOpaqueSupport) == "true") {
695     LOG(INFO) << "transparent.opaque.support is true!!";
696     SetWindowOpaque();
697   }
698
699   if (meta_data_info.GetValue(kUseDimScreen) == "true") {
700     LOG(INFO) << "use.dimscreen is true!!";
701     SetDimScreen();
702   }
703
704   if (meta_data_info.GetValue(kPartial) == "true") {
705     LOG(INFO) << "partial.overlay.support is true!!";
706     partial_ = true;
707   }
708
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;
714   }
715
716   if (meta_data_info.GetValue(kSkipDisable) == "true") {
717     LOG(INFO) << "skip.disable.tvmenu is true!!";
718     skip_disable_tvmenu_ = true;
719   }
720
721   if (meta_data_info.GetValue(kUseTension) == "false") {
722     LOG(INFO) << "use.tension is false!!";
723     SetWindowEffect(false);
724   }
725
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);
730 #endif
731   }
732
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);
737   }
738 #endif
739
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");
743   }
744
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);
749   }
750
751   if (meta_data_info.GetValue(kDualDecodingWebRTC) == "true") {
752     auto current_command_line = base::CommandLine::ForCurrentProcess();
753     current_command_line->AppendSwitch(switches::kDualDecodingWebRTC);
754   }
755
756   if (meta_data_info.GetValue(kMultiPlayerSupport) == "true") {
757     auto current_command_line = base::CommandLine::ForCurrentProcess();
758     current_command_line->AppendSwitch(switches::kEnableMultiPlayerForWebapp);
759   }
760
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");
766
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",
771                                            "enabled:true");
772     base::FieldTrialList::CreateFieldTrial("WebRTC-ForceNackBeforeRtt",
773                                            "enabled:true");
774   }
775
776   if (meta_data_info.GetValue(kNDecoding) == "true") {
777     auto current_command_line = base::CommandLine::ForCurrentProcess();
778     current_command_line->AppendSwitch(switches::kEnableNDecoding);
779   }
780
781   if (legacy_game_mode) {
782     auto current_command_line = base::CommandLine::ForCurrentProcess();
783     current_command_line->AppendSwitch(switches::kEnableLegacyGameMode);
784   }
785
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);
790   }
791
792   if (meta_data_info.GetValue(kScreenOrientationMultiView) == "portrait") {
793     SetWinUserGeometry();
794     ecore_evas_aux_hint_add(
795         GetPlatformCanvas(), "wm.policy.win.transform.mode", "ratiofit");
796
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);
802     }
803     vconf_notify_key_changed(kMultiScreenInfoVconfKey,
804         MultiviewStateChangedCb, this);
805   }
806
807   if (meta_data_info.GetValue(kFrameRawDataCopy) == "true") {
808     auto current_command_line = base::CommandLine::ForCurrentProcess();
809     current_command_line->AppendSwitch(switches::kEnableFrameRawDataCopy);
810   }
811
812   if (meta_data_info.HasKey(kErrorPagePath)) {
813     error_page_path_ = ApplicationData::GetInstance().application_path() +
814                        meta_data_info.GetValue(kErrorPagePath);
815   }
816
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",
820                             "true");
821     ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.luminescence.mode",
822                             "true");
823   }
824
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);
834     }
835   }
836
837   if (!use_focus_) {
838     LOG(INFO) << "use.focus is false!!";
839     SetUseFocus(false);
840   }
841
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);
846   }
847 }
848
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)";
856   }
857
858   use_focus_ = !(meta_data_info.GetValue(kUseFocus) == "false");
859 }
860
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;
869   }
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;
874   }
875 }
876
877 bool WRTNativeWindowTV::IsMultiScreenShowed(const std::string& multiview_config) {
878   Json::Value root;
879   Json::Reader reader;
880   if (!reader.parse(multiview_config, root)) {
881     LOG(ERROR) << "Fail to parse vconf value [" << multiview_config << "]";
882     return false;
883   }
884   std::string mode = root["mode"].asString();
885   LOG(INFO) << "MultiviewState [" << mode << "]";
886   return mode == "on";
887 }
888
889 void WRTNativeWindowTV::SetRuntimeVariables() {
890   auto& runtime = NativeWebRuntime::GetInstance();
891
892   LOG(INFO) << "global_resource_id : " << global_resource_id;
893   runtime.SetRuntimeVariable("global_resource_id",
894       std::to_string(global_resource_id));
895
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());
900
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);
905 }
906
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();
915   } else {
916     proxy_info = VconfHandle(kProxyVconfKey).Str();
917   }
918   if (proxy_info.empty() || proxy_info.find("://") == std::string::npos) {
919     LOG(INFO) << "proxy address : " << proxy_info;
920     return;
921   }
922   NativeWebRuntimeDelegateTV::GetInstance().SetProxyInfo(proxy_info);
923
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);
933   } else {
934     sscanf(proxy_info.c_str(), "%9[^:/]://%63s", protocol, uri);
935   }
936   browser_context->SetProxyURI(uri);
937   browser_context->SetProxyProtocol(protocol);
938
939   std::string bypass_rule = VconfHandle(kProxyExceptionList).Str();
940
941   // Add proxy settings
942   browser::ProxyConfigMonitor::GetInstance()->UpdateProxyConfig(
943       std::string(uri), bypass_rule);
944 #endif
945 }
946
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";
951     return;
952   }
953   if (!NativeWebRuntimeDelegateTV::GetInstance().GetDiskCachePath().empty()) {
954     content::GetIOThreadTaskRunner({})->PostTask(
955         FROM_HERE,
956         base::BindOnce(&SetDiskCacheEnableOnIOThread,
957                        browser_context->GetDefaultStoragePartition()));
958   }
959 }
960
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;
967 }
968
969 void WRTNativeWindowTV::SetWindowAlpha(bool alpha) {
970   LOG(INFO) << "Setting window Alpha : " << alpha;
971   alphaset_ = alpha;
972
973   Eina_Bool alpha_enable = alpha ? EINA_TRUE : EINA_FALSE;
974   ecore_evas_alpha_set(GetPlatformCanvas(), alpha_enable);
975 }
976
977 void WRTNativeWindowTV::SetUseFocus(bool use_focus) {
978   LOG(INFO) << "SetUseFocus : " << use_focus;
979   ecore_evas_focus_skip_set(GetPlatformCanvas(), !use_focus);
980   if (use_focus) {
981     InputDeviceManager::GetInstance()->Initialize(view_evas());
982   }
983 }
984
985 void WRTNativeWindowTV::SetDimScreen() {
986   LOG(INFO) << "SetDimScreen, alphaset is " << alphaset_;
987   if (!alphaset_) {
988     ecore_evas_aux_hint_add(
989         GetPlatformCanvas(), "wm.policy.win.accept.dim", "1");
990   }
991 }
992
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);
997 }
998
999 void WRTNativeWindowTV::SetScreenResolution(unsigned int width,
1000                                           unsigned int height) {
1001   LOG(INFO) << "called : width(" << width << "), height(" << height << ")";
1002   int x, y;
1003   evas_object_geometry_get(view_evas(), &x, &y, nullptr, nullptr);
1004   gfx::Rect bounds(x, y, width, height);
1005
1006   auto* efl_window = GetWindowTreeHost()->platform_window();
1007   efl_window->SetBoundsInPixels(bounds);
1008
1009   bounds.set_origin({0, 0});
1010   SetBounds(bounds);
1011 }
1012
1013 void WRTNativeWindowTV::HalfWindowSupport(std::string position) {
1014   int w = 0, h = 0, x = 0, y = 0;
1015   GetScreenResolution(w, h);
1016
1017   if (position == "LEFT")
1018     w /= 2;
1019   else if (position == "RIGHT") {
1020     w /= 2;
1021     x = w;
1022   } else if (position == "TOP")
1023     h /= 2;
1024   else if (position == "BOTTOM") {
1025     h /= 2;
1026     y = h;
1027   } else if (position == "RWI") {   // quator size window and right and center
1028     w /= 2;
1029     x = w;
1030     h /= 2;
1031     y = h/2;
1032   } else if (position != "RESET")
1033     return;
1034
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);
1042 }
1043
1044 void WRTNativeWindowTV::Hide() {
1045   WRTNativeWindow::Hide();
1046
1047   if (electron::Browser::Get()->is_quitting()) {
1048     LOG(ERROR) << "App is quitting, hide backexecution app's window is skipped";
1049     return;
1050   }
1051   auto& app_data = wrt::ApplicationData::GetInstance();
1052   if (app_data.GetMetadata(kForceHideWindow) == "true") {
1053     auto* top_window = WRTNativeWindow::GetTopWindow();
1054     if (!top_window)
1055       return;
1056     LOG(INFO) << "Will hide window forcely";
1057     evas_object_hide(top_window);
1058   }
1059 }
1060
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);
1065
1066   KeyRouter_Set_InputConfig(
1067       +surface, TIZEN_TV_KEYROUTER_CONFIG_MODE_USE_KEYBOARD_FUNC_KEY, nullptr);
1068 }
1069
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);
1074
1075   KeyRouter_Set_InputConfig(surface, TIZEN_KEYROUTER_CONFIG_MODE_INVISIBLE_SET,
1076                             nullptr);
1077   use_tv_window_ = true;
1078 }
1079
1080 void WRTNativeWindowTV::SetMenuZoomFill(const std::string& enable) {
1081   if (menu_zoom_fill_.empty())
1082     menu_zoom_fill_ = enable;
1083 }
1084
1085 void WRTNativeWindowTV::SetWindowEffect(bool enable) {
1086   ecore_evas_aux_hint_add(
1087       GetPlatformCanvas(), "wm.comp.win.effect.enable", (enable ? "1" : "0"));
1088 }
1089
1090 void WRTNativeWindowTV::EnableVisibilitySetting() {
1091   std::string app_id = ApplicationData::GetInstance().app_id();
1092   VconfHandle(kMostRecentApp).Set(app_id);
1093
1094   if (channel_changeable_)
1095     VconfHandle(kBGChannelChange).Set(true);
1096
1097   bool opt = (alphaset_ || use_tv_window_)
1098                  ? (!graphic_plane_support_ && !partial_)
1099                  : false;
1100   VconfHandle("memory/VDWebApp/partial").Set(opt);
1101   LOG(INFO) << "memory/VDWebApp/partial set as " << opt;
1102
1103   if (!alphaset_) {
1104     activateScreenSaver(const_cast<char*>("DEFAULT"),
1105                         0,
1106                         10,
1107                         DEFAULT_BLANKING,
1108                         DEFAULT_EXPOSURES);
1109   }
1110
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";
1122     }
1123     SettingsAPI* settings = SettingsAPI::Get();
1124     if (settings)
1125       settings->DisableItemsByList(disableItems, app_id);
1126   }
1127 }
1128
1129 void WRTNativeWindowTV::DisableVisibilitySetting() {
1130   std::string app_id = ApplicationData::GetInstance().app_id();
1131   std::string most_recent_app = VconfHandle(kMostRecentApp).Str();
1132
1133   if (app_id == most_recent_app)
1134     VconfHandle(kMostRecentApp).Set("none");
1135
1136   if (channel_changeable_)
1137     VconfHandle(kBGChannelChange).Set(false);
1138
1139   if (!skip_disable_tvmenu_) {
1140     SettingsAPI* settings = SettingsAPI::Get();
1141     if (settings)
1142       settings->RemoveDisabledItemsByAppname(app_id);
1143   }
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);
1149 }
1150
1151 void WRTNativeWindowTV::VisibilityChangedAsBackground() {
1152   std::string app_id = ApplicationData::GetInstance().app_id();
1153   LOG(ERROR) << app_id << " is hidden from the screen";
1154
1155   SuspendMedia(true);
1156   DisableVisibilitySetting();
1157   if (visibility_state_.empty() && !VideoSplashScreen::IsVSSPlaying())
1158     WidgetStateProvider::OnStatusChanged("behind");
1159
1160   visibility_state_ = "hidden";
1161   OnVisibilityChange(false);
1162   VideoSplashScreen::FinalizeVSS();
1163 }
1164
1165 void WRTNativeWindowTV::VisibilityChangedAsForeground() {
1166   std::string app_id = ApplicationData::GetInstance().app_id();
1167   LOG(ERROR) << app_id << " has shown on the screen";
1168
1169   SuspendMedia(false);
1170   CreateMouseCursor(top_window_);
1171
1172   EnableVisibilitySetting();
1173   visibility_state_ = "visible";
1174   OnVisibilityChange(true);
1175   TvWindowManager::GetInstance()->SetMuteAudioVideo(false);
1176 }
1177
1178 void WRTNativeWindowTV::SetPageVisibility(bool visible) {
1179   if (visible)
1180     SetEnabled(true);
1181
1182   WRTNativeWindow::SetPageVisibility(visible);
1183
1184   if (visible)
1185     VisibilityChangedAsForeground();
1186   else
1187     VisibilityChangedAsBackground();
1188
1189   auto* extension_manager = XWalkExtensionManager::GetInstance();
1190   extension_manager->NotifyWindowEvent("visibility", visibility_state_);
1191
1192 #if defined(THREAD_BOOSTER_SERVICE)
1193   if (visible)
1194     suspend_resume::NotifyStateChange(suspend_resume::State::RESUMED);
1195   else
1196     suspend_resume::NotifyStateChange(suspend_resume::State::SUSPENDED);
1197 #endif
1198 }
1199
1200 void WRTNativeWindowTV::OnVisibilityChange(bool visible) {
1201   std::stringstream script_format;
1202   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());
1209 }
1210
1211 bool WRTNativeWindowTV::WillHandleConformantChange() {
1212   if (orientation_ == ScreenOrientation::NONE)
1213     return false;
1214
1215   int preferred_rotation =
1216       ecore_evas_wm_rotation_preferred_rotation_get(GetPlatformCanvas());
1217   if (preferred_rotation == 0 &&
1218       orientation_ != ScreenOrientation::LANDSCAPE_PRIMARY)
1219     return false;
1220   return true;
1221 }
1222
1223 bool WRTNativeWindowTV::ShouldHandleConformantChange() {
1224   return !use_floating_ime_;
1225 }
1226
1227 void WRTNativeWindowTV::ExecuteJavaScript(const std::string& script) {
1228   auto* rfh = GetRenderFrameHost();
1229   if (!rfh)
1230     return;
1231
1232   std::u16string script_converted;
1233   base::UTF8ToUTF16(script.c_str(), script.size(), &script_converted);
1234   rfh->ExecuteJavaScriptWithUserGestureForTests(
1235       script_converted, base::NullCallback());
1236 }
1237
1238 void WRTNativeWindowTV::SetWinUserGeometry() {
1239   LOG(INFO) << "called : wm.policy.win.user.geometry";
1240   if (window_user_geometry_)
1241     return;
1242   ecore_evas_aux_hint_add(
1243       GetPlatformCanvas(), "wm.policy.win.user.geometry", "1");
1244   window_user_geometry_ = true;
1245 }
1246
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);
1250 }
1251
1252 bool WRTNativeWindowTV::SetQuarterPosition(
1253     const std::string& position) {
1254   if (position.empty())
1255     return false;
1256
1257   LOG(INFO) << "SetQuarterPosition : " << position;
1258   int quarter_position = 0;
1259   base::StringToInt(position, &quarter_position);
1260   if (quarter_position > kMaxWidgetPosition) {
1261     return false;
1262   } else if (quarter_position <= 0) {
1263     quarter_position = 1;
1264   }
1265   int screen_width = 0, screen_height = 0;
1266   GetPanelResolution(&screen_width, &screen_height);
1267   if (!screen_width)
1268     return false;
1269
1270   screen_width /= kPannelToGraphicSize;
1271   int widget_left = ((screen_width / 4) * (quarter_position - 1));
1272   SetWinUserGeometry();
1273   SetWindowPosition(widget_left, 0);
1274
1275   return true;
1276 }
1277
1278 bool WRTNativeWindowTV::MoveWindow(const std::string& coordinate) {
1279   if (coordinate.empty())
1280     return false;
1281
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)
1286     return false;
1287
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);
1293
1294   return true;
1295 }
1296
1297 bool WRTNativeWindowTV::ResizeWindow(const std::string& resolution) {
1298   if (resolution.empty())
1299     return false;
1300
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)
1305     return false;
1306
1307   int widget_width, widget_height;
1308   base::StringToInt(resolution_vector[0], &widget_width);
1309   base::StringToInt(resolution_vector[1], &widget_height);
1310   SetWinUserGeometry();
1311
1312   evas_object_resize(view_evas(), widget_width, widget_height);
1313   SetScreenResolution(widget_width, widget_height);
1314
1315   return true;
1316 }
1317
1318 #if defined(TIZEN_PEPPER_EXTENSIONS)
1319 void WRTNativeWindowTV::InitializePepperExtensionSystem() {
1320   RegisterPepperExtensionDelegate();
1321   SetWindowId();
1322   SetPepperExtensionCallback();
1323   SetPepperExtensionWidgetInfo();
1324   widget_extension_sync_call_handlers_["RegisterKey"] =
1325       &WRTNativeWindowTV::RegisterKey;
1326   widget_extension_sync_call_handlers_["UnRegisterKey"] =
1327       &WRTNativeWindowTV::UnRegisterKey;
1328 }
1329
1330 EwkExtensionSystemDelegate* WRTNativeWindowTV::GetExtensionDelegate() {
1331   auto* render_frame_host = GetRenderFrameHost();
1332   if (!render_frame_host)
1333     return nullptr;
1334
1335   return static_cast<EwkExtensionSystemDelegate*>(
1336       content::ExtensionSystemDelegateManager::GetInstance()
1337           ->GetDelegateForFrame(render_frame_id_));
1338 }
1339
1340 void WRTNativeWindowTV::SetWindowId() {
1341   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1342   if (!delegate) {
1343     LOG(ERROR) << "No delegate is available to set window id";
1344     return;
1345   }
1346   if (global_resource_id)
1347     delegate->SetWindowId(global_resource_id);
1348   else
1349     delegate->SetWindowId(top_window_);
1350 }
1351
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";
1356     return;
1357   }
1358
1359   render_frame_id_.render_process_id =
1360       render_frame_host->GetProcess()->GetID();
1361   render_frame_id_.render_frame_id = render_frame_host->GetRoutingID();
1362
1363   EwkExtensionSystemDelegate* delegate = new EwkExtensionSystemDelegate;
1364   content::ExtensionSystemDelegateManager::GetInstance()->RegisterDelegate(
1365       render_frame_id_, std::unique_ptr<EwkExtensionSystemDelegate>{delegate});
1366 }
1367
1368 void WRTNativeWindowTV::UnregisterPepperExtensionDelegate() {
1369   if (!GetRenderFrameHost()) {
1370     LOG(ERROR) << "web_contents_ is nullptr, can't unregister delegate";
1371     return;
1372   }
1373
1374   if (!content::ExtensionSystemDelegateManager::GetInstance()
1375            ->UnregisterDelegate(render_frame_id_))
1376     LOG(ERROR) << "Unregistering pepper extension delegate failed";
1377 }
1378
1379 void WRTNativeWindowTV::SetPepperExtensionWidgetInfo() {
1380   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1381   if (!delegate) {
1382     LOG(WARNING) << "No delegate is available to set extension info";
1383     return;
1384   }
1385   Ewk_Value dictionary = ewk_value_dictionary_new();
1386   if (!dictionary) {
1387     LOG(ERROR) << "Failed to create pepper extension info dictionary";
1388     return;
1389   }
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();
1398   bool result = true;
1399   result =
1400       result && AddNewElementToDictionary(dictionary, "id", app_id.c_str());
1401   result = result &&
1402            AddNewElementToDictionary(dictionary, "packageId", pkg_id.c_str());
1403   result = result && AddNewElementToDictionary(dictionary, "installPath",
1404                                                app_path.c_str());
1405   result = result && AddNewElementToDictionary(
1406                          dictionary, "temporaryStoragePath", temp_path.c_str());
1407   result =
1408       result && AddNewElementToDictionary(dictionary, "persistentStoragePath",
1409                                           pers_path.c_str());
1410   result = result && AddNewElementToDictionary(dictionary, "widgetVersion",
1411                                                version.c_str());
1412   LOG(ERROR) << "widgetVersion = " << version;
1413
1414   if (!result)
1415     LOG(ERROR) << "Failed to build pepper extension info dictionary";
1416   delegate->SetExtensionInfo(dictionary);
1417   ewk_value_unref(dictionary);
1418 }
1419
1420 void WRTNativeWindowTV::SetPepperExtensionCallback() {
1421   EwkExtensionSystemDelegate* delegate = GetExtensionDelegate();
1422   if (!delegate) {
1423     LOG(WARNING) << "No delegate is available to set generic callback";
1424     return;
1425   }
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";
1430       return nullptr;
1431     }
1432     auto* self = static_cast<WRTNativeWindowTV*>(user_data);
1433     std::string operation_name_string{operation_name};
1434     auto it =
1435         self->widget_extension_sync_call_handlers_.find(operation_name_string);
1436     if (it == self->widget_extension_sync_call_handlers_.end())
1437       return nullptr;
1438     return (self->*(it->second))(operation_data);
1439   };
1440   delegate->SetGenericSyncCallback(callback, this);
1441 }
1442
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);
1447   } else
1448     return ewk_value_boolean_new(EINA_FALSE);
1449 }
1450
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);
1455   else
1456     return ewk_value_boolean_new(EINA_FALSE);
1457 }
1458 #endif  // TIZEN_PEPPER_EXTENSIONS
1459
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)
1465     return;
1466
1467   auto* delegate = GetNativeWindowDelegate();
1468   if (!delegate)
1469     return;
1470
1471   if (prev_orientation == ScreenOrientation::NONE)
1472     delegate->OnConformantChange();
1473   delegate->SetScreenOrientation(this, orientation);
1474 }
1475
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";
1482
1483     auto orientation = ConvertRotatorOrientation(status.orientation);
1484     SetScreenOrientation(orientation);
1485
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.";
1490 #else
1491     auto callback = [](display_rotator_status_t* rotator_status, void* data) {
1492       LOG(INFO) << "display rotator callback is invoked!";
1493       if (!rotator_status)
1494         return;
1495
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);
1500     };
1501     if (DISPLAY_ROTATOR_OK != display_rotator_register_cb(0, callback, nullptr))
1502       LOG(ERROR) << "display_rotator_register_cb failed.";
1503 #endif
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);
1510     }
1511   }
1512 }
1513
1514 bool WRTNativeWindowTV::RegisterRotateSensorListener() {
1515   sensor_h sensor;
1516   if (sensor_get_default_sensor(SENSOR_AUTO_ROTATION, &sensor)
1517       != SENSOR_ERROR_NONE) {
1518     LOG(ERROR) << "sensor_get_default_sensor is error!";
1519     return false;
1520   }
1521   if (sensor_create_listener(sensor, &rotation_listener_) != SENSOR_ERROR_NONE) {
1522     LOG(ERROR) << "sensor_create_listener is error!";
1523     return false;
1524   }
1525
1526   auto callback = [](sensor_h sensor, sensor_event_s* event, void* data) {
1527     LOG(INFO) << "sensor listener callback is invoked!";
1528     if (!event || !sensor)
1529       return;
1530
1531     sensor_type_e type;
1532     sensor_get_type(sensor, &type);
1533     if (type != SENSOR_AUTO_ROTATION ) {
1534       LOG(INFO) << "not Rotation type!";
1535       return;
1536     }
1537
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);
1542   };
1543
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!";
1547     return false;
1548   }
1549   if (sensor_listener_start(rotation_listener_) != SENSOR_ERROR_NONE) {
1550     LOG(ERROR) << "sensor_listener_start is error!";
1551     return false;
1552   }
1553   LOG(INFO) << "reigster rotate sensor listener successfully.";
1554   return true;
1555 }
1556
1557 bool WRTNativeWindowTV::UnRegisterRotateSensorListener() {
1558   if (!rotation_listener_) {
1559     LOG(ERROR) << "rotation_listener_ is null!";
1560     return false;
1561   }
1562   if (sensor_listener_unset_event_cb(rotation_listener_) != SENSOR_ERROR_NONE) {
1563     LOG(ERROR) << "sensor_listener_unset_event_cb is error!";
1564     return false;
1565   }
1566   if (sensor_listener_stop(rotation_listener_) != SENSOR_ERROR_NONE) {
1567     LOG(ERROR) << "sensor_listener_stop is error!";
1568     return false;
1569   }
1570   if (sensor_destroy_listener(rotation_listener_) != SENSOR_ERROR_NONE) {
1571     LOG(ERROR) << "sensor_destroy_listener is error!";
1572     return false;
1573   }
1574   rotation_listener_ = nullptr;
1575   return true;
1576 }
1577
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());
1583 }
1584
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();
1591   if (delegate)
1592     delegate->DidFinishNavigation();
1593 }
1594
1595 void WRTNativeWindowTV::SetUpgradeWebapiJson() {
1596   auto upgrade_webapis_json_path =
1597       NativeWebRuntimeDelegateTV::GetInstance().GetUpgradeWebapiJsonPath();
1598
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());
1613   }
1614 }
1615
1616 bool WRTNativeWindowTV::IsSameWindowId(const unsigned int window_id) {
1617   return (wayland_window_id == window_id);
1618 }
1619
1620 void WRTNativeWindowTV::TakeScreenshot(
1621     const std::string& file_name, double scale_factor) {
1622   auto* rwhva = GetRenderWidgetHostView();
1623   if (!rwhva) {
1624     LOG(ERROR) << "rwhva is null";
1625     return;
1626   }
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);
1632 }
1633
1634 void WRTNativeWindowTV::Suspend() {
1635   LOG(INFO) << "suspend_timer is timeout";
1636   SetScheduledTasks(false);
1637 }
1638
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";
1643     return;
1644   }
1645   auto* render_interface = wrt_web_contents->GetRendererInterface();
1646   if (!render_interface) {
1647     LOG(ERROR) << "Frame is not created";
1648     return;
1649   }
1650
1651   render_interface->SuspendMediaTasks(suspend);
1652 }
1653
1654 bool WRTNativeWindowTV::IsJavaScriptDialogShowing() {
1655   auto dialog_manager = GetJavaScriptDialogManager();
1656   return dialog_manager && dialog_manager->IsShowing();
1657 }
1658
1659 void WRTNativeWindowTV::SetEnabled(bool enable) {
1660   if (is_enabled_ == enable)
1661     return;
1662
1663   LOG(INFO) << "Renderer scheduled-task will be " << enable;
1664   is_enabled_ = enable;
1665
1666   if (IsJavaScriptDialogShowing()) {
1667     LOG(INFO) << "Modal dialog is showing, skip SetScheduledTasks()";
1668     return;
1669   }
1670
1671   if (enable || !suspend_delay_) {
1672     if (suspend_timer_.IsRunning()) {
1673       LOG(INFO) << "stop suspend_timer";
1674       suspend_timer_.Stop();
1675     }
1676
1677     SetScheduledTasks(enable);
1678     return;
1679   }
1680
1681   LOG(INFO) << "suspend_delay : " << suspend_delay_;
1682   suspend_timer_.Start(FROM_HERE,
1683                        base::Milliseconds(suspend_delay_),
1684                        this, &WRTNativeWindowTV::Suspend);
1685 }
1686
1687 void WRTNativeWindowTV::SetSuspendDelay(int delay) {
1688   suspend_delay_ = delay;
1689   if (delay > SUSPEND_DELAY_TIME_MAX)
1690     suspend_delay_ = SUSPEND_DELAY_TIME_MAX;
1691   else if (delay < 0)
1692     suspend_delay_ = 0;
1693
1694   LOG(INFO) << "suspend delay time is  " << suspend_delay_ << " ms";
1695 }
1696
1697 void WRTNativeWindowTV::OnRotation(int degree) {
1698   int origin_degree = GetWebContentsViewAura()->GetOrientation();
1699   LOG(INFO) << "degree:" << degree << ", origin_degree : " << origin_degree;
1700
1701   WRTNativeWindow::OnRotation(degree);
1702   if (!is_main_native_window_)
1703     return;
1704
1705   auto* wrt_web_contents = WRTWebContents::FromNativeWindow(this);
1706   if (wrt_web_contents)
1707     wrt_web_contents->HidePopupMenuImpl();
1708
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_));
1716   }
1717
1718   RotateWindow(degree);
1719 }
1720
1721 void WRTNativeWindowTV::LowerWindow() {
1722   if (visibility_state_ == "hidden") {
1723     LOG(ERROR) << "window is already hidden, lower will be ignored.";
1724     return;
1725   }
1726   ecore_evas_lower(GetPlatformCanvas());
1727 }
1728
1729 void WRTNativeWindowTV::Focus(bool focus) {
1730   if (!is_main_native_window_)
1731     return;
1732
1733   if (use_focus_)
1734     ecore_evas_focus_set(GetPlatformCanvas(), focus);
1735 }
1736
1737 void WRTNativeWindowTV::SetZoomLevel(double level) {
1738   if (!web_contents_) {
1739     LOG(INFO) << "web_contents_ is nullptr";
1740     return;
1741   }
1742   if (!zoom_controller_) {
1743     electron::WebContentsZoomController::CreateForWebContents(web_contents_);
1744     zoom_controller_ =
1745         electron::WebContentsZoomController::FromWebContents(web_contents_);
1746   }
1747   LOG(INFO) << "SetZoomLevel : " << level;
1748   zoom_controller_->SetZoomLevel(level);
1749
1750   const char* style_type = (zoom_factor_ == 1.0 ? "default" : "portrait");
1751   auto* delegate = WRTNativeWindow::GetNativeWindowDelegate();
1752   if (delegate)
1753     delegate->SetZoomLevel(level, style_type);
1754 }
1755
1756 gfx::OverlayTransform WRTNativeWindowTV::GetOverlayTransform(int degree) {
1757   switch (degree) {
1758     case 90:
1759       return gfx::OVERLAY_TRANSFORM_ROTATE_270; // 270 is correct, not 90
1760     case 180:
1761       return gfx::OVERLAY_TRANSFORM_ROTATE_180;
1762     case 270:
1763       return gfx::OVERLAY_TRANSFORM_ROTATE_90;
1764     default:
1765       return gfx::OVERLAY_TRANSFORM_NONE;
1766   }
1767 }
1768
1769 int WRTNativeWindowTV::GetScreenDegree() {
1770   int degree = ecore_evas_rotation_get(GetPlatformCanvas());
1771   LOG(INFO) << "GetScreenDegree degree:" << degree;
1772   return degree;
1773 }
1774
1775 bool WRTNativeWindowTV::SetScreenDegree(const std::string& degree) {
1776   LOG(INFO) << "SetScreenDegree degree: " << degree;
1777   if (degree.empty())
1778     return false;
1779
1780   int screen_degree = 0;
1781   base::StringToInt(degree, &screen_degree);
1782   if (screen_degree < 0 || screen_degree % 90 != 0)
1783     return false;
1784
1785   ecore_evas_rotation_set(GetPlatformCanvas(), screen_degree);
1786   RotateWindow(screen_degree);
1787
1788   return true;
1789 }
1790
1791 bool WRTNativeWindowTV::SetFlipMode(const std::string& value) {
1792   LOG(INFO) << "SetFlipMode value: " << value;
1793   if (value.empty())
1794     return false;
1795
1796   if (value == "true")
1797     ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.video.flip.mode", "1");
1798   else
1799     ecore_evas_aux_hint_add(GetPlatformCanvas(), "wm.video.flip.mode", "0");
1800
1801   return true;
1802 }
1803
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,
1809                              &screen_height);
1810     if (screen_width == 0 || screen_height == 0)
1811       return;
1812
1813     evas_object_resize(top_window_, screen_width, screen_height);
1814     gfx::Rect bounds(0, 0, screen_width, screen_height);
1815     GetNativeView()->SetBounds(bounds);
1816   } else {
1817     auto* host = GetWindowTreeHost();
1818     host->SetDisplayTransformHint(GetOverlayTransform(degree));
1819
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);
1829
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();
1836     }
1837   }
1838   LOG(INFO) << "degree : " << degree << " (" << screen_width << "x"
1839             << screen_height << ")";
1840
1841   auto* extension_manager = XWalkExtensionManager::GetInstance();
1842   extension_manager->NotifyWindowEvent("orientation", std::to_string(degree));
1843 }
1844
1845 void WRTNativeWindowTV::ScreenSaverResetTimeout(void) {
1846   screensaver_reset_timeout();
1847 }
1848
1849 void WRTNativeWindowTV::SetScreenSaver(const std::string& state) {
1850   if (state == "0") {
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);
1858     }
1859   } else {
1860     activateScreenSaver(const_cast<char*>("DEFAULT"), 0, 0, DEFAULT_BLANKING,
1861                         DEFAULT_EXPOSURES);
1862     if (screensaver_reset_timer_.IsRunning())
1863       screensaver_reset_timer_.Stop();
1864   }
1865 }
1866
1867 void WRTNativeWindowTV::UnsetSuspendDelayForNonMultitasking() {
1868   if (!NativeWebRuntimeDelegateTV::GetInstance().IsMultitaskingSupport()) {
1869     suspend_delay_ = 0;
1870     LOG(INFO) << "app doesn't support multitasking, so no suspend delay "
1871                  "feature, will suspend app immediately";
1872   }
1873 }
1874
1875 }  // namespace wrt