Reorganizes Chromecast code to better reflect functional dependencies.
[chromium-blink-merge.git] / chromecast / browser / android / cast_window_android.cc
blob439c65166f98a4cd50914b4596f324762f236db2
1 // Copyright 2014 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.
5 #include "chromecast/browser/android/cast_window_android.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "base/path_service.h"
9 #include "chromecast/browser/android/cast_window_manager.h"
10 #include "content/public/browser/devtools_agent_host.h"
11 #include "content/public/browser/navigation_controller.h"
12 #include "content/public/browser/navigation_entry.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/common/renderer_preferences.h"
15 #include "jni/CastWindowAndroid_jni.h"
17 namespace chromecast {
18 namespace shell {
20 namespace {
22 // The time (in milliseconds) we wait for after a page is closed (i.e.
23 // after an app is stopped) before we delete the corresponding WebContents.
24 const int kWebContentsDestructionDelayInMs = 50;
26 } // namespace
28 // static
29 bool CastWindowAndroid::RegisterJni(JNIEnv* env) {
30 return RegisterNativesImpl(env);
33 CastWindowAndroid::CastWindowAndroid(content::WebContents* web_contents)
34 : content::WebContentsObserver(web_contents),
35 weak_factory_(this) {
38 CastWindowAndroid::~CastWindowAndroid() {
41 // static
42 CastWindowAndroid* CastWindowAndroid::CreateNewWindow(
43 content::BrowserContext* browser_context,
44 const GURL& url) {
45 content::WebContents::CreateParams create_params(browser_context);
46 create_params.routing_id = MSG_ROUTING_NONE;
47 content::WebContents* web_contents =
48 content::WebContents::Create(create_params);
49 CastWindowAndroid* shell = CreateCastWindowAndroid(
50 web_contents,
51 create_params.initial_size);
52 if (!url.is_empty())
53 shell->LoadURL(url);
54 return shell;
57 // static
58 CastWindowAndroid* CastWindowAndroid::CreateCastWindowAndroid(
59 content::WebContents* web_contents,
60 const gfx::Size& initial_size) {
61 CastWindowAndroid* shell = new CastWindowAndroid(web_contents);
63 JNIEnv* env = base::android::AttachCurrentThread();
64 base::android::ScopedJavaLocalRef<jobject> shell_android(
65 CreateCastWindowView(shell));
67 shell->java_object_.Reset(env, shell_android.Release());
68 shell->web_contents_.reset(web_contents);
69 web_contents->SetDelegate(shell);
71 Java_CastWindowAndroid_initFromNativeWebContents(
72 env, shell->java_object_.obj(), reinterpret_cast<jint>(web_contents));
74 // Enabling hole-punching also requires runtime renderer preference
75 web_contents->GetMutableRendererPrefs()->
76 use_video_overlay_for_embedded_encrypted_video = true;
77 web_contents->GetRenderViewHost()->SyncRendererPrefs();
79 return shell;
82 void CastWindowAndroid::Close() {
83 // Close page first, which fires the window.unload event. The WebContents
84 // itself will be destroyed after browser-process has received renderer
85 // notification that the page is closed.
86 web_contents_->GetRenderViewHost()->ClosePage();
89 void CastWindowAndroid::Destroy() {
90 // Note: if multiple windows becomes supported, this may close other devtools
91 // sessions.
92 content::DevToolsAgentHost::DetachAllClients();
93 CloseCastWindowView(java_object_.obj());
94 delete this;
97 void CastWindowAndroid::LoadURL(const GURL& url) {
98 content::NavigationController::LoadURLParams params(url);
99 params.transition_type = ui::PageTransitionFromInt(
100 ui::PAGE_TRANSITION_TYPED |
101 ui::PAGE_TRANSITION_FROM_ADDRESS_BAR);
102 web_contents_->GetController().LoadURLWithParams(params);
103 web_contents_->Focus();
106 void CastWindowAndroid::AddNewContents(content::WebContents* source,
107 content::WebContents* new_contents,
108 WindowOpenDisposition disposition,
109 const gfx::Rect& initial_pos,
110 bool user_gesture,
111 bool* was_blocked) {
112 NOTIMPLEMENTED();
113 if (was_blocked) {
114 *was_blocked = true;
118 void CastWindowAndroid::CloseContents(content::WebContents* source) {
119 DCHECK_EQ(source, web_contents_.get());
121 // We need to delay the deletion of web_contents_ (currently for 50ms) to
122 // give (and guarantee) the renderer enough time to finish 'onunload'
123 // handler (but we don't want to wait any longer than that to delay the
124 // starting of next app).
126 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType)) {
127 // When shutting down in a test context, the last remaining WebContents
128 // is torn down at browser-thread shutdown time. Call Destroy directly to
129 // avoid losing the last posted task to delete this object.
130 // TODO(gunsch): This could probably be avoided by using a
131 // CompletionCallback in StopCurrentApp to wait until the app is completely
132 // stopped. This might require a separate message loop and might only be
133 // appropriate for test contexts or during shutdown, since it triggers a
134 // wait on the main thread.
135 Destroy();
136 return;
139 base::MessageLoopProxy::current()->PostDelayedTask(
140 FROM_HERE,
141 base::Bind(&CastWindowAndroid::Destroy, weak_factory_.GetWeakPtr()),
142 base::TimeDelta::FromMilliseconds(kWebContentsDestructionDelayInMs));
145 bool CastWindowAndroid::CanOverscrollContent() const {
146 return false;
149 bool CastWindowAndroid::AddMessageToConsole(content::WebContents* source,
150 int32 level,
151 const base::string16& message,
152 int32 line_no,
153 const base::string16& source_id) {
154 return false;
157 void CastWindowAndroid::ActivateContents(content::WebContents* contents) {
158 DCHECK_EQ(contents, web_contents_.get());
159 contents->GetRenderViewHost()->Focus();
162 void CastWindowAndroid::DeactivateContents(content::WebContents* contents) {
163 DCHECK_EQ(contents, web_contents_.get());
164 contents->GetRenderViewHost()->Blur();
167 void CastWindowAndroid::RenderProcessGone(base::TerminationStatus status) {
168 LOG(ERROR) << "Render process gone: status=" << status;
169 Destroy();
172 } // namespace shell
173 } // namespace chromecast