1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "chrome/utility/importer/firefox_importer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 129ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/importer/firefox_importer_utils.h" 177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/importer/firefox_importer_utils.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_bookmark_entry.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/imported_favicon_usage.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/importer/importer_bridge.h" 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/importer/importer_url_row.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/bookmark_html_reader.h" 237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/favicon_reencode.h" 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/utility/importer/nss_decryptor.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/password_form.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/connection.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h" 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Original definition is in http://mxr.mozilla.org/firefox/source/toolkit/ 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// components/places/public/nsINavBookmarksService.idl 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum BookmarkItemType { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TYPE_BOOKMARK = 1, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TYPE_FOLDER = 2, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TYPE_SEPARATOR = 3, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TYPE_DYNAMIC_CONTAINER = 4 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// Loads the default bookmarks in the Firefox installed at |app_path|, 43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// and stores their locations in |urls|. 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void LoadDefaultBookmarks(const base::FilePath& app_path, 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::set<GURL>* urls) { 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::FilePath file = app_path.AppendASCII("defaults") 47a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) .AppendASCII("profile") 48a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) .AppendASCII("bookmarks.html"); 49a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) urls->clear(); 50a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::vector<ImportedBookmarkEntry> bookmarks; 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) bookmark_html_reader::ImportBookmarksFile(base::Callback<bool(void)>(), 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::Callback<bool(const GURL&)>(), 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) file, 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) &bookmarks, 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) NULL); 57a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) for (size_t i = 0; i < bookmarks.size(); ++i) 58a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) urls->insert(bookmarks[i].url); 59a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 60a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Returns true if |url| has a valid scheme that we allow to import. We 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// filter out the URL with a unsupported scheme. 63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool CanImportURL(const GURL& url) { 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // The URL is not valid. 65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!url.is_valid()) 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // Filter out the URLs with unsupported schemes. 69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const char* const kInvalidSchemes[] = {"wyciwyg", "place", "about", "chrome"}; 70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) { 71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (url.SchemeIs(kInvalidSchemes[i])) 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstruct FirefoxImporter::BookmarkItem { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int parent; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 title; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItemType type; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string keyword; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time date_added; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 favicon; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool empty_folder; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFirefoxImporter::FirefoxImporter() { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochFirefoxImporter::~FirefoxImporter() { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::StartImport( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const importer::SourceProfile& source_profile, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 items, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImporterBridge* bridge) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_ = bridge; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_path_ = source_profile.source_path; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_path_ = source_profile.app_path; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_POSIX) 107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch locale_ = source_profile.locale; 108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The order here is important! 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyStarted(); 1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if ((items & importer::HOME_PAGE) && !cancelled()) { 1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bridge_->NotifyItemStarted(importer::HOME_PAGE); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportHomepage(); // Doesn't have a UI item. 1157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bridge_->NotifyItemEnded(importer::HOME_PAGE); 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note history should be imported before bookmarks because bookmark import 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will also import favicons and we store favicon for a URL only if the URL 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exist in history or bookmarks. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((items & importer::HISTORY) && !cancelled()) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemStarted(importer::HISTORY); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportHistory(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemEnded(importer::HISTORY); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((items & importer::FAVORITES) && !cancelled()) { 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemStarted(importer::FAVORITES); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportBookmarks(); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemEnded(importer::FAVORITES); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((items & importer::SEARCH_ENGINES) && !cancelled()) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemStarted(importer::SEARCH_ENGINES); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportSearchEngines(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemEnded(importer::SEARCH_ENGINES); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((items & importer::PASSWORDS) && !cancelled()) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemStarted(importer::PASSWORDS); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ImportPasswords(); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyItemEnded(importer::PASSWORDS); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->NotifyEnded(); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::ImportHistory() { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file = source_path_.AppendASCII("places.sqlite"); 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(file)) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Connection db; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db.Open(file)) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |visit_type| represent the transition type of URLs (typed, click, 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirect, bookmark, etc.) We eliminate some URLs like sub-frames and 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // redirects, since we don't want them to appear in history. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox transition types are defined in: 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // toolkit/components/places/public/nsINavHistoryService.idl 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT h.url, h.title, h.visit_count, " 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "h.hidden, h.typed, v.visit_date " 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FROM moz_places h JOIN moz_historyvisits v " 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ON h.id = v.place_id " 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE v.visit_type <= 3"; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db.GetUniqueStatement(query)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<ImporterURLRow> rows; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step() && !cancelled()) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL url(s.ColumnString(0)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Filter out unwanted URLs. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CanImportURL(url)) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ImporterURLRow row(url); 176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch row.title = s.ColumnString16(1); 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch row.visit_count = s.ColumnInt(2); 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch row.hidden = s.ColumnInt(3) == 1; 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch row.typed_count = s.ColumnInt(4); 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch row.last_visit = base::Time::FromTimeT(s.ColumnInt64(5)/1000000); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rows.push_back(row); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!rows.empty() && !cancelled()) 1867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bridge_->SetHistoryItems(rows, importer::VISIT_SOURCE_FIREFOX_IMPORTED); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 189ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::ImportBookmarks() { 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file = source_path_.AppendASCII("places.sqlite"); 1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(file)) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Connection db; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db.Open(file)) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the bookmark folders that we are interested in. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int toolbar_folder_id = -1; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int menu_folder_id = -1; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int unsorted_folder_id = -1; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadRootNodeID(&db, &toolbar_folder_id, &menu_folder_id, &unsorted_folder_id); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load livemark IDs. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int> livemark_id; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadLivemarkIDs(&db, &livemark_id); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // Load the default bookmarks. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<GURL> default_urls; 210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) LoadDefaultBookmarks(app_path_, &default_urls); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkList list; 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTopBookmarkFolder(&db, toolbar_folder_id, &list); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTopBookmarkFolder(&db, menu_folder_id, &list); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetTopBookmarkFolder(&db, unsorted_folder_id, &list); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = list.size(); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < count; ++i) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWholeBookmarkFolder(&db, &list, i, NULL); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 220a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::vector<ImportedBookmarkEntry> bookmarks; 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<importer::URLKeywordInfo> url_keywords; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconMap favicon_map; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jcampan): http://b/issue?id=1196285 we do not support POST based 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // keywords yet. We won't include them in the list. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int> post_keyword_ids; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT b.id FROM moz_bookmarks b " 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INNER JOIN moz_items_annos ia ON ia.item_id = b.id " 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INNER JOIN moz_anno_attributes aa ON ia.anno_attribute_id = aa.id " 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE aa.name = 'bookmarkProperties/POSTData'"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db.GetUniqueStatement(query)); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!s.is_valid()) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step() && !cancelled()) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_keyword_ids.insert(s.ColumnInt(0)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < list.size(); ++i) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItem* item = list[i]; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item->type == TYPE_FOLDER) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Folders are added implicitly on adding children, so we only explicitly 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // add empty folders. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!item->empty_folder) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (item->type == TYPE_BOOKMARK) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Import only valid bookmarks 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CanImportURL(item->url)) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skip the default bookmarks and unwanted URLs. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (default_urls.find(item->url) != default_urls.end() || 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) post_keyword_ids.find(item->id) != post_keyword_ids.end()) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find the bookmark path by tracing their links to parent folders. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<string16> path; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItem* child = item; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool found_path = false; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_in_toolbar = false; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (child->parent >= 0) { 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItem* parent = list[child->parent]; 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (livemark_id.find(parent->id) != livemark_id.end()) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't import live bookmarks. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent->id != menu_folder_id) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // To avoid excessive nesting, omit the name for the bookmarks menu 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // folder. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path.insert(path.begin(), parent->title); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent->id == toolbar_folder_id) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_in_toolbar = true; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent->id == toolbar_folder_id || 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent->id == menu_folder_id || 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent->id == unsorted_folder_id) { 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've reached a root node, hooray! 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) found_path = true; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) child = parent; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!found_path) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ImportedBookmarkEntry entry; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.creation_time = item->date_added; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.title = item->title; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.url = item->url; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.path = path; 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.in_toolbar = is_in_toolbar; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) entry.is_folder = item->type == TYPE_FOLDER; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bookmarks.push_back(entry); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item->type == TYPE_BOOKMARK) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item->favicon) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicon_map[item->favicon].insert(item->url); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // This bookmark has a keyword, we should import it. 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!item->keyword.empty() && item->url.is_valid()) { 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch importer::URLKeywordInfo url_keyword_info; 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_keyword_info.url = item->url; 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_keyword_info.keyword.assign(UTF8ToUTF16(item->keyword)); 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_keyword_info.display_name = item->title; 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch url_keywords.push_back(url_keyword_info); 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteElements(&list); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write into profile. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!bookmarks.empty() && !cancelled()) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const string16& first_folder_name = 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->GetLocalizedString(IDS_BOOKMARK_GROUP_FROM_FIREFOX); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->AddBookmarks(bookmarks, first_folder_name); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!url_keywords.empty() && !cancelled()) { 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bridge_->SetKeywords(url_keywords, false); 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!favicon_map.empty() && !cancelled()) { 332a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::vector<ImportedFaviconUsage> favicons; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LoadFavicons(&db, favicon_map, &favicons); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->SetFavicons(favicons); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 338ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::ImportPasswords() { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initializes NSS3. 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSSDecryptor decryptor; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!decryptor.Init(source_path_, source_path_) && 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !decryptor.Init(app_path_, source_path_)) { 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<content::PasswordForm> forms; 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath source_path = source_path_; 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file = source_path.AppendASCII("signons.sqlite"); 3497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::PathExists(file)) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Since Firefox 3.1, passwords are in signons.sqlite db. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decryptor.ReadAndParseSignons(file, &forms); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox 3.0 uses signons3.txt to store the passwords. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = source_path.AppendASCII("signons3.txt"); 3557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(file)) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = source_path.AppendASCII("signons2.txt"); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string content; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_util::ReadFileToString(file, &content); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) decryptor.ParseSignons(content, &forms); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!cancelled()) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < forms.size(); ++i) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->SetPasswordForm(forms[i]); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 370ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::ImportSearchEngines() { 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<std::string> search_engine_data; 372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GetSearchEnginesXMLData(&search_engine_data); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 377ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::ImportHomepage() { 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GURL home_page = GetHomepage(source_path_); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (home_page.is_valid() && !IsDefaultHomepage(home_page, app_path_)) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bridge_->AddHomePage(home_page); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 384ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::GetSearchEnginesXMLData( 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<std::string>* search_engine_data) { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file = source_path_.AppendASCII("search.sqlite"); 3877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::PathExists(file)) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Connection db; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db.Open(file)) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT engineid FROM engine_data " 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE engineid NOT IN " 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(SELECT engineid FROM engine_data " 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE name='hidden') " 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ORDER BY value ASC"; 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db.GetUniqueStatement(query)); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!s.is_valid()) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath app_path = app_path_.AppendASCII("searchplugins"); 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath profile_path = source_path_.AppendASCII("searchplugins"); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox doesn't store a search engine in its sqlite database unless the 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user has added a engine. So we get search engines from sqlite db as well 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // as from the file system. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s.Step()) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kAppPrefix("[app]/"); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string kProfilePrefix("[profile]/"); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string engine(s.ColumnString(0)); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The string contains [app]/<name>.xml or [profile]/<name>.xml where 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the [app] and [profile] need to be replaced with the actual app or 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // profile path. 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t index = engine.find(kAppPrefix); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (index != std::string::npos) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove '[app]/'. 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = app_path.AppendASCII(engine.substr(index + kAppPrefix.length())); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((index = engine.find(kProfilePrefix)) != std::string::npos) { 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remove '[profile]/'. 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file = profile_path.AppendASCII( 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) engine.substr(index + kProfilePrefix.length())); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Looks like absolute path to the file. 430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) file = base::FilePath::FromUTF8Unsafe(engine); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string file_data; 433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_util::ReadFileToString(file, &file_data); 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch search_engine_data->push_back(file_data); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (s.Step() && !cancelled()); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_POSIX) 439ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Ubuntu-flavored Firefox supports locale-specific search engines via 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // locale-named subdirectories. They fall back to en-US. 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See http://crbug.com/53899 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jshin): we need to make sure our locale code matches that of 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Firefox. 444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(!locale_.empty()); 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath locale_app_path = app_path.AppendASCII(locale_); 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath default_locale_app_path = app_path.AppendASCII("en-US"); 4477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (base::DirectoryExists(locale_app_path)) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_path = locale_app_path; 4497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch else if (base::DirectoryExists(default_locale_app_path)) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) app_path = default_locale_app_path; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get search engine definition from file system. 454868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator engines(app_path, false, base::FileEnumerator::FILES); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (base::FilePath engine_path = engines.Next(); 4562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !engine_path.value().empty(); engine_path = engines.Next()) { 457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string file_data; 458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_util::ReadFileToString(file, &file_data); 459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch search_engine_data->push_back(file_data); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 463ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::LoadRootNodeID(sql::Connection* db, 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* toolbar_folder_id, 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* menu_folder_id, 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* unsorted_folder_id) { 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kToolbarFolderName = "toolbar"; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kMenuFolderName = "menu"; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kUnsortedFolderName = "unfiled"; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT root_name, folder_id FROM moz_bookmarks_roots"; 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db->GetUniqueStatement(query)); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step()) { 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string folder = s.ColumnString(0); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int id = s.ColumnInt(1); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (folder == kToolbarFolderName) 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *toolbar_folder_id = id; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (folder == kMenuFolderName) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *menu_folder_id = id; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (folder == kUnsortedFolderName) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *unsorted_folder_id = id; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 486ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::LoadLivemarkIDs(sql::Connection* db, 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<int>* livemark) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* kFeedAnnotation = "livemark/feedURI"; 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) livemark->clear(); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT b.item_id " 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FROM moz_anno_attributes a " 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "JOIN moz_items_annos b ON a.id = b.anno_attribute_id " 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE a.name = ? "; 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db->GetUniqueStatement(query)); 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindString(0, kFeedAnnotation); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step() && !cancelled()) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) livemark->insert(s.ColumnInt(0)); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 502ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::GetTopBookmarkFolder(sql::Connection* db, 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int folder_id, 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkList* list) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT b.title " 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FROM moz_bookmarks b " 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE b.type = 2 AND b.id = ? " 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ORDER BY b.position"; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db->GetUniqueStatement(query)); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(0, folder_id); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s.Step()) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItem* item = new BookmarkItem; 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->parent = -1; // The top level folder has no parent. 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->id = folder_id; 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->title = s.ColumnString16(0); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->type = TYPE_FOLDER; 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->favicon = 0; 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->empty_folder = true; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->push_back(item); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 524ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::GetWholeBookmarkFolder(sql::Connection* db, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkList* list, 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t position, 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* empty_folder) { 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (position >= list->size()) { 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT b.id, h.url, COALESCE(b.title, h.title), " 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "b.type, k.keyword, b.dateAdded, h.favicon_id " 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "FROM moz_bookmarks b " 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "LEFT JOIN moz_places h ON b.fk = h.id " 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "LEFT JOIN moz_keywords k ON k.id = b.keyword_id " 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE b.type IN (1,2) AND b.parent = ? " 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ORDER BY b.position"; 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db->GetUniqueStatement(query)); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt(0, (*list)[position]->id); 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkList temp_list; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (s.Step()) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkItem* item = new BookmarkItem; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->parent = static_cast<int>(position); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->id = s.ColumnInt(0); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->url = GURL(s.ColumnString(1)); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->title = s.ColumnString16(2); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->type = static_cast<BookmarkItemType>(s.ColumnInt(3)); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->keyword = s.ColumnString(4); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->date_added = base::Time::FromTimeT(s.ColumnInt64(5)/1000000); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->favicon = s.ColumnInt64(6); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item->empty_folder = true; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) temp_list.push_back(item); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (empty_folder != NULL) 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *empty_folder = false; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Appends all items to the list. 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (BookmarkList::iterator i = temp_list.begin(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != temp_list.end(); ++i) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->push_back(*i); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recursive add bookmarks in sub-folders. 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*i)->type == TYPE_FOLDER) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetWholeBookmarkFolder(db, list, list->size() - 1, &(*i)->empty_folder); 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid FirefoxImporter::LoadFavicons( 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Connection* db, 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FaviconMap& favicon_map, 574a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) std::vector<ImportedFaviconUsage>* favicons) { 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* query = "SELECT url, data FROM moz_favicons WHERE id=?"; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement s(db->GetUniqueStatement(query)); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!s.is_valid()) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (FaviconMap::const_iterator i = favicon_map.begin(); 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != favicon_map.end(); ++i) { 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.BindInt64(0, i->first); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (s.Step()) { 585a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ImportedFaviconUsage usage; 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usage.favicon_url = GURL(s.ColumnString(0)); 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!usage.favicon_url.is_valid()) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Don't bother importing favicons with invalid URLs. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<unsigned char> data; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.ColumnBlobAsVector(1, &data); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (data.empty()) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Data definitely invalid. 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!importer::ReencodeFavicon(&data[0], data.size(), &usage.png_data)) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; // Unable to decode. 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) usage.urls = i->second; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) favicons->push_back(usage); 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) s.Reset(true); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605