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

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

Issue 2626863006: [Chromecast] Add CastWebContents (Closed)
Patch Set: 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_contents.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 "net/base/net_errors.h"
14 #include "url/gurl.h"
15
16 #if defined(OS_ANDROID)
17 #include "chromecast/browser/android/cast_web_contents_activity.h"
18 #endif // defined(OS_ANDROID)
19
20 namespace chromecast {
21
22 namespace {
23 // The time (in milliseconds) we wait for after a page is closed (i.e.
24 // after an app is stopped) before we delete the corresponding WebContents.
25 constexpr int kWebContentsDestructionDelayInMs = 50;
26 } // namespace
27
28 CastWebContents::CastWebContents(Delegate* delegate,
29 content::BrowserContext* browser_context)
30 : delegate_(delegate),
31 browser_context_(browser_context),
32 window_(shell::CastContentWindow::Create(delegate)),
33 web_contents_(window_->CreateWebContents(browser_context_)),
alokp 2017/01/14 00:43:40 The overlap between CastContentWindow and CastWebC
derekjchow1 2017/01/18 03:21:20 Great idea. Done.
34 weak_factory_(this) {
35 DCHECK(delegate_);
36 DCHECK(browser_context_);
37 DCHECK(window_);
38 content::WebContentsObserver::Observe(web_contents_.get());
39 web_contents_->SetDelegate(this);
40 }
41
42 CastWebContents::~CastWebContents() {}
43
44 void CastWebContents::LoadUrl(GURL url) {
45 web_contents_->GetController().LoadURL(
46 url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, "");
47 }
48
49 void CastWebContents::ClosePage() {
50 content::WebContentsObserver::Observe(nullptr);
51 web_contents_->ClosePage();
52 }
53
54 void CastWebContents::CloseContents(content::WebContents* source) {
55 DCHECK_EQ(source, web_contents_.get());
56
57 // We need to delay the deletion of web_contents_ (currently for 50ms) to
58 // give (and guarantee) the renderer enough time to finish 'onunload'
59 // handler (but we don't want to wait any longer than that to delay the
60 // starting of next app).
61 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
62 FROM_HERE, base::Bind(&CastWebContents::DelayedCloseContents,
63 weak_factory_.GetWeakPtr()),
64 base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs));
65 }
66
67 void CastWebContents::DelayedCloseContents() {
68 // Delete the WebContents object here so that the gfx surface will be
69 // deleted as part of destroying RenderWidgetHostViewCast object.
70 // We want to delete the surface before we start the next app because
71 // the next app could be an external one whose Start() function would
72 // destroy the primary gfx plane.
73 web_contents_.reset();
74 delegate_->OnPageStopped(net::OK);
75 }
76
77 void CastWebContents::MakeVisible() {
78 window_->ShowWebContents(web_contents_.get());
79 web_contents_->Focus();
80 }
81
82 content::WebContents* CastWebContents::OpenURLFromTab(
83 content::WebContents* source,
84 const content::OpenURLParams& params) {
85 LOG(INFO) << "Change url: " << params.url;
86 // If source is NULL which means current tab, use web_contents_ of this class.
87 if (!source)
88 source = web_contents_.get();
89 DCHECK_EQ(source, web_contents_.get());
90 // We don't want to create another web_contents. Load url only when source is
91 // specified.
92 if (source) {
93 source->GetController().LoadURL(params.url, params.referrer,
94 params.transition, params.extra_headers);
95 }
96 return source;
97 }
98
99 void CastWebContents::LoadingStateChanged(content::WebContents* source,
100 bool to_different_document) {
101 delegate_->OnLoadingStateChanged(source->IsLoading());
102 }
103
104 void CastWebContents::ActivateContents(content::WebContents* contents) {
105 DCHECK_EQ(contents, web_contents_.get());
106 contents->GetRenderViewHost()->GetWidget()->Focus();
107 }
108
109 #if defined(OS_ANDROID)
110 base::android::ScopedJavaLocalRef<jobject>
111 CastWebContents::GetContentVideoViewEmbedder() {
112 DCHECK(web_contents_);
113 auto activity = shell::CastWebContentsActivity::Get(web_contents_.get());
114 return activity->GetContentVideoViewEmbedder();
115 }
116 #endif // defined(OS_ANDROID)
117
118 void CastWebContents::RenderProcessGone(base::TerminationStatus status) {
119 LOG(INFO) << "APP_ERROR_CHILD_PROCESS_CRASHED";
120 delegate_->OnPageStopped(net::ERR_UNEXPECTED);
121 }
122
123 void CastWebContents::DidFailProvisionalLoad(
124 content::RenderFrameHost* render_frame_host,
125 const GURL& validated_url,
126 int error_code,
127 const base::string16& error_description,
128 bool was_ignored_by_handler) {
129 // If we abort errors in an iframe, it can create a really confusing
130 // and fragile user experience. Rather than create a list of errors
131 // that are most likely to occur, we ignore all of them for now.
132 if (render_frame_host->GetParent()) {
133 LOG(ERROR) << "Got error on sub-iframe: url="
134 << validated_url.spec() << ", error=" << error_code;
135 return;
136 }
137
138 LOG(ERROR) << "Got error on provisional load: url=" << validated_url.spec()
139 << ", error_code=" << error_code
140 << "description=" << error_description;
141 delegate_->OnPageStopped(error_code);
142 }
143
144 void CastWebContents::DidFailLoad(content::RenderFrameHost* render_frame_host,
145 const GURL& validated_url,
146 int error_code,
147 const base::string16& error_description,
148 bool was_ignored_by_handler) {
149 // Only report an error if we are the main frame. See b/8433611.
150 if (render_frame_host->GetParent()) {
151 LOG(ERROR) << "Got error on sub-iframe: url="
152 << validated_url.spec() << ", error=" << error_code;
153 } else if (error_code == net::ERR_ABORTED) {
154 // ERR_ABORTED means download was aborted by the app, typically this happens
155 // when flinging URL for direct playback, the initial URLRequest gets
156 // cancelled/aborted and then the same URL is requested via the buffered
157 // data source for media::Pipeline playback.
158 LOG(INFO) << "Load canceled: url=" << validated_url.spec();
159 } else {
160 LOG(ERROR) << "Got error on load: url=" << validated_url.spec()
161 << ", error_code=" << error_code;
162 delegate_->OnPageStopped(error_code);
163 }
164 }
165
166 void CastWebContents::DidFirstVisuallyNonEmptyPaint() {
167 metrics::CastMetricsHelper::GetInstance()->LogTimeToFirstPaint();
168 }
169
170 void CastWebContents::MediaStartedPlaying(
171 const MediaPlayerInfo& media_info,
172 const MediaPlayerId& id) {
173 metrics::CastMetricsHelper::GetInstance()->LogMediaPlay();
174 }
175
176 void CastWebContents::MediaStoppedPlaying(
177 const MediaPlayerInfo& media_info,
178 const MediaPlayerId& id) {
179 metrics::CastMetricsHelper::GetInstance()->LogMediaPause();
180 }
181
182 } // namespace chromecast
OLDNEW
« no previous file with comments | « chromecast/browser/cast_web_contents.h ('k') | chromecast/browser/service/cast_service_simple.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698