OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/extensions/shell_window.h" | 5 #include "apps/shell_window.h" |
6 | 6 |
7 #include "apps/shell_window_geometry_cache.h" | 7 #include "apps/shell_window_geometry_cache.h" |
| 8 #include "base/strings/string_util.h" |
8 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
9 #include "base/values.h" | 10 #include "base/values.h" |
10 #include "chrome/browser/extensions/app_window_contents.h" | 11 #include "chrome/browser/extensions/app_window_contents.h" |
11 #include "chrome/browser/extensions/extension_process_manager.h" | 12 #include "chrome/browser/extensions/extension_process_manager.h" |
12 #include "chrome/browser/extensions/extension_system.h" | 13 #include "chrome/browser/extensions/extension_system.h" |
13 #include "chrome/browser/extensions/image_loader.h" | 14 #include "chrome/browser/extensions/image_loader.h" |
14 #include "chrome/browser/extensions/shell_window_registry.h" | 15 #include "chrome/browser/extensions/shell_window_registry.h" |
15 #include "chrome/browser/extensions/suggest_permission_util.h" | 16 #include "chrome/browser/extensions/suggest_permission_util.h" |
16 #include "chrome/browser/favicon/favicon_tab_helper.h" | |
17 #include "chrome/browser/file_select_helper.h" | |
18 #include "chrome/browser/lifetime/application_lifetime.h" | 17 #include "chrome/browser/lifetime/application_lifetime.h" |
19 #include "chrome/browser/media/media_capture_devices_dispatcher.h" | |
20 #include "chrome/browser/platform_util.h" | |
21 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
22 #include "chrome/browser/sessions/session_id.h" | |
23 #include "chrome/browser/ui/browser.h" | |
24 #include "chrome/browser/ui/browser_dialogs.h" | |
25 #include "chrome/browser/ui/browser_finder.h" | |
26 #include "chrome/browser/ui/browser_tabstrip.h" | |
27 #include "chrome/browser/ui/browser_window.h" | |
28 #include "chrome/browser/ui/extensions/native_app_window.h" | 19 #include "chrome/browser/ui/extensions/native_app_window.h" |
29 #include "chrome/common/chrome_notification_types.h" | 20 #include "chrome/common/chrome_notification_types.h" |
30 #include "chrome/common/extensions/extension.h" | 21 #include "chrome/common/extensions/extension.h" |
31 #include "chrome/common/extensions/extension_constants.h" | 22 #include "chrome/common/extensions/extension_constants.h" |
32 #include "chrome/common/extensions/extension_messages.h" | 23 #include "chrome/common/extensions/extension_messages.h" |
33 #include "chrome/common/extensions/manifest_handlers/icons_handler.h" | 24 #include "chrome/common/extensions/manifest_handlers/icons_handler.h" |
34 #include "components/web_modal/web_contents_modal_dialog_manager.h" | 25 #include "components/web_modal/web_contents_modal_dialog_manager.h" |
35 #include "content/public/browser/invalidate_type.h" | 26 #include "content/public/browser/invalidate_type.h" |
36 #include "content/public/browser/navigation_entry.h" | 27 #include "content/public/browser/navigation_entry.h" |
37 #include "content/public/browser/notification_details.h" | 28 #include "content/public/browser/notification_details.h" |
38 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
39 #include "content/public/browser/notification_source.h" | 30 #include "content/public/browser/notification_source.h" |
40 #include "content/public/browser/notification_types.h" | 31 #include "content/public/browser/notification_types.h" |
41 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
42 #include "content/public/browser/resource_dispatcher_host.h" | 33 #include "content/public/browser/resource_dispatcher_host.h" |
43 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
44 #include "content/public/common/media_stream_request.h" | 35 #include "content/public/common/media_stream_request.h" |
45 #include "extensions/browser/view_type_utils.h" | 36 #include "extensions/browser/view_type_utils.h" |
46 #include "skia/ext/image_operations.h" | 37 #include "skia/ext/image_operations.h" |
47 #include "third_party/skia/include/core/SkRegion.h" | 38 #include "third_party/skia/include/core/SkRegion.h" |
48 #include "ui/gfx/image/image_skia.h" | 39 #include "ui/gfx/image/image_skia.h" |
49 #include "ui/gfx/screen.h" | 40 #include "ui/gfx/screen.h" |
50 | 41 |
51 #if defined(USE_ASH) | |
52 #include "ash/launcher/launcher_types.h" | |
53 #endif | |
54 | |
55 using content::ConsoleMessageLevel; | 42 using content::ConsoleMessageLevel; |
56 using content::WebContents; | 43 using content::WebContents; |
57 using extensions::APIPermission; | 44 using extensions::APIPermission; |
58 using web_modal::WebContentsModalDialogHost; | 45 using web_modal::WebContentsModalDialogHost; |
59 using web_modal::WebContentsModalDialogManager; | 46 using web_modal::WebContentsModalDialogManager; |
60 | 47 |
61 namespace { | 48 namespace { |
62 const int kDefaultWidth = 512; | 49 const int kDefaultWidth = 512; |
63 const int kDefaultHeight = 384; | 50 const int kDefaultHeight = 384; |
64 | 51 |
65 // The preferred icon size for displaying the app icon. | 52 } // namespace |
66 #if defined(USE_ASH) | |
67 const int kPreferredIconSize = ash::kLauncherPreferredSize; | |
68 #else | |
69 const int kPreferredIconSize = extension_misc::EXTENSION_ICON_SMALL; | |
70 #endif | |
71 | 53 |
72 static bool disable_external_open_for_testing_ = false; | 54 namespace apps { |
73 | |
74 class ShellWindowLinkDelegate : public content::WebContentsDelegate { | |
75 private: | |
76 virtual content::WebContents* OpenURLFromTab( | |
77 content::WebContents* source, | |
78 const content::OpenURLParams& params) OVERRIDE; | |
79 }; | |
80 | |
81 content::WebContents* ShellWindowLinkDelegate::OpenURLFromTab( | |
82 content::WebContents* source, | |
83 const content::OpenURLParams& params) { | |
84 platform_util::OpenExternal(params.url); | |
85 delete source; | |
86 return NULL; | |
87 } | |
88 | |
89 } // namespace | |
90 | 55 |
91 ShellWindow::CreateParams::CreateParams() | 56 ShellWindow::CreateParams::CreateParams() |
92 : window_type(ShellWindow::WINDOW_TYPE_DEFAULT), | 57 : window_type(ShellWindow::WINDOW_TYPE_DEFAULT), |
93 frame(ShellWindow::FRAME_CHROME), | 58 frame(ShellWindow::FRAME_CHROME), |
94 transparent_background(false), | 59 transparent_background(false), |
95 bounds(INT_MIN, INT_MIN, 0, 0), | 60 bounds(INT_MIN, INT_MIN, 0, 0), |
96 creator_process_id(0), | 61 creator_process_id(0), |
97 state(ui::SHOW_STATE_DEFAULT), | 62 state(ui::SHOW_STATE_DEFAULT), |
98 hidden(false), | 63 hidden(false), |
99 resizable(true), | 64 resizable(true), |
100 focused(true) { | 65 focused(true) {} |
101 } | |
102 | 66 |
103 ShellWindow::CreateParams::~CreateParams() { | 67 ShellWindow::CreateParams::~CreateParams() {} |
104 } | 68 |
| 69 ShellWindow::Delegate::~Delegate() {} |
105 | 70 |
106 ShellWindow* ShellWindow::Create(Profile* profile, | 71 ShellWindow* ShellWindow::Create(Profile* profile, |
| 72 Delegate* delegate, |
107 const extensions::Extension* extension, | 73 const extensions::Extension* extension, |
108 const GURL& url, | 74 const GURL& url, |
109 const CreateParams& params) { | 75 const CreateParams& params) { |
110 // This object will delete itself when the window is closed. | 76 // This object will delete itself when the window is closed. |
111 ShellWindow* window = new ShellWindow(profile, extension); | 77 ShellWindow* window = new ShellWindow(profile, delegate, extension); |
112 window->Init(url, new AppWindowContents(window), params); | 78 window->Init(url, new AppWindowContents(window), params); |
113 extensions::ShellWindowRegistry::Get(profile)->AddShellWindow(window); | 79 extensions::ShellWindowRegistry::Get(profile)->AddShellWindow(window); |
114 return window; | 80 return window; |
115 } | 81 } |
116 | 82 |
117 ShellWindow::ShellWindow(Profile* profile, | 83 ShellWindow::ShellWindow(Profile* profile, |
| 84 Delegate* delegate, |
118 const extensions::Extension* extension) | 85 const extensions::Extension* extension) |
119 : profile_(profile), | 86 : profile_(profile), |
120 extension_(extension), | 87 extension_(extension), |
121 extension_id_(extension->id()), | 88 extension_id_(extension->id()), |
122 window_type_(WINDOW_TYPE_DEFAULT), | 89 window_type_(WINDOW_TYPE_DEFAULT), |
| 90 delegate_(delegate), |
123 image_loader_ptr_factory_(this), | 91 image_loader_ptr_factory_(this), |
124 fullscreen_for_window_api_(false), | 92 fullscreen_for_window_api_(false), |
125 fullscreen_for_tab_(false) { | 93 fullscreen_for_tab_(false) { |
126 } | 94 } |
127 | 95 |
128 void ShellWindow::Init(const GURL& url, | 96 void ShellWindow::Init(const GURL& url, |
129 ShellWindowContents* shell_window_contents, | 97 ShellWindowContents* shell_window_contents, |
130 const CreateParams& params) { | 98 const CreateParams& params) { |
131 // Initialize the render interface and web contents | 99 // Initialize the render interface and web contents |
132 shell_window_contents_.reset(shell_window_contents); | 100 shell_window_contents_.reset(shell_window_contents); |
133 shell_window_contents_->Initialize(profile(), url); | 101 shell_window_contents_->Initialize(profile(), url); |
134 WebContents* web_contents = shell_window_contents_->GetWebContents(); | 102 WebContents* web_contents = shell_window_contents_->GetWebContents(); |
| 103 delegate_->InitWebContents(web_contents); |
135 WebContentsModalDialogManager::CreateForWebContents(web_contents); | 104 WebContentsModalDialogManager::CreateForWebContents(web_contents); |
136 FaviconTabHelper::CreateForWebContents(web_contents); | |
137 | 105 |
138 web_contents->SetDelegate(this); | 106 web_contents->SetDelegate(this); |
139 WebContentsModalDialogManager::FromWebContents(web_contents)-> | 107 WebContentsModalDialogManager::FromWebContents(web_contents)-> |
140 set_delegate(this); | 108 set_delegate(this); |
141 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); | 109 extensions::SetViewType(web_contents, extensions::VIEW_TYPE_APP_SHELL); |
142 | 110 |
143 // Initialize the window | 111 // Initialize the window |
144 window_type_ = params.window_type; | 112 window_type_ = params.window_type; |
145 | 113 |
146 gfx::Rect bounds = params.bounds; | 114 gfx::Rect bounds = params.bounds; |
147 | 115 |
148 if (bounds.width() == 0) | 116 if (bounds.width() == 0) |
149 bounds.set_width(kDefaultWidth); | 117 bounds.set_width(kDefaultWidth); |
150 if (bounds.height() == 0) | 118 if (bounds.height() == 0) |
151 bounds.set_height(kDefaultHeight); | 119 bounds.set_height(kDefaultHeight); |
152 | 120 |
153 // If left and top are left undefined, the native shell window will center | 121 // If left and top are left undefined, the native shell window will center |
154 // the window on the main screen in a platform-defined manner. | 122 // the window on the main screen in a platform-defined manner. |
155 | 123 |
156 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; | 124 ui::WindowShowState cached_state = ui::SHOW_STATE_DEFAULT; |
157 if (!params.window_key.empty()) { | 125 if (!params.window_key.empty()) { |
158 window_key_ = params.window_key; | 126 window_key_ = params.window_key; |
159 | 127 |
160 apps::ShellWindowGeometryCache* cache = | 128 ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile()); |
161 apps::ShellWindowGeometryCache::Get(profile()); | |
162 | 129 |
163 gfx::Rect cached_bounds; | 130 gfx::Rect cached_bounds; |
164 gfx::Rect cached_screen_bounds; | 131 gfx::Rect cached_screen_bounds; |
165 if (cache->GetGeometry(extension()->id(), params.window_key, &cached_bounds, | 132 if (cache->GetGeometry(extension()->id(), params.window_key, &cached_bounds, |
166 &cached_screen_bounds, &cached_state)) { | 133 &cached_screen_bounds, &cached_state)) { |
167 bounds = cached_bounds; | 134 bounds = cached_bounds; |
168 // App window has cached screen bounds, make sure it fits on screen in | 135 // App window has cached screen bounds, make sure it fits on screen in |
169 // case the screen resolution changed. | 136 // case the screen resolution changed. |
170 if (!cached_screen_bounds.IsEmpty()) { | 137 if (!cached_screen_bounds.IsEmpty()) { |
171 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); | 138 gfx::Screen* screen = gfx::Screen::GetNativeScreen(); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 | 194 |
228 // When the render view host is changed, the native window needs to know | 195 // When the render view host is changed, the native window needs to know |
229 // about it in case it has any setup to do to make the renderer appear | 196 // about it in case it has any setup to do to make the renderer appear |
230 // properly. In particular, on Windows, the view's clickthrough region needs | 197 // properly. In particular, on Windows, the view's clickthrough region needs |
231 // to be set. | 198 // to be set. |
232 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, | 199 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED, |
233 content::Source<content::NavigationController>( | 200 content::Source<content::NavigationController>( |
234 &web_contents->GetController())); | 201 &web_contents->GetController())); |
235 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, | 202 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED, |
236 content::Source<Profile>(profile_)); | 203 content::Source<Profile>(profile_)); |
237 // Close when the browser is exiting. | 204 // Close when the browser process is exiting. |
238 // TODO(mihaip): we probably don't want this in the long run (when platform | |
239 // apps are no longer tied to the browser process). | |
240 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, | 205 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, |
241 content::NotificationService::AllSources()); | 206 content::NotificationService::AllSources()); |
242 | 207 |
243 shell_window_contents_->LoadContents(params.creator_process_id); | 208 shell_window_contents_->LoadContents(params.creator_process_id); |
244 | 209 |
245 // Prevent the browser process from shutting down while this window is open. | 210 // Prevent the browser process from shutting down while this window is open. |
246 chrome::StartKeepAlive(); | 211 chrome::StartKeepAlive(); |
247 | 212 |
248 UpdateExtensionAppIcon(); | 213 UpdateExtensionAppIcon(); |
249 } | 214 } |
250 | 215 |
251 ShellWindow::~ShellWindow() { | 216 ShellWindow::~ShellWindow() { |
252 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the | 217 // Unregister now to prevent getting NOTIFICATION_APP_TERMINATING if we're the |
253 // last window open. | 218 // last window open. |
254 registrar_.RemoveAll(); | 219 registrar_.RemoveAll(); |
255 | 220 |
256 // Remove shutdown prevention. | 221 // Remove shutdown prevention. |
257 chrome::EndKeepAlive(); | 222 chrome::EndKeepAlive(); |
258 } | 223 } |
259 | 224 |
260 void ShellWindow::RequestMediaAccessPermission( | 225 void ShellWindow::RequestMediaAccessPermission( |
261 content::WebContents* web_contents, | 226 content::WebContents* web_contents, |
262 const content::MediaStreamRequest& request, | 227 const content::MediaStreamRequest& request, |
263 const content::MediaResponseCallback& callback) { | 228 const content::MediaResponseCallback& callback) { |
264 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest( | 229 delegate_->RequestMediaAccessPermission(web_contents, request, callback, |
265 web_contents, request, callback, extension()); | 230 extension()); |
266 } | 231 } |
267 | 232 |
268 WebContents* ShellWindow::OpenURLFromTab(WebContents* source, | 233 WebContents* ShellWindow::OpenURLFromTab(WebContents* source, |
269 const content::OpenURLParams& params) { | 234 const content::OpenURLParams& params) { |
270 // Don't allow the current tab to be navigated. It would be nice to map all | 235 // Don't allow the current tab to be navigated. It would be nice to map all |
271 // anchor tags (even those without target="_blank") to new tabs, but right | 236 // anchor tags (even those without target="_blank") to new tabs, but right |
272 // now we can't distinguish between those and <meta> refreshes or window.href | 237 // now we can't distinguish between those and <meta> refreshes or window.href |
273 // navigations, which we don't want to allow. | 238 // navigations, which we don't want to allow. |
274 // TOOD(mihaip): Can we check for user gestures instead? | 239 // TOOD(mihaip): Can we check for user gestures instead? |
275 WindowOpenDisposition disposition = params.disposition; | 240 WindowOpenDisposition disposition = params.disposition; |
276 if (disposition == CURRENT_TAB) { | 241 if (disposition == CURRENT_TAB) { |
277 AddMessageToDevToolsConsole( | 242 AddMessageToDevToolsConsole( |
278 content::CONSOLE_MESSAGE_LEVEL_ERROR, | 243 content::CONSOLE_MESSAGE_LEVEL_ERROR, |
279 base::StringPrintf( | 244 base::StringPrintf( |
280 "Can't open same-window link to \"%s\"; try target=\"_blank\".", | 245 "Can't open same-window link to \"%s\"; try target=\"_blank\".", |
281 params.url.spec().c_str())); | 246 params.url.spec().c_str())); |
282 return NULL; | 247 return NULL; |
283 } | 248 } |
284 | 249 |
285 // These dispositions aren't really navigations. | 250 // These dispositions aren't really navigations. |
286 if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK || | 251 if (disposition == SUPPRESS_OPEN || disposition == SAVE_TO_DISK || |
287 disposition == IGNORE_ACTION) { | 252 disposition == IGNORE_ACTION) { |
288 return NULL; | 253 return NULL; |
289 } | 254 } |
290 | 255 |
291 // Force all links to open in a new tab, even if they were trying to open a | 256 WebContents* contents = delegate_->OpenURLFromTab(profile_, source, |
292 // window. | 257 params); |
293 chrome::NavigateParams new_tab_params( | 258 if (!contents) { |
294 static_cast<Browser*>(NULL), params.url, params.transition); | |
295 new_tab_params.disposition = | |
296 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; | |
297 new_tab_params.initiating_profile = profile_; | |
298 chrome::Navigate(&new_tab_params); | |
299 | |
300 if (!new_tab_params.target_contents) { | |
301 AddMessageToDevToolsConsole( | 259 AddMessageToDevToolsConsole( |
302 content::CONSOLE_MESSAGE_LEVEL_ERROR, | 260 content::CONSOLE_MESSAGE_LEVEL_ERROR, |
303 base::StringPrintf( | 261 base::StringPrintf( |
304 "Can't navigate to \"%s\"; apps do not support navigation.", | 262 "Can't navigate to \"%s\"; apps do not support navigation.", |
305 params.url.spec().c_str())); | 263 params.url.spec().c_str())); |
306 } | 264 } |
307 | 265 |
308 return new_tab_params.target_contents; | 266 return contents; |
309 } | 267 } |
310 | 268 |
311 void ShellWindow::AddNewContents(WebContents* source, | 269 void ShellWindow::AddNewContents(WebContents* source, |
312 WebContents* new_contents, | 270 WebContents* new_contents, |
313 WindowOpenDisposition disposition, | 271 WindowOpenDisposition disposition, |
314 const gfx::Rect& initial_pos, | 272 const gfx::Rect& initial_pos, |
315 bool user_gesture, | 273 bool user_gesture, |
316 bool* was_blocked) { | 274 bool* was_blocked) { |
317 DCHECK(Profile::FromBrowserContext(new_contents->GetBrowserContext()) == | 275 DCHECK(Profile::FromBrowserContext(new_contents->GetBrowserContext()) == |
318 profile_); | 276 profile_); |
319 #if defined(OS_MACOSX) || defined(OS_WIN) || \ | 277 delegate_->AddNewContents(profile_, new_contents, disposition, |
320 (defined(OS_LINUX) && !defined(OS_CHROMEOS)) | 278 initial_pos, user_gesture, was_blocked); |
321 if (disable_external_open_for_testing_) { | |
322 Browser* browser = | |
323 chrome::FindOrCreateTabbedBrowser(profile_, chrome::GetActiveDesktop()); | |
324 // Force all links to open in a new tab, even if they were trying to open a | |
325 // new window. | |
326 disposition = | |
327 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; | |
328 chrome::AddWebContents(browser, NULL, new_contents, disposition, | |
329 initial_pos, user_gesture, was_blocked); | |
330 } else { | |
331 new_contents->SetDelegate(new ShellWindowLinkDelegate()); | |
332 } | |
333 #else | |
334 Browser* browser = | |
335 chrome::FindOrCreateTabbedBrowser(profile_, chrome::GetActiveDesktop()); | |
336 // Force all links to open in a new tab, even if they were trying to open a | |
337 // new window. | |
338 disposition = | |
339 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB; | |
340 chrome::AddWebContents(browser, NULL, new_contents, disposition, initial_pos, | |
341 user_gesture, was_blocked); | |
342 #endif | |
343 } | 279 } |
344 | 280 |
345 void ShellWindow::HandleKeyboardEvent( | 281 void ShellWindow::HandleKeyboardEvent( |
346 WebContents* source, | 282 WebContents* source, |
347 const content::NativeWebKeyboardEvent& event) { | 283 const content::NativeWebKeyboardEvent& event) { |
348 native_app_window_->HandleKeyboardEvent(event); | 284 native_app_window_->HandleKeyboardEvent(event); |
349 } | 285 } |
350 | 286 |
351 void ShellWindow::RequestToLockMouse(WebContents* web_contents, | 287 void ShellWindow::RequestToLockMouse(WebContents* web_contents, |
352 bool user_gesture, | 288 bool user_gesture, |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
407 gfx::Rect ShellWindow::GetClientBounds() const { | 343 gfx::Rect ShellWindow::GetClientBounds() const { |
408 gfx::Rect bounds = native_app_window_->GetBounds(); | 344 gfx::Rect bounds = native_app_window_->GetBounds(); |
409 bounds.Inset(native_app_window_->GetFrameInsets()); | 345 bounds.Inset(native_app_window_->GetFrameInsets()); |
410 return bounds; | 346 return bounds; |
411 } | 347 } |
412 | 348 |
413 string16 ShellWindow::GetTitle() const { | 349 string16 ShellWindow::GetTitle() const { |
414 // WebContents::GetTitle() will return the page's URL if there's no <title> | 350 // WebContents::GetTitle() will return the page's URL if there's no <title> |
415 // specified. However, we'd prefer to show the name of the extension in that | 351 // specified. However, we'd prefer to show the name of the extension in that |
416 // case, so we directly inspect the NavigationEntry's title. | 352 // case, so we directly inspect the NavigationEntry's title. |
| 353 string16 title; |
417 if (!web_contents() || | 354 if (!web_contents() || |
418 !web_contents()->GetController().GetActiveEntry() || | 355 !web_contents()->GetController().GetActiveEntry() || |
419 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) | 356 web_contents()->GetController().GetActiveEntry()->GetTitle().empty()) { |
420 return UTF8ToUTF16(extension()->name()); | 357 title = UTF8ToUTF16(extension()->name()); |
421 string16 title = web_contents()->GetTitle(); | 358 } else { |
422 Browser::FormatTitleForDisplay(&title); | 359 title = web_contents()->GetTitle(); |
| 360 } |
| 361 const char16 kBadChars[] = { '\n', 0 }; |
| 362 RemoveChars(title, kBadChars, &title); |
423 return title; | 363 return title; |
424 } | 364 } |
425 | 365 |
426 void ShellWindow::SetAppIconUrl(const GURL& url) { | 366 void ShellWindow::SetAppIconUrl(const GURL& url) { |
427 // Avoid using any previous app icons were are being downloaded. | 367 // Avoid using any previous app icons were are being downloaded. |
428 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 368 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
429 | 369 |
430 app_icon_url_ = url; | 370 app_icon_url_ = url; |
431 web_contents()->DownloadImage( | 371 web_contents()->DownloadImage( |
432 url, | 372 url, |
433 true, // is a favicon | 373 true, // is a favicon |
434 kPreferredIconSize, | 374 delegate_->PreferredIconSize(), |
435 0, // no maximum size | 375 0, // no maximum size |
436 base::Bind(&ShellWindow::DidDownloadFavicon, | 376 base::Bind(&ShellWindow::DidDownloadFavicon, |
437 image_loader_ptr_factory_.GetWeakPtr())); | 377 image_loader_ptr_factory_.GetWeakPtr())); |
438 } | 378 } |
439 | 379 |
440 void ShellWindow::UpdateDraggableRegions( | 380 void ShellWindow::UpdateDraggableRegions( |
441 const std::vector<extensions::DraggableRegion>& regions) { | 381 const std::vector<extensions::DraggableRegion>& regions) { |
442 native_app_window_->UpdateDraggableRegions(regions); | 382 native_app_window_->UpdateDraggableRegions(regions); |
443 } | 383 } |
444 | 384 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 const GURL& image_url, | 425 const GURL& image_url, |
486 int requested_size, | 426 int requested_size, |
487 const std::vector<SkBitmap>& bitmaps) { | 427 const std::vector<SkBitmap>& bitmaps) { |
488 if (image_url != app_icon_url_ || bitmaps.empty()) | 428 if (image_url != app_icon_url_ || bitmaps.empty()) |
489 return; | 429 return; |
490 | 430 |
491 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap | 431 // Bitmaps are ordered largest to smallest. Choose the smallest bitmap |
492 // whose height >= the preferred size. | 432 // whose height >= the preferred size. |
493 int largest_index = 0; | 433 int largest_index = 0; |
494 for (size_t i = 1; i < bitmaps.size(); ++i) { | 434 for (size_t i = 1; i < bitmaps.size(); ++i) { |
495 if (bitmaps[i].height() < kPreferredIconSize) | 435 if (bitmaps[i].height() < delegate_->PreferredIconSize()) |
496 break; | 436 break; |
497 largest_index = i; | 437 largest_index = i; |
498 } | 438 } |
499 const SkBitmap& largest = bitmaps[largest_index]; | 439 const SkBitmap& largest = bitmaps[largest_index]; |
500 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); | 440 UpdateAppIcon(gfx::Image::CreateFrom1xBitmap(largest)); |
501 } | 441 } |
502 | 442 |
503 void ShellWindow::UpdateExtensionAppIcon() { | 443 void ShellWindow::UpdateExtensionAppIcon() { |
504 // Avoid using any previous app icons were are being downloaded. | 444 // Avoid using any previous app icons were are being downloaded. |
505 image_loader_ptr_factory_.InvalidateWeakPtrs(); | 445 image_loader_ptr_factory_.InvalidateWeakPtrs(); |
506 | 446 |
507 // Enqueue OnImageLoaded callback. | 447 // Enqueue OnImageLoaded callback. |
508 extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile()); | 448 extensions::ImageLoader* loader = extensions::ImageLoader::Get(profile()); |
509 loader->LoadImageAsync( | 449 loader->LoadImageAsync( |
510 extension(), | 450 extension(), |
511 extensions::IconsInfo::GetIconResource(extension(), | 451 extensions::IconsInfo::GetIconResource(extension(), |
512 kPreferredIconSize, | 452 delegate_->PreferredIconSize(), |
513 ExtensionIconSet::MATCH_BIGGER), | 453 ExtensionIconSet::MATCH_BIGGER), |
514 gfx::Size(kPreferredIconSize, kPreferredIconSize), | 454 gfx::Size(delegate_->PreferredIconSize(), delegate_->PreferredIconSize()), |
515 base::Bind(&ShellWindow::OnImageLoaded, | 455 base::Bind(&ShellWindow::OnImageLoaded, |
516 image_loader_ptr_factory_.GetWeakPtr())); | 456 image_loader_ptr_factory_.GetWeakPtr())); |
517 } | 457 } |
518 | 458 |
519 void ShellWindow::CloseContents(WebContents* contents) { | 459 void ShellWindow::CloseContents(WebContents* contents) { |
520 native_app_window_->Close(); | 460 native_app_window_->Close(); |
521 } | 461 } |
522 | 462 |
523 bool ShellWindow::ShouldSuppressDialogs() { | 463 bool ShellWindow::ShouldSuppressDialogs() { |
524 return true; | 464 return true; |
525 } | 465 } |
526 | 466 |
527 content::ColorChooser* ShellWindow::OpenColorChooser(WebContents* web_contents, | 467 content::ColorChooser* ShellWindow::OpenColorChooser(WebContents* web_contents, |
528 SkColor initial_color) { | 468 SkColor initial_color) { |
529 return chrome::ShowColorChooser(web_contents, initial_color); | 469 return delegate_->ShowColorChooser(web_contents, initial_color); |
530 } | 470 } |
531 | 471 |
532 void ShellWindow::RunFileChooser(WebContents* tab, | 472 void ShellWindow::RunFileChooser(WebContents* tab, |
533 const content::FileChooserParams& params) { | 473 const content::FileChooserParams& params) { |
534 if (window_type_is_panel()) { | 474 if (window_type_is_panel()) { |
535 // Panels can't host a file dialog, abort. TODO(stevenjb): allow file | 475 // Panels can't host a file dialog, abort. TODO(stevenjb): allow file |
536 // dialogs to be unhosted but still close with the owning web contents. | 476 // dialogs to be unhosted but still close with the owning web contents. |
537 // crbug.com/172502. | 477 // crbug.com/172502. |
538 LOG(WARNING) << "File dialog opened by panel."; | 478 LOG(WARNING) << "File dialog opened by panel."; |
539 return; | 479 return; |
540 } | 480 } |
541 FileSelectHelper::RunFileChooser(tab, params); | 481 |
| 482 delegate_->RunFileChooser(tab, params); |
542 } | 483 } |
543 | 484 |
544 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { | 485 bool ShellWindow::IsPopupOrPanel(const WebContents* source) const { |
545 return true; | 486 return true; |
546 } | 487 } |
547 | 488 |
548 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { | 489 void ShellWindow::MoveContents(WebContents* source, const gfx::Rect& pos) { |
549 native_app_window_->SetBounds(pos); | 490 native_app_window_->SetBounds(pos); |
550 } | 491 } |
551 | 492 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 break; | 541 break; |
601 } | 542 } |
602 case chrome::NOTIFICATION_APP_TERMINATING: | 543 case chrome::NOTIFICATION_APP_TERMINATING: |
603 native_app_window_->Close(); | 544 native_app_window_->Close(); |
604 break; | 545 break; |
605 default: | 546 default: |
606 NOTREACHED() << "Received unexpected notification"; | 547 NOTREACHED() << "Received unexpected notification"; |
607 } | 548 } |
608 } | 549 } |
609 | 550 |
| 551 void ShellWindow::SetWebContentsBlocked(content::WebContents* web_contents, |
| 552 bool blocked) { |
| 553 delegate_->SetWebContentsBlocked(web_contents, blocked); |
| 554 } |
| 555 |
| 556 bool ShellWindow::IsWebContentsVisible(content::WebContents* web_contents) { |
| 557 return delegate_->IsWebContentsVisible(web_contents); |
| 558 } |
| 559 |
610 extensions::ActiveTabPermissionGranter* | 560 extensions::ActiveTabPermissionGranter* |
611 ShellWindow::GetActiveTabPermissionGranter() { | 561 ShellWindow::GetActiveTabPermissionGranter() { |
612 // Shell windows don't support the activeTab permission. | 562 // Shell windows don't support the activeTab permission. |
613 return NULL; | 563 return NULL; |
614 } | 564 } |
615 | 565 |
616 WebContentsModalDialogHost* ShellWindow::GetWebContentsModalDialogHost() { | 566 WebContentsModalDialogHost* ShellWindow::GetWebContentsModalDialogHost() { |
617 return native_app_window_.get(); | 567 return native_app_window_.get(); |
618 } | 568 } |
619 | 569 |
620 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, | 570 void ShellWindow::AddMessageToDevToolsConsole(ConsoleMessageLevel level, |
621 const std::string& message) { | 571 const std::string& message) { |
622 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); | 572 content::RenderViewHost* rvh = web_contents()->GetRenderViewHost(); |
623 rvh->Send(new ExtensionMsg_AddMessageToConsole( | 573 rvh->Send(new ExtensionMsg_AddMessageToConsole( |
624 rvh->GetRoutingID(), level, message)); | 574 rvh->GetRoutingID(), level, message)); |
625 } | 575 } |
626 | 576 |
627 void ShellWindow::SaveWindowPosition() { | 577 void ShellWindow::SaveWindowPosition() { |
628 if (window_key_.empty()) | 578 if (window_key_.empty()) |
629 return; | 579 return; |
630 if (!native_app_window_) | 580 if (!native_app_window_) |
631 return; | 581 return; |
632 | 582 |
633 apps::ShellWindowGeometryCache* cache = | 583 ShellWindowGeometryCache* cache = ShellWindowGeometryCache::Get(profile()); |
634 apps::ShellWindowGeometryCache::Get(profile()); | |
635 | 584 |
636 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); | 585 gfx::Rect bounds = native_app_window_->GetRestoredBounds(); |
637 bounds.Inset(native_app_window_->GetFrameInsets()); | 586 bounds.Inset(native_app_window_->GetFrameInsets()); |
638 gfx::Rect screen_bounds = | 587 gfx::Rect screen_bounds = |
639 gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area(); | 588 gfx::Screen::GetNativeScreen()->GetDisplayMatching(bounds).work_area(); |
640 ui::WindowShowState window_state = native_app_window_->GetRestoredState(); | 589 ui::WindowShowState window_state = native_app_window_->GetRestoredState(); |
641 cache->SaveGeometry(extension()->id(), | 590 cache->SaveGeometry(extension()->id(), |
642 window_key_, | 591 window_key_, |
643 bounds, | 592 bounds, |
644 screen_bounds, | 593 screen_bounds, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
690 sk_region->op( | 639 sk_region->op( |
691 region.bounds.x(), | 640 region.bounds.x(), |
692 region.bounds.y(), | 641 region.bounds.y(), |
693 region.bounds.right(), | 642 region.bounds.right(), |
694 region.bounds.bottom(), | 643 region.bounds.bottom(), |
695 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); | 644 region.draggable ? SkRegion::kUnion_Op : SkRegion::kDifference_Op); |
696 } | 645 } |
697 return sk_region; | 646 return sk_region; |
698 } | 647 } |
699 | 648 |
700 void ShellWindow::DisableExternalOpenForTesting() { | 649 } // namespace apps |
701 disable_external_open_for_testing_ = true; | |
702 } | |
703 | |
OLD | NEW |