blob: a338935b9d4f82a1bad9b34aae018399130980aa [file] [log] [blame]
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/importer/importer_list.h"
#include "base/bind.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/importer/firefox_importer_utils.h"
#include "chrome/browser/importer/importer_bridge.h"
#include "chrome/browser/importer/importer_data_types.h"
#include "chrome/browser/importer/importer_list_observer.h"
#include "chrome/browser/shell_integration.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#if defined(OS_MACOSX)
#include <CoreFoundation/CoreFoundation.h>
#include "base/mac/foundation_util.h"
#include "chrome/browser/importer/safari_importer.h"
#endif
using content::BrowserThread;
namespace {
#if defined(OS_WIN)
void DetectIEProfiles(std::vector<importer::SourceProfile*>* profiles) {
// IE always exists and doesn't have multiple profiles.
importer::SourceProfile* ie = new importer::SourceProfile;
ie->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_IE);
ie->importer_type = importer::TYPE_IE;
ie->source_path.clear();
ie->app_path.clear();
ie->services_supported = importer::HISTORY | importer::FAVORITES |
importer::COOKIES | importer::PASSWORDS | importer::SEARCH_ENGINES;
profiles->push_back(ie);
}
#endif // defined(OS_WIN)
#if defined(OS_MACOSX)
void DetectSafariProfiles(std::vector<importer::SourceProfile*>* profiles) {
uint16 items = importer::NONE;
if (!SafariImporter::CanImport(base::mac::GetUserLibraryPath(), &items))
return;
importer::SourceProfile* safari = new importer::SourceProfile;
safari->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_SAFARI);
safari->importer_type = importer::TYPE_SAFARI;
safari->source_path.clear();
safari->app_path.clear();
safari->services_supported = items;
profiles->push_back(safari);
}
#endif // defined(OS_MACOSX)
void DetectFirefoxProfiles(std::vector<importer::SourceProfile*>* profiles) {
FilePath profile_path = GetFirefoxProfilePath();
if (profile_path.empty())
return;
// Detects which version of Firefox is installed.
importer::ImporterType firefox_type;
FilePath app_path;
int version = 0;
#if defined(OS_WIN)
version = GetCurrentFirefoxMajorVersionFromRegistry();
#endif
if (version < 2)
GetFirefoxVersionAndPathFromProfile(profile_path, &version, &app_path);
if (version == 2) {
firefox_type = importer::TYPE_FIREFOX2;
} else if (version >= 3) {
firefox_type = importer::TYPE_FIREFOX3;
} else {
// Ignores other versions of firefox.
return;
}
importer::SourceProfile* firefox = new importer::SourceProfile;
firefox->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_FIREFOX);
firefox->importer_type = firefox_type;
firefox->source_path = profile_path;
#if defined(OS_WIN)
firefox->app_path = GetFirefoxInstallPathFromRegistry();
#endif
if (firefox->app_path.empty())
firefox->app_path = app_path;
firefox->services_supported = importer::HISTORY | importer::FAVORITES |
importer::PASSWORDS | importer::SEARCH_ENGINES;
profiles->push_back(firefox);
}
void DetectGoogleToolbarProfiles(
std::vector<importer::SourceProfile*>* profiles,
scoped_refptr<net::URLRequestContextGetter> request_context_getter) {
if (first_run::IsChromeFirstRun())
return;
importer::SourceProfile* google_toolbar = new importer::SourceProfile;
google_toolbar->importer_name =
l10n_util::GetStringUTF16(IDS_IMPORT_FROM_GOOGLE_TOOLBAR);
google_toolbar->importer_type = importer::TYPE_GOOGLE_TOOLBAR5;
google_toolbar->source_path.clear();
google_toolbar->app_path.clear();
google_toolbar->services_supported = importer::FAVORITES;
google_toolbar->request_context_getter = request_context_getter;
profiles->push_back(google_toolbar);
}
} // namespace
ImporterList::ImporterList(
net::URLRequestContextGetter* request_context_getter)
: source_thread_id_(BrowserThread::UI),
observer_(NULL),
is_observed_(false),
source_profiles_loaded_(false) {
request_context_getter_ = make_scoped_refptr(request_context_getter);
}
void ImporterList::DetectSourceProfiles(
importer::ImporterListObserver* observer) {
DCHECK(observer);
observer_ = observer;
is_observed_ = true;
bool res = BrowserThread::GetCurrentThreadIdentifier(&source_thread_id_);
DCHECK(res);
BrowserThread::PostTask(
BrowserThread::FILE,
FROM_HERE,
base::Bind(&ImporterList::DetectSourceProfilesWorker, this));
}
void ImporterList::SetObserver(importer::ImporterListObserver* observer) {
observer_ = observer;
}
void ImporterList::DetectSourceProfilesHack() {
DetectSourceProfilesWorker();
}
const importer::SourceProfile& ImporterList::GetSourceProfileAt(
size_t index) const {
DCHECK(source_profiles_loaded_);
DCHECK_LT(index, count());
return *source_profiles_[index];
}
const importer::SourceProfile& ImporterList::GetSourceProfileForImporterType(
int importer_type) const {
DCHECK(source_profiles_loaded_);
for (size_t i = 0; i < count(); ++i) {
if (source_profiles_[i]->importer_type == importer_type)
return *source_profiles_[i];
}
NOTREACHED();
return *(new importer::SourceProfile);
}
ImporterList::~ImporterList() {
}
void ImporterList::DetectSourceProfilesWorker() {
// TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
// removed.
if (is_observed_)
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
std::vector<importer::SourceProfile*> profiles;
// The first run import will automatically take settings from the first
// profile detected, which should be the user's current default.
#if defined(OS_WIN)
if (ShellIntegration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(&profiles);
DetectIEProfiles(&profiles);
} else {
DetectIEProfiles(&profiles);
DetectFirefoxProfiles(&profiles);
}
// TODO(brg) : Current UI requires win_util.
DetectGoogleToolbarProfiles(&profiles, request_context_getter_);
#elif defined(OS_MACOSX)
if (ShellIntegration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(&profiles);
DetectSafariProfiles(&profiles);
} else {
DetectSafariProfiles(&profiles);
DetectFirefoxProfiles(&profiles);
}
#else
DetectFirefoxProfiles(&profiles);
#endif
// TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
// removed.
if (is_observed_) {
BrowserThread::PostTask(
source_thread_id_,
FROM_HERE,
base::Bind(&ImporterList::SourceProfilesLoaded, this, profiles));
} else {
source_profiles_->assign(profiles.begin(), profiles.end());
source_profiles_loaded_ = true;
}
}
void ImporterList::SourceProfilesLoaded(
const std::vector<importer::SourceProfile*>& profiles) {
// |observer_| may be NULL if it removed itself before being notified.
if (!observer_)
return;
BrowserThread::ID current_thread_id;
BrowserThread::GetCurrentThreadIdentifier(&current_thread_id);
DCHECK_EQ(current_thread_id, source_thread_id_);
source_profiles_->assign(profiles.begin(), profiles.end());
source_profiles_loaded_ = true;
source_thread_id_ = BrowserThread::UI;
observer_->OnSourceProfilesLoaded();
observer_ = NULL;
// TODO(jhawkins): Remove once DetectSourceProfilesHack is removed.
is_observed_ = false;
}