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     bool include_interactive_profiles,
    110     importer::ImporterListObserver* observer) {
    111   DCHECK(observer);
    112   observer_ = observer;
    113   is_observed_ = true;
    114 
    115   bool res = BrowserThread::GetCurrentThreadIdentifier(&source_thread_id_);
    116   DCHECK(res);
    117 
    118   BrowserThread::PostTask(BrowserThread::FILE,
    119                           FROM_HERE,
    120                           base::Bind(&ImporterList::DetectSourceProfilesWorker,
    121                                      this,
    122                                      locale,
    123                                      include_interactive_profiles));
    124 }
    125 
    126 void ImporterList::DetectSourceProfilesHack(const std::string& locale,
    127                                             bool include_interactive_profiles) {
    128   DetectSourceProfilesWorker(locale, include_interactive_profiles);
    129 }
    130 
    131 const importer::SourceProfile& ImporterList::GetSourceProfileAt(
    132     size_t index) const {
    133   DCHECK(source_profiles_loaded_);
    134   DCHECK_LT(index, count());
    135   return *source_profiles_[index];
    136 }
    137 
    138 const importer::SourceProfile& ImporterList::GetSourceProfileForImporterType(
    139     int importer_type) const {
    140   DCHECK(source_profiles_loaded_);
    141 
    142   for (size_t i = 0; i < count(); ++i) {
    143     if (source_profiles_[i]->importer_type == importer_type)
    144       return *source_profiles_[i];
    145   }
    146   NOTREACHED();
    147   return *(new importer::SourceProfile);
    148 }
    149 
    150 ImporterList::~ImporterList() {
    151 }
    152 
    153 void ImporterList::DetectSourceProfilesWorker(
    154     const std::string& locale,
    155     bool include_interactive_profiles) {
    156   // TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
    157   // removed.
    158   if (is_observed_)
    159     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
    160 
    161   std::vector<importer::SourceProfile*> profiles;
    162 
    163   // The first run import will automatically take settings from the first
    164   // profile detected, which should be the user's current default.
    165 #if defined(OS_WIN)
    166   if (ShellIntegration::IsFirefoxDefaultBrowser()) {
    167     DetectFirefoxProfiles(locale, &profiles);
    168     DetectIEProfiles(&profiles);
    169   } else {
    170     DetectIEProfiles(&profiles);
    171     DetectFirefoxProfiles(locale, &profiles);
    172   }
    173 #elif defined(OS_MACOSX)
    174   if (ShellIntegration::IsFirefoxDefaultBrowser()) {
    175     DetectFirefoxProfiles(locale, &profiles);
    176     DetectSafariProfiles(&profiles);
    177   } else {
    178     DetectSafariProfiles(&profiles);
    179     DetectFirefoxProfiles(locale, &profiles);
    180   }
    181 #else
    182   DetectFirefoxProfiles(locale, &profiles);
    183 #endif
    184   if (include_interactive_profiles) {
    185     importer::SourceProfile* bookmarks_profile = new importer::SourceProfile;
    186     bookmarks_profile->importer_name =
    187         l10n_util::GetStringUTF16(IDS_IMPORT_FROM_BOOKMARKS_HTML_FILE);
    188     bookmarks_profile->importer_type = importer::TYPE_BOOKMARKS_FILE;
    189     bookmarks_profile->services_supported = importer::FAVORITES;
    190     profiles.push_back(bookmarks_profile);
    191   }
    192 
    193   // TODO(jhawkins): Remove this condition once DetectSourceProfilesHack is
    194   // removed.
    195   if (is_observed_) {
    196     BrowserThread::PostTask(
    197         source_thread_id_,
    198         FROM_HERE,
    199         base::Bind(&ImporterList::SourceProfilesLoaded, this, profiles));
    200   } else {
    201     source_profiles_.assign(profiles.begin(), profiles.end());
    202     source_profiles_loaded_ = true;
    203   }
    204 }
    205 
    206 void ImporterList::SourceProfilesLoaded(
    207     const std::vector<importer::SourceProfile*>& profiles) {
    208   // |observer_| may be NULL if it removed itself before being notified.
    209   if (!observer_)
    210     return;
    211 
    212   BrowserThread::ID current_thread_id;
    213   BrowserThread::GetCurrentThreadIdentifier(&current_thread_id);
    214   DCHECK_EQ(current_thread_id, source_thread_id_);
    215 
    216   source_profiles_.assign(profiles.begin(), profiles.end());
    217   source_profiles_loaded_ = true;
    218   source_thread_id_ = BrowserThread::UI;
    219 
    220   observer_->OnSourceProfilesLoaded();
    221   observer_ = NULL;
    222 
    223   // TODO(jhawkins): Remove once DetectSourceProfilesHack is removed.
    224   is_observed_ = false;
    225 }
    226