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

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: Move dependency from content_browsertests to layouttest_support_content Created 4 years, 6 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 NOTREACHED();
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, deduce NFCRecord type from JS data type:
78 // String or Number => 'text' record
79 // ArrayBuffer => 'opaque' record
80 // JSON serializable Object => 'json' record
81 NFCRecordType deduceRecordTypeFromDataType(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, c onst WTF::String& defaultMediaType)
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<uint8_t*>(buffer->data()), buffer->byteLength() );
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());
201 else
202 recordPtr->recordType = deduceRecordTypeFromDataType(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 NOTREACHED();
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 NOTREACHED();
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 {
317 namespace {
318
319 bool isValidTextRecord(const NFCRecord& record)
320 {
321 v8::Local<v8::Value> value = record.data().v8Value();
322 if (!value->IsString() && !(value->IsNumber() && !std::isnan(value.As<v8::Nu mber>()->Value())))
323 return false;
324
325 if (record.hasMediaType() && !record.mediaType().startsWith(kPlainTextMimePr efix, TextCaseInsensitive))
326 return false;
327
328 return true;
329 }
330
331 bool isValidURLRecord(const NFCRecord& record)
332 {
333 if (!record.data().v8Value()->IsString())
334 return false;
335
336 blink::V8StringResource<> stringResource = record.data().v8Value();
337 if (!stringResource.prepare())
338 return false;
339
340 return KURL(KURL(), stringResource).isValid();
341 }
342
343 bool isValidJSONRecord(const NFCRecord& record)
344 {
345 v8::Local<v8::Value> value = record.data().v8Value();
346 if (!value->IsObject() || value->IsArrayBuffer())
347 return false;
348
349 if (record.hasMediaType() && !record.mediaType().startsWith(kJsonMimePrefix, TextCaseInsensitive))
350 return false;
351
352 return true;
353 }
354
355 bool isValidOpaqueRecord(const NFCRecord& record)
356 {
357 return record.data().v8Value()->IsArrayBuffer();
358 }
359
360 bool isValidNFCRecord(const NFCRecord& record)
361 {
362 nfc::NFCRecordType type;
363 if (record.hasRecordType()) {
364 type = mojo::toNFCRecordType(record.recordType());
365 } else {
366 type = mojo::deduceRecordTypeFromDataType(record);
367
368 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
369 // If NFCRecord.recordType is not set and record type cannot be deduced
370 // from NFCRecord.data, reject promise with SyntaxError.
371 if (type == nfc::NFCRecordType::EMPTY)
372 return false;
373 }
374
375 // Non-empty records must have data.
376 if (!record.hasData() && (type != nfc::NFCRecordType::EMPTY))
377 return false;
378
379 switch (type) {
380 case nfc::NFCRecordType::TEXT:
381 return isValidTextRecord(record);
382 case nfc::NFCRecordType::URL:
383 return isValidURLRecord(record);
384 case nfc::NFCRecordType::JSON:
385 return isValidJSONRecord(record);
386 case nfc::NFCRecordType::OPAQUE_RECORD:
387 return isValidOpaqueRecord(record);
388 case nfc::NFCRecordType::EMPTY:
389 return !record.hasData() && record.mediaType().isEmpty();
390 }
391
392 NOTREACHED();
393 return false;
394 }
395
396 DOMException* isValidNFCRecordArray(const HeapVector<NFCRecord>& records)
397 {
398 // https://w3c.github.io/web-nfc/#the-push-method
399 // If NFCMessage.data is empty, reject promise with SyntaxError
400 if (records.isEmpty())
401 return DOMException::create(SyntaxError);
402
403 for (const auto& record : records) {
404 if (!isValidNFCRecord(record))
405 return DOMException::create(SyntaxError);
406 }
407
408 return nullptr;
409 }
410
411 DOMException* isValidNFCPushMessage(const NFCPushMessage& message)
412 {
413 if (!message.isNFCMessage() && !message.isString() && !message.isArrayBuffer ())
414 return DOMException::create(TypeMismatchError);
415
416 if (message.isNFCMessage()) {
417 if (!message.getAsNFCMessage().hasData())
418 return DOMException::create(TypeMismatchError);
419
420 return isValidNFCRecordArray(message.getAsNFCMessage().data());
421 }
422
423 return nullptr;
424 }
425
426 bool setURL(const String& origin, nfc::NFCMessagePtr& message)
427 {
428 KURL originURL(ParsedURLString, origin);
429
430 if (!message->url.isEmpty() && originURL.canSetPathname()) {
431 originURL.setPath(message->url);
432 }
433
434 message->url = originURL;
435 return originURL.isValid();
436 }
437
438 } // anonymous namespace
14 439
15 NFC::NFC(LocalFrame* frame) 440 NFC::NFC(LocalFrame* frame)
16 : LocalFrameLifecycleObserver(frame) 441 : PageLifecycleObserver(frame->page())
17 , PageLifecycleObserver(frame ? frame->page() : 0) 442 , ContextLifecycleObserver(frame->document())
18 { 443 , m_client(this)
444 {
445 ThreadState::current()->registerPreFinalizer(this);
446 frame->serviceRegistry()->connectToRemoteService(mojo::GetProxy(&m_nfc));
447 m_nfc.set_connection_error_handler(createBaseCallback(bind(&NFC::OnConnectio nError, WeakPersistentThisPointer<NFC>(this))));
448 m_nfc->SetClient(m_client.CreateInterfacePtrAndBind());
19 } 449 }
20 450
21 NFC* NFC::create(LocalFrame* frame) 451 NFC* NFC::create(LocalFrame* frame)
22 { 452 {
23 NFC* nfc = new NFC(frame); 453 NFC* nfc = new NFC(frame);
24 return nfc; 454 return nfc;
25 } 455 }
26 456
27 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& records, const NFCPushOptions& options) 457 NFC::~NFC()
28 { 458 {
29 // TODO(shalamov): To be implemented. 459 // |m_nfc| may hold persistent handle to |this| object, therefore, there
30 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 460 // should be no more outstanding requests when NFC object is destructed.
461 DCHECK(m_requests.isEmpty());
462 }
463
464 void NFC::dispose()
465 {
466 m_client.Close();
467 }
468
469 void NFC::contextDestroyed()
470 {
471 m_nfc.reset();
472 m_requests.clear();
473 }
474
475 // https://w3c.github.io/web-nfc/#writing-or-pushing-content
476 ScriptPromise NFC::push(ScriptState* scriptState, const NFCPushMessage& pushMess age, const NFCPushOptions& options)
477 {
478 String errorMessage;
479 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage))
480 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
481
482 DOMException* exception = isValidNFCPushMessage(pushMessage);
483 if (exception)
484 return ScriptPromise::rejectWithDOMException(scriptState, exception);
485
486 if (!m_nfc)
487 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(NotSupportedError));
488
489 nfc::NFCMessagePtr message = nfc::NFCMessage::From(pushMessage);
490 if (!message)
491 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
492
493 if (!setURL(scriptState->getExecutionContext()->getSecurityOrigin()->toStrin g(), message))
494 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SyntaxError));
495
496 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState) ;
497 m_requests.add(resolver);
498 auto callback = createBaseCallback(bind<nfc::NFCErrorPtr>(&NFC::OnRequestCom pleted, this, resolver));
499 m_nfc->Push(std::move(message), nfc::NFCPushOptions::From(options), callback );
500
501 return resolver->promise();
31 } 502 }
32 503
33 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target) 504 ScriptPromise NFC::cancelPush(ScriptState* scriptState, const String& target)
34 { 505 {
35 // TODO(shalamov): To be implemented. 506 String errorMessage;
36 return ScriptPromise::rejectWithDOMException(scriptState, DOMException::crea te(NotSupportedError)); 507 if (!scriptState->getExecutionContext()->isSecureContext(errorMessage))
508 return ScriptPromise::rejectWithDOMException(scriptState, DOMException:: create(SecurityError, errorMessage));
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 if (!m_requests.contains(resolver))
556 return;
557
558 m_requests.remove(resolver);
559 if (error.is_null())
560 resolver->resolve();
561 else
562 resolver->reject(NFCError::take(resolver, error->error_type));
563 }
564
565 void NFC::OnConnectionError()
566 {
567 m_nfc.reset();
568
569 // If NFCService is not available or disappears when NFC hardware is
570 // disabled, reject promise with NotSupportedError exception.
571 for (ScriptPromiseResolver* resolver : m_requests)
572 resolver->reject(NFCError::take(resolver, nfc::NFCErrorType::NOT_SUPPORT ED));
573
574 m_requests.clear();
575 }
576
577 void NFC::OnWatch(mojo::WTFArray<uint32_t> ids, nfc::NFCMessagePtr)
578 {
579 // TODO(shalamov): Not implemented.
67 } 580 }
68 581
69 DEFINE_TRACE(NFC) 582 DEFINE_TRACE(NFC)
70 { 583 {
71 LocalFrameLifecycleObserver::trace(visitor);
72 PageLifecycleObserver::trace(visitor); 584 PageLifecycleObserver::trace(visitor);
585 ContextLifecycleObserver::trace(visitor);
586 visitor->trace(m_requests);
73 } 587 }
74 588
75 } // namespace blink 589 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/nfc/NFC.h ('k') | third_party/WebKit/Source/modules/nfc/NFCError.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698