Commit 0637edbd authored by Nicolas Ouellet-Payeur's avatar Nicolas Ouellet-Payeur Committed by Commit Bot

[BrowserSwitcher] Download IE Enterprise Mode SiteList if configured

Adds the "browser_switcher.use_ie_sitelist" boolean pref. When set to
true, BrowserSwitcherService will download IE's sitelist after 60s.

Once the sitelist XML is downloaded, the rules are parsed and applied.

Bug: 884837
Change-Id: Ib7a6c374526c56c42265187667ea2d6febc3628b
Reviewed-on: https://chromium-review.googlesource.com/c/1286288
Commit-Queue: Nicolas Ouellet-Payeur <nicolaso@chromium.org>
Reviewed-by: default avatarRamin Halavati <rhalavati@chromium.org>
Reviewed-by: default avatarJulian Pastarmov <pastarmovj@chromium.org>
Cr-Commit-Position: refs/heads/master@{#603582}
parent 59816a6e
...@@ -25,11 +25,15 @@ const char kUrlList[] = "browser_switcher.url_list"; ...@@ -25,11 +25,15 @@ const char kUrlList[] = "browser_switcher.url_list";
// List of hosts that should not trigger a transition in either browser. // List of hosts that should not trigger a transition in either browser.
const char kUrlGreylist[] = "browser_switcher.url_greylist"; const char kUrlGreylist[] = "browser_switcher.url_greylist";
// If set to true, use the IE Enterprise Mode Sitelist policy.
const char kUseIeSitelist[] = "browser_switcher.use_ie_sitelist";
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterStringPref(prefs::kAlternativeBrowserPath, ""); registry->RegisterStringPref(prefs::kAlternativeBrowserPath, "");
registry->RegisterListPref(prefs::kAlternativeBrowserParameters); registry->RegisterListPref(prefs::kAlternativeBrowserParameters);
registry->RegisterListPref(prefs::kUrlList); registry->RegisterListPref(prefs::kUrlList);
registry->RegisterListPref(prefs::kUrlGreylist); registry->RegisterListPref(prefs::kUrlGreylist);
registry->RegisterBooleanPref(prefs::kUseIeSitelist, false);
} }
} // namespace prefs } // namespace prefs
......
...@@ -16,6 +16,7 @@ extern const char kAlternativeBrowserPath[]; ...@@ -16,6 +16,7 @@ extern const char kAlternativeBrowserPath[];
extern const char kAlternativeBrowserParameters[]; extern const char kAlternativeBrowserParameters[];
extern const char kUrlList[]; extern const char kUrlList[];
extern const char kUrlGreylist[]; extern const char kUrlGreylist[];
extern const char kUseIeSitelist[];
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry); void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
......
...@@ -4,17 +4,96 @@ ...@@ -4,17 +4,96 @@
#include "chrome/browser/browser_switcher/browser_switcher_service.h" #include "chrome/browser/browser_switcher/browser_switcher_service.h"
#include "build/build_config.h"
#include "chrome/browser/browser_switcher/alternative_browser_launcher.h" #include "chrome/browser/browser_switcher/alternative_browser_launcher.h"
#include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
#include "chrome/browser/browser_switcher/browser_switcher_sitelist.h" #include "chrome/browser/browser_switcher/browser_switcher_sitelist.h"
#include "chrome/browser/browser_switcher/ieem_sitelist_parser.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/simple_url_loader.h"
#if defined(OS_WIN)
#include "base/strings/utf_string_conversions.h"
#include "base/win/registry.h"
#endif
namespace browser_switcher { namespace browser_switcher {
BrowserSwitcherService::BrowserSwitcherService(PrefService* prefs) namespace {
: launcher_(nullptr), sitelist_(nullptr), prefs_(prefs) {
#if defined(OS_WIN)
const wchar_t kIeSiteListKey[] =
L"SOFTWARE\\Policies\\Microsoft\\Internet Explorer\\Main\\EnterpriseMode";
const wchar_t kIeSiteListValue[] = L"SiteList";
// How long to wait after |BrowserSwitcherService| is created before initiating
// the sitelist fetch.
const base::TimeDelta kFetchSitelistDelay = base::TimeDelta::FromSeconds(60);
// How many times to re-try fetching the XML file for the sitelist.
const int kFetchNumRetries = 1;
// TODO(nicolaso): Add chrome_policy for this annotation once the policy is
// implemented.
constexpr net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("browser_switcher_ieem_sitelist", R"(
semantics {
sender: "Browser Switcher"
description:
"BrowserSwitcher may download Internet Explorer's Enterprise Mode "
"SiteList XML, to load the list of URLs to open in an alternative "
"browser. This is often on the organization's intranet. For more "
"information on Internet Explorer's Enterprise Mode, see: "
"https://docs.microsoft.com/internet-explorer/ie11-deploy-guide"
"/what-is-enterprise-mode"
trigger:
"This happens only once per profile, 60s after the first page "
"starts loading. The request may be retried once if it failed the "
"first time."
data:
"An HTTP or HTTPS GET request to the URL configured in Internet "
"Explorer's SiteList policy."
destination: OTHER
destination_other:
"URL configured in Internet Explorer's SiteList policy."
}
policy {
cookies_allowed: NO
setting: "This feature cannot be disabled by settings."
policy_exception_justification:
"This feature is still in development, and is disabled by default."
})");
#endif
} // namespace
BrowserSwitcherService::BrowserSwitcherService(Profile* profile)
: launcher_(nullptr), sitelist_(nullptr), prefs_(profile->GetPrefs()) {
DCHECK(profile);
DCHECK(prefs_); DCHECK(prefs_);
#if defined(OS_WIN)
if (prefs_->GetBoolean(prefs::kUseIeSitelist)) {
GURL sitelist_url = GetIeemSitelistUrl();
if (sitelist_url.is_valid()) {
auto factory =
content::BrowserContext::GetDefaultStoragePartition(profile)
->GetURLLoaderFactoryForBrowserProcess();
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE,
base::BindOnce(&BrowserSwitcherService::FetchIeemSitelist,
base::Unretained(this), std::move(sitelist_url),
std::move(factory)),
fetch_sitelist_delay_);
}
} else {
DoneLoadingIeemSitelist();
}
#endif
} }
BrowserSwitcherService::~BrowserSwitcherService() {} BrowserSwitcherService::~BrowserSwitcherService() {}
...@@ -41,4 +120,92 @@ void BrowserSwitcherService::SetSitelistForTesting( ...@@ -41,4 +120,92 @@ void BrowserSwitcherService::SetSitelistForTesting(
sitelist_ = std::move(sitelist); sitelist_ = std::move(sitelist);
} }
#if defined(OS_WIN)
base::TimeDelta BrowserSwitcherService::fetch_sitelist_delay_ =
kFetchSitelistDelay;
// static
void BrowserSwitcherService::SetIeemFetchDelayForTesting(
base::TimeDelta delay) {
fetch_sitelist_delay_ = delay;
}
base::OnceCallback<void()>
BrowserSwitcherService::xml_parsed_callback_for_testing_;
// static
void BrowserSwitcherService::SetXmlParsedCallbackForTesting(
base::OnceCallback<void()> callback) {
xml_parsed_callback_for_testing_ = std::move(callback);
}
GURL BrowserSwitcherService::ieem_sitelist_url_for_testing_;
// static
void BrowserSwitcherService::SetIeemSitelistUrlForTesting(const GURL& url) {
ieem_sitelist_url_for_testing_ = url;
}
GURL BrowserSwitcherService::GetIeemSitelistUrl() {
if (!ieem_sitelist_url_for_testing_.is_empty())
return ieem_sitelist_url_for_testing_;
base::win::RegKey key;
if (ERROR_SUCCESS != key.Open(HKEY_LOCAL_MACHINE, kIeSiteListKey, KEY_READ) &&
ERROR_SUCCESS != key.Open(HKEY_CURRENT_USER, kIeSiteListKey, KEY_READ)) {
return GURL();
}
std::wstring url_string;
if (ERROR_SUCCESS != key.ReadValue(kIeSiteListValue, &url_string))
return GURL();
return GURL(base::UTF16ToUTF8(url_string));
}
void BrowserSwitcherService::FetchIeemSitelist(
GURL url,
scoped_refptr<network::SharedURLLoaderFactory> factory) {
DCHECK(factory);
DCHECK(!url_loader_);
auto request = std::make_unique<network::ResourceRequest>();
request->url = url;
request->load_flags =
(net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DISABLE_CACHE);
url_loader_ =
network::SimpleURLLoader::Create(std::move(request), traffic_annotation);
url_loader_->SetRetryOptions(
kFetchNumRetries,
network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
url_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
factory.get(), base::BindOnce(&BrowserSwitcherService::ParseXml,
base::Unretained(this)));
}
void BrowserSwitcherService::ParseXml(std::unique_ptr<std::string> bytes) {
if (!bytes) {
DoneLoadingIeemSitelist();
return;
}
ParseIeemXml(*bytes,
base::BindOnce(&BrowserSwitcherService::OnIeemSitelistXmlParsed,
base::Unretained(this)));
}
void BrowserSwitcherService::OnIeemSitelistXmlParsed(ParsedXml xml) {
if (xml.error) {
LOG(ERROR) << "Unable to parse IEEM SiteList: " << *xml.error;
} else {
VLOG(2) << "Done parsing IEEM SiteList. "
<< "Applying rules to future navigations.";
sitelist()->SetIeemSitelist(std::move(xml));
}
DoneLoadingIeemSitelist();
}
void BrowserSwitcherService::DoneLoadingIeemSitelist() {
if (xml_parsed_callback_for_testing_)
std::move(xml_parsed_callback_for_testing_).Run();
}
#endif
} // namespace browser_switcher } // namespace browser_switcher
...@@ -5,22 +5,33 @@ ...@@ -5,22 +5,33 @@
#ifndef CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_ #ifndef CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_
#define CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_ #define CHROME_BROWSER_BROWSER_SWITCHER_BROWSER_SWITCHER_SERVICE_H_
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "url/gurl.h"
#include <memory> #include <memory>
namespace network {
class SimpleURLLoader;
class SharedURLLoaderFactory;
} // namespace network
class PrefService; class PrefService;
class Profile;
namespace browser_switcher { namespace browser_switcher {
class AlternativeBrowserLauncher; class AlternativeBrowserLauncher;
class BrowserSwitcherSitelist; class BrowserSwitcherSitelist;
class ParsedXml;
// Manages resources that can be accessed from a |BrowserSwitcherTabHelper|. // Manages per-profile resources for BrowserSwitcher.
class BrowserSwitcherService : public KeyedService { class BrowserSwitcherService : public KeyedService {
public: public:
explicit BrowserSwitcherService(PrefService* prefs); explicit BrowserSwitcherService(Profile* profile);
~BrowserSwitcherService() override; ~BrowserSwitcherService() override;
AlternativeBrowserLauncher* launcher(); AlternativeBrowserLauncher* launcher();
...@@ -30,7 +41,43 @@ class BrowserSwitcherService : public KeyedService { ...@@ -30,7 +41,43 @@ class BrowserSwitcherService : public KeyedService {
std::unique_ptr<AlternativeBrowserLauncher> launcher); std::unique_ptr<AlternativeBrowserLauncher> launcher);
void SetSitelistForTesting(std::unique_ptr<BrowserSwitcherSitelist> sitelist); void SetSitelistForTesting(std::unique_ptr<BrowserSwitcherSitelist> sitelist);
#if defined(OS_WIN)
static void SetIeemFetchDelayForTesting(base::TimeDelta delay);
static void SetXmlParsedCallbackForTesting(
base::OnceCallback<void()> callback);
static void SetIeemSitelistUrlForTesting(const GURL& url);
#endif
private: private:
#if defined(OS_WIN)
// Returns the URL to fetch to get Internet Explorer's Enterprise Mode
// sitelist, based on policy. Returns an empty (invalid) URL if IE's SiteList
// policy is unset.
GURL GetIeemSitelistUrl();
// Steps to process the IEEM sitelist rules: fetch, parse, apply.
void FetchIeemSitelist(
GURL url,
scoped_refptr<network::SharedURLLoaderFactory> factory);
void ParseXml(std::unique_ptr<std::string> bytes);
void OnIeemSitelistXmlParsed(ParsedXml xml);
void DoneLoadingIeemSitelist();
// Delay for the IEEM XML fetch task, launched from the constructor.
static base::TimeDelta fetch_sitelist_delay_;
// URL to fetch the IEEM sitelist from. Only used for testing.
static GURL ieem_sitelist_url_for_testing_;
// If set, gets called once the IEEM sitelist rules are applied. Also gets
// called if any step of the process fails.
static base::OnceCallback<void()> xml_parsed_callback_for_testing_;
// Used to fetch the IEEM XML.
std::unique_ptr<network::SimpleURLLoader> url_loader_;
#endif
// Per-profile helpers.
std::unique_ptr<AlternativeBrowserLauncher> launcher_; std::unique_ptr<AlternativeBrowserLauncher> launcher_;
std::unique_ptr<BrowserSwitcherSitelist> sitelist_; std::unique_ptr<BrowserSwitcherSitelist> sitelist_;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/browser_switcher/browser_switcher_service.h"
#include "base/run_loop.h"
#include "base/test/test_timeouts.h"
#include "chrome/browser/browser_switcher/browser_switcher_prefs.h"
#include "chrome/browser/browser_switcher/browser_switcher_service_factory.h"
#include "chrome/browser/browser_switcher/browser_switcher_sitelist.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/url_loader_interceptor.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
namespace browser_switcher {
namespace {
const char kAValidUrl[] = "http://example.com/";
const char kAnInvalidUrl[] = "the quick brown fox jumps over the lazy dog";
bool ReturnValidXml(content::URLLoaderInterceptor::RequestParams* params) {
std::string headers = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";
std::string xml =
"<rules version=\"1\"><docMode><domain docMode=\"9\">"
"docs.google.com</domain></docMode></rules>";
content::URLLoaderInterceptor::WriteResponse(headers, xml,
params->client.get());
return true;
}
bool FailToDownload(content::URLLoaderInterceptor::RequestParams* params) {
std::string headers = "HTTP/1.1 500 Internal Server Error\n\n";
content::URLLoaderInterceptor::WriteResponse(headers, "",
params->client.get());
return true;
}
} // namespace
class BrowserSwitcherServiceTest : public InProcessBrowserTest {
public:
BrowserSwitcherServiceTest() = default;
~BrowserSwitcherServiceTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(BrowserSwitcherServiceTest);
};
IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, NotEnabledByPolicy) {
// Only load the IEEM sitelist if the 'use_ie_sitelist' pref is set to true.
browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseIeSitelist, false);
base::RunLoop run_loop;
BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta());
BrowserSwitcherService::SetXmlParsedCallbackForTesting(
run_loop.QuitClosure());
BrowserSwitcherService::SetIeemSitelistUrlForTesting(GURL(kAValidUrl));
bool fetch_happened = false;
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](bool* happened, content::URLLoaderInterceptor::RequestParams*) {
*happened = true;
return false;
},
&fetch_happened));
// Execute everything and make sure we didn't get to the fetch step.
BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile());
run_loop.Run();
EXPECT_FALSE(fetch_happened);
}
IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IeemSitelistInvalidUrl) {
// Only load the IEEM sitelist if the 'use_ie_sitelist' pref is set to true.
browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseIeSitelist, false);
base::RunLoop run_loop;
BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta());
BrowserSwitcherService::SetXmlParsedCallbackForTesting(
run_loop.QuitClosure());
BrowserSwitcherService::SetIeemSitelistUrlForTesting(GURL(kAnInvalidUrl));
bool fetch_happened = false;
content::URLLoaderInterceptor interceptor(base::BindRepeating(
[](bool* happened, content::URLLoaderInterceptor::RequestParams*) {
*happened = true;
return false;
},
&fetch_happened));
// Execute everything and make sure we didn't get to the fetch step.
BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile());
run_loop.Run();
EXPECT_FALSE(fetch_happened);
}
IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, FetchAndParseAfterStartup) {
browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseIeSitelist, true);
base::RunLoop run_loop;
BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta());
BrowserSwitcherService::SetXmlParsedCallbackForTesting(
run_loop.QuitClosure());
BrowserSwitcherService::SetIeemSitelistUrlForTesting(GURL(kAValidUrl));
content::URLLoaderInterceptor interceptor(
base::BindRepeating(ReturnValidXml));
// Execute everything and make sure the rules are applied correctly.
auto* service =
BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile());
run_loop.Run();
EXPECT_FALSE(service->sitelist()->ShouldSwitch(GURL("http://google.com/")));
EXPECT_TRUE(
service->sitelist()->ShouldSwitch(GURL("http://docs.google.com/")));
}
IN_PROC_BROWSER_TEST_F(BrowserSwitcherServiceTest, IgnoresFailedDownload) {
browser()->profile()->GetPrefs()->SetBoolean(prefs::kUseIeSitelist, true);
base::RunLoop run_loop;
BrowserSwitcherService::SetIeemFetchDelayForTesting(base::TimeDelta());
BrowserSwitcherService::SetXmlParsedCallbackForTesting(
run_loop.QuitClosure());
BrowserSwitcherService::SetIeemSitelistUrlForTesting(GURL(kAValidUrl));
content::URLLoaderInterceptor interceptor(
base::BindRepeating(FailToDownload));
// Execute everything and make sure no rules are applied.
auto* service =
BrowserSwitcherServiceFactory::GetForBrowserContext(browser()->profile());
run_loop.Run();
EXPECT_FALSE(service->sitelist()->ShouldSwitch(GURL("http://google.com/")));
EXPECT_FALSE(
service->sitelist()->ShouldSwitch(GURL("http://docs.google.com/")));
}
} // namespace browser_switcher
...@@ -35,8 +35,7 @@ BrowserSwitcherServiceFactory::~BrowserSwitcherServiceFactory() {} ...@@ -35,8 +35,7 @@ BrowserSwitcherServiceFactory::~BrowserSwitcherServiceFactory() {}
KeyedService* BrowserSwitcherServiceFactory::BuildServiceInstanceFor( KeyedService* BrowserSwitcherServiceFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const { content::BrowserContext* context) const {
return new BrowserSwitcherService( return new BrowserSwitcherService(Profile::FromBrowserContext(context));
Profile::FromBrowserContext(context)->GetPrefs());
} }
content::BrowserContext* BrowserSwitcherServiceFactory::GetBrowserContextToUse( content::BrowserContext* BrowserSwitcherServiceFactory::GetBrowserContextToUse(
......
...@@ -127,7 +127,7 @@ void ParseIeFileVersionTwo(const base::Value& xml, ParsedXml* result) { ...@@ -127,7 +127,7 @@ void ParseIeFileVersionTwo(const base::Value& xml, ParsedXml* result) {
} }
} }
void RawXmlParsed(ParseIeemXmlCallback callback, void RawXmlParsed(base::OnceCallback<void(ParsedXml)> callback,
std::unique_ptr<base::Value> xml, std::unique_ptr<base::Value> xml,
const base::Optional<std::string>& error) { const base::Optional<std::string>& error) {
if (error) { if (error) {
...@@ -163,7 +163,8 @@ ParsedXml::ParsedXml(std::vector<std::string>&& sitelist_, ...@@ -163,7 +163,8 @@ ParsedXml::ParsedXml(std::vector<std::string>&& sitelist_,
error(std::move(error_)) {} error(std::move(error_)) {}
ParsedXml::~ParsedXml() = default; ParsedXml::~ParsedXml() = default;
void ParseIeemXml(const std::string& xml, ParseIeemXmlCallback callback) { void ParseIeemXml(const std::string& xml,
base::OnceCallback<void(ParsedXml)> callback) {
data_decoder::ParseXml( data_decoder::ParseXml(
content::ServiceManagerConnection::GetForProcess()->GetConnector(), xml, content::ServiceManagerConnection::GetForProcess()->GetConnector(), xml,
base::BindOnce(&RawXmlParsed, std::move(callback))); base::BindOnce(&RawXmlParsed, std::move(callback)));
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "url/gurl.h"
namespace browser_switcher { namespace browser_switcher {
...@@ -29,12 +30,9 @@ class ParsedXml { ...@@ -29,12 +30,9 @@ class ParsedXml {
DISALLOW_COPY_AND_ASSIGN(ParsedXml); DISALLOW_COPY_AND_ASSIGN(ParsedXml);
}; };
// Callback type for the |ParseIeemXml()| method.
using ParseIeemXmlCallback = base::OnceCallback<void(ParsedXml)>;
// Parses the XML contained in |xml|, and calls |callback| with the parsed XML // Parses the XML contained in |xml|, and calls |callback| with the parsed XML
// result. // result.
void ParseIeemXml(const std::string& xml, ParseIeemXmlCallback callback); void ParseIeemXml(const std::string& xml, base::OnceCallback<void(ParsedXml)>);
} // namespace browser_switcher } // namespace browser_switcher
......
...@@ -1987,6 +1987,7 @@ test("browser_tests") { ...@@ -1987,6 +1987,7 @@ test("browser_tests") {
} }
if (is_win) { if (is_win) {
sources += [ sources += [
"../browser/browser_switcher/browser_switcher_service_browsertest.cc",
"../browser/extensions/api/networking_private/networking_private_credentials_getter_browsertest.cc", "../browser/extensions/api/networking_private/networking_private_credentials_getter_browsertest.cc",
"../browser/printing/pdf_to_emf_converter_browsertest.cc", "../browser/printing/pdf_to_emf_converter_browsertest.cc",
"../browser/ui/views/accessibility/invert_bubble_view_browsertest.cc", "../browser/ui/views/accessibility/invert_bubble_view_browsertest.cc",
......
...@@ -32,6 +32,7 @@ Refer to README.md for content description and update process. ...@@ -32,6 +32,7 @@ Refer to README.md for content description and update process.
<item id="blob_reader" hash_code="5154306" type="0" deprecated="2018-06-14" content_hash_code="39702178" file_path=""/> <item id="blob_reader" hash_code="5154306" type="0" deprecated="2018-06-14" content_hash_code="39702178" file_path=""/>
<item id="bluetooth_socket" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/> <item id="bluetooth_socket" hash_code="94099818" type="0" content_hash_code="30932349" os_list="linux,windows" file_path="device/bluetooth/bluetooth_socket_net.cc"/>
<item id="brandcode_config" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/> <item id="brandcode_config" hash_code="109679553" type="0" content_hash_code="128843792" os_list="linux,windows" file_path="chrome/browser/profile_resetter/brandcode_config_fetcher.cc"/>
<item id="browser_switcher_ieem_sitelist" hash_code="97159948" type="0" content_hash_code="9996111" os_list="windows" file_path="chrome/browser/browser_switcher/browser_switcher_service.cc"/>
<item id="captive_portal_service" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="chrome/browser/captive_portal/captive_portal_service.cc"/> <item id="captive_portal_service" hash_code="88754904" type="0" content_hash_code="70737580" os_list="linux,windows" file_path="chrome/browser/captive_portal/captive_portal_service.cc"/>
<item id="cast_channel_send" hash_code="103172229" type="0" deprecated="2018-08-23" content_hash_code="33946302" file_path=""/> <item id="cast_channel_send" hash_code="103172229" type="0" deprecated="2018-08-23" content_hash_code="33946302" file_path=""/>
<item id="cast_keep_alive_delegate" hash_code="134755844" type="0" deprecated="2018-08-23" content_hash_code="66118796" file_path=""/> <item id="cast_keep_alive_delegate" hash_code="134755844" type="0" deprecated="2018-08-23" content_hash_code="66118796" file_path=""/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment