Compare commits

...
34 changed files with 1682 additions and 535 deletions
+11 -34
View File
@@ -1,6 +1,16 @@
# 68.0.3440.110
* add import action to Bookmarks activity page
* use different user-agent version based on Android OS version
# 68.0.3440.90
* reduce rects randomisation by factor of 100
* use a fixed user-agent (fixes https://github.com/bromite/bromite/issues/103)
# 68.0.3440.87
* add export action to Bookmarks activity page
# 68.0.3440.81
* fix issue with filters with an excluded domain option
* updated AdBlock filters
# 68.0.3440.72
* fix crash during some canvas rendering (fixes https://github.com/bromite/bromite/issues/95)
@@ -12,11 +22,9 @@
* disable ads metrics by default
* disable all field trials (fixes https://github.com/bromite/bromite/issues/83)
* re-introduced own battery API patch (fixes https://github.com/bromite/bromite/issues/80)
* updated AdBlock filters
# 67.0.3396.107
* removed patch to use Android Media Player for URLs (fixes https://github.com/bromite/bromite/issues/71)
* updated AdBlock filters
# 67.0.3396.101
* set home page to new tab page
@@ -33,7 +41,6 @@
* safe_browsing: disable cookie transmission
* extensions: always show component extensions in the ext list
* translate: disable fetching of translate languages from server
* updated AdBlock filters
# 67.0.3396.95
* reduce headers sent in DoH requests (fixes https://github.com/bromite/bromite/issues/70)
@@ -41,11 +48,9 @@
* `CloudFlare` -> `Cloudflare` (fixes https://github.com/bromite/bromite/issues/73)
* fingerprint mitigations: cover also `ConvertToArrayBufferContents`
* removed redundant own patch for battery API
* updated AdBlock filters
# 67.0.3396.92
* improve randomization for each retrieved Canvas data (fixes https://github.com/bromite/bromite/issues/69)
* updated AdBlock filters
# 67.0.3396.88
* add flag for DNS-over-HTTPS (Google experimental DNS) (fixes https://github.com/bromite/bromite/issues/68)
@@ -56,90 +61,70 @@
* use Android Media Player for URLs
* add exit menu item
* hide "send reports to Google" menu item
* updated AdBlock filters
# 67.0.3396.82
* updated AdBlock filters
# 67.0.3396.76
* updated AdBlock filters
# 67.0.3396.72
* add global toggle for adblock engine (https://github.com/bromite/bromite/issues/53)
* updated AdBlock filters
# 67.0.3396.67
* updated AdBlock filters
# 66.0.3359.202
* fix DevTools integration (https://github.com/bromite/bromite/issues/23)
* allow toggling of Javascript from New Tab Page (fixes https://github.com/bromite/bromite/issues/60)
* updated AdBlock filters
# 66.0.3359.200
* updated AdBlock filters
# 66.0.3359.196
* updated AdBlock filters
# 66.0.3359.188
* updated AdBlock filters
* increase max (persistent) connections per server from 6 to 15
* preliminary work for better canvas fingerprinting mitigations
# 66.0.3359.161
* updated AdBlock filters
# 66.0.3359.148
* disable permanently all custom tab intents (https://github.com/bromite/bromite/issues/17)
* updated AdBlock filters
* reduce randomization for client rects from 5% to 3%
# 65.0.3325.230
* fixed permission to access Google account issue (https://github.com/bromite/bromite/issues/11)
* updated AdBlock filters
# 65.0.3325.218
* always set WideVine version
* updated AdBlock filters
# 65.0.3325.204
* add menu option to toggle global Javascript preferences setting (https://github.com/bromite/bromite/issues/37)
* add fingeprinting mitigation for getClientRects, getBoundingClientRect
* set audio latency to fixed number
* updated AdBlock filters
# 65.0.3325.198
* re-landed support for third-party AdBlock filters
* completed patches cleanup
* updated AdBlock filters
# 65.0.3325.190
* block some Canvas and AudioBuffer APIs mostly used for fingerprinting (https://github.com/bromite/bromite/issues/15)
* updated AdBlock filters
# 65.0.3325.176
* block plugins enumeration API
* block battery API
* remove device name and build id from User Agent
* added Qwant search engine
* updated AdBlock filters
* disable non-working 3rd-party filters support
# 64.0.3282.204
* use H264 NEON optimizations also for arm64
* fix build of Stable channel
* updated AdBlock filters
* started building vanilla Chromium releases as well
# 64.0.3282.193
* updated AdBlock filters
* disable reporting
# 64.0.3282.182
* add support for domain-based adblock filters
* optimized memory allocation for filters
* updated AdBlock filters
# 64.0.3282.168
* extension: allow playing youtube/vimeo videos in background (https://github.com/bromite/bromite/issues/16)
@@ -156,20 +141,16 @@
* disabled plugin untraceable URLs (ungoogled-chromium)
# 64.0.3282.149
* updated AdBlock filters
# 63.0.3239.150
* fixed crash when clicking on address bar lock (page info) or opening site settings (https://github.com/bromite/bromite/issues/28)
* build H264 with NEON optimizations for ARMv7
* updated AdBlock filters
* more builds for arm64 architecture
# 63.0.3239.144
* fixed invalid AdBlock filter rule blocking all connections (https://github.com/bromite/bromite/issues/26)
* updated AdBlock filters
# 63.0.3239.129
* updated AdBlock filters
# 63.0.3239.122
* disable webRTC completely (https://github.com/bromite/bromite/issues/9)
@@ -182,23 +163,19 @@
* revert /deep/ and ::shadow feature drop to attempt fixing DevTools support (https://github.com/bromite/bromite/issues/23)
* remove also ads from search results
* add Google search engine with English-only results, no RLZ and field trials
* updated adBlock filters
* fix build of x86 version (was broken in previous version)
# 63.0.3239.85
* no suggest URL for DuckDuckGo (https://github.com/bromite/bromite/issues/19)
* fixed 4chan blocking rule
* limit AMP links cleanup to search results only (fixes broken images/news result tabs)
* updated adBlock filters
# 63.0.3239.78
* correctly set version and build numbers
* updated adBlock filters
# 63.0.3239.73
# 63.0.3239.64
* updated adblock filters
* fixed an issue with incognito new tab
* permanent disable for ToS/metrics and unused auto-updates check
+6 -2
View File
@@ -10,7 +10,7 @@ Bromite is only available for Android v4.1 and above.
See [open issues](https://github.com/bromite/bromite/issues) for the development in progress.
<img src="https://www.bromite.org/bromite_bromite_gh_downloads.svg" alt="downloads on Github" title="downloads on Github" /> <img src="https://www.bromite.org/bromite_bromite_xda_downloads.svg" alt="downloads on XDA Labs" title="downloads on XDA Labs" />
<img src="https://www.bromite.org/bromite_bromite_gh_downloads.svg" alt="downloads on Github" title="downloads on Github" />
# Goals
@@ -70,10 +70,12 @@ No, it is not built-in.
* remove click-tracking and AMP from search results
* DNS-over-HTTPS support via Google/CloudFlare servers
* [StartPage](https://startpage.com/), [DuckDuckGo](https://duckduckgo.com/) and [Qwant](https://www.qwant.com/) search engines
* chrome flag to hide NTP tiles and to disable custom intents
* privacy enhancement patches from [Iridium](https://iridiumbrowser.de/), [Inox patchset](https://github.com/gcarq/inox-patchset), [Brave](https://brave.com/) and [ungoogled-chromium](https://github.com/Eloston/ungoogled-chromium) projects
* webRTC, canvas, audio and other anti-fingerprinting mitigations
## Features not related to privacy
* import/export bookmarks
* allow playing videos in background
* all codecs included (proprietary, open H.264 etc.)
* built with official speed optimizations
@@ -87,7 +89,9 @@ All built versions are available as [releases](https://github.com/bromite/bromit
Each tag corresponds to a Chromium Stable release tag.
Bromite is currently built for ARM, ARM64 and x86 and for the Android SDKs versions 16 and 21
Additionally, [SystemWebView](https://www.bromite.org/system_web_view), Monochrome and the [vanilla Chromium](https://www.bromite.org/chromium) builds are provided.
Additionally, [SystemWebView](https://www.bromite.org/system_web_view) and the [vanilla Chromium](https://www.bromite.org/chromium) builds are provided.
The official releases are also available through the [official third-party F-Droid repository](https://www.bromite.org/fdroid).
## Integrity and authenticity
+677 -407
View File
File diff suppressed because it is too large Load Diff
@@ -3,9 +3,11 @@ Date: Sat, 28 Oct 2017 10:09:41 +0200
Subject: Cure AMP and tracking from search results
---
third_party/blink/renderer/core/dom/BUILD.gn | 1 +
third_party/blink/renderer/core/dom/document.cc | 20 +++++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
third_party/blink/renderer/core/dom/BUILD.gn | 1 +
third_party/blink/renderer/core/dom/document.cc | 20 +++++++++++++++++++-
.../renderer/core/dom/extensions/anti_amp_cure.h | 6 ++++++
3 files changed, 26 insertions(+), 1 deletion(-)
create mode 100644 third_party/blink/renderer/core/dom/extensions/anti_amp_cure.h
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn
--- a/third_party/blink/renderer/core/dom/BUILD.gn
@@ -56,6 +58,17 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
FirstMeaningfulPaintDetector::From(*this).CheckNetworkStable();
}
diff --git a/third_party/blink/renderer/core/dom/extensions/anti_amp_cure.h b/third_party/blink/renderer/core/dom/extensions/anti_amp_cure.h
new file mode 100644
--- /dev/null
+++ b/third_party/blink/renderer/core/dom/extensions/anti_amp_cure.h
@@ -0,0 +1,6 @@
+#ifndef anti_amp_cure_h
+#define anti_amp_cure_h
+
+#define ANTI_AMP_CURE_JS "/* Bromite click-tracking and AMP removal v0.3.5 */\n\nfunction recreateHyperlink(a) {\n // skip already-sanitized hyperlinks\n if (a.sane) return false;\n\n // create new A element - old one has event listeners attached\n var newA = document.createElement('a');\n newA.referrerPolicy = 'origin';\n // property set when hyperlink has been created by this script\n newA.sane = 1;\n\n // remove AMP class, get actual page URL\n var ampCur = a.getAttribute('data-amp-cur');\n if (ampCur) {\n newA.href = ampCur;\n a.classList.remove('amp_r');\n } else {\n var realLink = getRealLinkFromGoogleUrl(a);\n if (realLink) {\n newA.href = realLink;\n } else {\n // might not be an actual hyperlink, ignore it\n if (!a.href) {\n return false;\n }\n // leave original href unchanged\n newA.href = a.href;\n }\n }\n // copy CSS classes\n newA.className = a.className;\n\n // copy nodes inside the hyperlink\n while (a.firstChild) {\n newA.appendChild(a.lastChild);\n }\n // replace hyperlink\n a.parentNode.replaceChild(newA, a);\n return true;\n}\n\nfunction isResult(a) {\n if (a.getAttribute('data-amp-cur'))\n return true;\n var inlineMousedown = a.getAttribute('onmousedown');\n if (!inlineMousedown)\n\treturn false;\n // return rwt(....); // E.g Google search results.\n // return google.rwt(...); // E.g. sponsored search results\n // return google.arwt(this); // E.g. sponsored search results (dec 2016).\n return /\\ba?rwt\\(/.test(inlineMousedown) || /\\bctpacw\\b/.test(inlineMousedown);\n}\n\n/**\n * @returns {String} the real URL if the given link is a Google redirect URL.\n */\nfunction getRealLinkFromGoogleUrl(a) {\n if ((a.hostname === location.hostname || a.hostname.indexOf('www.google.') == 0) &&\n /^\\/(local_)?url$/.test(a.pathname)) {\n // Google Maps / Dito (/local_url?q=<url>)\n // Mobile (/url?q=<url>)\n var url = /[?&](?:q|url)=((?:https?|ftp)[%:][^&]+)/.exec(a.search);\n if (url) {\n return decodeURIComponent(url[1]);\n }\n // Help pages, e.g. safe browsing (/url?...&q=%2Fsupport%2Fanswer...)\n url = /[?&](?:q|url)=((?:%2[Ff]|\\/)[^&]+)/.exec(a.search);\n if (url) {\n return a.origin + decodeURIComponent(url[1]);\n }\n }\n}\n\nfunction sanitizeAds() {\n // scan all divs\n var div = document.getElementById('tads');\n if (div) {\n div.style.display = 'none';\n\treturn true;\n }\n return false;\n}\n\nfunction sanitizeAll() {\n console.log(\"ads removed: \", sanitizeAds());\n console.log(\"hyperlinks sanitized: \", sanitizeAllHyperlinks(document));\n}\n\nfunction hookMoreResults() {\n var extrares = document.getElementById('extrares');\n if (!extrares) {\n console.log(\"could not hook more results\");\n return;\n }\n // mutation observers are great but they don't work\n extrares.addEventListener(\"DOMNodeInserted\", function(e) {\n var node = e.target;\n if (node.id && node.id.startsWith(\"arc-srp\"))\n console.log(\"hyperlinks sanitized on new result node: \", sanitizeAllHyperlinks(node));\n });\n}\n\nfunction setMlogoClick() {\n var mlogo = document.getElementById('qslc');\n if (mlogo && mlogo.children[0]) {\n mlogo = mlogo.children[0];\n mlogo.removeAttribute(\"href\");\n mlogo.setAttribute(\"onclick\", \"sanitizeAll()\");\n console.log(\"logo link replaced\");\n } else {\n console.log(\"could not replace logo link\");\n }\n}\n\nfunction sanitizeAllHyperlinks(rootNode) {\n var saned = 0, total = 0;\n rootNode.querySelectorAll('div[data-hveid]:not([data-hveid=\"\"]) a').forEach(function(a) {\n\ttotal++;\n\tvar res = recreateHyperlink(a);\n\tif (res) saned++;\n });\n console.log(\"sanitized \", saned, \"/\", total, \" hyperlinks\");\n\n return saned;\n}\n\n// avoid running cleanup on non-search pages\nif ((document.location.host.indexOf(\"images.google.\") == -1) && (document.location.host.indexOf(\"news.google.\") == -1)) {\n sanitizeAll();\n}\nsetMlogoClick();\n\nhookMoreResults();\n"
+
+#endif // anti_amp_cure_h
--
2.7.4
+16 -3
View File
@@ -5,9 +5,11 @@ Subject: Play videos in background
Break Page Visibility API and Fullscreen API for youtube.com and vimeo.com
Original Javascript code by timdream
---
third_party/blink/renderer/core/dom/BUILD.gn | 1 +
third_party/blink/renderer/core/dom/document.cc | 17 +++++++++++++----
2 files changed, 14 insertions(+), 4 deletions(-)
third_party/blink/renderer/core/dom/BUILD.gn | 1 +
third_party/blink/renderer/core/dom/document.cc | 17 +++++++++++++----
.../blink/renderer/core/dom/extensions/video_bg_play.h | 6 ++++++
3 files changed, 20 insertions(+), 4 deletions(-)
create mode 100644 third_party/blink/renderer/core/dom/extensions/video_bg_play.h
diff --git a/third_party/blink/renderer/core/dom/BUILD.gn b/third_party/blink/renderer/core/dom/BUILD.gn
--- a/third_party/blink/renderer/core/dom/BUILD.gn
@@ -61,6 +63,17 @@ diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink
FirstMeaningfulPaintDetector::From(*this).CheckNetworkStable();
}
diff --git a/third_party/blink/renderer/core/dom/extensions/video_bg_play.h b/third_party/blink/renderer/core/dom/extensions/video_bg_play.h
new file mode 100644
--- /dev/null
+++ b/third_party/blink/renderer/core/dom/extensions/video_bg_play.h
@@ -0,0 +1,6 @@
+#ifndef video_bg_play_h
+#define video_bg_play_h
+
+#define VIDEO_BG_PLAY_JS "'use strict';\n\n/* video background play fix - original version by timdream */\ndocument.videoBGFix = {};\n\n// Page Visibility API\nObject.defineProperties(document.videoBGFix,\n { 'hidden': {value: false}, 'visibilityState': {value: 'visible'} });\n\nwindow.addEventListener(\n 'visibilitychange', evt => evt.stopImmediatePropagation(), true);\nwindow.addEventListener(\n 'blur', evt => evt.stopImmediatePropagation(), true);\n\n// Fullscreen API\nwindow.addEventListener('fullscreenchange', evt => {\n Object.defineProperties(document.videoBGFix,\n { 'fullscreenEnabled': {value: true},\n 'fullscreen': {value: true},\n 'fullscreenElement': {value: document.fullscreenElement.videoBGFix}});\n window.addEventListener(\n 'fullscreenchange', evt => evt.stopImmediatePropagation(), true);\n}, { capture: true, once: true });\n"
+
+#endif // video_bg_play_h
--
2.7.4
+43 -46
View File
@@ -22,12 +22,12 @@ Perform adblock interception in StartJob to address lagging issues
.../java/strings/android_chrome_strings.grd | 11 +
.../subresource_filter_content_settings_manager.cc | 3 +
net/BUILD.gn | 9 +-
net/url_request/adblock_intercept.cc | 329 +++++++++++++++++++++
net/url_request/adblock_intercept.cc | 326 +++++++++++++++++++++
net/url_request/adblock_intercept.h | 18 ++
net/url_request/nochromo_intercept.cc | 116 --------
net/url_request/nochromo_intercept.h | 13 -
net/url_request/url_request.cc | 36 ++-
14 files changed, 480 insertions(+), 134 deletions(-)
14 files changed, 477 insertions(+), 134 deletions(-)
create mode 100644 net/url_request/adblock_intercept.cc
create mode 100644 net/url_request/adblock_intercept.h
delete mode 100644 net/url_request/nochromo_intercept.cc
@@ -251,7 +251,7 @@ diff --git a/net/url_request/adblock_intercept.cc b/net/url_request/adblock_inte
new file mode 100644
--- /dev/null
+++ b/net/url_request/adblock_intercept.cc
@@ -0,0 +1,329 @@
@@ -0,0 +1,326 @@
+#include "url/gurl.h"
+
+#ifdef ADB_TESTER
@@ -431,69 +431,69 @@ new file mode 100644
+ return match;
+}
+
+static int url_match_domain(adblock_entry *entry, const std::string &origin_host) {
+ if (entry->domains_skip && !origin_host.empty()) {
+ // filter will not be activated on these domains
+bool url_match_domain(adblock_entry *entry, const std::string &origin_host) {
+ bool match_domain = true;
+ // check for a negative domain match
+ if (entry->domains_skip) {
+ if (origin_host.empty()) {
+ // skip this rule, cannot match on domain
+ return false;
+ }
+ for (int d = 0; const char *domain = entry->domains_skip[d]; d++) {
+ if (domain == origin_host) {
+ // this domain is whitelisted, do not further process this rule in any way
+ return 0;
+ match_domain = false;
+ break;
+ }
+ }
+ }
+ // fallthrough is desired
+
+ if (!entry->domains || origin_host.empty()) {
+ // undetermined
+ return 3;
+ }
+
+ // filter will be active only if a domain matches
+ // if none matches, the filter is to be skipped
+ for (int d = 0; const char *domain = entry->domains[d]; d++) {
+ if (domain == origin_host) {
+ // this domain is one of those that activate the rule
+ return 1;
+ // check for a required positive domain match
+ if (entry->domains) {
+ if (origin_host.empty()) {
+ // skip this rule, cannot match on domain
+ return false;
+ }
+ for (int d = 0; const char *domain = entry->domains[d]; d++) {
+ if (domain != origin_host) {
+ match_domain = false;
+ break;
+ }
+ }
+ }
+
+ // at least one domain should have been found, but none was
+ // thus the filter must be skipped
+ return 0;
+ return match_domain;
+}
+
+static int url_match_party(adblock_entry *entry, const GURL &url,
+ const std::string &origin_host, int &fp) {
+ int desired_fp;
+static bool url_match_party(adblock_entry *entry, const GURL &url,
+ const std::string &origin_host, bool &checked_fp,
+ bool &fp) {
+ bool wanted_fp;
+ if ((entry->flags & ADBLOCK_FLAG_THIRD_PARTY) != 0) {
+ desired_fp = 0;
+ wanted_fp = false;
+ } else if ((entry->flags & ADBLOCK_FLAG_FIRST_PARTY) != 0) {
+ desired_fp = 1;
+ wanted_fp = true;
+ } else {
+ // undetermined, it does not test for first/third party
+ return 3;
+ // no-op
+ return true;
+ }
+
+ if (origin_host.empty()) {
+ // cannot match this rule, no origin host to determine first/third party
+ return 0;
+ return false;
+ }
+
+#ifdef ADB_TESTER
+//__android_log_print(ANDROID_LOG_INFO, LOG_TAG, "matchFirst=%d matchThird=%d",
+// matchFirstParty, matchThirdParty);
+#endif
+ if (fp == 3) {
+ if (!checked_fp) {
+ // lower-case version
+ char *l_host = strtolower(origin_host.c_str()),
+ *l_url_host = strtolower(url.host().c_str());
+
+ // is the URL a first-party to the current page's host?
+ if (is_first_party(l_host, l_url_host))
+ fp = 1;
+ else
+ fp = 0;
+ fp = is_first_party(l_host, l_url_host);
+
+ checked_fp = true;
+#ifdef ADB_TESTER
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG,
+ "is_first_party(\"%s\", \"%s\") = %s", l_host,
@@ -503,7 +503,7 @@ new file mode 100644
+ free(l_url_host);
+ }
+
+ return fp == desired_fp ? 1 : 0;
+ return fp == wanted_fp;
+}
+
+int adblock_intercept(const GURL &url, const std::string &origin_host) {
@@ -522,7 +522,7 @@ new file mode 100644
+ c_url, url.host().c_str(), origin_host.c_str());
+#endif
+
+ int fp = 3;
+ bool checked_fp = false, fp = false;
+
+ bool intercept = false;
+ for (int i = 0; i < ADBLOCK_ENTRY_COUNT; i++) {
@@ -532,22 +532,19 @@ new file mode 100644
+ bool check =
+ (!intercept && ((entry->flags & ADBLOCK_FLAG_EXCEPTION) == 0)) ||
+ (intercept && ((entry->flags & ADBLOCK_FLAG_EXCEPTION) != 0));
+
+ if (!check)
+ continue;
+
+ // first check for domain matches, a quick branch out if matching
+ if (0 == url_match_domain(entry, origin_host)) {
+ if (!url_match_domain(entry, origin_host))
+ continue;
+ }
+ // fallthrough with values 3 (undetermined / no domain options) or 1 (matched)
+
+ // check on the URL matcher
+ if (!url_matches(c_url, c_url_sep, c_url_lower, c_url_lower_sep, entry))
+ continue;
+
+ // finally check first/third-party
+ if (0 == url_match_party(entry, url, origin_host, fp))
+ if (!url_match_party(entry, url, origin_host, checked_fp, fp))
+ continue;
+
+#ifdef ADBLOCK_LOG
@@ -569,12 +566,12 @@ new file mode 100644
+
+ if (intercept) {
+#ifdef ADBLOCK_LOG
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "blocked (fp=%d)", fp);
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "blocked");
+#endif
+ return 1;
+ }
+#ifdef ADBLOCK_LOG
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "pass (fp=%d)", fp);
+ __android_log_print(ANDROID_LOG_INFO, LOG_TAG, "pass");
+#endif
+ }
+ return 0;
+72 -16
View File
@@ -2,20 +2,60 @@ From: csagan5 <32685696+csagan5@users.noreply.github.com>
Date: Wed, 21 Mar 2018 14:15:28 +0100
Subject: User Agent: anonymize
Remove device name and build id
Use a fixed device name and Chrome product version.
---
content/common/user_agent.cc | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
components/version_info/version_info.cc | 17 ++++++++++++-
content/common/user_agent.cc | 45 +++++++++++++++++++--------------
2 files changed, 42 insertions(+), 20 deletions(-)
diff --git a/components/version_info/version_info.cc b/components/version_info/version_info.cc
--- a/components/version_info/version_info.cc
+++ b/components/version_info/version_info.cc
@@ -7,13 +7,28 @@
#include "base/logging.h"
#include "base/no_destructor.h"
#include "base/version.h"
+#include "base/sys_info.h"
#include "build/build_config.h"
#include "components/version_info/version_info_values.h"
namespace version_info {
std::string GetProductNameAndVersionForUserAgent() {
- return "Chrome/" + GetVersionNumber();
+ int32_t major, minor, bugfix;
+ base::SysInfo::OperatingSystemVersionNumbers(&major,
+ &minor,
+ &bugfix);
+ switch (major) {
+ case 7:
+ return "Chrome/63.0.3239.111";
+ case 6:
+ return "Chrome/63.0.3239.83";
+ case 5:
+ case 4:
+ return "Chrome/62.0.3202.84";
+ }
+ // version 8 and above
+ return "Chrome/67.0.3396.87";
}
std::string GetProductName() {
diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc
--- a/content/common/user_agent.cc
+++ b/content/common/user_agent.cc
@@ -60,26 +60,6 @@ std::string BuildOSCpuInfo() {
@@ -59,26 +59,33 @@ std::string BuildOSCpuInfo() {
architecture_token = "; Win64; IA64";
}
#elif defined(OS_ANDROID)
std::string android_version_str = base::SysInfo::OperatingSystemVersion();
-
- std::string android_info_str;
- std::string android_version_str = base::SysInfo::OperatingSystemVersion();
+ int32_t major, minor, bugfix;
+ base::SysInfo::OperatingSystemVersionNumbers(&major, &minor, &bugfix);
+ std::string android_version_str = base::StringPrintf("%d.%d.%d", major, minor, bugfix);
+ // Send information about the device and buld ID.
+ // Use a common device/build ID based on Android major version.
std::string android_info_str;
-
- // Send information about the device.
- bool semicolon_inserted = false;
@@ -33,22 +73,38 @@ diff --git a/content/common/user_agent.cc b/content/common/user_agent.cc
- android_info_str += ";";
- }
- android_info_str += " Build/" + android_build_id;
- }
+ switch (major) {
+ case 7:
+ // Chrome/63.0.3239.111
+ android_info_str = "SM-J730GM Build/NRD90M";
+ break;
+ case 6:
+ // Chrome/63.0.3239.83
+ android_info_str = "SM-G532G Build/MMB29T";
+ break;
+ case 5:
+ // Chrome/62.0.3202.84
+ android_info_str = "A37fw Build/LMY47V";
+ break;
+ case 4:
+ // Chrome/62.0.3202.84
+ android_info_str = "SM-G7102 Build/KOT49H";
+ break;
+ default: // version 8 and above
+ android_info_str = "SM-G950U Build/R16NW";
+ break;
}
#elif (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA)
// Should work on any Posix system.
struct utsname unixinfo;
@@ -115,9 +95,8 @@ std::string BuildOSCpuInfo() {
@@ -115,7 +122,7 @@ std::string BuildOSCpuInfo() {
os_minor_version,
os_bugfix_version
#elif defined(OS_ANDROID)
- "Android %s%s",
- android_version_str.c_str(),
- android_info_str.c_str()
+ "Android %s",
+ android_version_str.c_str()
+ "Android %s; %s",
android_version_str.c_str(),
android_info_str.c_str()
#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
"%s %s",
unixinfo.sysname, // e.g. Linux
--
2.7.4
@@ -4,7 +4,7 @@ Subject: getClientRects, getBoundingClientRect, measureText: add
fingerprinting mitigation
Scale the result of Range::getClientRects, Element::getBoundingClientRect and
Canvas::measureText by a random +/-3/10000th of the original value for each
Canvas::measureText by a random +/-3/1000000th of the original value for each
float in the returned Rect/Quad.
Rationale is that the returned values are within the same order of magnitude
@@ -36,9 +36,9 @@ diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/
GetDocument().AdjustFloatQuadsForScrollAndAbsoluteZoom(
quads, *element_layout_object);
+
+ // scale all quads by 3/10000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ // scale all quads
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.000003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.000003;
+
+ for (FloatQuad& quad : quads) {
+ quad.Scale(shuffleX, shuffleY);
@@ -52,9 +52,9 @@ diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/
GetDocument().AdjustFloatRectForScrollAndAbsoluteZoom(result,
*element_layout_object);
+
+ // scale rect by 3/10000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ // scale rect by 3/1000000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.000003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.000003;
+
+ result.Scale(shuffleX, shuffleY);
+
@@ -77,9 +77,9 @@ diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/re
Vector<FloatQuad> quads;
GetBorderAndTextQuads(quads);
+ // scale all quads by 3/10000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ // scale all quads by 3/1000000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.000003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.000003;
+
+ for (FloatQuad& quad : quads) {
+ quad.Scale(shuffleX, shuffleY);
@@ -92,9 +92,9 @@ diff --git a/third_party/blink/renderer/core/dom/range.cc b/third_party/blink/re
- return DOMRect::FromFloatRect(BoundingRect());
+ auto rect = BoundingRect();
+
+ // scale rect by 3/10000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ // scale rect by 3/1000000th
+ auto shuffleX = 1 + (base::RandDouble() - 0.5) * 0.000003;
+ auto shuffleY = 1 + (base::RandDouble() - 0.5) * 0.000003;
+
+ rect.Scale(shuffleX, shuffleY);
+
@@ -162,8 +162,8 @@ diff --git a/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering
+ TextMetrics* textMetrics = TextMetrics::Create(font, direction, GetState().GetTextBaseline(),
GetState().GetTextAlign(), text);
+
+ // scale text metrics by 3/10000th
+ auto shuffleFactor = 1 + (base::RandDouble() - 0.5) * 0.0003;
+ // scale text metrics by 3/1000000th
+ auto shuffleFactor = 1 + (base::RandDouble() - 0.5) * 0.000003;
+ textMetrics->Shuffle(shuffleFactor);
+
+ return textMetrics;
@@ -23,7 +23,7 @@ diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
};
+const FeatureEntry::Choice kMaxConnectionsPerHostChoices[] = {
+ {features::kMaxConnectionsPerHostChoiceDefault, "", "0"},
+ {features::kMaxConnectionsPerHostChoiceDefault, "", "6"},
+ {features::kMaxConnectionsPerHostChoice6, switches::kMaxConnectionsPerHost, "6"},
+ {features::kMaxConnectionsPerHostChoice15, switches::kMaxConnectionsPerHost, "15"},
+};
@@ -14,17 +14,17 @@ Subject: Add flag to show/hide NTP tiles
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1285,6 +1285,10 @@ const FeatureEntry kFeatureEntries[] = {
flag_descriptions::kWebrtcNewEncodeCpuLoadEstimatorDescription, kOsAll,
FEATURE_VALUE_TYPE(media::kNewEncodeCpuLoadEstimator)},
#if defined(OS_ANDROID)
@@ -1916,6 +1916,10 @@ const FeatureEntry kFeatureEntries[] = {
flag_descriptions::kChromeModernAlternateCardLayoutName,
flag_descriptions::kChromeModernAlternateCardLayoutDescription, kOsAndroid,
FEATURE_VALUE_TYPE(chrome::android::kChromeModernAlternateCardLayout)},
+ {"hide-ntp-tiles",
+ flag_descriptions::kHideNTPTilesName,
+ flag_descriptions::kHideNTPTilesDescription, kOsAndroid,
+ SINGLE_VALUE_TYPE(switches::kHideNTPTiles)},
{"clear-old-browsing-data", flag_descriptions::kClearOldBrowsingDataName,
flag_descriptions::kClearOldBrowsingDataDescription, kOsAndroid,
FEATURE_VALUE_TYPE(features::kClearOldBrowsingData)},
{"force-enable-home-page-button", flag_descriptions::kHomePageButtonName,
flag_descriptions::kHomePageButtonDescription, kOsAndroid,
FEATURE_VALUE_TYPE(chrome::android::kHomePageButtonForceEnabled)},
diff --git a/chrome/browser/android/ntp/most_visited_sites_bridge.cc b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
--- a/chrome/browser/android/ntp/most_visited_sites_bridge.cc
+++ b/chrome/browser/android/ntp/most_visited_sites_bridge.cc
@@ -50,7 +50,7 @@ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/LaunchIntentDis
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1302,6 +1302,10 @@ const FeatureEntry kFeatureEntries[] = {
@@ -1298,6 +1298,10 @@ const FeatureEntry kFeatureEntries[] = {
flag_descriptions::kMediaScreenCaptureName,
flag_descriptions::kMediaScreenCaptureDescription, kOsAndroid,
FEATURE_VALUE_TYPE(chrome::android::kUserMediaScreenCapturing)},
@@ -0,0 +1,817 @@
From: csagan5 <32685696+csagan5@users.noreply.github.com>
Date: Wed, 1 Aug 2018 09:19:40 +0200
Subject: Add bookmark import/export actions in bookmarks activity and page
---
.../java/res/menu/bookmark_action_bar_menu.xml | 14 ++
.../browser/bookmarks/BookmarkActionBar.java | 12 ++
.../chrome/browser/bookmarks/BookmarkActivity.java | 19 ++
.../chrome/browser/bookmarks/BookmarkBridge.java | 21 ++
.../chrome/browser/bookmarks/BookmarkDelegate.java | 10 +
.../chrome/browser/bookmarks/BookmarkManager.java | 20 ++
.../chrome/browser/bookmarks/BookmarkPage.java | 1 +
.../java/strings/android_chrome_strings.grd | 6 +
chrome/browser/BUILD.gn | 8 +-
.../browser/android/bookmarks/bookmark_bridge.cc | 219 +++++++++++++++++++++
chrome/browser/android/bookmarks/bookmark_bridge.h | 19 +-
chrome/browser/importer/profile_writer.cc | 2 +
chrome/common/BUILD.gn | 3 +
chrome/utility/BUILD.gn | 7 +-
chrome/utility/importer/bookmark_html_reader.cc | 27 ++-
chrome/utility/importer/bookmark_html_reader.h | 9 +
16 files changed, 387 insertions(+), 10 deletions(-)
diff --git a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml b/chrome/android/java/res/menu/bookmark_action_bar_menu.xml
--- a/chrome/android/java/res/menu/bookmark_action_bar_menu.xml
+++ b/chrome/android/java/res/menu/bookmark_action_bar_menu.xml
@@ -22,6 +22,20 @@
app:showAsAction="ifRoom"
app:iconTint="@color/dark_mode_tint" />
<item
+ android:id="@+id/import_menu_id"
+ android:icon="@drawable/folder_open"
+ android:title="@string/import_bookmarks"
+ android:visible="true"
+ app:showAsAction="ifRoom"
+ app:iconTint="@color/dark_mode_tint" />
+ <item
+ android:id="@+id/export_menu_id"
+ android:icon="@drawable/save"
+ android:title="@string/export_bookmarks"
+ android:visible="true"
+ app:showAsAction="ifRoom"
+ app:iconTint="@color/dark_mode_tint" />
+ <item
android:id="@+id/close_menu_id"
android:icon="@drawable/btn_close"
android:title="@string/bookmark_action_bar_close"
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActionBar.java
@@ -82,6 +82,12 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
} else if (menuItem.getItemId() == R.id.search_menu_id) {
mDelegate.openSearchUI();
return true;
+ } else if (menuItem.getItemId() == R.id.import_menu_id) {
+ mDelegate.importBookmarks();
+ return true;
+ } else if (menuItem.getItemId() == R.id.export_menu_id) {
+ mDelegate.exportBookmarks();
+ return true;
}
SelectionDelegate<BookmarkId> selectionDelegate = mDelegate.getSelectionDelegate();
@@ -125,6 +131,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
void showLoadingUi() {
setTitle(null);
setNavigationButton(NAVIGATION_BUTTON_NONE);
+ getMenu().findItem(R.id.import_menu_id).setVisible(false);
+ getMenu().findItem(R.id.export_menu_id).setVisible(false);
getMenu().findItem(R.id.search_menu_id).setVisible(false);
getMenu().findItem(R.id.edit_menu_id).setVisible(false);
}
@@ -134,6 +142,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
super.showNormalView();
if (mDelegate == null) {
+ getMenu().findItem(R.id.import_menu_id).setVisible(false);
+ getMenu().findItem(R.id.export_menu_id).setVisible(false);
getMenu().findItem(R.id.search_menu_id).setVisible(false);
getMenu().findItem(R.id.edit_menu_id).setVisible(false);
}
@@ -166,6 +176,8 @@ public class BookmarkActionBar extends SelectableListToolbar<BookmarkId>
public void onFolderStateSet(BookmarkId folder) {
mCurrentFolder = mDelegate.getModel().getBookmarkById(folder);
+ getMenu().findItem(R.id.import_menu_id).setVisible(true);
+ getMenu().findItem(R.id.export_menu_id).setVisible(true);
getMenu().findItem(R.id.search_menu_id).setVisible(true);
getMenu().findItem(R.id.edit_menu_id).setVisible(mCurrentFolder.isEditable());
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActivity.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkActivity.java
@@ -12,6 +12,7 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.browser.SnackbarActivity;
import org.chromium.chrome.browser.UrlConstants;
import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.ui.base.ActivityWindowAndroid;
/**
* The activity that displays the bookmark UI on the phone. It keeps a {@link BookmarkManager}
@@ -21,6 +22,7 @@ import org.chromium.components.bookmarks.BookmarkId;
public class BookmarkActivity extends SnackbarActivity {
private BookmarkManager mBookmarkManager;
+ private ActivityWindowAndroid mWindowAndroid;
static final int EDIT_BOOKMARK_REQUEST_CODE = 14;
public static final String INTENT_VISIT_BOOKMARK_ID = "BookmarkEditActivity.VisitBookmarkId";
@@ -32,6 +34,22 @@ public class BookmarkActivity extends SnackbarActivity {
if (TextUtils.isEmpty(url)) url = UrlConstants.BOOKMARKS_URL;
mBookmarkManager.updateForUrl(url);
setContentView(mBookmarkManager.getView());
+
+ final boolean listenToActivityState = true;
+ mWindowAndroid = new ActivityWindowAndroid(this, listenToActivityState);
+ mWindowAndroid.restoreInstanceState(savedInstanceState);
+ mBookmarkManager.setWindow(mWindowAndroid);
+ // Set up the animation placeholder to be the SurfaceView. This disables the
+ // SurfaceView's 'hole' clipping during animations that are notified to the window.
+// mWindowAndroid.setAnimationPlaceholderView(
+// mBookmarkManager.getContentViewRenderView().getSurfaceView());
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+
+ mWindowAndroid.saveInstanceState(outState);
}
@Override
@@ -48,6 +66,7 @@ public class BookmarkActivity extends SnackbarActivity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
+ mWindowAndroid.onActivityResult(requestCode, resultCode, data);
if (requestCode == EDIT_BOOKMARK_REQUEST_CODE && resultCode == RESULT_OK) {
BookmarkId bookmarkId = BookmarkId.getBookmarkIdFromString(data.getStringExtra(
INTENT_VISIT_BOOKMARK_ID));
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkBridge.java
@@ -18,6 +18,7 @@ import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.components.bookmarks.BookmarkId;
import org.chromium.components.bookmarks.BookmarkType;
import org.chromium.components.url_formatter.UrlFormatter;
+import org.chromium.ui.base.WindowAndroid;
import java.util.ArrayList;
import java.util.List;
@@ -508,6 +509,24 @@ public class BookmarkBridge {
}
/**
+ * Import bookmarks from a selected file.
+ * @param window The current window of the bookmarks activity or page.
+ */
+ public void importBookmarks(WindowAndroid window) {
+ assert mIsNativeBookmarkModelLoaded;
+ nativeImportBookmarks(mNativeBookmarkBridge, window);
+ }
+
+ /**
+ * Export bookmarks to a path selected by the user.
+ * @param window The current window of the bookmarks activity or page.
+ */
+ public void exportBookmarks() {
+ assert mIsNativeBookmarkModelLoaded;
+ nativeExportBookmarks(mNativeBookmarkBridge);
+ }
+
+ /**
* Synchronously gets a list of bookmarks that match the specified search query.
* @param query Keyword used for searching bookmarks.
* @param maxNumberOfResult Maximum number of result to fetch.
@@ -906,6 +925,8 @@ public class BookmarkBridge {
boolean getFolders, boolean getBookmarks, List<BookmarkId> bookmarksList);
private native BookmarkId nativeGetChildAt(long nativeBookmarkBridge, long id, int type,
int index);
+ private native void nativeImportBookmarks(long nativeBookmarkBridge, WindowAndroid window);
+ private native void nativeExportBookmarks(long nativeBookmarkBridge);
private native int nativeGetTotalBookmarkCount(long nativeBookmarkBridge, long id, int type);
private native void nativeSetBookmarkTitle(long nativeBookmarkBridge, long id, int type,
String title);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkDelegate.java
@@ -69,6 +69,16 @@ interface BookmarkDelegate {
void openSearchUI();
/**
+ * Imports bookmarks from user-selected file.
+ */
+ void importBookmarks();
+
+ /**
+ * Exports bookmarks to downloads directory.
+ */
+ void exportBookmarks();
+
+ /**
* Dismisses the search UI.
*/
void closeSearchUI();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkManager.java
@@ -22,6 +22,7 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.BasicNativePage;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkItem;
import org.chromium.chrome.browser.bookmarks.BookmarkBridge.BookmarkModelObserver;
+import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.favicon.LargeIconBridge;
import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksReader;
import org.chromium.chrome.browser.profiles.Profile;
@@ -30,6 +31,7 @@ import org.chromium.chrome.browser.widget.selection.SelectableListLayout;
import org.chromium.chrome.browser.widget.selection.SelectableListToolbar.SearchDelegate;
import org.chromium.chrome.browser.widget.selection.SelectionDelegate;
import org.chromium.components.bookmarks.BookmarkId;
+import org.chromium.ui.base.ActivityWindowAndroid;
import java.util.Stack;
@@ -53,6 +55,7 @@ public class BookmarkManager implements BookmarkDelegate, SearchDelegate,
private Activity mActivity;
private ViewGroup mMainView;
private BookmarkModel mBookmarkModel;
+ private ActivityWindowAndroid mWindowAndroid;
private BookmarkUndoController mUndoController;
private final ObserverList<BookmarkUIObserver> mUIObservers = new ObserverList<>();
private BasicNativePage mNativePage;
@@ -269,6 +272,13 @@ public class BookmarkManager implements BookmarkDelegate, SearchDelegate,
}
/**
+ * Sets the Android window that is used by further intents created by the bookmark activity.
+ */
+ public void setWindow(ActivityWindowAndroid window) {
+ mWindowAndroid = window;
+ }
+
+ /**
* @return Current URL representing the UI state of bookmark manager. If no state has been shown
* yet in this session, on phone return last used state stored in preference; on tablet
* return the url previously set by {@link #updateForUrl(String)}.
@@ -416,6 +426,16 @@ public class BookmarkManager implements BookmarkDelegate, SearchDelegate,
}
@Override
+ public void importBookmarks() {
+ mBookmarkModel.importBookmarks(mWindowAndroid);
+ }
+
+ @Override
+ public void exportBookmarks() {
+ mBookmarkModel.exportBookmarks();
+ }
+
+ @Override
public void openSearchUI() {
setState(BookmarkUIState.createSearchState());
mSelectableListLayout.onStartSearch();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java
--- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/BookmarkPage.java
@@ -35,6 +35,7 @@ public class BookmarkPage extends BasicNativePage {
mManager = new BookmarkManager(
activity, false, ((SnackbarManageable) activity).getSnackbarManager());
mManager.setBasicNativePage(this);
+ mManager.setWindow(activity.getWindowAndroid());
mTitle = activity.getString(R.string.bookmarks);
}
diff --git a/chrome/android/java/strings/android_chrome_strings.grd b/chrome/android/java/strings/android_chrome_strings.grd
--- a/chrome/android/java/strings/android_chrome_strings.grd
+++ b/chrome/android/java/strings/android_chrome_strings.grd
@@ -209,6 +209,12 @@ CHAR-LIMIT guidelines:
<message name="IDS_SEARCH" desc="The label for a search button.">
Search
</message>
+ <message name="IDS_IMPORT_BOOKMARKS" desc="The label for the import bookmarks button.">
+ Import
+ </message>
+ <message name="IDS_EXPORT_BOOKMARKS" desc="The label for an export bookmarks button.">
+ Export
+ </message>
<message name="IDS_SHOW_INFO" desc="The label for a info button to show info.">
Show Info
</message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -135,6 +135,10 @@ jumbo_split_static_library("browser") {
"bitmap_fetcher/bitmap_fetcher_service.h",
"bitmap_fetcher/bitmap_fetcher_service_factory.cc",
"bitmap_fetcher/bitmap_fetcher_service_factory.h",
+ "importer/profile_writer.cc",
+ "importer/profile_writer.h",
+ "bookmarks/bookmark_html_writer.cc",
+ "bookmarks/bookmark_html_writer.h",
"bookmarks/bookmark_model_factory.cc",
"bookmarks/bookmark_model_factory.h",
"bookmarks/bookmark_stats.cc",
@@ -2422,8 +2426,6 @@ jumbo_split_static_library("browser") {
"banners/app_banner_infobar_delegate_desktop.h",
"banners/app_banner_manager_desktop.cc",
"banners/app_banner_manager_desktop.h",
- "bookmarks/bookmark_html_writer.cc",
- "bookmarks/bookmark_html_writer.h",
"certificate_viewer.h",
"chrome_browser_field_trials_desktop.cc",
"chrome_browser_field_trials_desktop.h",
@@ -2510,8 +2512,6 @@ jumbo_split_static_library("browser") {
"importer/importer_uma.h",
"importer/in_process_importer_bridge.cc",
"importer/in_process_importer_bridge.h",
- "importer/profile_writer.cc",
- "importer/profile_writer.h",
"lifetime/browser_close_manager.cc",
"lifetime/browser_close_manager.h",
"lifetime/termination_notification.cc",
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.cc b/chrome/browser/android/bookmarks/bookmark_bridge.cc
--- a/chrome/browser/android/bookmarks/bookmark_bridge.cc
+++ b/chrome/browser/android/bookmarks/bookmark_bridge.cc
@@ -9,18 +9,29 @@
#include <memory>
+#include "base/android/content_uri_utils.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
+#include "base/android/path_utils.h"
#include "base/containers/stack.h"
#include "base/containers/stack_container.h"
#include "base/i18n/string_compare.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/utility/importer/bookmark_html_reader.h"
+#include "chrome/browser/bookmarks/bookmark_html_writer.h"
#include "chrome/browser/bookmarks/bookmark_model_factory.h"
#include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
+#include "chrome/browser/importer/profile_writer.h"
+#include "chrome/browser/platform_util.h"
+#include "chrome/browser/ui/chrome_select_file_policy.h"
#include "chrome/browser/profiles/incognito_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/undo/bookmark_undo_service_factory.h"
+#include "chrome/common/importer/imported_bookmark_entry.h"
+#include "chrome/common/importer/importer_data_types.h"
+#include "chrome/common/url_constants.h"
#include "components/bookmarks/browser/bookmark_model.h"
#include "components/bookmarks/browser/bookmark_utils.h"
#include "components/bookmarks/browser/scoped_group_bookmark_actions.h"
@@ -30,11 +41,14 @@
#include "components/bookmarks/managed/managed_bookmark_service.h"
#include "components/prefs/pref_service.h"
#include "components/query_parser/query_parser.h"
+#include "components/search_engines/template_url.h"
#include "components/signin/core/browser/signin_manager.h"
#include "components/undo/bookmark_undo_service.h"
#include "components/undo/undo_manager.h"
+#include "components/url_formatter/url_fixer.h"
#include "content/public/browser/browser_thread.h"
#include "jni/BookmarkBridge_jni.h"
+#include "ui/android/window_android.h"
using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
@@ -53,6 +67,57 @@ using bookmarks::BookmarkPermanentNode;
using bookmarks::BookmarkType;
using content::BrowserThread;
+namespace internal {
+
+// Returns true if |url| has a valid scheme that we allow to import. We
+// filter out the URL with a unsupported scheme.
+bool CanImportURL(const GURL& url) {
+ // The URL is not valid.
+ if (!url.is_valid())
+ return false;
+
+ // Filter out the URLs with unsupported schemes.
+ const char* const kInvalidSchemes[] = {"wyciwyg", "place"};
+ for (size_t i = 0; i < arraysize(kInvalidSchemes); ++i) {
+ if (url.SchemeIs(kInvalidSchemes[i]))
+ return false;
+ }
+
+ // Check if |url| is about:blank.
+ if (url == url::kAboutBlankURL)
+ return true;
+
+ // If |url| starts with chrome:// or about:, check if it's one of the URLs
+ // that we support.
+ if (url.SchemeIs(content::kChromeUIScheme) ||
+ url.SchemeIs(url::kAboutScheme)) {
+ if (url.host_piece() == chrome::kChromeUIUberHost ||
+ url.host_piece() == chrome::kChromeUIAboutHost)
+ return true;
+
+ GURL fixed_url(url_formatter::FixupURL(url.spec(), std::string()));
+ for (size_t i = 0; i < chrome::kNumberOfChromeHostURLs; ++i) {
+ if (fixed_url.DomainIs(chrome::kChromeHostURLs[i]))
+ return true;
+ }
+
+ for (size_t i = 0; i < chrome::kNumberOfChromeDebugURLs; ++i) {
+ if (fixed_url == chrome::kChromeDebugURLs[i])
+ return true;
+ }
+
+ // If url has either chrome:// or about: schemes but wasn't found in the
+ // above lists, it means we don't support it, so we don't allow the user
+ // to import it.
+ return false;
+ }
+
+ // Otherwise, we assume the url has a valid (importable) scheme.
+ return true;
+}
+
+} // internal
+
namespace {
class BookmarkTitleComparer {
@@ -129,6 +194,10 @@ BookmarkBridge::~BookmarkBridge() {
bookmark_model_->RemoveObserver(this);
if (partner_bookmarks_shim_)
partner_bookmarks_shim_->RemoveObserver(this);
+ // There may be pending file dialogs, we need to tell them that we've gone
+ // away so they don't try and call back to us.
+ if (select_file_dialog_)
+ select_file_dialog_->ListenerDestroyed();
}
void BookmarkBridge::Destroy(JNIEnv*, const JavaParamRef<jobject>&) {
@@ -470,6 +539,156 @@ jint BookmarkBridge::GetTotalBookmarkCount(
return count;
}
+void BookmarkBridge::ImportBookmarks(JNIEnv* env,
+ const JavaParamRef<jobject>& obj,
+ const JavaParamRef<jobject>& java_window) {
+ DCHECK(IsLoaded());
+
+ ui::WindowAndroid* window =
+ ui::WindowAndroid::FromJavaWindowAndroid(java_window);
+ CHECK(window);
+
+ select_file_dialog_ = ui::SelectFileDialog::Create(
+ this, std::make_unique<ChromeSelectFilePolicy>(nullptr));
+
+ //NOTE: extension and description are not used on Android
+ ui::SelectFileDialog::FileTypeInfo file_type_info;
+ file_type_info.extensions.resize(1);
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("html"));
+ file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("htm"));
+ file_type_info.extension_description_overrides.push_back(base::ASCIIToUTF16("Netscape Bookmark"));
+ file_type_info.allowed_paths =
+ ui::SelectFileDialog::FileTypeInfo::NATIVE_OR_DRIVE_PATH;
+
+ const base::FilePath file_path;
+
+ select_file_dialog_->SelectFile(
+ ui::SelectFileDialog::SELECT_OPEN_FILE,
+ base::string16(),
+ file_path,
+ NULL,
+ 0,
+ base::FilePath::StringType(),
+ window,
+ NULL);
+}
+
+void ExporterCallback(Profile* profile, const base::FilePath& path) {
+ bookmark_html_writer::WriteBookmarks(profile, path, NULL);
+ //NOTE: nothing will be written if write permission has not been granted before
+ LOG(INFO) << "Bookmarks exported successfully in " << path;
+}
+
+void BookmarkBridge::ExportBookmarks(JNIEnv* env,
+ const JavaParamRef<jobject>& obj) {
+ DCHECK(IsLoaded());
+ base::FilePath path;
+ if (!base::android::GetDownloadsDirectory(&path)) {
+ LOG(ERROR) << "Could not retrieve downloads directory for bookmarks export";
+ return;
+ }
+
+ path = path.Append(FILE_PATH_LITERAL("bookmarks.html"));
+
+// base::PostTaskWithTraits(FROM_HERE, {base::MayBlock()},
+// base::BindOnce(&ExporterCallback, profile_, path));
+ ExporterCallback(profile_, path);
+}
+
+// Attempts to create a TemplateURL from the provided data. |title| is optional.
+// If TemplateURL creation fails, returns null.
+std::unique_ptr<TemplateURL> CreateTemplateURL(const base::string16& url,
+ const base::string16& keyword,
+ const base::string16& title) {
+ if (url.empty() || keyword.empty())
+ return nullptr;
+ TemplateURLData data;
+ data.SetKeyword(keyword);
+ // We set short name by using the title if it exists.
+ // Otherwise, we use the shortcut.
+ data.SetShortName(title.empty() ? keyword : title);
+ data.SetURL(TemplateURLRef::DisplayURLToURLRef(url));
+ return std::make_unique<TemplateURL>(data);
+}
+
+void ImporterCallback(Profile* profile, const base::FilePath& path, const std::string& contents) {
+ // this import logic comes from BookmarksFileImporter class
+ std::vector<ImportedBookmarkEntry> bookmarks;
+ std::vector<importer::SearchEngineInfo> search_engines;
+
+ bookmark_html_reader::ImportBookmarksFile(
+ base::Callback<bool(void)>(),
+ base::Bind(internal::CanImportURL),
+ contents,
+ &bookmarks,
+ &search_engines,
+ nullptr);
+
+ // writing to profile will begin extensive changes and use the same bookmarks model for persisting changes
+ auto *writer = new ProfileWriter(profile);
+
+ if (!bookmarks.empty()) {
+ writer->AddBookmarks(bookmarks, base::ASCIIToUTF16("Imported"));
+ }
+ if (!search_engines.empty()) {
+ TemplateURLService::OwnedTemplateURLVector owned_template_urls;
+ for (const auto& search_engine : search_engines) {
+ std::unique_ptr<TemplateURL> owned_template_url = CreateTemplateURL(
+ search_engine.url, search_engine.keyword, search_engine.display_name);
+ if (owned_template_url)
+ owned_template_urls.push_back(std::move(owned_template_url));
+ }
+ writer->AddKeywords(std::move(owned_template_urls), false);
+ }
+
+ LOG(INFO) << "Imported " << bookmarks.size() << " bookmarks and " <<
+ search_engines.size() << " search engines from " << path;
+}
+
+void BookmarkBridge::FileSelected(const base::FilePath& path, int index,
+ void* params) {
+ base::File file;
+ if (path.IsContentUri()) {
+ file = base::OpenContentUriForRead(path);
+ } else {
+ file.Initialize(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ }
+ if (!file.IsValid()) {
+ LOG(ERROR) << "Cannot open bookmarks file for import";
+ return;
+ }
+
+ auto fileLength = file.GetLength();
+ if (-1 == fileLength) {
+ LOG(ERROR) << "Cannot read bookmarks file length";
+ return;
+ }
+
+ if (fileLength > 10 * 1024 * 1024) {
+ LOG(ERROR) << "Bookmarks file is too big";
+ return;
+ }
+
+ std::vector<char> buffer(fileLength);
+ if (-1 == file.ReadAtCurrentPos(buffer.data(), fileLength)) {
+ LOG(ERROR) << "Could not read bookmarks file";
+ return;
+ }
+
+ if (buffer.empty()) {
+ LOG(ERROR) << "Empty bookmarks file";
+ return;
+ }
+
+ std::string content(buffer.begin(), buffer.end());
+// base::PostTaskWithTraits(FROM_HERE, {base::MayBlock()},
+// base::BindOnce(&ImporterCallback, profile_, path, content));
+ ImporterCallback(profile_, path, content);
+}
+
+void BookmarkBridge::FileSelectionCanceled(void* params) {
+}
+
void BookmarkBridge::SetBookmarkTitle(JNIEnv* env,
const JavaParamRef<jobject>& obj,
jlong id,
diff --git a/chrome/browser/android/bookmarks/bookmark_bridge.h b/chrome/browser/android/bookmarks/bookmark_bridge.h
--- a/chrome/browser/android/bookmarks/bookmark_bridge.h
+++ b/chrome/browser/android/bookmarks/bookmark_bridge.h
@@ -13,6 +13,8 @@
#include "components/bookmarks/browser/base_bookmark_model_observer.h"
#include "components/bookmarks/common/android/bookmark_id.h"
#include "components/prefs/pref_change_registrar.h"
+#include "components/search_engines/template_url.h"
+#include "ui/shell_dialogs/select_file_dialog.h"
namespace bookmarks {
class BookmarkModel;
@@ -26,7 +28,8 @@ class Profile;
// bookmark page. This fetches the bookmarks, title, urls, folder
// hierarchy.
class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
- public PartnerBookmarksShim::Observer {
+ public PartnerBookmarksShim::Observer,
+ public ui::SelectFileDialog::Listener {
public:
BookmarkBridge(JNIEnv* env,
const base::android::JavaRef<jobject>& obj,
@@ -36,6 +39,12 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
bool IsDoingExtensiveChanges(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
+ // SelectFileDialog::Listener implementation.
+ void FileSelected(const base::FilePath& path,
+ int index,
+ void* params) override;
+ void FileSelectionCanceled(void* params) override;
+
jboolean IsEditBookmarksEnabled(
JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj);
@@ -116,6 +125,13 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
jlong id,
jint type);
+ void ImportBookmarks(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj,
+ const base::android::JavaParamRef<jobject>& java_window);
+
+ void ExportBookmarks(JNIEnv* env,
+ const base::android::JavaParamRef<jobject>& obj);
+
void SetBookmarkTitle(JNIEnv* env,
const base::android::JavaParamRef<jobject>& obj,
jlong id,
@@ -267,6 +283,7 @@ class BookmarkBridge : public bookmarks::BaseBookmarkModelObserver,
std::unique_ptr<bookmarks::ScopedGroupBookmarkActions>
grouped_bookmark_actions_;
PrefChangeRegistrar pref_change_registrar_;
+ scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
// Information about the Partner bookmarks (must check for IsLoaded()).
// This is owned by profile.
diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc
--- a/chrome/browser/importer/profile_writer.cc
+++ b/chrome/browser/importer/profile_writer.cc
@@ -109,12 +109,14 @@ void ProfileWriter::AddHistoryPage(const history::URLRows& page,
HistoryServiceFactory::GetForProfile(profile_,
ServiceAccessType::EXPLICIT_ACCESS)
->AddPagesWithDetails(page, visit_source);
+#if !defined(OS_ANDROID)
// Measure the size of the history page after Auto Import on first run.
if (first_run::IsChromeFirstRun() &&
visit_source == history::SOURCE_IE_IMPORTED) {
UMA_HISTOGRAM_COUNTS("Import.ImportedHistorySize.AutoImportFromIE",
page.size());
}
+#endif
}
void ProfileWriter::AddHomepage(const GURL& home_page) {
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -434,6 +434,9 @@ static_library("common") {
sources += [
"media/chrome_media_drm_bridge_client.cc",
"media/chrome_media_drm_bridge_client.h",
+ ## Bromite dependencies for bookmark import functionality
+ "importer/imported_bookmark_entry.cc",
+ "importer/imported_bookmark_entry.h",
]
} else {
# Non-Android.
diff --git a/chrome/utility/BUILD.gn b/chrome/utility/BUILD.gn
--- a/chrome/utility/BUILD.gn
+++ b/chrome/utility/BUILD.gn
@@ -55,8 +55,6 @@ static_library("utility") {
if (!is_android) {
sources += [
- "importer/bookmark_html_reader.cc",
- "importer/bookmark_html_reader.h",
"importer/bookmarks_file_importer.cc",
"importer/bookmarks_file_importer.h",
"importer/edge_database_reader_win.cc",
@@ -160,6 +158,11 @@ static_library("utility") {
]
}
+ sources += [
+ "importer/bookmark_html_reader.cc",
+ "importer/bookmark_html_reader.h",
+ ]
+
if (use_nss_certs) {
sources += [
"importer/nss_decryptor_system_nss.cc",
diff --git a/chrome/utility/importer/bookmark_html_reader.cc b/chrome/utility/importer/bookmark_html_reader.cc
--- a/chrome/utility/importer/bookmark_html_reader.cc
+++ b/chrome/utility/importer/bookmark_html_reader.cc
@@ -17,7 +17,9 @@
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/common/importer/imported_bookmark_entry.h"
+#if !defined(OS_ANDROID)
#include "chrome/utility/importer/favicon_reencode.h"
+#endif
#include "components/search_engines/search_terms_data.h"
#include "components/search_engines/template_url.h"
#include "net/base/data_url.h"
@@ -56,6 +58,7 @@ bool GetAttribute(const std::string& attribute_list,
return true;
}
+#if !defined(OS_ANDROID)
// Given the URL of a page and a favicon data URL, adds an appropriate record
// to the given favicon usage vector.
void DataURLToFaviconUsage(const GURL& link_url,
@@ -86,6 +89,7 @@ void DataURLToFaviconUsage(const GURL& link_url,
favicons->push_back(usage);
}
+#endif
} // namespace
@@ -108,12 +112,10 @@ static std::string stripDt(const std::string& lineDt) {
void ImportBookmarksFile(
const base::Callback<bool(void)>& cancellation_callback,
const base::Callback<bool(const GURL&)>& valid_url_callback,
- const base::FilePath& file_path,
+ const std::string& content,
std::vector<ImportedBookmarkEntry>* bookmarks,
std::vector<importer::SearchEngineInfo>* search_engines,
favicon_base::FaviconUsageDataList* favicons) {
- std::string content;
- base::ReadFileToString(file_path, &content);
std::vector<std::string> lines = base::SplitString(
content, "\n", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
@@ -126,6 +128,7 @@ void ImportBookmarksFile(
std::vector<base::string16> path;
size_t toolbar_folder_index = 0;
std::string charset = "UTF-8"; // If no charset is specified, assume utf-8.
+
for (size_t i = 0;
i < lines.size() &&
(cancellation_callback.is_null() || !cancellation_callback.Run());
@@ -218,10 +221,12 @@ void ImportBookmarksFile(
}
bookmarks->push_back(entry);
+#if !defined(OS_ANDROID)
// Save the favicon. DataURLToFaviconUsage will handle the case where
// there is no favicon.
if (favicons)
DataURLToFaviconUsage(url, favicon, favicons);
+#endif
continue;
}
@@ -278,6 +283,22 @@ void ImportBookmarksFile(
}
}
+void ImportBookmarksFile(
+ const base::Callback<bool(void)>& cancellation_callback,
+ const base::Callback<bool(const GURL&)>& valid_url_callback,
+ const base::FilePath& file_path,
+ std::vector<ImportedBookmarkEntry>* bookmarks,
+ std::vector<importer::SearchEngineInfo>* search_engines,
+ favicon_base::FaviconUsageDataList* favicons) {
+ std::string content;
+ if (!base::ReadFileToString(file_path, &content)) {
+ LOG(ERROR) << "Could not directly read bookmarks import file";
+ return;
+ }
+
+ ImportBookmarksFile(cancellation_callback, valid_url_callback, content, bookmarks, search_engines, favicons);
+}
+
bool CanImportURLAsSearchEngine(const GURL& url,
std::string* search_engine_url) {
std::string url_spec = url.possibly_invalid_spec();
diff --git a/chrome/utility/importer/bookmark_html_reader.h b/chrome/utility/importer/bookmark_html_reader.h
--- a/chrome/utility/importer/bookmark_html_reader.h
+++ b/chrome/utility/importer/bookmark_html_reader.h
@@ -51,6 +51,15 @@ void ImportBookmarksFile(
std::vector<importer::SearchEngineInfo>* search_engines,
favicon_base::FaviconUsageDataList* favicons);
+void ImportBookmarksFile(
+ const base::Callback<bool(void)>& cancellation_callback,
+ const base::Callback<bool(const GURL&)>& valid_url_callback,
+ const std::string& content,
+ std::vector<ImportedBookmarkEntry>* bookmarks,
+ std::vector<importer::SearchEngineInfo>* search_engines,
+ favicon_base::FaviconUsageDataList* favicons);
+
+
// Returns true if |url| should be imported as a search engine, i.e. because it
// has replacement terms. Chrome treats such bookmarks as search engines rather
// than true bookmarks.
--
2.7.4