blob: ff0ec581cb258314dfb8036e6f4d6ba6dcc072c8 [file] [log] [blame]
[email protected]5a20b192012-03-01 06:01:571// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]4a0765a2009-05-08 23:12:255#include "chrome/browser/shell_integration.h"
6
[email protected]c5efb952011-11-01 01:28:367#include "base/bind.h"
[email protected]28375ae2010-02-05 04:45:508#include "base/command_line.h"
9#include "base/file_util.h"
[email protected]b96aa932009-08-12 21:34:4910#include "base/path_service.h"
[email protected]3853a4c2013-02-11 17:15:5711#include "base/prefs/pref_service.h"
[email protected]5d91c9e2010-07-28 17:25:2812#include "base/string_util.h"
[email protected]124901f52013-03-27 14:42:1013#include "base/threading/thread_restrictions.h"
[email protected]64048bd2010-03-08 23:28:5814#include "base/utf_string_conversions.h"
[email protected]ba26a442013-02-20 15:32:5515#include "chrome/browser/policy/policy_path_parser.h"
[email protected]b96aa932009-08-12 21:34:4916#include "chrome/common/chrome_paths.h"
[email protected]28375ae2010-02-05 04:45:5017#include "chrome/common/chrome_switches.h"
[email protected]e450fa62011-02-01 12:52:5618#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4919#include "content/public/browser/browser_thread.h"
initial.commit09911bf2008-07-26 23:55:2920
[email protected]631bb742011-11-02 11:29:3921using content::BrowserThread;
22
[email protected]bd046bd42012-06-08 05:07:3223ShellIntegration::DefaultWebClientSetPermission
24 ShellIntegration::CanSetAsDefaultProtocolClient() {
[email protected]a01481b2011-07-15 04:30:0225 // Allowed as long as the browser can become the operating system default
26 // browser.
27 return CanSetAsDefaultBrowser();
28}
29
[email protected]93aa89c72010-10-20 21:32:0430ShellIntegration::ShortcutInfo::ShortcutInfo()
[email protected]b5ff7ab2013-03-01 07:48:5331 : is_platform_app(false) {
[email protected]93aa89c72010-10-20 21:32:0432}
33
34ShellIntegration::ShortcutInfo::~ShortcutInfo() {}
35
[email protected]b5ff7ab2013-03-01 07:48:5336ShellIntegration::ShortcutLocations::ShortcutLocations()
37 : on_desktop(false),
38 in_applications_menu(false),
[email protected]d81a63c02013-03-07 08:49:0439 in_quick_launch_bar(false),
40 hidden(false) {
[email protected]b5ff7ab2013-03-01 07:48:5341}
42
[email protected]9561bc912012-03-07 02:41:1643static const struct ShellIntegration::AppModeInfo* gAppModeInfo = NULL;
44
45// static
46void ShellIntegration::SetAppModeInfo(const struct AppModeInfo* info) {
47 gAppModeInfo = info;
48}
49
50// static
51const struct ShellIntegration::AppModeInfo* ShellIntegration::AppModeInfo() {
52 return gAppModeInfo;
53}
54
55// static
56bool ShellIntegration::IsRunningInAppMode() {
57 return gAppModeInfo != NULL;
58}
59
[email protected]b10392932011-03-08 21:28:1460// static
61CommandLine ShellIntegration::CommandLineArgsForLauncher(
[email protected]2f1c09d2011-01-14 14:58:1462 const GURL& url,
[email protected]5c93a0c12012-05-02 19:45:2463 const std::string& extension_app_id,
[email protected]650b2d52013-02-10 03:41:4564 const base::FilePath& profile_path) {
[email protected]124901f52013-03-27 14:42:1065 base::ThreadRestrictions::AssertIOAllowed();
[email protected]b10392932011-03-08 21:28:1466 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
67 CommandLine new_cmd_line(CommandLine::NO_PROGRAM);
[email protected]28375ae2010-02-05 04:45:5068
69 // Use the same UserDataDir for new launches that we currently have set.
[email protected]650b2d52013-02-10 03:41:4570 base::FilePath user_data_dir =
71 cmd_line.GetSwitchValuePath(switches::kUserDataDir);
[email protected]ba26a442013-02-20 15:32:5572#if defined(OS_MACOSX) || defined(OS_WIN)
73 policy::path_parser::CheckUserDataDirPolicy(&user_data_dir);
74#endif
[email protected]b10392932011-03-08 21:28:1475 if (!user_data_dir.empty()) {
[email protected]28375ae2010-02-05 04:45:5076 // Make sure user_data_dir is an absolute path.
77 if (file_util::AbsolutePath(&user_data_dir) &&
[email protected]63597e4e2010-07-08 17:49:0578 file_util::PathExists(user_data_dir)) {
[email protected]b10392932011-03-08 21:28:1479 new_cmd_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
[email protected]28375ae2010-02-05 04:45:5080 }
81 }
82
[email protected]660e428f2010-08-04 01:23:0083#if defined(OS_CHROMEOS)
[email protected]650b2d52013-02-10 03:41:4584 base::FilePath profile = cmd_line.GetSwitchValuePath(switches::kLoginProfile);
[email protected]b10392932011-03-08 21:28:1485 if (!profile.empty())
86 new_cmd_line.AppendSwitchPath(switches::kLoginProfile, profile);
[email protected]5951c852012-06-20 00:12:5387#else
88 if (!profile_path.empty() && !extension_app_id.empty())
[email protected]2215c8d52012-07-06 06:10:3389 new_cmd_line.AppendSwitchPath(switches::kProfileDirectory,
90 profile_path.BaseName());
[email protected]28375ae2010-02-05 04:45:5091#endif
92
93 // If |extension_app_id| is present, we use the kAppId switch rather than
94 // the kApp switch (the launch url will be read from the extension app
95 // during launch.
[email protected]ec5b50d2010-10-09 16:35:1896 if (!extension_app_id.empty()) {
[email protected]b10392932011-03-08 21:28:1497 new_cmd_line.AppendSwitchASCII(switches::kAppId, extension_app_id);
[email protected]64048bd2010-03-08 23:28:5898 } else {
[email protected]28375ae2010-02-05 04:45:5099 // Use '--app=url' instead of just 'url' to launch the browser with minimal
100 // chrome.
101 // Note: Do not change this flag! Old Gears shortcuts will break if you do!
[email protected]b10392932011-03-08 21:28:14102 new_cmd_line.AppendSwitchASCII(switches::kApp, url.spec());
[email protected]28375ae2010-02-05 04:45:50103 }
[email protected]b10392932011-03-08 21:28:14104 return new_cmd_line;
[email protected]28375ae2010-02-05 04:45:50105}
106
[email protected]bd046bd42012-06-08 05:07:32107#if !defined(OS_WIN)
108// static
109bool ShellIntegration::SetAsDefaultBrowserInteractive() {
110 return false;
111}
[email protected]ee9d89d2012-09-25 18:21:03112
113// static
114bool ShellIntegration::SetAsDefaultProtocolClientInteractive(
115 const std::string& protocol) {
116 return false;
117}
[email protected]bd046bd42012-06-08 05:07:32118#endif
119
[email protected]693baa5d2012-06-22 22:23:38120bool ShellIntegration::DefaultWebClientObserver::IsOwnedByWorker() {
121 return false;
122}
123
124bool ShellIntegration::DefaultWebClientObserver::
125 IsInteractiveSetDefaultPermitted() {
126 return false;
127}
128
[email protected]d24c4012009-07-28 01:57:31129///////////////////////////////////////////////////////////////////////////////
[email protected]4468a5b2011-05-26 07:48:02130// ShellIntegration::DefaultWebClientWorker
[email protected]d24c4012009-07-28 01:57:31131//
initial.commit09911bf2008-07-26 23:55:29132
[email protected]4468a5b2011-05-26 07:48:02133ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker(
134 DefaultWebClientObserver* observer)
[email protected]0d3dc8e22009-11-03 02:27:01135 : observer_(observer) {
initial.commit09911bf2008-07-26 23:55:29136}
137
[email protected]4468a5b2011-05-26 07:48:02138void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() {
139 if (observer_) {
140 observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
141 BrowserThread::PostTask(
142 BrowserThread::FILE, FROM_HERE,
[email protected]c5efb952011-11-01 01:28:36143 base::Bind(
144 &DefaultWebClientWorker::ExecuteCheckIsDefault, this));
[email protected]4468a5b2011-05-26 07:48:02145 }
146}
147
148void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() {
[email protected]693baa5d2012-06-22 22:23:38149 bool interactive_permitted = false;
[email protected]4468a5b2011-05-26 07:48:02150 if (observer_) {
151 observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
[email protected]693baa5d2012-06-22 22:23:38152 interactive_permitted = observer_->IsInteractiveSetDefaultPermitted();
[email protected]4468a5b2011-05-26 07:48:02153 }
[email protected]0c7d74f2010-10-11 11:55:26154 BrowserThread::PostTask(
155 BrowserThread::FILE, FROM_HERE,
[email protected]693baa5d2012-06-22 22:23:38156 base::Bind(&DefaultWebClientWorker::ExecuteSetAsDefault, this,
157 interactive_permitted));
initial.commit09911bf2008-07-26 23:55:29158}
159
[email protected]4468a5b2011-05-26 07:48:02160void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() {
[email protected]d24c4012009-07-28 01:57:31161 // Our associated view has gone away, so we shouldn't call back to it if
162 // our worker thread returns after the view is dead.
[email protected]bcb999d2011-05-31 15:11:35163 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]d24c4012009-07-28 01:57:31164 observer_ = NULL;
165}
166
167///////////////////////////////////////////////////////////////////////////////
[email protected]4468a5b2011-05-26 07:48:02168// DefaultWebClientWorker, private:
[email protected]d24c4012009-07-28 01:57:31169
[email protected]4468a5b2011-05-26 07:48:02170void ShellIntegration::DefaultWebClientWorker::ExecuteCheckIsDefault() {
[email protected]0c7d74f2010-10-11 11:55:26171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]4468a5b2011-05-26 07:48:02172 DefaultWebClientState state = CheckIsDefault();
[email protected]0c7d74f2010-10-11 11:55:26173 BrowserThread::PostTask(
174 BrowserThread::UI, FROM_HERE,
[email protected]c5efb952011-11-01 01:28:36175 base::Bind(
176 &DefaultWebClientWorker::CompleteCheckIsDefault, this, state));
[email protected]d24c4012009-07-28 01:57:31177}
178
[email protected]4468a5b2011-05-26 07:48:02179void ShellIntegration::DefaultWebClientWorker::CompleteCheckIsDefault(
180 DefaultWebClientState state) {
[email protected]0c7d74f2010-10-11 11:55:26181 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]264f74d12009-09-04 23:39:58182 UpdateUI(state);
[email protected]97e2e3f2011-07-22 10:21:25183 // The worker has finished everything it needs to do, so free the observer
184 // if we own it.
185 if (observer_ && observer_->IsOwnedByWorker()) {
186 delete observer_;
187 observer_ = NULL;
188 }
[email protected]d24c4012009-07-28 01:57:31189}
190
[email protected]693baa5d2012-06-22 22:23:38191void ShellIntegration::DefaultWebClientWorker::ExecuteSetAsDefault(
192 bool interactive_permitted) {
[email protected]0c7d74f2010-10-11 11:55:26193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
[email protected]693baa5d2012-06-22 22:23:38194
195 bool result = SetAsDefault(interactive_permitted);
[email protected]0c7d74f2010-10-11 11:55:26196 BrowserThread::PostTask(
197 BrowserThread::UI, FROM_HERE,
[email protected]693baa5d2012-06-22 22:23:38198 base::Bind(&DefaultWebClientWorker::CompleteSetAsDefault, this, result));
[email protected]d24c4012009-07-28 01:57:31199}
200
[email protected]693baa5d2012-06-22 22:23:38201void ShellIntegration::DefaultWebClientWorker::CompleteSetAsDefault(
202 bool succeeded) {
[email protected]0c7d74f2010-10-11 11:55:26203 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]693baa5d2012-06-22 22:23:38204 // First tell the observer what the SetAsDefault call has returned.
205 if (observer_)
206 observer_->OnSetAsDefaultConcluded(succeeded);
[email protected]4468a5b2011-05-26 07:48:02207 // Set as default completed, check again to make sure it stuck...
208 StartCheckIsDefault();
[email protected]d24c4012009-07-28 01:57:31209}
210
[email protected]4468a5b2011-05-26 07:48:02211void ShellIntegration::DefaultWebClientWorker::UpdateUI(
212 DefaultWebClientState state) {
[email protected]d24c4012009-07-28 01:57:31213 if (observer_) {
[email protected]264f74d12009-09-04 23:39:58214 switch (state) {
[email protected]89886652012-12-11 18:09:07215 case NOT_DEFAULT:
[email protected]4468a5b2011-05-26 07:48:02216 observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT);
[email protected]264f74d12009-09-04 23:39:58217 break;
[email protected]89886652012-12-11 18:09:07218 case IS_DEFAULT:
[email protected]4468a5b2011-05-26 07:48:02219 observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT);
[email protected]264f74d12009-09-04 23:39:58220 break;
[email protected]89886652012-12-11 18:09:07221 case UNKNOWN_DEFAULT:
[email protected]4468a5b2011-05-26 07:48:02222 observer_->SetDefaultWebClientUIState(STATE_UNKNOWN);
[email protected]264f74d12009-09-04 23:39:58223 break;
224 default:
225 break;
226 }
[email protected]d24c4012009-07-28 01:57:31227 }
initial.commit09911bf2008-07-26 23:55:29228}
[email protected]4468a5b2011-05-26 07:48:02229
230///////////////////////////////////////////////////////////////////////////////
231// ShellIntegration::DefaultBrowserWorker
232//
233
234ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker(
235 DefaultWebClientObserver* observer)
236 : DefaultWebClientWorker(observer) {
237}
238
239///////////////////////////////////////////////////////////////////////////////
240// DefaultBrowserWorker, private:
241
242ShellIntegration::DefaultWebClientState
243ShellIntegration::DefaultBrowserWorker::CheckIsDefault() {
[email protected]89886652012-12-11 18:09:07244 return ShellIntegration::GetDefaultBrowser();
[email protected]4468a5b2011-05-26 07:48:02245}
246
[email protected]693baa5d2012-06-22 22:23:38247bool ShellIntegration::DefaultBrowserWorker::SetAsDefault(
[email protected]bd046bd42012-06-08 05:07:32248 bool interactive_permitted) {
[email protected]693baa5d2012-06-22 22:23:38249 bool result = false;
[email protected]bd046bd42012-06-08 05:07:32250 switch (ShellIntegration::CanSetAsDefaultBrowser()) {
251 case ShellIntegration::SET_DEFAULT_UNATTENDED:
[email protected]693baa5d2012-06-22 22:23:38252 result = ShellIntegration::SetAsDefaultBrowser();
[email protected]bd046bd42012-06-08 05:07:32253 break;
254 case ShellIntegration::SET_DEFAULT_INTERACTIVE:
255 if (interactive_permitted)
[email protected]693baa5d2012-06-22 22:23:38256 result = ShellIntegration::SetAsDefaultBrowserInteractive();
[email protected]bd046bd42012-06-08 05:07:32257 break;
258 default:
259 NOTREACHED();
260 }
[email protected]693baa5d2012-06-22 22:23:38261
262 return result;
[email protected]4468a5b2011-05-26 07:48:02263}
264
265///////////////////////////////////////////////////////////////////////////////
266// ShellIntegration::DefaultProtocolClientWorker
267//
268
269ShellIntegration::DefaultProtocolClientWorker::DefaultProtocolClientWorker(
270 DefaultWebClientObserver* observer, const std::string& protocol)
271 : DefaultWebClientWorker(observer),
272 protocol_(protocol) {
273}
274
275///////////////////////////////////////////////////////////////////////////////
276// DefaultProtocolClientWorker, private:
277
278ShellIntegration::DefaultWebClientState
279ShellIntegration::DefaultProtocolClientWorker::CheckIsDefault() {
280 return ShellIntegration::IsDefaultProtocolClient(protocol_);
281}
282
[email protected]693baa5d2012-06-22 22:23:38283bool ShellIntegration::DefaultProtocolClientWorker::SetAsDefault(
[email protected]bd046bd42012-06-08 05:07:32284 bool interactive_permitted) {
[email protected]ee9d89d2012-09-25 18:21:03285 bool result = false;
286 switch (ShellIntegration::CanSetAsDefaultProtocolClient()) {
287 case ShellIntegration::SET_DEFAULT_UNATTENDED:
288 result = ShellIntegration::SetAsDefaultProtocolClient(protocol_);
289 break;
290 case ShellIntegration::SET_DEFAULT_INTERACTIVE:
291 if (interactive_permitted) {
292 result = ShellIntegration::SetAsDefaultProtocolClientInteractive(
293 protocol_);
294 }
295 break;
296 default:
297 NOTREACHED();
298 }
299
300 return result;
[email protected]4468a5b2011-05-26 07:48:02301}