[M85 Dev][EFL] Fix errors to generate ninja files
[platform/framework/web/chromium-efl.git] / 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/files/file_util.h"
10 #include "base/i18n/file_util_icu.h"
11 #include "base/metrics/histogram_macros.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
14 #include "base/strings/utf_string_conversions.h"
15 #include "base/task/lazy_thread_pool_task_runner.h"
16 #include "base/task/single_thread_task_runner_thread_mode.h"
17 #include "base/task/task_traits.h"
18 #include "base/threading/scoped_blocking_call.h"
19 #include "build/build_config.h"
20 #include "chrome/browser/policy/policy_path_parser.h"
21 #include "chrome/common/chrome_paths.h"
22 #include "chrome/common/chrome_switches.h"
23 #include "components/prefs/pref_service.h"
24 #include "components/version_info/version_info.h"
25 #include "content/public/browser/browser_task_traits.h"
26 #include "content/public/browser/browser_thread.h"
27
28 #if defined(OS_CHROMEOS)
29 #include "chromeos/constants/chromeos_switches.h"
30 #endif
31
32 #if defined(OS_WIN)
33 #include "base/win/windows_version.h"
34 #include "chrome/browser/shell_integration_win.h"
35 #include "chrome/installer/util/shell_util.h"
36 #endif
37
38 #if !defined(OS_WIN)
39 #include "chrome/common/channel_info.h"
40 #include "chrome/grit/chromium_strings.h"
41 #include "ui/base/l10n/l10n_util.h"
42 #endif
43
44 using content::BrowserThread;
45
46 namespace shell_integration {
47
48 namespace {
49
50 const struct AppModeInfo* gAppModeInfo = nullptr;
51
52 // TODO(crbug.com/773563): Remove |g_sequenced_task_runner| and use an instance
53 // field / singleton instead.
54 #if defined(OS_WIN)
55 base::LazyThreadPoolCOMSTATaskRunner g_sequenced_task_runner =
56     LAZY_COM_STA_TASK_RUNNER_INITIALIZER(
57         base::TaskTraits(base::MayBlock()),
58         base::SingleThreadTaskRunnerThreadMode::SHARED);
59 #else
60 base::LazyThreadPoolSequencedTaskRunner g_sequenced_task_runner =
61     LAZY_THREAD_POOL_SEQUENCED_TASK_RUNNER_INITIALIZER(
62         base::TaskTraits(base::MayBlock()));
63 #endif
64
65 }  // namespace
66
67 bool CanSetAsDefaultBrowser() {
68   return GetDefaultWebClientSetPermission() != SET_DEFAULT_NOT_ALLOWED;
69 }
70
71 #if !defined(OS_WIN)
72 bool IsElevationNeededForSettingDefaultProtocolClient() {
73   return false;
74 }
75 #endif  // !defined(OS_WIN)
76
77 void SetAppModeInfo(const struct AppModeInfo* info) {
78   gAppModeInfo = info;
79 }
80
81 const struct AppModeInfo* AppModeInfo() {
82   return gAppModeInfo;
83 }
84
85 bool IsRunningInAppMode() {
86   return gAppModeInfo != NULL;
87 }
88
89 base::CommandLine CommandLineArgsForLauncher(
90     const GURL& url,
91     const std::string& extension_app_id,
92     const base::FilePath& profile_path) {
93   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
94                                                 base::BlockingType::MAY_BLOCK);
95   base::CommandLine new_cmd_line(base::CommandLine::NO_PROGRAM);
96
97   AppendProfileArgs(
98       extension_app_id.empty() ? base::FilePath() : profile_path,
99       &new_cmd_line);
100
101   // If |extension_app_id| is present, we use the kAppId switch rather than
102   // the kApp switch (the launch url will be read from the extension app
103   // during launch.
104   if (!extension_app_id.empty()) {
105     new_cmd_line.AppendSwitchASCII(switches::kAppId, extension_app_id);
106   } else {
107     // Use '--app=url' instead of just 'url' to launch the browser with minimal
108     // chrome.
109     // Note: Do not change this flag!  Old Gears shortcuts will break if you do!
110     new_cmd_line.AppendSwitchASCII(switches::kApp, url.spec());
111   }
112   return new_cmd_line;
113 }
114
115 void AppendProfileArgs(const base::FilePath& profile_path,
116                        base::CommandLine* command_line) {
117   DCHECK(command_line);
118   const base::CommandLine& cmd_line = *base::CommandLine::ForCurrentProcess();
119
120   // Use the same UserDataDir for new launches that we currently have set.
121   base::FilePath user_data_dir =
122       cmd_line.GetSwitchValuePath(switches::kUserDataDir);
123 #if defined(OS_MACOSX) || defined(OS_WIN)
124   policy::path_parser::CheckUserDataDirPolicy(&user_data_dir);
125 #endif
126   if (!user_data_dir.empty()) {
127     // Make sure user_data_dir is an absolute path.
128     user_data_dir = base::MakeAbsoluteFilePath(user_data_dir);
129     if (!user_data_dir.empty() && base::PathExists(user_data_dir))
130       command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir);
131   }
132
133 #if defined(OS_CHROMEOS)
134   base::FilePath profile = cmd_line.GetSwitchValuePath(
135       chromeos::switches::kLoginProfile);
136   if (!profile.empty())
137     command_line->AppendSwitchPath(chromeos::switches::kLoginProfile, profile);
138 #else
139   if (!profile_path.empty())
140     command_line->AppendSwitchPath(switches::kProfileDirectory,
141                                    profile_path.BaseName());
142 #endif
143 }
144
145 #if !defined(OS_WIN)
146 base::string16 GetAppShortcutsSubdirName() {
147   if (chrome::GetChannel() == version_info::Channel::CANARY)
148     return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME_CANARY);
149   return l10n_util::GetStringUTF16(IDS_APP_SHORTCUTS_SUBDIR_NAME);
150 }
151 #endif  // !defined(OS_WIN)
152
153 ///////////////////////////////////////////////////////////////////////////////
154 // DefaultWebClientWorker
155 //
156
157 void DefaultWebClientWorker::StartCheckIsDefault() {
158   g_sequenced_task_runner.Get()->PostTask(
159       FROM_HERE,
160       base::BindOnce(&DefaultWebClientWorker::CheckIsDefault, this, false));
161 }
162
163 void DefaultWebClientWorker::StartSetAsDefault() {
164   g_sequenced_task_runner.Get()->PostTask(
165       FROM_HERE, base::BindOnce(&DefaultWebClientWorker::SetAsDefault, this));
166 }
167
168 ///////////////////////////////////////////////////////////////////////////////
169 // DefaultWebClientWorker, protected:
170
171 DefaultWebClientWorker::DefaultWebClientWorker(
172     const DefaultWebClientWorkerCallback& callback,
173     const char* worker_name)
174     : callback_(callback), worker_name_(worker_name) {}
175
176 DefaultWebClientWorker::~DefaultWebClientWorker() = default;
177
178 void DefaultWebClientWorker::OnCheckIsDefaultComplete(
179     DefaultWebClientState state,
180     bool is_following_set_as_default) {
181   DCHECK_CURRENTLY_ON(BrowserThread::UI);
182   UpdateUI(state);
183
184   if (is_following_set_as_default)
185     ReportSetDefaultResult(state);
186 }
187
188 ///////////////////////////////////////////////////////////////////////////////
189 // DefaultWebClientWorker, private:
190
191 void DefaultWebClientWorker::CheckIsDefault(bool is_following_set_as_default) {
192   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
193                                                 base::BlockingType::MAY_BLOCK);
194
195   DefaultWebClientState state = CheckIsDefaultImpl();
196   content::GetUIThreadTaskRunner({})->PostTask(
197       FROM_HERE, base::BindOnce(&DefaultBrowserWorker::OnCheckIsDefaultComplete,
198                                 this, state, is_following_set_as_default));
199 }
200
201 void DefaultWebClientWorker::SetAsDefault() {
202   base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
203                                                 base::BlockingType::MAY_BLOCK);
204
205   // SetAsDefaultImpl will make sure the callback is executed exactly once.
206   SetAsDefaultImpl(
207       base::Bind(&DefaultWebClientWorker::CheckIsDefault, this, true));
208 }
209
210 void DefaultWebClientWorker::ReportSetDefaultResult(
211     DefaultWebClientState state) {
212   base::LinearHistogram::FactoryGet(
213       base::StringPrintf("%s.SetDefaultResult2", worker_name_), 1,
214       DefaultWebClientState::NUM_DEFAULT_STATES,
215       DefaultWebClientState::NUM_DEFAULT_STATES + 1,
216       base::HistogramBase::kUmaTargetedHistogramFlag)
217       ->Add(state);
218 }
219
220 void DefaultWebClientWorker::UpdateUI(DefaultWebClientState state) {
221   if (!callback_.is_null()) {
222     switch (state) {
223       case NOT_DEFAULT:
224       case IS_DEFAULT:
225       case UNKNOWN_DEFAULT:
226       case OTHER_MODE_IS_DEFAULT:
227         callback_.Run(state);
228         return;
229       case NUM_DEFAULT_STATES:
230         break;
231     }
232     NOTREACHED();
233   }
234 }
235
236 ///////////////////////////////////////////////////////////////////////////////
237 // DefaultBrowserWorker
238 //
239
240 DefaultBrowserWorker::DefaultBrowserWorker(
241     const DefaultWebClientWorkerCallback& callback)
242     : DefaultWebClientWorker(callback, "DefaultBrowser") {}
243
244 ///////////////////////////////////////////////////////////////////////////////
245 // DefaultBrowserWorker, private:
246
247 DefaultBrowserWorker::~DefaultBrowserWorker() = default;
248
249 DefaultWebClientState DefaultBrowserWorker::CheckIsDefaultImpl() {
250   return GetDefaultBrowser();
251 }
252
253 void DefaultBrowserWorker::SetAsDefaultImpl(
254     const base::Closure& on_finished_callback) {
255   switch (GetDefaultWebClientSetPermission()) {
256     case SET_DEFAULT_NOT_ALLOWED:
257       NOTREACHED();
258       break;
259     case SET_DEFAULT_UNATTENDED:
260       SetAsDefaultBrowser();
261       break;
262     case SET_DEFAULT_INTERACTIVE:
263 #if defined(OS_WIN)
264       if (interactive_permitted_) {
265         switch (ShellUtil::GetInteractiveSetDefaultMode()) {
266           case ShellUtil::INTENT_PICKER:
267             win::SetAsDefaultBrowserUsingIntentPicker();
268             break;
269           case ShellUtil::SYSTEM_SETTINGS:
270             win::SetAsDefaultBrowserUsingSystemSettings(on_finished_callback);
271             // Early return because the function above takes care of calling
272             // |on_finished_callback|.
273             return;
274         }
275       }
276 #endif  // defined(OS_WIN)
277       break;
278   }
279   on_finished_callback.Run();
280 }
281
282 ///////////////////////////////////////////////////////////////////////////////
283 // DefaultProtocolClientWorker
284 //
285
286 DefaultProtocolClientWorker::DefaultProtocolClientWorker(
287     const DefaultWebClientWorkerCallback& callback,
288     const std::string& protocol)
289     : DefaultWebClientWorker(callback, "DefaultProtocolClient"),
290       protocol_(protocol) {}
291
292 ///////////////////////////////////////////////////////////////////////////////
293 // DefaultProtocolClientWorker, protected:
294
295 DefaultProtocolClientWorker::~DefaultProtocolClientWorker() = default;
296
297 ///////////////////////////////////////////////////////////////////////////////
298 // DefaultProtocolClientWorker, private:
299
300 DefaultWebClientState DefaultProtocolClientWorker::CheckIsDefaultImpl() {
301   return IsDefaultProtocolClient(protocol_);
302 }
303
304 void DefaultProtocolClientWorker::SetAsDefaultImpl(
305     const base::Closure& on_finished_callback) {
306   switch (GetDefaultWebClientSetPermission()) {
307     case SET_DEFAULT_NOT_ALLOWED:
308       // Not allowed, do nothing.
309       break;
310     case SET_DEFAULT_UNATTENDED:
311       SetAsDefaultProtocolClient(protocol_);
312       break;
313     case SET_DEFAULT_INTERACTIVE:
314 #if defined(OS_WIN)
315       if (interactive_permitted_) {
316         switch (ShellUtil::GetInteractiveSetDefaultMode()) {
317           case ShellUtil::INTENT_PICKER:
318             win::SetAsDefaultProtocolClientUsingIntentPicker(protocol_);
319             break;
320           case ShellUtil::SYSTEM_SETTINGS:
321             win::SetAsDefaultProtocolClientUsingSystemSettings(
322                 protocol_, on_finished_callback);
323             // Early return because the function above takes care of calling
324             // |on_finished_callback|.
325             return;
326         }
327       }
328 #endif  // defined(OS_WIN)
329       break;
330   }
331   on_finished_callback.Run();
332 }
333
334 }  // namespace shell_integration