#ifndef CONTENT_SERVICES_AUCTION_WORKLET_WORKLET_LOADER_H_
#define CONTENT_SERVICES_AUCTION_WORKLET_WORKLET_LOADER_H_
#include <stddef.h>
#include <memory>
#include <string>
#include <vector>
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
#include "content/services/auction_worklet/auction_downloader.h"
#include "content/services/auction_worklet/auction_v8_helper.h"
#include "services/network/public/mojom/url_loader_factory.mojom-forward.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "url/gurl.h"
#include "v8/include/v8-persistent-handle.h"
namespace v8 {
class UnboundScript;
class WasmModuleObject;
}
namespace auction_worklet {
class AuctionDownloader;
class CONTENT_EXPORT WorkletLoaderBase {
public:
class CONTENT_EXPORT Result {
public:
Result();
Result(Result&&);
~Result();
Result& operator=(Result&&);
bool success() const { return success_; }
size_t original_size_bytes() const { return original_size_bytes_; }
base::TimeDelta download_time() const { return download_time_; }
private:
friend class WorkletLoader;
friend class WorkletLoaderBase;
friend class WorkletWasmLoader;
void DownloadReady(scoped_refptr<AuctionV8Helper> v8_helper,
size_t original_size_bytes,
base::TimeDelta download_time);
void set_success(bool success) { success_ = success; }
struct V8Data {
explicit V8Data(scoped_refptr<AuctionV8Helper> v8_helper);
~V8Data();
void SetScript(v8::Global<v8::UnboundScript> script);
void SetModule(v8::Global<v8::WasmModuleObject> wasm_module);
bool compiled = false;
scoped_refptr<AuctionV8Helper> v8_helper;
v8::Global<v8::UnboundScript> script;
v8::Global<v8::WasmModuleObject> wasm_module;
};
std::unique_ptr<V8Data, base::OnTaskRunnerDeleter> state_;
size_t original_size_bytes_ = 0;
base::TimeDelta download_time_;
bool success_ = false;
};
using LoadWorkletCallback =
base::OnceCallback<void(Result result,
absl::optional<std::string> error_msg)>;
explicit WorkletLoaderBase(const WorkletLoaderBase&) = delete;
WorkletLoaderBase& operator=(const WorkletLoaderBase&) = delete;
protected:
WorkletLoaderBase(network::mojom::URLLoaderFactory* url_loader_factory,
const GURL& source_url,
AuctionDownloader::MimeType mime_type,
scoped_refptr<AuctionV8Helper> v8_helper,
scoped_refptr<AuctionV8Helper::DebugId> debug_id,
LoadWorkletCallback load_worklet_callback);
~WorkletLoaderBase();
private:
void OnDownloadComplete(std::unique_ptr<std::string> body,
scoped_refptr<net::HttpResponseHeaders> headers,
absl::optional<std::string> error_msg);
static void HandleDownloadResultOnV8Thread(
GURL source_url,
AuctionDownloader::MimeType mime_type,
scoped_refptr<AuctionV8Helper> v8_helper,
scoped_refptr<AuctionV8Helper::DebugId> debug_id,
std::unique_ptr<std::string> body,
absl::optional<std::string> error_msg,
WorkletLoaderBase::Result::V8Data* out_data,
scoped_refptr<base::SequencedTaskRunner> user_thread_task_runner,
base::WeakPtr<WorkletLoaderBase> weak_instance);
static bool CompileJs(const std::string& body,
scoped_refptr<AuctionV8Helper> v8_helper,
const GURL& source_url,
AuctionV8Helper::DebugId* debug_id,
absl::optional<std::string>& error_msg,
WorkletLoaderBase::Result::V8Data* out_data);
static bool CompileWasm(const std::string& body,
scoped_refptr<AuctionV8Helper> v8_helper,
const GURL& source_url,
AuctionV8Helper::DebugId* debug_id,
absl::optional<std::string>& error_msg,
WorkletLoaderBase::Result::V8Data* out_data);
void DeliverCallbackOnUserThread(bool success,
absl::optional<std::string> error_msg);
const GURL source_url_;
const AuctionDownloader::MimeType mime_type_;
const scoped_refptr<AuctionV8Helper> v8_helper_;
const scoped_refptr<AuctionV8Helper::DebugId> debug_id_;
const base::TimeTicks start_time_;
Result pending_result_;
std::unique_ptr<AuctionDownloader> auction_downloader_;
LoadWorkletCallback load_worklet_callback_;
base::WeakPtrFactory<WorkletLoaderBase> weak_ptr_factory_{this};
};
class CONTENT_EXPORT WorkletLoader : public WorkletLoaderBase {
public:
WorkletLoader(network::mojom::URLLoaderFactory* url_loader_factory,
const GURL& source_url,
scoped_refptr<AuctionV8Helper> v8_helper,
scoped_refptr<AuctionV8Helper::DebugId> debug_id,
LoadWorkletCallback load_worklet_callback);
static v8::Global<v8::UnboundScript> TakeScript(Result&& result);
};
class CONTENT_EXPORT WorkletWasmLoader : public WorkletLoaderBase {
public:
WorkletWasmLoader(network::mojom::URLLoaderFactory* url_loader_factory,
const GURL& source_url,
scoped_refptr<AuctionV8Helper> v8_helper,
scoped_refptr<AuctionV8Helper::DebugId> debug_id,
LoadWorkletCallback load_worklet_callback);
static v8::MaybeLocal<v8::WasmModuleObject> MakeModule(const Result& result);
};
}
#endif