Commit 23e967ba authored by Mark Pilgrim's avatar Mark Pilgrim Committed by Commit Bot

Migrate ServicesCustomizationDocument to SimpleURLLoader

Bug: 773295
Change-Id: Id129cea8341c14bd8da4b5374034423223f03859
Reviewed-on: https://chromium-review.googlesource.com/884063
Commit-Queue: Mark Pilgrim <pilgrim@chromium.org>
Reviewed-by: default avatarJames Cook <jamescook@chromium.org>
Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Cr-Commit-Position: refs/heads/master@{#541884}
parent 125fa22c
...@@ -130,6 +130,7 @@ source_set("chromeos") { ...@@ -130,6 +130,7 @@ source_set("chromeos") {
"//components/viz/host", "//components/viz/host",
"//services/identity/public/cpp", "//services/identity/public/cpp",
"//services/metrics/public/cpp:ukm_builders", "//services/metrics/public/cpp:ukm_builders",
"//services/network:network_service",
"//services/resource_coordinator/public/cpp:resource_coordinator_cpp", "//services/resource_coordinator/public/cpp:resource_coordinator_cpp",
"//third_party/fontconfig", "//third_party/fontconfig",
"//third_party/metrics_proto", "//third_party/metrics_proto",
......
...@@ -27,6 +27,7 @@ include_rules = [ ...@@ -27,6 +27,7 @@ include_rules = [
"+mojo/edk/embedder", "+mojo/edk/embedder",
"+services/device/public", "+services/device/public",
"+services/metrics/public", "+services/metrics/public",
"+services/network",
"+services/tracing/public", "+services/tracing/public",
"+services/viz/public/interfaces", "+services/viz/public/interfaces",
# Chromeos should not use ozone directly, it must go through mojo as ozone # Chromeos should not use ozone directly, it must go through mojo as ozone
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include "chrome/browser/chromeos/net/delay_network_call.h" #include "chrome/browser/chromeos/net/delay_network_call.h"
#include "chrome/browser/extensions/external_loader.h" #include "chrome/browser/extensions/external_loader.h"
#include "chrome/browser/extensions/external_provider_impl.h" #include "chrome/browser/extensions/external_provider_impl.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/app_list/app_list_syncable_service.h" #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
...@@ -44,11 +45,14 @@ ...@@ -44,11 +45,14 @@
#include "components/prefs/pref_registry_simple.h" #include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_partition.h"
#include "extensions/common/extension_urls.h" #include "extensions/common/extension_urls.h"
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h" #include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/simple_url_loader.h"
#include "services/network/url_loader_factory.h"
namespace chromeos { namespace chromeos {
namespace { namespace {
...@@ -570,14 +574,40 @@ void ServicesCustomizationDocument::StartFileFetch() { ...@@ -570,14 +574,40 @@ void ServicesCustomizationDocument::StartFileFetch() {
} }
void ServicesCustomizationDocument::DoStartFileFetch() { void ServicesCustomizationDocument::DoStartFileFetch() {
url_fetcher_ = net::URLFetcher::Create(url_, net::URLFetcher::GET, this); net::NetworkTrafficAnnotationTag traffic_annotation =
url_fetcher_->SetRequestContext(g_browser_process->system_request_context()); net::DefineNetworkTrafficAnnotation("chromeos_customization_document", R"(
url_fetcher_->AddExtraRequestHeader("Accept: application/json"); semantics {
url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | sender: "Chrome OS Services Customization"
net::LOAD_DO_NOT_SAVE_COOKIES | description:
net::LOAD_DISABLE_CACHE | "Chrome OS downloads the OEM services customization manifest."
net::LOAD_DO_NOT_SEND_AUTH_DATA); trigger:
url_fetcher_->Start(); "When a public session starts on managed devices and an OEM "
"has uploaded a service customization document."
data:
"URL of the OEM service customization document. "
"No user information is sent."
destination: WEBSITE
}
policy {
cookies_allowed: NO
setting: "Unconditionally enabled on Chrome OS."
})");
auto resource_request = std::make_unique<network::ResourceRequest>();
resource_request->url = url_;
resource_request->load_flags =
net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES |
net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_AUTH_DATA;
resource_request->headers.SetHeader("Accept", "application/json");
simple_loader_ = network::SimpleURLLoader::Create(std::move(resource_request),
traffic_annotation);
network::mojom::URLLoaderFactory* loader_factory = url_loader_factory_;
if (!loader_factory) {
g_browser_process->system_network_context_manager()->GetURLLoaderFactory();
}
simple_loader_->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory,
base::BindOnce(&ServicesCustomizationDocument::OnSimpleLoaderComplete,
base::Unretained(this)));
} }
bool ServicesCustomizationDocument::LoadManifestFromString( bool ServicesCustomizationDocument::LoadManifestFromString(
...@@ -609,26 +639,30 @@ void ServicesCustomizationDocument::OnManifestLoaded() { ...@@ -609,26 +639,30 @@ void ServicesCustomizationDocument::OnManifestLoaded() {
} }
} }
void ServicesCustomizationDocument::OnURLFetchComplete( void ServicesCustomizationDocument::OnSimpleLoaderComplete(
const net::URLFetcher* source) { std::unique_ptr<std::string> response_body) {
std::string mime_type; int response_code = 0;
std::string data; bool retry = true;
if (source->GetStatus().is_success() && if (simple_loader_->ResponseInfo() &&
source->GetResponseCode() == net::HTTP_OK && simple_loader_->ResponseInfo()->headers) {
source->GetResponseHeaders()->GetMimeType(&mime_type) && response_code = simple_loader_->ResponseInfo()->headers->response_code();
mime_type == "application/json" && std::string mime_type;
source->GetResponseAsString(&data)) { simple_loader_->ResponseInfo()->headers->GetMimeType(&mime_type);
LoadManifestFromString(data); if (mime_type == "application/json" and response_body) {
} else if (source->GetResponseCode() == net::HTTP_NOT_FOUND) { LoadManifestFromString(*response_body);
LOG(ERROR) << "Customization manifest is missing on server: " retry = false;
<< source->GetURL().spec(); } else if (response_code == net::HTTP_NOT_FOUND) {
OnCustomizationNotFound(); LOG(ERROR) << "Customization manifest is missing on server: "
} else { << url_.spec();
OnCustomizationNotFound();
retry = false;
}
}
if (retry) {
if (num_retries_ < kMaxFetchRetries) { if (num_retries_ < kMaxFetchRetries) {
num_retries_++; num_retries_++;
content::BrowserThread::PostDelayedTask( content::BrowserThread::PostDelayedTask(
content::BrowserThread::UI, content::BrowserThread::UI, FROM_HERE,
FROM_HERE,
base::Bind(&ServicesCustomizationDocument::StartFileFetch, base::Bind(&ServicesCustomizationDocument::StartFileFetch,
weak_ptr_factory_.GetWeakPtr()), weak_ptr_factory_.GetWeakPtr()),
base::TimeDelta::FromSeconds(kRetriesDelayInSec)); base::TimeDelta::FromSeconds(kRetriesDelayInSec));
...@@ -636,8 +670,8 @@ void ServicesCustomizationDocument::OnURLFetchComplete( ...@@ -636,8 +670,8 @@ void ServicesCustomizationDocument::OnURLFetchComplete(
} }
// This doesn't stop fetching manifest on next restart. // This doesn't stop fetching manifest on next restart.
LOG(ERROR) << "URL fetch for services customization failed:" LOG(ERROR) << "URL fetch for services customization failed:"
<< " response code = " << source->GetResponseCode() << " response code = " << response_code
<< " URL = " << source->GetURL().spec(); << " URL = " << url_.spec();
LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL); LogManifestLoadResult(HISTOGRAM_LOAD_RESULT_RETRIES_FAIL);
} }
...@@ -777,8 +811,8 @@ void ServicesCustomizationDocument::SetOemFolderName( ...@@ -777,8 +811,8 @@ void ServicesCustomizationDocument::SetOemFolderName(
std::string ServicesCustomizationDocument::GetOemAppsFolderNameImpl( std::string ServicesCustomizationDocument::GetOemAppsFolderNameImpl(
const std::string& locale, const std::string& locale,
const base::DictionaryValue& root) const { const base::DictionaryValue& root) const {
return GetLocaleSpecificStringImpl( return GetLocaleSpecificStringImpl(&root, locale, kLocalizedContent,
&root, locale, kLocalizedContent, kDefaultAppsFolderName); kDefaultAppsFolderName);
} }
// static // static
...@@ -851,10 +885,9 @@ void ServicesCustomizationDocument::CheckAndApplyWallpaper() { ...@@ -851,10 +885,9 @@ void ServicesCustomizationDocument::CheckAndApplyWallpaper() {
std::unique_ptr<bool> exists(new bool(false)); std::unique_ptr<bool> exists(new bool(false));
base::Closure check_file_exists = base::Closure check_file_exists = base::Bind(
base::Bind(&CheckWallpaperCacheExists, &CheckWallpaperCacheExists, GetCustomizedWallpaperDownloadedFileName(),
GetCustomizedWallpaperDownloadedFileName(), base::Unretained(exists.get()));
base::Unretained(exists.get()));
base::Closure on_checked_closure = base::Bind( base::Closure on_checked_closure = base::Bind(
&ServicesCustomizationDocument::OnCheckedWallpaperCacheExists, &ServicesCustomizationDocument::OnCheckedWallpaperCacheExists,
weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(exists)), weak_ptr_factory_.GetWeakPtr(), base::Passed(std::move(exists)),
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "base/memory/singleton.h" #include "base/memory/singleton.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/values.h" #include "base/values.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "url/gurl.h" #include "url/gurl.h"
class PrefRegistrySimple; class PrefRegistrySimple;
...@@ -32,8 +31,14 @@ namespace extensions { ...@@ -32,8 +31,14 @@ namespace extensions {
class ExternalLoader; class ExternalLoader;
} }
namespace net { namespace network {
class URLFetcher; class SimpleURLLoader;
}
namespace network {
namespace mojom {
class URLLoaderFactory;
}
} }
namespace user_prefs { namespace user_prefs {
...@@ -141,8 +146,7 @@ class StartupCustomizationDocument : public CustomizationDocument { ...@@ -141,8 +146,7 @@ class StartupCustomizationDocument : public CustomizationDocument {
// outside this class by calling StartFetching() or EnsureCustomizationApplied() // outside this class by calling StartFetching() or EnsureCustomizationApplied()
// methods. // methods.
// User of the file should check IsReady before use it. // User of the file should check IsReady before use it.
class ServicesCustomizationDocument : public CustomizationDocument, class ServicesCustomizationDocument : public CustomizationDocument {
private net::URLFetcherDelegate {
public: public:
static ServicesCustomizationDocument* GetInstance(); static ServicesCustomizationDocument* GetInstance();
...@@ -200,6 +204,11 @@ class ServicesCustomizationDocument : public CustomizationDocument, ...@@ -200,6 +204,11 @@ class ServicesCustomizationDocument : public CustomizationDocument,
return wallpaper_downloader_.get(); return wallpaper_downloader_.get();
} }
void SetURLLoaderFactoryForTesting(
network::mojom::URLLoaderFactory* url_loader_factory) {
url_loader_factory_ = url_loader_factory;
}
private: private:
friend struct base::DefaultSingletonTraits<ServicesCustomizationDocument>; friend struct base::DefaultSingletonTraits<ServicesCustomizationDocument>;
FRIEND_TEST_ALL_PREFIXES(CustomizationWallpaperDownloaderBrowserTest, FRIEND_TEST_ALL_PREFIXES(CustomizationWallpaperDownloaderBrowserTest,
...@@ -227,8 +236,7 @@ class ServicesCustomizationDocument : public CustomizationDocument, ...@@ -227,8 +236,7 @@ class ServicesCustomizationDocument : public CustomizationDocument,
// Overriden from CustomizationDocument: // Overriden from CustomizationDocument:
bool LoadManifestFromString(const std::string& manifest) override; bool LoadManifestFromString(const std::string& manifest) override;
// Overriden from net::URLFetcherDelegate: void OnSimpleLoaderComplete(std::unique_ptr<std::string> response_body);
void OnURLFetchComplete(const net::URLFetcher* source) override;
// Initiate file fetching. Wait for online status. // Initiate file fetching. Wait for online status.
void StartFileFetch(); void StartFileFetch();
...@@ -293,9 +301,6 @@ class ServicesCustomizationDocument : public CustomizationDocument, ...@@ -293,9 +301,6 @@ class ServicesCustomizationDocument : public CustomizationDocument,
// Services customization manifest URL. // Services customization manifest URL.
GURL url_; GURL url_;
// URLFetcher instance.
std::unique_ptr<net::URLFetcher> url_fetcher_;
// How many times we already tried to fetch customization manifest file. // How many times we already tried to fetch customization manifest file.
int num_retries_; int num_retries_;
...@@ -309,6 +314,7 @@ class ServicesCustomizationDocument : public CustomizationDocument, ...@@ -309,6 +314,7 @@ class ServicesCustomizationDocument : public CustomizationDocument,
ExternalLoaders external_loaders_; ExternalLoaders external_loaders_;
std::unique_ptr<CustomizationWallpaperDownloader> wallpaper_downloader_; std::unique_ptr<CustomizationWallpaperDownloader> wallpaper_downloader_;
std::unique_ptr<network::SimpleURLLoader> simple_loader_;
// This is barrier until customization is applied. // This is barrier until customization is applied.
// When number of finished tasks match number of started - customization is // When number of finished tasks match number of started - customization is
...@@ -321,6 +327,9 @@ class ServicesCustomizationDocument : public CustomizationDocument, ...@@ -321,6 +327,9 @@ class ServicesCustomizationDocument : public CustomizationDocument,
// successfully. // successfully.
size_t apply_tasks_success_; size_t apply_tasks_success_;
// Only used for unit tests. Not owned.
network::mojom::URLLoaderFactory* url_loader_factory_;
// Weak factory for callbacks. // Weak factory for callbacks.
base::WeakPtrFactory<ServicesCustomizationDocument> weak_ptr_factory_; base::WeakPtrFactory<ServicesCustomizationDocument> weak_ptr_factory_;
......
...@@ -32,13 +32,10 @@ ...@@ -32,13 +32,10 @@
#include "extensions/common/manifest.h" #include "extensions/common/manifest.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "net/url_request/test_url_fetcher_factory.h" #include "services/network/test/test_url_loader_factory.h"
#include "net/url_request/url_request_status.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using ::testing::Exactly;
using ::testing::Invoke;
using ::testing::Mock; using ::testing::Mock;
using ::testing::_; using ::testing::_;
using extensions::ExternalInstallInfoFile; using extensions::ExternalInstallInfoFile;
...@@ -159,30 +156,6 @@ TEST(StartupCustomizationDocumentTest, BadManifest) { ...@@ -159,30 +156,6 @@ TEST(StartupCustomizationDocumentTest, BadManifest) {
EXPECT_FALSE(customization.IsReady()); EXPECT_FALSE(customization.IsReady());
} }
class TestURLFetcherCallback {
public:
std::unique_ptr<net::FakeURLFetcher> CreateURLFetcher(
const GURL& url,
net::URLFetcherDelegate* d,
const std::string& response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
std::unique_ptr<net::FakeURLFetcher> fetcher(
new net::FakeURLFetcher(url, d, response_data, response_code, status));
OnRequestCreate(url, fetcher.get());
return fetcher;
}
MOCK_METHOD2(OnRequestCreate,
void(const GURL&, net::FakeURLFetcher*));
};
void AddMimeHeader(const GURL& url, net::FakeURLFetcher* fetcher) {
scoped_refptr<net::HttpResponseHeaders> download_headers =
new net::HttpResponseHeaders("");
download_headers->AddHeader("Content-Type: application/json");
fetcher->set_response_headers(download_headers);
}
class MockExternalProviderVisitor class MockExternalProviderVisitor
: public extensions::ExternalProviderInterface::VisitorInterface { : public extensions::ExternalProviderInterface::VisitorInterface {
public: public:
...@@ -203,11 +176,6 @@ class MockExternalProviderVisitor ...@@ -203,11 +176,6 @@ class MockExternalProviderVisitor
class ServicesCustomizationDocumentTest : public testing::Test { class ServicesCustomizationDocumentTest : public testing::Test {
protected: protected:
ServicesCustomizationDocumentTest()
: factory_(nullptr,
base::Bind(&TestURLFetcherCallback::CreateURLFetcher,
base::Unretained(&url_callback_))) {}
// testing::Test: // testing::Test:
void SetUp() override { void SetUp() override {
ServicesCustomizationDocument::InitializeForTesting(); ServicesCustomizationDocument::InitializeForTesting();
...@@ -258,25 +226,24 @@ class ServicesCustomizationDocumentTest : public testing::Test { ...@@ -258,25 +226,24 @@ class ServicesCustomizationDocumentTest : public testing::Test {
const std::string& manifest) { const std::string& manifest) {
GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl, GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl,
id.c_str())); id.c_str()));
factory_.SetFakeResponse(url, network::ResourceResponseHead head;
manifest, head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
net::HTTP_OK, head.headers->AddHeader("Content-Type: application/json");
net::URLRequestStatus::SUCCESS); network::URLLoaderCompletionStatus status;
EXPECT_CALL(url_callback_, OnRequestCreate(url, _)) status.decoded_body_length = manifest.size();
.Times(Exactly(1)) factory_.AddResponse(url, head, manifest, status);
.WillRepeatedly(Invoke(AddMimeHeader));
} }
void AddManifestNotFound(const std::string& id) { void AddManifestNotFound(const std::string& id) {
GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl, GURL url(base::StringPrintf(ServicesCustomizationDocument::kManifestUrl,
id.c_str())); id.c_str()));
factory_.SetFakeResponse(url, network::ResourceResponseHead head;
std::string(), head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
net::HTTP_NOT_FOUND, "HTTP/1.x 404 Not Found");
net::URLRequestStatus::SUCCESS); head.headers->AddHeader("Content-Type: application/json");
EXPECT_CALL(url_callback_, OnRequestCreate(url, _)) network::URLLoaderCompletionStatus status;
.Times(Exactly(1)) status.decoded_body_length = 0;
.WillRepeatedly(Invoke(AddMimeHeader)); factory_.AddResponse(url, head, "", status);
} }
std::unique_ptr<TestingProfile> CreateProfile() { std::unique_ptr<TestingProfile> CreateProfile() {
...@@ -291,13 +258,13 @@ class ServicesCustomizationDocumentTest : public testing::Test { ...@@ -291,13 +258,13 @@ class ServicesCustomizationDocumentTest : public testing::Test {
return profile_builder.Build(); return profile_builder.Build();
} }
network::TestURLLoaderFactory factory_;
private: private:
content::TestBrowserThreadBundle thread_bundle_; content::TestBrowserThreadBundle thread_bundle_;
system::ScopedFakeStatisticsProvider fake_statistics_provider_; system::ScopedFakeStatisticsProvider fake_statistics_provider_;
ScopedCrosSettingsTestHelper scoped_cros_settings_test_helper_; ScopedCrosSettingsTestHelper scoped_cros_settings_test_helper_;
TestingPrefServiceSimple local_state_; TestingPrefServiceSimple local_state_;
TestURLFetcherCallback url_callback_;
net::FakeURLFetcherFactory factory_;
NetworkPortalDetectorTestImpl network_portal_detector_; NetworkPortalDetectorTestImpl network_portal_detector_;
}; };
...@@ -309,6 +276,7 @@ TEST_F(ServicesCustomizationDocumentTest, Basic) { ...@@ -309,6 +276,7 @@ TEST_F(ServicesCustomizationDocumentTest, Basic) {
ServicesCustomizationDocument::GetInstance(); ServicesCustomizationDocument::GetInstance();
EXPECT_FALSE(doc->IsReady()); EXPECT_FALSE(doc->IsReady());
doc->SetURLLoaderFactoryForTesting(&factory_);
doc->StartFetching(); doc->StartFetching();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(doc->IsReady()); EXPECT_TRUE(doc->IsReady());
...@@ -346,6 +314,7 @@ TEST_F(ServicesCustomizationDocumentTest, NoCustomizationIdInVpd) { ...@@ -346,6 +314,7 @@ TEST_F(ServicesCustomizationDocumentTest, NoCustomizationIdInVpd) {
ServicesCustomizationDocument::GetInstance(); ServicesCustomizationDocument::GetInstance();
EXPECT_FALSE(doc->IsReady()); EXPECT_FALSE(doc->IsReady());
doc->SetURLLoaderFactoryForTesting(&factory_);
std::unique_ptr<TestingProfile> profile = CreateProfile(); std::unique_ptr<TestingProfile> profile = CreateProfile();
extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get()); extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
EXPECT_TRUE(loader); EXPECT_TRUE(loader);
...@@ -382,6 +351,7 @@ TEST_F(ServicesCustomizationDocumentTest, DefaultApps) { ...@@ -382,6 +351,7 @@ TEST_F(ServicesCustomizationDocumentTest, DefaultApps) {
ServicesCustomizationDocument::GetInstance(); ServicesCustomizationDocument::GetInstance();
EXPECT_FALSE(doc->IsReady()); EXPECT_FALSE(doc->IsReady());
doc->SetURLLoaderFactoryForTesting(&factory_);
std::unique_ptr<TestingProfile> profile = CreateProfile(); std::unique_ptr<TestingProfile> profile = CreateProfile();
extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get()); extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
EXPECT_TRUE(loader); EXPECT_TRUE(loader);
...@@ -432,6 +402,7 @@ TEST_F(ServicesCustomizationDocumentTest, CustomizationManifestNotFound) { ...@@ -432,6 +402,7 @@ TEST_F(ServicesCustomizationDocumentTest, CustomizationManifestNotFound) {
ServicesCustomizationDocument::GetInstance(); ServicesCustomizationDocument::GetInstance();
EXPECT_FALSE(doc->IsReady()); EXPECT_FALSE(doc->IsReady());
doc->SetURLLoaderFactoryForTesting(&factory_);
std::unique_ptr<TestingProfile> profile = CreateProfile(); std::unique_ptr<TestingProfile> profile = CreateProfile();
extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get()); extensions::ExternalLoader* loader = doc->CreateExternalLoader(profile.get());
EXPECT_TRUE(loader); EXPECT_TRUE(loader);
......
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