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

Side by Side Diff: ui/keyboard/content/keyboard_ui_content.cc

Issue 1392713002: Extract content dependency from keyboard code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 5 years, 2 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 | « ui/keyboard/content/keyboard_ui_content.h ('k') | ui/keyboard/keyboard.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 (c) 2013 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 "ui/keyboard/content/keyboard_ui_content.h"
6
7 #include "base/command_line.h"
8 #include "base/values.h"
9 #include "content/public/browser/render_widget_host.h"
10 #include "content/public/browser/render_widget_host_iterator.h"
11 #include "content/public/browser/render_widget_host_view.h"
12 #include "content/public/browser/site_instance.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/browser/web_contents_delegate.h"
16 #include "content/public/browser/web_contents_observer.h"
17 #include "content/public/browser/web_ui.h"
18 #include "content/public/common/bindings_policy.h"
19 #include "ui/aura/layout_manager.h"
20 #include "ui/aura/window.h"
21 #include "ui/base/ime/input_method.h"
22 #include "ui/base/ime/text_input_client.h"
23 #include "ui/keyboard/content/keyboard_constants.h"
24 #include "ui/keyboard/keyboard_controller.h"
25 #include "ui/keyboard/keyboard_switches.h"
26 #include "ui/keyboard/keyboard_util.h"
27 #include "ui/wm/core/shadow.h"
28
29 namespace {
30
31 // The WebContentsDelegate for the keyboard.
32 // The delegate deletes itself when the keyboard is destroyed.
33 class KeyboardContentsDelegate : public content::WebContentsDelegate,
34 public content::WebContentsObserver {
35 public:
36 explicit KeyboardContentsDelegate(keyboard::KeyboardUIContent* ui)
37 : ui_(ui) {}
38 ~KeyboardContentsDelegate() override {}
39
40 private:
41 // Overridden from content::WebContentsDelegate:
42 content::WebContents* OpenURLFromTab(
43 content::WebContents* source,
44 const content::OpenURLParams& params) override {
45 source->GetController().LoadURL(
46 params.url, params.referrer, params.transition, params.extra_headers);
47 Observe(source);
48 return source;
49 }
50
51 bool CanDragEnter(content::WebContents* source,
52 const content::DropData& data,
53 blink::WebDragOperationsMask operations_allowed) override {
54 return false;
55 }
56
57 bool ShouldCreateWebContents(
58 content::WebContents* web_contents,
59 int route_id,
60 int main_frame_route_id,
61 WindowContainerType window_container_type,
62 const std::string& frame_name,
63 const GURL& target_url,
64 const std::string& partition_id,
65 content::SessionStorageNamespace* session_storage_namespace) override {
66 return false;
67 }
68
69 bool IsPopupOrPanel(const content::WebContents* source) const override {
70 return true;
71 }
72
73 void MoveContents(content::WebContents* source,
74 const gfx::Rect& pos) override {
75 aura::Window* keyboard = ui_->GetKeyboardWindow();
76 // keyboard window must have been added to keyboard container window at this
77 // point. Otherwise, wrong keyboard bounds is used and may cause problem as
78 // described in crbug.com/367788.
79 DCHECK(keyboard->parent());
80 // keyboard window bounds may not set to |pos| after this call. If keyboard
81 // is in FULL_WIDTH mode, only the height of keyboard window will be
82 // changed.
83 keyboard->SetBounds(pos);
84 }
85
86 // Overridden from content::WebContentsDelegate:
87 void RequestMediaAccessPermission(
88 content::WebContents* web_contents,
89 const content::MediaStreamRequest& request,
90 const content::MediaResponseCallback& callback) override {
91 ui_->RequestAudioInput(web_contents, request, callback);
92 }
93
94 // Overridden from content::WebContentsObserver:
95 void WebContentsDestroyed() override { delete this; }
96
97 keyboard::KeyboardUIContent* ui_;
98
99 DISALLOW_COPY_AND_ASSIGN(KeyboardContentsDelegate);
100 };
101
102 } // namespace
103
104 namespace keyboard {
105
106 class WindowBoundsChangeObserver : public aura::WindowObserver {
107 public:
108 explicit WindowBoundsChangeObserver(KeyboardUIContent* ui) : ui_(ui) {}
109 ~WindowBoundsChangeObserver() override {}
110
111 void AddObservedWindow(aura::Window* window) {
112 if (!window->HasObserver(this)) {
113 window->AddObserver(this);
114 observed_windows_.insert(window);
115 }
116 }
117 void RemoveAllObservedWindows() {
118 for (std::set<aura::Window*>::iterator it = observed_windows_.begin();
119 it != observed_windows_.end(); ++it)
120 (*it)->RemoveObserver(this);
121 observed_windows_.clear();
122 }
123
124 private:
125 void OnWindowBoundsChanged(aura::Window* window,
126 const gfx::Rect& old_bounds,
127 const gfx::Rect& new_bounds) override {
128 ui_->UpdateInsetsForWindow(window);
129 }
130 void OnWindowDestroyed(aura::Window* window) override {
131 if (window->HasObserver(this))
132 window->RemoveObserver(this);
133 observed_windows_.erase(window);
134 }
135
136 KeyboardUIContent* ui_;
137 std::set<aura::Window*> observed_windows_;
138
139 DISALLOW_COPY_AND_ASSIGN(WindowBoundsChangeObserver);
140 };
141
142 KeyboardUIContent::KeyboardUIContent(content::BrowserContext* context)
143 : browser_context_(context),
144 default_url_(kKeyboardURL),
145 window_bounds_observer_(new WindowBoundsChangeObserver(this)) {
146 }
147
148 KeyboardUIContent::~KeyboardUIContent() {
149 ResetInsets();
150 }
151
152 void KeyboardUIContent::LoadSystemKeyboard() {
153 DCHECK(keyboard_contents_);
154 if (keyboard_contents_->GetURL() != default_url_) {
155 // TODO(bshe): The height of system virtual keyboard and IME virtual
156 // keyboard may different. The height needs to be restored too.
157 LoadContents(default_url_);
158 }
159 }
160
161 void KeyboardUIContent::UpdateInsetsForWindow(aura::Window* window) {
162 aura::Window* keyboard_window = GetKeyboardWindow();
163 scoped_ptr<content::RenderWidgetHostIterator> widgets(
164 content::RenderWidgetHost::GetRenderWidgetHosts());
165 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
166 content::RenderWidgetHostView* view = widget->GetView();
167 if (view && window->Contains(view->GetNativeView())) {
168 gfx::Rect window_bounds = view->GetNativeView()->GetBoundsInScreen();
169 gfx::Rect intersect =
170 gfx::IntersectRects(window_bounds, keyboard_window->bounds());
171 int overlap = ShouldEnableInsets(window) ? intersect.height() : 0;
172 if (overlap > 0 && overlap < window_bounds.height())
173 view->SetInsets(gfx::Insets(0, 0, overlap, 0));
174 else
175 view->SetInsets(gfx::Insets());
176 return;
177 }
178 }
179 }
180
181 aura::Window* KeyboardUIContent::GetKeyboardWindow() {
182 if (!keyboard_contents_) {
183 content::BrowserContext* context = browser_context();
184 keyboard_contents_.reset(content::WebContents::Create(
185 content::WebContents::CreateParams(context,
186 content::SiteInstance::CreateForURL(context,
187 GetVirtualKeyboardUrl()))));
188 keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this));
189 SetupWebContents(keyboard_contents_.get());
190 LoadContents(GetVirtualKeyboardUrl());
191 keyboard_contents_->GetNativeView()->AddObserver(this);
192 }
193
194 return keyboard_contents_->GetNativeView();
195 }
196
197 bool KeyboardUIContent::HasKeyboardWindow() const {
198 return keyboard_contents_;
199 }
200
201 void KeyboardUIContent::ReloadKeyboardIfNeeded() {
202 DCHECK(keyboard_contents_);
203 if (keyboard_contents_->GetURL() != GetVirtualKeyboardUrl()) {
204 if (keyboard_contents_->GetURL().GetOrigin() !=
205 GetVirtualKeyboardUrl().GetOrigin()) {
206 // Sets keyboard window rectangle to 0 and close current page before
207 // navigate to a keyboard in a different extension. This keeps the UX the
208 // same as Android. Note we need to explicitly close current page as it
209 // might try to resize keyboard window in javascript on a resize event.
210 GetKeyboardWindow()->SetBounds(gfx::Rect());
211 keyboard_contents_->ClosePage();
212 keyboard_controller()->SetKeyboardMode(FULL_WIDTH);
213 }
214 LoadContents(GetVirtualKeyboardUrl());
215 }
216 }
217
218 void KeyboardUIContent::InitInsets(const gfx::Rect& new_bounds) {
219 // Adjust the height of the viewport for visible windows on the primary
220 // display.
221 // TODO(kevers): Add EnvObserver to properly initialize insets if a
222 // window is created while the keyboard is visible.
223 scoped_ptr<content::RenderWidgetHostIterator> widgets(
224 content::RenderWidgetHost::GetRenderWidgetHosts());
225 aura::Window* keyboard_window = GetKeyboardWindow();
226 aura::Window* root_window = keyboard_window->GetRootWindow();
227 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
228 content::RenderWidgetHostView* view = widget->GetView();
229 // Can be NULL, e.g. if the RenderWidget is being destroyed or
230 // the render process crashed.
231 if (view) {
232 aura::Window* window = view->GetNativeView();
233 // If virtual keyboard failed to load, a widget that displays error
234 // message will be created and adds as a child of the virtual keyboard
235 // window. We want to avoid add BoundsChangedObserver to that window.
236 if (!keyboard_window->Contains(window) &&
237 window->GetRootWindow() == root_window) {
238 gfx::Rect window_bounds = window->GetBoundsInScreen();
239 gfx::Rect intersect = gfx::IntersectRects(window_bounds,
240 new_bounds);
241 int overlap = intersect.height();
242 if (overlap > 0 && overlap < window_bounds.height())
243 view->SetInsets(gfx::Insets(0, 0, overlap, 0));
244 else
245 view->SetInsets(gfx::Insets());
246 AddBoundsChangedObserver(window);
247 }
248 }
249 }
250 }
251
252 void KeyboardUIContent::ResetInsets() {
253 const gfx::Insets insets;
254 scoped_ptr<content::RenderWidgetHostIterator> widgets(
255 content::RenderWidgetHost::GetRenderWidgetHosts());
256 while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
257 content::RenderWidgetHostView* view = widget->GetView();
258 if (view)
259 view->SetInsets(insets);
260 }
261 window_bounds_observer_->RemoveAllObservedWindows();
262 }
263
264 void KeyboardUIContent::SetupWebContents(content::WebContents* contents) {
265 }
266
267 void KeyboardUIContent::OnWindowBoundsChanged(aura::Window* window,
268 const gfx::Rect& old_bounds,
269 const gfx::Rect& new_bounds) {
270 if (!shadow_) {
271 shadow_.reset(new wm::Shadow());
272 shadow_->Init(wm::Shadow::STYLE_ACTIVE);
273 shadow_->layer()->SetVisible(true);
274 DCHECK(keyboard_contents_->GetNativeView()->parent());
275 keyboard_contents_->GetNativeView()->parent()->layer()->Add(
276 shadow_->layer());
277 }
278
279 shadow_->SetContentBounds(new_bounds);
280 }
281
282 void KeyboardUIContent::OnWindowDestroyed(aura::Window* window) {
283 window->RemoveObserver(this);
284 }
285
286 void KeyboardUIContent::LoadContents(const GURL& url) {
287 if (keyboard_contents_) {
288 content::OpenURLParams params(
289 url,
290 content::Referrer(),
291 SINGLETON_TAB,
292 ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
293 false);
294 keyboard_contents_->OpenURL(params);
295 }
296 }
297
298 const GURL& KeyboardUIContent::GetVirtualKeyboardUrl() {
299 if (keyboard::IsInputViewEnabled()) {
300 const GURL& override_url = GetOverrideContentUrl();
301 return override_url.is_valid() ? override_url : default_url_;
302 } else {
303 return default_url_;
304 }
305 }
306
307 bool KeyboardUIContent::ShouldEnableInsets(aura::Window* window) {
308 aura::Window* keyboard_window = GetKeyboardWindow();
309 return (keyboard_window->GetRootWindow() == window->GetRootWindow() &&
310 keyboard::IsKeyboardOverscrollEnabled() &&
311 keyboard_window->IsVisible() &&
312 keyboard_controller()->keyboard_visible());
313 }
314
315 void KeyboardUIContent::AddBoundsChangedObserver(aura::Window* window) {
316 aura::Window* target_window = window ? window->GetToplevelWindow() : nullptr;
317 if (target_window)
318 window_bounds_observer_->AddObservedWindow(target_window);
319 }
320
321 } // namespace keyboard
OLDNEW
« no previous file with comments | « ui/keyboard/content/keyboard_ui_content.h ('k') | ui/keyboard/keyboard.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698