Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / apps / chrome_app_delegate.cc
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.
4
5 #include "chrome/browser/ui/apps/chrome_app_delegate.h"
6
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"
26
27 #if defined(USE_ASH)
28 #include "ash/shelf/shelf_constants.h"
29 #endif
30
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"
35 #else
36 #include "chrome/browser/printing/print_view_manager_basic.h"
37 #endif  // defined(ENABLE_FULL_PRINTING)
38 #endif  // defined(ENABLE_PRINTING)
39
40 namespace {
41
42 bool disable_external_open_for_testing_ = false;
43
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
49   // window.
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;
54   } else {
55     new_tab_params.disposition = NEW_FOREGROUND_TAB;
56     new_tab_params.window_action = chrome::NavigateParams::SHOW_WINDOW;
57   }
58
59   new_tab_params.initiating_profile = Profile::FromBrowserContext(context);
60   chrome::Navigate(&new_tab_params);
61
62   return new_tab_params.target_contents;
63 }
64
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 {
70  public:
71   OpenURLFromTabBasedOnBrowserDefault(scoped_ptr<content::WebContents> source,
72                                       const content::OpenURLParams& params)
73       : source_(source.Pass()), params_(params) {}
74
75   // Opens a URL when called with the result of if this is the default system
76   // browser or not.
77   virtual void SetDefaultWebClientUIState(
78       ShellIntegration::DefaultWebClientUIState state) OVERRIDE {
79     Profile* profile =
80         Profile::FromBrowserContext(source_->GetBrowserContext());
81     DCHECK(profile);
82     if (!profile)
83       return;
84     switch (state) {
85       case ShellIntegration::STATE_PROCESSING:
86         break;
87       case ShellIntegration::STATE_IS_DEFAULT:
88         OpenURLFromTabInternal(profile, params_);
89         break;
90       case ShellIntegration::STATE_NOT_DEFAULT:
91       case ShellIntegration::STATE_UNKNOWN:
92         platform_util::OpenExternal(profile, params_.url);
93         break;
94     }
95   }
96
97   virtual bool IsOwnedByWorker() OVERRIDE { return true; }
98
99  private:
100   scoped_ptr<content::WebContents> source_;
101   const content::OpenURLParams params_;
102 };
103
104 }  // namespace
105
106 class ChromeAppDelegate::NewWindowContentsDelegate
107     : public content::WebContentsDelegate {
108  public:
109   NewWindowContentsDelegate() {}
110   virtual ~NewWindowContentsDelegate() {}
111
112   virtual content::WebContents* OpenURLFromTab(
113       content::WebContents* source,
114       const content::OpenURLParams& params) OVERRIDE;
115
116  private:
117   DISALLOW_COPY_AND_ASSIGN(NewWindowContentsDelegate);
118 };
119
120 content::WebContents*
121 ChromeAppDelegate::NewWindowContentsDelegate::OpenURLFromTab(
122     content::WebContents* source,
123     const content::OpenURLParams& params) {
124   if (source) {
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(),
135                                                         params));
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();
141   }
142   return NULL;
143 }
144
145 ChromeAppDelegate::ChromeAppDelegate()
146     : new_window_contents_delegate_(new NewWindowContentsDelegate()) {
147 }
148
149 ChromeAppDelegate::~ChromeAppDelegate() {
150 }
151
152 void ChromeAppDelegate::DisableExternalOpenForTesting() {
153   disable_external_open_for_testing_ = true;
154 }
155
156 void ChromeAppDelegate::InitWebContents(content::WebContents* web_contents) {
157   FaviconTabHelper::CreateForWebContents(web_contents);
158
159 #if defined(ENABLE_PRINTING)
160 #if defined(ENABLE_FULL_PRINTING)
161   printing::PrintViewManager::CreateForWebContents(web_contents);
162   printing::PrintPreviewMessageHandler::CreateForWebContents(web_contents);
163 #else
164   printing::PrintViewManagerBasic::CreateForWebContents(web_contents);
165 #endif  // defined(ENABLE_FULL_PRINTING)
166 #endif  // defined(ENABLE_PRINTING)
167 }
168
169 content::WebContents* ChromeAppDelegate::OpenURLFromTab(
170     content::BrowserContext* context,
171     content::WebContents* source,
172     const content::OpenURLParams& params) {
173   return OpenURLFromTabInternal(context, params);
174 }
175
176 void ChromeAppDelegate::AddNewContents(content::BrowserContext* context,
177                                        content::WebContents* new_contents,
178                                        WindowOpenDisposition disposition,
179                                        const gfx::Rect& initial_pos,
180                                        bool user_gesture,
181                                        bool* was_blocked) {
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());
188     return;
189   }
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
193   // new window.
194   disposition =
195       disposition == NEW_BACKGROUND_TAB ? disposition : NEW_FOREGROUND_TAB;
196   chrome::AddWebContents(displayer.browser(),
197                          NULL,
198                          new_contents,
199                          disposition,
200                          initial_pos,
201                          user_gesture,
202                          was_blocked);
203 }
204
205 content::ColorChooser* ChromeAppDelegate::ShowColorChooser(
206     content::WebContents* web_contents,
207     SkColor initial_color) {
208   return chrome::ShowColorChooser(web_contents, initial_color);
209 }
210
211 void ChromeAppDelegate::RunFileChooser(
212     content::WebContents* tab,
213     const content::FileChooserParams& params) {
214   FileSelectHelper::RunFileChooser(tab, params);
215 }
216
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);
224 }
225
226 int ChromeAppDelegate::PreferredIconSize() {
227 #if defined(USE_ASH)
228   return ash::kShelfSize;
229 #else
230   return extension_misc::EXTENSION_ICON_SMALL;
231 #endif
232 }
233
234 void ChromeAppDelegate::SetWebContentsBlocked(
235     content::WebContents* web_contents,
236     bool blocked) {
237   // RenderViewHost may be NULL during shutdown.
238   content::RenderViewHost* host = web_contents->GetRenderViewHost();
239   if (host) {
240     host->Send(new ChromeViewMsg_SetVisuallyDeemphasized(host->GetRoutingID(),
241                                                          blocked));
242   }
243 }
244
245 bool ChromeAppDelegate::IsWebContentsVisible(
246     content::WebContents* web_contents) {
247   return platform_util::IsVisible(web_contents->GetNativeView());
248 }