diff options
Diffstat (limited to 'chrome/browser/shell_integration.cc')
-rw-r--r-- | chrome/browser/shell_integration.cc | 192 |
1 files changed, 57 insertions, 135 deletions
diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc index 6f1957a..e982ab8 100644 --- a/chrome/browser/shell_integration.cc +++ b/chrome/browser/shell_integration.cc @@ -4,152 +4,74 @@ #include "chrome/browser/shell_integration.h" -#include <windows.h> -#include <shlobj.h> -#include <shobjidl.h> - -#include "app/win_util.h" -#include "base/command_line.h" -#include "base/file_util.h" #include "base/message_loop.h" -#include "base/path_service.h" -#include "base/registry.h" -#include "base/string_util.h" -#include "base/task.h" -#include "base/win_util.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/installer/util/browser_distribution.h" -#include "chrome/installer/util/create_reg_key_work_item.h" -#include "chrome/installer/util/set_reg_value_work_item.h" -#include "chrome/installer/util/shell_util.h" -#include "chrome/installer/util/util_constants.h" -#include "chrome/installer/util/work_item.h" -#include "chrome/installer/util/work_item_list.h" +#include "base/thread.h" +#include "chrome/browser/browser_process.h" -bool ShellIntegration::SetAsDefaultBrowser() { - std::wstring chrome_exe; - if (!PathService::Get(base::FILE_EXE, &chrome_exe)) { - LOG(ERROR) << "Error getting app exe path"; - return false; - } +/////////////////////////////////////////////////////////////////////////////// +// ShellIntegration::DefaultBrowserWorker +// - // From UI currently we only allow setting default browser for current user. - if (!ShellUtil::MakeChromeDefault(ShellUtil::CURRENT_USER, - chrome_exe, true)) { - LOG(ERROR) << "Chrome could not be set as default browser."; - return false; - } +ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker( + DefaultBrowserObserver* observer) + : observer_(observer), + ui_loop_(MessageLoop::current()), + file_loop_(g_browser_process->file_thread()->message_loop()) { +} - LOG(INFO) << "Chrome registered as default browser."; - return true; +void ShellIntegration::DefaultBrowserWorker::StartCheckDefaultBrowser() { + observer_->SetDefaultBrowserUIState(STATE_PROCESSING); + file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &DefaultBrowserWorker::ExecuteCheckDefaultBrowser)); } -bool ShellIntegration::IsDefaultBrowser() { - // First determine the app path. If we can't determine what that is, we have - // bigger fish to fry... - std::wstring app_path; - if (!PathService::Get(base::FILE_EXE, &app_path)) { - LOG(ERROR) << "Error getting app exe path"; - return false; - } - // When we check for default browser we don't necessarily want to count file - // type handlers and icons as having changed the default browser status, - // since the user may have changed their shell settings to cause HTML files - // to open with a text editor for example. We also don't want to aggressively - // claim FTP, since the user may have a separate FTP client. It is an open - // question as to how to "heal" these settings. Perhaps the user should just - // re-run the installer or run with the --set-default-browser command line - // flag. There is doubtless some other key we can hook into to cause "Repair" - // to show up in Add/Remove programs for us. - const std::wstring kChromeProtocols[] = {L"http", L"https"}; +void ShellIntegration::DefaultBrowserWorker::StartSetAsDefaultBrowser() { + observer_->SetDefaultBrowserUIState(STATE_PROCESSING); + file_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &DefaultBrowserWorker::ExecuteSetAsDefaultBrowser)); +} - if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { - IApplicationAssociationRegistration* pAAR; - HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration, - NULL, CLSCTX_INPROC, __uuidof(IApplicationAssociationRegistration), - (void**)&pAAR); - if (!SUCCEEDED(hr)) - return false; +void ShellIntegration::DefaultBrowserWorker::ObserverDestroyed() { + // Our associated view has gone away, so we shouldn't call back to it if + // our worker thread returns after the view is dead. + observer_ = NULL; +} - BrowserDistribution* dist = BrowserDistribution::GetDistribution(); - std::wstring app_name = dist->GetApplicationName(); - std::wstring app_name_with_suffix; - ShellUtil::GetUserSpecificDefaultBrowserSuffix(&app_name_with_suffix); - app_name_with_suffix = app_name + app_name_with_suffix; - for (int i = 0; i < _countof(kChromeProtocols); i++) { - BOOL result = TRUE; - hr = pAAR->QueryAppIsDefault(kChromeProtocols[i].c_str(), AT_URLPROTOCOL, - AL_EFFECTIVE, app_name_with_suffix.c_str(), &result); - if (!SUCCEEDED(hr) || (result == FALSE)) { - hr = pAAR->QueryAppIsDefault(kChromeProtocols[i].c_str(), - AT_URLPROTOCOL, AL_EFFECTIVE, app_name.c_str(), &result); - if (!SUCCEEDED(hr) || (result == FALSE)) { - pAAR->Release(); - return false; - } - } - } - pAAR->Release(); - } else { - std::wstring short_app_path; - GetShortPathName(app_path.c_str(), WriteInto(&short_app_path, MAX_PATH), - MAX_PATH); +/////////////////////////////////////////////////////////////////////////////// +// DefaultBrowserWorker, private: + +void ShellIntegration::DefaultBrowserWorker::ExecuteCheckDefaultBrowser() { + DCHECK(MessageLoop::current() == file_loop_); + bool is_default = ShellIntegration::IsDefaultBrowser(); + ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &DefaultBrowserWorker::CompleteCheckDefaultBrowser, is_default)); +} + +void ShellIntegration::DefaultBrowserWorker::CompleteCheckDefaultBrowser( + bool is_default) { + DCHECK(MessageLoop::current() == ui_loop_); + UpdateUI(is_default); +} + +void ShellIntegration::DefaultBrowserWorker::ExecuteSetAsDefaultBrowser() { + DCHECK(MessageLoop::current() == file_loop_); + ShellIntegration::SetAsDefaultBrowser(); + ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, + &DefaultBrowserWorker::CompleteSetAsDefaultBrowser)); +} - // open command for protocol associations - for (int i = 0; i < _countof(kChromeProtocols); i++) { - // Check in HKEY_CLASSES_ROOT that is the result of merge between - // HKLM and HKCU - HKEY root_key = HKEY_CLASSES_ROOT; - // Check <protocol>\shell\open\command - std::wstring key_path(kChromeProtocols[i] + ShellUtil::kRegShellOpen); - RegKey key(root_key, key_path.c_str(), KEY_READ); - std::wstring value; - if (!key.Valid() || !key.ReadValue(L"", &value)) - return false; - // Need to normalize path in case it's been munged. - CommandLine command_line(L""); - command_line.ParseFromString(value); - std::wstring short_path; - GetShortPathName(command_line.program().c_str(), - WriteInto(&short_path, MAX_PATH), MAX_PATH); - if ((short_path.size() != short_app_path.size()) || - (!std::equal(short_path.begin(), - short_path.end(), - short_app_path.begin(), - CaseInsensitiveCompare<wchar_t>()))) - return false; - } +void ShellIntegration::DefaultBrowserWorker::CompleteSetAsDefaultBrowser() { + DCHECK(MessageLoop::current() == ui_loop_); + if (observer_) { + // Set as default completed, check again to make sure it stuck... + StartCheckDefaultBrowser(); } - return true; } -// There is no reliable way to say which browser is default on a machine (each -// browser can have some of the protocols/shortcuts). So we look for only HTTP -// protocol handler. Even this handler is located at different places in -// registry on XP and Vista: -// - HKCR\http\shell\open\command (XP) -// - HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\ -// http\UserChoice (Vista) -// This method checks if Firefox is defualt browser by checking these -// locations and returns true if Firefox traces are found there. In case of -// error (or if Firefox is not found)it returns the default value which -// is false. -bool ShellIntegration::IsFirefoxDefaultBrowser() { - bool ff_default = false; - if (win_util::GetWinVersion() >= win_util::WINVERSION_VISTA) { - std::wstring app_cmd; - RegKey key(HKEY_CURRENT_USER, ShellUtil::kRegVistaUrlPrefs, KEY_READ); - if (key.Valid() && key.ReadValue(L"Progid", &app_cmd) && - app_cmd == L"FirefoxURL") - ff_default = true; - } else { - std::wstring key_path(L"http"); - key_path.append(ShellUtil::kRegShellOpen); - RegKey key(HKEY_CLASSES_ROOT, key_path.c_str(), KEY_READ); - std::wstring app_cmd; - if (key.Valid() && key.ReadValue(L"", &app_cmd) && - std::wstring::npos != StringToLowerASCII(app_cmd).find(L"firefox")) - ff_default = true; +void ShellIntegration::DefaultBrowserWorker::UpdateUI(bool is_default) { + if (observer_) { + DefaultBrowserUIState state = + is_default ? STATE_DEFAULT : STATE_NOT_DEFAULT; + observer_->SetDefaultBrowserUIState(state); } - return ff_default; } |