blob: 28ad7ddf6c80b8517c52f8f4eb225a9352d6eab8 [file] [log] [blame]
// Copyright 2018 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 "third_party/blink/renderer/modules/idle/idle_manager.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/idle/idle_status.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
const uint32_t kDefaultThresholdSeconds = 60;
IdleManager::IdleManager(ExecutionContext* context) {}
ScriptPromise IdleManager::query(ScriptState* script_state,
const IdleOptions* options,
ExceptionState& exception_state) {
ExecutionContext* context = ExecutionContext::From(script_state);
DCHECK(context->IsContextThread());
// Validate options.
int32_t threshold_seconds =
options->hasThreshold() ? options->threshold() : kDefaultThresholdSeconds;
if (threshold_seconds <= 0) {
exception_state.ThrowTypeError("Invalid threshold");
return ScriptPromise();
}
// TODO: Permission check.
if (!service_) {
// NOTE(goto): what are the benefits of initializing this here
// as opposed to the constructor? lazy loading?
context->GetInterfaceProvider()->GetInterface(mojo::MakeRequest(&service_));
service_.set_connection_error_handler(WTF::Bind(
&IdleManager::OnIdleManagerConnectionError, WrapWeakPersistent(this)));
}
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
mojom::blink::IdleMonitorPtr monitor_ptr;
IdleStatus* status = MakeGarbageCollected<IdleStatus>(
ExecutionContext::From(script_state), threshold_seconds,
mojo::MakeRequest(&monitor_ptr));
requests_.insert(resolver);
service_->AddMonitor(
threshold_seconds, std::move(monitor_ptr),
WTF::Bind(&IdleManager::OnAddMonitor, WrapPersistent(this),
WrapPersistent(resolver), WrapPersistent(status)));
return promise;
}
IdleManager* IdleManager::Create(ExecutionContext* context) {
IdleManager* idle_manager = MakeGarbageCollected<IdleManager>(context);
return idle_manager;
}
void IdleManager::OnAddMonitor(ScriptPromiseResolver* resolver,
IdleStatus* status,
mojom::blink::IdleState state) {
DCHECK(requests_.Contains(resolver));
requests_.erase(resolver);
status->Init(state);
resolver->Resolve(status);
}
void IdleManager::Trace(blink::Visitor* visitor) {
ScriptWrappable::Trace(visitor);
visitor->Trace(requests_);
}
void IdleManager::OnIdleManagerConnectionError() {
// TODO(goto): write a unittest to cover this.
for (const auto& request : requests_) {
request->Reject(DOMException::Create(DOMExceptionCode::kNotSupportedError,
"Idle detection not available"));
}
requests_.clear();
service_.reset();
}
} // namespace blink