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