Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Unified Diff: chromecast/browser/cast_web_view.cc

Issue 2626863006: [Chromecast] Add CastWebContents (Closed)
Patch Set: [Chromecast] Add CastWebContents Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chromecast/browser/cast_web_view.h ('k') | chromecast/browser/service/cast_service_simple.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chromecast/browser/cast_web_view.cc
diff --git a/chromecast/browser/cast_web_view.cc b/chromecast/browser/cast_web_view.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2259a2bbe65aed10e189a6d4be04cc901d934351
--- /dev/null
+++ b/chromecast/browser/cast_web_view.cc
@@ -0,0 +1,232 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/browser/cast_web_view.h"
+
+#include "base/logging.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "chromecast/base/metrics/cast_metrics_helper.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_view_host.h"
+#include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
+#include "ipc/ipc_message.h"
+#include "net/base/net_errors.h"
+#include "ui/display/display.h"
+#include "ui/display/screen.h"
+#include "url/gurl.h"
+
+#if defined(OS_ANDROID)
+#include "chromecast/browser/android/cast_web_contents_activity.h"
+#endif // defined(OS_ANDROID)
+
+#if defined(USE_AURA)
+#include "ui/aura/window.h"
+#endif
+
+namespace chromecast {
+
+namespace {
+// The time (in milliseconds) we wait for after a page is closed (i.e.
+// after an app is stopped) before we delete the corresponding WebContents.
+constexpr int kWebContentsDestructionDelayInMs = 50;
alokp 2017/01/19 05:26:36 this seems like a hack. How did you arrive at this
halliwell 2017/01/19 17:54:30 This is long-standing behaviour of Cast. Note tha
+
+std::unique_ptr<content::WebContents> CreateWebContents(
+ content::BrowserContext* browser_context) {
+ CHECK(display::Screen::GetScreen());
+ gfx::Size display_size =
+ display::Screen::GetScreen()->GetPrimaryDisplay().size();
+
+ content::WebContents::CreateParams create_params(browser_context, NULL);
+ create_params.routing_id = MSG_ROUTING_NONE;
+ create_params.initial_size = display_size;
+ content::WebContents* web_contents =
+ content::WebContents::Create(create_params);
+
+#if defined(USE_AURA)
+ // Resize window
+ aura::Window* content_window = web_contents->GetNativeView();
+ content_window->SetBounds(
+ gfx::Rect(display_size.width(), display_size.height()));
+#endif
+
+#if defined(OS_ANDROID)
+ content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
+ prefs->use_video_overlay_for_embedded_encrypted_video = true;
+ web_contents->GetRenderViewHost()->SyncRendererPrefs();
+#endif
+
+ return base::WrapUnique(web_contents);
+}
+
+} // namespace
+
+CastWebView::CastWebView(Delegate* delegate,
+ content::BrowserContext* browser_context,
+ GURL url,
+ bool transparent)
+ : delegate_(delegate),
+ browser_context_(browser_context),
+ transparent_(transparent),
+ window_(shell::CastContentWindow::Create(delegate)),
+ web_contents_(CreateWebContents(browser_context_)),
+ weak_factory_(this) {
+ DCHECK(delegate_);
+ DCHECK(browser_context_);
+ DCHECK(window_);
+ content::WebContentsObserver::Observe(web_contents_.get());
+ web_contents_->SetDelegate(this);
+
+ if (transparent_)
+ window_->SetTransparent();
+
+ web_contents_->GetController().LoadURL(
+ url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, "");
+}
+
+CastWebView::~CastWebView() {}
+
+void CastWebView::ClosePage() {
+ content::WebContentsObserver::Observe(nullptr);
+ web_contents_->ClosePage();
+}
+
+void CastWebView::CloseContents(content::WebContents* source) {
alokp 2017/01/19 05:26:36 nit: please define functions in the same order as
derekjchow1 2017/01/19 21:59:16 Done (regarding reordering). Although this functi
+ DCHECK_EQ(source, web_contents_.get());
+
+ // We need to delay the deletion of web_contents_ (currently for 50ms) to
+ // give (and guarantee) the renderer enough time to finish 'onunload'
+ // handler (but we don't want to wait any longer than that to delay the
+ // starting of next app).
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, base::Bind(&CastWebView::DelayedCloseContents,
alokp 2017/01/19 05:26:36 Hmm. I do not understand this code. You do not sta
derekjchow1 2017/01/19 21:59:16 I added an additional comment. This function gets
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs));
+}
+
+void CastWebView::DelayedCloseContents() {
+ // Delete the WebContents object here so that the gfx surface will be
+ // deleted as part of destroying RenderWidgetHostViewCast object.
+ // We want to delete the surface before we start the next app because
+ // the next app could be an external one whose Start() function would
+ // destroy the primary gfx plane.
+ web_contents_.reset();
+ delegate_->OnPageStopped(net::OK);
+}
+
+void CastWebView::Show() {
+ window_->ShowWebContents(web_contents_.get());
+ web_contents_->Focus();
+}
+
+content::WebContents* CastWebView::OpenURLFromTab(
+ content::WebContents* source,
+ const content::OpenURLParams& params) {
+ LOG(INFO) << "Change url: " << params.url;
+ // If source is NULL which means current tab, use web_contents_ of this class.
+ if (!source)
+ source = web_contents_.get();
+ DCHECK_EQ(source, web_contents_.get());
+ // We don't want to create another web_contents. Load url only when source is
+ // specified.
+ if (source) {
+ source->GetController().LoadURL(params.url, params.referrer,
+ params.transition, params.extra_headers);
+ }
+ return source;
+}
+
+void CastWebView::LoadingStateChanged(content::WebContents* source,
+ bool to_different_document) {
+ delegate_->OnLoadingStateChanged(source->IsLoading());
+}
+
+void CastWebView::ActivateContents(content::WebContents* contents) {
+ DCHECK_EQ(contents, web_contents_.get());
+ contents->GetRenderViewHost()->GetWidget()->Focus();
+}
+
+#if defined(OS_ANDROID)
+base::android::ScopedJavaLocalRef<jobject>
+CastWebView::GetContentVideoViewEmbedder() {
+ DCHECK(web_contents_);
+ auto activity = shell::CastWebContentsActivity::Get(web_contents_.get());
+ return activity->GetContentVideoViewEmbedder();
+}
+#endif // defined(OS_ANDROID)
+
+void CastWebView::RenderProcessGone(base::TerminationStatus status) {
+ LOG(INFO) << "APP_ERROR_CHILD_PROCESS_CRASHED";
+ delegate_->OnPageStopped(net::ERR_UNEXPECTED);
+}
+
+void CastWebView::RenderViewCreated(content::RenderViewHost* render_view_host) {
+ content::RenderWidgetHostView* view =
+ render_view_host->GetWidget()->GetView();
+ if (view) {
+ view->SetBackgroundColor(transparent_ ? SK_ColorTRANSPARENT
+ : SK_ColorBLACK);
+ }
+}
+
+void CastWebView::DidFailProvisionalLoad(
+ content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url,
+ int error_code,
+ const base::string16& error_description,
+ bool was_ignored_by_handler) {
+ // If we abort errors in an iframe, it can create a really confusing
+ // and fragile user experience. Rather than create a list of errors
+ // that are most likely to occur, we ignore all of them for now.
+ if (render_frame_host->GetParent()) {
+ LOG(ERROR) << "Got error on sub-iframe: url="
+ << validated_url.spec() << ", error=" << error_code;
+ return;
+ }
+
+ LOG(ERROR) << "Got error on provisional load: url=" << validated_url.spec()
+ << ", error_code=" << error_code
+ << "description=" << error_description;
+ delegate_->OnPageStopped(error_code);
+}
+
+void CastWebView::DidFailLoad(content::RenderFrameHost* render_frame_host,
+ const GURL& validated_url,
+ int error_code,
+ const base::string16& error_description,
+ bool was_ignored_by_handler) {
+ // Only report an error if we are the main frame. See b/8433611.
+ if (render_frame_host->GetParent()) {
+ LOG(ERROR) << "Got error on sub-iframe: url="
+ << validated_url.spec() << ", error=" << error_code;
+ } else if (error_code == net::ERR_ABORTED) {
+ // ERR_ABORTED means download was aborted by the app, typically this happens
+ // when flinging URL for direct playback, the initial URLRequest gets
+ // cancelled/aborted and then the same URL is requested via the buffered
+ // data source for media::Pipeline playback.
+ LOG(INFO) << "Load canceled: url=" << validated_url.spec();
+ } else {
+ LOG(ERROR) << "Got error on load: url=" << validated_url.spec()
+ << ", error_code=" << error_code;
+ delegate_->OnPageStopped(error_code);
+ }
+}
+
+void CastWebView::DidFirstVisuallyNonEmptyPaint() {
+ metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstPaint();
+}
+
+void CastWebView::MediaStartedPlaying(
+ const MediaPlayerInfo& media_info,
+ const MediaPlayerId& id) {
+ metrics::CastMetricsHelper::GetInstance()->LogMediaPlay();
+}
+
+void CastWebView::MediaStoppedPlaying(
+ const MediaPlayerInfo& media_info,
+ const MediaPlayerId& id) {
+ metrics::CastMetricsHelper::GetInstance()->LogMediaPause();
+}
+
+} // namespace chromecast
« no previous file with comments | « chromecast/browser/cast_web_view.h ('k') | chromecast/browser/service/cast_service_simple.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698