blob: 13fd3241b3c219b3421d867588834b0e54f3160c [file] [log] [blame]
// Copyright 2019 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/wake_lock/wake_lock_state_record.h"
#include "base/logging.h"
#include "third_party/blink/public/common/browser_interface_broker_proxy.h"
#include "third_party/blink/public/mojom/wake_lock/wake_lock.mojom-blink.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/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
WakeLockStateRecord::WakeLockStateRecord(ExecutionContext* execution_context,
WakeLockType type)
: wake_lock_type_(ToMojomWakeLockType(type)),
execution_context_(execution_context) {
DCHECK_NE(execution_context, nullptr);
}
void WakeLockStateRecord::AcquireWakeLock(ScriptPromiseResolver* resolver) {
// https://w3c.github.io/wake-lock/#acquire-wake-lock-algorithm
// 1. If the wake lock for type type is not applicable, return false.
// 2. Set active to true if the platform wake lock has an active wake lock for
// type.
// 3. Otherwise, ask the underlying operation system to acquire the wake lock
// of type type and set active to true if the operation succeeded, or else
// false.
// 4. If active is true:
// 4.1. Let document be the responsible document of the current settings
// object.
// 4.2. Let record be the platform wake lock's state record associated with
// document and type.
// 4.3. Add lockPromise to record.[[WakeLockStateRecord]].
// 5. Return active.
if (!wake_lock_) {
mojo::Remote<mojom::blink::WakeLockService> wake_lock_service;
execution_context_->GetBrowserInterfaceBroker().GetInterface(
wake_lock_service.BindNewPipeAndPassReceiver());
wake_lock_service->GetWakeLock(
wake_lock_type_, device::mojom::blink::WakeLockReason::kOther,
"Blink Wake Lock", wake_lock_.BindNewPipeAndPassReceiver());
wake_lock_.set_disconnect_handler(
WTF::Bind(&WakeLockStateRecord::OnWakeLockConnectionError,
WrapWeakPersistent(this)));
wake_lock_->RequestWakeLock();
}
DCHECK(!active_locks_.Contains(resolver));
active_locks_.insert(resolver);
}
void WakeLockStateRecord::ReleaseWakeLock(ScriptPromiseResolver* resolver) {
// https://w3c.github.io/wake-lock/#release-wake-lock-algorithm
// 1. Reject lockPromise with an "AbortError" DOMException.
resolver->Reject(MakeGarbageCollected<DOMException>(
DOMExceptionCode::kAbortError, "Wake Lock released"));
// 2. Let document be the responsible document of the current settings object.
// 3. Let record be the platform wake lock's state record associated with
// document and type.
// 4. If record.[[ActiveLocks]] does not contain lockPromise, abort these
// steps.
auto iterator = active_locks_.find(resolver);
if (iterator == active_locks_.end())
return;
// 5. Remove lockPromise from record.[[ActiveLocks]].
active_locks_.erase(iterator);
// 6. If the internal slot [[ActiveLocks]] of all the platform wake lock's
// state records are all empty, then run the following steps in parallel:
// 6.1. Ask the underlying operation system to release the wake lock of type
// type and let success be true if the operation succeeded, or else
// false.
if (active_locks_.IsEmpty() && wake_lock_.is_bound()) {
wake_lock_->CancelWakeLock();
wake_lock_.reset();
// 6.2. If success is true and type is "screen" run the following:
// 6.2.1. Reset the platform-specific inactivity timer after which the
// screen is actually turned off.
}
}
void WakeLockStateRecord::ClearWakeLocks() {
while (!active_locks_.IsEmpty())
ReleaseWakeLock(*active_locks_.begin());
}
void WakeLockStateRecord::OnWakeLockConnectionError() {
wake_lock_.reset();
ClearWakeLocks();
}
void WakeLockStateRecord::Trace(blink::Visitor* visitor) {
visitor->Trace(execution_context_);
visitor->Trace(active_locks_);
}
} // namespace blink