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

Side by Side Diff: chromecast/browser/cast_web_view.cc

Issue 2626863006: [Chromecast] Add CastWebContents (Closed)
Patch Set: s/CastWebContents/CastWebView/g 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chromecast/browser/cast_web_view.h"
6
7 #include "base/logging.h"
8 #include "base/threading/thread_task_runner_handle.h"
9 #include "chromecast/base/metrics/cast_metrics_helper.h"
10 #include "content/public/browser/render_frame_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/render_widget_host.h"
13 #include "content/public/browser/render_widget_host_view.h"
14 #include "ipc/ipc_message.h"
15 #include "net/base/net_errors.h"
16 #include "ui/display/display.h"
17 #include "ui/display/screen.h"
18 #include "url/gurl.h"
19
20 #if defined(OS_ANDROID)
21 #include "chromecast/browser/android/cast_web_contents_activity.h"
22 #endif // defined(OS_ANDROID)
23
24 #if defined(USE_AURA)
25 #include "ui/aura/window.h"
26 #endif
27
28 namespace chromecast {
29
30 namespace {
31 // The time (in milliseconds) we wait for after a page is closed (i.e.
32 // after an app is stopped) before we delete the corresponding WebContents.
33 constexpr int kWebContentsDestructionDelayInMs = 50;
34
35 std::unique_ptr<content::WebContents> CreateWebContents(
36 content::BrowserContext* browser_context) {
37 CHECK(display::Screen::GetScreen());
38 gfx::Size display_size =
39 display::Screen::GetScreen()->GetPrimaryDisplay().size();
40
41 content::WebContents::CreateParams create_params(browser_context, NULL);
42 create_params.routing_id = MSG_ROUTING_NONE;
43 create_params.initial_size = display_size;
44 content::WebContents* web_contents =
45 content::WebContents::Create(create_params);
46
47 #if defined(USE_AURA)
48 // Resize window
49 aura::Window* content_window = web_contents->GetNativeView();
50 content_window->SetBounds(
51 gfx::Rect(display_size.width(), display_size.height()));
52 #endif
53
54 #if defined(OS_ANDROID)
55 content::RendererPreferences* prefs = web_contents->GetMutableRendererPrefs();
56 prefs->use_video_overlay_for_embedded_encrypted_video = true;
57 web_contents->GetRenderViewHost()->SyncRendererPrefs();
58 #endif
59
60 return base::WrapUnique(web_contents);
61 }
62
63 } // namespace
64
65 CastWebView::CastWebView(Delegate* delegate,
66 content::BrowserContext* browser_context,
67 bool transparent)
68 : delegate_(delegate),
69 browser_context_(browser_context),
70 transparent_(transparent),
71 window_(shell::CastContentWindow::Create(delegate)),
72 web_contents_(CreateWebContents(browser_context_)),
73 weak_factory_(this) {
74 DCHECK(delegate_);
75 DCHECK(browser_context_);
76 DCHECK(window_);
77 content::WebContentsObserver::Observe(web_contents_.get());
78 web_contents_->SetDelegate(this);
79
80 if (transparent_)
81 window_->SetTransparent();
82 }
83
84 CastWebView::~CastWebView() {}
85
86 void CastWebView::LoadUrl(GURL url) {
87 web_contents_->GetController().LoadURL(
88 url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, "");
89 }
90
91 void CastWebView::ClosePage() {
92 content::WebContentsObserver::Observe(nullptr);
93 web_contents_->ClosePage();
94 }
95
96 void CastWebView::CloseContents(content::WebContents* source) {
97 DCHECK_EQ(source, web_contents_.get());
98
99 // We need to delay the deletion of web_contents_ (currently for 50ms) to
100 // give (and guarantee) the renderer enough time to finish 'onunload'
101 // handler (but we don't want to wait any longer than that to delay the
102 // starting of next app).
103 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
104 FROM_HERE, base::Bind(&CastWebView::DelayedCloseContents,
105 weak_factory_.GetWeakPtr()),
106 base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs));
107 }
108
109 void CastWebView::DelayedCloseContents() {
110 // Delete the WebContents object here so that the gfx surface will be
111 // deleted as part of destroying RenderWidgetHostViewCast object.
112 // We want to delete the surface before we start the next app because
113 // the next app could be an external one whose Start() function would
114 // destroy the primary gfx plane.
115 web_contents_.reset();
116 delegate_->OnPageStopped(net::OK);
117 }
118
119 void CastWebView::MakeVisible() {
120 window_->ShowWebContents(web_contents_.get());
121 web_contents_->Focus();
122 }
123
124 content::WebContents* CastWebView::OpenURLFromTab(
125 content::WebContents* source,
126 const content::OpenURLParams& params) {
127 LOG(INFO) << "Change url: " << params.url;
128 // If source is NULL which means current tab, use web_contents_ of this class.
129 if (!source)
130 source = web_contents_.get();
131 DCHECK_EQ(source, web_contents_.get());
132 // We don't want to create another web_contents. Load url only when source is
133 // specified.
134 if (source) {
135 source->GetController().LoadURL(params.url, params.referrer,
136 params.transition, params.extra_headers);
137 }
138 return source;
139 }
140
141 void CastWebView::LoadingStateChanged(content::WebContents* source,
142 bool to_different_document) {
143 delegate_->OnLoadingStateChanged(source->IsLoading());
144 }
145
146 void CastWebView::ActivateContents(content::WebContents* contents) {
147 DCHECK_EQ(contents, web_contents_.get());
148 contents->GetRenderViewHost()->GetWidget()->Focus();
149 }
150
151 #if defined(OS_ANDROID)
152 base::android::ScopedJavaLocalRef<jobject>
153 CastWebView::GetContentVideoViewEmbedder() {
154 DCHECK(web_contents_);
155 auto activity = shell::CastWebContentsActivity::Get(web_contents_.get());
156 return activity->GetContentVideoViewEmbedder();
157 }
158 #endif // defined(OS_ANDROID)
159
160 void CastWebView::RenderProcessGone(base::TerminationStatus status) {
161 LOG(INFO) << "APP_ERROR_CHILD_PROCESS_CRASHED";
162 delegate_->OnPageStopped(net::ERR_UNEXPECTED);
163 }
164
165 void CastWebView::RenderViewCreated(content::RenderViewHost* render_view_host) {
166 content::RenderWidgetHostView* view =
167 render_view_host->GetWidget()->GetView();
168 if (view) {
169 view->SetBackgroundColor(transparent_ ? SK_ColorTRANSPARENT
170 : SK_ColorBLACK);
171 }
172 }
173
174 void CastWebView::DidFailProvisionalLoad(
175 content::RenderFrameHost* render_frame_host,
176 const GURL& validated_url,
177 int error_code,
178 const base::string16& error_description,
179 bool was_ignored_by_handler) {
180 // If we abort errors in an iframe, it can create a really confusing
181 // and fragile user experience. Rather than create a list of errors
182 // that are most likely to occur, we ignore all of them for now.
183 if (render_frame_host->GetParent()) {
184 LOG(ERROR) << "Got error on sub-iframe: url="
185 << validated_url.spec() << ", error=" << error_code;
186 return;
187 }
188
189 LOG(ERROR) << "Got error on provisional load: url=" << validated_url.spec()
190 << ", error_code=" << error_code
191 << "description=" << error_description;
192 delegate_->OnPageStopped(error_code);
193 }
194
195 void CastWebView::DidFailLoad(content::RenderFrameHost* render_frame_host,
196 const GURL& validated_url,
197 int error_code,
198 const base::string16& error_description,
199 bool was_ignored_by_handler) {
200 // Only report an error if we are the main frame. See b/8433611.
201 if (render_frame_host->GetParent()) {
202 LOG(ERROR) << "Got error on sub-iframe: url="
203 << validated_url.spec() << ", error=" << error_code;
204 } else if (error_code == net::ERR_ABORTED) {
205 // ERR_ABORTED means download was aborted by the app, typically this happens
206 // when flinging URL for direct playback, the initial URLRequest gets
207 // cancelled/aborted and then the same URL is requested via the buffered
208 // data source for media::Pipeline playback.
209 LOG(INFO) << "Load canceled: url=" << validated_url.spec();
210 } else {
211 LOG(ERROR) << "Got error on load: url=" << validated_url.spec()
212 << ", error_code=" << error_code;
213 delegate_->OnPageStopped(error_code);
214 }
215 }
216
217 void CastWebView::DidFirstVisuallyNonEmptyPaint() {
218 metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstPaint();
219 }
220
221 void CastWebView::MediaStartedPlaying(
222 const MediaPlayerInfo& media_info,
223 const MediaPlayerId& id) {
224 metrics::CastMetricsHelper::GetInstance()->LogMediaPlay();
225 }
226
227 void CastWebView::MediaStoppedPlaying(
228 const MediaPlayerInfo& media_info,
229 const MediaPlayerId& id) {
230 metrics::CastMetricsHelper::GetInstance()->LogMediaPause();
231 }
232
233 } // namespace chromecast
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698