Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(70)

Side by Side Diff: third_party/WebKit/Source/modules/nfc/NFC.cpp

Issue 1708543002: [webnfc] Implement push() method in blink nfc module. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@onionsoup_webnfc
Patch Set: Rebased. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "modules/nfc/NFC.h" 5 #include "modules/nfc/NFC.h"
6 6
7 #include "bindings/core/v8/JSONValuesForV8.h"
7 #include "bindings/core/v8/ScriptPromiseResolver.h" 8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/V8ArrayBuffer.h"
10 #include "core/dom/DOMArrayBuffer.h"
8 #include "core/dom/DOMException.h" 11 #include "core/dom/DOMException.h"
12 #include "core/dom/Document.h"
9 #include "core/dom/ExceptionCode.h" 13 #include "core/dom/ExceptionCode.h"
14 #include "core/frame/LocalDOMWindow.h"
15 #include "modules/nfc/NFCError.h"
10 #include "modules/nfc/NFCMessage.h" 16 #include "modules/nfc/NFCMessage.h"
11 #include "modules/nfc/NFCPushOptions.h" 17 #include "modules/nfc/NFCPushOptions.h"
18 #include "platform/mojo/MojoHelper.h"
19 #include "public/platform/ServiceRegistry.h"
20
21 namespace nfc = device::nfc::blink;
22
23 namespace {
24 const char kJsonMimePrefix[] = "application/";
25 const char kJsonMimeType[] = "application/json";
26 const char kOpaqueMimeType[] = "application/octet-stream";
27 const char kPlainTextMimeType[] = "text/plain";
28 const char kPlainTextMimePrefix[] = "text/";
29 const char kCharSetUTF8[] = ";charset=UTF-8";
30 } // anonymous namespace
31
32 // Mojo type converters
33 namespace mojo {
34
35 using nfc::NFCMessage;
36 using nfc::NFCMessagePtr;
37 using nfc::NFCRecord;
38 using nfc::NFCRecordPtr;
39 using nfc::NFCRecordType;
40 using nfc::NFCPushOptions;
41 using nfc::NFCPushOptionsPtr;
42 using nfc::NFCPushTarget;
43
44 NFCPushTarget toNFCPushTarget(const WTF::String& target)
45 {
46 if (target == "tag")
47 return NFCPushTarget::TAG;
48
49 if (target == "peer")
50 return NFCPushTarget::PEER;
51
52 return NFCPushTarget::ANY;
53 }
54
55 NFCRecordType toNFCRecordType(const WTF::String& recordType)
56 {
57 if (recordType == "empty")
58 return NFCRecordType::EMPTY;
59
60 if (recordType == "text")
61 return NFCRecordType::TEXT;
62
63 if (recordType == "url")
64 return NFCRecordType::URL;
65
66 if (recordType == "json")
67 return NFCRecordType::JSON;
68
69 if (recordType == "opaque")
70 return NFCRecordType::OPAQUE_RECORD;
71
72 ASSERT_NOT_REACHED();
73 return NFCRecordType::EMPTY;
74 }
75
76 // https://w3c.github.io/web-nfc/#creating-web-nfc-message Step 2.1
77 // If NFCRecord type is not provided, deduct NFCRecord type from JS data type:
Reilly Grant (use Gerrit) 2016/05/20 18:31:22 You mean "deduce" here and elsewhere.
shalamov 2016/05/24 16:09:07 Done.
78 // String or Number => 'text' record
79 // ArrayBuffer => 'opaque' record
80 // JSON serializable Object => 'json' record
81 NFCRecordType deductRecordTypeFromDataType(const blink::NFCRecord& record)
82 {
83 if (record.hasData()) {
84 v8::Local<v8::Value> value = record.data().v8Value();
85
86 if (value->IsString()
87 || (value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value() ))) {
88 return NFCRecordType::TEXT;
89 }
90
91 if (value->IsObject() && !value->IsArrayBuffer()) {
92 return NFCRecordType::JSON;
93 }
94
95 if (value->IsArrayBuffer()) {
96 return NFCRecordType::OPAQUE_RECORD;
97 }
98 }
99
100 return NFCRecordType::EMPTY;
101 }
102
103 void setMediaType(NFCRecordPtr& recordPtr, const WTF::String& recordMediaType, const WTF::String& defaultMediaType)
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 s/NFCRecordPtr& recordPtr/NFCRecordPtr& recordPtr
104 {
105 recordPtr->mediaType = recordMediaType.isEmpty() ? defaultMediaType : record MediaType;
106 }
107
108 template <>
109 struct TypeConverter<mojo::WTFArray<uint8_t>, WTF::String> {
110 static mojo::WTFArray<uint8_t> Convert(const WTF::String& string)
111 {
112 WTF::CString utf8String = string.utf8();
113 WTF::Vector<uint8_t> array;
114 array.append(utf8String.data(), utf8String.length());
115 return mojo::WTFArray<uint8_t>(std::move(array));
116 }
117 };
118
119 template <>
120 struct TypeConverter<mojo::WTFArray<uint8_t>, blink::DOMArrayBuffer*> {
121 static mojo::WTFArray<uint8_t> Convert(blink::DOMArrayBuffer* buffer)
122 {
123 WTF::Vector<uint8_t> array;
124 array.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLe ngth());
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 nit: const is unnecessary here
shalamov 2016/05/24 16:09:07 Done.
125 return mojo::WTFArray<uint8_t>(std::move(array));
126 }
127 };
128
129 template <>
130 struct TypeConverter<NFCRecordPtr, WTF::String> {
131 static NFCRecordPtr Convert(const WTF::String& string)
132 {
133 NFCRecordPtr record = NFCRecord::New();
134 record->recordType = NFCRecordType::TEXT;
135 record->mediaType = kPlainTextMimeType;
136 record->mediaType.append(kCharSetUTF8);
137 record->data = mojo::WTFArray<uint8_t>::From(string);
138 return record;
139 }
140 };
141
142 template <>
143 struct TypeConverter<NFCRecordPtr, blink::DOMArrayBuffer*> {
144 static NFCRecordPtr Convert(blink::DOMArrayBuffer* buffer)
145 {
146 NFCRecordPtr record = NFCRecord::New();
147 record->recordType = NFCRecordType::OPAQUE_RECORD;
148 record->mediaType = kOpaqueMimeType;
149 record->data = mojo::WTFArray<uint8_t>::From(buffer);
150 return record;
151 }
152 };
153
154 template <>
155 struct TypeConverter<NFCMessagePtr, WTF::String> {
156 static NFCMessagePtr Convert(const WTF::String& string)
157 {
158 NFCMessagePtr message = NFCMessage::New();
159 message->data = mojo::WTFArray<NFCRecordPtr>::New(1);
160 message->data[0] = NFCRecord::From(string);
161 return message;
162 }
163 };
164
165 template <>
166 struct TypeConverter<mojo::WTFArray<uint8_t>, blink::ScriptValue> {
167 static mojo::WTFArray<uint8_t> Convert(const blink::ScriptValue& scriptValue )
168 {
169 v8::Local<v8::Value> value = scriptValue.v8Value();
170
171 if (value->IsNumber())
172 return mojo::WTFArray<uint8_t>::From(WTF::String::number(value.As<v8 ::Number>()->Value()));
173
174 if (value->IsString()) {
175 blink::V8StringResource<> stringResource = value;
176 if (stringResource.prepare())
177 return mojo::WTFArray<uint8_t>::From<WTF::String>(stringResource );
178 }
179
180 if (value->IsObject() && !value->IsArrayBuffer()) {
181 RefPtr<blink::JSONValue> jsonResult = blink::toJSONValue(scriptValue .context(), value);
182 if (jsonResult && (jsonResult->getType() == blink::JSONValue::TypeOb ject))
183 return mojo::WTFArray<uint8_t>::From(jsonResult->toJSONString()) ;
184 }
185
186 if (value->IsArrayBuffer())
187 return mojo::WTFArray<uint8_t>::From(blink::V8ArrayBuffer::toImpl(va lue.As<v8::Object>()));
188
189 return nullptr;
190 }
191 };
192
193 template <>
194 struct TypeConverter<NFCRecordPtr, blink::NFCRecord> {
195 static NFCRecordPtr Convert(const blink::NFCRecord& record)
196 {
197 NFCRecordPtr recordPtr = NFCRecord::New();
198
199 if (record.hasRecordType())
200 recordPtr->recordType = toNFCRecordType(record.recordType());
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 This seems to allow the caller to specify a record
shalamov 2016/05/24 16:09:07 Conversion would be done only if type<->data combi
201 else
202 recordPtr->recordType = deductRecordTypeFromDataType(record);
203
204 // If record type is "empty", no need to set media type or data.
205 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
206 if (recordPtr->recordType == NFCRecordType::EMPTY)
207 return recordPtr;
208
209 switch (recordPtr->recordType) {
210 case NFCRecordType::TEXT:
211 case NFCRecordType::URL:
212 setMediaType(recordPtr, record.mediaType(), kPlainTextMimeType);
213 recordPtr->mediaType.append(kCharSetUTF8);
214 break;
215 case NFCRecordType::JSON:
216 setMediaType(recordPtr, record.mediaType(), kJsonMimeType);
217 break;
218 case NFCRecordType::OPAQUE_RECORD:
219 setMediaType(recordPtr, record.mediaType(), kOpaqueMimeType);
220 break;
221 default:
222 ASSERT_NOT_REACHED();
223 break;
224 }
225
226 recordPtr->data = mojo::WTFArray<uint8_t>::From(record.data());
227
228 // If JS object cannot be converted to uint8_t array, return null,
229 // interrupt NFCMessage conversion algorithm and reject promise with
230 // SyntaxError exception.
231 if (recordPtr->data.is_null())
232 return nullptr;
233
234 return recordPtr;
235 }
236 };
237
238 template <>
239 struct TypeConverter<NFCMessagePtr, blink::NFCMessage> {
240 static NFCMessagePtr Convert(const blink::NFCMessage& message)
241 {
242 NFCMessagePtr messagePtr = NFCMessage::New();
243 messagePtr->url = message.url();
244 messagePtr->data.resize(message.data().size());
245 for (size_t i = 0; i < message.data().size(); ++i) {
246 NFCRecordPtr record = NFCRecord::From(message.data()[i]);
247 if (record.is_null())
248 return nullptr;
249
250 messagePtr->data[i] = std::move(record);
251 }
252 messagePtr->data = mojo::WTFArray<NFCRecordPtr>::From(message.data());
253 return messagePtr;
254 }
255 };
256
257 template <>
258 struct TypeConverter<NFCMessagePtr, blink::DOMArrayBuffer*> {
259 static NFCMessagePtr Convert(blink::DOMArrayBuffer* buffer)
260 {
261 NFCMessagePtr message = NFCMessage::New();
262 message->data = mojo::WTFArray<NFCRecordPtr>::New(1);
263 message->data[0] = NFCRecord::From(buffer);
264 return message;
265 }
266 };
267
268 template <>
269 struct TypeConverter<NFCMessagePtr, blink::NFCPushMessage> {
270 static NFCMessagePtr Convert(const blink::NFCPushMessage& message)
271 {
272 if (message.isString())
273 return NFCMessage::From(message.getAsString());
274
275 if (message.isNFCMessage())
276 return NFCMessage::From(message.getAsNFCMessage());
277
278 if (message.isArrayBuffer())
279 return NFCMessage::From(message.getAsArrayBuffer());
280
281 ASSERT_NOT_REACHED();
282 return nullptr;
283 }
284 };
285
286 template <>
287 struct TypeConverter<NFCPushOptionsPtr, blink::NFCPushOptions> {
288 static NFCPushOptionsPtr Convert(const blink::NFCPushOptions& pushOptions)
289 {
290 // https://w3c.github.io/web-nfc/#the-nfcpushoptions-dictionary
291 // Default values for NFCPushOptions dictionary are:
292 // target = 'any', timeout = Infinity, ignoreRead = true
293 NFCPushOptionsPtr pushOptionsPtr = NFCPushOptions::New();
294
295 if (pushOptions.hasTarget())
296 pushOptionsPtr->target = toNFCPushTarget(pushOptions.target());
297 else
298 pushOptionsPtr->target = NFCPushTarget::ANY;
299
300 if (pushOptions.hasTimeout())
301 pushOptionsPtr->timeout = pushOptions.timeout();
302 else
303 pushOptionsPtr->timeout = std::numeric_limits<double>::infinity();
304
305 if (pushOptions.hasIgnoreRead())
306 pushOptionsPtr->ignoreRead = pushOptions.ignoreRead();
307 else
308 pushOptionsPtr->ignoreRead = true;
309
310 return pushOptionsPtr;
311 }
312 };
313
314 } // namespace mojo
12 315
13 namespace blink { 316 namespace blink {
14 317
318
319 namespace {
320
321 bool isValidTextRecord(const NFCRecord& record)
322 {
323 v8::Local<v8::Value> value = record.data().v8Value();
324 if (!value->IsString() && !(value->IsNumber() && !std::isnan(value.As<v8::Nu mber>()->Value())))
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 nit: The parenthesis around the right hand side of
shalamov 2016/05/24 16:09:08 I wanted to check whether number is NaN, only when
Reilly Grant (use Gerrit) 2016/05/24 19:25:38 I see. I misread it as (!value->IsNumber() && !std
325 return false;
326
327 if (record.hasMediaType() && !record.mediaType().startsWith(kPlainTextMimePr efix, TextCaseInsensitive))
328 return false;
329
330 return true;
331 }
332
333 bool isValidURLRecord(const NFCRecord& record)
334 {
335 if (!record.data().v8Value()->IsString())
336 return false;
337
338 return isValidTextRecord(record);
Reilly Grant (use Gerrit) 2016/05/20 18:31:22 You may want to attempt to parse the URL and retur
shalamov 2016/05/24 16:09:08 Done.
339 }
340
341 bool isValidJSONRecord(const NFCRecord& record)
342 {
343 v8::Local<v8::Value> value = record.data().v8Value();
344 if (!value->IsObject() || value->IsArrayBuffer())
345 return false;
346
347 if (record.hasMediaType() && !record.mediaType().startsWith(kJsonMimePrefix, TextCaseInsensitive))
348 return false;
349
350 return true;
351 }
352
353 bool isValidOpaqueRecord(const NFCRecord& record)
354 {
355 return record.data().v8Value()->IsArrayBuffer();
356 }
357
358 bool isValidNFCRecord(const NFCRecord& record)
359 {
360 nfc::NFCRecordType type;
361 if (record.hasRecordType()) {
362 type = mojo::toNFCRecordType(record.recordType());
363 } else {
364 type = mojo::deductRecordTypeFromDataType(record);
365
366 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
367 // If NFCRecord.recordType is not set and record type cannot be deducted
368 // from NFCRecord.data, reject promise with SyntaxError.
369 if (type == nfc::NFCRecordType::EMPTY)
370 return false;
371 }
372
373 // Non-empty records must have data.
374 if (!record.hasData() && (type != nfc::NFCRecordType::EMPTY))
375 return false;
376
377 switch (type) {
378 case nfc::NFCRecordType::TEXT:
379 return isValidTextRecord(record);
380 case nfc::NFCRecordType::URL:
381 return isValidURLRecord(record);
382 case nfc::NFCRecordType::JSON:
383 return isValidJSONRecord(record);
384 case nfc::NFCRecordType::OPAQUE_RECORD:
385 return isValidOpaqueRecord(record);
386 case nfc::NFCRecordType::EMPTY:
387 return !record.hasData() && record.mediaType().isEmpty();
388 }
389
390 ASSERT_NOT_REACHED();
391 return false;
392 }
393
394 DOMException* isValidNFCRecordArray(const HeapVector<NFCRecord>& records)
395 {
396 // https://w3c.github.io/web-nfc/#the-push-method
397 // If NFCMessage.data is empty, reject promise with SyntaxError
398 if (records.isEmpty())
399 return DOMException::create(SyntaxError);
400
401 for (const auto& record : records) {
402 if (!isValidNFCRecord(record))
403 return DOMException::create(SyntaxError);
404 }
405
406 return nullptr;
407 }
408
409 DOMException* isValidNFCPushMessage(const NFCPushMessage& message)
410 {
411 if (!message.isNFCMessage() && !message.isString() && !message.isArrayBuffer ())
412 return DOMException::create(TypeMismatchError);
413
414 if (message.isNFCMessage()) {
415 if (!message.getAsNFCMessage().hasData())
416 return DOMException::create(TypeMismatchError);
417
418 return isValidNFCRecordArray(message.getAsNFCMessage().data());
419 }
420
421 return nullptr;
422 }
423
424 bool setURL(const String& origin, nfc::NFCMessagePtr& message)
425 {
426 KURL originURL(ParsedURLString, origin);
427
428 if (!message->url.isEmpty() && originURL.canSetPathname()) {
429 originURL.setPath(message->url);
430 }
431
432 message->url = originURL;
433 return originURL.isValid();
434 }
435
436 } // anonymous namespace
437
15 NFC::NFC(LocalFrame* frame) 438 NFC::NFC(LocalFrame* frame)
16 : LocalFrameLifecycleObserver(frame) 439 : PageLifecycleObserver(frame->page())
17 , PageLifecycleObserver(frame ? frame->page() : 0) 440 , ContextLifecycleObserver(frame->document())
18 { 441 , m_client(this)
442 {
443 ThreadState::current()->registerPreFinalizer(this);
444 frame->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_nfc));
445 m_nfc.set_connection_error_handler(createBaseCallback(bind(&NFC::OnConnectio nError, WeakPersistentThisPointer<NFC>(this))));
446 m_nfc->SetClient(m_client.CreateInterfacePtrAndBind());
19 } 447 }
20 448
21 NFC* NFC::create(LocalFrame* frame) 449 NFC* NFC::create(LocalFrame* frame)
22 { 450 {
23 NFC* nfc = new NFC(frame); 451 NFC* nfc = new NFC(frame);
24 return nfc; 452 return nfc;
25 } 453 }
26 454
27 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& records, const NFCPushOptions& options) 455 NFC::~NFC()
28 { 456 {
29 // TODO(shalamov): To be implemented. 457 // |m_nfc| may hold persistent handle to |this| object, therefore, there
30 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 458 // should be no more outstanding requests when NFC object is destructed.
459 DCHECK(m_requests.isEmpty());
460 }
461
462 void NFC::dispose()
463 {
464 m_client.Close();
465 }
466
467 void NFC::contextDestroyed()
468 {
469 m_nfc.reset();
470 m_requests.clear();
471 }
472
473 // https://w3c.github.io/web-nfc/#writing-or-pushing-content
474 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options)
475 {
476 String errorMessage;
477 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
478 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
479 }
480
481 DOMException* exception = isValidNFCPushMessage(pushMessage);
482 if (exception)
483 return ScriptPromise::rejectWithDOMException(scriptState, exception);
484
485 if (!m_nfc)
486 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
487
488 nfc::NFCMessagePtr message = nfc::NFCMessage::From(pushMessage);
489 if (!message)
490 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
491
492 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message))
493 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
494
495 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
496 m_requests.add(resolver);
497 auto callback = createBaseCallback(bind<nfc::NFCErrorPtr>(&NFC::OnRequestCom pleted, this, resolver));
498 m_nfc->Push(std::move(message), nfc::NFCPushOptions::From(options), callback );
499
500 return resolver->promise();
31 } 501 }
32 502
33 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) 503 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target)
34 { 504 {
35 // TODO(shalamov): To be implemented. 505 String errorMessage;
36 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 506 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
507 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
508 }
509
510 if (!m_nfc)
511 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
512
513 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
514 m_requests.add(resolver);
515 auto callback = createBaseCallback(bind<nfc::NFCErrorPtr>(&NFC::OnRequestCom pleted, this, resolver));
516 m_nfc->CancelPush(mojo::toNFCPushTarget(target), callback);
517
518 return resolver->promise();
37 } 519 }
38 520
39 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options) 521 ScriptPromise NFC::watch(ScriptState* scriptState, MessageCallback* callback, co nst NFCWatchOptions& options)
40 { 522 {
41 // TODO(shalamov): To be implemented. 523 // TODO(shalamov): To be implemented.
42 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 524 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
43 } 525 }
44 526
45 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id) 527 ScriptPromise NFC::cancelWatch(ScriptState* scriptState, long id)
46 { 528 {
47 // TODO(shalamov): To be implemented. 529 // TODO(shalamov): To be implemented.
48 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 530 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
49 } 531 }
50 532
51 ScriptPromise NFC::cancelWatch(ScriptState* scriptState) 533 ScriptPromise NFC::cancelWatch(ScriptState* scriptState)
52 { 534 {
53 // TODO(shalamov): To be implemented. 535 // TODO(shalamov): To be implemented.
54 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 536 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError));
55 } 537 }
56 538
57 void NFC::willDetachFrameHost()
58 {
59 // TODO(shalamov): To be implemented.
60 }
61
62 void NFC::pageVisibilityChanged() 539 void NFC::pageVisibilityChanged()
63 { 540 {
64 // TODO(shalamov): To be implemented. When visibility is lost, 541 // If service is not initialized, there cannot be any pending NFC activities
542 if (!m_nfc)
543 return;
544
65 // NFC operations should be suspended. 545 // NFC operations should be suspended.
66 // https://w3c.github.io/web-nfc/#nfc-suspended 546 // https://w3c.github.io/web-nfc/#nfc-suspended
547 if (page()->visibilityState() == PageVisibilityStateVisible)
548 m_nfc->ResumeNFCOperations();
549 else
550 m_nfc->SuspendNFCOperations();
551 }
552
553 void NFC::OnRequestCompleted(ScriptPromiseResolver* resolver, nfc::NFCErrorPtr e rror)
554 {
555 m_requests.remove(resolver);
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 Only resolve() or reject() if |m_requests| still c
shalamov 2016/05/24 16:09:08 Done.
556 if (error.is_null())
557 resolver->resolve();
558 else
559 resolver->reject(NFCError::take(resolver, error->error_type));
560 }
561
562 void NFC::OnConnectionError()
563 {
564 m_nfc.reset();
565
566 // If NFCService is not available or disappears when NFC hardware is
567 // disabled, reject promise with NotSupportedError exception.
568 for (ScriptPromiseResolver* resolver : m_requests) {
Reilly Grant (use Gerrit) 2016/05/20 18:31:21 nit: Unnecessary braces.
shalamov 2016/05/24 16:09:08 Done.
569 resolver->reject(NFCError::take(resolver, nfc::NFCErrorType::NOT_SUPPORT ED));
570 }
571
572 m_requests.clear();
573 }
574
575 void NFC::OnWatch(mojo::WTFArray<uint32_t> ids, nfc::NFCMessagePtr)
576 {
577 // TODO(shalamov): Not implemented.
67 } 578 }
68 579
69 DEFINE_TRACE(NFC) 580 DEFINE_TRACE(NFC)
70 { 581 {
71 LocalFrameLifecycleObserver::trace(visitor);
72 PageLifecycleObserver::trace(visitor); 582 PageLifecycleObserver::trace(visitor);
583 ContextLifecycleObserver::trace(visitor);
584 visitor->trace(m_requests);
73 } 585 }
74 586
75 } // namespace blink 587 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698