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