1 // Copyright (c) 2011 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/shell_integration.h"
6
7 #include "base/command_line.h"
8 #include "base/file_util.h"
9 #include "base/path_service.h"
10 #include "base/string_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/common/chrome_paths.h"
14 #include "chrome/common/chrome_switches.h"
15 #include "chrome/common/pref_names.h"
16 #include "content/browser/browser_thread.h"
17
ShortcutInfo()18 ShellIntegration::ShortcutInfo::ShortcutInfo()
19 : create_on_desktop(false),
20 create_in_applications_menu(false),
21 create_in_quick_launch_bar(false) {
22 }
23
~ShortcutInfo()24 ShellIntegration::ShortcutInfo::~ShortcutInfo() {}
25
26 // static
CommandLineArgsForLauncher(const GURL & url,const std::string & extension_app_id)27 CommandLine ShellIntegration::CommandLineArgsForLauncher(
28 const GURL& url,
29 const std::string& extension_app_id) {
30 const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
31 CommandLine new_cmd_line(CommandLine::NO_PROGRAM);
32
33 // Use the same UserDataDir for new launches that we currently have set.
34 FilePath user_data_dir = cmd_line.GetSwitchValuePath(switches::kUserDataDir);
35 if (!user_data_dir.empty()) {
36 // Make sure user_data_dir is an absolute path.
37 if (file_util::AbsolutePath(&user_data_dir) &&
38 file_util::PathExists(user_data_dir)) {
39 new_cmd_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
40 }
41 }
42
43 #if defined(OS_CHROMEOS)
44 FilePath profile = cmd_line.GetSwitchValuePath(switches::kLoginProfile);
45 if (!profile.empty())
46 new_cmd_line.AppendSwitchPath(switches::kLoginProfile, profile);
47 #endif
48
49 // If |extension_app_id| is present, we use the kAppId switch rather than
50 // the kApp switch (the launch url will be read from the extension app
51 // during launch.
52 if (!extension_app_id.empty()) {
53 new_cmd_line.AppendSwitchASCII(switches::kAppId, extension_app_id);
54 } else {
55 // Use '--app=url' instead of just 'url' to launch the browser with minimal
56 // chrome.
57 // Note: Do not change this flag! Old Gears shortcuts will break if you do!
58 new_cmd_line.AppendSwitchASCII(switches::kApp, url.spec());
59 }
60 return new_cmd_line;
61 }
62
63 ///////////////////////////////////////////////////////////////////////////////
64 // ShellIntegration::DefaultBrowserWorker
65 //
66
DefaultBrowserWorker(DefaultBrowserObserver * observer)67 ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker(
68 DefaultBrowserObserver* observer)
69 : observer_(observer) {
70 }
71
StartCheckDefaultBrowser()72 void ShellIntegration::DefaultBrowserWorker::StartCheckDefaultBrowser() {
73 observer_->SetDefaultBrowserUIState(STATE_PROCESSING);
74 BrowserThread::PostTask(
75 BrowserThread::FILE, FROM_HERE,
76 NewRunnableMethod(
77 this, &DefaultBrowserWorker::ExecuteCheckDefaultBrowser));
78 }
79
StartSetAsDefaultBrowser()80 void ShellIntegration::DefaultBrowserWorker::StartSetAsDefaultBrowser() {
81 observer_->SetDefaultBrowserUIState(STATE_PROCESSING);
82 BrowserThread::PostTask(
83 BrowserThread::FILE, FROM_HERE,
84 NewRunnableMethod(
85 this, &DefaultBrowserWorker::ExecuteSetAsDefaultBrowser));
86 }
87
ObserverDestroyed()88 void ShellIntegration::DefaultBrowserWorker::ObserverDestroyed() {
89 // Our associated view has gone away, so we shouldn't call back to it if
90 // our worker thread returns after the view is dead.
91 observer_ = NULL;
92 }
93
94 ///////////////////////////////////////////////////////////////////////////////
95 // DefaultBrowserWorker, private:
96
ExecuteCheckDefaultBrowser()97 void ShellIntegration::DefaultBrowserWorker::ExecuteCheckDefaultBrowser() {
98 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
99 DefaultBrowserState state = ShellIntegration::IsDefaultBrowser();
100 BrowserThread::PostTask(
101 BrowserThread::UI, FROM_HERE,
102 NewRunnableMethod(
103 this, &DefaultBrowserWorker::CompleteCheckDefaultBrowser, state));
104 }
105
CompleteCheckDefaultBrowser(DefaultBrowserState state)106 void ShellIntegration::DefaultBrowserWorker::CompleteCheckDefaultBrowser(
107 DefaultBrowserState state) {
108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109 UpdateUI(state);
110 }
111
ExecuteSetAsDefaultBrowser()112 void ShellIntegration::DefaultBrowserWorker::ExecuteSetAsDefaultBrowser() {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
114 ShellIntegration::SetAsDefaultBrowser();
115 BrowserThread::PostTask(
116 BrowserThread::UI, FROM_HERE,
117 NewRunnableMethod(
118 this, &DefaultBrowserWorker::CompleteSetAsDefaultBrowser));
119 }
120
CompleteSetAsDefaultBrowser()121 void ShellIntegration::DefaultBrowserWorker::CompleteSetAsDefaultBrowser() {
122 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
123 if (observer_) {
124 // Set as default completed, check again to make sure it stuck...
125 StartCheckDefaultBrowser();
126 }
127 }
128
UpdateUI(DefaultBrowserState state)129 void ShellIntegration::DefaultBrowserWorker::UpdateUI(
130 DefaultBrowserState state) {
131 if (observer_) {
132 switch (state) {
133 case NOT_DEFAULT_BROWSER:
134 observer_->SetDefaultBrowserUIState(STATE_NOT_DEFAULT);
135 break;
136 case IS_DEFAULT_BROWSER:
137 observer_->SetDefaultBrowserUIState(STATE_IS_DEFAULT);
138 break;
139 case UNKNOWN_DEFAULT_BROWSER:
140 observer_->SetDefaultBrowserUIState(STATE_UNKNOWN);
141 break;
142 default:
143 break;
144 }
145 }
146 }
147