#include "content/services/auction_worklet/private_model_training_bindings.h"
#include "base/functional/callback.h"
#include "content/services/auction_worklet/auction_v8_helper.h"
#include "content/services/auction_worklet/webidl_compat.h"
#include "gin/public/gin_embedders.h"
#include "v8/include/v8-exception.h"
#include "v8/include/v8-external.h"
#include "v8/include/v8-function.h"
namespace auction_worklet {
PrivateModelTrainingBindings::PrivateModelTrainingBindings(
AuctionV8Helper* v8_helper)
: v8_helper_(v8_helper) {}
PrivateModelTrainingBindings::~PrivateModelTrainingBindings() = default;
void PrivateModelTrainingBindings::AttachToContext(
v8::Local<v8::Context> context) {
v8::Local<v8::External> v8_this = v8::External::New(
v8_helper_->isolate(), this, gin::kPrivateModelTrainingBindingsTag);
v8::Local<v8::Function> v8_function =
v8::Function::New(context, &PrivateModelTrainingBindings::SendEncryptedTo,
v8_this)
.ToLocalChecked();
context->Global()
->Set(context, v8_helper_->CreateStringFromLiteral("sendEncryptedTo"),
v8_function)
.Check();
}
void PrivateModelTrainingBindings::Reset() {
payload_ = std::nullopt;
already_called_ = false;
}
void PrivateModelTrainingBindings::SendEncryptedTo(
const v8::FunctionCallbackInfo<v8::Value>& args) {
PrivateModelTrainingBindings* bindings =
static_cast<PrivateModelTrainingBindings*>(
v8::External::Cast(*args.Data())
->Value(gin::kPrivateModelTrainingBindingsTag));
AuctionV8Helper* v8_helper = bindings->v8_helper_;
AuctionV8Helper::TimeLimitScope time_limit_scope(v8_helper->GetTimeLimit());
ArgsConverter args_converter(v8_helper, time_limit_scope,
"sendEncryptedTo(): ", &args,
1);
v8::Local<v8::Value> unencrypted_payload;
if (!args_converter.ConvertArg(0, "payload", unencrypted_payload)) {
args_converter.TakeStatus().PropagateErrorsToV8(v8_helper);
return;
}
if (!unencrypted_payload->IsArrayBuffer()) {
args.GetIsolate()->ThrowException(
v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
"sendEncryptedTo() may only take a ArrayBuffer")));
return;
}
v8::Local<v8::ArrayBuffer> array_buffer =
unencrypted_payload.As<v8::ArrayBuffer>();
if (array_buffer->IsResizableByUserJavaScript()) {
args.GetIsolate()->ThrowException(
v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
"sendEncryptedTo() may not be resizable by user JavaScript")));
return;
}
if (bindings->already_called_) {
bindings->payload_.reset();
args.GetIsolate()->ThrowException(
v8::Exception::TypeError(v8_helper->CreateStringFromLiteral(
"sendEncryptedTo() may be called at most once")));
return;
}
size_t buffer_size = array_buffer->ByteLength();
void* buffer_data = array_buffer->Data();
base::span<uint8_t> data_span = UNSAFE_BUFFERS(
base::span<uint8_t>(static_cast<uint8_t*>(buffer_data), buffer_size));
mojo_base::BigBuffer big_buffer(data_span);
bindings->payload_ = std::move(big_buffer);
bindings->already_called_ = true;
}
}