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

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