blob: f2326e17c5dd096e8fde0f6116dfc7f7ccbb8361 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef IOS_WEB_DOWNLOAD_DOWNLOAD_TASK_IMPL_H_
#define IOS_WEB_DOWNLOAD_DOWNLOAD_TASK_IMPL_H_
#include <string>
#include "base/files/file_path.h"
#include "base/functional/callback_forward.h"
#import "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequence_checker.h"
#include "ios/web/download/download_result.h"
#include "ios/web/public/download/download_task.h"
#include "url/gurl.h"
namespace base {
class SequencedTaskRunner;
} // namespace base
namespace web {
namespace download {
namespace internal {
struct CreateFileResult;
} // namespace internal
} // namespace download
class DownloadTaskObserver;
class WebState;
// Partial implementation of the DownloadTask interface used to share common
// behaviour between the different concrete sub-classes.
class DownloadTaskImpl : public DownloadTask {
public:
// Constructs a new DownloadTaskImpl objects. `web_state` and `identifier`
// must be valid.
DownloadTaskImpl(WebState* web_state,
const GURL& original_url,
NSString* http_method,
const std::string& content_disposition,
int64_t total_bytes,
const std::string& mime_type,
NSString* identifier,
const scoped_refptr<base::SequencedTaskRunner>& task_runner);
~DownloadTaskImpl() override;
// DownloadTask overrides:
WebState* GetWebState() final;
DownloadTask::State GetState() const final;
void Start(const base::FilePath& path) final;
void Cancel() final;
NSString* GetIdentifier() const final;
const GURL& GetOriginalUrl() const final;
NSString* GetHttpMethod() const final;
bool IsDone() const final;
int GetErrorCode() const final;
int GetHttpCode() const final;
int64_t GetTotalBytes() const final;
int64_t GetReceivedBytes() const final;
int GetPercentComplete() const final;
std::string GetContentDisposition() const final;
std::string GetOriginalMimeType() const final;
std::string GetMimeType() const final;
base::FilePath GenerateFileName() const final;
bool HasPerformedBackgroundDownload() const final;
void AddObserver(DownloadTaskObserver* observer) final;
void RemoveObserver(DownloadTaskObserver* observer) final;
void GetResponseData(ResponseDataReadCallback callback) const final;
const base::FilePath& GetResponsePath() const final;
private:
// Needs to be overridden by sub-classes to perform the download. When this
// method is invoked, `path` is non-empty, its parent directory exists, the
// location is writable, but the file does not exist.
virtual void StartInternal(const base::FilePath& path) = 0;
// Needs to be overridden by sub-classes to clean themselves when the
// download is cancelled. If they need to clean during their shutdown,
// then they need to call `CancelInternal()` from their destructor.
virtual void CancelInternal() = 0;
// Can be overridden by sub-classes to return a suggested name for the
// downloaded file. The default implementation returns an empty string.
virtual std::string GetSuggestedName() const;
// Invoked when UIApplicationWillResignActiveNotification is received.
void OnAppWillResignActive();
// Invoked asynchronously when the file has been created.
void OnDownloadFileCreated(download::internal::CreateFileResult result);
protected:
// Called when download was completed and the data writing was finished.
void OnDownloadFinished(DownloadResult download_result);
// Called when download task was updated.
void OnDownloadUpdated();
// Used to check that the methods are called on the correct sequence.
SEQUENCE_CHECKER(sequence_checker_);
// A list of observers. Weak references.
base::ObserverList<DownloadTaskObserver, true> observers_;
// Back up corresponding public methods of DownloadTask interface.
State state_ = State::kNotStarted;
GURL original_url_;
NSString* http_method_ = nil;
int http_code_ = -1;
int64_t total_bytes_ = -1;
int64_t received_bytes_ = 0;
int percent_complete_ = -1;
std::string content_disposition_;
std::string original_mime_type_;
std::string mime_type_;
NSString* identifier_ = nil;
bool has_performed_background_download_ = false;
DownloadResult download_result_;
raw_ptr<WebState> web_state_ = nullptr;
base::FilePath path_;
bool owns_file_ = false;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Observes UIApplicationWillResignActiveNotification notifications.
id<NSObject> observer_ = nil;
base::WeakPtrFactory<DownloadTaskImpl> weak_factory_{this};
};
} // namespace web
#endif // IOS_WEB_DOWNLOAD_DOWNLOAD_TASK_IMPL_H_