From 94e5cf3272cc882999e2ed22dc4f820beeec272f Mon Sep 17 00:00:00 2001 From: "zhishun.zhou" Date: Fri, 15 Mar 2024 19:10:37 +0800 Subject: [PATCH 01/16] [M120 Migration][HBBTV] Merge track and subtitle related patches 1. Support subtitle notification feature: ewk interface: ewk_view_media_current_time_get ewk_settings_media_subtitle_notification_set ewk_settings_media_subtitle_notification_get ewk view callback: SubtitlePlay, SubtitlePause, SubtitleStop, SubtitleResume, SubtitleSeekStart, SubtitleSeekComplete, SubtitleNotifyData 2. Support track and subtitle interfaces ewk interface: ewk_media_set_subtitle_lang ewk view callback: FirstTimestamp, PESData Patches from: https://review.tizen.org/gerrit/#/c/292656/ https://review.tizen.org/gerrit/#/c/293447/ https://review.tizen.org/gerrit/#/c/293815/ https://review.tizen.org/gerrit/#/c/294812/ https://review.tizen.org/gerrit/#/c/300412/ https://review.tizen.org/gerrit/#/c/296871/ https://review.tizen.org/gerrit/#/c/301281/ Change-Id: Idd2374d50006c95ebcfa2d197df991376fda1acc Signed-off-by: peng1xiao Signed-off-by: zhishun.zhou --- .../playback_command_forwarding_renderer.cc | 7 + components/plugins/renderer/webview_plugin.h | 3 + .../renderer_host/render_widget_host_impl.cc | 20 + .../renderer_host/render_widget_host_impl.h | 4 + .../renderer_host/render_widget_host_view_aura.cc | 11 + .../renderer_host/render_widget_host_view_aura.h | 3 + .../renderer_host/render_widget_host_view_base.h | 5 + content/public/browser/web_contents_delegate.h | 15 + content/public/common/content_switches.cc | 3 + content/public/common/content_switches.h | 1 + content/public/test/fake_render_widget_host.h | 3 + media/base/pipeline.h | 38 + media/base/pipeline_impl.cc | 114 ++ media/base/pipeline_impl.h | 6 + media/base/renderer.h | 4 + media/base/renderer_client.h | 10 + media/filters/pipeline_controller.cc | 32 + media/filters/pipeline_controller.h | 4 + media/mojo/clients/mojo_renderer.cc | 40 + media/mojo/clients/mojo_renderer.h | 4 + media/mojo/clients/mojo_renderer_wrapper.cc | 23 + media/mojo/clients/mojo_renderer_wrapper.h | 4 + media/mojo/mojom/renderer.mojom | 12 + media/mojo/mojom/renderer_extensions.mojom | 46 + media/mojo/services/mojo_renderer_service.cc | 36 + media/mojo/services/mojo_renderer_service.h | 4 + net/base/mime_util.cc | 1 + .../web_preferences_mojom_traits.cc | 2 + .../common/web_preferences/web_preferences.h | 1 + .../web_preferences/web_preferences_mojom_traits.h | 7 + .../mojom/webpreferences/web_preferences.mojom | 3 + .../public/mojom/widget/platform_widget.mojom | 7 + .../blink/public/platform/web_media_player.h | 16 + .../public/platform/web_media_player_client.h | 15 + third_party/blink/public/web/web_settings.h | 2 + third_party/blink/public/web/web_view.h | 1 + .../blink/renderer/bindings/generated_in_core.gni | 2 + .../blink/renderer/bindings/idl_in_core.gni | 1 + third_party/blink/renderer/core/dom/document.cc | 8 + third_party/blink/renderer/core/dom/document.h | 1 + .../core/execution_context/execution_context.cc | 19 + .../core/execution_context/execution_context.h | 1 + .../execution_context_lifecycle_state_observer.h | 1 + .../renderer/core/exported/web_settings_impl.cc | 8 + .../renderer/core/exported/web_settings_impl.h | 2 + .../blink/renderer/core/exported/web_view_impl.cc | 13 + .../blink/renderer/core/exported/web_view_impl.h | 1 + third_party/blink/renderer/core/frame/settings.h | 8 + .../renderer/core/frame/web_frame_widget_impl.cc | 19 + .../renderer/core/frame/web_frame_widget_impl.h | 7 + third_party/blink/renderer/core/html/build.gni | 2 + .../renderer/core/html/media/html_media_element.cc | 431 ++++++- .../renderer/core/html/media/html_media_element.h | 32 + .../renderer/core/html/track/html_track_element.cc | 35 +- .../blink/renderer/core/html/track/text_track.cc | 59 +- .../blink/renderer/core/html/track/text_track.h | 46 + .../blink/renderer/core/html/track/text_track.idl | 2 +- .../renderer/core/html/track/text_track_cue.cc | 11 + .../renderer/core/html/track/text_track_cue.h | 8 + .../renderer/core/html/track/text_track_list.cc | 16 + .../renderer/core/html/track/text_track_list.h | 4 + .../blink/renderer/core/html/track/track_base.h | 15 + .../platform/media/web_media_player_impl.cc | 150 +++ .../platform/media/web_media_player_impl.h | 6 + .../platform/runtime_enabled_features.json5 | 2 +- .../blink/renderer/platform/widget/widget_base.cc | 15 + .../blink/renderer/platform/widget/widget_base.h | 4 + .../renderer/platform/widget/widget_base_client.h | 1 + .../content/browser/media/tizen_renderer_impl.cc | 80 ++ .../content/browser/media/tizen_renderer_impl.h | 11 + .../renderer_host/rwhv_aura_common_helper_efl.cc | 21 + .../renderer_host/rwhv_aura_common_helper_efl.h | 5 + .../media/tizen/media_player_renderer_client.cc | 69 ++ .../media/tizen/media_player_renderer_client.h | 4 + .../media/base/efl/media_player_util_efl.cc | 225 ++++ .../media/base/efl/media_player_util_efl.h | 1 + .../media/filters/media_player_bridge_capi.h | 31 +- .../media/filters/media_player_bridge_capi_tv.cc | 1309 +++++++++++++++++++- .../media/filters/media_player_bridge_capi_tv.h | 93 ++ .../media/filters/media_player_tizen.h | 5 + .../media/filters/media_player_tizen_client.h | 8 + tizen_src/ewk/efl_integration/eweb_view.cc | 86 ++ tizen_src/ewk/efl_integration/eweb_view.h | 19 +- .../ewk/efl_integration/eweb_view_callbacks.h | 22 + .../public/ewk_media_subtitle_info.cc | 165 ++- .../public/ewk_media_subtitle_info_product.h | 13 + .../ewk/efl_integration/public/ewk_settings.cc | 16 +- tizen_src/ewk/efl_integration/public/ewk_view.cc | 14 +- .../efl_integration/web_contents_delegate_efl.cc | 34 + .../efl_integration/web_contents_delegate_efl.h | 15 + 90 files changed, 3634 insertions(+), 49 deletions(-) diff --git a/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc b/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc index b35995a..ccf00d8 100644 --- a/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc +++ b/components/cast_streaming/renderer/control/playback_command_forwarding_renderer.cc @@ -76,6 +76,13 @@ class RendererCommandForwarder : public media::mojom::Renderer { owning_renderer_->MojoRendererSetCdm(cdm_id, std::move(callback)); } +#if BUILDFLAG(IS_TIZEN_TV) + void SetActiveTextTrack(int, bool) override {} + void SetActiveAudioTrack(int) override {} + void SetActiveVideoTrack(int) override {} + void SetPreferTextLanguage(const std::string&) override {} +#endif + private: const raw_ptr owning_renderer_; diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h index 773dc1b..4d9c310 100644 --- a/components/plugins/renderer/webview_plugin.h +++ b/components/plugins/renderer/webview_plugin.h @@ -197,6 +197,9 @@ class WebViewPlugin : public blink::WebPlugin, public blink::WebViewObserver { void SetCursor(const ui::Cursor& cursor) override; #if BUILDFLAG(IS_TIZEN_TV) void DidEdgeScrollBy(const gfx::Point& point, bool handled) override {} + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) override {} #endif void UpdateTooltipUnderCursor(const std::u16string& tooltip_text, base::i18n::TextDirection hint) override; diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc index 3bd35b3..43ed9e9 100644 --- a/content/browser/renderer_host/render_widget_host_impl.cc +++ b/content/browser/renderer_host/render_widget_host_impl.cc @@ -639,6 +639,14 @@ void RenderWidgetHostImpl::SetParentalRatingResult(const std::string& url, } blink_widget_->SetParentalRatingResult(url, is_pass); } + +void RenderWidgetHostImpl::SetPreferSubtitleLang(std::string lang_list) { + if (!blink_widget_) { + LOG(ERROR) << "blink_widget_ is null"; + return; + } + blink_widget_->SetPreferSubtitleLang(lang_list); +} #endif // static @@ -2781,6 +2789,18 @@ void RenderWidgetHostImpl::SetTranslatedURL(const std::string& url) { return; blink_widget_->SetTranslatedURL(url); } + +void RenderWidgetHostImpl::NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) { + LOG(INFO) << __func__; + if (!GetView()) { + LOG(ERROR) << __func__ << ", GetView return null"; + return; + } + + view_->NotifyTrackInfoToBrowser(active_track_id, url, lang); +} #endif void RenderWidgetHostImpl::UpdateTooltipUnderCursor( diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h index 5141bdf..d895491 100644 --- a/content/browser/renderer_host/render_widget_host_impl.h +++ b/content/browser/renderer_host/render_widget_host_impl.h @@ -322,6 +322,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& point, bool handled) override; + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) override; #endif void UpdateTooltipUnderCursor( const std::u16string& tooltip_text, @@ -384,6 +387,7 @@ class CONTENT_EXPORT RenderWidgetHostImpl void OnGetVideoPlayingStatus(int callback_id, bool is_playing); void SetTranslatedURL(const std::string& url); void SetParentalRatingResult(const std::string& url, bool is_pass); + void SetPreferSubtitleLang(std::string lang_list); #endif RenderWidgetHostDelegate* delegate() const { return delegate_; } diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc index c6efa4f..b22ac2a 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.cc +++ b/content/browser/renderer_host/render_widget_host_view_aura.cc @@ -2313,6 +2313,17 @@ void RenderWidgetHostViewAura::DidEdgeScrollBy(const gfx::Point& offset, bool handled) { efl_helper_->DidEdgeScrollBy(offset, handled); } + +void RenderWidgetHostViewAura::NotifyTrackInfoToBrowser( + int active_track_id, + const std::string& url, + const std::string& lang) { + if (!aura_efl_helper()) { + LOG(ERROR) << "aura_efl_helper() is null"; + return; + } + aura_efl_helper()->NotifyTrackInfoToBrowser(active_track_id, url, lang); +} #endif void RenderWidgetHostViewAura::OnScrollEvent(ui::ScrollEvent* event) { diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h index d18e39a..92245f7 100644 --- a/content/browser/renderer_host/render_widget_host_view_aura.h +++ b/content/browser/renderer_host/render_widget_host_view_aura.h @@ -230,6 +230,9 @@ class CONTENT_EXPORT RenderWidgetHostViewAura #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled) override ; + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) override; #endif void OnSynchronizedDisplayPropertiesChanged(bool rotation = false) override; viz::ScopedSurfaceIdAllocator DidUpdateVisualProperties( diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h index a47162f..2b55acf 100644 --- a/content/browser/renderer_host/render_widget_host_view_base.h +++ b/content/browser/renderer_host/render_widget_host_view_base.h @@ -509,6 +509,11 @@ class CONTENT_EXPORT RenderWidgetHostViewBase : public RenderWidgetHostView { virtual void DidEdgeScrollBy(const gfx::Point& offset, bool handled) {} // notify web browser video playing status virtual void VideoPlayingStatusReceived(bool is_playing, int callback_id) {} + + // Notify track info to browser + virtual void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) {} #endif // Calls UpdateTooltip if the view is under the cursor. diff --git a/content/public/browser/web_contents_delegate.h b/content/public/browser/web_contents_delegate.h index 1ad242e..c561d38 100644 --- a/content/public/browser/web_contents_delegate.h +++ b/content/public/browser/web_contents_delegate.h @@ -754,6 +754,21 @@ class CONTENT_EXPORT WebContentsDelegate { const std::string& value, const std::string& data, int type) {} + virtual void NotifySubtitleState(int state, double time_stamp = 0.0) {} + virtual void NotifySubtitlePlay(int active_track_id, + const std::string& url, + const std::string& lang) {} + virtual void NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned size) {} + virtual void UpdateCurrentTime(double current_time) {} + virtual void NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) {} + virtual void NotifyPESData(const std::string& buf, + unsigned int len, + int media_position) {} #endif #if BUILDFLAG(IS_ANDROID) diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 7f95a83..6da2f0e 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -1083,6 +1083,9 @@ const char kEnableMediaPlaybackNotification[] = "enable-media-playback-notification"; // Enables dual decoding for webrtc video call const char kDualDecodingWebRTC[] = "enable-webrtc-dual-decoding"; +// Enables media subtitle notification for other applications +const char kEnableMediaSubtitleNotification[] = + "enable-media-subtitle-notification"; // Enables multiplayers feature for web app const char kEnableMultiPlayerForWebapp[] = "enable-multiplayer-for-webapp"; #endif diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index a851eed..f5c5852 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -302,6 +302,7 @@ CONTENT_EXPORT extern const char kMaxRefreshRate[]; #if BUILDFLAG(IS_TIZEN_TV) CONTENT_EXPORT extern const char kEnableMediaPlaybackNotification[]; CONTENT_EXPORT extern const char kDualDecodingWebRTC[]; +CONTENT_EXPORT extern const char kEnableMediaSubtitleNotification[]; CONTENT_EXPORT extern const char kEnableMultiPlayerForWebapp[]; #endif diff --git a/content/public/test/fake_render_widget_host.h b/content/public/test/fake_render_widget_host.h index b286d8d..983e724 100644 --- a/content/public/test/fake_render_widget_host.h +++ b/content/public/test/fake_render_widget_host.h @@ -60,6 +60,9 @@ class FakeRenderWidgetHost : public blink::mojom::FrameWidgetHost, void SetCursor(const ui::Cursor& cursor) override; #if BUILDFLAG(IS_TIZEN_TV) void DidEdgeScrollBy(const ::gfx::Point& offset, bool handled) override; + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) override {} #endif void UpdateTooltipUnderCursor( const std::u16string& tooltip_text, diff --git a/media/base/pipeline.h b/media/base/pipeline.h index 62f5dae1..0a1260e 100644 --- a/media/base/pipeline.h +++ b/media/base/pipeline.h @@ -31,6 +31,35 @@ namespace media { class CdmContext; class Demuxer; +enum TRACKCMD { SETTEXT, SETAUDIO, SETVIDEO, SETINBAND, SETCUE }; + +struct InbandTextInfo { + std::string info; + int band_type; + int action; +}; + +struct TrackInfo { + std::string id; + std::string kind; + std::string label; + std::string language; + bool enabled; +}; + +struct InbandCueInfo { + std::string info; + int id; + int band_type; + int stime; + int etime; +}; + +struct MediaTrackInfo { + TRACKCMD cmd; + void* info; +}; + class MEDIA_EXPORT Pipeline { public: class Client { @@ -59,6 +88,11 @@ class MEDIA_EXPORT Pipeline { virtual void OnBufferingStateChange(BufferingState state, BufferingStateChangeReason reason) = 0; +#if BUILDFLAG(IS_TIZEN_TV) + virtual void NotifyTrackInfoToBrowser(int active_track_id) {} + virtual void AddTrackInfo(MediaTrackInfo trackinfo) {} +#endif + // Executed whenever the presentation duration changes. virtual void OnDurationChange() = 0; @@ -282,6 +316,10 @@ class MEDIA_EXPORT Pipeline { #if BUILDFLAG(IS_TIZEN_TV) virtual void SetContentMimeType(const std::string& mime_type) = 0; virtual void SetParentalRatingResult(bool is_pass) = 0; + virtual void SetActiveTextTrack(int id, bool is_in_band) = 0; + virtual void SetActiveAudioTrack(int index) = 0; + virtual void SetActiveVideoTrack(int index) = 0; + virtual void SetPreferTextLanguage(const std::string& lang) = 0; #endif }; diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc index 63aaf7d..05d72c1 100644 --- a/media/base/pipeline_impl.cc +++ b/media/base/pipeline_impl.cc @@ -117,6 +117,10 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost, #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type); void SetParentalRatingResult(bool is_pass); + void SetActiveTextTrack(int id, bool is_in_band); + void SetActiveAudioTrack(int index); + void SetActiveVideoTrack(int index); + void SetPreferTextLanguage(const std::string& lang); #endif // |enabled_track_ids| contains track ids of enabled audio tracks. @@ -185,6 +189,10 @@ class PipelineImpl::RendererWrapper final : public DemuxerHost, void OnFallback(PipelineStatus status) final; void OnEnded() final; void OnStatisticsUpdate(const PipelineStatistics& stats) final; +#if BUILDFLAG(IS_TIZEN_TV) + void NotifyTrackInfoToBrowser(int active_track_id) final; + void AddTrackInfo(media::MediaTrackInfo trackinfo); +#endif void OnBufferingStateChange(BufferingState state, BufferingStateChangeReason reason) final; void OnWaiting(WaitingReason reason) final; @@ -714,6 +722,48 @@ void PipelineImpl::RendererWrapper::SetParentalRatingResult(bool is_pass) { else LOG(ERROR) << "renderer is null"; } + +void PipelineImpl::RendererWrapper::SetActiveTextTrack(int id, + bool is_in_band) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + + if (!shared_state_.renderer) { + LOG(ERROR) << "renderer is null"; + return; + } + shared_state_.renderer->SetActiveTextTrack(id, is_in_band); +} + +void PipelineImpl::RendererWrapper::SetActiveAudioTrack(int index) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + + if (!shared_state_.renderer) { + LOG(ERROR) << "renderer is null"; + return; + } + shared_state_.renderer->SetActiveAudioTrack(index); +} + +void PipelineImpl::RendererWrapper::SetActiveVideoTrack(int index) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + + if (!shared_state_.renderer) { + LOG(ERROR) << "renderer is null"; + return; + } + shared_state_.renderer->SetActiveVideoTrack(index); +} + +void PipelineImpl::RendererWrapper::SetPreferTextLanguage( + const std::string& lang) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + + if (!shared_state_.renderer) { + LOG(ERROR) << "renderer is null"; + return; + } + shared_state_.renderer->SetPreferTextLanguage(lang); +} #endif #if BUILDFLAG(IS_TIZEN_TV) @@ -1026,6 +1076,24 @@ void PipelineImpl::RendererWrapper::OnStatisticsUpdate( } } +#if BUILDFLAG(IS_TIZEN_TV) +void PipelineImpl::RendererWrapper::NotifyTrackInfoToBrowser( + int active_track_id) { + DVLOG(2) << __func__; + main_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&PipelineImpl::NotifyTrackInfoToBrowser, + weak_pipeline_, active_track_id)); +} + +void PipelineImpl::RendererWrapper::AddTrackInfo( + media::MediaTrackInfo trackinfo) { + DVLOG(2) << __func__; + main_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&PipelineImpl::AddTrackInfo, weak_pipeline_, + std::move(trackinfo))); +} +#endif + void PipelineImpl::RendererWrapper::OnBufferingStateChange( BufferingState state, BufferingStateChangeReason reason) { @@ -1949,6 +2017,52 @@ void PipelineImpl::SetParentalRatingResult(bool is_pass) { DCHECK(thread_checker_.CalledOnValidThread()); renderer_wrapper_->SetParentalRatingResult(is_pass); } + +void PipelineImpl::SetActiveTextTrack(int id, bool is_in_band) { + DVLOG(2) << __func__; + DCHECK(thread_checker_.CalledOnValidThread()); + media_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&RendererWrapper::SetActiveTextTrack, + base::Unretained(renderer_wrapper_.get()), id, + is_in_band)); +} + +void PipelineImpl::SetActiveAudioTrack(int index) { + DVLOG(2) << __func__; + DCHECK(thread_checker_.CalledOnValidThread()); + media_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RendererWrapper::SetActiveAudioTrack, + base::Unretained(renderer_wrapper_.get()), index)); +} + +void PipelineImpl::SetActiveVideoTrack(int index) { + DVLOG(2) << __func__; + DCHECK(thread_checker_.CalledOnValidThread()); + media_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RendererWrapper::SetActiveVideoTrack, + base::Unretained(renderer_wrapper_.get()), index)); +} + +void PipelineImpl::SetPreferTextLanguage(const std::string& lang) { + DVLOG(2) << __func__; + DCHECK(thread_checker_.CalledOnValidThread()); + media_task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&RendererWrapper::SetPreferTextLanguage, + base::Unretained(renderer_wrapper_.get()), lang)); +} + +void PipelineImpl::NotifyTrackInfoToBrowser(int active_track_id) { + DCHECK(client_); + client_->NotifyTrackInfoToBrowser(active_track_id); +} + +void PipelineImpl::AddTrackInfo(media::MediaTrackInfo trackinfo) { + DCHECK(client_); + client_->AddTrackInfo(std::move(trackinfo)); +} #endif void PipelineImpl::OnDurationChange(base::TimeDelta duration) { diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h index d49ba75..c933533 100644 --- a/media/base/pipeline_impl.h +++ b/media/base/pipeline_impl.h @@ -176,7 +176,13 @@ class MEDIA_EXPORT PipelineImpl : public Pipeline { void OnMetadata(const PipelineMetadata& metadata); #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type) override; + void NotifyTrackInfoToBrowser(int active_track_id); void SetParentalRatingResult(bool is_pass) override; + void AddTrackInfo(media::MediaTrackInfo trackinfo); + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveAudioTrack(int index) override; + void SetActiveVideoTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; #endif void OnBufferingStateChange(BufferingState state, BufferingStateChangeReason reason); diff --git a/media/base/renderer.h b/media/base/renderer.h index e1c5783..bde538a 100644 --- a/media/base/renderer.h +++ b/media/base/renderer.h @@ -110,6 +110,10 @@ class MEDIA_EXPORT Renderer { #if BUILDFLAG(IS_TIZEN_TV) virtual void SetContentMimeType(const std::string& mime_type) {} virtual void SetParentalRatingResult(bool is_pass) {} + virtual void SetActiveTextTrack(int id, bool is_in_band) {} + virtual void SetActiveAudioTrack(int index) {} + virtual void SetActiveVideoTrack(int index) {} + virtual void SetPreferTextLanguage(const std::string& lang) {} #endif // Starts rendering from |time|. diff --git a/media/base/renderer_client.h b/media/base/renderer_client.h index f53f7e6..1dcbdd1 100644 --- a/media/base/renderer_client.h +++ b/media/base/renderer_client.h @@ -15,6 +15,11 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "media/base/pipeline.h" +#include "media/mojo/mojom/renderer_extensions.mojom.h" +#endif + namespace media { // Interface used by Renderer, AudioRenderer, VideoRenderer and @@ -35,6 +40,11 @@ class MEDIA_EXPORT RendererClient { // OnStatisticsUpdate() call. virtual void OnStatisticsUpdate(const PipelineStatistics& stats) = 0; +#if BUILDFLAG(IS_TIZEN_TV) + virtual void NotifyTrackInfoToBrowser(int active_track_id) {} + virtual void AddTrackInfo(media::MediaTrackInfo trackinfo) {} +#endif + // Executed when buffering state is changed. |reason| indicates the cause of // the state change, when known. virtual void OnBufferingStateChange(BufferingState state, diff --git a/media/filters/pipeline_controller.cc b/media/filters/pipeline_controller.cc index 1bb647a..eed47f6 100644 --- a/media/filters/pipeline_controller.cc +++ b/media/filters/pipeline_controller.cc @@ -489,5 +489,37 @@ void PipelineController::SetParentalRatingResult(bool is_pass) { else LOG(ERROR) << "pipeline_ is null"; } + +void PipelineController::SetActiveTextTrack(int id, bool is_in_band) { + if (!pipeline_) { + LOG(ERROR) << "pipeline_ is null"; + return; + } + pipeline_->SetActiveTextTrack(id, is_in_band); +} + +void PipelineController::SetActiveAudioTrack(int index) { + if (!pipeline_) { + LOG(ERROR) << "pipeline_ is null"; + return; + } + pipeline_->SetActiveAudioTrack(index); +} + +void PipelineController::SetActiveVideoTrack(int index) { + if (!pipeline_) { + LOG(ERROR) << "pipeline_ is null"; + return; + } + pipeline_->SetActiveVideoTrack(index); +} + +void PipelineController::SetPreferTextLanguage(const std::string& lang) { + if (!pipeline_) { + LOG(ERROR) << "pipeline_ is null"; + return; + } + pipeline_->SetPreferTextLanguage(lang); +} #endif } // namespace media diff --git a/media/filters/pipeline_controller.h b/media/filters/pipeline_controller.h index c7d06ef..113d8bb 100644 --- a/media/filters/pipeline_controller.h +++ b/media/filters/pipeline_controller.h @@ -166,6 +166,10 @@ class MEDIA_EXPORT PipelineController { #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type); void SetParentalRatingResult(bool is_pass); + void SetActiveTextTrack(int id, bool is_in_band); + void SetActiveAudioTrack(int index); + void SetActiveVideoTrack(int index); + void SetPreferTextLanguage(const std::string& lang); #endif private: // Attempts to make progress from the current state to the target state. diff --git a/media/mojo/clients/mojo_renderer.cc b/media/mojo/clients/mojo_renderer.cc index da89779..55c5084 100644 --- a/media/mojo/clients/mojo_renderer.cc +++ b/media/mojo/clients/mojo_renderer.cc @@ -360,6 +360,46 @@ void MojoRenderer::SetParentalRatingResult(bool is_pass) { else LOG(ERROR) << "remote_renderer is null"; } + +void MojoRenderer::SetActiveTextTrack(int id, bool is_in_band) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (!remote_renderer_.is_bound()) { + LOG(ERROR) << "remote_renderer is not bound"; + return; + } + remote_renderer_->SetActiveTextTrack(id, is_in_band); +} + +void MojoRenderer::SetActiveAudioTrack(int index) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (!remote_renderer_.is_bound()) { + LOG(ERROR) << "remote_renderer is not bound"; + return; + } + remote_renderer_->SetActiveAudioTrack(index); +} + +void MojoRenderer::SetActiveVideoTrack(int index) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (!remote_renderer_.is_bound()) { + LOG(ERROR) << "remote_renderer is not bound"; + return; + } + remote_renderer_->SetActiveVideoTrack(index); +} + +void MojoRenderer::SetPreferTextLanguage(const std::string& lang) { + DCHECK(task_runner_->RunsTasksInCurrentSequence()); + + if (!remote_renderer_.is_bound()) { + LOG(ERROR) << "remote_renderer is not bound"; + return; + } + remote_renderer_->SetPreferTextLanguage(lang); +} #endif void MojoRenderer::OnWaiting(WaitingReason reason) { diff --git a/media/mojo/clients/mojo_renderer.h b/media/mojo/clients/mojo_renderer.h index bb3ca96..aa08217 100644 --- a/media/mojo/clients/mojo_renderer.h +++ b/media/mojo/clients/mojo_renderer.h @@ -79,6 +79,10 @@ class MojoRenderer : public Renderer, public mojom::RendererClient { #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type) override; void SetParentalRatingResult(bool is_pass) override; + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveAudioTrack(int index) override; + void SetActiveVideoTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; #endif private: diff --git a/media/mojo/clients/mojo_renderer_wrapper.cc b/media/mojo/clients/mojo_renderer_wrapper.cc index 798099f..4f1c591 100644 --- a/media/mojo/clients/mojo_renderer_wrapper.cc +++ b/media/mojo/clients/mojo_renderer_wrapper.cc @@ -88,6 +88,29 @@ void MojoRendererWrapper::SetParentalRatingResult(bool is_pass) { else LOG(ERROR) << "mojo_renderer_ is null"; } + +void MojoRendererWrapper::SetActiveTextTrack(int id, bool is_in_band) { + if (!mojo_renderer_) { + LOG(ERROR) << "mojo_renderer_ is null"; + return; + } + mojo_renderer_->SetActiveTextTrack(id, is_in_band); +} + +void MojoRendererWrapper::SetActiveAudioTrack(int index) { + if (mojo_renderer_) + mojo_renderer_->SetActiveAudioTrack(index); +} + +void MojoRendererWrapper::SetActiveVideoTrack(int index) { + if (mojo_renderer_) + mojo_renderer_->SetActiveVideoTrack(index); +} + +void MojoRendererWrapper::SetPreferTextLanguage(const std::string& lang) { + if (mojo_renderer_) + mojo_renderer_->SetPreferTextLanguage(lang); +} #endif } // namespace media diff --git a/media/mojo/clients/mojo_renderer_wrapper.h b/media/mojo/clients/mojo_renderer_wrapper.h index cd3b5d9..fb68130 100644 --- a/media/mojo/clients/mojo_renderer_wrapper.h +++ b/media/mojo/clients/mojo_renderer_wrapper.h @@ -51,6 +51,10 @@ class MojoRendererWrapper : public Renderer { #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type) override; void SetParentalRatingResult(bool is_pass) override; + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveVideoTrack(int index) override; + void SetActiveAudioTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; #endif base::TimeDelta GetMediaTime() override; diff --git a/media/mojo/mojom/renderer.mojom b/media/mojo/mojom/renderer.mojom index e1342e6..71979eb 100644 --- a/media/mojo/mojom/renderer.mojom +++ b/media/mojo/mojom/renderer.mojom @@ -73,6 +73,18 @@ interface Renderer { [EnableIf=is_tizen_tv] SetParentalRatingResult(bool is_pass); + + [EnableIf=is_tizen_tv] + SetActiveTextTrack(int32 id, bool is_in_band); + + [EnableIf=is_tizen_tv] + SetActiveAudioTrack(int32 index); + + [EnableIf=is_tizen_tv] + SetActiveVideoTrack(int32 index); + + [EnableIf=is_tizen_tv] + SetPreferTextLanguage(string lang); }; // A Mojo equivalent of media::RendererClient. See media/mojo/README.md diff --git a/media/mojo/mojom/renderer_extensions.mojom b/media/mojo/mojom/renderer_extensions.mojom index 93abe9e..966f077 100644 --- a/media/mojo/mojom/renderer_extensions.mojom +++ b/media/mojo/mojom/renderer_extensions.mojom @@ -13,6 +13,46 @@ import "ui/gfx/mojom/buffer_types.mojom"; [EnableIf=is_win] import "ui/gfx/mojom/buffer_types.mojom"; +enum TRACKCMD{ + SETTEXT, + SETAUDIO, + SETVIDEO, + SETINBAND, + SETCUE +}; + +struct InbandTextInfo { + string info; + int32 band_type; + int32 action; +}; + +struct Track { + string id; + string kind; + string label; + string language; + bool enabled; +}; + +struct InbandCueInfo { + string info; + uint32 id; + int32 band_type; + int64 stime; + int64 etime; +}; + +union COOKIES { + Track track; + InbandTextInfo inband; + InbandCueInfo cue; +}; + +struct MediaTrackInfo { + TRACKCMD cmd; + COOKIES ck; +}; // Extension of the mojo::RendererClient communication layer for HLS and Android // software rendering fallback paths. // This allows the Browser side to call back into the Renderer side. Concretely, @@ -39,6 +79,12 @@ interface MediaPlayerRendererClientExtension { OnNewTbmFrameAvailable(uint32 playerId, gfx.mojom.TbmBufferHandle tbm_buffer_handle, mojo_base.mojom.TimeDelta timestamp); + + [EnableIf=is_tizen_tv] + NotifyTrackInfoToBrowser(int32 active_track_id); + + [EnableIf=is_tizen_tv] + AddTrackInfo(MediaTrackInfo trackinfo); }; // Extension of the mojo::Renderer communication layer for HLS and Android diff --git a/media/mojo/services/mojo_renderer_service.cc b/media/mojo/services/mojo_renderer_service.cc index 9cf82ee..5537033 100644 --- a/media/mojo/services/mojo_renderer_service.cc +++ b/media/mojo/services/mojo_renderer_service.cc @@ -223,6 +223,42 @@ void MojoRendererService::SetParentalRatingResult(bool is_pass) { else LOG(ERROR) << "renderer_ is null"; } + +void MojoRendererService::SetActiveTextTrack(int id, bool is_in_band) { + DVLOG(2) << __func__ << "(id:" << id << ", is_in_band:" << is_in_band << ")"; + if (!renderer_) { + LOG(ERROR) << "renderer_ is null"; + return; + } + renderer_->SetActiveTextTrack(id, is_in_band); +} + +void MojoRendererService::SetActiveAudioTrack(int index) { + DVLOG(2) << __func__ << "(index:" << index << ")"; + if (!renderer_) { + LOG(ERROR) << "renderer_ is null"; + return; + } + renderer_->SetActiveAudioTrack(index); +} + +void MojoRendererService::SetActiveVideoTrack(int index) { + DVLOG(2) << __func__ << "(index:" << index << ")"; + if (!renderer_) { + LOG(ERROR) << "renderer_ is null"; + return; + } + renderer_->SetActiveVideoTrack(index); +} + +void MojoRendererService::SetPreferTextLanguage(const std::string& lang) { + DVLOG(2) << __func__ << "(lang:" << lang << ")"; + if (!renderer_) { + LOG(ERROR) << "renderer_ is null"; + return; + } + renderer_->SetPreferTextLanguage(lang); +} #endif void MojoRendererService::OnBufferingStateChange( diff --git a/media/mojo/services/mojo_renderer_service.h b/media/mojo/services/mojo_renderer_service.h index 4088111..afc535a 100644 --- a/media/mojo/services/mojo_renderer_service.h +++ b/media/mojo/services/mojo_renderer_service.h @@ -85,6 +85,10 @@ class MEDIA_MOJO_EXPORT MojoRendererService final : public mojom::Renderer, #if BUILDFLAG(IS_TIZEN_TV) void SetContentMimeType(const std::string& mime_type) final; void SetParentalRatingResult(bool is_pass) final; + void SetActiveTextTrack(int id, bool is_in_band) final; + void SetActiveAudioTrack(int index) final; + void SetActiveVideoTrack(int index) final; + void SetPreferTextLanguage(const std::string& lang) final; #endif private: diff --git a/net/base/mime_util.cc b/net/base/mime_util.cc index 0cc3af3..af82113 100644 --- a/net/base/mime_util.cc +++ b/net/base/mime_util.cc @@ -235,6 +235,7 @@ static const MimeInfo kSecondaryMappings[] = { {"video/mpeg", "mpeg,mpg"}, #if BUILDFLAG(IS_TIZEN_TV) {"application/dash+xml", "mpd"}, + {"application/ttml+xml", "ttml"}, {"application/vnd.oipf.contentaccessstreaming+xml", "casd"}, #endif }; diff --git a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc index 1c09ddf..699cd9d 100644 --- a/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc +++ b/third_party/blink/common/web_preferences/web_preferences_mojom_traits.cc @@ -265,6 +265,8 @@ bool StructTraitsmedia_playback_notification_enabled = data.media_playback_notification_enabled(); + out->media_subtitle_notification_enabled = + data.media_subtitle_notification_enabled(); #endif return true; } diff --git a/third_party/blink/public/common/web_preferences/web_preferences.h b/third_party/blink/public/common/web_preferences/web_preferences.h index cb56a6a..3c79709 100644 --- a/third_party/blink/public/common/web_preferences/web_preferences.h +++ b/third_party/blink/public/common/web_preferences/web_preferences.h @@ -322,6 +322,7 @@ struct BLINK_COMMON_EXPORT WebPreferences { #if BUILDFLAG(IS_TIZEN_TV) bool media_playback_notification_enabled = false; + bool media_subtitle_notification_enabled = false; #endif // Whether download UI should be hidden on this page. diff --git a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h index 0ed0971..1bc71f9 100644 --- a/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h +++ b/third_party/blink/public/common/web_preferences/web_preferences_mojom_traits.h @@ -893,6 +893,13 @@ struct BLINK_COMMON_EXPORT StructTraitsSetPreferTextLang(lang); +} #endif template class CORE_TEMPLATE_EXPORT Supplement; diff --git a/third_party/blink/renderer/core/dom/document.h b/third_party/blink/renderer/core/dom/document.h index c64ad1f..960abdd 100644 --- a/third_party/blink/renderer/core/dom/document.h +++ b/third_party/blink/renderer/core/dom/document.h @@ -1745,6 +1745,7 @@ class CORE_EXPORT Document : public ContainerNode, #if BUILDFLAG(IS_TIZEN_TV) void SetParentalRatingResult(const String& url, bool is_pass); + void SetPreferTextLang(const String&); #endif #if DCHECK_IS_ON() diff --git a/third_party/blink/renderer/core/execution_context/execution_context.cc b/third_party/blink/renderer/core/execution_context/execution_context.cc index c0382ee..f370d36 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.cc +++ b/third_party/blink/renderer/core/execution_context/execution_context.cc @@ -328,6 +328,25 @@ bool ExecutionContext::CheckVideoPlaying() const { return result; } + +void ExecutionContext::SetPreferTextLang(const String& lang) { + ContextLifecycleNotifier::observers().ForEachObserver( + [&](ContextLifecycleObserver* observer) { + if (!observer->IsExecutionContextLifecycleObserver()) + return; + if (static_cast(observer) + ->ObserverType() != + ExecutionContextLifecycleObserver::kStateObjectType) + return; + ExecutionContextLifecycleStateObserver* state_observer = + static_cast(observer); +#if DCHECK_IS_ON() + DCHECK_EQ(state_observer->GetExecutionContext(), Context()); + DCHECK(state_observer->UpdateStateIfNeededCalled()); +#endif + state_observer->SetPreferTextLang(lang); + }); +} #endif void ExecutionContext::AddConsoleMessageImpl( diff --git a/third_party/blink/renderer/core/execution_context/execution_context.h b/third_party/blink/renderer/core/execution_context/execution_context.h index bfac902..b9a40ab 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context.h +++ b/third_party/blink/renderer/core/execution_context/execution_context.h @@ -480,6 +480,7 @@ class CORE_EXPORT ExecutionContext : public Supplementable, bool CheckVideoPlaying() const; void SetTranslatedURL(const String&); void SetParentalRatingResult(const String& url, bool is_pass); + void SetPreferTextLang(const String&); #endif protected: diff --git a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h index 45b9b86..f427c5f 100644 --- a/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h +++ b/third_party/blink/renderer/core/execution_context/execution_context_lifecycle_state_observer.h @@ -77,6 +77,7 @@ class CORE_EXPORT ExecutionContextLifecycleStateObserver virtual String GetUrl() const { return ""; } virtual void SetParentalRatingResult(bool) {} virtual void SetTranslatedURL(const String&) {} + virtual void SetPreferTextLang(const String&) {} #endif void SetExecutionContext(ExecutionContext*) override; diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.cc b/third_party/blink/renderer/core/exported/web_settings_impl.cc index e9d6b3c..5082766 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.cc +++ b/third_party/blink/renderer/core/exported/web_settings_impl.cc @@ -838,6 +838,14 @@ void WebSettingsImpl::SetAllowFileAccessFromExternalURLs(bool allow) { bool WebSettingsImpl::AllowFileAccessFromExternalURLs() { return settings_->GetAllowFileAccessFromExternalURLs(); } + +void WebSettingsImpl::SetMediaSubtitleNotificationEnabled(bool enabled) { + settings_->SetMediaSubtitleNotificationEnabled(enabled); +} + +bool WebSettingsImpl::MediaSubtitleNotificationEnabled() { + return settings_->MediaSubtitleNotificationEnabled(); +} #endif #if defined(TIZEN_ATK_SUPPORT) diff --git a/third_party/blink/renderer/core/exported/web_settings_impl.h b/third_party/blink/renderer/core/exported/web_settings_impl.h index f64d55d..aacdcf1 100644 --- a/third_party/blink/renderer/core/exported/web_settings_impl.h +++ b/third_party/blink/renderer/core/exported/web_settings_impl.h @@ -245,6 +245,8 @@ class CORE_EXPORT WebSettingsImpl final : public WebSettings { bool AllowFileAccessFromExternalURLs() override; void SetMediaPlaybackNotificationEnabled(bool) override; bool MediaPlaybackNotificationEnabled() override; + void SetMediaSubtitleNotificationEnabled(bool) override; + bool MediaSubtitleNotificationEnabled() override; #endif #if defined(TIZEN_ATK_SUPPORT) diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index 57e90f8..a1e160c 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc @@ -4632,6 +4632,19 @@ bool WebViewImpl::IsVideoPlaying() const { } return false; } +void WebViewImpl::SetPreferTextLang(const WebString& lang) { + if (!MainFrameImpl()) { + LOG(ERROR) << "no main frame."; + return; + } + + for (const Frame* frame = MainFrameImpl()->GetFrame(); frame; + frame = frame->Tree().TraverseNext()) { + Document* document = To(frame)->GetDocument(); + DCHECK(document); + document->SetPreferTextLang(lang); + } +} #endif } // namespace blink diff --git a/third_party/blink/renderer/core/exported/web_view_impl.h b/third_party/blink/renderer/core/exported/web_view_impl.h index 1414e9f..af2b529 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.h +++ b/third_party/blink/renderer/core/exported/web_view_impl.h @@ -565,6 +565,7 @@ class CORE_EXPORT WebViewImpl final : public WebView, #if BUILDFLAG(IS_TIZEN_TV) bool IsVideoPlaying() const override; void SetParentalRatingResult(const WebString&, bool) override; + void SetPreferTextLang(const WebString&) override; #endif PageScaleConstraintsSet& GetPageScaleConstraintsSet() const; diff --git a/third_party/blink/renderer/core/frame/settings.h b/third_party/blink/renderer/core/frame/settings.h index f424df9..de16276 100644 --- a/third_party/blink/renderer/core/frame/settings.h +++ b/third_party/blink/renderer/core/frame/settings.h @@ -88,6 +88,13 @@ class CORE_EXPORT Settings { void SetDelegate(SettingsDelegate*); #if BUILDFLAG(IS_TIZEN_TV) + void SetMediaSubtitleNotificationEnabled(bool enabled) { + media_subtitle_notification_enabled_ = enabled; + } + bool MediaSubtitleNotificationEnabled() const { + return media_subtitle_notification_enabled_; + } + void SetMediaPlaybackNotificationEnabled(bool enabled) { media_playback_notification_enabled_ = enabled; } @@ -105,6 +112,7 @@ class CORE_EXPORT Settings { #if BUILDFLAG(IS_TIZEN_TV) bool media_playback_notification_enabled_ : 1 = false; + bool media_subtitle_notification_enabled_ : 1 = false; #endif #if BUILDFLAG(IS_EFL) diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 6f16d70..49630e7 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -1461,6 +1461,15 @@ bool WebFrameWidgetImpl::IsVideoPlaying() { } return webview->IsVideoPlaying(); } + +void WebFrameWidgetImpl::SetPreferSubtitleLang(const WTF::String lang_list) { + WebViewImpl* webview = View(); + if (!webview) { + LOG(ERROR) << "no webview."; + return; + } + webview->SetPreferTextLang(lang_list); +} #endif void WebFrameWidgetImpl::SetNeedsRecalculateRasterScales() { @@ -5164,6 +5173,16 @@ void WebFrameWidgetImpl::NotifyKeyEvent(WebInputEvent::Type type, } #endif +#if BUILDFLAG(IS_TIZEN_TV) +void WebFrameWidgetImpl::NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) { + LOG(INFO) << __func__ << " active_track_id:" << active_track_id + << " url:" << url << " lang:" << lang; + widget_base_->NotifyTrackInfoToBrowser(active_track_id, url, lang); +} +#endif + #if BUILDFLAG(IS_TIZEN) void WebFrameWidgetImpl::SetDrawsTransparentBackground( bool draws_transparent_background) { diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h index 3d779fd..2f28251 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.h +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.h @@ -709,6 +709,12 @@ class CORE_EXPORT WebFrameWidgetImpl // coordinate space. Vector CalculateVisibleLineBoundsOnScreen(); +#if BUILDFLAG(IS_TIZEN_TV) + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang); +#endif + protected: // WidgetBaseClient overrides: void WillBeginMainFrame() override; @@ -870,6 +876,7 @@ class CORE_EXPORT WebFrameWidgetImpl bool IsVideoPlaying() override; void SetTranslatedURL(const WTF::String& url) override; void SetParentalRatingResult(const WTF::String& url, bool is_pass) override; + void SetPreferSubtitleLang(const WTF::String lang_list) override; #endif // mojom::blink::FrameWidgetInputHandler overrides. diff --git a/third_party/blink/renderer/core/html/build.gni b/third_party/blink/renderer/core/html/build.gni index 260cf2d..f5c3c56 100644 --- a/third_party/blink/renderer/core/html/build.gni +++ b/third_party/blink/renderer/core/html/build.gni @@ -525,6 +525,8 @@ blink_core_sources_html = [ "track/cue_timeline.h", "track/html_track_element.cc", "track/html_track_element.h", + "track/inband_cue.cpp", + "track/inband_cue.h", "track/loadable_text_track.cc", "track/loadable_text_track.h", "track/text_track.cc", diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index abdb046..8ff57d2 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc @@ -35,6 +35,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/string_split.h" #include "base/synchronization/lock.h" #include "base/time/time.h" #include "cc/layers/layer.h" @@ -120,7 +121,9 @@ #include "ui/display/screen_info.h" #if BUILDFLAG(IS_TIZEN_TV) +#include #include "third_party/blink/public/platform/web_application_type.h" +#include "third_party/blink/renderer/core/frame/web_frame_widget_impl.h" #endif #ifndef LOG_MEDIA_EVENTS @@ -502,6 +505,7 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tag_name, #if BUILDFLAG(IS_TIZEN_TV) is_deactivate_(false), is_translated_url_(false), + text_track_menu_on_(false), #endif #if defined(TIZEN_MULTIMEDIA) live_playback_complete_(false), @@ -1734,11 +1738,27 @@ void HTMLMediaElement::TextTrackReadyStateChanged(TextTrack* track) { } void HTMLMediaElement::TextTrackModeChanged(TextTrack* track) { + LOG(INFO) << "textTrackModeChanged,mode:" << (int)track->mode().AsEnum() + << ",this:" << (void*)this; // Mark this track as "configured" so configureTextTracks won't change the // mode again. if (IsA(track)) track->SetHasBeenConfigured(true); +#if BUILDFLAG(IS_TIZEN_TV) + // if current track is showing, disable other texttrack + // Chromium support one active TextTrack shown on screen at the same time from + // 2018 Tizen TV Upstream can support more than one TextTrack shown up + if (track->mode() == TextTrackMode::kShowing) { + for (unsigned i = 0; i < text_tracks_->length(); ++i) { + TextTrack* textTrack = text_tracks_->AnonymousIndexedGetter(i); + if (textTrack && textTrack != track && + textTrack->mode() == TextTrackMode::kShowing) + textTrack->SetModeEnum(TextTrackMode::kDisabled); + } + } +#endif + if (track->IsRendered()) { GetDocument().GetStyleEngine().AddTextTrack(track); } else { @@ -2147,7 +2167,9 @@ void HTMLMediaElement::SetReadyState(ReadyState state) { // Once enough of the media data has been fetched to determine the duration of // the media resource, its dimensions, and other metadata... if (ready_state_ >= kHaveMetadata && old_state < kHaveMetadata) { +#if !BUILDFLAG(IS_TIZEN_TV) CreatePlaceholderTracksIfNecessary(); +#endif MediaFragmentURIParser fragment_parser(current_src_.GetSource()); fragment_end_time_ = fragment_parser.EndTime(); @@ -3218,6 +3240,18 @@ void HTMLMediaElement::AudioTrackChanged(AudioTrack* track) { audioTracks().ScheduleChangeEvent(); +#if BUILDFLAG(IS_TIZEN_TV) + // Active: + // only need to notify mmplayer about the active id + // Deactive: + // if track_count > 1 set the active id,others will be deactive + // if track_count = 1 player_set_mute / player_set_display_visible + if (track->enabled()) + DisableOtherAudioTracks(track); + if (!track->enabled() && 1 == audioTracks().length() && GetWebMediaPlayer()) + GetWebMediaPlayer()->SetActiveAudioTrack(-1); +#endif + if (media_source_attachment_) media_source_attachment_->OnTrackChanged(media_source_tracer_, track); @@ -3226,6 +3260,18 @@ void HTMLMediaElement::AudioTrackChanged(AudioTrack* track) { } void HTMLMediaElement::AudioTracksTimerFired(TimerBase*) { +#if BUILDFLAG(IS_TIZEN_TV) + for (unsigned i = 0; i < audioTracks().length(); ++i) { + AudioTrack* track = audioTracks().AnonymousIndexedGetter(i); + // player_select_track_ex parameter is "index",not "id" + //"index" is defined by mmplayer,start from 0 + //"id" is defined by file,mp4/dash/ts id definition is different + if (track->enabled() && GetWebMediaPlayer()) { + GetWebMediaPlayer()->SetActiveAudioTrack(i); + break; + } + } +#else Vector enabled_track_ids; for (unsigned i = 0; i < audioTracks().length(); ++i) { AudioTrack* track = audioTracks().AnonymousIndexedGetter(i); @@ -3234,6 +3280,7 @@ void HTMLMediaElement::AudioTracksTimerFired(TimerBase*) { } web_media_player_->EnabledAudioTracksChanged(enabled_track_ids); +#endif } WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack( @@ -3251,6 +3298,11 @@ WebMediaPlayer::TrackId HTMLMediaElement::AddAudioTrack( language, enabled); audioTracks().Add(audio_track); +#if BUILDFLAG(IS_TIZEN_TV) + if (enabled) + DisableOtherAudioTracks(audio_track); +#endif + return audio_track->id(); } @@ -3276,9 +3328,29 @@ void HTMLMediaElement::SelectedVideoTrackChanged(VideoTrack* track) { if (media_source_attachment_) media_source_attachment_->OnTrackChanged(media_source_tracer_, track); + if (!GetWebMediaPlayer()) { + LOG(ERROR) << "GetWebMediaPlayer fail"; + return; + } + +#if BUILDFLAG(IS_TIZEN_TV) + if (track->selected()) { + for (unsigned i = 0; i < videoTracks().length(); ++i) { + VideoTrack* cur_track = videoTracks().AnonymousIndexedGetter(i); + if (cur_track->selected()) { + GetWebMediaPlayer()->SetActiveVideoTrack(i); + break; + } + } + } else { + if (1 == videoTracks().length()) + GetWebMediaPlayer()->SetActiveVideoTrack(-1); + } +#else WebMediaPlayer::TrackId id = track->id(); web_media_player_->SelectedVideoTrackChanged(track->selected() ? &id : nullptr); +#endif } WebMediaPlayer::TrackId HTMLMediaElement::AddVideoTrack( @@ -3309,6 +3381,48 @@ void HTMLMediaElement::RemoveVideoTrack(WebMediaPlayer::TrackId track_id) { videoTracks().Remove(track_id); } +#if BUILDFLAG(IS_TIZEN_TV) +void HTMLMediaElement::AddTextTrack(const WebString& id, + const WebString& kind, + const WebString& label, + const WebString& language) { + // 4.8.12.11.2 Sourcing in-band text tracks + // 1. Associate the relevant data with a new text track and its corresponding + // new TextTrack object. + auto* text_track = TextTrack::CreateInband(kind, label, language, id, *this); + + // 2. Set the new text track's kind, label, and language based on the + // semantics of the relevant data, as defined by the relevant specification. + // If there is no label in that data, then the label must be set to the empty + // string. + // 3. Associate the text track list of cues with the rules for updating the + // text track rendering appropriate for the format in question. + // 4. If the new text track's kind is metadata, then set the text track + // in-band metadata track dispatch type as follows, based on the type of the + // media resource: + // 5. Populate the new text track's list of cues with the cues parsed so far, + // folllowing the guidelines for exposing cues, and begin updating it + // dynamically as necessary. + // - Thess are all done by the media engine. + + // 6. Set the new text track's readiness state to loaded. + text_track->SetReadinessState(TextTrack::kLoaded); + + // 7. Set the new text track's mode to the mode consistent with the user's + // preferences and the requirements of the relevant specification for the + // data. + // - This will happen in honorUserPreferencesForAutomaticTextTrackSelection() + ScheduleTextTrackResourceLoad(); + + // 8. Add the new text track to the media element's list of text tracks. + // 9. Fire an event with the name addtrack, that does not bubble and is not + // cancelable, and that uses the TrackEvent interface, with the track + // attribute initialized to the text track's TextTrack object, at the media + // element's textTracks attribute's TextTrackList object. + textTracks()->Append(text_track); +} +#endif + void HTMLMediaElement::ForgetResourceSpecificTracks() { audio_tracks_->RemoveAll(); video_tracks_->RemoveAll(); @@ -4089,6 +4203,40 @@ WebString HTMLMediaElement::GetContentMIMEType() { return WebString(content_mime_type_); } +void HTMLMediaElement::NotifyTrackInfoToBrowser(int active_track_id) { + LOG(INFO) << __func__ << "id " << active_track_id; + + LocalFrame* frame = GetDocument().GetFrame(); + if (!frame) { + LOG(ERROR) << "frame is null"; + return; + } + + if (!text_tracks_ || + text_tracks_->length() <= static_cast(active_track_id)) { + LOG(ERROR) << "text_tracks_ is null"; + return; + } + + TextTrack* text_track = text_tracks_->AnonymousIndexedGetter(active_track_id); + if (!text_track) { + LOG(ERROR) << "text_track is null"; + return; + } + + if (IsHTMLVideoElement()) { + WebFrameWidgetImpl* wfwgt = + static_cast(frame->GetWidgetForLocalRoot()); + wfwgt->NotifyTrackInfoToBrowser(active_track_id, + text_track->SrcUrl().GetString().Utf8(), + text_track->language().Utf8()); + LOG(INFO) << "HTMLMediaElement(" << (void*)this + << "),NotifyTrackInfoToBrowser:" + << text_track->SrcUrl().GetString().Utf8() + << text_track->language().Utf8(); + } +} + void HTMLMediaElement::RequestReload(const KURL& new_url) { DCHECK(GetWebMediaPlayer()); DCHECK(new_url.IsValid()); @@ -4120,6 +4268,236 @@ void HTMLMediaElement::SetParentalRatingResult(bool is_pass) { } GetWebMediaPlayer()->SetParentalRatingResult(is_pass); } + +// MMPLAYER only support one audio track active +void HTMLMediaElement::DisableOtherAudioTracks(AudioTrack* audio_track) { + for (unsigned i = 0; i < audioTracks().length(); ++i) { + AudioTrack* track = audioTracks().AnonymousIndexedGetter(i); + if (track && track != audio_track && track->enabled()) + track->setEnabled(false); + } +} + +TextTrack* HTMLMediaElement::FindTextTrack(int band_type, + const std::string& info) { + for (unsigned int i = 0; i < textTracks()->length(); i++) { + TextTrack* text_track = textTracks()->AnonymousIndexedGetter(i); + if (text_track && (band_type == text_track->GetTextTrackType()) && + (!info.compare( + text_track->inBandMetadataTrackDispatchType().Ascii().data()))) + return text_track; + } + return nullptr; +} + +void HTMLMediaElement::OnInbandTextTrack(const std::string& info, + int band_type, + int action) { + LOG(INFO) << "inband text info" << info << " band_type " << band_type + << " action " << action; + TextTrack* find_track = FindTextTrack(band_type, info); + if (action == ADD_INBAND_TEXT_TRACK) { + if (find_track) { + LOG(ERROR) << "inBandMetadataTrackDispatchType" << info.c_str() + << "alredy exsit"; + return; + } + TextTrack* text_track = TextTrack::Create( + TextTrack::MetadataKeyword(), g_empty_atom, g_empty_atom, *this); + if (!text_track) { + LOG(ERROR) << "create textTrack fail(" << (void*)this << ")"; + return; + } + text_track->setInBandMetadataTrackDispatchType( + AtomicString::FromUTF8(info.c_str())); + text_track->SetReadinessState(TextTrack::kLoaded); + textTracks()->Append(text_track); + text_track->SetModeEnum(TextTrackMode::kHidden); + text_track->SetTextTrackType(band_type); + LOG(INFO) << "add inband text successfully(" << (void*)this << ")"; + } else if (action == DEL_INBAND_TEXT_TRACK) { + if (!find_track) { + LOG(ERROR) << "inBandMetadataTrackDispatchType" << info.c_str() + << "not exsit"; + return; + } + textTracks()->Remove(find_track); + } +} + +void HTMLMediaElement::AddInbandCue(const std::string& info, + unsigned int id, + int band_type, + long long int start_time, + long long int end_time) { + // info: "scheme_id_uri value data" + // Before: Use space to split, but string may contain multiple spaces + // After : Use $ to split, $ is added for string on purpose + std::string::size_type delimiter = info.rfind('$'); + if (delimiter == std::string::npos) { + LOG(ERROR) << "can't find $ delimiter in info: " << info.c_str(); + return; + } + std::string type = info.substr(0, delimiter); + std::string json_data = info.substr(delimiter + 1); + std::string data = ""; + unsigned int index = std::numeric_limits::max(); + Json::Reader reader; + Json::Value value; + if (reader.parse(json_data, value)) { + data = value["data"].asString(); + index = atoi(value["index"].asString().c_str()); + } + LOG(INFO) << "type: " << type.c_str() << ",data: " << data.c_str() + << ", index: " << index; + + blink::TextTrack* text_track = FindTextTrack(band_type, type); + if (!text_track) { + LOG(ERROR) << "find textTrack fail"; + return; + } + + if (text_track->FindCue(index)) { + LOG(ERROR) << "cue already exsit,pass it"; + return; + } + + // Please refer to this spec: + // HbbTV_v202_specification.pdf chapter 9.3.2.2 + // 1. For any Dash event with a duration of 250ms or less, the terminal + // shall set the end time of the corresponding DataCue object to the + // startTime + 250ms + // 2. If event duration is OxFFFF,endTime shall be set to Number.MAX_VALUE + double start = start_time / 1000.0; + double end = end_time / 1000.0; + if (end_time - start_time <= 250) + end = (start_time + 250) / 1000.0; + if ((end_time - start_time) / 1000 == 0xFFFF) + end = std::numeric_limits::max(); + + AtomicString str_id(""); + if (id != std::numeric_limits::max()) + str_id = AtomicString::Number(id); + + text_track->AddCue(start, end, str_id, index, data); +} + +int HTMLMediaElement::FindMatchTrack(const String& lang) { + std::vector textLangList; + textLangList.clear(); + textLangList = base::SplitStringUsingSubstr(lang.Ascii().data(), ",", + base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + if (textLangList.empty()) { + LOG(ERROR) << "textLangList is empty"; + return -1; + } + for (unsigned i = 0; i < textTracks()->length(); i++) { + TextTrack* text_track = textTracks()->AnonymousIndexedGetter(i); + if (!text_track) + continue; + std::string lang = text_track->language().Ascii().data(); + for (unsigned k = 0; k < textLangList.size(); k++) { + if (textLangList[k].find(lang) != std::string::npos) + return i; + } + } + return -1; +} + +bool HTMLMediaElement::IsTs() { + return current_src_.GetSource().GetString().EndsWithIgnoringCase(".ts"); +} + +void HTMLMediaElement::SetPreferTextLang(const String& lang) { + // 1.Menu OFF + if (lang.empty()) { + LOG(INFO) << "HTMLMediaElement::SetPreferTextLang Menu set subtitle off"; + text_track_menu_on_ = false; + active_text_track_id_ = -1; + prefer_text_lang_ = "off"; + // app may not call setMode(),it should call setActiveTextTrack(-1,false) + // here + // if app call setMode(), check menu on/off in configureTextTrackDisplay + if (GetWebMediaPlayer() && !IsTs()) + GetWebMediaPlayer()->SetActiveTextTrack(active_text_track_id_, false); + } else { + text_track_menu_on_ = true; + // 2.Menu is ON, all tracks are disabled/hidden by App + if (textTracks()->IsAllDisabledByApp()) { + LOG(INFO) << "all tracks are disabled by App"; + active_text_track_id_ = -1; + prefer_text_lang_ = "off"; + if (GetWebMediaPlayer() && !IsTs()) + GetWebMediaPlayer()->SetActiveTextTrack(active_text_track_id_, false); + return; + } + prefer_text_lang_ = lang.Ascii().data(); + // 3.Menu ON, has showing track,then match prefer language + int idx = FindMatchTrack(lang); + // 4. If not foud matched track,the current TC is to display app enabled + // track. find m_activeTextTrackId when app set mode showing + if (idx == -1) { + active_text_track_id_ = -1; + LOG(INFO) << "can't find matched track"; + + // 4.1 if app also not set active texttrack, show default track + for (unsigned i = 0; i < textTracks()->length(); i++) { + TextTrack* textTrack = textTracks()->AnonymousIndexedGetter(i); + if (!textTrack) + continue; + if (textTrack->TrackType() == TextTrack::kTrackElement && + textTrack->IsDefault()) { + LOG(INFO) << "default track id:" << i; + active_text_track_id_ = i; + break; + } + } + + // 4.2 if no default track,show track0 + if (active_text_track_id_ == -1) { + LOG(INFO) << "no defaut track,show track 0"; + active_text_track_id_ = 0; + } + + TextTrack* finalTrack = + textTracks()->AnonymousIndexedGetter(active_text_track_id_); + if (finalTrack) { + // When TrackElement is inserted, the mode may change to showing, + // but WMP is not created, so active text track won't be set. + // And setMode will return if we set the same mode again, + // so for showing TrackElement, we need to set active text track + // here directly. + LOG(INFO) << "finalTrack mode " << (int)finalTrack->mode().AsEnum(); + if (finalTrack->mode() != TextTrackMode::kShowing) { + finalTrack->SetModeEnum(TextTrackMode::kShowing); + } else if (GetWebMediaPlayer() && !IsTs()) { + GetWebMediaPlayer()->SetActiveTextTrack( + active_text_track_id_, + finalTrack->TrackType() == TextTrack::kInBand); + } + } + } + // 5.foud, showing + else { + LOG(INFO) << "find matched track id:" << idx; + if (idx != active_text_track_id_) { + active_text_track_id_ = idx; + TextTrack* textTrack = textTracks()->AnonymousIndexedGetter(idx); + if (textTrack->mode() != TextTrackMode::kShowing) { + textTrack->SetModeEnum(TextTrackMode::kShowing); + } else if (GetWebMediaPlayer() && !IsTs()) { + GetWebMediaPlayer()->SetActiveTextTrack( + active_text_track_id_, + textTrack->TrackType() == TextTrack::kInBand); + } + } + } + } + + if (GetWebMediaPlayer() && IsTs()) + GetWebMediaPlayer()->SetPreferTextLanguage(prefer_text_lang_); +} #endif bool HTMLMediaElement::HasPendingActivity() const { @@ -4439,8 +4817,57 @@ void HTMLMediaElement::ConfigureTextTrackDisplay() { bool have_visible_text_track = text_tracks_->HasShowingTracks(); text_tracks_visible_ = have_visible_text_track; - if (!have_visible_text_track && !GetMediaControls()) - return; +#if BUILDFLAG(IS_TIZEN_TV) + if (IsHbbTV()) { + if (!have_visible_text_track) { + active_text_track_id_ = -1; + prefer_text_lang_ = "off"; + DVLOG(3) << "have no visible text track(" << *this << ")"; + if (GetWebMediaPlayer() && !IsTs()) + GetWebMediaPlayer()->SetActiveTextTrack(-1, false); + } + } else { +#endif + if (!have_visible_text_track && !GetMediaControls()) { + DVLOG(3) << "have no visible text track && media_controls_ is null (" + << *this << ")"; + return; + } +#if BUILDFLAG(IS_TIZEN_TV) + } +#endif + +#if BUILDFLAG(IS_TIZEN_TV) + if (!text_track_menu_on_) { + DVLOG(3) << "text track is off (" << *this << ")"; + prefer_text_lang_ = "off"; + if (GetWebMediaPlayer() && !IsTs()) + GetWebMediaPlayer()->SetActiveTextTrack(-1, false); + } else { + // there is a case,when prefer language match a track + // and then js set another active texttrack + for (unsigned i = 0; i < text_tracks_->length(); ++i) { + TextTrack* textTrack = text_tracks_->AnonymousIndexedGetter(i); + if (textTrack && textTrack->mode() == TextTrackMode::kShowing) { + active_text_track_id_ = i; + prefer_text_lang_ = textTrack->language().Ascii().data(); + break; + } + } + DVLOG(3) << "text_tracks_->length() " << text_tracks_->length() + << "active_text_track_id_:" << active_text_track_id_; + if (GetWebMediaPlayer() && !IsTs()) + GetWebMediaPlayer()->SetActiveTextTrack( + active_text_track_id_, + active_text_track_id_ > -1 + ? text_tracks_->AnonymousIndexedGetter(active_text_track_id_) + ->TrackType() == TextTrack::kInBand + : false); + } + + if (GetWebMediaPlayer() && IsTs()) + GetWebMediaPlayer()->SetPreferTextLanguage(prefer_text_lang_); +#endif // Note: The "time marches on" algorithm |CueTimeline::TimeMarchesOn| runs // the "rules for updating the text track rendering" (updateTextTrackDisplay) diff --git a/third_party/blink/renderer/core/html/media/html_media_element.h b/third_party/blink/renderer/core/html/media/html_media_element.h index d61c516..6a5a2b2 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.h +++ b/third_party/blink/renderer/core/html/media/html_media_element.h @@ -72,6 +72,12 @@ enum class MediaContentType; } // namespace media namespace blink { +#if BUILDFLAG(IS_TIZEN_TV) +enum TrackAction { + ADD_INBAND_TEXT_TRACK = 0, + DEL_INBAND_TEXT_TRACK, +}; +#endif class AudioSourceProviderClient; class AudioTrack; @@ -386,11 +392,22 @@ class CORE_EXPORT HTMLMediaElement #if BUILDFLAG(IS_TIZEN_TV) WebString GetContentMIMEType() override; + void NotifyTrackInfoToBrowser(int active_track_id) override; void RequestReload(const KURL& new_url); void SetTranslatedURL(const String&) override; bool IsHTMLMediaElement() const override { return true; } WTF::String GetUrl() const override { return current_src_.GetSource(); } void SetParentalRatingResult(bool is_pass) override; + TextTrack* FindTextTrack(int band_type, const std::string& info); + void OnInbandTextTrack(const std::string& info, + int band_type, + int action) override; + void AddInbandCue(const std::string& info, + unsigned int id, + int band_type, + long long int start_time, + long long int end_time) override; + void SetPreferTextLang(const String& lang) override; #endif #if defined(TIZEN_MULTIMEDIA) @@ -567,6 +584,12 @@ class CORE_EXPORT HTMLMediaElement const WebString&, bool) final; void RemoveVideoTrack(WebMediaPlayer::TrackId) final; +#if BUILDFLAG(IS_TIZEN_TV) + void AddTextTrack(const WebString& id, + const WebString& kind, + const WebString& label, + const WebString& language) final; +#endif void MediaSourceOpened(WebMediaSource*) final; void RemotePlaybackCompatibilityChanged(const WebURL&, bool is_compatible) final; @@ -633,6 +656,12 @@ class CORE_EXPORT HTMLMediaElement void NotifyPlayingUrl(); #endif +#if BUILDFLAG(IS_TIZEN_TV) + void DisableOtherAudioTracks(AudioTrack*); + int FindMatchTrack(const String& lang); + bool IsTs(); +#endif + void LoadTimerFired(TimerBase*); void ProgressEventTimerFired(); void PlaybackProgressTimerFired(); @@ -884,8 +913,11 @@ class CORE_EXPORT HTMLMediaElement #endif #if BUILDFLAG(IS_TIZEN_TV) + bool text_track_menu_on_ : 1; + int active_text_track_id_{-1}; String content_mime_type_; bool is_translated_url_ : 1; + std::string prefer_text_lang_{"und"}; // only for ts #endif // Set if the user has used the context menu to set the visibility of the // controls. diff --git a/third_party/blink/renderer/core/html/track/html_track_element.cc b/third_party/blink/renderer/core/html/track/html_track_element.cc index 0a647d3..25bbb42 100644 --- a/third_party/blink/renderer/core/html/track/html_track_element.cc +++ b/third_party/blink/renderer/core/html/track/html_track_element.cc @@ -37,6 +37,11 @@ #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/blink/public/platform/web_application_type.h" +#include "third_party/blink/renderer/core/frame/settings.h" +#endif + #define TRACK_LOG_LEVEL 3 namespace blink { @@ -155,6 +160,12 @@ void HTMLTrackElement::ScheduleLoad() { if (!MediaElement()) return; +#if BUILDFLAG(IS_TIZEN_TV) + if (TextTrack* text_track = track()) + text_track->SetSrcUrl(GetNonEmptyURLAttribute(html_names::kSrcAttr)); + MediaElement()->ConfigureTextTrackDisplay(); +#endif + // 4. Run the remainder of these steps in parallel, allowing whatever caused // these steps to run to continue. load_timer_.StartOneShot(base::TimeDelta(), FROM_HERE); @@ -168,6 +179,18 @@ void HTMLTrackElement::ScheduleLoad() { void HTMLTrackElement::LoadTimerFired(TimerBase*) { DVLOG(TRACK_LOG_LEVEL) << "loadTimerFired"; +#if BUILDFLAG(IS_TIZEN_TV) + TextTrack* text_track = track(); + // Webmedia only handle WEBVTT subtitle + if (IsHbbTV() && text_track->IsTTML()) { + DVLOG(TRACK_LOG_LEVEL) + << "Webmedia ignore TTML subtile,It will be handled by HBBTV"; + load_timer_.Stop(); + SetReadyState(ReadyState::kLoaded); + return; + } +#endif + // 7. [X] Let URL be the track URL of the track element. KURL url = GetNonEmptyURLAttribute(html_names::kSrcAttr); @@ -239,8 +262,18 @@ bool HTMLTrackElement::CanLoadUrl(const KURL& url) { if (!parent || !GetExecutionContext()) return false; - if (url.IsEmpty()) + if (url.IsEmpty()) { + LOG(INFO) << __func__ << ", url is empty"; return false; + } + +#if BUILDFLAG(IS_TIZEN_TV) + TextTrack* text_track = track(); + if (text_track->IsTTML()) { + LOG(INFO) << __func__ << ", text track is ttml"; + return false; + } +#endif if (!GetExecutionContext()->GetContentSecurityPolicy()->AllowMediaFromSource( url)) { diff --git a/third_party/blink/renderer/core/html/track/text_track.cc b/third_party/blink/renderer/core/html/track/text_track.cc index 2601457..74bb1e0 100644 --- a/third_party/blink/renderer/core/html/track/text_track.cc +++ b/third_party/blink/renderer/core/html/track/text_track.cc @@ -39,6 +39,10 @@ #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "ui/accessibility/accessibility_features.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/blink/renderer/core/html/track/inband_cue.h" +#endif + namespace blink { static const int kInvalidTrackIndex = -1; @@ -76,13 +80,19 @@ TextTrack::TextTrack(const AtomicString& kind, TextTrackType type) : TrackBase(WebMediaPlayer::kTextTrack, kind, label, language, id), active_cues_(nullptr), +#if BUILDFLAG(IS_TIZEN_TV) + src_url_(KURL()), + is_ttml_(false), + is_disabled_by_app_(false), +#endif track_list_(nullptr), source_element_(source_element), track_type_(type), readiness_state_(kNotLoaded), track_index_(kInvalidTrackIndex), rendered_track_index_(kInvalidTrackIndex), - has_been_configured_(false) {} + has_been_configured_(false) { +} TextTrack::~TextTrack() = default; @@ -123,6 +133,14 @@ void TextTrack::setMode(const V8TextTrackMode& mode) { if (mode_ == mode.AsEnum()) return; +#if BUILDFLAG(IS_TIZEN_TV) + // default mode = disabled, is_disabled_by_app_ means user set disabled/hidden + if (mode == TextTrackMode::kDisabled || mode == TextTrackMode::kHidden) + is_disabled_by_app_ = true; + else + is_disabled_by_app_ = false; +#endif + if (cues_ && GetCueTimeline()) { // If mode changes to disabled, remove this track's cues from the client // because they will no longer be accessible from the cues() function. @@ -272,6 +290,9 @@ void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exception_state) { DCHECK(!cue->IsActive() || GetCueTimeline()); cue->SetTrack(nullptr); +#if BUILDFLAG(IS_TIZEN_TV) + indexs_.erase(cue->index().ToInt()); +#endif if (GetCueTimeline()) GetCueTimeline()->RemoveCue(this, cue); @@ -375,6 +396,42 @@ CueTimeline* TextTrack::GetCueTimeline() const { return MediaElement() ? &MediaElement()->GetCueTimeline() : nullptr; } +#if BUILDFLAG(IS_TIZEN_TV) +void TextTrack::SetSrcUrl(const KURL& url) { + src_url_ = url; + String last_path = url.LastPathComponent(); + size_t pos = last_path.ReverseFind('.'); + if (pos != kNotFound) { + String extension = last_path.Substring(pos + 1); + String mime_type = MIMETypeRegistry::GetMIMETypeForExtension(extension); + if (mime_type == "text/xml" || mime_type == "application/ttml+xml") + is_ttml_ = true; + } +} + +bool TextTrack::FindCue(unsigned int index) { + if (indexs_.find(index) == indexs_.end()) + return false; + else + return true; +} + +void TextTrack::AddCue(double start_time, + double end_time, + AtomicString& id, + unsigned int index, + const std::string& data) { + TextTrackCue* cue = InbandCue::Create(start_time, end_time, data); + if (cue) { + cue->setId(id); + cue->setIndex(AtomicString::Number(index)); + // index&id can make sure which cue is. because some TCs id will be null. + indexs_.insert(std::pair(index, id)); + addCue(cue); + } +} +#endif + Node* TextTrack::Owner() const { return MediaElement(); } diff --git a/third_party/blink/renderer/core/html/track/text_track.h b/third_party/blink/renderer/core/html/track/text_track.h index 8106c6a..f25ee9b 100644 --- a/third_party/blink/renderer/core/html/track/text_track.h +++ b/third_party/blink/renderer/core/html/track/text_track.h @@ -36,6 +36,10 @@ #include "third_party/blink/renderer/platform/wtf/casting.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "third_party/blink/renderer/platform/weborigin/kurl.h" +#endif + namespace blink { class CueTimeline; @@ -54,6 +58,25 @@ class CORE_EXPORT TextTrack : public EventTarget, public TrackBase { DEFINE_WRAPPERTYPEINFO(); public: + static TextTrack* Create(const AtomicString& kind, + const AtomicString& label, + const AtomicString& language, + HTMLElement& source_element) { + return MakeGarbageCollected( + kind, label, language, source_element, g_empty_atom, kAddTrack); + } + +#if BUILDFLAG(IS_TIZEN_TV) + static TextTrack* CreateInband(const AtomicString& kind, + const AtomicString& label, + const AtomicString& language, + const AtomicString& id, + HTMLElement& source_element) { + return MakeGarbageCollected(kind, label, language, + source_element, id, kInBand); + } +#endif + enum TextTrackType { kTrackElement, kAddTrack, kInBand }; TextTrack(const AtomicString& kind, @@ -94,6 +117,8 @@ class CORE_EXPORT TextTrack : public EventTarget, public TrackBase { }; ReadinessState GetReadinessState() const { return readiness_state_; } void SetReadinessState(ReadinessState state) { readiness_state_ = state; } + void SetTextTrackType(int band_type) { band_type_ = band_type; } + int GetTextTrackType() { return band_type_; } TextTrackCueList* cues(); TextTrackCueList* activeCues(); @@ -138,6 +163,19 @@ class CORE_EXPORT TextTrack : public EventTarget, public TrackBase { void SetCSSStyleSheets(HeapVector>); +#if BUILDFLAG(IS_TIZEN_TV) + virtual void SetSrcUrl(const KURL&); + const KURL& SrcUrl() const { return src_url_; } + virtual bool IsTTML() { return is_ttml_; } + bool FindCue(unsigned int index); + void AddCue(double start_time, + double end_time, + AtomicString& id, + unsigned int index, + const std::string& data); + bool IsDisabledByApp() { return is_disabled_by_app_; } +#endif + protected: void AddListOfCues(HeapVector>&); @@ -149,11 +187,19 @@ class CORE_EXPORT TextTrack : public EventTarget, public TrackBase { Member active_cues_; HeapVector> style_sheets_; +#if BUILDFLAG(IS_TIZEN_TV) + KURL src_url_; + bool is_ttml_; + bool is_disabled_by_app_; + std::unordered_map indexs_; +#endif + Member track_list_; Member source_element_; TextTrackMode mode_ = TextTrackMode::kDisabled; TextTrackType track_type_; ReadinessState readiness_state_; + int band_type_{0}; int track_index_; int rendered_track_index_; bool has_been_configured_; diff --git a/third_party/blink/renderer/core/html/track/text_track.idl b/third_party/blink/renderer/core/html/track/text_track.idl index a4268f5..cef5559 100644 --- a/third_party/blink/renderer/core/html/track/text_track.idl +++ b/third_party/blink/renderer/core/html/track/text_track.idl @@ -35,7 +35,7 @@ interface TextTrack : EventTarget { readonly attribute DOMString language; readonly attribute DOMString id; - // readonly attribute DOMString inBandMetadataTrackDispatchType; + readonly attribute DOMString inBandMetadataTrackDispatchType; attribute TextTrackMode mode; diff --git a/third_party/blink/renderer/core/html/track/text_track_cue.cc b/third_party/blink/renderer/core/html/track/text_track_cue.cc index 154ab34..6b4c360 100644 --- a/third_party/blink/renderer/core/html/track/text_track_cue.cc +++ b/third_party/blink/renderer/core/html/track/text_track_cue.cc @@ -80,6 +80,17 @@ void TextTrackCue::setId(const AtomicString& id) { CueDidChange(); } +#if BUILDFLAG(IS_TIZEN_TV) +void TextTrackCue::setIndex(const AtomicString& index) { + if (index_ == index) + return; + + CueWillChange(); + index_ = index; + CueDidChange(); +} +#endif + void TextTrackCue::setStartTime(double value) { if (start_time_ == value) return; diff --git a/third_party/blink/renderer/core/html/track/text_track_cue.h b/third_party/blink/renderer/core/html/track/text_track_cue.h index 555ead2..fe65fba 100644 --- a/third_party/blink/renderer/core/html/track/text_track_cue.h +++ b/third_party/blink/renderer/core/html/track/text_track_cue.h @@ -67,6 +67,11 @@ class CORE_EXPORT TextTrackCue : public EventTarget { double endTime() const { return end_time_; } void setEndTime(double); +#if BUILDFLAG(IS_TIZEN_TV) + const AtomicString& index() const { return index_; } + void setIndex(const AtomicString&); +#endif + bool pauseOnExit() const { return pause_on_exit_; } void setPauseOnExit(bool); @@ -125,6 +130,9 @@ class CORE_EXPORT TextTrackCue : public EventTarget { DispatchEventResult DispatchEventInternal(Event&) override; private: +#if BUILDFLAG(IS_TIZEN_TV) + AtomicString index_; +#endif AtomicString id_; double start_time_; double end_time_; diff --git a/third_party/blink/renderer/core/html/track/text_track_list.cc b/third_party/blink/renderer/core/html/track/text_track_list.cc index cb899fc..ca85dc5 100644 --- a/third_party/blink/renderer/core/html/track/text_track_list.cc +++ b/third_party/blink/renderer/core/html/track/text_track_list.cc @@ -266,4 +266,20 @@ void TextTrackList::Trace(Visitor* visitor) const { EventTarget::Trace(visitor); } +#if BUILDFLAG(IS_TIZEN_TV) +bool TextTrackList::IsAllDisabledByApp() { + unsigned long disableCount = 0; + if (length() <= 0) + return false; + + for (unsigned i = 0; i < length(); i++) { + if (AnonymousIndexedGetter(i)->IsDisabledByApp()) + disableCount++; + } + if (disableCount >= length()) + return true; + return false; +} +#endif + } // namespace blink diff --git a/third_party/blink/renderer/core/html/track/text_track_list.h b/third_party/blink/renderer/core/html/track/text_track_list.h index 1386ea2..cdc2506 100644 --- a/third_party/blink/renderer/core/html/track/text_track_list.h +++ b/third_party/blink/renderer/core/html/track/text_track_list.h @@ -72,6 +72,10 @@ class CORE_EXPORT TextTrackList final : public EventTarget { void Trace(Visitor*) const override; +#if BUILDFLAG(IS_TIZEN_TV) + bool IsAllDisabledByApp(); +#endif + private: void ScheduleTrackEvent(const AtomicString& event_name, TextTrack*); diff --git a/third_party/blink/renderer/core/html/track/track_base.h b/third_party/blink/renderer/core/html/track/track_base.h index e099be8..13d2e1f 100644 --- a/third_party/blink/renderer/core/html/track/track_base.h +++ b/third_party/blink/renderer/core/html/track/track_base.h @@ -48,6 +48,20 @@ class CORE_EXPORT TrackBase : public Supplementable { AtomicString label() const { return label_; } AtomicString language() const { return language_; } + AtomicString inBandMetadataTrackDispatchType() const { +#if BUILDFLAG(IS_TIZEN_TV) + return inband_metadata_track_dispatch_type_; +#else + return g_empty_atom; +#endif + } + + void setInBandMetadataTrackDispatchType(const AtomicString& type) { +#if BUILDFLAG(IS_TIZEN_TV) + inband_metadata_track_dispatch_type_ = type; +#endif + } + void SetMediaElement(HTMLMediaElement* media_element) { media_element_ = media_element; } @@ -67,6 +81,7 @@ class CORE_EXPORT TrackBase : public Supplementable { AtomicString label_; AtomicString language_; String id_; + AtomicString inband_metadata_track_dispatch_type_; Member media_element_; }; diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc index e568676..b632c01 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc @@ -111,6 +111,37 @@ const base::TimeDelta kLayerBoundUpdateInterval = base::Milliseconds(50); } // namespace #endif +#if BUILDFLAG(IS_TIZEN_TV) +#include "tizen_src/chromium_impl/tizen/tizen_tv_platform.h" +#include "tizen_src/ewk/efl_integration/common/application_type.h" + +typedef struct { + const std::string kind_str_; + blink::WebMediaPlayerClient::AudioTrackKind kind_enum_; +} AudioKind; + +static AudioKind audioKinds[] = { + {"alternative", blink::WebMediaPlayerClient::kAudioTrackKindAlternative}, + {"descriptions", blink::WebMediaPlayerClient::kAudioTrackKindDescriptions}, + {"main", blink::WebMediaPlayerClient::kAudioTrackKindMain}, + {"main-desc", blink::WebMediaPlayerClient::kAudioTrackKindMainDescriptions}, + {"translation", blink::WebMediaPlayerClient::kAudioTrackKindTranslation}, + {"commentary", blink::WebMediaPlayerClient::kAudioTrackKindCommentary}}; + +typedef struct { + const std::string kind_str_; + blink::WebMediaPlayerClient::VideoTrackKind kind_enum_; +} VideoKind; + +static VideoKind videoKinds[] = { + {"alternative", blink::WebMediaPlayerClient::kVideoTrackKindAlternative}, + {"captions", blink::WebMediaPlayerClient::kVideoTrackKindCaptions}, + {"main", blink::WebMediaPlayerClient::kVideoTrackKindMain}, + {"sign", blink::WebMediaPlayerClient::kVideoTrackKindSign}, + {"subtitles", blink::WebMediaPlayerClient::kVideoTrackKindSubtitles}, + {"commentary", blink::WebMediaPlayerClient::kVideoTrackKindCommentary}}; +#endif + namespace blink { namespace { @@ -2214,6 +2245,24 @@ void WebMediaPlayerImpl::OnProgress() { } } +#if BUILDFLAG(IS_TIZEN_TV) +void WebMediaPlayerImpl::SetActiveTextTrack(int id, bool is_in_band) { + pipeline_controller_->SetActiveTextTrack(id, is_in_band); +} + +void WebMediaPlayerImpl::SetActiveAudioTrack(int index) { + pipeline_controller_->SetActiveAudioTrack(index); +} + +void WebMediaPlayerImpl::SetActiveVideoTrack(int index) { + pipeline_controller_->SetActiveVideoTrack(index); +} + +void WebMediaPlayerImpl::SetPreferTextLanguage(const std::string& lang) { + pipeline_controller_->SetPreferTextLanguage(lang); +} +#endif + bool WebMediaPlayerImpl::CanPlayThrough() { if (!base::FeatureList::IsEnabled(media::kSpecCompliantCanPlayThrough)) return true; @@ -2343,9 +2392,110 @@ void WebMediaPlayerImpl::OnBufferingStateChangeInternal( } #if BUILDFLAG(IS_TIZEN_TV) +void WebMediaPlayerImpl::NotifyTrackInfoToBrowser(int active_track_id) { + LOG(INFO) << __func__ << "active_track_id " << active_track_id; + if (!client_) { + LOG(ERROR) << __func__ << " client is null "; + return; + } + client_->NotifyTrackInfoToBrowser(active_track_id); +} + void WebMediaPlayerImpl::SetParentalRatingResult(bool is_pass) { pipeline_controller_->SetParentalRatingResult(is_pass); } + +void WebMediaPlayerImpl::AddTrackInfo(media::MediaTrackInfo trackinfo) { + LOG(INFO) << "WebMediaPlayerEfl::AddTrackInfo trackinfo->cmd " + << (int)trackinfo.cmd; + media::TrackInfo* pTrack; + if (trackinfo.cmd == media::TRACKCMD::SETTEXT) { + pTrack = (media::TrackInfo*)trackinfo.info; + LOG(INFO) << "AddTrackInfo SETTEXT-pTrack:" << pTrack; + LOG(INFO) << "AddTrackInfo SETTEXT kind " << pTrack->kind << " label " + << pTrack->label << " language " << pTrack->language << " id " + << pTrack->id; + + client_->AddTextTrack(blink::WebString::FromUTF8(pTrack->id), + blink::WebString::FromUTF8(pTrack->kind), + blink::WebString::FromUTF8(pTrack->label), + blink::WebString::FromUTF8(pTrack->language)); + delete (pTrack); + } else if (trackinfo.cmd == media::TRACKCMD::SETAUDIO) { + pTrack = (media::TrackInfo*)trackinfo.info; + LOG(INFO) << "AddTrackInfo SETAUDIO - id: " << pTrack->id + << ", kind: " << pTrack->kind.c_str() + << ", label: " << pTrack->label.c_str() + << ", lang: " << pTrack->language.c_str(); + + blink::WebMediaPlayerClient::AudioTrackKind audio_track_kind = + blink::WebMediaPlayerClient::kAudioTrackKindNone; + + for (const auto& i : audioKinds) { + if (pTrack->kind.compare(i.kind_str_) == 0) { + audio_track_kind = i.kind_enum_; + break; + } + } + + client_->AddAudioTrack( + blink::WebString::FromUTF8(pTrack->id), audio_track_kind, + blink::WebString::FromUTF8(pTrack->label), + blink::WebString::FromUTF8(pTrack->language), pTrack->enabled); + delete (pTrack); + } else if (trackinfo.cmd == media::TRACKCMD::SETVIDEO) { + pTrack = (media::TrackInfo*)trackinfo.info; + LOG(INFO) << "SETVIDEO - id: " << pTrack->id + << ", kind: " << pTrack->kind.c_str() + << ", label: " << pTrack->label.c_str() + << ", lang: " << pTrack->language.c_str(); + + blink::WebMediaPlayerClient::VideoTrackKind video_track_kind = + blink::WebMediaPlayerClient::kVideoTrackKindNone; + + for (const auto& i : videoKinds) { + if (pTrack->kind.compare(i.kind_str_) == 0) { + video_track_kind = i.kind_enum_; + break; + } + } + + LOG(INFO) << "video track kind type is: " << video_track_kind; + client_->AddVideoTrack( + blink::WebString::FromUTF8(pTrack->id), video_track_kind, + blink::WebString::FromUTF8(pTrack->label), + blink::WebString::FromUTF8(pTrack->language), pTrack->enabled); + delete (pTrack); + } else if (trackinfo.cmd == media::TRACKCMD::SETINBAND) { + media::InbandTextInfo* pInBand = (media::InbandTextInfo*)trackinfo.info; + + LOG(INFO) << "AddTrackInfo SETINBAND-pInBand:" << pInBand; + LOG(INFO) << "AddTrackInfo SETINBAND-info:" << pInBand->info + << ", band_type: " << pInBand->band_type + << ", action: " << pInBand->action; + + if (client_) + client_->OnInbandTextTrack(pInBand->info, pInBand->band_type, + pInBand->action); + delete (pInBand); + } else if (trackinfo.cmd == media::TRACKCMD::SETCUE) { + media::InbandCueInfo* pInbandCue = (media::InbandCueInfo*)trackinfo.info; + + LOG(INFO) << "AddTrackInfo SETCUE-pInbandCue:" << pInbandCue; + LOG(INFO) << "AddTrackInfo SETCUE-info:" << pInbandCue->info + << ", id: " << pInbandCue->id + << ", band_type: " << pInbandCue->band_type + << ", stime: " << pInbandCue->stime + << ", etime: " << pInbandCue->etime; + + if (client_) + client_->AddInbandCue(pInbandCue->info, pInbandCue->id, + pInbandCue->band_type, pInbandCue->stime, + pInbandCue->etime); + + delete (pInbandCue); + } +} #endif void WebMediaPlayerImpl::OnDurationChange() { diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h index 3340d55..e4b2115 100644 --- a/third_party/blink/renderer/platform/media/web_media_player_impl.h +++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h @@ -409,7 +409,13 @@ class PLATFORM_EXPORT WebMediaPlayerImpl media::BufferingStateChangeReason reason) override; void OnDurationChange() override; #if BUILDFLAG(IS_TIZEN_TV) + void NotifyTrackInfoToBrowser(int active_track_id) override; void SetParentalRatingResult(bool is_pass) override; + void AddTrackInfo(media::MediaTrackInfo trackinfo) override; + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveAudioTrack(int index) override; + void SetActiveVideoTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; #endif void OnWaiting(media::WaitingReason reason) override; void OnAudioConfigChange(const media::AudioDecoderConfig& config) override; diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index c529cc3..31e383b 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5 @@ -357,7 +357,7 @@ }, { name: "AudioVideoTracks", - status: "experimental", + status: "stable", base_feature: "none", }, { diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index 209997e..02db385 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc @@ -582,6 +582,10 @@ void WidgetBase::SetParentalRatingResult(const WTF::String& url, bool is_pass) { void WidgetBase::IsVideoPlaying(IsVideoPlayingCallback callback) { std::move(callback).Run(client_->IsVideoPlaying()); } + +void WidgetBase::SetPreferSubtitleLang(const WTF::String& lang_list) { + client_->SetPreferSubtitleLang(lang_list); +} #endif // IS_TIZEN_TV void WidgetBase::WasHidden() { @@ -1154,6 +1158,17 @@ void WidgetBase::SetCursor(const ui::Cursor& cursor) { void WidgetBase::DidEdgeScrollBy(const gfx::Point& offset, bool handled) { widget_host_->DidEdgeScrollBy(offset, handled); } + +void WidgetBase::NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang) { + if (!widget_host_) { + LOG(ERROR) << "widget host is null "; + return; + } + widget_host_->NotifyTrackInfoToBrowser( + active_track_id, WTF::String::FromUTF8(url), WTF::String::FromUTF8(lang)); +} #endif void WidgetBase::UpdateTooltipUnderCursor(const String& tooltip_text, diff --git a/third_party/blink/renderer/platform/widget/widget_base.h b/third_party/blink/renderer/platform/widget/widget_base.h index 0fd2e85..9f3e2b1 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.h +++ b/third_party/blink/renderer/platform/widget/widget_base.h @@ -173,6 +173,7 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget, void SetTranslatedURL(const WTF::String& url) override; void IsVideoPlaying(IsVideoPlayingCallback callback) override; void SetParentalRatingResult(const WTF::String& url, bool is_pass) override; + void SetPreferSubtitleLang(const WTF::String& lang_list) override; #endif void WasHidden() override; @@ -263,6 +264,9 @@ class PLATFORM_EXPORT WidgetBase : public mojom::blink::Widget, #if BUILDFLAG(IS_TIZEN_TV) //Browser edge scroll void DidEdgeScrollBy(const gfx::Point& offset, bool handled); + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang); #endif void UpdateTooltipUnderCursor(const String& tooltip_text, TextDirection dir); diff --git a/third_party/blink/renderer/platform/widget/widget_base_client.h b/third_party/blink/renderer/platform/widget/widget_base_client.h index 1486406..623a994 100644 --- a/third_party/blink/renderer/platform/widget/widget_base_client.h +++ b/third_party/blink/renderer/platform/widget/widget_base_client.h @@ -208,6 +208,7 @@ class WidgetBaseClient { virtual bool IsVideoPlaying() {} virtual void SetTranslatedURL(const WTF::String& url) {} virtual void SetParentalRatingResult(const WTF::String& url, bool is_pass) {} + virtual void SetPreferSubtitleLang(const WTF::String lang_list) {} #endif // Convert screen coordinates to device emulated coordinates (scaled diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc index 46c28dc..835c40b 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.cc @@ -371,6 +371,49 @@ void TizenRendererImpl::Suspend() { } #if BUILDFLAG(IS_TIZEN_TV) +void TizenRendererImpl::SetActiveTextTrack(int id, bool is_in_band) { + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " " << id << "/ " << is_in_band; + + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->SetActiveTextTrack(id, is_in_band); +} + +void TizenRendererImpl::SetActiveAudioTrack(int index) { + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " index:" << index; + + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->SetActiveAudioTrack(index); +} + +void TizenRendererImpl::SetActiveVideoTrack(int index) { + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " index:" << index; + + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->SetActiveVideoTrack(index); +} + +void TizenRendererImpl::SetPreferTextLanguage(const std::string& lang) { + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " " << lang; + + if (!media_player_) { + LOG_ID(ERROR, player_id_) << "media_player_ is not created yet"; + return; + } + media_player_->SetPreferTextLanguage(lang); +} content::WebContentsDelegate* TizenRendererImpl::GetWebContentsDelegate() const { content::WebContents* web_contents = GetWebContents(); @@ -484,6 +527,30 @@ void TizenRendererImpl::OnStatisticsUpdate( NOTIMPLEMENTED(); } #if BUILDFLAG(IS_TIZEN_TV) +void TizenRendererImpl::NotifyTrackInfoToBrowser(int active_track_id) { + LOG_ID(INFO, player_id_) + << "TizenRendererImpl::NotifyTrackInfoToBrowser active_track_id " + << active_track_id; + client_extension_->NotifyTrackInfoToBrowser(active_track_id); +} + +void TizenRendererImpl::AddTrackInfo( + media::mojom::MediaTrackInfoPtr trackinfo) { + client_extension_->AddTrackInfo(std::move(trackinfo)); +} + +void TizenRendererImpl::UpdateCurrentTime(base::TimeDelta current_time) { + content::WebContentsDelegate* web_contents_delegate = + GetWebContentsDelegate(); + + if (!web_contents_delegate) { + LOG_ID(ERROR, player_id_) << "GetWebContentsDelegate is nullprt"; + return; + } + + web_contents_delegate->UpdateCurrentTime(current_time.InSecondsF()); +} + void TizenRendererImpl::SetContentMimeType(const std::string& mime_type) { mime_type_ = mime_type; if (media_player_) @@ -510,6 +577,19 @@ bool TizenRendererImpl::PlaybackNotificationEnabled() { return enable; } +bool TizenRendererImpl::SubtitleNotificationEnabled() { + content::WebContents* web_contents = GetWebContents(); + if (!web_contents) { + LOG_ID(ERROR, player_id_) << "web_contents is nullptr"; + return false; + } + blink::web_pref::WebPreferences web_preference = + web_contents->GetOrCreateWebPreferences(); + bool enable = web_preference.media_subtitle_notification_enabled; + LOG_ID(INFO, player_id_) << "media_subtitle_notification_enabled:" << enable; + return enable; +} + void TizenRendererImpl::NotifyPlaybackState(int state, int player_id, const std::string& url, diff --git a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h index 5e50009..bf9f6ad 100644 --- a/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h +++ b/tizen_src/chromium_impl/content/browser/media/tizen_renderer_impl.h @@ -23,6 +23,7 @@ #include "mojo/public/cpp/bindings/receiver.h" #include "mojo/public/cpp/bindings/remote.h" #include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/platform/web_media_player.h" #include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h" #include "ui/gfx/geometry/size.h" @@ -116,7 +117,10 @@ class CONTENT_EXPORT TizenRendererImpl void OnBufferUpdate(base::TimeDelta time) override; #if BUILDFLAG(IS_TIZEN_TV) + void NotifyTrackInfoToBrowser(int active_track_id) override; + void AddTrackInfo(media::mojom::MediaTrackInfoPtr trackinfo) override; bool PlaybackNotificationEnabled(); + bool SubtitleNotificationEnabled() override; void NotifyPlaybackState(int state, int player_id = 0, const std::string& url = "", @@ -124,6 +128,7 @@ class CONTENT_EXPORT TizenRendererImpl bool* media_resource_acquired = NULL, std::string* translated_url = NULL, std::string* drm_info = NULL) override; + void UpdateCurrentTime(base::TimeDelta current_time) override; void OnLivePlaybackComplete() override; #endif @@ -178,6 +183,12 @@ class CONTENT_EXPORT TizenRendererImpl void SetPlayerMediaGeometry(); void OnWebViewMoved(); #endif +#if BUILDFLAG(IS_TIZEN_TV) + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveAudioTrack(int index) override; + void SetActiveVideoTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; +#endif content::WebContents* GetWebContents() const; media::RendererClient* client_ = nullptr; diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc index ca2b174..caac65a 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.cc @@ -484,11 +484,32 @@ void RWHVAuraCommonHelperEfl::SetPopupMenuBounds( NOTIMPLEMENTED(); } +void RWHVAuraCommonHelperEfl::NotifyTrackInfoToBrowser( + int active_track_id, + const std::string& url, + const std::string& lang) { + LOG(INFO) << __FUNCTION__ << " url " << url << " lang:" << lang; + if (!web_contents_ || !web_contents_->GetDelegate()) { + LOG(ERROR) << "content or delegate is null"; + return; + } + + web_contents_->GetDelegate()->NotifySubtitlePlay(active_track_id, url, lang); +} + void RWHVAuraCommonHelperEfl::SetTranslatedURL(const std::string& url) { if (rwhv_aura_) rwhv_aura_->host()->SetTranslatedURL(url); } +void RWHVAuraCommonHelperEfl::SetPreferSubtitleLang(std::string lang_list) { + if (!rwhv_aura_) { + LOG(ERROR) << "rwhv_aura_ is null"; + return; + } + rwhv_aura_->host()->SetPreferSubtitleLang(lang_list); +} + void RWHVAuraCommonHelperEfl::SetIMERecommendedWords( const std::string& recommended_words) { auto im_context = GetIMContextEfl(); diff --git a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h index a216b09..f2a5da0 100644 --- a/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h +++ b/tizen_src/chromium_impl/content/browser/renderer_host/rwhv_aura_common_helper_efl.h @@ -140,6 +140,11 @@ class CONTENT_EXPORT RWHVAuraCommonHelperEfl { void SetPopupMenuVisible(const bool visible); void SetPopupMenuBounds(const gfx::Rect& popup_bounds); void SetCursorByClient(bool enable) { cursor_set_by_client_ = enable; } + // notify track info to browser process + void NotifyTrackInfoToBrowser(int active_track_id, + const std::string& url, + const std::string& lang); + void SetPreferSubtitleLang(std::string lang_list); void SetIMERecommendedWords(const std::string& recommended_words); void SetIMERecommendedWordsType(bool should_enable); void SetMouseEventsEnabled(bool enabled); diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc index 988f07a..caf7284 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.cc @@ -80,6 +80,75 @@ void MediaPlayerRendererClient::SetMediaGeometry(const gfx::RectF& rect) { } #endif +#if BUILDFLAG(IS_TIZEN_TV) +void MediaPlayerRendererClient::NotifyTrackInfoToBrowser(int active_track_id) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + client_->NotifyTrackInfoToBrowser(active_track_id); +} + +void MediaPlayerRendererClient::AddTrackInfo( + media::mojom::MediaTrackInfoPtr trackinfo) { + DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); + media::MediaTrackInfo sMediatrackInfo; + + LOG(INFO) << "trackinfo->cmd " << (int)trackinfo->cmd; + sMediatrackInfo.cmd = (media::TRACKCMD)trackinfo->cmd; + + if ((trackinfo->cmd == media::mojom::TRACKCMD::SETTEXT || + trackinfo->cmd == media::mojom::TRACKCMD::SETAUDIO || + trackinfo->cmd == media::mojom::TRACKCMD::SETVIDEO) && + trackinfo->ck->is_track()) { + LOG(INFO) << "AddTrackInfo SETTEXT kind:" + << trackinfo->ck->get_track()->kind << " label " + << trackinfo->ck->get_track()->label << " language " + << trackinfo->ck->get_track()->language << " id " + << trackinfo->ck->get_track()->id << " enabled " + << trackinfo->ck->get_track()->enabled; + + media::TrackInfo* ptinfo = new (media::TrackInfo); + ptinfo->id = trackinfo->ck->get_track()->id; + ptinfo->kind = trackinfo->ck->get_track()->kind; + ptinfo->label = trackinfo->ck->get_track()->label; + ptinfo->language = trackinfo->ck->get_track()->language; + ptinfo->enabled = trackinfo->ck->get_track()->enabled; + LOG(INFO) << "AddTrackInfo SETTEXT-ptinfo:" << ptinfo; + sMediatrackInfo.info = std::move((void*)ptinfo); + + } else if (trackinfo->cmd == media::mojom::TRACKCMD::SETINBAND && + trackinfo->ck->is_inband()) { + LOG(INFO) << "SETINBAND - info: " << trackinfo->ck->get_inband()->info + << ", band_type: " << trackinfo->ck->get_inband()->band_type + << ", action: " << trackinfo->ck->get_inband()->action; + + media::InbandTextInfo* pinband = new (media::InbandTextInfo); + pinband->info = trackinfo->ck->get_inband()->info; + pinband->band_type = trackinfo->ck->get_inband()->band_type; + pinband->action = trackinfo->ck->get_inband()->action; + LOG(INFO) << "AddTrackInfo SETCUE-pinband:" << pinband; + sMediatrackInfo.info = std::move((void*)pinband); + } else if (trackinfo->cmd == media::mojom::TRACKCMD::SETCUE && + trackinfo->ck->is_cue()) { + LOG(INFO) << "AddTrackInfo SETCUE - info: " + << trackinfo->ck->get_cue()->info + << ", id: " << trackinfo->ck->get_cue()->id + << ", band_type: " << trackinfo->ck->get_cue()->band_type + << ", stime: " << trackinfo->ck->get_cue()->stime + << ", etime: " << trackinfo->ck->get_cue()->etime; + + media::InbandCueInfo* pinbandcue = new (media::InbandCueInfo); + pinbandcue->info = trackinfo->ck->get_cue()->info; + pinbandcue->id = trackinfo->ck->get_cue()->id; + pinbandcue->band_type = trackinfo->ck->get_cue()->band_type; + pinbandcue->stime = trackinfo->ck->get_cue()->stime; + pinbandcue->etime = trackinfo->ck->get_cue()->etime; + LOG(INFO) << "AddTrackInfo SETCUE-inbandcue:" << pinbandcue; + sMediatrackInfo.info = std::move((void*)pinbandcue); + } + LOG(INFO) << "AddTrackInfo SETCUE-info:" << sMediatrackInfo.info; + client_->AddTrackInfo(std::move(sMediatrackInfo)); +} +#endif + void MediaPlayerRendererClient::OnRemoteRendererInitialized( media::PipelineStatus status) { DCHECK(media_task_runner_->RunsTasksInCurrentSequence()); diff --git a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h index 85fc655..5109bf4 100644 --- a/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h +++ b/tizen_src/chromium_impl/content/renderer/media/tizen/media_player_renderer_client.h @@ -72,6 +72,10 @@ class CONTENT_EXPORT MediaPlayerRendererClient // media::mojom::MediaPlayerRendererClientExtension implementation void OnDurationChange(base::TimeDelta duration) override; +#if BUILDFLAG(IS_TIZEN_TV) + void NotifyTrackInfoToBrowser(int active_track_id) override; + void AddTrackInfo(media::mojom::MediaTrackInfoPtr trackinfo) override; +#endif void OnVideoSizeChange(const gfx::Size& size) override; void OnBufferUpdate(base::TimeDelta time) override; void OnNewFrameAvailable(uint32_t playerId, diff --git a/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.cc b/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.cc index 60f291f..9724b9d 100644 --- a/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.cc +++ b/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.cc @@ -11,8 +11,233 @@ #include #include +#include namespace media { +// key: alpha3 value: alpha2 +std::map language_code_ = { + // ISO639-2/B ISO639-1 + {"aar", "aa"}, + {"abk", "ab"}, + {"afr", "af"}, + {"aka", "ak"}, + {"alb", "sq"}, + {"amh", "am"}, + {"ara", "ar"}, + {"arg", "an"}, + {"arm", "hy"}, + {"asm", "as"}, + {"ava", "av"}, + {"ave", "ae"}, + {"aym", "ay"}, + {"aze", "az"}, + {"bak", "ba"}, + {"bam", "bm"}, + {"bel", "be"}, + {"ben", "bn"}, + {"baq", "eu"}, + {"bih", "bh"}, + {"bis", "bi"}, + {"bos", "bs"}, + {"bre", "br"}, + {"bul", "bg"}, + {"bur", "my"}, + {"cat", "ca"}, + {"cze", "cs"}, + {"cha", "ch"}, + {"che", "ce"}, + {"chi", "zh"}, + {"chu", "cu"}, + {"chv", "cv"}, + {"cym", "cy"}, + {"cor", "kw"}, + {"cos", "co"}, + {"cre", "cr"}, + {"dan", "da"}, + {"div", "dv"}, + {"dut", "nl"}, + {"dzo", "dz"}, + {"eng", "en"}, + {"epo", "eo"}, + {"est", "et"}, + {"ewe", "ee"}, + {"fao", "fo"}, + {"fij", "fj"}, + {"fin", "fi"}, + {"fre", "fr"}, + {"fry", "fy"}, + {"ful", "ff"}, + {"gre", "el"}, + {"ger", "de"}, + {"geo", "ka"}, + {"gla", "gd"}, + {"gle", "ga"}, + {"glg", "gl"}, + {"glv", "gv"}, + {"grn", "gn"}, + {"guj", "gu"}, + {"hat", "ht"}, + {"hau", "ha"}, + {"heb", "he"}, + {"her", "hz"}, + {"hin", "hi"}, + {"hmo", "ho"}, + {"hrv", "hr"}, + {"hun", "hu"}, + {"ibo", "ig"}, + {"ice", "is"}, + {"ido", "io"}, + {"iii", "ii"}, + {"iku", "iu"}, + {"ile", "ie"}, + {"ina", "ia"}, + {"ind", "id"}, + {"ipk", "ik"}, + {"ita", "it"}, + {"jav", "jv"}, + {"jpn", "ja"}, + {"kal", "kl"}, + {"kan", "kn"}, + {"kas", "ks"}, + {"kau", "kr"}, + {"kaz", "kk"}, + {"khm", "km"}, + {"kik", "ki"}, + {"kin", "rw"}, + {"kir", "ky"}, + {"kom", "kv"}, + {"kon", "kg"}, + {"kor", "ko"}, + {"kua", "kj"}, + {"kur", "ku"}, + {"lao", "lo"}, + {"lat", "la"}, + {"lav", "lv"}, + {"lim", "li"}, + {"lin", "ln"}, + {"lit", "lt"}, + {"ltz", "lb"}, + {"lub", "lu"}, + {"lug", "lg"}, + {"mac", "mk"}, + {"mah", "mh"}, + {"mal", "ml"}, + {"mao", "mi"}, + {"mar", "mr"}, + {"may", "ms"}, + {"mlg", "mg"}, + {"mlt", "mt"}, + {"mon", "mn"}, + {"nau", "na"}, + {"nav", "nv"}, + {"nbl", "nr"}, + {"nde", "nd"}, + {"ndo", "ng"}, + {"nep", "ne"}, + {"nno", "nn"}, + {"nob", "nb"}, + {"nor", "no"}, + {"nya", "ny"}, + {"oci", "oc"}, + {"oji", "oj"}, + {"ori", "or"}, + {"orm", "om"}, + {"oss", "os"}, + {"pan", "pa"}, + {"pli", "pi"}, + {"pol", "pl"}, + {"por", "pt"}, + {"pus", "ps"}, + {"per", "fa"}, + {"que", "qu"}, + {"roh", "rm"}, + {"rum", "ro"}, + {"run", "rn"}, + {"rus", "ru"}, + {"sag", "sg"}, + {"san", "sa"}, + {"sin", "si"}, + {"slo", "sk"}, + {"slv", "sl"}, + {"sme", "se"}, + {"smo", "sm"}, + {"sna", "sn"}, + {"snd", "sd"}, + {"som", "so"}, + {"sot", "st"}, + {"spa", "es"}, + {"srd", "sc"}, + {"srp", "sr"}, + {"ssw", "ss"}, + {"sun", "su"}, + {"swa", "sw"}, + {"swe", "sv"}, + {"tah", "ty"}, + {"tam", "ta"}, + {"tat", "tt"}, + {"tel", "te"}, + {"tgk", "tg"}, + {"tgl", "tl"}, + {"tha", "th"}, + {"tib", "bo"}, + {"tir", "ti"}, + {"ton", "to"}, + {"tsn", "tn"}, + {"tso", "ts"}, + {"tuk", "tk"}, + {"tur", "tr"}, + {"twi", "tw"}, + {"uig", "ug"}, + {"ukr", "uk"}, + {"urd", "ur"}, + {"uzb", "uz"}, + {"ven", "ve"}, + {"vie", "vi"}, + {"vol", "vo"}, + {"wel", "cy"}, + {"wln", "wa"}, + {"wol", "wo"}, + {"xho", "xh"}, + {"yid", "yi"}, + {"yor", "yo"}, + {"zha", "za"}, + {"zul", "zu"}, + // ISO639-2/T ISO639-1 + {"sqi", "sq"}, + {"hye", "hy"}, + {"eus", "eu"}, + {"mya", "my"}, + {"zho", "zh"}, + {"ces", "cs"}, + {"nld", "nl"}, + {"fra", "fr"}, + {"kat", "ka"}, + {"deu", "de"}, + {"deu", "de"}, + {"ell", "el"}, + {"isl", "is"}, + {"mkd", "mk"}, + {"msa", "ms"}, + {"mri", "mi"}, + {"fas", "fa"}, + {"ron", "ro"}, + {"slk", "sk"}, + {"bod", "bo"}, + {"cym", "cy"}, +}; + +const std::string GetAlpha2(const std::string& alpha3) { + if (alpha3 == "") + return ""; + auto iter = language_code_.find(alpha3); + if (iter == language_code_.end()) { + LOG(ERROR) << "can't find alpha2 for lang:" << alpha3.c_str(); + return ""; + } + std::string alpha2 = iter->second; + LOG(INFO) << "alpha3:" << alpha3.c_str() << ",alpha2:" << alpha2.c_str(); + return alpha2; +} std::string GetErrorString(int player_error) { switch (player_error) { diff --git a/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.h b/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.h index 00cd6dd..50da37f 100644 --- a/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.h +++ b/tizen_src/chromium_impl/media/base/efl/media_player_util_efl.h @@ -45,6 +45,7 @@ enum MediaError { MEDIA_ERROR_NETWORK, // Network error. }; +const std::string GetAlpha2(const std::string& alpha3); std::string GetErrorString(int capi_player_error); MediaError GetMediaError(int capi_player_error); diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h index 5d5025c..c5a748b 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi.h @@ -88,7 +88,7 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { void SetMediaPlayerClient(MediaPlayerTizenClient* client) override { client_ = client; } - void SetParentalRatingResult(bool is_pass) override{}; + void SetParentalRatingResult(bool is_pass) override {} #if defined(TIZEN_VIDEO_HOLE) void SetVideoHole(bool is_video_hole) override; @@ -105,7 +105,6 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { void OnHandleBufferingStatus(int percent); void OnHandlePlayerError(int player_error_code, const base::Location& loc); void OnResourceConflict(); - void OnResumeComplete(bool success); void OnMediaPacketUpdated(media_packet_h packet); void OnDurationChange(int player_id, double duration); @@ -143,9 +142,17 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { bool SetPlayerPrepareAsync(); virtual void PlayerPrepared(); virtual void PlaybackCompleteUpdate(); - virtual bool PreloadIfNeeded(int& ret) { return false; }; + virtual bool PreloadIfNeeded(int& ret) { return false; } virtual void UpdateMediaType(); virtual void UpdateDuration(); + virtual void OnCurrentTimeUpdateTimerFired(); + virtual void SeekCompleteUpdate(); + virtual void OnResumeComplete(bool success); + virtual void HandleBufferingStatus(int percent); + + void SeekInternal(base::TimeDelta time); + void StartBufferingUpdateTimer(); + void StopCurrentTimeUpdateTimer(); GURL url_; bool is_live_stream_{false}; @@ -159,46 +166,38 @@ class MEDIA_EXPORT MediaPlayerBridgeCapi : public MediaPlayerTizen { int width_{0}; int height_{0}; + base::TimeDelta playback_time_{base::TimeDelta()}; base::TimeDelta duration_{base::TimeDelta()}; + base::OnceClosure seek_cb_; + bool is_file_url_{false}; + bool is_paused_{true}; + bool is_seeking_{false}; bool is_preparing_{false}; bool is_play_pending_{false}; bool suspended_{false}; private: // |duration_update_timer_| related - void OnCurrentTimeUpdateTimerFired(); void StartCurrentTimeUpdateTimer(); - void StopCurrentTimeUpdateTimer(); // |buffering_update_timer_| related void OnBufferingUpdateTimerFired(); - void StartBufferingUpdateTimer(); void StopBufferingUpdateTimer(); void OnTimeChanged(); void UpdateSeekState(bool state); - void SeekCompleteUpdate(); - void HandleBufferingStatus(int percent); - - void SeekInternal(base::TimeDelta time); - MediaPlayerTizenClient* client_ = nullptr; bool is_end_reached_{false}; - bool is_file_url_{false}; - bool is_paused_{false}; - bool is_seeking_{false}; bool is_set_playback_rate_delayed_{false}; double playback_rate_{1.0}; double volume_{0.0}; - base::OnceClosure seek_cb_; base::RepeatingTimer current_time_update_timer_; base::RepeatingTimer buffering_update_timer_; std::string user_agent_; - base::TimeDelta playback_time_{base::TimeDelta()}; base::TimeDelta seek_duration_{base::TimeDelta()}; #if defined(TIZEN_VIDEO_HOLE) diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc index 8e7420a..44e3845 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.cc @@ -6,14 +6,35 @@ #include "base/strings/string_split.h" #include "media/base/efl/media_player_util_efl.h" +#include "third_party/blink/public/common/web_preferences/web_preferences.h" +#include "third_party/blink/public/platform/web_media_player.h" #include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h" #include +#include namespace { const int kSeekableTimeUpdateInterval = 500; } +static void OnSubtitleDataCallback(unsigned long long time_stamp, + unsigned index, + void* buffer, + void* user_data) { + DCHECK(user_data); + media::MediaPlayerBridgeCapiTV* player = + static_cast(user_data); + if (buffer) { + const std::string info{static_cast(buffer)}; + LOG(INFO) << " onSubtitleDataCallback : index=" << index + << ",time stamp=" << time_stamp << ",bufferSize=" << info.size(); + + constexpr size_t null_terminator_size = 1; + player->SubtitleDataCB(time_stamp, index, info, + info.size() + null_terminator_size); + } +} + static void PlayerPreLoadingCb(void* data) { if (!data) { LOG(ERROR) << "input data is null"; @@ -32,6 +53,36 @@ static void DrmErrorCb(int err_code, char* err_str, void* data) { player->OnDrmError(err_code, err_str); } +static void OtherEventCb(int event_type, void* event_data, void* data) { + DCHECK(data); + media::MediaPlayerBridgeCapiTV* player = + static_cast(data); + player->OnOtherEvent(event_type, event_data); +} + +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) +static void FirstTimeStampCb(unsigned long long timestamp, + int time_base_num, + int time_base_den, + void* user_data) { + DCHECK(user_data); + media::MediaPlayerBridgeCapiTV* player = + static_cast(user_data); + player->OnFirstTimeStamp(timestamp, time_base_num, time_base_den); +} + +static void TSSubtitleDataCb(int pid, + unsigned char* data, + unsigned int len, + void* user_data) { + DCHECK(user_data); + media::MediaPlayerBridgeCapiTV* player = + static_cast(user_data); + if (data) { + player->OnTSSubtitleData(pid, data, len); + } +} +#endif namespace media { MediaPlayerBridgeCapiTV::MediaPlayerBridgeCapiTV(const GURL& url, @@ -79,14 +130,19 @@ void MediaPlayerBridgeCapiTV::Prepare() { if (GetMediaPlayerClient() && GetMediaPlayerClient()->PlaybackNotificationEnabled() && blink::IsHbbTV()) { +#if !defined(TIZEN_MULTIMEDIA_DRMMANAGER_SUPPORT) if (!SetDrmInfo(drm_info)) { LOG_ID(ERROR, GetPlayerId()) << "SetDrmInfo failed"; return; } +#endif if (!translated_url.empty()) url_ = media::GetCleanURL(translated_url); } + if (blink::IsHbbTV()) { + GetUserPreferAudioLanguage(); + } if (url_.spec().find(".mpd") != std::string::npos) stream_type_ = DASH_STREAM; else if (url_.spec().find(".m3u") != std::string::npos) @@ -99,6 +155,24 @@ void MediaPlayerBridgeCapiTV::Prepare() { stream_type_ = DASH_STREAM; } + if (blink::IsHbbTV() && !is_preloaded_) { + int ret = player_set_others_event_cb(player_, OtherEventCb, this); + if (ret != PLAYER_ERROR_NONE) + LOG(ERROR) << "player_set_others_event_cb() failed"; +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + if (stream_type_ == TS_STREAM) { + if (prefer_subtitle_lang_ == "") { + prefer_subtitle_lang_ = "und"; + player_set_ini_param(player_, "set_subtitle_language = und"); + } + if (prefer_subtitle_lang_ != "off") { + //-999 means invalid pes id, MM will decide use which pes id + player_set_pes_cb(player_, -999, TSSubtitleDataCb, this); + player_set_first_timestamp_callback(player_, FirstTimeStampCb, this); + } + } +#endif + } if (blink::IsHbbTV() && CheckHighBitRate() && stream_type_ == DASH_STREAM) AppendUrlHighBitRate(url_.spec()); player_prepared_ = false; @@ -116,6 +190,16 @@ void MediaPlayerBridgeCapiTV::Release() { MediaPlayerBridgeCapi::Release(); if (GetMediaPlayerClient()) GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackStop, player_id_); + NotifySubtitleState(blink::WebMediaPlayer::kSubtitleStop); + pending_active_text_track_id_ = active_text_track_id_; + pending_active_audio_track_id_ = active_audio_track_id_; + pending_active_video_track_id_ = active_video_track_id_; + active_audio_track_id_ = -1; + active_video_track_id_ = -1; + active_text_track_id_ = -1; +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + player_unset_pes_cb(player_, -999); +#endif } bool MediaPlayerBridgeCapiTV::Play() { @@ -141,8 +225,40 @@ bool MediaPlayerBridgeCapiTV::Play() { if (!MediaPlayerBridgeCapi::Play()) return false; + if (blink::IsHbbTV()) { + UpdatePreferAudio(); + } + + LOG_ID(INFO, player_id_) << "pending_active_text_track_id_:" + << pending_active_text_track_id_ + << " active_text_track_id_ " << active_text_track_id_ + << " pending_active_audio_track_id_ " + << pending_active_audio_track_id_ + << " active_audio_track_id_ " + << active_audio_track_id_ + << " pending_active_video_track_id_ " + << pending_active_video_track_id_ + << " active_video_track_id_ " + << active_video_track_id_; + + if (pending_active_text_track_id_ != -1 && active_text_track_id_ == -1) { + active_text_track_id_ = pending_active_text_track_id_; + pending_active_text_track_id_ = -1; + } + + if (pending_active_audio_track_id_ != -1 && active_audio_track_id_ == -1) { + SetActiveAudioTrack(pending_active_audio_track_id_); + pending_active_audio_track_id_ = -1; + } + + if (pending_active_video_track_id_ != -1 && active_video_track_id_ == -1) { + SetActiveVideoTrack(pending_active_video_track_id_); + pending_active_video_track_id_ = -1; + } + if (GetMediaPlayerClient()) GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackStart, player_id_); + NotifySubtitleState(blink::WebMediaPlayer::kSubtitlePlay); return true; } @@ -155,17 +271,241 @@ void MediaPlayerBridgeCapiTV::Pause(bool is_media_related_action) { return; } MediaPlayerBridgeCapi::Pause(is_media_related_action); + NotifySubtitleState(blink::WebMediaPlayer::kSubtitlePause); } void MediaPlayerBridgeCapiTV::PlaybackCompleteUpdate() { MediaPlayerBridgeCapi::PlaybackCompleteUpdate(); if (GetMediaPlayerClient()) { GetMediaPlayerClient()->NotifyPlaybackState(kPlaybackFinish, player_id_); + GetMediaPlayerClient()->UpdateCurrentTime( + MediaPlayerBridgeCapi::GetCurrentTime()); if (is_live_stream_) GetMediaPlayerClient()->OnLivePlaybackComplete(); } + + NotifySubtitleState(blink::WebMediaPlayer::kSubtitleStop); } // namespace media +void MediaPlayerBridgeCapiTV::Seek(base::TimeDelta time, + base::OnceClosure seek_cb) { + LOG_ID(INFO, player_id_) << "(" << static_cast(this) << ") " + << __func__ << " time: " << time.InSecondsF(); + + seek_cb_ = std::move(seek_cb); + if (IsPlayerSuspended() && playback_time_ != time) { + playback_time_ = time; + delayed_player_state_ = PLAYER_STATE_DELAYED_SEEK; + pending_seek_duration_ = playback_time_; + OnTimeUpdate(player_id_, playback_time_); + OnTimeChanged(player_id_); + Resume(); + return; + } + + MediaPlayerBridgeCapi::SeekInternal(time); + NotifySubtitleState(blink::WebMediaPlayer::kSubtitleSeekStart, + time.InSecondsF()); +} + +void MediaPlayerBridgeCapiTV::SubtitleDataCB(long long time_stamp, + unsigned index, + const std::string& buffer, + unsigned buffer_size) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerBridgeCapiTV::NotifySubtitleData, + weak_factory_.GetWeakPtr(), index, time_stamp, + buffer, buffer_size)); +} + +void MediaPlayerBridgeCapiTV::NotifySubtitlePlay(int id, + const std::string& url, + const std::string& lang) { + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "MediaPlayerClient is null"; + return; + } + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + if (!web_contents_delegate) + return; + + web_contents_delegate->NotifySubtitlePlay(id, url, lang); +} + +void MediaPlayerBridgeCapiTV::NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned int size) { + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + + if (!web_contents_delegate) { + LOG(ERROR) << "web_contents_delegate is null"; + return; + } + + web_contents_delegate->NotifySubtitleData(track_id, time_stamp, data, size); +} + +void MediaPlayerBridgeCapiTV::NotifySubtitleState(int new_state, + double time_stamp) { + if (!blink::IsHbbTV() || !GetMediaPlayerClient() || + !GetMediaPlayerClient()->SubtitleNotificationEnabled() || + subtitle_state_ == new_state) { + LOG(ERROR) + << " MediaPlayerBridgeCapiTV::NotifySubtitleState null condition "; + return; + } + + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + if (!web_contents_delegate) { + LOG(ERROR) << "web_contents_delegate is null"; + return; + } + + // Workaround. Use subtitle state machine only when player has + // activated a text_track. Right now, subtitle state machine + // is shared between players, so any Player A notification + // influences Player B notification, which causes issues. + // This workaround won't work when two players have activated a text_track. + if (active_text_track_id_ == -1) { + LOG(ERROR) << "active_text_track_id_==-1"; + return; + } + + int old_state = subtitle_state_; + if (new_state != blink::WebMediaPlayer::kSubtitleSeekStart && + new_state != blink::WebMediaPlayer::kSubtitleSeekComplete) + subtitle_state_ = new_state; + + LOG(INFO) << "subtitle state transision:" + << "new_state=" << new_state << ", old_state=" << old_state + << ", subtitle_state=" << subtitle_state_ + << ", time_stamp=" << time_stamp; + + switch (new_state) { + case blink::WebMediaPlayer::kSubtitlePlay: + if (old_state == blink::WebMediaPlayer::kSubtitlePause) + web_contents_delegate->NotifySubtitleState( + blink::WebMediaPlayer::kSubtitleResume); + else + NotifyPlayTrack(); + break; + case blink::WebMediaPlayer::kSubtitlePause: + if (old_state != blink::WebMediaPlayer::kSubtitleStop) + web_contents_delegate->NotifySubtitleState(new_state); + break; + case blink::WebMediaPlayer::kSubtitleStop: + NotifyStopTrack(); + break; + case blink::WebMediaPlayer::kSubtitleSeekStart: + web_contents_delegate->NotifySubtitleState(new_state, time_stamp); + break; + case blink::WebMediaPlayer::kSubtitleSeekComplete: + web_contents_delegate->NotifySubtitleState(new_state); + break; + default: + NOTREACHED(); + return; + } +} + +void MediaPlayerBridgeCapiTV::NotifyPlayTrack() { + if (active_text_track_id_ == -1 || + subtitle_state_ == blink::WebMediaPlayer::kSubtitleStop) + return; + if (is_inband_text_track_) { + // process select player's track ... + UpdateActiveTextTrack(active_text_track_id_); + NotifySubtitlePlay(active_text_track_id_, blink::WebString().Utf8(), + blink::WebString().Utf8()); + } else { + // get outband track info and then NotifyPlayTrack + LOG_ID(INFO, player_id_) << __func__; + + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->NotifyTrackInfoToBrowser(active_text_track_id_); + } +} + +void MediaPlayerBridgeCapiTV::NotifyStopTrack() { + active_text_track_id_ = -1; + if (is_inband_text_track_) + UpdateActiveTextTrack(active_text_track_id_); + + is_inband_text_track_ = false; + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "MediaPlayerClient is null"; + return; + } + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + if (!web_contents_delegate) { + LOG(ERROR) << "web contents delegate is null"; + return; + } + + web_contents_delegate->NotifySubtitleState( + blink::WebMediaPlayer::kSubtitleStop); +} + +void MediaPlayerBridgeCapiTV::UpdateActiveTextTrack(int id) { + int ret = PLAYER_ERROR_NONE; + + // unselected... + if (id == -1) { + LOG_ID(INFO, player_id_) << "UpdateActiveTextTrack id=-1"; + return; + } + + int count = 0; + int err = player_get_track_count(player_, PLAYER_STREAM_TYPE_TEXT, &count); + if (err != PLAYER_ERROR_NONE || count <= 0 || id >= count) { + LOG(ERROR) << "player_get_track_count err,ret=" << ret + << ",count=" << count; + return; + } + + ret = player_select_track_ex(player_, PLAYER_STREAM_TYPE_TEXT, id, + -1); //-1 means use the default mode for + // mmplayer demuxer to select stream + if (ret != PLAYER_ERROR_NONE) { + LOG(ERROR) << "player_select_track_ex err,ret=" << ret; + return; + } +} + +void MediaPlayerBridgeCapiTV::OnCurrentTimeUpdateTimerFired() { + MediaPlayerBridgeCapi::OnCurrentTimeUpdateTimerFired(); + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "media player client is null"; + return; + } + GetMediaPlayerClient()->UpdateCurrentTime( + MediaPlayerBridgeCapi::GetCurrentTime()); +} + +void MediaPlayerBridgeCapiTV::SeekCompleteUpdate() { + MediaPlayerBridgeCapi::SeekCompleteUpdate(); + NotifySubtitleState(blink::WebMediaPlayer::kSubtitleSeekComplete); +} + +void MediaPlayerBridgeCapiTV::OnResumeComplete(bool success) { + LOG(INFO) << __func__ << ", success: " << success; + MediaPlayerBridgeCapi::OnResumeComplete(success); + + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "media player client is null"; + return; + } + + if (success) + GetMediaPlayerClient()->UpdateCurrentTime( + MediaPlayerBridgeCapi::GetCurrentTime()); +} + void MediaPlayerBridgeCapiTV::PlayerPrepared() { player_prepared_ = true; MediaPlayerBridgeCapi::PlayerPrepared(); @@ -180,6 +520,9 @@ void MediaPlayerBridgeCapiTV::PlayerPrepared() { UpdateSeekableTime(); StartSeekableTimeUpdateTimer(); } + + if (blink::IsHbbTV()) + UpdatePreferAudio(); } void MediaPlayerBridgeCapiTV::StartSeekableTimeUpdateTimer() { @@ -360,6 +703,45 @@ bool MediaPlayerBridgeCapiTV::GetDashLiveDuration(int64_t* duration) { return true; } +void MediaPlayerBridgeCapiTV::HandleBufferingStatus(int percent) { + if (is_paused_ || is_seeking_) + return; + + if (percent == 100) { + LOG(INFO) << "(" << static_cast(this) << ") " << __func__; + is_buffering_compeleted_ = true; + if (MediaPlayerBridgeCapi::GetPlayerState() != PLAYER_STATE_PAUSED) + return; + if (player_start(player_) != PLAYER_ERROR_NONE) { + LOG(ERROR) << "|player_start| failed"; + return; + } + + if (is_buffering_compeleted_ && blink::IsHbbTV()) + UpdatePreferAudio(); + + if (!is_file_url_) + MediaPlayerBridgeCapi::StartBufferingUpdateTimer(); + + MediaPlayerBridgeCapi::OnReadyStateChange( + player_id_, blink::WebMediaPlayer::kReadyStateHaveEnoughData); + } else { + is_buffering_compeleted_ = false; + if (GetPlayerState() != PLAYER_STATE_PLAYING) + return; + if (player_pause(player_) != PLAYER_ERROR_NONE) { + LOG(ERROR) << "|player_pause| failed"; + return; + } + + MediaPlayerBridgeCapi::StopCurrentTimeUpdateTimer(); + MediaPlayerBridgeCapi::OnReadyStateChange( + player_id_, blink::WebMediaPlayer::kReadyStateHaveCurrentData); + } + MediaPlayerBridgeCapi::OnNetworkStateChange( + player_id_, blink::WebMediaPlayer::kNetworkStateLoading); +} + void MediaPlayerBridgeCapiTV::AppendUrlHighBitRate(const std::string& url) { // don't use url.append("|STARTBITRATE=HIGHEST") to get hbbtv url // "|" will be replaced with "%7C" @@ -437,6 +819,89 @@ void MediaPlayerBridgeCapiTV::SetDisplayAtPausedState() { << "player_display_video_at_paused_state() failed"; } +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) +void MediaPlayerBridgeCapiTV::HandleFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) { + LOG_ID(INFO, player_id_) << "HandleFirstTimeStamp,timestamp:" << timestamp + << ",time_base_num:" << time_base_num + << ",time_base_den:" << time_base_den; + NotifyFirstTimeStamp(timestamp, time_base_num, time_base_den); +} + +void MediaPlayerBridgeCapiTV::HandleTSSubtitleData(int pid, + const std::string& buf, + unsigned int len) { + NotifyPESData(buf, len, GetCurrentTime().InMilliseconds()); +} + +void MediaPlayerBridgeCapiTV::OnFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) { + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerBridgeCapiTV::HandleFirstTimeStamp, + weak_factory_.GetWeakPtr(), timestamp, + time_base_num, time_base_den)); +} + +void MediaPlayerBridgeCapiTV::OnTSSubtitleData(int pid, + unsigned char* data, + unsigned int len) { + // maybe prefer subtitle lang changed + if (prefer_subtitle_lang_ == "off") + return; + + if (!data || !len) { + LOG(ERROR) << "invalid data"; + return; + } + + std::string buf((char*)data); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerBridgeCapiTV::HandleTSSubtitleData, + weak_factory_.GetWeakPtr(), pid, buf, len)); +} + +void MediaPlayerBridgeCapiTV::NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) { + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "MediaPlayerClient is null"; + return; + } + if (!blink::IsHbbTV() || + !GetMediaPlayerClient()->SubtitleNotificationEnabled()) + return; + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + if (!web_contents_delegate) { + LOG(ERROR) << "web contents delegate is null"; + return; + } + web_contents_delegate->NotifyFirstTimeStamp(timestamp, time_base_num, + time_base_den); +} + +void MediaPlayerBridgeCapiTV::NotifyPESData(const std::string& buf, + unsigned int len, + int media_position) { + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "MediaPlayerClient is null"; + return; + } + if (!blink::IsHbbTV() || + !GetMediaPlayerClient()->SubtitleNotificationEnabled()) + return; + content::WebContentsDelegate* web_contents_delegate = + GetMediaPlayerClient()->GetWebContentsDelegate(); + if (!web_contents_delegate) { + LOG(ERROR) << "web contents delegate is null"; + return; + } + web_contents_delegate->NotifyPESData(buf, len, media_position); +} +#endif + void MediaPlayerBridgeCapiTV::UpdateDuration() { LOG_ID(INFO, GetPlayerId()) << "(" << static_cast(this) << ") " << __func__; @@ -543,9 +1008,9 @@ void MediaPlayerBridgeCapiTV::PlayerPreloaded() { // UpdateSeekableTime(); // StartSeekableTimeUpdateTimer(); } - // UpdateAudioTrackInfo(); - // UpdateVideoTrackInfo(); - // UpdateTextTrackInfo(); + UpdateAudioTrackInfo(); + UpdateVideoTrackInfo(); + UpdateTextTrackInfo(); UpdateDuration(); UpdateMediaType(); if (GetMediaType() == MediaType::Invalid) { @@ -682,4 +1147,842 @@ void MediaPlayerBridgeCapiTV::SetParentalRatingResult(bool is_pass) { ExecuteDelayedPlayerState(); } } +void MediaPlayerBridgeCapiTV::AddAudioTrackInfo(const std::string& id, + const std::string& kind, + const std::string& label, + const std::string& lang, + int enabled) { + LOG_ID(INFO, player_id_) << "AudioTrack Info - id: " << id + << ", kind: " << kind.c_str() + << ", label: " << label.c_str() + << ", lang: " << lang.c_str(); + + media::mojom::MediaTrackInfoPtr trackinfo = + media::mojom::MediaTrackInfo::New(); + trackinfo->cmd = media::mojom::TRACKCMD::SETAUDIO; + trackinfo->ck = media::mojom::COOKIES::NewTrack( + media::mojom::Track::New(id, kind, label, lang, enabled)); + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->AddTrackInfo(std::move(trackinfo)); + else + LOG(ERROR) << "Media player client is null"; +} + +void MediaPlayerBridgeCapiTV::OnOtherEvent(int event_type, void* event_data) { + if (!event_data) { + LOG(ERROR) << "event_data is null."; + return; + } + switch (event_type) { + case PLAYER_MSG_STREAM_EVENT_TYPE: { + LOG_ID(INFO, player_id_) << "PLAYER_MSG_STREAM_EVENT_TYPE"; + EventStream* eventstream = static_cast(event_data); + if (!eventstream) { + LOG(ERROR) << "eventstream is null."; + return; + } + std::string uri(eventstream->schemeIdUri ? eventstream->schemeIdUri : ""); + std::string value(eventstream->value ? eventstream->value : ""); +#if TIZEN_VERSION_AT_LEAST(6, 5, 0) + int band_type = eventstream->type; + int event_mode = static_cast( + (band_type >= IN_BAND) ? (band_type - IN_BAND) + : (band_type - OUT_BAND)); +#else + player_event_mode event_mode = eventstream->type; + int band_type = static_cast(event_mode); +#endif + LOG_ID(INFO, player_id_) + << "uri:" << uri << ",value:" << value << ",band_type:" << band_type + << ",event_mode:" << event_mode; + + // parental rating event only need to handle data info + if (event_mode == PLAYER_DVB_EVENT_MODE_PARENTAL_GUIDANCE) { + LOG_ID(INFO, player_id_) << "parental rating event, skip type"; + return; + } + + if (!uri.compare("urn:mpeg:dash:event:2012") || + !uri.compare("urn:dvb:iptv:cpm:2014")) { + LOG_ID(INFO, player_id_) << "not supported scheme id uri,uri:" << uri; + return; + } +#if !defined(EWK_BRINGUP) + if (!uri.compare("urn:dvb:css")) { + LOG_ID(INFO, player_id_) << "event->value:" << eventstream->value + << " evalue " << value.c_str(); + task_runner_->PostTask( + FROM_HERE, base::BindOnce(&MediaPlayerBridgeCapi::UpdateEventData, + weak_factory_.GetWeakPtr(), value)); + return; + } +#endif + const std::string info = uri + " " + value; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleInbandTextTrack, + weak_factory_.GetWeakPtr(), info, band_type, + ADD_INBAND_TEXT_TRACK)); + break; + } + case PLAYER_MSG_STREAM_EVENT_DATA: { + LOG_ID(INFO, player_id_) << "PLAYER_MSG_STREAM_EVENT_DATA"; + Event* event = static_cast(event_data); + if (!event) { + LOG(ERROR) << "event is null."; + return; + } + std::string uri(event->schemeIdUri ? event->schemeIdUri : ""); + std::string value(event->value ? event->value : ""); + unsigned int id = event->id; + long long int start_time = event->startTimeMs; + long long int end_time = event->endTimeMs; + std::string data(event->data ? event->data : ""); +#if TIZEN_VERSION_AT_LEAST(6, 5, 0) + int band_type = event->type; + int event_mode = static_cast( + (band_type >= IN_BAND) ? (band_type - IN_BAND) + : (band_type - OUT_BAND)); +#else + player_event_mode event_mode = event->type; + int band_type = static_cast(event_mode); +#endif + LOG_ID(INFO, player_id_) + << "uri:" << uri << ",value:" << value << ",data:" << data + << ",id:" << id << ",start_time:" << start_time + << ",end_time:" << end_time << ",band_type:" << band_type + << ",event_mode:" << event_mode; + + if (event_mode == PLAYER_DVB_EVENT_MODE_DEAULT) { + if (0 == uri.compare("urn:mpeg:dash:event:2012") || + 0 == uri.compare("urn:dvb:iptv:cpm:2014")) { + LOG_ID(INFO, player_id_) << "not supported scheme id uri,uri:" << uri; + return; + } + const std::string info = uri + " " + value + "$" + data; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleInbandTextCue, + weak_factory_.GetWeakPtr(), info, id, band_type, + start_time, end_time)); + } else if (event_mode == PLAYER_DVB_EVENT_MODE_PARENTAL_GUIDANCE) { + // + std::size_t pos = data.find("ParentalRating href="); + if (pos != std::string::npos) { + parental_rating_pass_ = false; + std::size_t quotation1 = data.find('"', pos); + std::size_t quotation2 = data.find('"', quotation1 + 1); + std::string target = + data.substr(quotation1 + 1, quotation2 - quotation1 - 1); + LOG_ID(INFO, player_id_) + << "parentl rating info string is:" << target; + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleParentalRatingInfo, + weak_factory_.GetWeakPtr(), target, url_.spec())); + } + } else if ( + event_mode == + PLAYER_DVB_EVENT_MODE_SUPPLEMENTAL_PROPERTY_FONT_DOWNLOAD || + event_mode == + PLAYER_DVB_EVENT_MODE_ESSENTIAL_PROPERTY_FONT_DOWNLOAD) { + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleDownloadableFontInfo, + weak_factory_.GetWeakPtr(), uri, value, data, + event_mode)); + } + break; + } + case PLAYER_MSG_STREAM_EVENT_MRS_URL_CHANGED: { + LOG_ID(INFO, player_id_) << "PLAYER_MSG_STREAM_EVENT_MRS_URL_CHANGED"; + char* url = static_cast(event_data); + std::string mrsUrl(url ? url : ""); + LOG_ID(INFO, player_id_) << "mrsUrl:" << mrsUrl; +#if !defined(EWK_BRINGUP) + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleMrsUrlChange, + weak_factory_.GetWeakPtr(), mrsUrl)); +#endif + break; + } + case PLAYER_MSG_STREAM_EVENT_PERIOAD_ID_CHANGED: { + LOG_ID(INFO, player_id_) << "PLAYER_MSG_STREAM_EVENT_PERIOAD_ID_CHANGED"; + char* id = static_cast(event_data); + std::string periodId(id ? id : ""); + LOG_ID(INFO, player_id_) << "periodId:" << periodId; +#if !defined(EWK_BRINGUP) + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandlePeriodIdChange, + weak_factory_.GetWeakPtr(), periodId)); +#endif + break; + } + case PLAYER_MSG_STREAM_EVENT_REMOVE_TRACK: { + LOG_ID(INFO, player_id_) << "PLAYER_MSG_STREAM_EVENT_REMOVE_TRACK"; + EventStream* eventstream = static_cast(event_data); + if (!eventstream) { + LOG(ERROR) << "eventstream is null."; + return; + } + std::string uri(eventstream->schemeIdUri ? eventstream->schemeIdUri : ""); + std::string value(eventstream->value ? eventstream->value : ""); + LOG_ID(INFO, player_id_) << "uri:" << uri << ",value:" << value; + + const std::string info = uri + " " + value; +#if TIZEN_VERSION_AT_LEAST(6, 5, 0) + int band_type = eventstream->type; +#else + int band_type = static_cast(eventstream->type); +#endif + task_runner_->PostTask( + FROM_HERE, + base::BindOnce(&MediaPlayerBridgeCapiTV::HandleInbandTextTrack, + weak_factory_.GetWeakPtr(), info, band_type, + DEL_INBAND_TEXT_TRACK)); + break; + } + default: + LOG_ID(INFO, player_id_) << "unknow event type:" << event_type; + break; + } +} + +void MediaPlayerBridgeCapiTV::HandleInbandTextTrack(const std::string& info, + int band_type, + int action) { + LOG_ID(INFO, player_id_) << "HandleInbandTextTrack info:" << info + << " band_type:" << band_type + << " action:" << action; + media::mojom::MediaTrackInfoPtr trackinfo = + media::mojom::MediaTrackInfo::New(); + trackinfo->cmd = media::mojom::TRACKCMD::SETINBAND; + trackinfo->ck = media::mojom::COOKIES::NewInband( + media::mojom::InbandTextInfo::New(info, band_type, action)); + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->AddTrackInfo(std::move(trackinfo)); +} + +void MediaPlayerBridgeCapiTV::HandleInbandTextCue(const std::string& info, + unsigned int id, + int band_type, + long long int start_time, + long long int end_time) { + LOG_ID(INFO, player_id_) << "HandleInbandTextCue info:" << info + << " id:" << id << " band_type:" << band_type + << " start_time:" << start_time + << " end_time:" << end_time; + media::mojom::MediaTrackInfoPtr trackinfo = + media::mojom::MediaTrackInfo::New(); + trackinfo->cmd = media::mojom::TRACKCMD::SETCUE; + trackinfo->ck = + media::mojom::COOKIES::NewCue(media::mojom::InbandCueInfo::New( + info, id, band_type, start_time, end_time)); + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->AddTrackInfo(std::move(trackinfo)); + else + LOG(ERROR) << "Media player client is null"; +} + +std::string MediaPlayerBridgeCapiTV::MapDashMediaTrackKind( + const std::string& role, + const int size, + bool isAudio) { + // HBBTV Spec : A.2.12.3 Modifications to clause 8.4.6 + // HBBTV spec v2.0.2 seperate audioTrack and videoTrack kind definition + // and changed the "main" definiton of audioTrack(page 258) + if (role.find("alternate") != std::string::npos && + role.find("main") == std::string::npos && + role.find("commentary") == std::string::npos && + role.find("dub") == std::string::npos) + return "alternative"; + + if (role.find("caption") != std::string::npos && + role.find("main") != std::string::npos) + return "captions"; + + if (role.find("description") != std::string::npos && + role.find("supplementary") != std::string::npos) + return "descriptions"; + + if (role.find("main") != std::string::npos && + role.find("caption") == std::string::npos && + role.find("subtitle") == std::string::npos && + role.find("dub") == std::string::npos) { + if (!isAudio) + return "main"; + else if (role.find("description") == std::string::npos) + return "main"; + } + + if (role.find("main") != std::string::npos && + role.find("description") != std::string::npos) + return "main-desc"; + + if (role.find("subtitle") != std::string::npos && + role.find("main") != std::string::npos) + return "subtitles"; + + if (role.find("dub") != std::string::npos && + role.find("main") != std::string::npos) + return "translation"; + + if (role.find("commentary") != std::string::npos && + role.find("main") == std::string::npos) + return "commentary"; + + return ""; +} + +void MediaPlayerBridgeCapiTV::UpdateAudioTrackInfo() { + int cntTracks = 0; + int err = player_get_adaptationset_count(player_, PLAYER_STREAM_TYPE_AUDIO, + &cntTracks); + if (err != PLAYER_ERROR_NONE || cntTracks == 0) { + LOG_ID(ERROR, player_id_) + << "get audio track fail,err:" << err << ",count:" << cntTracks; + return; + } + + LOG_ID(INFO, player_id_) << "audio track count: " << cntTracks; + + player_audio_adaptationset_info* audio_track_info = + static_cast( + malloc(cntTracks * sizeof(player_audio_adaptationset_info))); + if (!audio_track_info) { + LOG_ID(ERROR, player_id_) << "malloc fail"; + return; + } + memset(audio_track_info, 0, + cntTracks * sizeof(player_audio_adaptationset_info)); + + unsigned audio_alter_count_total = 0; + for (int i = 0; i < cntTracks; i++) { + int audio_alter_count = 0; + err = player_get_alternative_count(player_, PLAYER_STREAM_TYPE_AUDIO, i, + &audio_alter_count); + if (err != PLAYER_ERROR_NONE || audio_alter_count == 0) { + LOG_ID(WARNING, player_id_) + << "player_get_alternative_count error,idx: " << i + << ",audio_alter_count: " << audio_alter_count; + continue; + } + + LOG_ID(INFO, player_id_) + << "audio track idx:" << i << ",alter_count:" << audio_alter_count; + audio_alter_count_total += audio_alter_count; + audio_track_info[i].alternatives = + static_cast( + malloc(audio_alter_count * sizeof(Alternative_audioStreamInfo))); + if (!audio_track_info[i].alternatives) { + LOG_ID(ERROR, player_id_) + << "malloc fail,free memory which is already malloced"; + if (i >= 1) { + for (int j = 0; j <= i - 1; j++) + BLINKFREE(audio_track_info[j].alternatives); + } + BLINKFREE(audio_track_info); + return; + } + memset(audio_track_info[i].alternatives, 0, + audio_alter_count * sizeof(Alternative_audioStreamInfo)); + } +#if !defined(EWK_BRINGUP) + if (blink::IsHbbTV()) + AudioTracksCountChanged(audio_alter_count_total); +#endif + err = player_get_audio_adaptationset_info(player_, audio_track_info); + if (err != PLAYER_ERROR_NONE) { + LOG_ID(ERROR, player_id_) << "|player_get_audio_adaptationset_info| failed"; + for (int i = 0; i < cntTracks; i++) + BLINKFREE(audio_track_info[i].alternatives); + BLINKFREE(audio_track_info); + return; + } + + int selected_idx = -1; + int audio_track_index = 0; + + /* Get audio index for prefer languange & audio description */ + for (int i = 0; i < cntTracks; i++) { + if (!audio_track_info[i].alternatives) { + LOG_ID(WARNING, player_id_) << "track[" << i << "] fail,ignore it."; + continue; + } + + const char* language = audio_track_info[i].language; + if (prefer_audio_lang_.find(language) != std::string::npos || + (GetAlpha2(prefer_audio_lang_).find(language) != std::string::npos)) { + if (stream_type_ == DASH_STREAM) + prefer_audio_adaptionset_idx_ = audio_track_info[i].index; + else + prefer_audio_adaptionset_idx_ = i; + + selected_idx = i; + break; + } + } + LOG_ID(INFO, player_id_) << "prefer_audio_adaptationset_idx_: " + << prefer_audio_adaptionset_idx_ + << ",selected_idx:" << selected_idx; + + audio_track_index = 0; + + for (int i = 0; i < cntTracks; i++) { +#if TIZEN_VERSION_AT_LEAST(7, 0, 0) + if (audio_track_info[i].preselectionInfo_count) { + for (int j = 0; j < audio_track_info[i].preselectionInfo_count; j++) { + std::string pres_id = audio_track_info[i].preselectionInfos[j].m_id; + std::string language = audio_track_info[i].preselectionInfos[j].m_lang; + std::string kind = audio_track_info[i].preselectionInfos[j].m_roleValue; + std::string label = ""; + int enabled = (selected_idx == audio_track_index); + AddAudioTrackInfo(pres_id, kind, label, language, enabled); + audio_track_index++; + } + continue; + } +#endif + + if (!audio_track_info[i].alternatives) { + LOG_ID(WARNING, player_id_) << "track[" << i << "] fail,ignore it."; + continue; + } + const char* lang = audio_track_info[i].language; + std::string langStr(lang ? lang : ""); + + std::stringstream roleInfoBuilder; + const int role_count = audio_track_info[i].role_count; + + for (int k = 0; k < role_count; k++) { + const char* role_member = audio_track_info[i].role_value[k]; + const std::string role_str(role_member ? role_member : ""); + roleInfoBuilder << role_str << ","; + } + + LOG_ID(INFO, player_id_) + << "role str:" << roleInfoBuilder.str() << ",role count:" << role_count; + std::string kindStr = ""; + if (stream_type_ == DASH_STREAM) + kindStr = MapDashMediaTrackKind(roleInfoBuilder.str(), role_count, true); + if (stream_type_ == TS_STREAM) // role_count = 1 + kindStr = audio_track_info[i].role_value[0]; + + char* label = nullptr; + err = player_get_content_info(player_, PLAYER_CONTENT_INFO_TITLE, &label); + if (err != PLAYER_ERROR_NONE) + LOG_ID(WARNING, player_id_) << "|player_get_content_info| failed"; + std::string labelStr(label ? label : ""); + BLINKFREE(label); + + int id = 0; + if (stream_type_ == DASH_STREAM) + id = audio_track_info[i].adaptationset_id; + else + id = audio_track_info[i].alternatives[0].track_id; + + std::string pres_id = std::to_string(id); + std::string language = langStr; + std::string kind = kindStr; + std::string labels = labelStr; + int enabled = (selected_idx == audio_track_index); + AddAudioTrackInfo(pres_id, kind, labels, language, enabled); + audio_track_index++; + } + + for (int j = 0; j < cntTracks; j++) { + BLINKFREE(audio_track_info[j].alternatives); +#if TIZEN_VERSION_AT_LEAST(7, 0, 0) + BLINKFREE(audio_track_info[j].preselectionInfos); +#endif + } + + BLINKFREE(audio_track_info); +} + +void MediaPlayerBridgeCapiTV::UpdateVideoTrackInfo() { + int cntTracks = 0; + int err = player_get_adaptationset_count(player_, PLAYER_STREAM_TYPE_VIDEO, + &cntTracks); + if (err != PLAYER_ERROR_NONE || cntTracks == 0) { + LOG(ERROR) << "get video track fail,err:" << err << ",count" << cntTracks; + return; + } + + LOG_ID(INFO, player_id_) << "video track count: " << cntTracks; + + player_video_adaptationset_info* video_track_info = + static_cast( + malloc(cntTracks * sizeof(player_video_adaptationset_info))); + if (!video_track_info) { + LOG(ERROR) << "malloc fail"; + return; + } + memset(video_track_info, 0, + cntTracks * sizeof(player_video_adaptationset_info)); + + int adaptionSetIdx = -1; + int alternativeIdx = -1; + err = player_get_current_track_ex(player_, PLAYER_STREAM_TYPE_VIDEO, + &adaptionSetIdx, &alternativeIdx); + if (err != PLAYER_ERROR_NONE) + LOG(WARNING) << "|player_get_current_track| failed"; + LOG_ID(INFO, player_id_) << "video adaptionSetIdx:" << adaptionSetIdx + << ",alternativeIdx:" << alternativeIdx; + + for (int i = 0; i < cntTracks; i++) { + int video_alter_count = 0; + err = player_get_alternative_count(player_, PLAYER_STREAM_TYPE_VIDEO, i, + &video_alter_count); + if (err != PLAYER_ERROR_NONE || video_alter_count == 0) { + LOG(WARNING) << "player_get_alternative_count error,idx: " << i + << ",video_alter_count: " << video_alter_count; + continue; + } + + LOG_ID(INFO, player_id_) + << "video track idx:" << i << ",alter_count:" << video_alter_count; + video_track_info[i].alternatives = + static_cast( + malloc(video_alter_count * sizeof(Alternative_videoStreamInfo))); + if (!video_track_info[i].alternatives) { + LOG(ERROR) << "malloc fail,free memory which is already malloced"; + if (i >= 1) { + for (int j = 0; j <= i - 1; j++) + BLINKFREE(video_track_info[j].alternatives); + } + BLINKFREE(video_track_info); + return; + } + memset(video_track_info[i].alternatives, 0, + video_alter_count * sizeof(Alternative_videoStreamInfo)); + } + + err = player_get_video_adaptationset_info(player_, video_track_info); + if (err != PLAYER_ERROR_NONE) { + LOG(WARNING) << "|player_get_video_adaptationset_info| failed"; + for (int i = 0; i < cntTracks; i++) + BLINKFREE(video_track_info[i].alternatives); + BLINKFREE(video_track_info); + return; + } + + for (int i = 0; i < cntTracks; i++) { + if (!video_track_info[i].alternatives) { + LOG(WARNING) << "track[" << i << "] fail,ignore it."; + continue; + } + + char* lang = nullptr; + err = player_get_track_language_code_ex(player_, PLAYER_STREAM_TYPE_VIDEO, + i, &lang); + if (err != PLAYER_ERROR_NONE) + LOG(WARNING) << "|player_get_track_language_code| failed"; + std::string langStr(lang ? lang : ""); + BLINKFREE(lang); + + std::stringstream roleInfoBuilder; + const int role_count = video_track_info[i].role_count; + + for (int k = 0; k < role_count; k++) { + const char* role_member = video_track_info[i].role_value[k]; + const std::string role_str(role_member ? role_member : ""); + roleInfoBuilder << role_str << ","; + } + + LOG_ID(INFO, player_id_) + << "role str:" << roleInfoBuilder.str() << ",role count:" << role_count; + + std::string kindStr = ""; + if (stream_type_ == DASH_STREAM) + kindStr = MapDashMediaTrackKind(roleInfoBuilder.str(), role_count, false); + + char* label = nullptr; + err = player_get_content_info(player_, PLAYER_CONTENT_INFO_TITLE, &label); + if (err != PLAYER_ERROR_NONE) + LOG(WARNING) << "|player_get_content_info| failed"; + std::string labelStr(label ? label : ""); + BLINKFREE(label); + + int id = 0; + if (stream_type_ == DASH_STREAM) + id = video_track_info[i].adaptationset_id; + else + id = video_track_info[i].alternatives[0].track_id; + + if (adaptionSetIdx == i) + LOG_ID(INFO, player_id_) << "VideoTrack index: [" << i << "] is selected"; + + BLINKFREE(video_track_info[i].alternatives); + + LOG_ID(INFO, player_id_) + << "VideoTrack Info - id: " << id << ", kind: " << kindStr.c_str() + << ", label: " << labelStr.c_str() << ", lang: " << langStr.c_str(); + + media::mojom::MediaTrackInfoPtr trackinfo = + media::mojom::MediaTrackInfo::New(); + trackinfo->cmd = media::mojom::TRACKCMD::SETVIDEO; + trackinfo->ck = media::mojom::COOKIES::NewTrack(media::mojom::Track::New( + std::to_string(id), kindStr, labelStr, langStr, adaptionSetIdx == i)); + + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->AddTrackInfo(std::move(trackinfo)); + else + LOG(ERROR) << "Media player client is null"; + } + BLINKFREE(video_track_info); +} + +void MediaPlayerBridgeCapiTV::UpdateTextTrackInfo() { + int cntTracks = 0; + int err = player_get_adaptationset_count(player_, PLAYER_STREAM_TYPE_TEXT, + &cntTracks); + if (err != PLAYER_ERROR_NONE || cntTracks == 0) { + LOG_ID(ERROR, player_id_) + << "get text track fail,err:" << err << ",count:" << cntTracks; + return; + } + + LOG_ID(INFO, player_id_) << "text track count: " << cntTracks; + + player_subtitle_adaptationset_info* text_track_info = + static_cast( + malloc(cntTracks * sizeof(player_subtitle_adaptationset_info))); + if (!text_track_info) { + LOG_ID(ERROR, player_id_) << "malloc fail"; + return; + } + memset(text_track_info, 0, + cntTracks * sizeof(player_subtitle_adaptationset_info)); + + int adaptionSetIdx = -1; + int alternativeIdx = -1; + err = player_get_current_track_ex(player_, PLAYER_STREAM_TYPE_TEXT, + &adaptionSetIdx, &alternativeIdx); + if (err != PLAYER_ERROR_NONE) + LOG_ID(WARNING, player_id_) << "|player_get_current_track| failed"; + LOG_ID(INFO, player_id_) << "text adaptionSetIdx:" << adaptionSetIdx + << ",alternativeIdx:" << alternativeIdx; + + for (int i = 0; i < cntTracks; i++) { + int text_alter_count = 0; + err = player_get_alternative_count(player_, PLAYER_STREAM_TYPE_TEXT, i, + &text_alter_count); + if (err != PLAYER_ERROR_NONE || text_alter_count == 0) { + LOG_ID(WARNING, player_id_) + << "player_get_alternative_count error,idx: " << i + << ",text_alter_count: " << text_alter_count; + continue; + } + + LOG_ID(INFO, player_id_) + << "text track idx:" << i << ",alter_count:" << text_alter_count; + text_track_info[i].alternatives = + static_cast( + malloc(text_alter_count * sizeof(Alternative_subtitleStreamInfo))); + if (!text_track_info[i].alternatives) { + LOG_ID(ERROR, player_id_) + << "malloc fail,free memory which is already malloced"; + if (i >= 1) { + for (int j = 0; j <= i - 1; j++) + BLINKFREE(text_track_info[j].alternatives); + } + BLINKFREE(text_track_info); + return; + } + memset(text_track_info[i].alternatives, 0, + text_alter_count * sizeof(Alternative_subtitleStreamInfo)); + } + + err = player_get_subtitle_adaptationset_info(player_, text_track_info); + if (err != PLAYER_ERROR_NONE) { + LOG_ID(ERROR, player_id_) + << "|player_get_subtitle_adaptationset_info| failed"; + for (int i = 0; i < cntTracks; i++) + BLINKFREE(text_track_info[i].alternatives); + BLINKFREE(text_track_info); + return; + } + + for (int i = 0; i < cntTracks; i++) { + if (!text_track_info[i].alternatives) { + LOG_ID(WARNING, player_id_) << "track[" << i << "] fail,ignore it."; + continue; + } + + char* lang = nullptr; + err = player_get_track_language_code_ex(player_, PLAYER_STREAM_TYPE_TEXT, i, + &lang); + if (err != PLAYER_ERROR_NONE) + LOG_ID(ERROR, player_id_) << "|player_get_track_language_code| failed"; + std::string langStr(lang ? lang : ""); + BLINKFREE(lang); + + char* label = nullptr; + err = player_get_content_info(player_, PLAYER_CONTENT_INFO_TITLE, &label); + if (err != PLAYER_ERROR_NONE) + LOG_ID(ERROR, player_id_) << "|player_get_content_info| failed"; + std::string labelStr(label ? label : ""); + BLINKFREE(label); + + int id = 0; + if (stream_type_ == TS_STREAM) + id = text_track_info[i].alternatives[0].track_id; + else + id = text_track_info[i].adaptationset_id; + + std::string kindStr(""); +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + // subtitling_type: 8bit, maybe unvisible char + if (stream_type_ == TS_STREAM) { + int subitle_type = (int)text_track_info[i].role_value[0][0]; + LOG(INFO) << "subitle_type:" << subitle_type; + if (subitle_type == 0x10 || subitle_type == 0x11 || + subitle_type == 0x12 || subitle_type == 0x13 || + subitle_type == 0x14 || subitle_type == 0x15) + kindStr = "subtitles"; + } +#endif + + if (adaptionSetIdx == i) + LOG_ID(INFO, player_id_) << "TextTrack index: [" << i << "] is selected"; + + BLINKFREE(text_track_info[i].alternatives); + + LOG_ID(INFO, player_id_) + << "TextTrack Info - id: " << id << ", label: " << labelStr.c_str() + << ", lang: " << langStr.c_str() << ", kind: " << kindStr.c_str(); + + media::mojom::MediaTrackInfoPtr trackinfo = + media::mojom::MediaTrackInfo::New(); + trackinfo->cmd = media::mojom::TRACKCMD::SETTEXT; + trackinfo->ck = media::mojom::COOKIES::NewTrack(media::mojom::Track::New( + std::to_string(id), kindStr, labelStr, langStr, true)); + + if (GetMediaPlayerClient()) + GetMediaPlayerClient()->AddTrackInfo(std::move(trackinfo)); + } + + BLINKFREE(text_track_info); +} + +void MediaPlayerBridgeCapiTV::UpdatePreferAudio() { + LOG(INFO) << "UpdatePreferAudio,idx: " << prefer_audio_adaptionset_idx_ + << ",last idx:" << last_prefer_audio_adaptionset_idx_; + if (prefer_audio_adaptionset_idx_ == last_prefer_audio_adaptionset_idx_) { + LOG_ID(ERROR, player_id_) << "same track,no need to select"; + return; + } + int ret = player_select_track_ex(player_, PLAYER_STREAM_TYPE_AUDIO, + prefer_audio_adaptionset_idx_, -1); + if (ret != PLAYER_ERROR_NONE) { + LOG_ID(ERROR, player_id_) << "player_select_track_ex fail"; + return; + } + active_audio_track_id_ = prefer_audio_adaptionset_idx_; + last_prefer_audio_adaptionset_idx_ = prefer_audio_adaptionset_idx_; +} + +bool MediaPlayerBridgeCapiTV::GetUserPreferAudioLanguage() { + prefer_audio_lang_.clear(); + int retval; + const char* primary_audio_lang = + "db/menu/broadcasting/audio_options/primary_audio_language"; + int ret = vconf_get_int(primary_audio_lang, &retval); + if (ret != 0) { + LOG(ERROR) << "vconf_get_int failed"; + return false; + } + prefer_audio_lang_ += (char)(retval >> 16 & 0xFF); + prefer_audio_lang_ += (char)(retval >> 8 & 0xFF); + prefer_audio_lang_ += (char)(retval & 0xFF); + LOG_ID(INFO, player_id_) << "primary audio lang is: " + << prefer_audio_lang_.c_str(); + return true; +} + +void MediaPlayerBridgeCapiTV::SetActiveTextTrack(int id, bool is_in_band) { + LOG_ID(INFO, player_id_) << "id=" << id << ",is_in_band=" << is_in_band + << " active_text_track_id_ " + << active_text_track_id_; + if (!GetMediaPlayerClient()) { + LOG(ERROR) << "GetMediaPlayerClient return null"; + return; + } + if (!GetMediaPlayerClient()->SubtitleNotificationEnabled()) { + LOG(ERROR) << "SubtitleNotificationEnabled failed"; + return; + } + +#if !defined(EWK_BRINGUP) + if (id == -1) { + NotifyStopTrack(); + return; + } + + if (active_text_track_id_ == id) + return; + + active_text_track_id_ = id; + + is_inband_text_track_ = is_in_band; + NotifyPlayTrack(); +#endif +} + +void MediaPlayerBridgeCapiTV::SetActiveAudioTrack(int index) { + LOG_ID(INFO, player_id_) << "active_audio_track_id_ " + << active_audio_track_id_ << " index " << index; + + if (index == -1) { + player_set_mute(player_, true); + active_audio_track_id_ = -1; + return; + } + + if (active_audio_track_id_ == index) + return; + active_audio_track_id_ = index; + int ret = player_select_track_ex(player_, PLAYER_STREAM_TYPE_AUDIO, + active_audio_track_id_, -1); + if (ret != PLAYER_ERROR_NONE) + LOG_ID(WARNING, player_id_) << "player_select_track_ex fail,ret:" << ret; +} + +void MediaPlayerBridgeCapiTV::SetActiveVideoTrack(int index) { + LOG_ID(INFO, player_id_) << "active_video_track_id_ " + << active_video_track_id_ << " index " << index; + + if (index == -1) { + player_set_display_visible(player_, false); + active_video_track_id_ = -1; + return; + } + + if (active_video_track_id_ == index) + return; + active_video_track_id_ = index; + int ret = player_select_track_ex(player_, PLAYER_STREAM_TYPE_VIDEO, + active_video_track_id_, -1); + if (ret != PLAYER_ERROR_NONE) + LOG_ID(WARNING, player_id_) << "player_select_track_ex fail,ret:" << ret; +} + +void MediaPlayerBridgeCapiTV::SetPreferTextLanguage(const std::string& lang) { + LOG_ID(INFO, player_id_) + << "MediaPlayerBridgeCapiTV::SetPreferTextLanguage lang" << lang + << " prefer_subtitle_lang_ " << prefer_subtitle_lang_; + + if (lang == prefer_subtitle_lang_) + return; + prefer_subtitle_lang_ = lang; + const std::string prefer_subtitle_language = + "set_subtitle_language = " + lang; + + LOG_ID(INFO, player_id_) << "prefer_subtitle_language:" + << prefer_subtitle_language.c_str(); + player_set_ini_param(player_, prefer_subtitle_language.c_str()); +} } // namespace media diff --git a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h index 702a098..dc78210 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h +++ b/tizen_src/chromium_impl/media/filters/media_player_bridge_capi_tv.h @@ -8,8 +8,17 @@ #include #include "media/filters/media_player_bridge_capi.h" +#include "tizen_src/chromium_impl/build/tizen_version.h" namespace media { +/* TC: org.hbbtv_DASH-EVENT0100 + * Current use @schemeIdUri and @value to divide texttrack. + * So add event type to divide InbandEventStreams and EventStreams. + * event_type: 0x7700 for eventstream; + * 0x9900 for inbandeventstream + */ +#define OUT_BAND 0x7700 +#define IN_BAND 0x9900 enum StreamType { HLS_STREAM = 0, @@ -18,6 +27,11 @@ enum StreamType { OTHER_STREAM, }; +enum TrackAction { + ADD_INBAND_TEXT_TRACK = 0, + DEL_INBAND_TEXT_TRACK, +}; + // This class is focus on HBBTV/HLS feature on Tizen TV. class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { public: @@ -43,12 +57,43 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { const std::string& data, int type); void OnPlayerPreloading(); + void OnOtherEvent(int event_type, void* event_data); + void SetActiveTextTrack(int id, bool is_in_band) override; + void SetActiveAudioTrack(int index) override; + void SetActiveVideoTrack(int index) override; + void SetPreferTextLanguage(const std::string& lang) override; void OnDrmError(int err_code, char* err_str); + void Seek(base::TimeDelta time, base::OnceClosure seek_cb) override; + void OnCurrentTimeUpdateTimerFired() override; + void SeekCompleteUpdate() override; + void OnResumeComplete(bool success) override; void SetParentalRatingResult(bool is_pass) override; void HandleParentalRatingInfo(const std::string& info, const std::string& url); + void HandleBufferingStatus(int percent) override; + void SubtitleDataCB(long long time_stamp, + unsigned index, + const std::string& buffer, + unsigned buffer_size); +#if TIZEN_VERSION_AT_LEAST(6, 0, 0) + void OnFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den); + void OnTSSubtitleData(int pid, unsigned char* data, unsigned int len); + void HandleFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den); + void HandleTSSubtitleData(int pid, const std::string& buf, unsigned int len); + void NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den); + void NotifyPESData(const std::string& buf, + unsigned int len, + int media_position); + +#endif protected: void PlayerPrepared() override; @@ -62,6 +107,41 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { bool SetMediaDRMInfo(const std::string&, const std::string&); bool is_preloaded_{false}; bool is_player_seek_available_{true}; + + void NotifySubtitlePlay(int id, + const std::string& url, + const std::string& lang); + void NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned size); + void NotifySubtitleState(int state, double time_stamp = 0.0); + void NotifyStopTrack(); + void NotifyPlayTrack(); + void UpdateActiveTextTrack(int track_id); + void OnHandleOtherEvent(int event_type, void* event_data); + void UpdateAudioTrackInfo(); + void UpdateVideoTrackInfo(); + void UpdateTextTrackInfo(); + std::string MapMediaTrackKind(const std::string& role, const int size); + bool GetUserPreferAudioLanguage(); + void UpdatePreferAudio(); + void HandleInbandTextTrack(const std::string& info, + int band_type, + int action); + void HandleInbandTextCue(const std::string& info, + unsigned int id, + int band_type, + long long int start_time, + long long int end_time); + std::string MapDashMediaTrackKind(const std::string& role, + const int size, + bool isAudio); + void AddAudioTrackInfo(const std::string& id, + const std::string& kind, + const std::string& label, + const std::string& lang, + int enabled); void StartSeekableTimeUpdateTimer(); void StopSeekableTimeUpdateTimer(); void OnSeekableTimeUpdateTimerFired(); @@ -79,7 +159,20 @@ class MEDIA_EXPORT MediaPlayerBridgeCapiTV : public MediaPlayerBridgeCapi { std::string mrs_url_{""}; std::string content_id_{""}; // clean_url + period,only report to APP + int subtitle_state_{blink::WebMediaPlayer::kSubtitleStop}; + bool is_inband_text_track_{false}; + std::string prefer_audio_lang_; + std::string prefer_subtitle_lang_{""}; + int active_audio_track_id_{-1}; + int active_text_track_id_{-1}; + int active_video_track_id_{-1}; + int pending_active_audio_track_id_{-1}; + int pending_active_text_track_id_{-1}; + int pending_active_video_track_id_{-1}; + int prefer_audio_adaptionset_idx_{0}; + int last_prefer_audio_adaptionset_idx_{0}; bool parental_rating_pass_{false}; + bool is_buffering_compeleted_{false}; base::TimeDelta min_seekable_time_{base::TimeDelta()}; base::TimeDelta max_seekable_time_{base::TimeDelta()}; diff --git a/tizen_src/chromium_impl/media/filters/media_player_tizen.h b/tizen_src/chromium_impl/media/filters/media_player_tizen.h index d4b9de5..10a5f22 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_tizen.h +++ b/tizen_src/chromium_impl/media/filters/media_player_tizen.h @@ -10,6 +10,7 @@ #include "media/base/demuxer_stream.h" #include "media/filters/flags.h" #include "third_party/blink/public/platform/web_application_type.h" +#include "third_party/blink/public/platform/web_media_player.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/tbm_buffer_handle.h" @@ -110,6 +111,10 @@ class MEDIA_EXPORT MediaPlayerTizen { virtual int GetPlayerId() { return -1; } virtual void SetContentMimeType(const std::string& mime_type) {} virtual void SetParentalRatingResult(bool is_pass) {} + virtual void SetActiveTextTrack(int id, bool is_in_band) {} + virtual void SetActiveAudioTrack(int index) {} + virtual void SetActiveVideoTrack(int index) {} + virtual void SetPreferTextLanguage(const std::string& lang) {} }; } // namespace media diff --git a/tizen_src/chromium_impl/media/filters/media_player_tizen_client.h b/tizen_src/chromium_impl/media/filters/media_player_tizen_client.h index 9b21291..f4ad8ea 100644 --- a/tizen_src/chromium_impl/media/filters/media_player_tizen_client.h +++ b/tizen_src/chromium_impl/media/filters/media_player_tizen_client.h @@ -10,6 +10,7 @@ #include "media/base/pipeline_status.h" #include "media/base/video_decoder_config.h" #include "media/base/waiting.h" +#include "media/mojo/mojom/renderer_extensions.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/tbm_buffer_handle.h" @@ -37,6 +38,10 @@ class MEDIA_EXPORT MediaPlayerTizenClient { virtual void OnRequestSeek(base::TimeDelta time) = 0; virtual void OnRequestSuspend(bool resource_conflict) = 0; +#if BUILDFLAG(IS_TIZEN_TV) + virtual void NotifyTrackInfoToBrowser(int active_track_id) = 0; +#endif + // MediaPlayerRendererClientExtension virtual void OnVideoSizeChange(const gfx::Size& size) = 0; virtual void OnDurationChange(base::TimeDelta duration) = 0; @@ -55,7 +60,9 @@ class MEDIA_EXPORT MediaPlayerTizenClient { #endif #if BUILDFLAG(IS_TIZEN_TV) + virtual void AddTrackInfo(media::mojom::MediaTrackInfoPtr trackinfo) = 0; virtual bool PlaybackNotificationEnabled() = 0; + virtual bool SubtitleNotificationEnabled() = 0; virtual void NotifyPlaybackState(int state, int player_id = 0, const std::string& url = "", @@ -63,6 +70,7 @@ class MEDIA_EXPORT MediaPlayerTizenClient { bool* media_resource_acquired = NULL, std::string* translated_url = NULL, std::string* drm_info = NULL) = 0; + virtual void UpdateCurrentTime(base::TimeDelta current_time) = 0; virtual void OnLivePlaybackComplete() = 0; virtual content::WebContentsDelegate* GetWebContentsDelegate() const = 0; #endif diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 964ec6e..62823cf 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -105,7 +105,9 @@ #include "public/ewk_media_downloadable_font_info.h" #include "public/ewk_media_parental_rating_info.h" #include "public/ewk_media_playback_info_product.h" +#include "public/ewk_media_subtitle_info_product.h" #include "public/ewk_user_media_internal.h" +#include "third_party/blink/public/platform/web_media_player.h" #endif #if defined(TIZEN_PEPPER_EXTENSIONS) @@ -3384,6 +3386,60 @@ void EWebView::AddDynamicCertificatePath(const std::string& host, web_contents_->AddDynamicCertificatePath(host, cert_path); } +void EWebView::NotifySubtitleState(int state, double time_stamp) { + LOG(INFO) << "subtitle state: " << state + << ",(0-Play : 1-Pause : 2-SeekStart : 3-SeekComplete : 4-Stop " + ":5-Resume)"; + switch (state) { + case blink::WebMediaPlayer::kSubtitlePause: + SmartCallback().call(); + break; + case blink::WebMediaPlayer::kSubtitleStop: + SmartCallback().call(); + break; + case blink::WebMediaPlayer::kSubtitleResume: + SmartCallback().call(); + break; + case blink::WebMediaPlayer::kSubtitleSeekStart: { + double ts = time_stamp; + SmartCallback().call(&ts); + } break; + case blink::WebMediaPlayer::kSubtitleSeekComplete: + SmartCallback().call(); + break; + default: + NOTREACHED(); + break; + } +} + +void EWebView::NotifySubtitlePlay(int active_track_id, + const char* url, + const char* lang) { + LOG(INFO) << "id:" << active_track_id << ",url:" << url << ",lang:" << lang; + Ewk_Media_Subtitle_Info* subtitle_info = + ewkMediaSubtitleInfoCreate(active_track_id, url, lang, 0); + SmartCallback().call( + static_cast(subtitle_info)); + ewkMediaSubtitleInfoDelete(subtitle_info); +} + +void EWebView::NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned int size) { + const void* buffer = static_cast(data.c_str()); + Ewk_Media_Subtitle_Data* subtitle_data = + ewkMediaSubtitleDataCreate(track_id, time_stamp, buffer, size); + SmartCallback().call( + static_cast(subtitle_data)); + ewkMediaSubtitleDataDelete(subtitle_data); +} + +void EWebView::UpdateCurrentTime(double current_time) { + current_time_ = current_time; +} + void EWebView::NotifyParentalRatingInfo(const char* info, const char* url) { LOG(INFO) << "info:" << info << ",url:" << url; Ewk_Media_Parental_Rating_Info* data = @@ -3404,6 +3460,36 @@ void EWebView::SetParentalRatingResult(const char* url, bool is_pass) { rwhva()->aura_efl_helper()->SetParentalRatingResult( static_cast(url), is_pass); } +void EWebView::NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) { + Ewk_First_Timestamp_Info* info = + ewkFirstTimeStampInfoCreate(timestamp, time_base_num, time_base_den); + SmartCallback().call( + static_cast(info)); + ewkFirstTimeStampInfoDelete(info); +} + +void EWebView::NotifyPESData(const std::string& buf, + unsigned int len, + int media_position) { + const void* data = static_cast(buf.c_str()); + Ewk_PES_Info* info = ewkPESInfoCreate(data, len, media_position); + SmartCallback().call(static_cast(info)); + ewkPESInfoDelete(info); +} + +void EWebView::SetPreferSubtitleLang(const char* lang_list) { + LOG(INFO) << "SetPreferSubtitleLang: " << lang_list; + const std::string lang(lang_list ? lang_list : ""); + + if (!rwhva()) { + LOG(ERROR) << "rwhva() is null"; + return; + } + + rwhva()->aura_efl_helper()->SetPreferSubtitleLang(lang); +} #endif bool EWebView::SetVisibility(bool enable) { diff --git a/tizen_src/ewk/efl_integration/eweb_view.h b/tizen_src/ewk/efl_integration/eweb_view.h index ccfb65b..f6bf763 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.h +++ b/tizen_src/ewk/efl_integration/eweb_view.h @@ -804,7 +804,23 @@ class EWebView { uint32_t current); void SetHighBitRate(Eina_Bool is_high_bitrate); bool IsHighBitRate() const { return is_high_bitrate_; } - + void NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den); + void NotifyPESData(const std::string& buf, + unsigned int len, + int media_position); + void SetPreferSubtitleLang(const char* lang_list); + void NotifySubtitleState(int state, double time_stamp); + void NotifySubtitlePlay(int active_track_id, + const char* url, + const char* lang); + void NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned int size); + void UpdateCurrentTime(double current_time); + double GetCurrentTime() { return current_time_; } void GetMediaDeviceList(Ewk_Media_Device_List_Get_Callback callback, void* userData); using MediaDeviceEnumeration = @@ -1024,6 +1040,7 @@ class EWebView { kPlaybackFinish, kPlaybackStop, }; + double current_time_ = 0.0; #endif std::unique_ptr<_Ewk_Back_Forward_List> back_forward_list_; diff --git a/tizen_src/ewk/efl_integration/eweb_view_callbacks.h b/tizen_src/ewk/efl_integration/eweb_view_callbacks.h index 11dea6a..0128cf1 100644 --- a/tizen_src/ewk/efl_integration/eweb_view_callbacks.h +++ b/tizen_src/ewk/efl_integration/eweb_view_callbacks.h @@ -129,6 +129,15 @@ enum CallbackType { UserMediaState, PopupMenuShow, PopupMenuHide, + SubtitlePlay, + SubtitlePause, + SubtitleStop, + SubtitleResume, + SubtitleSeekStart, + SubtitleSeekComplete, + SubtitleNotifyData, + FirstTimestamp, + PESData, #endif OverscrolledLeft, OverscrolledRight, @@ -307,6 +316,19 @@ DECLARE_EWK_VIEW_CALLBACK(PlaybackFinish, DECLARE_EWK_VIEW_CALLBACK(UserMediaState, "usermedia,state", void*); DECLARE_EWK_VIEW_CALLBACK(PopupMenuShow, "popup,menu,show", void); DECLARE_EWK_VIEW_CALLBACK(PopupMenuHide, "popup,menu,hide", void); +DECLARE_EWK_VIEW_CALLBACK(SubtitlePlay, "notify,subtitle,play", void*); +DECLARE_EWK_VIEW_CALLBACK(SubtitlePause, "notify,video,pause", void); +DECLARE_EWK_VIEW_CALLBACK(SubtitleStop, "notify,subtitle,stop", void); +DECLARE_EWK_VIEW_CALLBACK(SubtitleResume, "notify,video,resume", void); +DECLARE_EWK_VIEW_CALLBACK(SubtitleSeekStart, + "notify,subtitle,seek,start", + double*); +DECLARE_EWK_VIEW_CALLBACK(SubtitleSeekComplete, + "notify,subtitle,seek,completed", + void); +DECLARE_EWK_VIEW_CALLBACK(SubtitleNotifyData, "on,subtitle,data", void*); +DECLARE_EWK_VIEW_CALLBACK(FirstTimestamp, "on,dvb,subtitle,timestamp", void*); +DECLARE_EWK_VIEW_CALLBACK(PESData, "on,dvb,subtitle,data", void*); #endif DECLARE_EWK_VIEW_CALLBACK(OverscrolledLeft, "overscrolled,left", void); DECLARE_EWK_VIEW_CALLBACK(OverscrolledRight, "overscrolled,right", void); diff --git a/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info.cc b/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info.cc index 7c0cb73..f59fd0b 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info.cc @@ -7,61 +7,125 @@ #include "build/build_config.h" #include "private/ewk_private.h" +/* LCOV_EXCL_START */ +struct _Ewk_Media_Subtitle_Info { + int id; + const char* url; + const char* lang; + const char* label; +}; + +struct _Ewk_Media_Subtitle_Data { + int id; + double timestamp; + unsigned size; + const void* data; +}; + +struct _Ewk_First_Timestamp_Info { + unsigned long long timestamp; + int time_base_num; + int time_base_den; +}; + +struct _Ewk_PES_Info { + const void* data; + unsigned int len; + int media_position; +}; + int ewk_media_subtitle_info_id_get(Ewk_Media_Subtitle_Info *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + return data->id; +#else return 0; +#endif } const char* ewk_media_subtitle_info_url_get(Ewk_Media_Subtitle_Info *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); + return data->url; +#else return NULL; +#endif } const char* ewk_media_subtitle_info_lang_get(Ewk_Media_Subtitle_Info *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); + return data->lang; +#else return NULL; +#endif } const char* ewk_media_subtitle_info_label_get(Ewk_Media_Subtitle_Info *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); + return data->label; +#else return NULL; +#endif } int ewk_media_subtitle_data_id_get(Ewk_Media_Subtitle_Data *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + return data->id; +#else return 0; +#endif } double ewk_media_subtitle_data_timestamp_get(Ewk_Media_Subtitle_Data *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + return data->timestamp; +#else return 0; +#endif + } unsigned ewk_media_subtitle_data_size_get(Ewk_Media_Subtitle_Data *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, 0); + return data->size; +#else return 0; +#endif } const void* ewk_media_subtitle_data_get(Ewk_Media_Subtitle_Data *data) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(data, NULL); + return data->data; +#else return NULL; +#endif } +/* LCOV_EXCL_STOP */ Ewk_Media_Subtitle_Info* ewkMediaSubtitleInfoCreate(int id, const char* url, const char* lang, const char* label) { #if BUILDFLAG(IS_TIZEN_TV) - LOG_EWK_API_MOCKUP(); - return NULL; + Ewk_Media_Subtitle_Info* subtitleInfo = new Ewk_Media_Subtitle_Info; + subtitleInfo->id = id; + subtitleInfo->url = eina_stringshare_add(url ? url : ""); + subtitleInfo->lang = eina_stringshare_add(lang ? lang : ""); + subtitleInfo->label = eina_stringshare_add(label ? label : ""); + return subtitleInfo; #else - LOG_EWK_API_MOCKUP("Only for Tizen TV."); return NULL; #endif } @@ -69,28 +133,91 @@ Ewk_Media_Subtitle_Info* ewkMediaSubtitleInfoCreate(int id, const char* url, con void ewkMediaSubtitleInfoDelete(Ewk_Media_Subtitle_Info* data) { #if BUILDFLAG(IS_TIZEN_TV) - LOG_EWK_API_MOCKUP(); + if (!data) + return; + if (data->url) + eina_stringshare_del(data->url); + if (data->lang) + eina_stringshare_del(data->lang); + if (data->label) + eina_stringshare_del(data->label); + delete data; #else - LOG_EWK_API_MOCKUP("Only for Tizen TV."); + LOG(INFO)<<"Only for Tizen TV."; #endif } Ewk_Media_Subtitle_Data* ewkMediaSubtitleDataCreate(int id, double timestamp, const void* data, unsigned size) { #if BUILDFLAG(IS_TIZEN_TV) - LOG_EWK_API_MOCKUP(); - return NULL; + Ewk_Media_Subtitle_Data* subtitleData = new Ewk_Media_Subtitle_Data; + subtitleData->id = id; + subtitleData->timestamp = timestamp; + subtitleData->size = size; + subtitleData->data = eina_binshare_add_length(data, size); + return subtitleData; #else - LOG_EWK_API_MOCKUP("Only for Tizen TV."); - return NULL; + return NULL; #endif } void ewkMediaSubtitleDataDelete(Ewk_Media_Subtitle_Data* data) { #if BUILDFLAG(IS_TIZEN_TV) - LOG_EWK_API_MOCKUP(); + if (!data) + return; + if (data->data) + eina_binshare_del(data->data); + delete data; +#else + LOG(INFO)<<"Only for Tizen TV."; +#endif +} + +Ewk_First_Timestamp_Info* ewkFirstTimeStampInfoCreate(unsigned long long timestamp, + int time_base_num, + int time_base_den) { +#if BUILDFLAG(IS_TIZEN_TV) + Ewk_First_Timestamp_Info* info = new Ewk_First_Timestamp_Info; + info->timestamp = timestamp; + info->time_base_num = time_base_num; + info->time_base_den = time_base_den; + return info; +#else + return NULL; +#endif +} + +void ewkFirstTimeStampInfoDelete(Ewk_First_Timestamp_Info* info) { +#if BUILDFLAG(IS_TIZEN_TV) + delete info; #else - LOG_EWK_API_MOCKUP("Only for Tizen TV."); + LOG(INFO)<<"Only for Tizen TV."; #endif } + +Ewk_PES_Info* ewkPESInfoCreate(const void* data, + unsigned int len, + int media_position){ +#if BUILDFLAG(IS_TIZEN_TV) + Ewk_PES_Info* info = new Ewk_PES_Info; + info->data = eina_binshare_add_length(data, len); + info->len = len; + info->media_position = media_position; + return info; +#else + return NULL; +#endif +} + +void ewkPESInfoDelete(Ewk_PES_Info* info){ +#if BUILDFLAG(IS_TIZEN_TV) + if (!info) + return; + if (info->data) + eina_binshare_del(info->data); + delete info; +#else + LOG(INFO)<<"Only for Tizen TV."; +#endif +} \ No newline at end of file diff --git a/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info_product.h b/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info_product.h index 6036ad8..c02fd22 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info_product.h +++ b/tizen_src/ewk/efl_integration/public/ewk_media_subtitle_info_product.h @@ -40,6 +40,8 @@ extern "C" { #endif typedef struct _Ewk_Media_Subtitle_Info Ewk_Media_Subtitle_Info; +typedef struct _Ewk_First_Timestamp_Info Ewk_First_Timestamp_Info; +typedef struct _Ewk_PES_Info Ewk_PES_Info; /** * Get id of subtitle. @@ -125,6 +127,17 @@ const void* data, unsigned size); void ewkMediaSubtitleDataDelete(Ewk_Media_Subtitle_Data* data); +Ewk_First_Timestamp_Info* ewkFirstTimeStampInfoCreate(unsigned long long timestamp, + int time_base_num, + int time_base_den); + +void ewkFirstTimeStampInfoDelete(Ewk_First_Timestamp_Info* info); + +Ewk_PES_Info* ewkPESInfoCreate(const void* data, + unsigned int len, + int media_position); + +void ewkPESInfoDelete(Ewk_PES_Info* info); #ifdef __cplusplus } #endif diff --git a/tizen_src/ewk/efl_integration/public/ewk_settings.cc b/tizen_src/ewk/efl_integration/public/ewk_settings.cc index 5870cb3..bcbecc9 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_settings.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_settings.cc @@ -752,13 +752,25 @@ Eina_Bool ewk_settings_media_playback_notification_get(const Ewk_Settings* setti void ewk_settings_media_subtitle_notification_set(Ewk_Settings *settings, Eina_Bool enabled) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + LOG(INFO) << "subtitle notification set enabled:" << (bool)enabled; + EINA_SAFETY_ON_NULL_RETURN(settings); + settings->getPreferences().media_subtitle_notification_enabled = (bool)enabled; + ewkUpdateWebkitPreferences(settings->ewk_view()); +#else + LOG_EWK_API_MOCKUP("Only for Tizen TV"); +#endif } Eina_Bool ewk_settings_media_subtitle_notification_get(const Ewk_Settings *settings) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EINA_SAFETY_ON_NULL_RETURN_VAL(settings, EINA_FALSE); + return settings->getPreferences().media_subtitle_notification_enabled; +#else + LOG_EWK_API_MOCKUP("Only for Tizen TV"); return EINA_FALSE; +#endif } Eina_Bool ewk_settings_text_autosizing_scale_factor_set(Ewk_Settings* settings, double factor) diff --git a/tizen_src/ewk/efl_integration/public/ewk_view.cc b/tizen_src/ewk/efl_integration/public/ewk_view.cc index 8a3054f..97c6c20 100644 --- a/tizen_src/ewk/efl_integration/public/ewk_view.cc +++ b/tizen_src/ewk/efl_integration/public/ewk_view.cc @@ -1741,7 +1741,12 @@ void ewk_view_broadcast_decoder_set( void ewk_media_set_subtitle_lang(Evas_Object* ewkView, const char* lang_list) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EWK_VIEW_IMPL_GET_OR_RETURN(ewkView, impl); + impl->SetPreferSubtitleLang(lang_list); +#else + LOG_EWK_API_MOCKUP("Only for Tizen TV."); +#endif } void ewk_media_set_parental_rating_result(Evas_Object* ewkView, const char* url, Eina_Bool is_pass) @@ -1766,8 +1771,13 @@ void ewk_media_start_with_high_bit_rate(Evas_Object* ewkView, Eina_Bool high_bit double ewk_view_media_current_time_get(const Evas_Object *o) { - LOG_EWK_API_MOCKUP(); +#if BUILDFLAG(IS_TIZEN_TV) + EWK_VIEW_IMPL_GET_OR_RETURN(o, impl, 0); + return impl->GetCurrentTime(); +#else + LOG_EWK_API_MOCKUP("Only for Tizen TV."); return 0; +#endif } void ewk_view_request_canvas_fullscreen(Evas_Object* ewkView) diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc index 54d16b7..1357ccc 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.cc @@ -769,6 +769,40 @@ void WebContentsDelegateEfl::UpdateTargetURL(WebContents* /*source*/, // Update latest hovered url. last_hovered_url_ = absolute_link_url; } + +void WebContentsDelegateEfl::UpdateCurrentTime(double current_time) { + web_view_->UpdateCurrentTime(current_time); +} + +void WebContentsDelegateEfl::NotifySubtitleState(int state, double time_stamp) { + web_view_->NotifySubtitleState(state, time_stamp); +} + +void WebContentsDelegateEfl::NotifySubtitlePlay(int active_track_id, + const std::string& url, + const std::string& lang) { + web_view_->NotifySubtitlePlay(active_track_id, url.c_str(), lang.c_str()); +} + +void WebContentsDelegateEfl::NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned int size) { + web_view_->NotifySubtitleData(track_id, time_stamp, data, size); +} + +void WebContentsDelegateEfl::NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) { + return web_view_->NotifyFirstTimeStamp(timestamp, time_base_num, + time_base_den); +} + +void WebContentsDelegateEfl::NotifyPESData(const std::string& buf, + unsigned int len, + int media_position) { + return web_view_->NotifyPESData(buf, len, media_position); +} #endif void WebContentsDelegateEfl::OnGetMainFrameScrollbarVisible(int callback_id, diff --git a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h index 4e57012..a4955c8 100644 --- a/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h +++ b/tizen_src/ewk/efl_integration/web_contents_delegate_efl.h @@ -155,6 +155,21 @@ class WebContentsDelegateEfl : public WebContentsDelegate { #if BUILDFLAG(IS_TIZEN_TV) void UpdateTargetURL(WebContents* source, const GURL& url) override; void ShowInspectorPortInfo(); + void NotifyFirstTimeStamp(unsigned long long timestamp, + int time_base_num, + int time_base_den) override; + void NotifyPESData(const std::string& buf, + unsigned int len, + int media_position) override; + void UpdateCurrentTime(double current_time) override; + void NotifySubtitleState(int state, double time_stamp) override; + void NotifySubtitlePlay(int active_track_id, + const std::string& url, + const std::string& lang) override; + void NotifySubtitleData(int track_id, + double time_stamp, + const std::string& data, + unsigned int size) override; void NotifyMediaStateChanged(uint32_t type, uint32_t previous, uint32_t current) override; -- 2.7.4 From 0bf5353eaf05d4537cdc0b9621272614b6fe106c Mon Sep 17 00:00:00 2001 From: "zhishun.zhou" Date: Thu, 21 Mar 2024 11:48:44 +0800 Subject: [PATCH 02/16] fixup! [M120 Migration][HBBTV] Merge track and subtitle related patches Add missing files of inband_cue.h, inband_cue.cpp and inband_cue.idl Change-Id: I0f767db3a50528ca9bff5605d310640fd9ef79b4 Signed-off-by: zhishun.zhou --- .../blink/renderer/core/html/track/inband_cue.cpp | 35 ++++++++++++++ .../blink/renderer/core/html/track/inband_cue.h | 55 ++++++++++++++++++++++ .../blink/renderer/core/html/track/inband_cue.idl | 7 +++ 3 files changed, 97 insertions(+) create mode 100755 third_party/blink/renderer/core/html/track/inband_cue.cpp create mode 100755 third_party/blink/renderer/core/html/track/inband_cue.h create mode 100755 third_party/blink/renderer/core/html/track/inband_cue.idl diff --git a/third_party/blink/renderer/core/html/track/inband_cue.cpp b/third_party/blink/renderer/core/html/track/inband_cue.cpp new file mode 100755 index 0000000..41073f4 --- /dev/null +++ b/third_party/blink/renderer/core/html/track/inband_cue.cpp @@ -0,0 +1,35 @@ +// Copyright 2023 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/renderer/core/html/track/inband_cue.h" + +namespace blink { + +InbandCue::InbandCue(double start, double end, DOMArrayBuffer* data) + : TextTrackCue(start, end), data_(data) {} + +InbandCue::~InbandCue() {} + +#ifndef NDEBUG +String InbandCue::ToString() const { + return String::Format("%p id=%s interval=%f-->%f cue=%s)", this, + id().utf8().data(), startTime(), endTime(), + data().utf8().data()); +} +#endif + +void InbandCue::setData(DOMArrayBuffer* data) { + if (data_ == data) + return; + + CueWillChange(); + data_ = data; + CueDidChange(); +} +void InbandCue::Trace(blink::Visitor* visitor) const { + visitor->Trace(data_); + TextTrackCue::Trace(visitor); +} + +} // namespace blink diff --git a/third_party/blink/renderer/core/html/track/inband_cue.h b/third_party/blink/renderer/core/html/track/inband_cue.h new file mode 100755 index 0000000..c3ca43c --- /dev/null +++ b/third_party/blink/renderer/core/html/track/inband_cue.h @@ -0,0 +1,55 @@ +// Copyright 2023 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_INBAND_CUE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_INBAND_CUE_H_ + +#include "third_party/blink/renderer/core/html/track/text_track_cue.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" + +namespace blink { + +class InbandCue final : public TextTrackCue { + DEFINE_WRAPPERTYPEINFO(); + + public: + InbandCue(double start, double end, DOMArrayBuffer* array_buffer); + ~InbandCue() override; + + static InbandCue* Create(double start, double end, const std::string& data) { + DOMArrayBuffer* arrayBuffer = + DOMArrayBuffer::Create(data.c_str(), data.length()); + return MakeGarbageCollected(start, end, arrayBuffer); + } + + DOMArrayBuffer* data() const { return data_.Get(); } + void setData(DOMArrayBuffer* data); + + void UpdateDisplay(HTMLDivElement& container) override{}; + + void UpdatePastAndFutureNodes(double movieTime) override{}; + + void RemoveDisplayTree(RemovalNotification) override{}; + + ExecutionContext* GetExecutionContext() const override { return nullptr; } + void Trace(blink::Visitor*) const override; + + absl::optional GetNextIntraCueTime(double movie_time) const override { + return absl::nullopt; + }; + + void OnEnter(HTMLMediaElement& video) override{}; + void OnExit(HTMLMediaElement& video) override{}; + +#ifndef NDEBUG + String ToString() const override; +#endif + + private: + Member data_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_HTML_TRACK_INBAND_CUE_H_ diff --git a/third_party/blink/renderer/core/html/track/inband_cue.idl b/third_party/blink/renderer/core/html/track/inband_cue.idl new file mode 100755 index 0000000..bef5ebc --- /dev/null +++ b/third_party/blink/renderer/core/html/track/inband_cue.idl @@ -0,0 +1,7 @@ +// Copyright 2023 Samsung Electronics Inc. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +[Exposed=Window] +interface InbandCue : TextTrackCue { + attribute ArrayBuffer data; +}; -- 2.7.4 From b145838ffc9cf7d369eca8a7c1f45107a3775ca4 Mon Sep 17 00:00:00 2001 From: sidpaswan Date: Wed, 20 Mar 2024 19:13:20 +0530 Subject: [PATCH 03/16] fixup! Fix for Geolocation webTCT failures This patch set |position->accuracy| directly instead of doing it through |position_ptr->get_position()->accuracy| Change-Id: Id1db11d8f7f08b47339928a66a2aeac2822158d3 Signed-off-by: sidpaswan --- .../efl_integration/browser/geolocation/location_provider_efl.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tizen_src/ewk/efl_integration/browser/geolocation/location_provider_efl.cc b/tizen_src/ewk/efl_integration/browser/geolocation/location_provider_efl.cc index ac21bf1..1c73383 100644 --- a/tizen_src/ewk/efl_integration/browser/geolocation/location_provider_efl.cc +++ b/tizen_src/ewk/efl_integration/browser/geolocation/location_provider_efl.cc @@ -74,13 +74,14 @@ void LocationProviderEfl::NotifyPositionChanged(double latitude, position->speed = KilometerPerHourToMeterPerSecond(speed); position->heading = direction; + location_accuracy_level_e level; + location_manager_get_last_accuracy(location_manager_, &level, + &position->accuracy, + &position->altitude_accuracy); + auto position_ptr = mojom::GeopositionResult::NewPosition(std::move(position)); - location_accuracy_level_e level; - location_manager_get_last_accuracy( - location_manager_, &level, &(position_ptr->get_position()->accuracy), - &(position_ptr->get_position()->altitude_accuracy)); base::OnceClosure task = base::BindOnce(&LocationProviderEfl::NotifyCallback, base::Unretained(this), std::move(position_ptr)); -- 2.7.4 From dc040ada5512bfacb5a6c65399e22d0f70659bbc Mon Sep 17 00:00:00 2001 From: Rohit Kumar Date: Wed, 20 Mar 2024 14:48:20 +0530 Subject: [PATCH 04/16] [M120 Migration] Build libchromium-impl.so with chrome implementation This patch builds libchromium-impl.so inlcude chrome implementation and chrome_tizen as chrome main executable when |--build-chrome| option is given. Plus, gbs root and out directory are seperated. Reference: https://review.tizen.org/gerrit/303499 https://review.tizen.org/gerrit/306836 https://review.tizen.org/gerrit/305200 Change-Id: Ie7718fa71ff361932e07eddb2651fcc7a4a3a6c2 Signed-off-by: Rohit Kumar --- build/config/BUILD.gn | 4 - build/config/linux/libffi/BUILD.gn | 6 +- chrome/BUILD.gn | 86 +++++++++++++++ .../content/renderer/password_autofill_agent.cc | 5 +- components/autofill_strings.grdp | 2 +- components/components_strings.grd | 14 +-- components/omnibox_strings.grdp | 4 +- components/password_manager_strings.grdp | 2 + components/policy_strings.grdp | 4 +- components/version_ui_strings.grdp | 4 +- content/browser/browser_interface_binders.cc | 6 +- .../render_frame_audio_input_stream_factory.cc | 2 +- .../renderer_host/render_process_host_impl.cc | 2 +- device/bluetooth/BUILD.gn | 2 +- .../shell/browser/certificate_manager_model.cc | 4 + electron/shell/browser/certificate_manager_model.h | 4 + headless/BUILD.gn | 2 +- packaging/chromium-efl.spec | 120 ++++++++++----------- printing/printing_context_linux.cc | 6 +- services/device/geolocation/location_arbitrator.cc | 2 +- .../modulescript/document_module_script_fetcher.cc | 2 +- tizen_src/build/common.sh | 8 +- tizen_src/build/config/tizen_features.gni | 2 +- tizen_src/downloadable/ewk_interface_main.cc | 12 +++ tizen_src/ewk/chromium-ewk.filter | 2 + tizen_src/ewk/efl_integration/BUILD.gn | 4 +- .../pepper/pepper_shared_memory_message_filter.cc | 4 + .../pepper/pepper_shared_memory_message_filter.h | 4 + tools/grit/grit_args.gni | 3 + wrt/BUILD.gn | 93 +++++++++------- 30 files changed, 270 insertions(+), 145 deletions(-) diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn index 6f5ac4f..7b48894 100644 --- a/build/config/BUILD.gn +++ b/build/config/BUILD.gn @@ -221,10 +221,6 @@ config("default_libs") { "rt", ] - if (is_tizen && is_clang) { - libs += [ "atomic" ] - ldflags = [ "-Wl,-rpath=/usr/local/lib/" ] - } } } diff --git a/build/config/linux/libffi/BUILD.gn b/build/config/linux/libffi/BUILD.gn index 7052491..771170c 100644 --- a/build/config/linux/libffi/BUILD.gn +++ b/build/config/linux/libffi/BUILD.gn @@ -3,9 +3,6 @@ # found in the LICENSE file. import("//build/config/linux/pkg_config.gni") -if (use_efl) { - import("//tizen_src/build/config/tizen_features.gni") -} declare_args() { # Controls whether the build should use the version of libffi library shipped @@ -13,8 +10,7 @@ declare_args() { # on Linux, libffi must be statically linked to prevent a situation where the # runtime version of libffi is different from the build-time version from the # sysroot. - use_system_libffi = - default_toolchain == "//build/toolchain/cros:target" || build_chrome + use_system_libffi = default_toolchain == "//build/toolchain/cros:target" } if (use_system_libffi) { diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn index ea0b7d9..2131b35 100644 --- a/chrome/BUILD.gn +++ b/chrome/BUILD.gn @@ -1457,6 +1457,92 @@ if (is_win) { group("chrome_dsym_archive") { } } +} else if (is_tizen) { + executable("chrome_tizen") { + testonly = true + deps = [ "//tizen_src/ewk/efl_integration:libchromium-ewk" ] + sources = [ + "app/chrome_exe_main_aura.cc", + "app/chrome_exe_resource.h", + ] + ldflags = [ + "-pie", + "-Wl,--export-dynamic", + ] + cflags = [ "-fPIC" ] + configs += [ "//tizen_src/build/config/tizen:executable_config" ] + } + + static_library("chrome_lib") { + sources = [ "app/chrome_exe_resource.h" ] + defines = [] + public_deps = [] + deps = [ + "//build:chromeos_buildflags", + "//printing/buildflags", + ] + data = [ "$root_out_dir/resources.pak" ] + data_deps = [] + + sources += [ + "app/chrome_dll_resource.h", + "app/chrome_main.cc", + "app/chrome_main_delegate.cc", + "app/chrome_main_delegate.h", + "app/chrome_main_linux.cc", + "app/chrome_main_linux.h", + ] + + deps += [ + # On Linux, link the dependencies (libraries) that make up actual + # Chromium functionality directly into the executable. + ":dependencies", + + # For configuring PartitionAlloc + "//base/allocator:buildflags", + + # For the sampling profiler. + "//chrome/common/profiler", + + # Needed to use the master_preferences functions + "//chrome/installer/util:with_no_strings", + "//content/public/app", + + # For headless mode. + "//headless:headless_shell_lib", + ] + + public_deps = [ "//chrome/common:buildflags" ] + + if (!is_fuchsia) { + public_deps += [ + ":xdg_mime", # Needs to be public for installer to consume files. + ] + + data_deps += [ "//components/crash/core/app:chrome_crashpad_handler" ] + } + + ldflags = [] + + if ((is_linux || is_chromeos_lacros) && !is_component_build && + !using_sanitizer) { + version_script = "//build/linux/chrome.map" + inputs = [ version_script ] + ldflags += [ "-Wl,--version-script=" + + rebase_path(version_script, root_build_dir) ] + } + + # These files are used by the installer so we need a public dep. + public_deps += [ ":packed_resources" ] + + # The step's output are needed at runtime, so we also need a data_dep. + data_deps += [ ":packed_resources" ] + + data_deps += [ + "//chrome/browser/resources/media/mei_preload:component", + "//third_party/widevine/cdm", + ] + } } group("dependencies") { diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc index 723b3ef..295ac32 100644 --- a/components/autofill/content/renderer/password_autofill_agent.cc +++ b/components/autofill/content/renderer/password_autofill_agent.cc @@ -2372,14 +2372,11 @@ bool PasswordAutofillAgent::SupportAutoLogin() { // org.tizen.browser, com.samsung.tv.knox-browser // Only org.tizen.browser app need AutoLogin behavior according to their spec. // The latter just wants Autofill. -#if defined(BUILD_CHROME) - return false; -#else + const std::string tizen_app_id = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kTizenAppId); return tizen_app_id == "org.tizen.browser"; -#endif } #endif diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp index 55754a3..4d331f3 100644 --- a/components/autofill_strings.grdp +++ b/components/autofill_strings.grdp @@ -23,7 +23,7 @@ - + Remove copy diff --git a/components/components_strings.grd b/components/components_strings.grd index fb29e4b..5d2e302 100644 --- a/components/components_strings.grd +++ b/components/components_strings.grd @@ -285,7 +285,7 @@ - + @@ -295,14 +295,14 @@ - + - + @@ -336,7 +336,7 @@ - + @@ -361,7 +361,7 @@ - + Cancel @@ -382,7 +382,7 @@ OK - + Reload @@ -528,7 +528,7 @@ JSON Parser - + Restore diff --git a/components/omnibox_strings.grdp b/components/omnibox_strings.grdp index bee4840..bba574c 100644 --- a/components/omnibox_strings.grdp +++ b/components/omnibox_strings.grdp @@ -32,7 +32,7 @@ Image you copied - + $1Paypal Inc. [$2US] @@ -64,7 +64,7 @@ Search or type URL - + $1 - $2 diff --git a/components/password_manager_strings.grdp b/components/password_manager_strings.grdp index 32d04bf..13dd105 100644 --- a/components/password_manager_strings.grdp +++ b/components/password_manager_strings.grdp @@ -87,6 +87,8 @@ Suggest Strong Password… + + Never saved diff --git a/components/policy_strings.grdp b/components/policy_strings.grdp index 0130f34..29a7fab 100644 --- a/components/policy_strings.grdp +++ b/components/policy_strings.grdp @@ -387,7 +387,7 @@ Additional details: Policies is loaded - + Export to JSON @@ -614,7 +614,7 @@ Additional details: Device local account override - + Full Admin Access diff --git a/components/version_ui_strings.grdp b/components/version_ui_strings.grdp index 89453a3..b55edca 100644 --- a/components/version_ui_strings.grdp +++ b/components/version_ui_strings.grdp @@ -1,6 +1,6 @@ - + About Version @@ -11,7 +11,7 @@ Developer Build - + (32-bit) diff --git a/content/browser/browser_interface_binders.cc b/content/browser/browser_interface_binders.cc index 9899337..df54bce 100644 --- a/content/browser/browser_interface_binders.cc +++ b/content/browser/browser_interface_binders.cc @@ -247,8 +247,8 @@ #include "third_party/blink/public/mojom/badging/badging.mojom.h" #endif -#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP) -#include "tizen_src/chromium_impl/components/xwalk_extensions/browser/xwalk_extension_manager.h" +#if BUILDFLAG(IS_TIZEN) +#include "components/xwalk_extensions/browser/xwalk_extension_manager.h" #endif namespace blink { @@ -1416,7 +1416,7 @@ void PopulateDedicatedWorkerBinders(DedicatedWorkerHost* host, host->GetAncestorRenderFrameHostId(), RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker, host)); -#if BUILDFLAG(IS_TIZEN) && !defined(EWK_BRINGUP) +#if BUILDFLAG(IS_TIZEN) map->Add(base::BindRepeating( &wrt::XWalkExtensionManager::Bind)); #endif diff --git a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc index 6af445d..0e0488e 100644 --- a/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc +++ b/content/browser/renderer_host/media/render_frame_audio_input_stream_factory.cc @@ -163,7 +163,7 @@ class RenderFrameAudioInputStreamFactory::Core final const std::string& raw_output_device_id); #if BUILDFLAG(IS_TIZEN_TV) - void OnMediaStateChanged(uint32_t previous, uint32_t current); + void OnMediaStateChanged(uint32_t previous, uint32_t current) final; void NotifyMediaStateChanged(uint32_t previous, uint32_t current); #endif diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 8d834f5..ec8e9ec 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -3569,7 +3569,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDiscardableMemoryLimit, switches::kDiscardableMemoryPurgeDelay, #endif -#if BUILDFLAG(IS_TIZEN_TV) && !defined(BUILD_CHROME) +#if BUILDFLAG(IS_TIZEN_TV) switches::kTizenAppId, switches::kXWalkExtensionPath, #endif diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 978a59f..847c3e9 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn @@ -46,7 +46,7 @@ source_set("deprecated_experimental_mojo") { "socket.h", ] - if (is_chromeos || is_linux || is_tizen) { + if (is_chromeos || is_linux) { sources += [ "bluez/metrics_recorder.cc", "bluez/metrics_recorder.h", diff --git a/electron/shell/browser/certificate_manager_model.cc b/electron/shell/browser/certificate_manager_model.cc index e2c09a5..78cc91b 100644 --- a/electron/shell/browser/certificate_manager_model.cc +++ b/electron/shell/browser/certificate_manager_model.cc @@ -45,6 +45,8 @@ net::NSSCertDatabase* GetNSSCertDatabaseForResourceContext( } // namespace +namespace electron { + // CertificateManagerModel is created on the UI thread. It needs a // NSSCertDatabase handle (and on ChromeOS it needs to get the TPM status) which // needs to be done on the IO thread. @@ -167,3 +169,5 @@ void CertificateManagerModel::GetCertDBOnIOThread( if (cert_db) std::move(split_callback.second).Run(cert_db); } + +} // namespace electron diff --git a/electron/shell/browser/certificate_manager_model.h b/electron/shell/browser/certificate_manager_model.h index 91f7f3c..a6c2fe8 100644 --- a/electron/shell/browser/certificate_manager_model.h +++ b/electron/shell/browser/certificate_manager_model.h @@ -18,6 +18,8 @@ class BrowserContext; class ResourceContext; } // namespace content +namespace electron { + // CertificateManagerModel provides the data to be displayed in the certificate // manager dialog, and processes changes from the view. class CertificateManagerModel { @@ -114,4 +116,6 @@ class CertificateManagerModel { bool is_user_db_available_; }; +} // namespace electron + #endif // ELECTRON_SHELL_BROWSER_CERTIFICATE_MANAGER_MODEL_H_ diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 1fc8258..dadca05 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn @@ -862,7 +862,7 @@ static_library("headless_shell_lib") { ] defines = [] - if (!is_component_build) { + if (!is_component_build && !build_chrome) { sources += [ "lib/utility/headless_content_utility_client.cc", "lib/utility/headless_content_utility_client.h", diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index 07a9f5c..ccc8e52 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -537,7 +537,6 @@ touch ./tizen_src/downloadable/ewk_api_wrapper_generator.py "build_chrome=true" \ %else "build_chrome=false" \ - "ozone_auto_platforms=false" \ %endif %if "%{?tizen_profile_name}" == "tv" "lib_dir_path=\"%{_libdir}\"" \ @@ -548,9 +547,12 @@ touch ./tizen_src/downloadable/ewk_api_wrapper_generator.py %if 0%{?__enable_ewk_interface} "enable_ewk_interface=true" \ %endif + "ozone_auto_platforms=false" \ "enable_wrt_js=%{macro_to_bool __enable_wrt_js}" \ +%if 0%{?__enable_wrt_js} "xwalk_extension_path=\"%{__xwalk_extension_path}\"" \ "xwalk_extension_service_path=\"%{__xwalk_extension_service_path}\"" \ +%endif %if %{__enable_network_camera} "enable_network_camera=true" \ %endif @@ -579,11 +581,10 @@ ninja %{_smp_mflags} -C "%{OUTPUT_FOLDER}" \ %if 0%{?__enable_squashfs_image} && "%{?tizen_profile_name}" == "tv" chromium-efl-install \ %endif -%if %{__build_chrome} == 1 - content_shell chrome -%else - efl_webprocess chromium-ewk efl_webview_app mini_browser ubrowser +%if 0%{?__build_chrome} + chrome_tizen \ %endif + efl_webprocess chromium-ewk efl_webview_app mini_browser ubrowser %if 0%{?_enable_unittests} ninja %{_smp_mflags} -C"%{OUTPUT_FOLDER}" angle_unittests env_chromium_unittests cacheinvalidation_unittests \ @@ -704,22 +705,17 @@ install -m 0644 %{_libdir}/libscl-common.so "%{buildroot}"%{_libdir} %endif %if %{__build_chrome} == 1 - install -m 0755 "%{OUTPUT_FOLDER}"/content_shell "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/ - sed 's#@binary@#%{CHROMIUM_LIB_DIR}/bin/content_shell#' %{SOURCE1} > "%{buildroot}"%{_bindir}/content_shell - - install -m 0755 "%{OUTPUT_FOLDER}"/chrome "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/chrome - sed 's#@binary@#%{CHROMIUM_LIB_DIR}/bin/chrome#' %{SOURCE1} > "%{buildroot}"%{_bindir}/chrome - + install -m 0755 "%{OUTPUT_FOLDER}"/chrome_tizen "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/chrome_tizen + sed 's#@binary@#%{CHROMIUM_LIB_DIR}/bin/chrome_tizen#' %{SOURCE1} > "%{buildroot}"%{_bindir}/chrome_tizen install -m 0755 "%{OUTPUT_FOLDER}"/chrome_crashpad_handler "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/chrome_crashpad_handler sed 's#@binary@#%{CHROMIUM_LIB_DIR}/bin/chrome_crashpad_handler#' %{SOURCE1} > "%{buildroot}"%{_bindir}/chrome_crashpad_handler - install -m 0644 "%{OUTPUT_FOLDER}"/ui_resources_100_percent.pak "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/ install -m 0644 "%{OUTPUT_FOLDER}"/locales/*.pak "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/locales install -m 0644 "%{OUTPUT_FOLDER}"/chrome_100_percent.pak "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/ install -m 0644 "%{OUTPUT_FOLDER}"/resources.pak "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/ - - install -m 0755 "%{OUTPUT_FOLDER}"/libminigbm.so "%{buildroot}"%{_libdir} %else install -m 0644 "%{OUTPUT_FOLDER}"/locales/efl/*.pak "%{buildroot}"%{CHROMIUM_LIB_DIR}/bin/locales/ +%endif + install -m 0755 "%{OUTPUT_FOLDER}"/libtest_trace_processor.so "%{buildroot}"%{_libdir} install -m 0755 "%{OUTPUT_FOLDER}"/efl_webprocess "%{buildroot}"%{_bindir}/ %if "%{?profile}" == "tv" @@ -748,16 +744,15 @@ install -m 0644 %{_libdir}/libscl-common.so "%{buildroot}"%{_libdir} %endif %endif - # org.tizen.chromium-efl Tizen App package - install -m 0755 "%{OUTPUT_FOLDER}"/efl_webview_app "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ - install -m 0755 "%{OUTPUT_FOLDER}"/mini_browser "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ - install -m 0755 "%{OUTPUT_FOLDER}"/ubrowser "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ +# org.tizen.chromium-efl Tizen App package +install -m 0755 "%{OUTPUT_FOLDER}"/efl_webview_app "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ +install -m 0755 "%{OUTPUT_FOLDER}"/mini_browser "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ +install -m 0755 "%{OUTPUT_FOLDER}"/ubrowser "%{buildroot}"%{CHROMIUM_APP_DIR}/bin/ - %if 0%{?__enable_ewk_interface} - install -m 0644 "%{OUTPUT_FOLDER}"/libchromium-impl.so "%{buildroot}"%{CHROMIUM_LIB_DIR}/lib/ - %else - install -m 0644 "%{OUTPUT_FOLDER}"/libchromium-ewk.so "%{buildroot}"%{CHROMIUM_LIB_DIR}/lib/ - %endif +%if 0%{?__enable_ewk_interface} + install -m 0644 "%{OUTPUT_FOLDER}"/libchromium-impl.so "%{buildroot}"%{CHROMIUM_LIB_DIR}/lib/ +%else + install -m 0644 "%{OUTPUT_FOLDER}"/libchromium-ewk.so "%{buildroot}"%{CHROMIUM_LIB_DIR}/lib/ %endif install -m 0644 "%{OUTPUT_FOLDER}"/resources/*.edj "%{buildroot}"%{CHROMIUM_LIB_DIR}/res/themes/ @@ -782,10 +777,7 @@ install -m 0644 "%{OUTPUT_FOLDER}"/tizen-manifest.xml "%{buildroot}"%{_xmldir}/% %define tizen_dist_sign 1 %endif -%if %{__build_chrome} != 1 install -m 0644 "%{OUTPUT_FOLDER}"/images/*.png "%{buildroot}"%{CHROMIUM_LIB_DIR}/res/images/ -%endif - install -m 0644 "%{OUTPUT_FOLDER}"/resources/*.edj "%{buildroot}"%{CHROMIUM_LIB_DIR}/res/themes/ %if "%{?__use_system_icu}" != "1" @@ -817,12 +809,10 @@ install -m 0644 tizen_src/ewk/efl_integration/public/*.h "%{buildroot}"%{_includ install -d "%{buildroot}"%{_includedir}/v8 install -m 0644 v8/include/*.h "%{buildroot}"%{_includedir}/v8/ -%if %{__build_chrome} != 1 - # The native applications using ewk API from Tizen 2.x have a dependency about libewebkit2.so. - # The chromium-efl should support the backward compatibility of the native applications. - ln -s %{_libdir}/libchromium-ewk.so %{buildroot}%{_libdir}/libewebkit2.so.0 - ln -s %{_libdir}/libewebkit2.so.0 %{buildroot}%{_libdir}/libewebkit2.so -%endif +# The native applications using ewk API from Tizen 2.x have a dependency about libewebkit2.so. +# The chromium-efl should support the backward compatibility of the native applications. +ln -s %{_libdir}/libchromium-ewk.so %{buildroot}%{_libdir}/libewebkit2.so.0 +ln -s %{_libdir}/libewebkit2.so.0 %{buildroot}%{_libdir}/libewebkit2.so %if 0%{?__make_squashfs_rpm} install -d "%{buildroot}"%{CHROMIUM_APP_DIR}/res @@ -937,6 +927,8 @@ install -m 0755 -p -D %{OUTPUT_FOLDER}/ppapi_unittests %{buildroot}/opt/usr/utc_ install -m 644 -D $file %{buildroot}%{CHROMIUM_LIB_DIR}/res/locale/${file#%{__wrt_localedir}} done + install -m 0644 %{OUTPUT_FOLDER}/gen/wrt/resources/*.edj %{buildroot}%{CHROMIUM_LIB_DIR}/res/themes/ + install -d %{buildroot}/etc/notstrip/ install -m 644 packaging/wrt.notstrip %{buildroot}/etc/notstrip/wrt.notstrip %if 0%{?__generate_tpk} @@ -1100,15 +1092,11 @@ rm -rf %{CHROMIUM_TPK_DIR}/%{_tpk_file_name}.tpk %if %{__build_chrome} == 1 %{CHROMIUM_LIB_DIR}/bin/chrome_100_percent.pak %{CHROMIUM_LIB_DIR}/bin/resources.pak - %{CHROMIUM_LIB_DIR}/bin/ui_resources_100_percent.pak - %{CHROMIUM_LIB_DIR}/bin/content_shell - %{_bindir}/content_shell - %{CHROMIUM_LIB_DIR}/bin/chrome - %{_bindir}/chrome + %{CHROMIUM_LIB_DIR}/bin/chrome_tizen + %{_bindir}/chrome_tizen %{CHROMIUM_LIB_DIR}/bin/chrome_crashpad_handler %{_bindir}/chrome_crashpad_handler - %{_libdir}/libminigbm.so -%else +%endif %{CHROMIUM_LIB_DIR}/res/locale/* %{_libdir}/libchromium-ewk.so %{_libdir}/libtest_trace_processor.so @@ -1116,33 +1104,37 @@ rm -rf %{CHROMIUM_TPK_DIR}/%{_tpk_file_name}.tpk %if 0%{?__enable_squashfs_image} %if "%{?tizen_profile_name}" == "tv" %{_bindir}/chromium-efl-install - %{_unitdir_user}/chromium-efl-vd.service - %{_unitdir_user}/default.target.wants/chromium-efl-vd.service - %dir %{CHROMIUM_LIB_UPGRADE_DIR} - %else - %{_unitdir}/chromium-efl.service - %{_unitdir}/multi-user.target.wants/chromium-efl.service - %{_unitdir}/chromium-efl-update.service - %{_unitdir}/multi-user.target.wants/chromium-efl-update.service - %endif - %endif - %{CHROMIUM_APP_DIR}/bin/efl_webview_app - %{CHROMIUM_APP_DIR}/bin/mini_browser - %{CHROMIUM_APP_DIR}/bin/ubrowser - - %if "%{?tizen_profile_name}" == "tv" - %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/efl_webprocess - %{_bindir}/efl_pluginprocess - %else - %{_bindir}/efl_webprocess - %endif - %if 0%{?__enable_ewk_interface} - %{CHROMIUM_LIB_DIR}/lib/libchromium-impl.so + %{_unitdir_user}/chromium-efl-vd.service + %{_unitdir_user}/default.target.wants/chromium-efl-vd.service + %dir %{CHROMIUM_LIB_UPGRADE_DIR} %else - %{CHROMIUM_LIB_DIR}/lib/libchromium-ewk.so + %{_unitdir}/chromium-efl.service + %{_unitdir}/multi-user.target.wants/chromium-efl.service + %{_unitdir}/chromium-efl-update.service + %{_unitdir}/multi-user.target.wants/chromium-efl-update.service %endif - %{CHROMIUM_LIB_DIR}/res/images/*.png %endif +%{CHROMIUM_APP_DIR}/bin/efl_webview_app +%{CHROMIUM_APP_DIR}/bin/mini_browser +%{CHROMIUM_APP_DIR}/bin/ubrowser + +%if "%{?tizen_profile_name}" == "tv" + %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/efl_webprocess + %{_bindir}/efl_pluginprocess +%else + %{_bindir}/efl_webprocess +%endif + +%if 0%{?__enable_ewk_interface} + %{CHROMIUM_LIB_DIR}/lib/libchromium-impl.so +%else + %{CHROMIUM_LIB_DIR}/lib/libchromium-ewk.so +%endif + +%{CHROMIUM_LIB_DIR}/res/images/*.png + +%{CHROMIUM_LIB_DIR}/res/themes/*.edj +%{CHROMIUM_LIB_DIR}/res/locale %if "%{?__use_system_icu}" != "1" %{CHROMIUM_LIB_DIR}/bin/icudtl.dat @@ -1157,7 +1149,7 @@ rm -rf %{CHROMIUM_TPK_DIR}/%{_tpk_file_name}.tpk %endif %else %{_bindir}/wrt - %endif +%endif %{_bindir}/wrt-client %{_sysconfdir}/profile.d/wrt_env.sh %if %{__build_chrome} != 1 diff --git a/printing/printing_context_linux.cc b/printing/printing_context_linux.cc index 2bb8fbf..73fe985 100644 --- a/printing/printing_context_linux.cc +++ b/printing/printing_context_linux.cc @@ -72,7 +72,7 @@ mojom::ResultCode PrintingContextLinux::UseDefaultSettings() { ResetSettings(); -#if BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_TIZEN) if (!ui::LinuxUi::instance()) return mojom::ResultCode::kSuccess; @@ -88,7 +88,7 @@ mojom::ResultCode PrintingContextLinux::UseDefaultSettings() { } gfx::Size PrintingContextLinux::GetPdfPaperSizeDeviceUnits() { -#if BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_TIZEN) if (ui::LinuxUi::instance()) return ui::LinuxUi::instance()->GetPdfPaperSize(this); #endif @@ -101,7 +101,7 @@ mojom::ResultCode PrintingContextLinux::UpdatePrinterSettings( DCHECK(!printer_settings.show_system_dialog); DCHECK(!in_print_job_); -#if BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_TIZEN) if (!ui::LinuxUi::instance()) return mojom::ResultCode::kSuccess; diff --git a/services/device/geolocation/location_arbitrator.cc b/services/device/geolocation/location_arbitrator.cc index 6ef49eb..cf3b855 100644 --- a/services/device/geolocation/location_arbitrator.cc +++ b/services/device/geolocation/location_arbitrator.cc @@ -198,7 +198,7 @@ LocationArbitrator::NewNetworkLocationProvider( std::unique_ptr LocationArbitrator::NewSystemLocationProvider() { -#if BUILDFLAG(IS_TIZEN) && !defined(BUILD_CHROME) +#if BUILDFLAG(IS_TIZEN) if (base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableOffscreenRendering)) { return device::NewSystemLocationProvider(main_task_runner_, diff --git a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc index a51bb34..a0f074f 100644 --- a/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc +++ b/third_party/blink/renderer/core/loader/modulescript/document_module_script_fetcher.cc @@ -37,7 +37,7 @@ void DocumentModuleScriptFetcher::Fetch( DCHECK(!client_); client_ = client; expected_module_type_ = expected_module_type; -#if defined(ENABLE_WRT_JS) && !defined(BUILD_CHROME) +#if defined(ENABLE_WRT_JS) if (wrt::WRTModuleScriptFetcher::Fetch(fetch_params, client)) return; #endif diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index c0b3c33..1dd2645 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -242,6 +242,7 @@ function setupAndExecuteTargetBuild() { local LOCAL_BUILD=1 local RELEASE_BUILD=0 local MAKE_SQUASHFS_RPM=0 + local BUILD_CHROME=0 # "|| :" means "or always succeeding built-in command" PROFILE=$(echo "$@" | grep -Po "(?<=\-P\s)[^\s]*" | head -1 || :) @@ -313,6 +314,7 @@ function setupAndExecuteTargetBuild() { --tizen*) ;; --build-chrome) + BUILD_CHROME=1 ARGS+=(--define "_build_chrome 1") ;; *) @@ -388,7 +390,11 @@ function setupAndExecuteTargetBuild() { if [ "$USE_GLOBAL_GBS_CONF" == "" ]; then CONF_FLAG="--conf ${SCRIPTDIR}/gbs.conf" if [ "$GBS_ROOT" == "" ]; then - GBS_ROOT_OPT="-B ~/GBS-ROOT-M${CHROMIUM_VERSION}-${PROFILE^^}-TIZEN_${DEFAULT_TIZEN_VERSION^^}-${BRANCH^^}" + if [ "$BUILD_CHROME" == "1" ]; then + GBS_ROOT_OPT="-B ~/GBS-ROOT-M${CHROMIUM_VERSION}-${PROFILE^^}-TIZEN_${DEFAULT_TIZEN_VERSION^^}-CHROME-${BRANCH^^}" + else + GBS_ROOT_OPT="-B ~/GBS-ROOT-M${CHROMIUM_VERSION}-${PROFILE^^}-TIZEN_${DEFAULT_TIZEN_VERSION^^}-${BRANCH^^}" + fi else GBS_ROOT_OPT="-B $GBS_ROOT" fi diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index afc058c..c754301 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -76,7 +76,7 @@ declare_args() { drm_mapi_aarch_64 = false } -if (use_efl && !build_chrome) { +if (use_efl) { tizen_autofill = true if (tizen_product_tv) { tizen_autofill_fw = true diff --git a/tizen_src/downloadable/ewk_interface_main.cc b/tizen_src/downloadable/ewk_interface_main.cc index cf16835..2857e01 100644 --- a/tizen_src/downloadable/ewk_interface_main.cc +++ b/tizen_src/downloadable/ewk_interface_main.cc @@ -470,6 +470,18 @@ int WRTServiceMain(int argc, char** argv) { } #endif +#if defined(BUILD_CHROME) +__attribute__((visibility("default"))) int ChromeMain(int argc, + const char** argv) { + LOG(INFO) << "EWK-INTERFACE : ChromeMain called.."; + typedef int (*func_ptr_t)(int argc, const char** argv); + func_ptr_t fp = reinterpret_cast(ewk_dlsym("ChromeMain")); + if (fp) + return fp(argc, argv); + return 0; +} +#endif // defined(BUILD_CHROME) + #ifdef __cplusplus } #endif diff --git a/tizen_src/ewk/chromium-ewk.filter b/tizen_src/ewk/chromium-ewk.filter index 18a1d58..52f4727 100644 --- a/tizen_src/ewk/chromium-ewk.filter +++ b/tizen_src/ewk/chromium-ewk.filter @@ -42,6 +42,8 @@ WRTServiceMain; ime_app_main; node_module_register; + # CHROMIUM BROWSER + ChromeMain; local: *; }; diff --git a/tizen_src/ewk/efl_integration/BUILD.gn b/tizen_src/ewk/efl_integration/BUILD.gn index 2a2f56e..b09d396 100644 --- a/tizen_src/ewk/efl_integration/BUILD.gn +++ b/tizen_src/ewk/efl_integration/BUILD.gn @@ -115,7 +115,9 @@ shared_library("chromium-ewk") { "//ui/views:test_support", "//v8", ] - + if (build_chrome && is_tizen) { + deps += [ "//chrome:chrome_lib" ] + } if (enable_basic_printing) { deps += [ "//printing" ] } diff --git a/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.cc b/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.cc index 987c2c6..1fd507c 100644 --- a/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.cc +++ b/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.cc @@ -21,6 +21,8 @@ #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/var_tracker.h" +namespace pepper { + PepperSharedMemoryMessageFilter::PepperSharedMemoryMessageFilter( content::RendererPpapiHost* host) : InstanceMessageFilter(host->GetPpapiHost()), host_(host) {} @@ -63,3 +65,5 @@ void PepperSharedMemoryMessageFilter::OnHostMsgCreateSharedMemory( ->GetVarTracker() ->TrackSharedMemoryRegion(instance, std::move(shm), size); } + +} // namespace pepper diff --git a/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.h b/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.h index c425868..11b224b 100644 --- a/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.h +++ b/tizen_src/ewk/efl_integration/renderer/pepper/pepper_shared_memory_message_filter.h @@ -25,6 +25,8 @@ class SerializedHandle; } } // namespace ppapi +namespace pepper { + // Implements the backend for shared memory messages from a plugin process. class PepperSharedMemoryMessageFilter : public ppapi::host::InstanceMessageFilter { @@ -48,4 +50,6 @@ class PepperSharedMemoryMessageFilter content::RendererPpapiHost* host_; }; +} // namespace pepper + #endif // RENDERER_PEPPER_PEPPER_SHARED_MEMORY_MESSAGE_FILTER_H_ diff --git a/tools/grit/grit_args.gni b/tools/grit/grit_args.gni index 52f0fc5..eadb5a3 100644 --- a/tools/grit/grit_args.gni +++ b/tools/grit/grit_args.gni @@ -6,6 +6,7 @@ import("//build/config/chrome_build.gni") import("//build/config/chromeos/ui_mode.gni") import("//build/config/devtools.gni") import("//build/config/ui.gni") +import("//tizen_src/build/config/tizen_features.gni") shared_intermediate_dir = rebase_path(root_gen_dir, root_build_dir) devtools_grd_path = "$shared_intermediate_dir/$devtools_grd_location" @@ -33,6 +34,8 @@ _grit_defines = [ "toolkit_views=${toolkit_views}", "use_aura=${use_aura}", "use_ozone=${use_ozone}", + "is_tizen=${is_tizen}", + "build_chrome=${build_chrome}", # Mac and iOS want Title Case strings. "use_titlecase=${is_apple}", diff --git a/wrt/BUILD.gn b/wrt/BUILD.gn index 2c97238..b6ba21d 100644 --- a/wrt/BUILD.gn +++ b/wrt/BUILD.gn @@ -388,43 +388,6 @@ static_library("wrt_lib") { } sources = wrt_lib_sources + [ - "//chrome/browser/app_mode/app_mode_utils.cc", - "//chrome/browser/app_mode/app_mode_utils.h", - "//chrome/browser/browser_features.cc", - "//chrome/browser/browser_features.h", - "//chrome/browser/browser_process.cc", - "//chrome/browser/browser_process.h", - "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc", - "//chrome/browser/devtools/devtools_contents_resizing_strategy.h", - "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc", - "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h", - "//chrome/browser/devtools/devtools_file_system_indexer.cc", - "//chrome/browser/devtools/devtools_file_system_indexer.h", - "//chrome/browser/icon_loader.cc", - "//chrome/browser/icon_loader.h", - "//chrome/browser/icon_loader_auralinux.cc", - "//chrome/browser/icon_manager.cc", - "//chrome/browser/icon_manager.h", - "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc", - "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h", - "//chrome/browser/net/proxy_config_monitor.cc", - "//chrome/browser/net/proxy_config_monitor.h", - "//chrome/browser/net/proxy_service_factory.cc", - "//chrome/browser/net/proxy_service_factory.h", - "//chrome/browser/process_singleton.h", - "//chrome/browser/process_singleton_posix.cc", - "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc", - "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h", - "//chrome/browser/ui/exclusive_access/exclusive_access_manager.cc", - "//chrome/browser/ui/exclusive_access/exclusive_access_manager.h", - "//chrome/browser/ui/exclusive_access/fullscreen_controller.cc", - "//chrome/browser/ui/exclusive_access/fullscreen_controller.h", - "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.cc", - "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.h", - "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc", - "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.h", - "//chrome/browser/ui/exclusive_access/mouse_lock_controller.cc", - "//chrome/browser/ui/exclusive_access/mouse_lock_controller.h", "//electron/shell/browser/certificate_manager_model.cc", "//electron/shell/browser/certificate_manager_model.h", "//electron/shell/browser/lib/power_observer_linux.cc", @@ -432,6 +395,47 @@ static_library("wrt_lib") { "//electron/shell/common/node_bindings_linux.cc", ] sources += rebase_path(electron_override_sources, ".", "overrides/electron") + if (!build_chrome) { + sources += [ + "//chrome/browser/app_mode/app_mode_utils.cc", + "//chrome/browser/app_mode/app_mode_utils.h", + "//chrome/browser/browser_features.cc", + "//chrome/browser/browser_features.h", + "//chrome/browser/browser_process.cc", + "//chrome/browser/browser_process.h", + "//chrome/browser/devtools/devtools_contents_resizing_strategy.cc", + "//chrome/browser/devtools/devtools_contents_resizing_strategy.h", + "//chrome/browser/devtools/devtools_embedder_message_dispatcher.cc", + "//chrome/browser/devtools/devtools_embedder_message_dispatcher.h", + "//chrome/browser/devtools/devtools_file_system_indexer.cc", + "//chrome/browser/devtools/devtools_file_system_indexer.h", + "//chrome/browser/icon_loader.cc", + "//chrome/browser/icon_loader.h", + "//chrome/browser/icon_loader_auralinux.cc", + "//chrome/browser/icon_manager.cc", + "//chrome/browser/icon_manager.h", + "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.cc", + "//chrome/browser/net/chrome_mojo_proxy_resolver_factory.h", + "//chrome/browser/net/proxy_config_monitor.cc", + "//chrome/browser/net/proxy_config_monitor.h", + "//chrome/browser/net/proxy_service_factory.cc", + "//chrome/browser/net/proxy_service_factory.h", + "//chrome/browser/process_singleton.h", + "//chrome/browser/process_singleton_posix.cc", + "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.cc", + "//chrome/browser/ui/exclusive_access/exclusive_access_controller_base.h", + "//chrome/browser/ui/exclusive_access/exclusive_access_manager.cc", + "//chrome/browser/ui/exclusive_access/exclusive_access_manager.h", + "//chrome/browser/ui/exclusive_access/fullscreen_controller.cc", + "//chrome/browser/ui/exclusive_access/fullscreen_controller.h", + "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.cc", + "//chrome/browser/ui/exclusive_access/fullscreen_within_tab_helper.h", + "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.cc", + "//chrome/browser/ui/exclusive_access/keyboard_lock_controller.h", + "//chrome/browser/ui/exclusive_access/mouse_lock_controller.cc", + "//chrome/browser/ui/exclusive_access/mouse_lock_controller.h", + ] + } if (tizen_product_tv) { sources += wrt_lib_sources_tv } else { @@ -480,10 +484,12 @@ static_library("wrt_lib") { ] sources += wrt_lib_sources_chrome_extensions } else { - sources += wrt_lib_sources_without_chrome_extensions + if (!build_chrome) { + sources += wrt_lib_sources_without_chrome_extensions + } } - if (enable_printing) { + if (enable_printing && !build_chrome) { deps += [ "//chrome/services/printing:lib", "//chrome/services/printing/public/mojom", @@ -518,6 +524,7 @@ static_library("wrt_lib") { "//electron/shell/renderer/printing/print_render_frame_helper_delegate.cc", "//electron/shell/renderer/printing/print_render_frame_helper_delegate.h", ] + if (enable_oop_printing) { sources += [ "//chrome/browser/printing/print_backend_service_manager.cc", @@ -533,6 +540,14 @@ static_library("wrt_lib") { ] } } + else { + sources += [ + "//electron/shell/browser/printing/print_view_manager_electron.cc", + "//electron/shell/browser/printing/print_view_manager_electron.h", + "//electron/shell/renderer/printing/print_render_frame_helper_delegate.cc", + "//electron/shell/renderer/printing/print_render_frame_helper_delegate.h", + ] +} unused_electron_sources = [ "shell/browser/api/electron_api_desktop_capturer.cc", -- 2.7.4 From 2f2598a812bf1749c438473715d6ef45566074c2 Mon Sep 17 00:00:00 2001 From: "zhishun.zhou" Date: Fri, 22 Mar 2024 11:54:39 +0800 Subject: [PATCH 05/16] fixup! [M120 Migration] Add new api for webbrowser to get media device list Fix link error when build with "--build-chrome": ld.lld: error: undefined symbol: content::IsWebBrowser() ld.lld: error: undefined symbol: switches::kTizenAppId Change-Id: Id100dd5deaa7bc1c0f8123c0b66b7db75e90ac19 Signed-off-by: zhishun.zhou --- content/browser/renderer_host/media/media_devices_manager.cc | 4 ++-- tizen_src/chromium_impl/media/filters/esplusplayer_util.cc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/content/browser/renderer_host/media/media_devices_manager.cc b/content/browser/renderer_host/media/media_devices_manager.cc index 880e009..5e58928 100644 --- a/content/browser/renderer_host/media/media_devices_manager.cc +++ b/content/browser/renderer_host/media/media_devices_manager.cc @@ -51,7 +51,7 @@ #endif #if BUILDFLAG(IS_TIZEN_TV) -#include "tizen_src/ewk/efl_integration/common/application_type.h" +#include "third_party/blink/public/platform/web_application_type.h" #endif namespace content { @@ -1031,7 +1031,7 @@ void MediaDevicesManager::DevicesEnumerated( #if BUILDFLAG(IS_TIZEN_TV) // report device list to webbrowser - if (IsWebBrowser() && !enum_cb_.is_null()) { + if (blink::IsWebBrowser() && !enum_cb_.is_null()) { got_result_[static_cast(type)] = true; for (const auto& device : snapshot) { diff --git a/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc b/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc index 6d62cd9..1e42c3d 100644 --- a/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc +++ b/tizen_src/chromium_impl/media/filters/esplusplayer_util.cc @@ -219,9 +219,13 @@ gfx::Size GetDynamicMaxCodecResolution() { int max_width = 0; int max_height = 0; int max_framerate = 0; +#if !defined(BUILD_CHROME) std::string app_id = base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( switches::kTizenAppId); +#else + std::string app_id = ""; +#endif // resource center returns decodeer ability not resolution (ex.1088) // http://wiki.vd.sec.samsung.net/display/OSS/02.+Max+Resolution -- 2.7.4 From 98565b6bd0df2aaa35f21f30f0bd81ed718b2cf5 Mon Sep 17 00:00:00 2001 From: Chandan Padhi Date: Fri, 22 Mar 2024 17:21:30 +0530 Subject: [PATCH 06/16] Use third party libxml System libxml update results in build errors in QB. Change-Id: I039ec4bd18a6842f8608b9e48d3bef73d2311f20 Signed-off-by: Chandan Padhi --- third_party/libxml/BUILD.gn | 232 ++++++++++++++++++++++++++++++++++++++------ tizen_src/build/common.sh | 1 - 2 files changed, 203 insertions(+), 30 deletions(-) diff --git a/third_party/libxml/BUILD.gn b/third_party/libxml/BUILD.gn index 3772c67..d40e166 100644 --- a/third_party/libxml/BUILD.gn +++ b/third_party/libxml/BUILD.gn @@ -1,8 +1,55 @@ -# Copyright 2016 The Chromium Authors +# Copyright 2013 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//build/config/linux/pkg_config.gni") +# Define an "os_include" variable that points at the OS-specific generated +# headers. These were generated by running the configure script offline. +if (is_linux || is_chromeos || is_android || is_nacl || is_fuchsia || is_tizen) { + os_include = "linux" +} else if (is_apple) { + os_include = "mac" +} else if (is_win) { + os_include = "win32" +} + +import("//third_party/libxml/libxml_visibility.gni") + +config("libxml_config") { + # Define LIBXML_STATIC as nothing to match how libxml.h (an internal header) + # defines LIBXML_STATIC, otherwise we get the macro redefined warning from + # GCC. ("defines" does "-DFOO" which defines the macro FOO as 1.) + cflags = [ "-DLIBXML_STATIC=" ] + + include_dirs = [ + "src/include", + "$os_include/include", + ] +} + +config("libxml_warnings") { + if (is_win) { + cflags_c = [ + "/wd4018", # Signed/unsigned mismatch in comparison. + "/wd4267", # TODO(brucedawson): http://crbug.com/554200 fix C4267 + "/wd4311", # and C4311 warnings. + ] + } + if (is_clang) { + cflags = [ + # libxml passes `const unsigned char*` through `const char*`. + "-Wno-pointer-sign", + + # pattern.c and uri.c both have an intentional `for (...);` / + # `while(...);` loop. I submitted a patch to move the `'` to its own + # line, but until that's landed suppress the warning: + "-Wno-empty-body", + + # debugXML.c compares array 'arg' to NULL. + "-Wno-tautological-pointer-compare", + + # threads.c attempts to forward declare a pthread_equal which doesn't + # match the prototype in pthreads.h + "-Wno-ignored-attributes", # libxml casts from int to long to void*. "-Wno-int-to-void-pointer-cast", @@ -51,11 +98,22 @@ static_library("xml_reader") { configs += [ ":libxml_config" ] } -source_set("libxml") { - public_configs = [ ":system_libxml" ] +# Please keep in sync with //build/linux/unbundle/libxml.gn. +static_library("xml_writer") { + # The XmlWriter is considered safe to use from any target. + visibility = [ "*" ] + sources = [ + "chromium/xml_writer.cc", + "chromium/xml_writer.h", + ] + deps = [ + ":libxml", + ":libxml_utils", + ] + configs += [ ":libxml_config" ] } -# Please keep in sync with //third_party/libxml/BUILD.gn. +# Please keep in sync with //build/linux/unbundle/libxml.gn. static_library("libxml_utils") { # Do not expand this visibility list without first consulting with the # Security Team. @@ -70,40 +128,156 @@ static_library("libxml_utils") { "chromium/libxml_utils.cc", "chromium/libxml_utils.h", ] - public_configs = [ ":system_libxml" ] + deps = [ ":libxml" ] + public_deps = [ "//third_party/icu:icuuc" ] + public_configs = [ ":libxml_config" ] } -# Please keep in sync with //third_party/libxml/BUILD.gn. -static_library("xml_reader") { +static_library("libxml") { # Do not expand this visibility list without first consulting with the # Security Team. visibility = [ - "//base/test:test_support", - "//components/policy/core/common:unit_tests", - "//services/data_decoder:*", - "//tools/traffic_annotation/auditor:auditor_sources", - ] - sources = [ - "chromium/xml_reader.cc", - "chromium/xml_reader.h", + ":libxml_utils", + ":xml_reader", + ":xml_writer", + "//chromecast/internal", + "//testing/libfuzzer/*", + "//third_party/blink/renderer/*", + "//third_party/fontconfig", + "//third_party/libxslt", + "//third_party/maldoca/*", ] - deps = [ ":libxml_utils" ] -} + if (is_ios) { + foreach(tgt, ios_libxml_visibility_additions) { + visibility += [ "//ios_internal/$tgt" ] + } + } -# Please keep in sync with //third_party/libxml/BUILD.gn. -static_library("xml_writer") { - # The XmlWriter is considered safe to use from any target. - visibility = [ "*" ] + output_name = "libxml2" + + # Commented out sources are libxml2 files we do not want to include. They are + # here to make it easy to identify files which are new. sources = [ - "chromium/xml_writer.cc", - "chromium/xml_writer.h", + "src/HTMLparser.c", + "src/HTMLtree.c", + + #"src/SAX.c", + "src/SAX2.c", + "src/buf.c", + + #"src/c14n.c", + #"src/catalog.c", + "src/chvalid.c", + + #"src/debugXML.c", + "src/dict.c", + "src/encoding.c", + "src/entities.c", + "src/error.c", + "src/globals.c", + "src/hash.c", + "src/include/libxml/HTMLparser.h", + "src/include/libxml/HTMLtree.h", + "src/include/libxml/SAX.h", + "src/include/libxml/SAX2.h", + "src/include/libxml/c14n.h", + "src/include/libxml/catalog.h", + "src/include/libxml/chvalid.h", + "src/include/libxml/debugXML.h", + "src/include/libxml/dict.h", + "src/include/libxml/encoding.h", + "src/include/libxml/entities.h", + "src/include/libxml/globals.h", + "src/include/libxml/hash.h", + "src/include/libxml/list.h", + "src/include/libxml/nanoftp.h", + "src/include/libxml/nanohttp.h", + "src/include/libxml/parser.h", + "src/include/libxml/parserInternals.h", + "src/include/libxml/pattern.h", + "src/include/libxml/relaxng.h", + "src/include/libxml/schemasInternals.h", + "src/include/libxml/schematron.h", + "src/include/libxml/threads.h", + "src/include/libxml/tree.h", + "src/include/libxml/uri.h", + "src/include/libxml/valid.h", + "src/include/libxml/xinclude.h", + "src/include/libxml/xlink.h", + "src/include/libxml/xmlIO.h", + "src/include/libxml/xmlautomata.h", + "src/include/libxml/xmlerror.h", + "src/include/libxml/xmlexports.h", + "src/include/libxml/xmlmemory.h", + "src/include/libxml/xmlmodule.h", + "src/include/libxml/xmlreader.h", + "src/include/libxml/xmlregexp.h", + "src/include/libxml/xmlsave.h", + "src/include/libxml/xmlschemas.h", + "src/include/libxml/xmlschemastypes.h", + "src/include/libxml/xmlstring.h", + "src/include/libxml/xmlunicode.h", + "src/include/libxml/xmlwriter.h", + "src/include/libxml/xpath.h", + "src/include/libxml/xpathInternals.h", + "src/include/libxml/xpointer.h", + + #"src/legacy.c", + "src/libxml.h", + "src/list.c", + "src/parser.c", + "src/parserInternals.c", + "src/pattern.c", + + #"src/relaxng.c", + + #"src/schematron.c", + "src/threads.c", + "src/timsort.h", + "src/tree.c", + "src/triodef.h", + "src/trionan.h", + + #"src/trio.c", + #"src/trio.h", + #"src/triodef.h", + # Note: xpath.c #includes trionan.c + #"src/trionan.c", + #"src/triop.h", + #"src/triostr.c", + #"src/triostr.h", + "src/uri.c", + "src/valid.c", + + #"src/xinclude.c", + #"src/xlink.c", + "src/xmlIO.c", + "src/xmlmemory.c", + + #"src/xmlmodule.c", + "src/xmlreader.c", + + #"src/xmlregexp.c", + "src/xmlsave.c", + + #"src/xmlschemas.c", + #"src/xmlschemastypes.c", + "src/xmlstring.c", + "src/xmlunicode.c", + "src/xmlwriter.c", + "src/xpath.c", + + #"src/xpointer.c", + #"src/xzlib.c", ] - deps = [ - ":libxml", - ":libxml_utils", + + configs -= [ "//build/config/compiler:chromium_code" ] + configs += [ + "//build/config/compiler:no_chromium_code", + + # Must be after no_chromium_code for warning flags to be ordered correctly. + ":libxml_warnings", ] - configs += [ ":libxml_config" ] -} if (is_linux || is_chromeos) { sources += [ diff --git a/tizen_src/build/common.sh b/tizen_src/build/common.sh index 1dd2645..45054d5 100755 --- a/tizen_src/build/common.sh +++ b/tizen_src/build/common.sh @@ -25,7 +25,6 @@ function getSystemDeps() { local platform=$1 local system_deps="--system-libraries libpng - libxml libxslt zlib " -- 2.7.4 From c09468bc5ebed5fa425afc35ab46bfe6dc969f80 Mon Sep 17 00:00:00 2001 From: Manjeet Date: Thu, 21 Mar 2024 21:28:09 +0530 Subject: [PATCH 07/16] fixup! [M120 Migration] Languages pak optimization This patch fixes the AssertionError[1] which occurs while desktop build. [1] undefined Grit variable found: is_tizen Reference: https://review.tizen.org/gerrit/291547 Change-Id: I18eda849a0f4a0f5712d082d5f42ad6c85b0d125 Signed-off-by: Manjeet --- tools/grit/grit_rule.gni | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni index f0e7fdf..7956feb 100644 --- a/tools/grit/grit_rule.gni +++ b/tools/grit/grit_rule.gni @@ -96,7 +96,6 @@ import("//tools/grit/grit_args.gni") _strip_resource_files = is_android && is_official_build _js_minifier = "//tools/grit/minify_js.py" _css_minifier = "//tools/grit/minimize_css.py" -grit_defines = [] grit_resource_id_target = "//tools/gritsettings:default_resource_ids" grit_resource_id_file = @@ -115,13 +114,6 @@ if (is_win) { "//tools/gritsettings/startup_resources_win.txt" } -if (is_tizen) { - grit_defines += [ - "-D", - "is_tizen", - ] -} - template("grit") { if (defined(invoker.output_dir)) { _output_dir = invoker.output_dir @@ -202,7 +194,7 @@ template("grit") { rebase_path(depfile, root_build_dir), "--write-only-new=1", "--depend-on-stamp", - ] + _grit_flags + grit_defines + ] + _grit_flags # Add brotli executable if using brotli. if (defined(invoker.use_brotli) && invoker.use_brotli) { -- 2.7.4 From da87b4aadc5c56c4853bc618eab31568521c06bb Mon Sep 17 00:00:00 2001 From: peng1xiao Date: Thu, 21 Mar 2024 17:31:08 +0800 Subject: [PATCH 08/16] [M120 Migration][MM] Supporting ATMOS decoding & checking ATMOS decoding capability - HDMI CEC API is deprecated. - Audio controller API can check soundBar/TV/receiver's capability. Migrated from: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/291012/ https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/291239/ Change-Id: Ibf3813fe5f795fb472eebe2e3a6978951556c84c Signed-off-by: peng1xiao --- packaging/chromium-efl.spec | 9 +++++++ .../renderer/modules/mediasource/media_source.cc | 29 +++++++++++++++++++++- tizen_src/build/BUILD.gn | 13 ++++++++++ tizen_src/build/config/BUILD.gn | 3 +++ tizen_src/build/config/tizen_features.gni | 1 + tizen_src/chromium_impl/media/media_efl.gni | 7 ++++++ tizen_src/ewk/efl_integration/eweb_context.cc | 3 +++ 7 files changed, 64 insertions(+), 1 deletion(-) diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index ccc8e52..030e38f 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -71,6 +71,11 @@ Source1: content_shell.in %else %define __enable_gamepad_latency_test 0 %endif + +%if "%{_vd_cfg_product_type}" != "LFD" && "%{_vd_cfg_product_type}" != "IWB" && "%{?_with_emulator}" != "1" && "%{_vd_cfg_licensing}" == "n" && %{tizen_version} > 60 +%define _tizen_atmos_decoder_enable 1 +%endif + %{?_use_system_icu: %define __use_system_icu %{_use_system_icu}} # Product tv can't utilize system icu due to nacl dependency. %if "%{?profile}" != "tv" && %{tizen_version} == 60 && %{?_use_system_icu: 0}%{!?_use_system_icu: 1} @@ -203,6 +208,9 @@ BuildRequires: pkgconfig(tv-resource-manager) BuildRequires: pkgconfig(tv-resource-information) BuildRequires: pkgconfig(vd-win-util) BuildRequires: pkgconfig(WebProduct) +%if "%{_tizen_atmos_decoder_enable}" == "1" +BuildRequires: pkgconfig(ais-control-settings) +%endif %if %{tizen_version} >= 60 BuildRequires: pkgconfig(resource-center-api) %endif @@ -549,6 +557,7 @@ touch ./tizen_src/downloadable/ewk_api_wrapper_generator.py %endif "ozone_auto_platforms=false" \ "enable_wrt_js=%{macro_to_bool __enable_wrt_js}" \ + "tizen_atmos_decoder_enable=%{macro_to_bool _tizen_atmos_decoder_enable}" \ %if 0%{?__enable_wrt_js} "xwalk_extension_path=\"%{__xwalk_extension_path}\"" \ "xwalk_extension_service_path=\"%{__xwalk_extension_service_path}\"" \ diff --git a/third_party/blink/renderer/modules/mediasource/media_source.cc b/third_party/blink/renderer/modules/mediasource/media_source.cc index 4a8adf9..1f886fd 100644 --- a/third_party/blink/renderer/modules/mediasource/media_source.cc +++ b/third_party/blink/renderer/modules/mediasource/media_source.cc @@ -62,6 +62,9 @@ #include "hdmicec_api.h" #include "tizen_src/chromium_impl/build/tizen_version.h" #include "tizen_src/chromium_impl/tizen/tizen_tv_platform.h" +#if defined(ENABLE_ATMOS_DECODER) +#include +#endif #endif using blink::WebMediaSource; @@ -1735,6 +1738,27 @@ bool MediaSource::IsAV1SupportedOnTizen() { #endif } +bool IsAtmosDecodingSupportedOnTizen(const ContentType& content_type) { +#if defined(ENABLE_ATMOS_DECODER) + int atmos_support = 0; + // audio_ctrl_setting_get_atmos_capability() checks if TV can decode ATMOS + // itself. The function returns 0 when 1) The sound output is not a TV + // speaker. 2) Menu > Sound > Expert Settings > Dolby ATMOS menu OFF. 3) In + // case of Multiview mode. 4) In VR360 mode. + AUDIO_CTRL_SETTING_E ret = AUDIO_CTRL_SETTING_ERR_NONE; + ret = audio_ctrl_setting_get_atmos_capability(&atmos_support); + if (ret != AUDIO_CTRL_SETTING_ERR_NONE) { + LOG(WARNING) << "[ATMOS] AUDIO_CTRL_SETTING_ERR: " << ret; + } + if (atmos_support == 1 && + content_type.Parameter("codecs").FindIgnoringCase("ec-3") != kNotFound && + content_type.Parameter("channels").ToInt() <= 8) { + return true; + } +#endif + return false; +} + bool MediaSource::IsCodecAndMediaTypeSupported( const ContentType& content_type) { DVLOG(1) << __func__ << "MediaSource Extention Type (W=" @@ -1763,7 +1787,10 @@ bool MediaSource::IsCodecAndMediaTypeSupported( } String features = content_type.Parameter("features"); - if (!features.empty()) { + if (features == dolby_eac3_atmos) { + return IsAtmosDecodingSupportedOnTizen(content_type); + } else if (!features.empty()) { + LOG(WARNING) << "The features has invalid parameter: " << features; return false; } diff --git a/tizen_src/build/BUILD.gn b/tizen_src/build/BUILD.gn index 7d3f2a8..4721b99 100644 --- a/tizen_src/build/BUILD.gn +++ b/tizen_src/build/BUILD.gn @@ -670,6 +670,19 @@ if (tizen_multimedia) { } } +config("audio_ctrl_setting") { + if (tizen_atmos_decoder_enable) { + ldflags = [ "-laudio_ctrl_setting" ] + } +} + +tizen_pkg_config("libaudio_ctrl_setting") { + packages = [] + if (tizen_atmos_decoder_enable) { + packages = [ "ais-control-settings" ] + } +} + tizen_pkg_config("libmm-player") { packages = [] if (is_tizen) { diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index 0c73e19..0773b06 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -71,6 +71,9 @@ config("tizen_feature_flags") { if (tizen_audio_io) { defines += [ "TIZEN_MULTIMEDIA_USE_CAPI_AUDIO_IO" ] } + if (tizen_atmos_decoder_enable) { + defines += [ "ENABLE_ATMOS_DECODER" ] + } if (tizen_autofill) { defines += [ "TIZEN_AUTOFILL" ] if (tizen_autofill_fw) { diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index c754301..027b580 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -53,6 +53,7 @@ declare_args() { enable_ewk_interface = false enable_wrt_js = false + tizen_atmos_decoder_enable = false tizen_pepper_extensions = false # Tizen multimedia related diff --git a/tizen_src/chromium_impl/media/media_efl.gni b/tizen_src/chromium_impl/media/media_efl.gni index 02bc620..7b41f67 100644 --- a/tizen_src/chromium_impl/media/media_efl.gni +++ b/tizen_src/chromium_impl/media/media_efl.gni @@ -120,6 +120,13 @@ if (tizen_multimedia) { ] } + if (tizen_atmos_decoder_enable) { + external_media_video_decode_config += [ + "//tizen_src/build:libaudio_ctrl_setting", + "//tizen_src/build:audio_ctrl_setting", + ] + } + external_media_capture_config += [ "//tizen_src/build:capi-media-camera", "//tizen_src/build:libcapi-media-camera", diff --git a/tizen_src/ewk/efl_integration/eweb_context.cc b/tizen_src/ewk/efl_integration/eweb_context.cc index 9da8a8c..dd84743 100644 --- a/tizen_src/ewk/efl_integration/eweb_context.cc +++ b/tizen_src/ewk/efl_integration/eweb_context.cc @@ -277,6 +277,9 @@ void EWebContext::SetTizenAppId(const std::string& tizen_app_id) { auto* plugin = &HbbtvDynamicPlugin::Get(); plugin->Init(injected_bundle_path_); } + // Keep tizen app id into CommandLine in order to access it + // from all over the browser process. + command_line.AppendSwitchASCII(switches::kTizenAppId, tizen_app_id_); #endif // IS_TIZEN_TV #endif // IS_TIZEN } -- 2.7.4 From 6fd842debf6e7ee62750cf3b611eb2eeb24955f7 Mon Sep 17 00:00:00 2001 From: jiangyuwei Date: Tue, 19 Mar 2024 13:33:48 +0800 Subject: [PATCH 09/16] [M120 Migration][VD][AX] Custom the focus event when setFocus to webview Accessibility needs to be informed when system focus has moved into the web area again even if focus did not change within WebCore; And if there is no focus element, try move down to find one. References: - https://review.tizen.org/gerrit/#/c/291817/ Change-Id: I2cc752397b14562e9beaca3ca107d73137750b02 Signed-off-by: jiangyuwei --- .../blink/renderer/core/exported/web_view_impl.cc | 23 ++++++++++++++++++++++ .../blink/renderer/core/page/spatial_navigation.cc | 4 ++++ .../core/page/spatial_navigation_controller.cc | 6 ++++++ .../core/page/spatial_navigation_controller.h | 4 ++++ .../ewk/efl_integration/eweb_accessibility.cc | 6 ++++++ 5 files changed, 43 insertions(+) diff --git a/third_party/blink/renderer/core/exported/web_view_impl.cc b/third_party/blink/renderer/core/exported/web_view_impl.cc index a1e160c..684ef49 100644 --- a/third_party/blink/renderer/core/exported/web_view_impl.cc +++ b/third_party/blink/renderer/core/exported/web_view_impl.cc @@ -209,6 +209,8 @@ #if BUILDFLAG(IS_TIZEN_TV) #include "third_party/blink/public/platform/web_application_type.h" +#include "third_party/blink/renderer/core/page/spatial_navigation_controller.h" +#include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" #include "third_party/blink/public/web/web_security_policy.h" #endif @@ -2015,6 +2017,27 @@ void WebViewImpl::SetPageFocus(bool enable) { SelectionInDOMTree::Builder().Collapse(position).Build()); } } +#if BUILDFLAG(IS_TIZEN_TV) + if (element) { + // Accessibility needs to be informed that system focus has moved + // into the web area again, even if focus did not change within + // WebCore. send the notification even if the element is the same. + AXObjectCache* cache = + focused_frame->GetDocument()->ExistingAXObjectCache(); + if (cache) + cache->HandleFocusedUIElementChanged(0, element); + } else { + // if no focus element and spatial navigation enabled, + // move to the first top element by send a fake arrow down + if (IsSpatialNavigationEnabled(focused_frame) && IsWebBrowser()) { + LOG(INFO) << "No focused element in view, navigate downward"; + GetPage() + ->GetSpatialNavigationController() + .HandleSpatialNavigationDirection( + SpatialNavigationDirection::kDown); + } + } +#endif } } else { CancelPagePopup(); diff --git a/third_party/blink/renderer/core/page/spatial_navigation.cc b/third_party/blink/renderer/core/page/spatial_navigation.cc index 70cb3a8..e430935 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation.cc @@ -610,11 +610,15 @@ bool BothOnTopmostPaintLayerInStackingContext( return false; const LayoutObject* origin = current_interest.visible_node->GetLayoutObject(); + if (!origin) + return false; const PaintLayer* focused_layer = origin->PaintingLayer(); if (!focused_layer || focused_layer->IsRootLayer()) return false; const LayoutObject* next = candidate.visible_node->GetLayoutObject(); + if (!next) + return false; const PaintLayer* candidate_layer = next->PaintingLayer(); if (focused_layer != candidate_layer) return false; diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc index 9886254..0f3e1a9 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.cc @@ -606,4 +606,10 @@ void SpatialNavigationController::FullscreenStateChanged(Element* element) { } } +#if BUILDFLAG(IS_TIZEN_TV) +bool SpatialNavigationController::HandleSpatialNavigationDirection( + SpatialNavigationDirection direction) { + return Advance(direction); +} +#endif } // namespace blink diff --git a/third_party/blink/renderer/core/page/spatial_navigation_controller.h b/third_party/blink/renderer/core/page/spatial_navigation_controller.h index 8354679..01311b6 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation_controller.h +++ b/third_party/blink/renderer/core/page/spatial_navigation_controller.h @@ -48,6 +48,10 @@ class CORE_EXPORT SpatialNavigationController final void Trace(Visitor*) const; +#if BUILDFLAG(IS_TIZEN_TV) + bool HandleSpatialNavigationDirection(SpatialNavigationDirection direction); +#endif + private: // Entry-point into SpatialNavigation advancement. Will return true if an // action (moving interest or scrolling), false otherwise. diff --git a/tizen_src/ewk/efl_integration/eweb_accessibility.cc b/tizen_src/ewk/efl_integration/eweb_accessibility.cc index 0882ef4..c3702dd 100644 --- a/tizen_src/ewk/efl_integration/eweb_accessibility.cc +++ b/tizen_src/ewk/efl_integration/eweb_accessibility.cc @@ -81,8 +81,14 @@ void EWebAccessibility::NotifyAccessibilityStatus(bool is_enabled) { if (IsMobileProfile() || IsTvProfile()) (is_enabled) ? AddPlug() : RemovePlug(); +// On TV, the Spatial Navigation and Accessibility are independent, the +// Accessibility Status change should not trigger Spatial Navigation status +// change. So disbale trigger SpatialNavigationStatusChange when +// AccessibilityStatusChanged. +#if !BUILDFLAG(IS_TIZEN_TV) if (observer_) { observer_->OnSpatialNavigationStatusChanged(is_enabled); observer_->OnAccessibilityStatusChanged(is_enabled); } +#endif } -- 2.7.4 From 53bb9e3daf8f45d9609a60445b8bc88bae1a36c9 Mon Sep 17 00:00:00 2001 From: liwei90727 Date: Tue, 12 Mar 2024 14:38:36 +0800 Subject: [PATCH 10/16] [M120 Migration][WRTjs] Support NavigationPolicy on decide Navigation From M108, OnDecideNavigationPolicy() doesn't have logic for open media, only logic related with NavigationPolicy. Reference Patch https://review.tizen.org/gerrit/271794/ https://review.tizen.org/gerrit/230348/ Change-Id: Id51431ea975a7625061f89a1589a9893bdd3a716 Signed-off-by: liwei90727 --- wrt/src/browser/wrt_render_message_filter.cc | 72 +++++++++++++++------------- wrt/src/browser/wrt_render_message_filter.h | 28 ++++------- 2 files changed, 49 insertions(+), 51 deletions(-) mode change 100755 => 100644 wrt/src/browser/wrt_render_message_filter.cc mode change 100755 => 100644 wrt/src/browser/wrt_render_message_filter.h diff --git a/wrt/src/browser/wrt_render_message_filter.cc b/wrt/src/browser/wrt_render_message_filter.cc old mode 100755 new mode 100644 index 5fe9e7e..bfd8ab8 --- a/wrt/src/browser/wrt_render_message_filter.cc +++ b/wrt/src/browser/wrt_render_message_filter.cc @@ -2,56 +2,64 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "wrt_render_message_filter.h" +#include "wrt/src/browser/wrt_render_message_filter.h" -#if !defined(WRT_JS_BRINGUP) -#include "tizen_src/chromium_impl/content/public/browser/policy_decision_util.h" -#endif +#include "third_party/blink/public/web/web_navigation_policy.h" +#include "tizen_src/ewk/efl_integration/common/render_messages_ewk.h" #include "tizen_src/ewk/efl_integration/private/ewk_policy_decision_private.h" #include "wrt/src/browser/native_web_runtime.h" -#include "wrt/src/browser/wrt_browser_context.h" namespace { -static void NavigationPolicyDecision(void* /*data*/, - const std::string& url, - void* event_info) { - if (!event_info) { - LOG(ERROR) << "event_info is nullptr"; - return; - } - - auto policy_decision = static_cast<_Ewk_Policy_Decision*>(event_info); - if (wrt::NativeWebRuntime::GetInstance().ShouldAllowNavigation(url)) - policy_decision->Use(); - else - policy_decision->Ignore(); -} +const uint32_t kFilteredMessageClasses[] = {EwkMsgStart}; } // namespace namespace wrt { -WRTRenderMessageFilter::WRTRenderMessageFilter() {} +WRTRenderMessageFilter::WRTRenderMessageFilter() + : BrowserMessageFilter(kFilteredMessageClasses, + std::size(kFilteredMessageClasses)) {} WRTRenderMessageFilter::~WRTRenderMessageFilter() {} +void WRTRenderMessageFilter::OverrideThreadForMessage( + const IPC::Message& message, + content::BrowserThread::ID* thread) { + switch (message.type()) { + case EwkHostMsg_DecideNavigationPolicy::ID: + *thread = content::BrowserThread::UI; + break; + } +} + +bool WRTRenderMessageFilter::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(WRTRenderMessageFilter, message) + IPC_MESSAGE_HANDLER(EwkHostMsg_DecideNavigationPolicy, + OnDecideNavigationPolicy) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + void WRTRenderMessageFilter::OnDecideNavigationPolicy( - const NavigationPolicyParams& params, + NavigationPolicyParams params, bool* handled) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); -#if defined(WRT_JS_BRINGUP) - *handled = false; -#else - std::unique_ptr navigation( - new content::PolicyDecisionUtil()); - auto* browser_context = WRTBrowserContext::GetInstance(); - DCHECK(browser_context); - navigation->SetNavigationPolicyDecisionCallback(NavigationPolicyDecision); - navigation->PolicyNavigation(params, browser_context->GetProxyURI(), handled, - nullptr); -#endif + std::unique_ptr<_Ewk_Policy_Decision> policy_decision( + new _Ewk_Policy_Decision(params)); + + if (NativeWebRuntime::GetInstance().ShouldAllowNavigation(params.url.spec())) + policy_decision->Use(); + else + policy_decision->Ignore(); + + CHECK(!policy_decision->isSuspended()); + + *handled = policy_decision->GetNavigationPolicyHandler()->GetDecision() == + NavigationPolicyHandlerEfl::Handled; } } // namespace wrt diff --git a/wrt/src/browser/wrt_render_message_filter.h b/wrt/src/browser/wrt_render_message_filter.h old mode 100755 new mode 100644 index ef3b992..638f374 --- a/wrt/src/browser/wrt_render_message_filter.h +++ b/wrt/src/browser/wrt_render_message_filter.h @@ -5,36 +5,26 @@ #ifndef BROWSER_WRT_RENDER_MESSAGE_FILTER_H #define BROWSER_WRT_RENDER_MESSAGE_FILTER_H -#if defined(WRT_JS_BRINGUP) +#include "base/threading/thread.h" +#include "content/public/browser/browser_associated_interface.h" #include "content/public/browser/browser_message_filter.h" + struct NavigationPolicyParams; -namespace content { -class BrowserMessageFilterCommon : public content::BrowserMessageFilter { - public: - bool OnMessageReceived(const IPC::Message& message) override { return false; } - virtual void OnDecideNavigationPolicy(const NavigationPolicyParams&, - bool* handled) {} -}; -} -#else -#include "tizen_src/chromium_impl/content/browser/message_filter/browser_message_filter_common.h" -#endif namespace wrt { -class WRTRenderMessageFilter - : public content::BrowserMessageFilterCommon { +class WRTRenderMessageFilter : public content::BrowserMessageFilter { public: WRTRenderMessageFilter(); ~WRTRenderMessageFilter(); - WRTRenderMessageFilter(const WRTRenderMessageFilter&) = delete; - WRTRenderMessageFilter& operator=(const WRTRenderMessageFilter&) = delete; + // BrowserMessageFilter methods: + bool OnMessageReceived(const IPC::Message&) override; + void OverrideThreadForMessage(const IPC::Message&, + content::BrowserThread::ID*) override; private: - // override content::BrowserMessageFilterCommon - void OnDecideNavigationPolicy(const NavigationPolicyParams&, - bool* handled) override; + void OnDecideNavigationPolicy(NavigationPolicyParams, bool* handled); }; } // namespace wrt -- 2.7.4 From 468917def4930b188c5bbf3963a74d5e5a4a9b94 Mon Sep 17 00:00:00 2001 From: DongHyun Song Date: Mon, 25 Mar 2024 09:41:40 +0900 Subject: [PATCH 11/16] [M120 Migration][WRTjs][VD] Use ps-agent mount for appzone enabled model direct mount's mount_namespace is changed when appzone container is enabled. Then, chromium initilization can be failed since mount point's internal path cannot be accessible. So, for the enterprise models, it will disable direct mount Reference: https://review.tizen.org/gerrit/#/c/platform/framework/web/chromium-efl/+/308292/ Change-Id: I100c872832197578108232020bfe21627e6fe992 Signed-off-by: DongHyun Song --- packaging/chromium-efl.spec | 6 ++ tizen_src/build/config/BUILD.gn | 4 + tizen_src/build/config/tizen_features.gni | 2 + tizen_src/build/gn_chromiumefl.sh | 8 ++ tizen_src/downloadable/BUILD.gn | 7 +- tizen_src/downloadable/ewk_interface_main.cc | 108 ++++++++++++++++++++++++--- 6 files changed, 123 insertions(+), 12 deletions(-) diff --git a/packaging/chromium-efl.spec b/packaging/chromium-efl.spec index 030e38f..aace036 100644 --- a/packaging/chromium-efl.spec +++ b/packaging/chromium-efl.spec @@ -528,6 +528,12 @@ touch ./tizen_src/downloadable/ewk_api_wrapper_generator.py %if "%{?tizen_profile_name}" == "tv" && "%{_vd_cfg_product_type}" != "AUDIO" && "%{_vd_cfg_product_type}" != "AV" && %{__build_chrome} != 1 "tizen_vd_accessory=true" \ %endif +%if "%{_vd_cfg_product_type}" == "LFD" + "tizen_vd_lfd=true" \ +%endif +%if "%{_vd_cfg_product_type}" == "IWB" + "tizen_vd_iwb=true" \ +%endif %if 0%{?component_build} "component=\"shared_library\"" \ %endif diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index 0773b06..fa23ca0 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -122,4 +122,8 @@ config("tizen_feature_flags") { if (drm_mapi_aarch_64) { defines += [ "DRM_MAPI_AARCH_64" ] } + + if (tizen_vd_lfd || tizen_vd_iwb) { + defines += ["TIZEN_VD_ENTERPRISE_FEATURE" ] + } } diff --git a/tizen_src/build/config/tizen_features.gni b/tizen_src/build/config/tizen_features.gni index 027b580..f98fd04 100644 --- a/tizen_src/build/config/tizen_features.gni +++ b/tizen_src/build/config/tizen_features.gni @@ -32,6 +32,8 @@ declare_args() { tizen_product_tv = false tizen_product_da = false + tizen_vd_lfd = false + tizen_vd_iwb = false exe_dir = "/usr/lib/chromium-efl/" lib_ro_root_dir = "/usr/share/chromium-efl" diff --git a/tizen_src/build/gn_chromiumefl.sh b/tizen_src/build/gn_chromiumefl.sh index 4dd81c6..ec70017 100755 --- a/tizen_src/build/gn_chromiumefl.sh +++ b/tizen_src/build/gn_chromiumefl.sh @@ -267,6 +267,14 @@ add_tizen_flags() { ADDITIONAL_GN_PARAMETERS+="tizen_video_hole=false " fi + + if [ "$tizen_vd_lfd" == "true" ]; then + ADDITIONAL_GN_PARAMETERS+="tizen_vd_lfd=true" + fi + + if [ "$tizen_vd_iwb" == "true" ]; then + ADDITIONAL_GN_PARAMETERS+="tizen_vd_iwb=true" + fi } add_wayland_flags() { diff --git a/tizen_src/downloadable/BUILD.gn b/tizen_src/downloadable/BUILD.gn index f209c4b..b2351a1 100644 --- a/tizen_src/downloadable/BUILD.gn +++ b/tizen_src/downloadable/BUILD.gn @@ -40,7 +40,12 @@ shared_library("ewk-interface") { defines += [ "LIB_UPGRADE_ROOT_DIR=\"$lib_upgrade_root_dir\"", ] - libs += [ "launchpad", "lwipc", "ttrace", "vconf" ] + configs += [ + "//tizen_src/build:libcapi-system-info", + "//tizen_src/build:launchpad", + "//tizen_src/build:vconf" + ] + libs += [ "capi-system-info", "lwipc", "ttrace", "vconf", "launchpad" ] } } diff --git a/tizen_src/downloadable/ewk_interface_main.cc b/tizen_src/downloadable/ewk_interface_main.cc index 2857e01..628a68c 100644 --- a/tizen_src/downloadable/ewk_interface_main.cc +++ b/tizen_src/downloadable/ewk_interface_main.cc @@ -47,10 +47,11 @@ #include #include #include -#include +#include +#include #if TIZEN_VERSION_AT_LEAST(8, 0, 0) && defined(TIZEN_VD_ENTERPRISE_FEATURE) -#include +#include #endif #endif // BUILDFLAG(IS_TIZEN_TV) #endif @@ -67,14 +68,15 @@ inline unsigned long long ConvertMilliseconds(timespec ts) { #if BUILDFLAG(IS_TIZEN_TV) bool g_upgrade_lib = false; // conservative policy const char* kChromiumMountReady = "/tmp/.chromium_mount.ready"; -#endif // BUILDFLAG(IS_TIZEN_TV) #if defined(ENABLE_WRT_JS) -#if BUILDFLAG(IS_TIZEN_TV) #define SQUASHFS_MAGIC 0x73717368 +const char* kPrivilegeServiceLibPath = "libprivileged-service-client.so"; +const char* kPSAgentReady = "/run/ps_agent.pid"; const char* kUWETag = "USE_UWE"; const char* kWrtLoaderCompleted = "/tmp/.wrt_loader.completed"; +const unsigned int kPSAgentTimeout = 30000; #if TIZEN_VERSION_AT_LEAST(8, 0, 0) && defined(TIZEN_VD_ENTERPRISE_FEATURE) const int kBooTypeLastModeUrlLauncher = 2; @@ -82,10 +84,10 @@ const char* kEPAppbootType = "db/ep-common/last_mode"; #endif char app_define_base_path[128] = {0}; -bool direct_mounted = false; +bool try_mounted = false; bool IsFirstWrtLoader() { - return direct_mounted || access(kWrtLoaderCompleted, F_OK) != 0; + return try_mounted || access(kWrtLoaderCompleted, F_OK) != 0; } void DisposeLoaderIfNecessary() { @@ -138,6 +140,83 @@ void LowerPriorityIfNecessary() { SetPriority(10); } +bool WaitPSAgentReady() { + static bool ps_agent_ready = false; + if (ps_agent_ready) + return true; + + int max_retry = 20; + LOG(INFO) << "Waiting the ps_agent ready"; + while (max_retry != 0) { + int ret = LwipcWaitEvent(kPSAgentReady, kPSAgentTimeout); + if (ret == 0) { + LOG(INFO) << "ps_agent is ready"; + ps_agent_ready = true; + return true; + } + + --max_retry; + LOG(ERROR) << "ps_agent is not ready : " << (ret > 0 ? "timeout" : "fail") + << ", remain retry [" << max_retry << "]"; + } + + return false; +} + +bool PSAgentMount(const char* image_path) { + if (access(image_path, F_OK) != 0) { + LOG(INFO) << "no chromium-efl.img"; + return false; + } + + if (WaitPSAgentReady() == false) + LOG(ERROR) << "Chromium-efl mount may not work."; + + int rv = 0; + int result = 0; + const char* args = MOUNT_ARGS_PRELOAD_CHROMIUM; + + LOG(INFO) << "mount args: \"" << args << "\""; + + auto ps_handle_ = dlopen(kPrivilegeServiceLibPath, RTLD_LAZY); + if (!ps_handle_) { + LOG(ERROR) << "dlopen() fail : " << dlerror(); + return false; + } + typedef int (*ps_mount)(const char*, size_t, int, int*); + ps_mount PS_Mount = nullptr; +#if TIZEN_VERSION_AT_LEAST(7, 0, 0) + PS_Mount = (ps_mount)dlsym(ps_handle_, "PS_Mount_Fast"); +#else + PS_Mount = (ps_mount)dlsym(ps_handle_, "PS_Mount"); +#endif + if (!PS_Mount) { + LOG(ERROR) << "dlsym() fail : " << dlerror(); + return false; + } + rv = PS_Mount(args, strlen(args) + 1, 1, &result); + LOG(INFO) << "result = " << rv << ", " << result; + if (rv != 0 || result != 0) { + LOG(ERROR) << "mount failed. (" << rv << ", " << result << ")"; + return false; + } + return true; +} + +bool IsAppzoneSupport() { + bool web_isolation_support = false; + LOG(INFO) << "fms get start"; + if (SYSTEM_INFO_ERROR_NONE == + system_info_get_custom_bool( + "com.samsung/featureconf/security.container.web_isolation", + &web_isolation_support)) { + LOG(INFO) << "fms get end"; + return web_isolation_support; + } else { + return false; + } +} + bool DirectMount(const char* image_path, const char* point_point) { const char* dev_loop_control = "/dev/loop-control"; const char* dev_loop_prefix = "/dev/loop"; @@ -199,11 +278,18 @@ bool MountDefaultChromiumImage() { return true; } - if (!DirectMount(PATH_PRELOAD_CHROMIUM_EFL_IMG, LIB_RO_ROOT_DIR)) { - LOG(ERROR) << "Direct mount has failed, will wait efl-install-service"; - return false; + if (IsAppzoneSupport()) { + if (!PSAgentMount(PATH_PRELOAD_CHROMIUM_EFL_IMG)) { + LOG(ERROR) << "pa-agent mount has failed, will wait efl-install-service"; + return false; + } + } else { + if (!DirectMount(PATH_PRELOAD_CHROMIUM_EFL_IMG, LIB_RO_ROOT_DIR)) { + LOG(ERROR) << "Direct mount has failed, will wait efl-install-service"; + return false; + } } - direct_mounted = true; + try_mounted = true; return true; } @@ -239,8 +325,8 @@ void TryOpenAppDefinedLib() { return; } } +#endif // defined(ENABLE_WRT_JS) #endif // BUILDFLAG(IS_TIZEN_TV) -#endif void* open_library() { if (g_impl_lib_handle) -- 2.7.4 From b7f997f4fb4c95179220de1884441cfe53a58fb4 Mon Sep 17 00:00:00 2001 From: "feifei08.liu" Date: Fri, 22 Mar 2024 18:45:49 +0800 Subject: [PATCH 12/16] [M120 Migration][VD] Add debug log for create new window process. Add some debug logs in window create process. Sometimes window.open()/target="_blank" will create a new window in app. Currently wrt not support this situation. Add some logs for locating similar issue in furture. Reference: - https://review.tizen.org/gerrit/291159/ Change-Id: I15dba40f38522b42d5cda9eea0ecf406da111c1c Signed-off-by: feifei08.liu --- content/browser/renderer_host/navigation_controller_impl.cc | 4 ++++ content/renderer/render_frame_impl.cc | 3 +++ .../content/browser/web_contents/web_contents_impl_efl.cc | 6 ++++-- tizen_src/ewk/efl_integration/eweb_view.cc | 3 +++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/content/browser/renderer_host/navigation_controller_impl.cc b/content/browser/renderer_host/navigation_controller_impl.cc index 93ac168..8de75f8 100644 --- a/content/browser/renderer_host/navigation_controller_impl.cc +++ b/content/browser/renderer_host/navigation_controller_impl.cc @@ -1275,6 +1275,10 @@ base::WeakPtr NavigationControllerImpl::LoadURLWithParams( if (params.is_renderer_initiated) DCHECK(params.initiator_origin.has_value()); +#if BUILDFLAG(IS_TIZEN_TV) + LOG(ERROR) << "url: " << params.url.possibly_invalid_spec(); +#endif + TRACE_EVENT1("browser,navigation", "NavigationControllerImpl::LoadURLWithParams", "url", params.url.possibly_invalid_spec()); diff --git a/content/renderer/render_frame_impl.cc b/content/renderer/render_frame_impl.cc index be31843..c9c6c3e 100644 --- a/content/renderer/render_frame_impl.cc +++ b/content/renderer/render_frame_impl.cc @@ -6513,6 +6513,9 @@ WebView* RenderFrameImpl::CreateNewWindow( const absl::optional& pip_options, const blink::WebURL& base_url) { consumed_user_gesture = false; +#if BUILDFLAG(IS_TIZEN_TV) + LOG(ERROR) << __FUNCTION__; +#endif mojom::CreateNewWindowParamsPtr params = mojom::CreateNewWindowParams::New(); // The user activation check is done at the browser process through diff --git a/tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.cc b/tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.cc index be4ba5c..be6905d 100644 --- a/tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.cc +++ b/tizen_src/chromium_impl/content/browser/web_contents/web_contents_impl_efl.cc @@ -123,8 +123,7 @@ FrameTree* WebContentsImplEfl::CreateNewWindow( bool has_user_gesture, SessionStorageNamespace* session_storage_namespace) { // Added for EFL implementation - LOG(INFO) << __FUNCTION__ << ", opener:" << opener - << ", target url: " << params.target_url; + LOG(INFO) << "opener:" << opener << ", target url: " << params.target_url; WebContents* new_contents = nullptr; WebViewDelegate::WebContentsCreateCallback callback = base::BindRepeating( &WebContentsImplEfl::HandleNewWebContentsCreate, base::Unretained(this), @@ -159,6 +158,9 @@ WebContents* WebContentsImplEfl::HandleNewWebContentsCreate( SessionStorageNamespace* session_storage_namespace, WebContents** new_contents_out, void* platform_data) { +#if BUILDFLAG(IS_TIZEN_TV) + LOG(ERROR) << __FUNCTION__; +#endif platform_data_for_new_window_ = platform_data; WebContentsImpl::CreateNewWindow(opener, params, is_new_browsing_instance, has_user_gesture, session_storage_namespace); diff --git a/tizen_src/ewk/efl_integration/eweb_view.cc b/tizen_src/ewk/efl_integration/eweb_view.cc index 62823cf..22539f1 100644 --- a/tizen_src/ewk/efl_integration/eweb_view.cc +++ b/tizen_src/ewk/efl_integration/eweb_view.cc @@ -633,6 +633,9 @@ bool EWebView::SetPageVisibility( bool EWebView::CreateNewWindow( content::WebViewDelegate::WebContentsCreateCallback cb) { +#if BUILDFLAG(IS_TIZEN_TV) + LOG(INFO) << __FUNCTION__; +#endif create_new_window_web_contents_cb_ = cb; Evas_Object* new_object = NULL; SmartCallback().call(&new_object); -- 2.7.4 From c17019af0cf7b0f69e8bcd873d3645ec61ce6048 Mon Sep 17 00:00:00 2001 From: jingjieli Date: Fri, 22 Mar 2024 11:37:24 +0800 Subject: [PATCH 13/16] [M120 Migration][VD]add new log tag for http request and response log Log Tag, "CHROMIUM_NETWORK" is added to separate a http network log from the log being printed with Log Tag, "CHROMIUM". It is to prevent lots of log from being printed with Log Tag, "CHROMIUM" Reference: https://review.tizen.org/gerrit/#/c/292083/ Change-Id: I59a2f2d106be723ffc8c3165035f0dabd857baca Signed-off-by: jingjieli --- net/http/http_stream_parser.cc | 17 +++++++++++++++++ net/quic/quic_http_stream.cc | 25 +++++++++++++++++++++++++ net/spdy/spdy_http_stream.cc | 26 ++++++++++++++++++++++++++ tizen_src/chromium_impl/base/base_efl.gni | 5 +++++ 4 files changed, 73 insertions(+) diff --git a/net/http/http_stream_parser.cc b/net/http/http_stream_parser.cc index 3fd45a6..e185f9a 100644 --- a/net/http/http_stream_parser.cc +++ b/net/http/http_stream_parser.cc @@ -34,6 +34,10 @@ #include "net/ssl/ssl_info.h" #include "url/url_canon.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "tizen_src/chromium_impl/base/logging_network.h" +#endif + namespace net { namespace { @@ -223,6 +227,11 @@ int HttpStreamParser::SendRequest( std::string request = request_line + headers.ToString(); request_headers_length_ = request.size(); +#if BUILDFLAG(IS_TIZEN_TV) + NET_LOGD("Request URL: %s", request_->url.spec().c_str()); + NET_LOGD("Request:\n%s\n", request.c_str()); +#endif + if (request_->upload_data_stream != nullptr) { request_body_send_buf_ = base::MakeRefCounted(kRequestBodyBufferSize); @@ -1042,6 +1051,14 @@ int HttpStreamParser::ParseResponseHeaders(int end_offset) { << response_->headers->GetContentLength() << "\n\"" << " headers = \"" << GetResponseHeaderLines(*response_->headers) << "\""; + +#if BUILDFLAG(IS_TIZEN_TV) + NET_LOGD("Response URL: %s", request_->url.spec().c_str()); + NET_LOGD("Response:\n%scontent_length: %lld\n", + GetResponseHeaderLines(*response_->headers).c_str(), + response_->headers->GetContentLength()); +#endif + return OK; } diff --git a/net/quic/quic_http_stream.cc b/net/quic/quic_http_stream.cc index e26c116..27687f3 100644 --- a/net/quic/quic_http_stream.cc +++ b/net/quic/quic_http_stream.cc @@ -33,6 +33,10 @@ #include "url/origin.h" #include "url/scheme_host_port.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "tizen_src/chromium_impl/base/logging_network.h" +#endif + namespace net { QuicHttpStream::QuicHttpStream( @@ -172,6 +176,11 @@ int QuicHttpStream::SendRequest(const HttpRequestHeaders& request_headers, if (rv == ERR_IO_PENDING) callback_ = std::move(callback); +#if BUILDFLAG(IS_TIZEN_TV) + NET_LOGD("Request URL: %s", request_info_->url.spec().c_str()); + NET_LOGD("Request Header: %s", request_headers.ToString().c_str()); +#endif + return rv > 0 ? OK : MapStreamError(rv); } @@ -603,6 +612,22 @@ int QuicHttpStream::ProcessResponseHeaders( return ERR_QUIC_PROTOCOL_ERROR; } +#if BUILDFLAG(IS_TIZEN_TV) + if (request_info_) + NET_LOGD("Response URL: %s", request_info_->url.spec().c_str()); + else + NET_LOGD("Response URL: Error, no request info"); + + HttpResponseHeaders* response_headers = response_info_->headers.get(); + std::string response_header = response_headers->GetStatusLine(); + response_header.push_back('\n'); + size_t iter = 0; + std::string name, value; + while (response_headers->EnumerateHeaderLines(&iter, &name, &value)) + response_header.append(name).append(": ").append(value).push_back('\n'); + NET_LOGD("Response Header: %s\n", response_header.c_str()); +#endif + if (response_info_->headers->response_code() == HTTP_EARLY_HINTS) { DCHECK(!response_headers_received_); headers_bytes_received_ = 0; diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index d16f6a5..60d1813 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc @@ -29,6 +29,11 @@ #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h" #include "url/scheme_host_port.h" +#if BUILDFLAG(IS_TIZEN_TV) +#include "net/http/http_response_headers.h" +#include "tizen_src/chromium_impl/base/logging_network.h" +#endif + namespace net { // Align our request body with |kMaxSpdyFrameChunkSize| to prevent unexpected @@ -238,6 +243,11 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, return result; response_info_->remote_endpoint = address; +#if BUILDFLAG(IS_TIZEN_TV) + NET_LOGD("Request URL: %s", request_info_->url.spec().c_str()); + NET_LOGD("Request Header: %s", request_headers.ToString().c_str()); +#endif + spdy::Http2HeaderBlock headers; CreateSpdyHeadersFromHttpRequest(*request_info_, priority_, request_headers, &headers); @@ -305,6 +315,22 @@ void SpdyHttpStream::OnHeadersReceived( return; } +#if BUILDFLAG(IS_TIZEN_TV) + if (request_info_) + NET_LOGD("Response URL: %s", request_info_->url.spec().c_str()); + else + NET_LOGD("Response URL: Error, no request info"); + + HttpResponseHeaders* headers = response_info_->headers.get(); + std::string response_header = headers->GetStatusLine(); + response_header.push_back('\n'); + size_t iter = 0; + std::string name, value; + while (headers->EnumerateHeaderLines(&iter, &name, &value)) + response_header.append(name).append(": ").append(value).push_back('\n'); + NET_LOGD("Response Header: %s\n", response_header.c_str()); +#endif + response_info_->response_time = stream_->response_time(); // Don't store the SSLInfo in the response here, HttpNetworkTransaction // will take care of that part. diff --git a/tizen_src/chromium_impl/base/base_efl.gni b/tizen_src/chromium_impl/base/base_efl.gni index 83210b2..9a4ff42 100644 --- a/tizen_src/chromium_impl/base/base_efl.gni +++ b/tizen_src/chromium_impl/base/base_efl.gni @@ -22,3 +22,8 @@ external_base_sources = [ "//tizen_src/chromium_impl/base/message_loop/message_pump_for_ui_efl.h", "//tizen_src/chromium_impl/base/trace_event/ttrace.h", ] + +if (tizen_product_tv) { + external_base_sources += + [ "//tizen_src/chromium_impl/base/logging_network.h" ] +} -- 2.7.4 From 97254b3e4e80005ffcec03ecebfce0774e94ce60 Mon Sep 17 00:00:00 2001 From: Chandan Padhi Date: Mon, 25 Mar 2024 13:18:34 +0530 Subject: [PATCH 14/16] fixup! Enable autofill for desktop Some of the changes got missed in the parent commit. Change-Id: I58662590dff6a27dcf361031078b1c68b5f6187c Signed-off-by: Chandan Padhi --- tizen_src/build/config/BUILD.gn | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tizen_src/build/config/BUILD.gn b/tizen_src/build/config/BUILD.gn index fa23ca0..2742003 100644 --- a/tizen_src/build/config/BUILD.gn +++ b/tizen_src/build/config/BUILD.gn @@ -20,6 +20,9 @@ config("tizen_feature_flags") { if (ewk_bringup) { defines += [ "EWK_BRINGUP" ] } + if (tizen_autofill) { + defines += [ "TIZEN_AUTOFILL" ] + } if (is_tizen) { defines += [ "OS_TIZEN", @@ -75,7 +78,6 @@ config("tizen_feature_flags") { defines += [ "ENABLE_ATMOS_DECODER" ] } if (tizen_autofill) { - defines += [ "TIZEN_AUTOFILL" ] if (tizen_autofill_fw) { defines += [ "TIZEN_AUTOFILL_FW" ] } -- 2.7.4 From 44aeebae032cbc5a2582b26f88e9137362eee66f Mon Sep 17 00:00:00 2001 From: Yu Yang Date: Thu, 21 Mar 2024 13:50:58 +0800 Subject: [PATCH 15/16] Fixup![Gamepad]fix coredump when gamepad disconnect. Gamepad connect/disconnect callback is invoked in mainthread, and gamepad read is invoked in polling thread. when gamepad disconnect, OCIGamepadItem will be accessed in mainthread and polling thread, mainthread destoring OCIGamepadItem while polling thread is still use it, that could make crash. solution: Moving all handle of OCIGamepadItem to polling thread to avoid issue. Change-Id: I3bfda2112ee78b9cf7a16ed2e92d091182a73bba Signed-off-by: Yu Yang --- .../gamepad_platform_data_fetcher_tizen_tv.cc | 125 ++++++++++++--------- .../gamepad_platform_data_fetcher_tizen_tv.h | 7 ++ .../browser/gamepad/oci_gamepad_item.cc | 13 ++- .../browser/gamepad/oci_gamepad_item.h | 4 +- 4 files changed, 90 insertions(+), 59 deletions(-) diff --git a/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc b/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc index fc0eaba..608527d 100644 --- a/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc +++ b/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.cc @@ -90,20 +90,10 @@ void GamepadPlatformDataFetcherTizenTV::MapperTizenStyleGamepad( GamepadPlatformDataFetcherTizenTV::GamepadPlatformDataFetcherTizenTV() { gamepad_manager_ = nullptr; - if (Gamepad_Create()) { -#if TIZEN_VERSION_AT_LEAST(8, 0, 0) - // initialize autoinput - VirtualKey_Initialize("gamepad-service"); -#endif - Initialize(); - } else { - LOG(ERROR) << "[Gamepad_LOG] " - "GamepadPlatformDataFetcherTizenTV::" - "GamepadPlatformDataFetcherTizenTV() Gamepad_Create() ERROR " - "!!!"; - } + polling_runner_ = nullptr; } +// invoked in polling thread GamepadPlatformDataFetcherTizenTV::~GamepadPlatformDataFetcherTizenTV() { CHECK(gamepad_manager_ != nullptr); gamepad_manager_->UnregisterCallback(this); @@ -217,6 +207,26 @@ void GamepadPlatformDataFetcherTizenTV::GetGamepadData( } } +// OnAddedToProvider is called in polling thread in initialize time +// gamepad initialize should be done here instead of constructor. +void GamepadPlatformDataFetcherTizenTV::OnAddedToProvider() { + polling_runner_ = base::SingleThreadTaskRunner::GetCurrentDefault(); + DCHECK(polling_runner_); + + if (Gamepad_Create()) { +#if TIZEN_VERSION_AT_LEAST(8, 0, 0) + // initialize autoinput + VirtualKey_Initialize("gamepad-service"); +#endif + Initialize(); + } else { + LOG(ERROR) << "[Gamepad_LOG] " + "GamepadPlatformDataFetcherTizenTV::" + "GamepadPlatformDataFetcherTizenTV() Gamepad_Create() ERROR " + "!!!"; + } +} + GamepadSource GamepadPlatformDataFetcherTizenTV::source() { return Factory::static_source(); } @@ -270,10 +280,54 @@ void GamepadPlatformDataFetcherTizenTV::InitMapping(size_t index) { UTF8toUTF16(pad.id, sizeof(pad.id), id, Gamepad::kIdLengthCap); } +void GamepadPlatformDataFetcherTizenTV::HandleGamepadConnectionStatus( + int type, + const OCIDevInfo& deviceinfo) { + LOG(INFO) << " deviceinfo.UID " << deviceinfo.UID << " deviceinfo.name " + << deviceinfo.name; + + switch (type) { + case OCI_EVENT_DEV_CONNECT: { + for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) { + if (gamepad_items_[i] == nullptr) { + LOG(INFO) << " connected"; + gamepad_items_[i] = OCIGamepadItem::Create( + gamepad_manager_, &deviceinfo, &data_.items[i], i); + if (gamepad_items_[i]) { + InitMapping(i); + break; + } + } + } + break; + } + + case OCI_EVENT_DEV_DISCONNECT: { + for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) { + if (gamepad_items_[i] != nullptr && + (strcmp(gamepad_items_[i]->GetUID(), deviceinfo.UID) == 0)) { + LOG(INFO) << " gamepad_items_[" << i << "]->GetUID() " + << gamepad_items_[i]->GetUID(); + gamepad_items_[i]->Shutdown(); + gamepad_items_[i] = nullptr; + break; + } + } + break; + } + default: { + break; + } + } +} void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type, void* pparam1, void* pparam2, void* pparam3) { + LOG(INFO) << "[Gamepad_LOG] t_OnCallback"; + LOG(INFO) << type << " pparam1 " << reinterpret_cast(pparam1); + LOG(INFO) << type << " pparam2 " << reinterpret_cast(pparam2); + int evType = 0; OCIDevInfo dev_info; std::string sType = ""; @@ -283,7 +337,6 @@ void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type, else if (type == OCI_EVENT_DEV_DISCONNECT) sType = " DISCONNECT "; - LOG(INFO) << sType << " pparam1 " << reinterpret_cast(pparam1); #if TIZEN_VERSION_AT_LEAST(8, 0, 0) strncpy(dev_info.UID, (char*)pparam1, OCI_SIZE_ID - 1); strncpy(dev_info.name, (char*)pparam2, OCI_SIZE_NAME - 1); @@ -312,45 +365,13 @@ void GamepadPlatformDataFetcherTizenTV::t_OnCallback(int type, } #endif - switch (type) { - case OCI_EVENT_DEV_CONNECT: { - for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) { - if (gamepad_items_[i] == nullptr) { - LOG(INFO) << " connected"; - gamepad_items_[i] = OCIGamepadItem::Create( - gamepad_manager_, &dev_info, &data_.items[i], i); - if (gamepad_items_[i]) { - InitMapping(i); - break; - } - } else { - continue; - } - } - break; - } - - case OCI_EVENT_DEV_DISCONNECT: { - for (size_t i = 0; i < Gamepads::kItemsLengthCap; i++) { - if (gamepad_items_[i] != nullptr && - (strcmp(gamepad_items_[i]->GetUID(), dev_info.UID) == 0)) { - LOG(INFO) << " gamepad_items_[" << i << "]->GetUID() " - << gamepad_items_[i]->GetUID(); - LOG(INFO) << " disconnected"; - gamepad_items_[i]->Shutdown(); - gamepad_items_[i] = nullptr; - break; - } - } - break; - } - case OCI_EVENT_DEV_STATUS: { - break; - } - default: { - break; - } - } + // operate gamepad in polling thread. + DCHECK(polling_runner_); + polling_runner_->PostTask( + FROM_HERE, + base::BindOnce( + &GamepadPlatformDataFetcherTizenTV::HandleGamepadConnectionStatus, + base::Unretained(this), type, dev_info)); } void GamepadPlatformDataFetcherTizenTV::PlayEffect( diff --git a/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h b/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h index 61239c5..cab6a56 100644 --- a/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h +++ b/tizen_src/ewk/efl_integration/browser/gamepad/gamepad_platform_data_fetcher_tizen_tv.h @@ -61,6 +61,7 @@ class GamepadPlatformDataFetcherTizenTV void* pparam3) override; private: + void OnAddedToProvider() override; void ReadTizenDeviceData(size_t index); void EnumerateTizenDevices(); @@ -75,6 +76,8 @@ class GamepadPlatformDataFetcherTizenTV std::string str, size_t str_length); + void HandleGamepadConnectionStatus(int type, const OCIDevInfo& deviceinfo); + // Functions to map from device data to standard layout. static void MapperTizenStyleGamepad(const Gamepad& input, Gamepad* mapped); @@ -84,6 +87,10 @@ class GamepadPlatformDataFetcherTizenTV gamepad::IGamepadManager* gamepad_manager_; std::array, Gamepads::kItemsLengthCap> gamepad_items_; + + // Task runner to use for gamepad polling. + // it will be set in OnAddedToProvider. + scoped_refptr polling_runner_; }; } // namespace device diff --git a/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.cc b/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.cc index 5420a15..572908e 100644 --- a/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.cc +++ b/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.cc @@ -44,10 +44,11 @@ void closeLatencyFile() { size_t OCIGamepadItem::s_oci_gamepaditem_num_ = 0; // static function -std::unique_ptr OCIGamepadItem::Create(IGamepadManager* manager, - OCIDevInfo* dev_info, - Gamepad* pad, - int index) { +std::unique_ptr OCIGamepadItem::Create( + IGamepadManager* manager, + const OCIDevInfo* dev_info, + Gamepad* pad, + int index) { if (manager == nullptr) { return nullptr; } @@ -135,8 +136,9 @@ bool OCIGamepadItem::InitAxisRangeTizen() { } OCIGamepadItem::OCIGamepadItem(IGamepadManager* manager, - OCIDevInfo* info, + const OCIDevInfo* info, Gamepad* pad) { + LOG(ERROR) << "[Gamepad_LOG]OCIGamepadItem construct"; CHECK(info != nullptr); memcpy(&info_, info, sizeof(OCIDevInfo)); CHECK(manager != nullptr); @@ -166,6 +168,7 @@ OCIGamepadItem::OCIGamepadItem(IGamepadManager* manager, } OCIGamepadItem::~OCIGamepadItem() { + LOG(ERROR) << "[Gamepad_LOG][~OCIGamepadItem]"; if (gamepad_ == nullptr) // CreateDevice fail, need not destroy device. return; this->DestroyDevice(); diff --git a/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h b/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h index 088adf7..d5ea0a8 100644 --- a/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h +++ b/tizen_src/ewk/efl_integration/browser/gamepad/oci_gamepad_item.h @@ -51,7 +51,7 @@ class OCIGamepadItem : public gamepad::CGamepadCallback, // static function for create OCIGamepadItem, used by // GamepadPlatformDataFetcherTizenTV static std::unique_ptr Create(IGamepadManager* manager, - OCIDevInfo* dev_info, + const OCIDevInfo* dev_info, Gamepad* pad, int index); @@ -89,7 +89,7 @@ class OCIGamepadItem : public gamepad::CGamepadCallback, OCIControllerEvent events_[kOCIGamepadItemsLength]; explicit OCIGamepadItem(IGamepadManager* manager, - OCIDevInfo* info, + const OCIDevInfo* info, Gamepad* pad); bool CreateDevice(); void DestroyDevice(); -- 2.7.4 From 745034474f1e4d5d007bf8a981b4cc533efa8b40 Mon Sep 17 00:00:00 2001 From: fangfengrong Date: Fri, 15 Mar 2024 19:53:11 +0800 Subject: [PATCH 16/16] [M120 Migration] Add mouseout event On webbrowser internal page (featured, most-visited, Bookmarks, watch later), when move mouse out of the webpage, the Blue Highlight remains in webpage. It caused by no mouse out event being delivered to js. So, keep same with M94, when receive the mouse out event callback from EFL, create a standard mouse out event and deliver it to js. refer: https://review.tizen.org/gerrit/#/c/297166 Change-Id: Id27837f957b633b594a15def0e185c6138502ca4 Signed-off-by: fangfengrong --- .../ui/ozone/platform/efl/efl_event_handler.cc | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc index 91ca651..862e74a 100644 --- a/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc +++ b/tizen_src/chromium_impl/ui/ozone/platform/efl/efl_event_handler.cc @@ -565,6 +565,7 @@ void EflEventHandler::OnMouseIn(void* data, Evas* evas, Evas_Object* obj, void* event_info) { + LOG(INFO) << "OnMouseIn"; EflEventHandler* thiz = static_cast(data); thiz->window_->UpdateFocus(true); } @@ -574,10 +575,23 @@ void EflEventHandler::OnMouseOut(void* data, Evas* evas, Evas_Object* obj, void* event_info) { -#if !BUILDFLAG(IS_TIZEN) + LOG(INFO) << "OnMouseOut"; EflEventHandler* thiz = static_cast(data); +#if !BUILDFLAG(IS_TIZEN) thiz->window_->UpdateFocus(false); #endif + Evas_Event_Mouse_Out* ev = static_cast(event_info); + + gfx::PointF root_location(ev->canvas.x, ev->canvas.y); + gfx::PointF location(ev->canvas.x, ev->canvas.y); + location.Offset(0, -thiz->GetTopControlsHeight()); + int button = EvasToUIMouseButton(ev->buttons); + int event_flags = EvasModifiersToEventFlags(ev->modifiers); + event_flags |= button; + MouseEvent event(ET_MOUSE_EXITED, location, root_location, + base::TimeTicks::Now(), event_flags, button); + + EflPlatformEventSource::GetInstance()->DispatchEflEvent(&event); } // static -- 2.7.4