shell_integration.cc revision ddb351dbec246cf1fab5ec20d2d5520909041de1
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
18ShellIntegration::ShortcutInfo::ShortcutInfo()
19    : create_on_desktop(false),
20      create_in_applications_menu(false),
21      create_in_quick_launch_bar(false) {
22}
23
24ShellIntegration::ShortcutInfo::~ShortcutInfo() {}
25
26// static
27CommandLine 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
67ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker(
68    DefaultBrowserObserver* observer)
69    : observer_(observer) {
70}
71
72void ShellIntegration::DefaultBrowserWorker::StartCheckDefaultBrowser() {
73  observer_->SetDefaultBrowserUIState(STATE_PROCESSING);
74  BrowserThread::PostTask(
75      BrowserThread::FILE, FROM_HERE,
76      NewRunnableMethod(
77          this, &DefaultBrowserWorker::ExecuteCheckDefaultBrowser));
78}
79
80void ShellIntegration::DefaultBrowserWorker::StartSetAsDefaultBrowser() {
81  observer_->SetDefaultBrowserUIState(STATE_PROCESSING);
82  BrowserThread::PostTask(
83      BrowserThread::FILE, FROM_HERE,
84      NewRunnableMethod(
85          this, &DefaultBrowserWorker::ExecuteSetAsDefaultBrowser));
86}
87
88void 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
97void 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
106void ShellIntegration::DefaultBrowserWorker::CompleteCheckDefaultBrowser(
107    DefaultBrowserState state) {
108  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
109  UpdateUI(state);
110}
111
112void 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
121void 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
129void 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