1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
// 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/background_fetch/background_fetch_update_ui_event.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/core/fetch/request.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_bridge.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_event_init.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_icon_loader.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_registration.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_settled_fetch.h"
#include "third_party/blink/renderer/modules/background_fetch/background_fetch_ui_options.h"
#include "third_party/blink/renderer/modules/event_modules_names.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
namespace blink {
BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
const AtomicString& type,
const BackgroundFetchEventInit& initializer)
: BackgroundFetchEvent(type, initializer, nullptr /* observer */) {}
BackgroundFetchUpdateUIEvent::BackgroundFetchUpdateUIEvent(
const AtomicString& type,
const BackgroundFetchEventInit& initializer,
WaitUntilObserver* observer,
ServiceWorkerRegistration* registration)
: BackgroundFetchEvent(type, initializer, observer),
service_worker_registration_(registration) {}
BackgroundFetchUpdateUIEvent::~BackgroundFetchUpdateUIEvent() = default;
void BackgroundFetchUpdateUIEvent::Trace(blink::Visitor* visitor) {
visitor->Trace(service_worker_registration_);
visitor->Trace(loader_);
BackgroundFetchEvent::Trace(visitor);
}
ScriptPromise BackgroundFetchUpdateUIEvent::updateUI(
ScriptState* script_state,
const BackgroundFetchUIOptions& ui_options) {
if (update_ui_called_) {
// Return a rejected promise as this method should only be called once.
return ScriptPromise::Reject(
script_state,
V8ThrowException::CreateTypeError(script_state->GetIsolate(),
"updateUI may only be called once."));
}
update_ui_called_ = true;
if (!service_worker_registration_) {
// Return a Promise that will never settle when a developer calls this
// method on a BackgroundFetchSuccessEvent instance they created themselves.
// TODO(crbug.com/872768): Figure out if this is the right thing to do
// vs reacting eagerly.
return ScriptPromise();
}
DCHECK(!registration_->unique_id().IsEmpty());
if (!ui_options.hasTitle() && ui_options.icons().IsEmpty()) {
// Nothing to update, just return a resolved promise.
return ScriptPromise::CastUndefined(script_state);
}
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
ScriptPromise promise = resolver->Promise();
if (ui_options.icons().IsEmpty()) {
DidGetIcon(resolver, ui_options.title(), SkBitmap());
} else {
DCHECK(!loader_);
loader_ = new BackgroundFetchIconLoader();
DCHECK(loader_);
loader_->Start(BackgroundFetchBridge::From(service_worker_registration_),
ExecutionContext::From(script_state), ui_options.icons(),
WTF::Bind(&BackgroundFetchUpdateUIEvent::DidGetIcon,
WrapPersistent(this), WrapPersistent(resolver),
ui_options.title()));
}
return promise;
}
void BackgroundFetchUpdateUIEvent::DidGetIcon(ScriptPromiseResolver* resolver,
const String& title,
const SkBitmap& icon) {
BackgroundFetchBridge::From(service_worker_registration_)
->UpdateUI(registration_->id(), registration_->unique_id(), title, icon,
WTF::Bind(&BackgroundFetchUpdateUIEvent::DidUpdateUI,
WrapPersistent(this), WrapPersistent(resolver)));
}
void BackgroundFetchUpdateUIEvent::DidUpdateUI(
ScriptPromiseResolver* resolver,
mojom::blink::BackgroundFetchError error) {
switch (error) {
case mojom::blink::BackgroundFetchError::NONE:
case mojom::blink::BackgroundFetchError::INVALID_ID:
resolver->Resolve();
return;
case mojom::blink::BackgroundFetchError::STORAGE_ERROR:
resolver->Reject(
DOMException::Create(DOMExceptionCode::kAbortError,
"Failed to update UI due to I/O error."));
return;
case mojom::blink::BackgroundFetchError::DUPLICATED_DEVELOPER_ID:
case mojom::blink::BackgroundFetchError::INVALID_ARGUMENT:
case mojom::blink::BackgroundFetchError::SERVICE_WORKER_UNAVAILABLE:
case mojom::blink::BackgroundFetchError::PERMISSION_DENIED:
case mojom::blink::BackgroundFetchError::QUOTA_EXCEEDED:
// Not applicable for this callback.
break;
}
NOTREACHED();
}
} // namespace blink
|