OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/importer/firefox3_importer.h" | 5 #include "chrome/browser/importer/firefox3_importer.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
15 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
16 #include "chrome/browser/bookmarks/bookmark_html_reader.h" | 16 #include "chrome/browser/bookmarks/bookmark_html_reader.h" |
17 #include "chrome/browser/bookmarks/imported_bookmark_entry.h" | 17 #include "chrome/browser/bookmarks/imported_bookmark_entry.h" |
18 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
19 #include "chrome/browser/favicon/favicon_util.h" | 19 #include "chrome/browser/favicon/favicon_util.h" |
20 #include "chrome/browser/favicon/imported_favicon_usage.h" | 20 #include "chrome/browser/favicon/imported_favicon_usage.h" |
21 #include "chrome/browser/importer/firefox_importer_utils.h" | 21 #include "chrome/browser/importer/firefox_importer_utils.h" |
22 #include "chrome/browser/importer/importer_bridge.h" | 22 #include "chrome/browser/importer/importer_bridge.h" |
23 #include "chrome/browser/importer/nss_decryptor.h" | 23 #include "chrome/browser/importer/nss_decryptor.h" |
24 #include "chrome/browser/search_engines/template_url.h" | |
25 #include "chrome/common/time_format.h" | 24 #include "chrome/common/time_format.h" |
26 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
27 #include "content/public/common/password_form.h" | 26 #include "content/public/common/password_form.h" |
28 #include "googleurl/src/gurl.h" | 27 #include "googleurl/src/gurl.h" |
29 #include "grit/generated_resources.h" | 28 #include "grit/generated_resources.h" |
30 #include "sql/connection.h" | 29 #include "sql/connection.h" |
31 #include "sql/statement.h" | 30 #include "sql/statement.h" |
32 | 31 |
33 using content::BrowserThread; | 32 using content::BrowserThread; |
34 | 33 |
35 namespace { | 34 namespace { |
36 | 35 |
37 // Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/ | 36 // Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/ |
38 // components/places/public/nsINavBookmarksService.idl | 37 // components/places/public/nsINavBookmarksService.idl |
39 enum BookmarkItemType { | 38 enum BookmarkItemType { |
40 TYPE_BOOKMARK = 1, | 39 TYPE_BOOKMARK = 1, |
41 TYPE_FOLDER = 2, | 40 TYPE_FOLDER = 2, |
42 TYPE_SEPARATOR = 3, | 41 TYPE_SEPARATOR = 3, |
43 TYPE_DYNAMIC_CONTAINER = 4 | 42 TYPE_DYNAMIC_CONTAINER = 4 |
44 }; | 43 }; |
45 | 44 |
46 // Creates a TemplateURL with the |keyword| and |url|. |title| may be empty. | |
47 // This function transfers ownership of the created TemplateURL to the caller. | |
48 TemplateURL* CreateTemplateURL(const string16& title, | |
49 const string16& keyword, | |
50 const GURL& url) { | |
51 // Skip if the keyword or url is invalid. | |
52 if (keyword.empty() || !url.is_valid()) | |
53 return NULL; | |
54 | |
55 TemplateURLData data; | |
56 // We set short name by using the title if it exists. | |
57 // Otherwise, we use the shortcut. | |
58 data.short_name = title.empty() ? keyword : title; | |
59 data.SetKeyword(keyword); | |
60 data.SetURL(TemplateURLRef::DisplayURLToURLRef(UTF8ToUTF16(url.spec()))); | |
61 return new TemplateURL(NULL, data); | |
62 } | |
63 | |
64 // Loads the default bookmarks in the Firefox installed at |app_path|, | 45 // Loads the default bookmarks in the Firefox installed at |app_path|, |
65 // and stores their locations in |urls|. | 46 // and stores their locations in |urls|. |
66 void LoadDefaultBookmarks(const base::FilePath& app_path, | 47 void LoadDefaultBookmarks(const base::FilePath& app_path, |
67 std::set<GURL>* urls) { | 48 std::set<GURL>* urls) { |
68 base::FilePath file = app_path.AppendASCII("defaults") | 49 base::FilePath file = app_path.AppendASCII("defaults") |
69 .AppendASCII("profile") | 50 .AppendASCII("profile") |
70 .AppendASCII("bookmarks.html"); | 51 .AppendASCII("bookmarks.html"); |
71 urls->clear(); | 52 urls->clear(); |
72 | 53 |
73 std::vector<ImportedBookmarkEntry> bookmarks; | 54 std::vector<ImportedBookmarkEntry> bookmarks; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
213 | 194 |
214 BookmarkList list; | 195 BookmarkList list; |
215 GetTopBookmarkFolder(&db, toolbar_folder_id, &list); | 196 GetTopBookmarkFolder(&db, toolbar_folder_id, &list); |
216 GetTopBookmarkFolder(&db, menu_folder_id, &list); | 197 GetTopBookmarkFolder(&db, menu_folder_id, &list); |
217 GetTopBookmarkFolder(&db, unsorted_folder_id, &list); | 198 GetTopBookmarkFolder(&db, unsorted_folder_id, &list); |
218 size_t count = list.size(); | 199 size_t count = list.size(); |
219 for (size_t i = 0; i < count; ++i) | 200 for (size_t i = 0; i < count; ++i) |
220 GetWholeBookmarkFolder(&db, &list, i, NULL); | 201 GetWholeBookmarkFolder(&db, &list, i, NULL); |
221 | 202 |
222 std::vector<ImportedBookmarkEntry> bookmarks; | 203 std::vector<ImportedBookmarkEntry> bookmarks; |
223 std::vector<TemplateURL*> template_urls; | 204 std::vector<importer::URLKeywordInfo> url_keywords; |
224 FaviconMap favicon_map; | 205 FaviconMap favicon_map; |
225 | 206 |
226 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based | 207 // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based |
227 // keywords yet. We won't include them in the list. | 208 // keywords yet. We won't include them in the list. |
228 std::set<int> post_keyword_ids; | 209 std::set<int> post_keyword_ids; |
229 const char* query = "SELECT b.id FROM moz_bookmarks b " | 210 const char* query = "SELECT b.id FROM moz_bookmarks b " |
230 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " | 211 "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " |
231 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " | 212 "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " |
232 "WHERE aa.name = 'bookmarkProperties/POSTData'"; | 213 "WHERE aa.name = 'bookmarkProperties/POSTData'"; |
233 sql::Statement s(db.GetUniqueStatement(query)); | 214 sql::Statement s(db.GetUniqueStatement(query)); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 entry.path = path; | 282 entry.path = path; |
302 entry.in_toolbar = is_in_toolbar; | 283 entry.in_toolbar = is_in_toolbar; |
303 entry.is_folder = item->type == TYPE_FOLDER; | 284 entry.is_folder = item->type == TYPE_FOLDER; |
304 | 285 |
305 bookmarks.push_back(entry); | 286 bookmarks.push_back(entry); |
306 | 287 |
307 if (item->type == TYPE_BOOKMARK) { | 288 if (item->type == TYPE_BOOKMARK) { |
308 if (item->favicon) | 289 if (item->favicon) |
309 favicon_map[item->favicon].insert(item->url); | 290 favicon_map[item->favicon].insert(item->url); |
310 | 291 |
311 // This bookmark has a keyword, we import it to our TemplateURL model. | 292 // This bookmark has a keyword, we should import it. |
312 TemplateURL* t_url = CreateTemplateURL( | 293 if (!item->keyword.empty() && item->url.is_valid()) { |
313 item->title, UTF8ToUTF16(item->keyword), item->url); | 294 importer::URLKeywordInfo url_keyword_info; |
314 if (t_url) | 295 url_keyword_info.url = item->url; |
315 template_urls.push_back(t_url); | 296 url_keyword_info.keyword.assign(UTF8ToUTF16(item->keyword)); |
| 297 url_keyword_info.display_name = item->title; |
| 298 url_keywords.push_back(url_keyword_info); |
| 299 } |
316 } | 300 } |
317 } | 301 } |
318 | 302 |
319 STLDeleteElements(&list); | 303 STLDeleteElements(&list); |
320 | 304 |
321 // Write into profile. | 305 // Write into profile. |
322 if (!bookmarks.empty() && !cancelled()) { | 306 if (!bookmarks.empty() && !cancelled()) { |
323 const string16& first_folder_name = | 307 const string16& first_folder_name = |
324 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX); | 308 bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX); |
325 bridge_->AddBookmarks(bookmarks, first_folder_name); | 309 bridge_->AddBookmarks(bookmarks, first_folder_name); |
326 } | 310 } |
327 if (!template_urls.empty() && !cancelled()) | 311 if (!url_keywords.empty() && !cancelled()) { |
328 bridge_->SetKeywords(template_urls, false); | 312 bridge_->SetKeywords(url_keywords, false); |
329 else | 313 } |
330 STLDeleteElements(&template_urls); | |
331 if (!favicon_map.empty() && !cancelled()) { | 314 if (!favicon_map.empty() && !cancelled()) { |
332 std::vector<ImportedFaviconUsage> favicons; | 315 std::vector<ImportedFaviconUsage> favicons; |
333 LoadFavicons(&db, favicon_map, &favicons); | 316 LoadFavicons(&db, favicon_map, &favicons); |
334 bridge_->SetFavicons(favicons); | 317 bridge_->SetFavicons(favicons); |
335 } | 318 } |
336 } | 319 } |
337 | 320 |
338 void Firefox3Importer::ImportPasswords() { | 321 void Firefox3Importer::ImportPasswords() { |
339 // Initializes NSS3. | 322 // Initializes NSS3. |
340 NSSDecryptor decryptor; | 323 NSSDecryptor decryptor; |
(...skipping 20 matching lines...) Expand all Loading... |
361 } | 344 } |
362 | 345 |
363 if (!cancelled()) { | 346 if (!cancelled()) { |
364 for (size_t i = 0; i < forms.size(); ++i) { | 347 for (size_t i = 0; i < forms.size(); ++i) { |
365 bridge_->SetPasswordForm(forms[i]); | 348 bridge_->SetPasswordForm(forms[i]); |
366 } | 349 } |
367 } | 350 } |
368 } | 351 } |
369 | 352 |
370 void Firefox3Importer::ImportSearchEngines() { | 353 void Firefox3Importer::ImportSearchEngines() { |
371 std::vector<base::FilePath> files; | 354 std::vector<std::string> search_engine_data; |
372 GetSearchEnginesXMLFiles(&files); | 355 GetSearchEnginesXMLData(&search_engine_data); |
373 | 356 |
374 std::vector<TemplateURL*> search_engines; | 357 bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data); |
375 ParseSearchEnginesFromXMLFiles(files, &search_engines); | |
376 | |
377 bridge_->SetKeywords(search_engines, true); | |
378 } | 358 } |
379 | 359 |
380 void Firefox3Importer::ImportHomepage() { | 360 void Firefox3Importer::ImportHomepage() { |
381 GURL home_page = GetHomepage(source_path_); | 361 GURL home_page = GetHomepage(source_path_); |
382 if (home_page.is_valid() && !IsDefaultHomepage(home_page, app_path_)) { | 362 if (home_page.is_valid() && !IsDefaultHomepage(home_page, app_path_)) { |
383 bridge_->AddHomePage(home_page); | 363 bridge_->AddHomePage(home_page); |
384 } | 364 } |
385 } | 365 } |
386 | 366 |
387 void Firefox3Importer::GetSearchEnginesXMLFiles( | 367 void Firefox3Importer::GetSearchEnginesXMLData( |
388 std::vector<base::FilePath>* files) { | 368 std::vector<std::string>* search_engine_data) { |
389 base::FilePath file = source_path_.AppendASCII("search.sqlite"); | 369 base::FilePath file = source_path_.AppendASCII("search.sqlite"); |
390 if (!file_util::PathExists(file)) | 370 if (!file_util::PathExists(file)) |
391 return; | 371 return; |
392 | 372 |
393 sql::Connection db; | 373 sql::Connection db; |
394 if (!db.Open(file)) | 374 if (!db.Open(file)) |
395 return; | 375 return; |
396 | 376 |
397 const char* query = "SELECT engineid FROM engine_data " | 377 const char* query = "SELECT engineid FROM engine_data " |
398 "WHERE engineid NOT IN " | 378 "WHERE engineid NOT IN " |
(...skipping 26 matching lines...) Expand all Loading... |
425 // Remove '[app]/'. | 405 // Remove '[app]/'. |
426 file = app_path.AppendASCII(engine.substr(index + kAppPrefix.length())); | 406 file = app_path.AppendASCII(engine.substr(index + kAppPrefix.length())); |
427 } else if ((index = engine.find(kProfilePrefix)) != std::string::npos) { | 407 } else if ((index = engine.find(kProfilePrefix)) != std::string::npos) { |
428 // Remove '[profile]/'. | 408 // Remove '[profile]/'. |
429 file = profile_path.AppendASCII( | 409 file = profile_path.AppendASCII( |
430 engine.substr(index + kProfilePrefix.length())); | 410 engine.substr(index + kProfilePrefix.length())); |
431 } else { | 411 } else { |
432 // Looks like absolute path to the file. | 412 // Looks like absolute path to the file. |
433 file = base::FilePath::FromUTF8Unsafe(engine); | 413 file = base::FilePath::FromUTF8Unsafe(engine); |
434 } | 414 } |
435 files->push_back(file); | 415 std::string file_data; |
| 416 file_util::ReadFileToString(file, &file_data); |
| 417 search_engine_data->push_back(file_data); |
436 } while (s.Step() && !cancelled()); | 418 } while (s.Step() && !cancelled()); |
437 } | 419 } |
438 | 420 |
439 #if defined(OS_POSIX) | 421 #if defined(OS_POSIX) |
440 // Ubuntu-flavored Firefox3 supports locale-specific search engines via | 422 // Ubuntu-flavored Firefox3 supports locale-specific search engines via |
441 // locale-named subdirectories. They fall back to en-US. | 423 // locale-named subdirectories. They fall back to en-US. |
442 // See http://crbug.com/53899 | 424 // See http://crbug.com/53899 |
443 // TODO(jshin): we need to make sure our locale code matches that of | 425 // TODO(jshin): we need to make sure our locale code matches that of |
444 // Firefox. | 426 // Firefox. |
445 DCHECK(!locale_.empty()); | 427 DCHECK(!locale_.empty()); |
446 base::FilePath locale_app_path = app_path.AppendASCII(locale_); | 428 base::FilePath locale_app_path = app_path.AppendASCII(locale_); |
447 base::FilePath default_locale_app_path = app_path.AppendASCII("en-US"); | 429 base::FilePath default_locale_app_path = app_path.AppendASCII("en-US"); |
448 if (file_util::DirectoryExists(locale_app_path)) | 430 if (file_util::DirectoryExists(locale_app_path)) |
449 app_path = locale_app_path; | 431 app_path = locale_app_path; |
450 else if (file_util::DirectoryExists(default_locale_app_path)) | 432 else if (file_util::DirectoryExists(default_locale_app_path)) |
451 app_path = default_locale_app_path; | 433 app_path = default_locale_app_path; |
452 #endif | 434 #endif |
453 | 435 |
454 // Get search engine definition from file system. | 436 // Get search engine definition from file system. |
455 base::FileEnumerator engines(app_path, false, base::FileEnumerator::FILES); | 437 base::FileEnumerator engines(app_path, false, base::FileEnumerator::FILES); |
456 for (base::FilePath engine_path = engines.Next(); | 438 for (base::FilePath engine_path = engines.Next(); |
457 !engine_path.value().empty(); engine_path = engines.Next()) { | 439 !engine_path.value().empty(); engine_path = engines.Next()) { |
458 files->push_back(engine_path); | 440 std::string file_data; |
| 441 file_util::ReadFileToString(file, &file_data); |
| 442 search_engine_data->push_back(file_data); |
459 } | 443 } |
460 } | 444 } |
461 | 445 |
462 void Firefox3Importer::LoadRootNodeID(sql::Connection* db, | 446 void Firefox3Importer::LoadRootNodeID(sql::Connection* db, |
463 int* toolbar_folder_id, | 447 int* toolbar_folder_id, |
464 int* menu_folder_id, | 448 int* menu_folder_id, |
465 int* unsorted_folder_id) { | 449 int* unsorted_folder_id) { |
466 static const char* kToolbarFolderName = "toolbar"; | 450 static const char* kToolbarFolderName = "toolbar"; |
467 static const char* kMenuFolderName = "menu"; | 451 static const char* kMenuFolderName = "menu"; |
468 static const char* kUnsortedFolderName = "unfiled"; | 452 static const char* kUnsortedFolderName = "unfiled"; |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 | 578 |
595 if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) | 579 if (!FaviconUtil::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) |
596 continue; // Unable to decode. | 580 continue; // Unable to decode. |
597 | 581 |
598 usage.urls = i->second; | 582 usage.urls = i->second; |
599 favicons->push_back(usage); | 583 favicons->push_back(usage); |
600 } | 584 } |
601 s.Reset(true); | 585 s.Reset(true); |
602 } | 586 } |
603 } | 587 } |
OLD | NEW |