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

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

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