From 5ed1ed2d342e6c834d26e1c2280d5cf7644157c7 Mon Sep 17 00:00:00 2001 From: Anthony Tseng Date: Tue, 18 Oct 2016 23:05:29 -0400 Subject: [PATCH] Add favicon for chrome bookmarks import fix https://github.com/brave/browser-laptop/issues/4882 Auditors: @bridiver, @bbondy --- atom/utility/importer/chrome_importer.cc | 74 ++++++++++++++++++++++++ atom/utility/importer/chrome_importer.h | 22 +++++++ 2 files changed, 96 insertions(+) diff --git a/atom/utility/importer/chrome_importer.cc b/atom/utility/importer/chrome_importer.cc index dbcf6d7f81..e84bfd1b6c 100644 --- a/atom/utility/importer/chrome_importer.cc +++ b/atom/utility/importer/chrome_importer.cc @@ -16,6 +16,7 @@ #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/common/importer/importer_bridge.h" #include "chrome/common/importer/importer_url_row.h" +#include "chrome/utility/importer/favicon_reencode.h" #include "sql/connection.h" #include "sql/statement.h" #include "url/gurl.h" @@ -132,6 +133,79 @@ void ChromeImporter::ImportBookmarks() { base::UTF8ToUTF16("Imported from Chrome"); bridge_->AddBookmarks(bookmarks, first_folder_name); } + + // Import favicons. + base::FilePath favicons_path = + source_path_.Append( + base::FilePath::StringType(FILE_PATH_LITERAL("Favicons"))); + if (!base::PathExists(favicons_path)) + return; + + sql::Connection db; + if (!db.Open(favicons_path)) + return; + + FaviconMap favicon_map; + ImportFaviconURLs(&db, &favicon_map); + // Write favicons into profile. + if (!favicon_map.empty() && !cancelled()) { + favicon_base::FaviconUsageDataList favicons; + LoadFaviconData(&db, favicon_map, &favicons); + bridge_->SetFavicons(favicons); + } +} + +void ChromeImporter::ImportFaviconURLs( + sql::Connection* db, + FaviconMap* favicon_map) { + const char query[] = "SELECT icon_id, page_url FROM icon_mapping;"; + sql::Statement s(db->GetUniqueStatement(query)); + + while (s.Step() && !cancelled()) { + int64_t icon_id = s.ColumnInt64(0); + GURL url = GURL(s.ColumnString(1)); + (*favicon_map)[icon_id].insert(url); + } +} + +void ChromeImporter::LoadFaviconData( + sql::Connection* db, + const FaviconMap& favicon_map, + favicon_base::FaviconUsageDataList* favicons) { + const char query[] = "SELECT url " + "FROM favicons " + "WHERE id = ?;"; + sql::Statement s(db->GetUniqueStatement(query)); + + for (FaviconMap::const_iterator i = favicon_map.begin(); + i != favicon_map.end(); ++i) { + s.Reset(true); + s.BindInt64(0, i->first); + if (s.Step()) { + favicon_base::FaviconUsageData usage; + + GURL url = GURL(s.ColumnString(0)); + if (url.is_valid()) { + if (url.SchemeIs(url::kDataScheme)) { + std::vector data; + s.ColumnBlobAsVector(0, &data); + if (data.empty()) { + continue; // Data definitely invalid. + } + if (!importer::ReencodeFavicon(&data[0], data.size(), + &usage.png_data)) + continue; // Unable to decode. + } else { + usage.favicon_url = url; + } + } else { + continue; // Don't bother importing favicons with invalid URLs. + } + + usage.urls = i->second; + favicons->push_back(usage); + } + } } void ChromeImporter::ImportCookies() { diff --git a/atom/utility/importer/chrome_importer.h b/atom/utility/importer/chrome_importer.h index be96680b78..9705f9e3bc 100644 --- a/atom/utility/importer/chrome_importer.h +++ b/atom/utility/importer/chrome_importer.h @@ -7,6 +7,8 @@ #include +#include +#include #include #include "base/compiler_specific.h" @@ -14,6 +16,7 @@ #include "base/macros.h" #include "build/build_config.h" #include "chrome/utility/importer/importer.h" +#include "components/favicon_base/favicon_usage_data.h" struct ImportedBookmarkEntry; @@ -21,6 +24,10 @@ namespace base { class DictionaryValue; } +namespace sql { +class Connection; +} + class ChromeImporter : public Importer { public: ChromeImporter(); @@ -37,6 +44,21 @@ class ChromeImporter : public Importer { void ImportHistory(); void ImportCookies(); + // Multiple URLs can share the same favicon; this is a map + // of URLs -> IconIDs that we load as a temporary step before + // actually loading the icons. + typedef std::map> FaviconMap; + + // Loads the urls associated with the favicons into favicon_map; + void ImportFaviconURLs( + sql::Connection* db, + FaviconMap* favicon_map); + + // Loads and reencodes the individual favicons. + void LoadFaviconData(sql::Connection* db, + const FaviconMap& favicon_map, + favicon_base::FaviconUsageDataList* favicons); + void RecursiveReadBookmarksFolder( const base::DictionaryValue* folder, const std::vector& parent_path,