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)
DetectIEProfiles(std::vector<importer::SourceProfile * > * profiles)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)
DetectSafariProfiles(std::vector<importer::SourceProfile * > * profiles)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
DetectFirefoxProfiles(std::vector<importer::SourceProfile * > * profiles)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
DetectGoogleToolbarProfiles(std::vector<importer::SourceProfile * > * profiles)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
ImporterList()109 ImporterList::ImporterList()
110 : source_thread_id_(BrowserThread::UI),
111 observer_(NULL),
112 is_observed_(false),
113 source_profiles_loaded_(false) {
114 }
115
~ImporterList()116 ImporterList::~ImporterList() {
117 }
118
DetectSourceProfiles(Observer * observer)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
SetObserver(Observer * observer)132 void ImporterList::SetObserver(Observer* observer) {
133 observer_ = observer;
134 }
135
DetectSourceProfilesHack()136 void ImporterList::DetectSourceProfilesHack() {
137 DetectSourceProfilesWorker();
138 }
139
GetSourceProfileAt(size_t index) const140 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
GetSourceProfileForImporterType(int importer_type) const147 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
DetectSourceProfilesWorker()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
SourceProfilesLoaded(const std::vector<importer::SourceProfile * > & profiles)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