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(¤t_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