Commit 76178d77 authored by Eugene But's avatar Eugene But Committed by Commit Bot

[PassKit refactoring] 1/4 PassKitTabHelper.

This is first refactoring CL for PassKit implementation based on ios/web
Download API.

Service CL: http://crrev.com/c/801916
UI CL: http://crrev.com/c/794302

Design doc: https://goto.google.com/ios-chrome-passkit

Bug: 787943
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Id5d3f42da40a9ee0da2c8532d646334e6af29917
Reviewed-on: https://chromium-review.googlesource.com/802080Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarGregory Chatzinoff <gchatz@chromium.org>
Commit-Queue: Eugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#521792}
parent 1ddc023a
......@@ -118,6 +118,7 @@ source_set("browser") {
"//ios/chrome/app/strings",
"//ios/chrome/browser/bookmarks:features",
"//ios/chrome/browser/browser_state",
"//ios/chrome/browser/download",
"//ios/chrome/browser/drag_and_drop",
"//ios/chrome/browser/payments:constants",
"//ios/chrome/browser/ssl:features",
......
# Copyright 2017 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.
source_set("download") {
sources = [
"pass_kit_tab_helper.h",
"pass_kit_tab_helper.mm",
"pass_kit_tab_helper_delegate.h",
]
deps = [
"//base",
"//ios/web/public",
"//ios/web/public/download",
]
libs = [ "PassKit.framework" ]
configs += [ "//build/config/compiler:enable_arc" ]
}
source_set("unit_tests") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"pass_kit_tab_helper_unittest.mm",
]
deps = [
":test_support",
"//base/test:test_support",
"//ios/chrome/browser/download",
"//ios/chrome/test/fakes",
"//ios/web/public/test/fakes",
"//net",
"//testing/gtest",
]
}
source_set("test_support") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"pass_kit_test_util.cc",
"pass_kit_test_util.h",
]
deps = [
"//base",
]
}
// Copyright 2017 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.
#ifndef IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_H_
#define IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_H_
#include <memory>
#include <set>
#include "base/macros.h"
#include "ios/web/public/download/download_task_observer.h"
#import "ios/web/public/web_state/web_state_user_data.h"
@protocol PassKitTabHelperDelegate;
namespace web {
class DownloadTask;
class WebState;
} // namespace web
// TabHelper which downloads pkpass file, constructs PKPass object and passes
// that PKPass to the delegate.
class PassKitTabHelper : public web::WebStateUserData<PassKitTabHelper>,
public web::DownloadTaskObserver {
public:
~PassKitTabHelper() override;
// Creates TabHelper. |delegate| is not retained by TabHelper. |web_state|
// must not be null.
static void CreateForWebState(web::WebState* web_state,
id<PassKitTabHelperDelegate> delegate);
// Asynchronously downloads pkpass file using the given |task|. Asks delegate
// to present "Add pkpass" dialog when the download is complete.
virtual void Download(std::unique_ptr<web::DownloadTask> task);
protected:
// Allow subclassing from PassKitTabHelper for testing purposes.
PassKitTabHelper(web::WebState* web_state,
id<PassKitTabHelperDelegate> delegate);
private:
// web::DownloadTaskObserver overrides:
void OnDownloadUpdated(web::DownloadTask* task) override;
web::WebState* web_state_;
__weak id<PassKitTabHelperDelegate> delegate_ = nil;
// Set of unfinished download tasks.
std::set<std::unique_ptr<web::DownloadTask>> tasks_;
DISALLOW_COPY_AND_ASSIGN(PassKitTabHelper);
};
#endif // IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_H_
// Copyright 2017 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.
#import "ios/chrome/browser/download/pass_kit_tab_helper.h"
#include <memory>
#include <string>
#import <PassKit/PassKit.h>
#include "base/memory/ptr_util.h"
#import "ios/chrome/browser/download/pass_kit_tab_helper_delegate.h"
#import "ios/web/public/download/download_task.h"
#include "net/url_request/url_fetcher_response_writer.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
DEFINE_WEB_STATE_USER_DATA_KEY(PassKitTabHelper);
PassKitTabHelper::PassKitTabHelper(web::WebState* web_state,
id<PassKitTabHelperDelegate> delegate)
: web_state_(web_state), delegate_(delegate) {
DCHECK(web_state_);
DCHECK(delegate_);
}
PassKitTabHelper::~PassKitTabHelper() {
for (auto& task : tasks_) {
task->RemoveObserver(this);
}
}
void PassKitTabHelper::CreateForWebState(
web::WebState* web_state,
id<PassKitTabHelperDelegate> delegate) {
DCHECK(web_state);
if (!FromWebState(web_state)) {
web_state->SetUserData(UserDataKey(), base::WrapUnique(new PassKitTabHelper(
web_state, delegate)));
}
}
void PassKitTabHelper::Download(std::unique_ptr<web::DownloadTask> task) {
DCHECK_EQ(task->GetMimeType(), "application/vnd.apple.pkpass");
web::DownloadTask* task_ptr = task.get();
// Start may call OnDownloadUpdated immediately, so add the task to the set of
// unfinished tasks.
tasks_.insert(std::move(task));
task_ptr->AddObserver(this);
task_ptr->Start(std::make_unique<net::URLFetcherStringWriter>());
}
void PassKitTabHelper::OnDownloadUpdated(web::DownloadTask* updated_task) {
auto it = std::find_if(tasks_.begin(), tasks_.end(), [=](const auto& task) {
return task.get() == updated_task;
});
DCHECK(it != tasks_.end());
if (!updated_task->IsDone())
return;
net::URLFetcherResponseWriter* writer = updated_task->GetResponseWriter();
std::string data = writer->AsStringWriter()->data();
NSData* nsdata = [NSData dataWithBytes:data.c_str() length:data.size()];
PKPass* pass = [[PKPass alloc] initWithData:nsdata error:nil];
[delegate_ passKitTabHelper:this
presentDialogForPass:pass
webState:web_state_];
// TODO(crbug.com/789735): report UMA if passkit download was not sucessfull.
updated_task->RemoveObserver(this);
tasks_.erase(it);
}
// Copyright 2017 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.
#ifndef IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_DELEGATE_H_
#define IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_DELEGATE_H_
#import <Foundation/Foundation.h>
@class PKPass;
class PassKitTabHelper;
namespace web {
class WebState;
} // namespace web
// Delegate for PassKitTabHelper class.
@protocol PassKitTabHelperDelegate<NSObject>
// Called to present "Add pkpass" dialog. |pass| can be nil if PassKitTabHelper
// failed to download or parse pkpass file.
- (void)passKitTabHelper:(nonnull PassKitTabHelper*)tabHelper
presentDialogForPass:(nullable PKPass*)pass
webState:(nonnull web::WebState*)webState;
@end
#endif // IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TAB_HELPER_DELEGATE_H_
// Copyright 2017 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.
#import "ios/chrome/browser/download/pass_kit_tab_helper.h"
#include <memory>
#import <PassKit/PassKit.h>
#include "ios/chrome/browser/download/pass_kit_test_util.h"
#import "ios/chrome/test/fakes/fake_pass_kit_tab_helper_delegate.h"
#import "ios/web/public/test/fakes/fake_download_task.h"
#import "ios/web/public/test/fakes/test_web_state.h"
#include "net/base/io_buffer.h"
#include "net/url_request/url_fetcher_response_writer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/gtest_mac.h"
#include "testing/platform_test.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
char kUrl[] = "https://test.test/";
char kMimeType[] = "application/vnd.apple.pkpass";
// Used as no-op callback.
void DoNothing(int) {}
} // namespace
// Test fixture for testing PassKitTabHelper class.
class PassKitTabHelperTest : public PlatformTest {
protected:
PassKitTabHelperTest()
: delegate_([[FakePassKitTabHelperDelegate alloc]
initWithWebState:&web_state_]) {
PassKitTabHelper::CreateForWebState(&web_state_, delegate_);
}
PassKitTabHelper* tab_helper() {
return PassKitTabHelper::FromWebState(&web_state_);
}
web::TestWebState web_state_;
FakePassKitTabHelperDelegate* delegate_;
};
// Tests downloading empty pkpass file.
TEST_F(PassKitTabHelperTest, EmptyFile) {
auto task = std::make_unique<web::FakeDownloadTask>(GURL(kUrl), kMimeType);
web::FakeDownloadTask* task_ptr = task.get();
tab_helper()->Download(std::move(task));
task_ptr->SetDone(true);
EXPECT_EQ(1U, delegate_.passes.count);
EXPECT_TRUE([delegate_.passes.firstObject isKindOfClass:[NSNull class]]);
}
// Tests downloading 2 empty pkpass files.
TEST_F(PassKitTabHelperTest, MultipleEmptyFiles) {
auto task = std::make_unique<web::FakeDownloadTask>(GURL(kUrl), kMimeType);
web::FakeDownloadTask* task_ptr = task.get();
tab_helper()->Download(std::move(task));
auto task2 = std::make_unique<web::FakeDownloadTask>(GURL(kUrl), kMimeType);
web::FakeDownloadTask* task_ptr2 = task2.get();
tab_helper()->Download(std::move(task2));
task_ptr->SetDone(true);
EXPECT_EQ(1U, delegate_.passes.count);
EXPECT_TRUE([delegate_.passes.firstObject isKindOfClass:[NSNull class]]);
task_ptr2->SetDone(true);
EXPECT_EQ(2U, delegate_.passes.count);
EXPECT_TRUE([delegate_.passes.lastObject isKindOfClass:[NSNull class]]);
}
// Tests downloading a valid pkpass file.
TEST_F(PassKitTabHelperTest, ValidPassKitFile) {
auto task = std::make_unique<web::FakeDownloadTask>(GURL(kUrl), kMimeType);
web::FakeDownloadTask* task_ptr = task.get();
tab_helper()->Download(std::move(task));
std::string pass_data = testing::GetTestPass();
auto buffer = base::MakeRefCounted<net::IOBuffer>(pass_data.size());
memcpy(buffer->data(), pass_data.c_str(), pass_data.size());
// Writing to URLFetcherStringWriter, which is used by PassKitTabHelper is
// synchronous, so it's ok to ignore Write's completion callback.
task_ptr->GetResponseWriter()->Write(buffer.get(), pass_data.size(),
base::BindRepeating(&DoNothing));
task_ptr->SetDone(true);
EXPECT_EQ(1U, delegate_.passes.count);
PKPass* pass = delegate_.passes.firstObject;
EXPECT_TRUE([pass isKindOfClass:[PKPass class]]);
EXPECT_EQ(PKPassTypeBarcode, pass.passType);
EXPECT_NSEQ(@"pass.com.apple.devpubs.example", pass.passTypeIdentifier);
EXPECT_NSEQ(@"Toy Town", pass.organizationName);
}
// Copyright 2017 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 "ios/chrome/browser/download/pass_kit_test_util.h"
#include "base/base_paths.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/path_service.h"
namespace testing {
std::string GetTestPass() {
base::FilePath path;
base::PathService::Get(base::DIR_MODULE, &path);
const char kFilePath[] = "ios/testing/data/http_server_files/generic.pkpass";
path = path.Append(FILE_PATH_LITERAL(kFilePath));
base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
char pass_kit_data[file.GetLength()];
file.ReadAtCurrentPos(pass_kit_data, file.GetLength());
return std::string(pass_kit_data, file.GetLength());
}
} // namespace testing
// Copyright 2017 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.
#ifndef IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TEST_UTIL_H_
#define IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TEST_UTIL_H_
#include <string>
namespace testing {
// Returns the content of a test pkpass file.
std::string GetTestPass();
} // namespace testing
#endif // IOS_CHROME_BROWSER_DOWNLOAD_PASS_KIT_TEST_UTIL_H_
......@@ -64,6 +64,7 @@ source_set("eg_tests") {
"//base",
"//ios/chrome/app:app_internal",
"//ios/chrome/app/strings",
"//ios/chrome/browser/download:test_support",
"//ios/chrome/browser/ui:ui_internal",
"//ios/chrome/browser/ui:ui_util",
"//ios/chrome/test/app:test_support",
......
......@@ -5,11 +5,9 @@
#import <EarlGrey/EarlGrey.h>
#import <PassKit/PassKit.h>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/memory/ptr_util.h"
#include "base/path_service.h"
#import "ios/chrome/app/main_controller.h"
#include "ios/chrome/browser/download/pass_kit_test_util.h"
#import "ios/chrome/browser/ui/browser_view_controller.h"
#include "ios/chrome/browser/ui/ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
......@@ -31,8 +29,6 @@ using chrome_test_util::GetMainController;
namespace {
const char kPKFilePath[] = "ios/testing/data/http_server_files/generic.pkpass";
// Returns matcher for PassKit error infobar.
id<GREYMatcher> PassKitErrorInfobar() {
using l10n_util::GetNSStringWithFixup;
......@@ -40,17 +36,6 @@ id<GREYMatcher> PassKitErrorInfobar() {
return grey_accessibilityLabel(label);
}
// Returns the content of test pkpass file.
std::string GetTestPass() {
base::FilePath path;
base::PathService::Get(base::DIR_MODULE, &path);
path = path.Append(FILE_PATH_LITERAL(kPKFilePath));
base::File file(path, base::File::FLAG_OPEN | base::File::FLAG_READ);
char pass_kit_data[file.GetLength()];
file.ReadAtCurrentPos(pass_kit_data, file.GetLength());
return std::string(pass_kit_data, file.GetLength());
}
// PassKit landing page and download request handler.
std::unique_ptr<net::test_server::HttpResponse> GetResponse(
const net::test_server::HttpRequest& request) {
......@@ -66,7 +51,7 @@ std::unique_ptr<net::test_server::HttpResponse> GetResponse(
result->set_content("corrupted");
} else if (request.GetURL().path() == "/good") {
result->AddCustomHeader("Content-Type", "application/vnd.apple.pkpass");
result->set_content(GetTestPass());
result->set_content(testing::GetTestPass());
}
return result;
......
......@@ -141,6 +141,7 @@ test("ios_chrome_unittests") {
"//ios/chrome/browser/content_suggestions:unit_tests",
"//ios/chrome/browser/crash_report:unit_tests",
"//ios/chrome/browser/device_sharing:unit_tests",
"//ios/chrome/browser/download:unit_tests",
"//ios/chrome/browser/drag_and_drop:unit_tests",
"//ios/chrome/browser/favicon:unit_tests",
"//ios/chrome/browser/find_in_page:unit_tests",
......
# Copyright 2017 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.
source_set("fakes") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
sources = [
"fake_pass_kit_tab_helper_delegate.h",
"fake_pass_kit_tab_helper_delegate.mm",
]
deps = [
"//ios/chrome/browser/download",
"//ios/web/public",
]
libs = [ "Foundation.framework" ]
}
// Copyright 2017 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.
#ifndef IOS_CHROME_TEST_FAKES_FAKE_PASS_KIT_TAB_HELPER_DELEGATE_H_
#define IOS_CHROME_TEST_FAKES_FAKE_PASS_KIT_TAB_HELPER_DELEGATE_H_
#import <Foundation/Foundation.h>
#import "ios/chrome/browser/download/pass_kit_tab_helper_delegate.h"
namespace web {
class WebState;
} // namespace web
// PassKitTabHelperDelegate which collects all passes into |passes| array.
@interface FakePassKitTabHelperDelegate : NSObject<PassKitTabHelperDelegate>
- (instancetype)initWithWebState:(web::WebState*)webState
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
// All passes presented by PassKitTabHelper. nil passes are represented with
// NSNull objects.
@property(nonatomic, readonly) NSArray* passes;
@end
#endif // IOS_CHROME_TEST_FAKES_FAKE_PASS_KIT_TAB_HELPER_DELEGATE_H_
// Copyright 2017 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.
#import "ios/chrome/test/fakes/fake_pass_kit_tab_helper_delegate.h"
#import "ios/chrome/browser/download/pass_kit_tab_helper.h"
#import "ios/web/public/web_state/web_state.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
@implementation FakePassKitTabHelperDelegate {
web::WebState* _webState;
NSMutableArray* _passes;
}
- (instancetype)initWithWebState:(web::WebState*)webState {
self = [super init];
if (self) {
_webState = webState;
_passes = [NSMutableArray array];
}
return self;
}
- (NSArray*)passes {
return [_passes copy];
}
- (void)passKitTabHelper:(nonnull PassKitTabHelper*)tabHelper
presentDialogForPass:(nullable PKPass*)pass
webState:(nonnull web::WebState*)webState {
DCHECK_EQ(_webState, webState);
DCHECK_EQ(PassKitTabHelper::FromWebState(_webState), tabHelper);
if (pass) {
[_passes addObject:pass];
} else {
[_passes addObject:[NSNull null]];
}
}
@end
......@@ -27,6 +27,8 @@ source_set("fakes") {
"crw_test_web_state_observer.mm",
"fake_download_controller_delegate.h",
"fake_download_controller_delegate.mm",
"fake_download_task.h",
"fake_download_task.mm",
"fake_navigation_context.h",
"fake_navigation_context.mm",
"test_browser_state.cc",
......
// Copyright 2017 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.
#ifndef IOS_WEB_PUBLIC_TEST_FAKES_FAKE_DOWNLOAD_TASK_H_
#define IOS_WEB_PUBLIC_TEST_FAKES_FAKE_DOWNLOAD_TASK_H_
#include <string>
#include "base/macros.h"
#include "base/observer_list.h"
#import "ios/web/public/download/download_task.h"
#include "url/gurl.h"
namespace web {
// Fake implementation for DownloadTask interface. Can be used for testing.
class FakeDownloadTask : public DownloadTask {
public:
FakeDownloadTask(const GURL& original_url, const std::string& mime_type);
~FakeDownloadTask() override;
// DownloadTask overrides:
void Start(std::unique_ptr<net::URLFetcherResponseWriter> writer) override;
net::URLFetcherResponseWriter* GetResponseWriter() const override;
NSString* GetIndentifier() const override;
const GURL& GetOriginalUrl() const override;
bool IsDone() const override;
int GetErrorCode() const override;
int64_t GetTotalBytes() const override;
int GetPercentComplete() const override;
std::string GetContentDisposition() const override;
std::string GetMimeType() const override;
base::string16 GetSuggestedFilename() const override;
void AddObserver(DownloadTaskObserver* observer) override;
void RemoveObserver(DownloadTaskObserver* observer) override;
// Setters for task properties. Setters invoke OnDownloadUpdated callback.
void SetDone(bool done);
void SetErrorCode(int error_code);
void SetTotalBytes(int64_t total_bytes);
void SetPercentComplete(int percent_complete);
void SetContentDisposition(const std::string& content_disposition);
void SetMimeType(const std::string& mime_type);
void SetSuggestedFilename(const base::string16& suggested_file_name);
private:
// Called when download task was updated.
void OnDownloadUpdated();
base::ObserverList<DownloadTaskObserver, true> observers_;
std::unique_ptr<net::URLFetcherResponseWriter> writer_;
GURL original_url_;
bool is_done_ = false;
int error_code_ = 0;
std::string content_disposition_;
int64_t total_bytes_ = -1;
int percent_complete_ = -1;
std::string mime_type_;
base::string16 suggested_file_name_;
__strong NSString* identifier_ = nil;
DISALLOW_COPY_AND_ASSIGN(FakeDownloadTask);
};
} // namespace web
#endif // IOS_WEB_PUBLIC_TEST_FAKES_FAKE_DOWNLOAD_TASK_H_
// Copyright 2017 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.
#import "ios/web/public/test/fakes/fake_download_task.h"
#include "ios/web/public/download/download_task_observer.h"
#include "net/url_request/url_fetcher_response_writer.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace web {
FakeDownloadTask::FakeDownloadTask(const GURL& original_url,
const std::string& mime_type)
: original_url_(original_url), mime_type_(mime_type) {}
FakeDownloadTask::~FakeDownloadTask() = default;
void FakeDownloadTask::Start(
std::unique_ptr<net::URLFetcherResponseWriter> writer) {
writer_ = std::move(writer);
OnDownloadUpdated();
}
net::URLFetcherResponseWriter* FakeDownloadTask::GetResponseWriter() const {
return writer_.get();
}
NSString* FakeDownloadTask::GetIndentifier() const {
return identifier_;
}
const GURL& FakeDownloadTask::GetOriginalUrl() const {
return original_url_;
}
bool FakeDownloadTask::IsDone() const {
return is_done_;
}
int FakeDownloadTask::GetErrorCode() const {
return error_code_;
}
int64_t FakeDownloadTask::GetTotalBytes() const {
return total_bytes_;
}
int FakeDownloadTask::GetPercentComplete() const {
return percent_complete_;
}
std::string FakeDownloadTask::GetContentDisposition() const {
return content_disposition_;
}
std::string FakeDownloadTask::GetMimeType() const {
return mime_type_;
}
base::string16 FakeDownloadTask::GetSuggestedFilename() const {
return suggested_file_name_;
}
void FakeDownloadTask::AddObserver(DownloadTaskObserver* observer) {
DCHECK(!observers_.HasObserver(observer));
observers_.AddObserver(observer);
}
void FakeDownloadTask::RemoveObserver(DownloadTaskObserver* observer) {
DCHECK(observers_.HasObserver(observer));
observers_.RemoveObserver(observer);
}
void FakeDownloadTask::SetDone(bool done) {
is_done_ = done;
OnDownloadUpdated();
}
void FakeDownloadTask::SetErrorCode(int error_code) {
error_code_ = error_code;
OnDownloadUpdated();
}
void FakeDownloadTask::SetTotalBytes(int64_t total_bytes) {
total_bytes_ = total_bytes;
OnDownloadUpdated();
}
void FakeDownloadTask::SetPercentComplete(int percent_complete) {
percent_complete_ = percent_complete;
OnDownloadUpdated();
}
void FakeDownloadTask::SetContentDisposition(
const std::string& content_disposition) {
content_disposition_ = content_disposition;
OnDownloadUpdated();
}
void FakeDownloadTask::SetMimeType(const std::string& mime_type) {
mime_type_ = mime_type;
OnDownloadUpdated();
}
void FakeDownloadTask::SetSuggestedFilename(
const base::string16& suggested_file_name) {
suggested_file_name_ = suggested_file_name;
OnDownloadUpdated();
}
void FakeDownloadTask::OnDownloadUpdated() {
for (auto& observer : observers_)
observer.OnDownloadUpdated(this);
}
} // namespace web
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