Skip to content

Commit

Permalink
Import from Chrome (#49)
Browse files Browse the repository at this point in the history
Import bookmark & history from chrome/chrome canary/chromium
  • Loading branch information
garrettr authored and darkdh committed Mar 15, 2018
1 parent ab55e64 commit 5f00709
Show file tree
Hide file tree
Showing 21 changed files with 958 additions and 1 deletion.
21 changes: 21 additions & 0 deletions common/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,36 @@ source_set("common") {
"brave_paths.h",
"common_message_generator.cc",
"common_message_generator.h",
"importer/chrome_importer_utils.cc",
"importer/chrome_importer_utils.h",
"pref_names.cc",
"pref_names.h",
"resource_bundle_helper.cc",
"resource_bundle_helper.h",
"webui_url_constants.cc",
"webui_url_constants.h",
]

deps = [
"extensions/api",
"//brave/chromium_src:common",
]

if (is_mac) {
sources += [
"importer/chrome_importer_utils_mac.mm",
]
}

if (is_linux) {
sources += [
"importer/chrome_importer_utils_linux.cc",
]
}

if (is_win) {
sources += [
"importer/chrome_importer_utils_win.cc",
]
}
}
73 changes: 73 additions & 0 deletions common/importer/chrome_importer_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/common/importer/chrome_importer_utils.h"

#include <memory>
#include <string>

#include "base/files/file_util.h"
#include "base/json/json_reader.h"
#include "base/values.h"
#include "chrome/common/importer/importer_data_types.h"

base::ListValue* GetChromeSourceProfiles(
const base::FilePath& user_data_folder) {
base::ListValue* profiles = new base::ListValue();
base::FilePath local_state_path =
user_data_folder.Append(
base::FilePath::StringType(FILE_PATH_LITERAL("Local State")));
if (!base::PathExists(local_state_path)) {
base::DictionaryValue* entry = new base::DictionaryValue();
entry->SetString("id", "Default");
entry->SetString("name", "Default");
profiles->Append(std::unique_ptr<base::DictionaryValue>(entry));
} else {
std::string local_state_content;
base::ReadFileToString(local_state_path, &local_state_content);
std::unique_ptr<base::Value> local_state =
base::JSONReader::Read(local_state_content);
const base::DictionaryValue* local_state_dict;
const base::DictionaryValue* profile_dict;
const base::DictionaryValue* info_cache;
if (!local_state || !local_state->GetAsDictionary(&local_state_dict))
return profiles;

if (local_state_dict->GetDictionary("profile", &profile_dict)) {
if (profile_dict->GetDictionary("info_cache", &info_cache)) {
for (base::DictionaryValue::Iterator it(*info_cache);
!it.IsAtEnd(); it.Advance()) {
const base::DictionaryValue* profile;
if (!it.value().GetAsDictionary(&profile))
continue;
std::string name;
profile->GetString("name", &name);
base::DictionaryValue* entry = new base::DictionaryValue();
entry->SetString("id", it.key());
entry->SetString("name", name);
profiles->Append(std::unique_ptr<base::DictionaryValue>(entry));
}
}
}
}
return profiles;
}

bool ChromeImporterCanImport(const base::FilePath& profile,
uint16_t* services_supported) {
DCHECK(services_supported);
*services_supported = importer::NONE;

base::FilePath bookmarks =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("Bookmarks")));
base::FilePath history =
profile.Append(base::FilePath::StringType(FILE_PATH_LITERAL("History")));

if (base::PathExists(bookmarks))
*services_supported |= importer::FAVORITES;
if (base::PathExists(history))
*services_supported |= importer::HISTORY;

return *services_supported != importer::NONE;
}
30 changes: 30 additions & 0 deletions common/importer/chrome_importer_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_COMMON_IMPORTER_CHROME_IMPORTER_UTILS_H_
#define BRAVE_COMMON_IMPORTER_CHROME_IMPORTER_UTILS_H_

#include <stdint.h>

#include <vector>

namespace base {
class DictionaryValue;
class FilePath;
class ListValue;
}

base::FilePath GetChromeUserDataFolder();
#if !defined(OS_LINUX)
base::FilePath GetCanaryUserDataFolder();
#endif
base::FilePath GetChromiumUserDataFolder();

base::ListValue* GetChromeSourceProfiles(
const base::FilePath& user_data_folder);

bool ChromeImporterCanImport(const base::FilePath& profile,
uint16_t* services_supported);

