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 "chrome/browser/ui/apps/chrome_app_delegate.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/strings/stringprintf.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/file_select_helper.h"
11 #include "chrome/browser/media/media_capture_devices_dispatcher.h"
12 #include "chrome/browser/platform_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/shell_integration.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_dialogs.h"
17 #include "chrome/browser/ui/browser_tabstrip.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
20 #include "chrome/common/extensions/chrome_extension_messages.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/render_view_host.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/browser/web_contents_delegate.h"
25 #include "extensions/common/constants.h"
28 #include "ash/shelf/shelf_constants.h"
31 #if defined(ENABLE_PRINTING)
32 #if defined(ENABLE_FULL_PRINTING)
33 #include "chrome/browser/printing/print_preview_message_handler.h"
34 #include "chrome/browser/printing/print_view_manager.h"
36 #include "chrome/browser/printing/print_view_manager_basic.h"
37 #endif // defined(ENABLE_FULL_PRINTING)
38 #endif // defined(ENABLE_PRINTING)
42 bool disable_external_open_for_testing_ = false;
44 // Opens a URL with Chromium (not external browser) with the right profile.
45 content::WebContents* OpenURLFromTabInternal(
46 content::BrowserContext* context,
47 const content::OpenURLParams& params) {
48 // Force all links to open in a new tab, even if they were trying to open a
50 chrome::NavigateParams new_tab_params(
51 static_cast<Browser*>(NULL), params.url, params.transition);
52 if (params.disposition == NEW_BACKGROUND_TAB) {
53 new_tab_params.disposition = NEW_BACKGROUND_TAB;
55 new_tab_params.disposition = NEW_FOREGROUND_TAB;
56 new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
59 new_tab_params.initiating_profile = Profile::FromBrowserContext(context);
60 chrome::Navigate(&new_tab_params);
62 return new_tab_params.target_contents;
65 // Helper class that opens a URL based on if this browser instance is the
66 // default system browser. If it is the default, open the URL directly instead
67 // of asking the system to open it.
68 class OpenURLFromTabBasedOnBrowserDefault
69 : public ShellIntegration::DefaultWebClientObserver {
71 OpenURLFromTabBasedOnBrowserDefault(scoped_ptr<content::WebContents> source,
72 const content::OpenURLParams& params)
73 : source_(source.Pass()), params_(params) {}
75 // Opens a URL when called with the result of if this is the default system
77 virtual void SetDefaultWebClientUIState(
78 ShellIntegration::DefaultWebClientUIState state) OVERRIDE {
80 Profile::FromBrowserContext(source_->GetBrowserContext());
85 case ShellIntegration::STATE_PROCESSING:
87 case ShellIntegration::STATE_IS_DEFAULT:
88 OpenURLFromTabInternal(profile, params_);
90 case ShellIntegration::STATE_NOT_DEFAULT:
91 case ShellIntegration::STATE_UNKNOWN:
92 platform_util::OpenExternal(profile, params_.url);
97 virtual bool IsOwnedByWorker() OVERRIDE { return true; }
100 scoped_ptr<content::WebContents> source_;
101 const content::OpenURLParams params_;
106 class ChromeAppDelegate::NewWindowContentsDelegate
107 : public content::WebContentsDelegate {
109 NewWindowContentsDelegate() {}
110 virtual ~NewWindowContentsDelegate() {}
112 virtual content::WebContents* OpenURLFromTab(
113 content::WebContents* source,
114 const content::OpenURLParams& params) OVERRIDE;
117 DISALLOW_COPY_AND_ASSIGN(NewWindowContentsDelegate);
120 content::WebContents*
121 ChromeAppDelegate::NewWindowContentsDelegate::OpenURLFromTab(
122 content::WebContents* source,
123 const content::OpenURLParams& params) {
125 // This NewWindowContentsDelegate was given ownership of the incoming
126 // WebContents by being assigned as its delegate within
127 // ChromeAppDelegate::AddNewContents, but this is the first time
128 // NewWindowContentsDelegate actually sees the WebContents.
129 // Here it is captured for deletion.
130 scoped_ptr<content::WebContents> owned_source(source);
131 scoped_refptr<ShellIntegration::DefaultWebClientWorker>
132 check_if_default_browser_worker =
133 new ShellIntegration::DefaultBrowserWorker(
134 new OpenURLFromTabBasedOnBrowserDefault(owned_source.Pass(),
136 // Object lifetime notes: The OpenURLFromTabBasedOnBrowserDefault is owned
137 // by check_if_default_browser_worker. StartCheckIsDefault() takes lifetime
138 // ownership of check_if_default_browser_worker and will clean up after
139 // the asynchronous tasks.
140 check_if_default_browser_worker->StartCheckIsDefault();
145 ChromeAppDelegate::ChromeAppDelegate()
146 : new_window_contents_delegate_(new NewWindowContentsDelegate()) {
149 ChromeAppDelegate::~ChromeAppDelegate() {
152 void ChromeAppDelegate::DisableExternalOpenForTesting() {
153 disable_external_open_for_testing_ = true;
156 void ChromeAppDelegate::InitWebContents(content::WebContents* web_contents) {
157 FaviconTabHelper::CreateForWebContents(web_contents);
159 #if defined(ENABLE_PRINTING)
160 #if defined(ENABLE_FULL_PRINTING)
161 printing::PrintViewManager::CreateForWebContents(web_contents);
162 printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
164 printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
165 #endif // defined(ENABLE_FULL_PRINTING)
166 #endif // defined(ENABLE_PRINTING)
169 content::WebContents* ChromeAppDelegate::OpenURLFromTab(
170 content::BrowserContext* context,
171 content::WebContents* source,
172 const content::OpenURLParams& params) {
173 return OpenURLFromTabInternal(context, params);
176 void ChromeAppDelegate::AddNewContents(content::BrowserContext* context,
177 content::WebContents* new_contents,
178 WindowOpenDisposition disposition,
179 const gfx::Rect& initial_pos,
182 if (!disable_external_open_for_testing_) {
183 // We don't really want to open a window for |new_contents|, but we need to
184 // capture its intended navigation. Here we give ownership to the
185 // NewWindowContentsDelegate, which will dispose of the contents once
186 // a navigation is captured.
187 new_contents->SetDelegate(new_window_contents_delegate_.get());
190 chrome::ScopedTabbedBrowserDisplayer displayer(
191 Profile::FromBrowserContext(context), chrome::GetActiveDesktop());
192 // Force all links to open in a new tab, even if they were trying to open a
195 disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB;
196 chrome::AddWebContents(displayer.browser(),
205 content::ColorChooser* ChromeAppDelegate::ShowColorChooser(
206 content::WebContents* web_contents,
207 SkColor initial_color) {
208 return chrome::ShowColorChooser(web_contents, initial_color);
211 void ChromeAppDelegate::RunFileChooser(
212 content::WebContents* tab,
213 const content::FileChooserParams& params) {
214 FileSelectHelper::RunFileChooser(tab, params);
217 void ChromeAppDelegate::RequestMediaAccessPermission(
218 content::WebContents* web_contents,
219 const content::MediaStreamRequest& request,
220 const content::MediaResponseCallback& callback,
221 const extensions::Extension* extension) {
222 MediaCaptureDevicesDispatcher::GetInstance()->ProcessMediaAccessRequest(
223 web_contents, request, callback, extension);
226 int ChromeAppDelegate::PreferredIconSize() {
228 return ash::kShelfSize;
230 return extension_misc::EXTENSION_ICON_SMALL;
234 void ChromeAppDelegate::SetWebContentsBlocked(
235 content::WebContents* web_contents,
237 // RenderViewHost may be NULL during shutdown.
238 content::RenderViewHost* host = web_contents->GetRenderViewHost();
240 host->Send(new ChromeViewMsg_SetVisuallyDeemphasized(host->GetRoutingID(),
245 bool ChromeAppDelegate::IsWebContentsVisible(
246 content::WebContents* web_contents) {
247 return platform_util::IsVisible(web_contents->GetNativeView());