- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / shell_integration.cc
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/shell_integration.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "base/path_service.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "chrome/browser/policy/policy_path_parser.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/chrome_switches.h"
18 #include "chrome/common/pref_names.h"
19 #include "content/public/browser/browser_thread.h"
20
21 #if defined(OS_CHROMEOS)
22 #include "chromeos/chromeos_switches.h"
23 #endif
24
25 using content::BrowserThread;
26
27 ShellIntegration::DefaultWebClientSetPermission
28     ShellIntegration::CanSetAsDefaultProtocolClient() {
29   // Allowed as long as the browser can become the operating system default
30   // browser.
31   return CanSetAsDefaultBrowser();
32 }
33
34 ShellIntegration::ShortcutInfo::ShortcutInfo()
35     : is_platform_app(false) {
36 }
37
38 ShellIntegration::ShortcutInfo::~ShortcutInfo() {}
39
40 ShellIntegration::ShortcutLocations::ShortcutLocations()
41     : on_desktop(false),
42       in_applications_menu(false),
43       in_quick_launch_bar(false),
44       hidden(false) {
45 }
46
47 static const struct ShellIntegration::AppModeInfo* gAppModeInfo = NULL;
48
49 // static
50 void ShellIntegration::SetAppModeInfo(const struct AppModeInfo* info) {
51   gAppModeInfo = info;
52 }
53
54 // static
55 const struct ShellIntegration::AppModeInfo* ShellIntegration::AppModeInfo() {
56   return gAppModeInfo;
57 }
58
59 // static
60 bool ShellIntegration::IsRunningInAppMode() {
61   return gAppModeInfo != NULL;
62 }
63
64 // static
65 CommandLine ShellIntegration::CommandLineArgsForLauncher(
66     const GURL& url,
67     const std::string& extension_app_id,
68     const base::FilePath& profile_path) {
69   base::ThreadRestrictions::AssertIOAllowed();
70   const CommandLine& cmd_line = *CommandLine::ForCurrentProcess();
71   CommandLine new_cmd_line(CommandLine::NO_PROGRAM);
72
73   // Use the same UserDataDir for new launches that we currently have set.
74   base::FilePath user_data_dir =
75       cmd_line.GetSwitchValuePath(switches::kUserDataDir);
76 #if defined(OS_MACOSX) || defined(OS_WIN)
77   policy::path_parser::CheckUserDataDirPolicy(&user_data_dir);
78 #endif
79   if (!user_data_dir.empty()) {
80     // Make sure user_data_dir is an absolute path.
81     user_data_dir = base::MakeAbsoluteFilePath(user_data_dir);
82     if (!user_data_dir.empty() && base::PathExists(user_data_dir))
83       new_cmd_line.AppendSwitchPath(switches::kUserDataDir, user_data_dir);
84   }
85
86 #if defined(OS_CHROMEOS)
87   base::FilePath profile = cmd_line.GetSwitchValuePath(
88       chromeos::switches::kLoginProfile);
89   if (!profile.empty())
90     new_cmd_line.AppendSwitchPath(chromeos::switches::kLoginProfile, profile);
91 #else
92   if (!profile_path.empty() && !extension_app_id.empty())
93     new_cmd_line.AppendSwitchPath(switches::kProfileDirectory,
94                                   profile_path.BaseName());
95 #endif
96
97   // If |extension_app_id| is present, we use the kAppId switch rather than
98   // the kApp switch (the launch url will be read from the extension app
99   // during launch.
100   if (!extension_app_id.empty()) {
101     new_cmd_line.AppendSwitchASCII(switches::kAppId, extension_app_id);
102   } else {
103     // Use '--app=url' instead of just 'url' to launch the browser with minimal
104     // chrome.
105     // Note: Do not change this flag!  Old Gears shortcuts will break if you do!
106     new_cmd_line.AppendSwitchASCII(switches::kApp, url.spec());
107   }
108   return new_cmd_line;
109 }
110
111 #if !defined(OS_WIN)
112 // static
113 bool ShellIntegration::SetAsDefaultBrowserInteractive() {
114   return false;
115 }
116
117 // static
118 bool ShellIntegration::SetAsDefaultProtocolClientInteractive(
119     const std::string& protocol) {
120   return false;
121 }
122 #endif
123
124 bool ShellIntegration::DefaultWebClientObserver::IsOwnedByWorker() {
125   return false;
126 }
127
128 bool ShellIntegration::DefaultWebClientObserver::
129     IsInteractiveSetDefaultPermitted() {
130   return false;
131 }
132
133 ///////////////////////////////////////////////////////////////////////////////
134 // ShellIntegration::DefaultWebClientWorker
135 //
136
137 ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker(
138     DefaultWebClientObserver* observer)
139     : observer_(observer) {
140 }
141
142 void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() {
143   if (observer_) {
144     observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
145     BrowserThread::PostTask(
146         BrowserThread::FILE, FROM_HERE,
147         base::Bind(
148             &DefaultWebClientWorker::ExecuteCheckIsDefault, this));
149   }
150 }
151
152 void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() {
153   bool interactive_permitted = false;
154   if (observer_) {
155     observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
156     interactive_permitted = observer_->IsInteractiveSetDefaultPermitted();
157   }
158   BrowserThread::PostTask(
159       BrowserThread::FILE, FROM_HERE,
160       base::Bind(&DefaultWebClientWorker::ExecuteSetAsDefault, this,
161                  interactive_permitted));
162 }
163
164 void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() {
165   // Our associated view has gone away, so we shouldn't call back to it if
166   // our worker thread returns after the view is dead.
167   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
168   observer_ = NULL;
169 }
170
171 ///////////////////////////////////////////////////////////////////////////////
172 // DefaultWebClientWorker, private:
173
174 void ShellIntegration::DefaultWebClientWorker::ExecuteCheckIsDefault() {
175   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
176   DefaultWebClientState state = CheckIsDefault();
177   BrowserThread::PostTask(
178       BrowserThread::UI, FROM_HERE,
179       base::Bind(
180           &DefaultWebClientWorker::CompleteCheckIsDefault, this, state));
181 }
182
183 void ShellIntegration::DefaultWebClientWorker::CompleteCheckIsDefault(
184     DefaultWebClientState state) {
185   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
186   UpdateUI(state);
187   // The worker has finished everything it needs to do, so free the observer
188   // if we own it.
189   if (observer_ && observer_->IsOwnedByWorker()) {
190     delete observer_;
191     observer_ = NULL;
192   }
193 }
194
195 void ShellIntegration::DefaultWebClientWorker::ExecuteSetAsDefault(
196     bool interactive_permitted) {
197   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
198
199   bool result = SetAsDefault(interactive_permitted);
200   BrowserThread::PostTask(
201       BrowserThread::UI, FROM_HERE,
202       base::Bind(&DefaultWebClientWorker::CompleteSetAsDefault, this, result));
203 }
204
205 void ShellIntegration::DefaultWebClientWorker::CompleteSetAsDefault(
206     bool succeeded) {
207   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
208   // First tell the observer what the SetAsDefault call has returned.
209   if (observer_)
210     observer_->OnSetAsDefaultConcluded(succeeded);
211   // Set as default completed, check again to make sure it stuck...
212   StartCheckIsDefault();
213 }
214
215 void ShellIntegration::DefaultWebClientWorker::UpdateUI(
216     DefaultWebClientState state) {
217   if (observer_) {
218     switch (state) {
219       case NOT_DEFAULT:
220         observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT);
221         break;
222       case IS_DEFAULT:
223         observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT);
224         break;
225       case UNKNOWN_DEFAULT:
226         observer_->SetDefaultWebClientUIState(STATE_UNKNOWN);
227         break;
228       default:
229         break;
230     }
231   }
232 }
233
234 ///////////////////////////////////////////////////////////////////////////////
235 // ShellIntegration::DefaultBrowserWorker
236 //
237
238 ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker(
239     DefaultWebClientObserver* observer)
240     : DefaultWebClientWorker(observer) {
241 }
242
243 ///////////////////////////////////////////////////////////////////////////////
244 // DefaultBrowserWorker, private:
245
246 ShellIntegration::DefaultWebClientState
247 ShellIntegration::DefaultBrowserWorker::CheckIsDefault() {
248   return ShellIntegration::GetDefaultBrowser();
249 }
250
251 bool ShellIntegration::DefaultBrowserWorker::SetAsDefault(
252     bool interactive_permitted) {
253   bool result = false;
254   switch (ShellIntegration::CanSetAsDefaultBrowser()) {
255     case ShellIntegration::SET_DEFAULT_UNATTENDED:
256       result = ShellIntegration::SetAsDefaultBrowser();
257       break;
258     case ShellIntegration::SET_DEFAULT_INTERACTIVE:
259       if (interactive_permitted)
260         result = ShellIntegration::SetAsDefaultBrowserInteractive();
261       break;
262     default:
263       NOTREACHED();
264   }
265
266   return result;
267 }
268
269 ///////////////////////////////////////////////////////////////////////////////
270 // ShellIntegration::DefaultProtocolClientWorker
271 //
272
273 ShellIntegration::DefaultProtocolClientWorker::DefaultProtocolClientWorker(
274     DefaultWebClientObserver* observer, const std::string& protocol)
275     : DefaultWebClientWorker(observer),
276       protocol_(protocol) {
277 }
278
279 ///////////////////////////////////////////////////////////////////////////////
280 // DefaultProtocolClientWorker, private:
281
282 ShellIntegration::DefaultWebClientState
283 ShellIntegration::DefaultProtocolClientWorker::CheckIsDefault() {
284   return ShellIntegration::IsDefaultProtocolClient(protocol_);
285 }
286
287 bool ShellIntegration::DefaultProtocolClientWorker::SetAsDefault(
288     bool interactive_permitted) {
289   bool result = false;
290   switch (ShellIntegration::CanSetAsDefaultProtocolClient()) {
291     case ShellIntegration::SET_DEFAULT_NOT_ALLOWED:
292       result = false;
293       break;
294     case ShellIntegration::SET_DEFAULT_UNATTENDED:
295       result = ShellIntegration::SetAsDefaultProtocolClient(protocol_);
296       break;
297     case ShellIntegration::SET_DEFAULT_INTERACTIVE:
298       if (interactive_permitted) {
299         result = ShellIntegration::SetAsDefaultProtocolClientInteractive(
300             protocol_);
301       }
302       break;
303   }
304
305   return result;
306 }