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 18 ShellIntegration::ShortcutInfo::ShortcutInfo() 19 : create_on_desktop(false), 20 create_in_applications_menu(false), 21 create_in_quick_launch_bar(false) { 22 } 23 24 ShellIntegration::ShortcutInfo::~ShortcutInfo() {} 25 26 // static 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 67 ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker( 68 DefaultBrowserObserver* observer) 69 : observer_(observer) { 70 } 71 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 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 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 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 106 void ShellIntegration::DefaultBrowserWorker::CompleteCheckDefaultBrowser( 107 DefaultBrowserState state) { 108 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 109 UpdateUI(state); 110 } 111 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 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 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