Home | History | Annotate | Download | only in importer
      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/importer/importer_list.h"
      6 
      7 #include "base/bind.h"
      8 #include "chrome/browser/importer/importer_list_observer.h"
      9 #include "chrome/browser/shell_integration.h"
     10 #include "chrome/common/importer/firefox_importer_utils.h"
     11 #include "chrome/common/importer/importer_bridge.h"
     12 #include "chrome/common/importer/importer_data_types.h"
     13 #include "grit/generated_resources.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 
     16 #if defined(OS_MACOSX)
     17 #include <CoreFoundation/CoreFoundation.h>
     18 
     19 #include "base/mac/foundation_util.h"
     20 #include "chrome/common/importer/safari_importer_utils.h"
     21 #endif
     22 
     23 using content::BrowserThread;
     24 
     25 namespace {
     26 
     27 #if defined(OS_WIN)
     28 void DetectIEProfiles(std::vector<importer::SourceProfile*>* profiles) {
     29     // IE always exists and doesn't have multiple profiles.
     30   importer::SourceProfile* ie = new importer::SourceProfile;
     31   ie->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_IE);
     32   ie->importer_type = importer::TYPE_IE;
     33   ie->source_path.clear();
     34   ie->app_path.clear();
     35   ie->services_supported = importer::HISTORY | importer::FAVORITES |
     36       importer::COOKIES | importer::PASSWORDS | importer::SEARCH_ENGINES;
     37   profiles->push_back(ie);
     38 }
     39 #endif  // defined(OS_WIN)
     40 
     41 #if defined(OS_MACOSX)
     42 void DetectSafariProfiles(std::vector<importer::SourceProfile*>* profiles) {
     43   uint16 items = importer::NONE;
     44   if (!SafariImporterCanImport(base::mac::GetUserLibraryPath(), &items))
     45     return;
     46 
     47   importer::SourceProfile* safari = new importer::SourceProfile;
     48   safari->importer_name = l10n_util::GetStringUTF16(IDS_IMPORT_FROM_SAFARI);
     49   safari->importer_type = importer::TYPE_SAFARI;
     50   safari->source_path.clear();
     51   safari->app_path.clear();
     52   safari->services_supported = items;
     53   profiles->push_back(safari);
     54 }
     55 #endif  // defined(OS_MACOSX)
     56 
     57 // |locale|: The application locale used for lookups in Firefox's
     58 // locale-specific search engines feature (see firefox_importer.cc for
     59 // details).
     60 void DetectFirefoxProfiles(const std::string locale,
     61                            std::vector<importer::SourceProfile*>* profiles) {
     62   base::FilePath profile_path = GetFirefoxProfilePath();
     63   if (profile_path.empty())
     64     return;
     65 
     66   // Detects which version of Firefox is installed.
     67   importer::ImporterType firefox_type;
     68   base::FilePath app_path;
     69   int version = 0;
     70 #if defined(OS_WIN)
     71   version = GetCurrentFirefoxMajorVersionFromRegistry();
     72 #endif
     73   if (version < 2)
     74     GetFirefoxVersionAndPathFromProfile(profile_path, &version, &app_path);
     75 
     76   if (version >= 3) {
     77     firefox_type = importer::TYPE_FIREFOX;
     78   } else {
     79     // Ignores old versions of firefox.
     80     return;
     81   }
     82 
     83   importer::SourceProfile* firefox = new importer::SourceProfile;
     84   firefox->importer_name = GetFirefoxImporterName(app_path);
     85   firefox->importer_type = firefox_type;
     86   firefox->source_path = profile_path;
     87 #if defined(OS_WIN)
     88   firefox->app_path = GetFirefoxInstallPathFromRegistry();
     89 #endif
     90   if (firefox->app_path.empty())
     91     firefox->app_path = app_path;
     92   firefox->services_supported = importer::HISTORY | importer::FAVORITES |
     93       importer::PASSWORDS | importer::SEARCH_ENGINES;
     94   firefox->locale = locale;
     95   profiles->push_back(firefox);
     96 }
     97 
     98 }  // namespace
     99 
    100 ImporterList::ImporterList()
    101     : source_thread_id_(BrowserThread::UI),
    102       observer_(NULL),
    103       is_observed_(false),
    104       source_profiles_loaded_(false) {
    105 }
    106 
    107 void ImporterList::DetectSourceProfiles(
    108     const std::string& locale,
    109     importer::ImporterListObserver* observer) {
    110   DCHECK(observer);
    111   observer_ = observer;
    112   is_observed_ = true;
    113 
    114   bool res = BrowserThread::GetCurrentThreadIdentifier(&source_thread_id_);
    115   DCHECK(res);
    116 
    117   BrowserThread::PostTask(
    118       BrowserThread::FILE,
    119       FROM_HERE,
    120       base::Bind(&ImporterList::DetectSourceProfilesWorker, this, locale));
    121 }
    122 
    123 void ImporterList::DetectSourceProfilesHack(const std::string& locale) {
    124   DetectSourceProfilesWorker(locale);
    125 }
    126 
    127 const importer::SourceProfile& ImporterList::GetSourceProfileAt(
    128     size_t index) const {
    129   DCHECK(source_profiles_loaded_);
    130   DCHECK_LT(index, count());
    131   return *source_profiles_[index];
    132 }
    133 
    134 const importer::SourceProfile& ImporterList::GetSourceProfileForImporterType(
    135     int importer_type) const {
    136   DCHECK(source_profiles_loaded_);
    137 
    138   for (size_t i = 0; i < count(); ++i) {
    139     if (source_profiles_[i]->importer_type == importer_type)
    140       return *source_profiles_[i];
    141   }
    142   NOTREACHED();
    143   return *(new importer::SourceProfile);
    144 }
    145 
    146 ImporterList::~ImporterList() {
    147 }
    148 
    149 void ImporterList::DetectSourceProfilesWorker(const std::string& locale) {
    150   // TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
    151   // removed.
    152   if (is_observed_)
    153     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    154 
    155   std::vector<importer::SourceProfile*> profiles;
    156 
    157   // The first run import will automatically take settings from the first
    158   // profile detected, which should be the user's current default.
    159 #if defined(OS_WIN)
    160   if (ShellIntegration::IsFirefoxDefaultBrowser()) {
    161     DetectFirefoxProfiles(locale, &profiles);
    162     DetectIEProfiles(&profiles);
    163   } else {
    164     DetectIEProfiles(&profiles);
    165     DetectFirefoxProfiles(locale, &profiles);
    166   }
    167 #elif defined(OS_MACOSX)
    168   if (ShellIntegration::IsFirefoxDefaultBrowser()) {
    169     DetectFirefoxProfiles(locale, &profiles);
    170     DetectSafariProfiles(&profiles);
    171   } else {
    172     DetectSafariProfiles(&profiles);
    173     DetectFirefoxProfiles(locale, &profiles);
    174   }
    175 #else
    176   DetectFirefoxProfiles(locale, &profiles);
    177 #endif
    178   importer::SourceProfile* bookmarks_file = new importer::SourceProfile;
    179   bookmarks_file->importer_name =
    180       l10n_util::GetStringUTF16(IDS_IMPORT_FROM_BOOKMARKS_HTML_FILE);
    181   bookmarks_file->importer_type = importer::TYPE_BOOKMARKS_FILE;
    182   bookmarks_file->services_supported = importer::FAVORITES;
    183   profiles.push_back(bookmarks_file);
    184 
    185   // TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
    186   // removed.
    187   if (is_observed_) {
    188     BrowserThread::PostTask(
    189         source_thread_id_,
    190         FROM_HERE,
    191         base::Bind(&ImporterList::SourceProfilesLoaded, this, profiles));
    192   } else {
    193     source_profiles_.assign(profiles.begin(), profiles.end());
    194     source_profiles_loaded_ = true;
    195   }
    196 }
    197 
    198 void ImporterList::SourceProfilesLoaded(
    199     const std::vector<importer::SourceProfile*>& profiles) {
    200   // |observer_| may be NULL if it removed itself before being notified.
    201   if (!observer_)
    202     return;
    203 
    204   BrowserThread::ID current_thread_id;
    205   BrowserThread::GetCurrentThreadIdentifier(&current_thread_id);
    206   DCHECK_EQ(current_thread_id, source_thread_id_);
    207 
    208   source_profiles_.assign(profiles.begin(), profiles.end());
    209   source_profiles_loaded_ = true;
    210   source_thread_id_ = BrowserThread::UI;
    211 
    212   observer_->OnSourceProfilesLoaded();
    213   observer_ = NULL;
    214 
    215   // TODO(jhawkins): Remove once DetectSourceProfilesHack is removed.
    216   is_observed_ = false;
    217 }
    218