#endif // BRAVE_COMMON_IMPORTER_CHROME_IMPORTER_UTILS_H_
32 changes: 32 additions & 0 deletions common/importer/chrome_importer_utils_linux.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/common/importer/chrome_importer_utils.h"

#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/path_service.h"

base::FilePath GetChromeUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_HOME, &result))
return base::FilePath();

result = result.Append(".config");
result = result.Append("google-chrome");

return result;
}

base::FilePath GetChromiumUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_HOME, &result))
return base::FilePath();

result = result.Append(".config");
result = result.Append("chromium");

return result;
}
26 changes: 26 additions & 0 deletions common/importer/chrome_importer_utils_mac.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include <Cocoa/Cocoa.h>
#include <sys/param.h>

#include "brave/common/importer/chrome_importer_utils.h"

#include "base/files/file_util.h"
#include "base/mac/foundation_util.h"

base::FilePath GetChromeUserDataFolder() {
base::FilePath result = base::mac::GetUserLibraryPath();
return result.Append("Application Support/Google/Chrome");
}

base::FilePath GetCanaryUserDataFolder() {
base::FilePath result = base::mac::GetUserLibraryPath();
return result.Append("Application Support/Google/Chrome Canary");
}

base::FilePath GetChromiumUserDataFolder() {
base::FilePath result = base::mac::GetUserLibraryPath();
return result.Append("Application Support/Chromium");
}
44 changes: 44 additions & 0 deletions common/importer/chrome_importer_utils_win.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "brave/common/importer/chrome_importer_utils.h"

#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string16.h"

base::FilePath GetChromeUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &result))
return base::FilePath();

result = result.AppendASCII("Google");
result = result.AppendASCII("Chrome");
result = result.AppendASCII("User Data");

return result;
}

base::FilePath GetCanaryUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &result))
return base::FilePath();

result = result.AppendASCII("Google");
result = result.AppendASCII("Chrome SxS");
result = result.AppendASCII("User Data");

return result;
}

base::FilePath GetChromiumUserDataFolder() {
base::FilePath result;
if (!PathService::Get(base::DIR_LOCAL_APP_DATA, &result))
return base::FilePath();

result = result.AppendASCII("Chromium");
result = result.AppendASCII("User Data");

return result;
}
111 changes: 111 additions & 0 deletions patches/chrome-browser-importer-importer_list.cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc
index 3bf47fa746e2a417f89201f3e3800d8639f2e323..122e9daf552834db4d41c77a320332305320696b 100644
--- a/chrome/browser/importer/importer_list.cc
+++ b/chrome/browser/importer/importer_list.cc
@@ -7,9 +7,12 @@
#include <stdint.h>

#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/task_scheduler/task_traits.h"
#include "base/threading/thread_restrictions.h"
+#include "base/values.h"
+#include "brave/common/importer/chrome_importer_utils.h"
#include "build/build_config.h"
#include "chrome/browser/shell_integration.h"
#include "chrome/common/importer/firefox_importer_utils.h"
@@ -124,6 +127,61 @@ void DetectFirefoxProfiles(const std::string locale,
profiles->push_back(firefox);
}

+void AddChromeToProfiles(std::vector<importer::SourceProfile>* profiles,
+ base::ListValue* chrome_profiles,
+ base::FilePath& user_data_folder,
+ std::string& brand) {
+ for (const auto& value : *chrome_profiles) {
+ const base::DictionaryValue* dict;
+ if (!value.GetAsDictionary(&dict))
+ continue;
+ uint16_t items = importer::NONE;
+ std::string profile;
+ std::string name;
+ dict->GetString("id", &profile);
+ dict->GetString("name", &name);
+ if (!ChromeImporterCanImport(user_data_folder.Append(
+ base::FilePath::StringType(profile.begin(), profile.end())), &items))
+ continue;
+ importer::SourceProfile chrome;
+ std::string importer_name(brand);
+ importer_name.append(name);
+ chrome.importer_name = base::UTF8ToUTF16(importer_name);
+ chrome.importer_type = importer::TYPE_CHROME;
+ chrome.services_supported = items;
+ chrome.source_path =
+ user_data_folder.Append(
+ base::FilePath::StringType(profile.begin(), profile.end()));
+ profiles->push_back(chrome);
+ }
+ delete chrome_profiles;
+}
+
+void DetectChromeProfiles(std::vector<importer::SourceProfile>* profiles) {
+ base::AssertBlockingAllowed();
+
+ base::FilePath chrome_user_data_folder = GetChromeUserDataFolder();
+ base::ListValue* chrome_profiles = GetChromeSourceProfiles(chrome_user_data_folder);
+ std::string brand_chrome("Chrome ");
+ AddChromeToProfiles(profiles, chrome_profiles, chrome_user_data_folder, brand_chrome);
+
+#if !defined(OS_LINUX)
+ base::FilePath canary_user_data_folder = GetCanaryUserDataFolder();
+ base::ListValue* canary_profiles =
+ GetChromeSourceProfiles(canary_user_data_folder);
+ std::string brandCanary("Chrome Canary ");
+ AddChromeToProfiles(profiles, canary_profiles, canary_user_data_folder,
+ brandCanary);
+#endif
+
+ base::FilePath chromium_user_data_folder = GetChromiumUserDataFolder();
+ base::ListValue* chromium_profiles =
+ GetChromeSourceProfiles(chromium_user_data_folder);
+ std::string brandChromium("Chromium ");
+ AddChromeToProfiles(profiles, chromium_profiles, chromium_user_data_folder,
+ brandChromium);
+}
+
std::vector<importer::SourceProfile> DetectSourceProfilesWorker(
const std::string& locale,
bool include_interactive_profiles) {
@@ -137,20 +195,30 @@ std::vector<importer::SourceProfile> DetectSourceProfilesWorker(
if (shell_integration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(locale, &profiles);
DetectBuiltinWindowsProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
} else {
DetectBuiltinWindowsProfiles(&profiles);
DetectFirefoxProfiles(locale, &profiles);
+ DetectChromeProfiles(&profiles);
}
#elif defined(OS_MACOSX)
if (shell_integration::IsFirefoxDefaultBrowser()) {
DetectFirefoxProfiles(locale, &profiles);
DetectSafariProfiles(&profiles);
+ DetectChromeProfiles(&profiles);
} else {
DetectSafariProfiles(&profiles);
DetectFirefoxProfiles(locale, &profiles);
+ DetectChromeProfiles(&profiles);
}
#else
- DetectFirefoxProfiles(locale, &profiles);
+ if (shell_integration::IsFirefoxDefaultBrowser()) {
+ DetectFirefoxProfiles(locale, &profiles);
+ DetectChromeProfiles(&profiles);
+ } else {
+ DetectChromeProfiles(&profiles);
+ DetectFirefoxProfiles(locale, &profiles);
+ }
#endif
if (include_interactive_profiles) {
importer::SourceProfile bookmarks_profile;
14 changes: 14 additions & 0 deletions patches/chrome-browser-importer-importer_uma.cc.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
diff --git a/chrome/browser/importer/importer_uma.cc b/chrome/browser/importer/importer_uma.cc
index da87e84ffe7c2193ea16d24f1ee1174c51c9503f..261dd432b1759b4e62c5ee2b2b0a6e27a688700d 100644
--- a/chrome/browser/importer/importer_uma.cc
+++ b/chrome/browser/importer/importer_uma.cc
@@ -59,6 +59,9 @@ void LogImporterUseToMetrics(const std::string& metric_postfix,
case TYPE_BOOKMARKS_FILE:
metrics_type = IMPORTER_METRICS_BOOKMARKS_FILE;
break;
+ case TYPE_CHROME:
+ // TODO: Wire this up if we want to record metrics on users who import from Chrome
+ break;
}

// Note: This leaks memory, which is the expected behavior as the factory
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
diff --git a/chrome/browser/importer/in_process_importer_bridge.cc b/chrome/browser/importer/in_process_importer_bridge.cc
index f62c224196bd13af6ed1fb36dccd1eccf15ee4df..8b4a6a94538b17b1177a5f1212205ef9f9843265 100644
--- a/chrome/browser/importer/in_process_importer_bridge.cc
+++ b/chrome/browser/importer/in_process_importer_bridge.cc
@@ -60,6 +60,8 @@ history::VisitSource ConvertImporterVisitSourceToHistoryVisitSource(
return history::SOURCE_IE_IMPORTED;
case importer::VISIT_SOURCE_SAFARI_IMPORTED:
return history::SOURCE_SAFARI_IMPORTED;
+ case importer::VISIT_SOURCE_CHROME_IMPORTED:
+ return history::SOURCE_CHROME_IMPORTED;
}
NOTREACHED();
return history::SOURCE_SYNCED;
Loading

0 comments on commit 5f00709

Please sign in to comment.