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

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

Issue 2885813002: [webnfc] Align nfc.push operation with the specification (Closed)
Patch Set: Remove WTF:: namespace where not needed. Don't use MaybeLocal. Created 3 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
« no previous file with comments | « third_party/WebKit/Source/modules/nfc/NFC.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/ScriptPromiseResolver.h" 7 #include "bindings/core/v8/ScriptPromiseResolver.h"
8 #include "bindings/core/v8/V8ArrayBuffer.h" 8 #include "bindings/core/v8/V8ArrayBuffer.h"
9 #include "bindings/core/v8/V8StringResource.h" 9 #include "bindings/core/v8/V8StringResource.h"
10 #include "core/dom/DOMArrayBuffer.h" 10 #include "core/dom/DOMArrayBuffer.h"
11 #include "core/dom/DOMException.h" 11 #include "core/dom/DOMException.h"
12 #include "core/dom/Document.h" 12 #include "core/dom/Document.h"
13 #include "core/dom/ExceptionCode.h" 13 #include "core/dom/ExceptionCode.h"
14 #include "core/dom/ExecutionContext.h" 14 #include "core/dom/ExecutionContext.h"
15 #include "core/frame/LocalDOMWindow.h" 15 #include "core/frame/LocalDOMWindow.h"
16 #include "modules/nfc/NFCError.h" 16 #include "modules/nfc/NFCError.h"
17 #include "modules/nfc/NFCMessage.h" 17 #include "modules/nfc/NFCMessage.h"
18 #include "modules/nfc/NFCPushOptions.h" 18 #include "modules/nfc/NFCPushOptions.h"
19 #include "modules/nfc/NFCWatchOptions.h" 19 #include "modules/nfc/NFCWatchOptions.h"
20 #include "platform/mojo/MojoHelper.h" 20 #include "platform/mojo/MojoHelper.h"
21 #include "public/platform/InterfaceProvider.h" 21 #include "public/platform/InterfaceProvider.h"
22 #include "public/platform/Platform.h" 22 #include "public/platform/Platform.h"
23 23
24 namespace { 24 namespace {
25 const char kJsonMimePostfix[] = "+json";
25 const char kJsonMimePrefix[] = "application/"; 26 const char kJsonMimePrefix[] = "application/";
26 const char kJsonMimeType[] = "application/json"; 27 const char kJsonMimeType[] = "application/json";
27 const char kOpaqueMimeType[] = "application/octet-stream"; 28 const char kOpaqueMimeType[] = "application/octet-stream";
28 const char kPlainTextMimeType[] = "text/plain"; 29 const char kPlainTextMimeType[] = "text/plain";
29 const char kPlainTextMimePrefix[] = "text/"; 30 const char kPlainTextMimePrefix[] = "text/";
30 const char kCharSetUTF8[] = ";charset=UTF-8"; 31 const char kCharSetUTF8[] = ";charset=UTF-8";
31 } // anonymous namespace 32 } // anonymous namespace
32 33
33 // Mojo type converters 34 // Mojo type converters
34 namespace mojo { 35 namespace mojo {
35 36
36 using device::nfc::mojom::blink::NFCMessage; 37 using device::nfc::mojom::blink::NFCMessage;
37 using device::nfc::mojom::blink::NFCMessagePtr; 38 using device::nfc::mojom::blink::NFCMessagePtr;
38 using device::nfc::mojom::blink::NFCRecord; 39 using device::nfc::mojom::blink::NFCRecord;
39 using device::nfc::mojom::blink::NFCRecordPtr; 40 using device::nfc::mojom::blink::NFCRecordPtr;
40 using device::nfc::mojom::blink::NFCRecordType; 41 using device::nfc::mojom::blink::NFCRecordType;
41 using device::nfc::mojom::blink::NFCRecordTypeFilter; 42 using device::nfc::mojom::blink::NFCRecordTypeFilter;
42 using device::nfc::mojom::blink::NFCPushOptions; 43 using device::nfc::mojom::blink::NFCPushOptions;
43 using device::nfc::mojom::blink::NFCPushOptionsPtr; 44 using device::nfc::mojom::blink::NFCPushOptionsPtr;
44 using device::nfc::mojom::blink::NFCPushTarget; 45 using device::nfc::mojom::blink::NFCPushTarget;
45 using device::nfc::mojom::blink::NFCWatchMode; 46 using device::nfc::mojom::blink::NFCWatchMode;
46 using device::nfc::mojom::blink::NFCWatchOptions; 47 using device::nfc::mojom::blink::NFCWatchOptions;
47 using device::nfc::mojom::blink::NFCWatchOptionsPtr; 48 using device::nfc::mojom::blink::NFCWatchOptionsPtr;
48 49
49 NFCPushTarget toNFCPushTarget(const WTF::String& target) { 50 NFCPushTarget toNFCPushTarget(const String& target) {
50 if (target == "tag") 51 if (target == "tag")
51 return NFCPushTarget::TAG; 52 return NFCPushTarget::TAG;
52 53
53 if (target == "peer") 54 if (target == "peer")
54 return NFCPushTarget::PEER; 55 return NFCPushTarget::PEER;
55 56
56 return NFCPushTarget::ANY; 57 return NFCPushTarget::ANY;
57 } 58 }
58 59
59 NFCRecordType toNFCRecordType(const WTF::String& recordType) { 60 NFCRecordType toNFCRecordType(const String& recordType) {
60 if (recordType == "empty") 61 if (recordType == "empty")
61 return NFCRecordType::EMPTY; 62 return NFCRecordType::EMPTY;
62 63
63 if (recordType == "text") 64 if (recordType == "text")
64 return NFCRecordType::TEXT; 65 return NFCRecordType::TEXT;
65 66
66 if (recordType == "url") 67 if (recordType == "url")
67 return NFCRecordType::URL; 68 return NFCRecordType::URL;
68 69
69 if (recordType == "json") 70 if (recordType == "json")
70 return NFCRecordType::JSON; 71 return NFCRecordType::JSON;
71 72
72 if (recordType == "opaque") 73 if (recordType == "opaque")
73 return NFCRecordType::OPAQUE_RECORD; 74 return NFCRecordType::OPAQUE_RECORD;
74 75
75 NOTREACHED(); 76 NOTREACHED();
76 return NFCRecordType::EMPTY; 77 return NFCRecordType::EMPTY;
77 } 78 }
78 79
79 NFCWatchMode toNFCWatchMode(const WTF::String& watchMode) { 80 NFCWatchMode toNFCWatchMode(const String& watchMode) {
80 if (watchMode == "web-nfc-only") 81 if (watchMode == "web-nfc-only")
81 return NFCWatchMode::WEBNFC_ONLY; 82 return NFCWatchMode::WEBNFC_ONLY;
82 83
83 if (watchMode == "any") 84 if (watchMode == "any")
84 return NFCWatchMode::ANY; 85 return NFCWatchMode::ANY;
85 86
86 NOTREACHED(); 87 NOTREACHED();
87 return NFCWatchMode::WEBNFC_ONLY; 88 return NFCWatchMode::WEBNFC_ONLY;
88 } 89 }
89 90
(...skipping 17 matching lines...) Expand all
107 108
108 if (value->IsArrayBuffer()) { 109 if (value->IsArrayBuffer()) {
109 return NFCRecordType::OPAQUE_RECORD; 110 return NFCRecordType::OPAQUE_RECORD;
110 } 111 }
111 } 112 }
112 113
113 return NFCRecordType::EMPTY; 114 return NFCRecordType::EMPTY;
114 } 115 }
115 116
116 void setMediaType(NFCRecordPtr& recordPtr, 117 void setMediaType(NFCRecordPtr& recordPtr,
117 const WTF::String& recordMediaType, 118 const String& recordMediaType,
118 const WTF::String& defaultMediaType) { 119 const String& defaultMediaType) {
119 recordPtr->media_type = 120 recordPtr->media_type =
120 recordMediaType.IsEmpty() ? defaultMediaType : recordMediaType; 121 recordMediaType.IsEmpty() ? defaultMediaType : recordMediaType;
121 } 122 }
122 123
123 template <> 124 template <>
124 struct TypeConverter<WTF::Vector<uint8_t>, WTF::String> { 125 struct TypeConverter<Vector<uint8_t>, String> {
125 static WTF::Vector<uint8_t> Convert(const WTF::String& string) { 126 static Vector<uint8_t> Convert(const String& string) {
126 WTF::CString utf8String = string.Utf8(); 127 CString utf8String = string.Utf8();
127 WTF::Vector<uint8_t> array; 128 Vector<uint8_t> array;
128 array.Append(utf8String.data(), utf8String.length()); 129 array.Append(utf8String.data(), utf8String.length());
129 return array; 130 return array;
130 } 131 }
131 }; 132 };
132 133
133 template <> 134 template <>
134 struct TypeConverter<WTF::Vector<uint8_t>, blink::DOMArrayBuffer*> { 135 struct TypeConverter<Vector<uint8_t>, blink::DOMArrayBuffer*> {
135 static WTF::Vector<uint8_t> Convert(blink::DOMArrayBuffer* buffer) { 136 static Vector<uint8_t> Convert(blink::DOMArrayBuffer* buffer) {
136 WTF::Vector<uint8_t> array; 137 Vector<uint8_t> array;
137 array.Append(static_cast<uint8_t*>(buffer->Data()), buffer->ByteLength()); 138 array.Append(static_cast<uint8_t*>(buffer->Data()), buffer->ByteLength());
138 return array; 139 return array;
139 } 140 }
140 }; 141 };
141 142
142 template <> 143 template <>
143 struct TypeConverter<NFCRecordPtr, WTF::String> { 144 struct TypeConverter<NFCRecordPtr, String> {
144 static NFCRecordPtr Convert(const WTF::String& string) { 145 static NFCRecordPtr Convert(const String& string) {
145 NFCRecordPtr record = NFCRecord::New(); 146 NFCRecordPtr record = NFCRecord::New();
146 record->record_type = NFCRecordType::TEXT; 147 record->record_type = NFCRecordType::TEXT;
147 record->media_type = kPlainTextMimeType; 148 record->media_type = kPlainTextMimeType;
148 record->media_type.append(kCharSetUTF8); 149 record->media_type.append(kCharSetUTF8);
149 record->data = mojo::ConvertTo<WTF::Vector<uint8_t>>(string); 150 record->data = mojo::ConvertTo<Vector<uint8_t>>(string);
150 return record; 151 return record;
151 } 152 }
152 }; 153 };
153 154
154 template <> 155 template <>
155 struct TypeConverter<NFCRecordPtr, blink::DOMArrayBuffer*> { 156 struct TypeConverter<NFCRecordPtr, blink::DOMArrayBuffer*> {
156 static NFCRecordPtr Convert(blink::DOMArrayBuffer* buffer) { 157 static NFCRecordPtr Convert(blink::DOMArrayBuffer* buffer) {
157 NFCRecordPtr record = NFCRecord::New(); 158 NFCRecordPtr record = NFCRecord::New();
158 record->record_type = NFCRecordType::OPAQUE_RECORD; 159 record->record_type = NFCRecordType::OPAQUE_RECORD;
159 record->media_type = kOpaqueMimeType; 160 record->media_type = kOpaqueMimeType;
160 record->data = mojo::ConvertTo<WTF::Vector<uint8_t>>(buffer); 161 record->data = mojo::ConvertTo<Vector<uint8_t>>(buffer);
161 return record; 162 return record;
162 } 163 }
163 }; 164 };
164 165
165 template <> 166 template <>
166 struct TypeConverter<NFCMessagePtr, WTF::String> { 167 struct TypeConverter<NFCMessagePtr, String> {
167 static NFCMessagePtr Convert(const WTF::String& string) { 168 static NFCMessagePtr Convert(const String& string) {
168 NFCMessagePtr message = NFCMessage::New(); 169 NFCMessagePtr message = NFCMessage::New();
169 message->data.push_back(NFCRecord::From(string)); 170 message->data.push_back(NFCRecord::From(string));
170 return message; 171 return message;
171 } 172 }
172 }; 173 };
173 174
174 template <> 175 template <>
175 struct TypeConverter<WTF::Optional<WTF::Vector<uint8_t>>, blink::ScriptValue> { 176 struct TypeConverter<Optional<Vector<uint8_t>>, blink::ScriptValue> {
176 static WTF::Optional<WTF::Vector<uint8_t>> Convert( 177 static Optional<Vector<uint8_t>> Convert(
177 const blink::ScriptValue& scriptValue) { 178 const blink::ScriptValue& scriptValue) {
178 v8::Local<v8::Value> value = scriptValue.V8Value(); 179 v8::Local<v8::Value> value = scriptValue.V8Value();
179 180
180 if (value->IsNumber()) 181 if (value->IsNumber()) {
181 return mojo::ConvertTo<WTF::Vector<uint8_t>>( 182 return mojo::ConvertTo<Vector<uint8_t>>(
182 WTF::String::Number(value.As<v8::Number>()->Value())); 183 String::Number(value.As<v8::Number>()->Value()));
184 }
183 185
184 if (value->IsString()) { 186 if (value->IsString()) {
185 blink::V8StringResource<> stringResource = value; 187 blink::V8StringResource<> stringResource = value;
186 if (stringResource.Prepare()) { 188 if (stringResource.Prepare()) {
187 return mojo::ConvertTo<WTF::Vector<uint8_t>>( 189 return mojo::ConvertTo<Vector<uint8_t>>(String(stringResource));
188 WTF::String(stringResource));
189 } 190 }
190 } 191 }
191 192
192 if (value->IsObject() && !value->IsArray() && !value->IsArrayBuffer()) { 193 if (value->IsObject() && !value->IsArray() && !value->IsArrayBuffer()) {
193 v8::Local<v8::String> jsonString; 194 v8::Local<v8::String> jsonString;
194 if (v8::JSON::Stringify(scriptValue.GetContext(), value.As<v8::Object>()) 195 v8::Isolate* isolate = scriptValue.GetIsolate();
195 .ToLocal(&jsonString)) { 196 v8::TryCatch try_catch(isolate);
196 WTF::String wtfString = blink::V8StringToWebCoreString<WTF::String>( 197
197 jsonString, blink::kDoNotExternalize); 198 // https://w3c.github.io/web-nfc/#mapping-json-to-ndef
198 return mojo::ConvertTo<WTF::Vector<uint8_t>>(wtfString); 199 // If serialization throws, reject promise with a "SyntaxError" exception.
200 if (!v8::JSON::Stringify(scriptValue.GetContext(), value.As<v8::Object>())
201 .ToLocal(&jsonString) ||
202 try_catch.HasCaught()) {
203 return WTF::nullopt;
199 } 204 }
205
206 String string = blink::V8StringToWebCoreString<String>(
207 jsonString, blink::kDoNotExternalize);
208 return mojo::ConvertTo<Vector<uint8_t>>(string);
200 } 209 }
201 210
202 if (value->IsArrayBuffer()) 211 if (value->IsArrayBuffer())
203 return mojo::ConvertTo<WTF::Vector<uint8_t>>( 212 return mojo::ConvertTo<Vector<uint8_t>>(
204 blink::V8ArrayBuffer::toImpl(value.As<v8::Object>())); 213 blink::V8ArrayBuffer::toImpl(value.As<v8::Object>()));
205 214
206 return WTF::nullopt; 215 return WTF::nullopt;
207 } 216 }
208 }; 217 };
209 218
210 template <> 219 template <>
211 struct TypeConverter<NFCRecordPtr, blink::NFCRecord> { 220 struct TypeConverter<NFCRecordPtr, blink::NFCRecord> {
212 static NFCRecordPtr Convert(const blink::NFCRecord& record) { 221 static NFCRecordPtr Convert(const blink::NFCRecord& record) {
213 NFCRecordPtr recordPtr = NFCRecord::New(); 222 NFCRecordPtr recordPtr = NFCRecord::New();
(...skipping 18 matching lines...) Expand all
232 setMediaType(recordPtr, record.mediaType(), kJsonMimeType); 241 setMediaType(recordPtr, record.mediaType(), kJsonMimeType);
233 break; 242 break;
234 case NFCRecordType::OPAQUE_RECORD: 243 case NFCRecordType::OPAQUE_RECORD:
235 setMediaType(recordPtr, record.mediaType(), kOpaqueMimeType); 244 setMediaType(recordPtr, record.mediaType(), kOpaqueMimeType);
236 break; 245 break;
237 default: 246 default:
238 NOTREACHED(); 247 NOTREACHED();
239 break; 248 break;
240 } 249 }
241 250
242 auto recordData = 251 auto recordData = mojo::ConvertTo<Optional<Vector<uint8_t>>>(record.data());
243 mojo::ConvertTo<WTF::Optional<WTF::Vector<uint8_t>>>(record.data());
244 // If JS object cannot be converted to uint8_t array, return null, 252 // If JS object cannot be converted to uint8_t array, return null,
245 // interrupt NFCMessage conversion algorithm and reject promise with 253 // interrupt NFCMessage conversion algorithm and reject promise with
246 // SyntaxError exception. 254 // SyntaxError exception.
247 if (!recordData) 255 if (!recordData)
248 return nullptr; 256 return nullptr;
249 257
250 recordPtr->data = recordData.value(); 258 recordPtr->data = recordData.value();
251 return recordPtr; 259 return recordPtr;
252 } 260 }
253 }; 261 };
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 354
347 return watchOptionsPtr; 355 return watchOptionsPtr;
348 } 356 }
349 }; 357 };
350 358
351 } // namespace mojo 359 } // namespace mojo
352 360
353 namespace blink { 361 namespace blink {
354 namespace { 362 namespace {
355 363
356 bool IsValidTextRecord(const NFCRecord& record) { 364 ScriptPromise RejectWithTypeError(ScriptState* script_state,
365 const String& message) {
366 return ScriptPromise::Reject(
367 script_state,
368 V8ThrowException::CreateTypeError(script_state->GetIsolate(), message));
369 }
370
371 ScriptPromise RejectWithDOMException(ScriptState* script_state,
372 ExceptionCode ec,
373 const String& message) {
374 return ScriptPromise::RejectWithDOMException(
375 script_state, DOMException::Create(ec, message));
376 }
377
378 ScriptPromise RejectIfInvalidTextRecord(ScriptState* script_state,
379 const NFCRecord& record) {
357 v8::Local<v8::Value> value = record.data().V8Value(); 380 v8::Local<v8::Value> value = record.data().V8Value();
358 if (!value->IsString() && 381 if (!value->IsString() &&
359 !(value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value()))) 382 !(value->IsNumber() && !std::isnan(value.As<v8::Number>()->Value()))) {
360 return false; 383 return RejectWithTypeError(script_state,
384 "The data for the 'text' NFCRecords must be of "
Reilly Grant (use Gerrit) 2017/05/18 21:49:37 "for the 'text' NFCRecords" -> "for 'text' NFCReco
shalamov 2017/05/19 07:03:03 Done.
385 "String or UnrestrctedDouble type.");
386 }
361 387
362 if (record.hasMediaType() && 388 if (record.hasMediaType() &&
363 !record.mediaType().StartsWith(kPlainTextMimePrefix, 389 !record.mediaType().StartsWith(kPlainTextMimePrefix,
364 kTextCaseUnicodeInsensitive)) 390 kTextCaseUnicodeInsensitive)) {
365 return false; 391 return RejectWithDOMException(script_state, kSyntaxError,
392 "Invalid media type for 'text' record.");
393 }
366 394
367 return true; 395 return ScriptPromise();
368 } 396 }
369 397
370 bool IsValidURLRecord(const NFCRecord& record) { 398 ScriptPromise RejectIfInvalidURLRecord(ScriptState* script_state,
371 if (!record.data().V8Value()->IsString()) 399 const NFCRecord& record) {
372 return false; 400 if (!record.data().V8Value()->IsString()) {
401 return RejectWithTypeError(
402 script_state,
403 "The data for the 'url' NFCRecord must be of String type.");
404 }
373 405
374 blink::V8StringResource<> string_resource = record.data().V8Value(); 406 blink::V8StringResource<> string_resource = record.data().V8Value();
375 if (!string_resource.Prepare()) 407 if (!string_resource.Prepare() || !KURL(KURL(), string_resource).IsValid()) {
376 return false; 408 return RejectWithDOMException(script_state, kSyntaxError,
409 "Cannot parse data for 'url' record.");
410 }
377 411
378 return KURL(KURL(), string_resource).IsValid(); 412 return ScriptPromise();
379 } 413 }
380 414
381 bool IsValidJSONRecord(const NFCRecord& record) { 415 ScriptPromise RejectIfInvalidJSONRecord(ScriptState* script_state,
416 const NFCRecord& record) {
382 v8::Local<v8::Value> value = record.data().V8Value(); 417 v8::Local<v8::Value> value = record.data().V8Value();
383 if (!value->IsObject() || value->IsArrayBuffer()) 418 if (!value->IsObject() || value->IsArrayBuffer()) {
384 return false; 419 return RejectWithTypeError(
420 script_state,
421 "The data for the 'json' NFCRecord must be of Object type.");
422 }
385 423
386 if (record.hasMediaType() && !record.mediaType().StartsWith( 424 // If JSON record has media type, it must be equal to "application/json" or
387 kJsonMimePrefix, kTextCaseASCIIInsensitive)) 425 // start with "application/" and end with "+json".
388 return false; 426 if (record.hasMediaType() &&
427 (record.mediaType() != kJsonMimeType &&
428 !(record.mediaType().StartsWith(kJsonMimePrefix,
429 kTextCaseASCIIInsensitive) &&
430 record.mediaType().EndsWith(kJsonMimePostfix,
431 kTextCaseASCIIInsensitive)))) {
432 return RejectWithDOMException(script_state, kSyntaxError,
433 "Invalid media type for 'json' record.");
434 }
389 435
390 return true; 436 return ScriptPromise();
391 } 437 }
392 438
393 bool IsValidOpaqueRecord(const NFCRecord& record) { 439 ScriptPromise RejectIfInvalidOpaqueRecord(ScriptState* script_state,
394 return record.data().V8Value()->IsArrayBuffer(); 440 const NFCRecord& record) {
441 if (!record.data().V8Value()->IsArrayBuffer()) {
442 return RejectWithTypeError(
443 script_state,
444 "The data for the 'opaque' NFCRecord must be of ArrayBuffer type.");
445 }
446
447 return ScriptPromise();
395 } 448 }
396 449
397 bool IsValidNFCRecord(const NFCRecord& record) { 450 ScriptPromise RejectIfInvalidNFCRecord(ScriptState* script_state,
451 const NFCRecord& record) {
398 device::nfc::mojom::blink::NFCRecordType type; 452 device::nfc::mojom::blink::NFCRecordType type;
399 if (record.hasRecordType()) { 453 if (record.hasRecordType()) {
400 type = mojo::toNFCRecordType(record.recordType()); 454 type = mojo::toNFCRecordType(record.recordType());
401 } else { 455 } else {
402 type = mojo::deduceRecordTypeFromDataType(record); 456 type = mojo::deduceRecordTypeFromDataType(record);
403 457
404 // https://w3c.github.io/web-nfc/#creating-web-nfc-message 458 // https://w3c.github.io/web-nfc/#creating-web-nfc-message
405 // If NFCRecord.recordType is not set and record type cannot be deduced 459 // If NFCRecord.recordType is not set and record type cannot be deduced
406 // from NFCRecord.data, reject promise with SyntaxError. 460 // from NFCRecord.data, reject promise with TypeError.
407 if (type == device::nfc::mojom::blink::NFCRecordType::EMPTY) 461 if (type == device::nfc::mojom::blink::NFCRecordType::EMPTY)
408 return false; 462 return RejectWithTypeError(script_state, "Unknown NFCRecord type.");
409 } 463 }
410 464
411 // Non-empty records must have data. 465 // Non-empty records must have data.
412 if (!record.hasData() && 466 if (!record.hasData() &&
413 (type != device::nfc::mojom::blink::NFCRecordType::EMPTY)) { 467 (type != device::nfc::mojom::blink::NFCRecordType::EMPTY)) {
414 return false; 468 return RejectWithTypeError(script_state,
469 "Nonempty NFCRecord must have data.");
415 } 470 }
416 471
417 switch (type) { 472 switch (type) {
418 case device::nfc::mojom::blink::NFCRecordType::TEXT: 473 case device::nfc::mojom::blink::NFCRecordType::TEXT:
419 return IsValidTextRecord(record); 474 return RejectIfInvalidTextRecord(script_state, record);
420 case device::nfc::mojom::blink::NFCRecordType::URL: 475 case device::nfc::mojom::blink::NFCRecordType::URL:
421 return IsValidURLRecord(record); 476 return RejectIfInvalidURLRecord(script_state, record);
422 case device::nfc::mojom::blink::NFCRecordType::JSON: 477 case device::nfc::mojom::blink::NFCRecordType::JSON:
423 return IsValidJSONRecord(record); 478 return RejectIfInvalidJSONRecord(script_state, record);
424 case device::nfc::mojom::blink::NFCRecordType::OPAQUE_RECORD: 479 case device::nfc::mojom::blink::NFCRecordType::OPAQUE_RECORD:
425 return IsValidOpaqueRecord(record); 480 return RejectIfInvalidOpaqueRecord(script_state, record);
426 case device::nfc::mojom::blink::NFCRecordType::EMPTY: 481 case device::nfc::mojom::blink::NFCRecordType::EMPTY:
427 return !record.hasData() && record.mediaType().IsEmpty(); 482 return ScriptPromise();
428 } 483 }
429 484
430 NOTREACHED(); 485 NOTREACHED();
431 return false; 486 return RejectWithTypeError(script_state,
487 "Invalid NFCRecordType was provided.");
432 } 488 }
433 489
434 bool IsValidNFCRecordArray(const HeapVector<NFCRecord>& records) { 490 ScriptPromise RejectIfInvalidNFCRecordArray(
435 if (records.IsEmpty()) 491 ScriptState* script_state,
436 return false; 492 const HeapVector<NFCRecord>& records) {
437
438 for (const auto& record : records) { 493 for (const auto& record : records) {
439 if (!IsValidNFCRecord(record)) 494 ScriptPromise isValidRecord =
440 return false; 495 RejectIfInvalidNFCRecord(script_state, record);
496 if (!isValidRecord.IsEmpty())
497 return isValidRecord;
441 } 498 }
442 499
443 return true; 500 return ScriptPromise();
444 } 501 }
445 502
446 bool IsValidNFCPushMessage(const NFCPushMessage& message) { 503 ScriptPromise RejectIfInvalidNFCPushMessage(
504 ScriptState* script_state,
505 const NFCPushMessage& push_message) {
447 // If NFCPushMessage of invalid type, reject promise with TypeError 506 // If NFCPushMessage of invalid type, reject promise with TypeError
448 if (!message.isNFCMessage() && !message.isString() && 507 if (!push_message.isNFCMessage() && !push_message.isString() &&
449 !message.isArrayBuffer()) 508 !push_message.isArrayBuffer()) {
450 return false; 509 return RejectWithTypeError(script_state,
510 "Invalid NFCPushMessage type was provided.");
511 }
451 512
452 if (message.isNFCMessage()) { 513 if (push_message.isNFCMessage()) {
453 // https://w3c.github.io/web-nfc/#the-push-method 514 // https://w3c.github.io/web-nfc/#the-push-method
454 // If NFCMessage.data is empty, reject promise with TypeError 515 // If NFCMessage.data is empty, reject promise with TypeError
455 if (!message.getAsNFCMessage().hasData()) 516 const NFCMessage& message = push_message.getAsNFCMessage();
456 return false; 517 if (!message.hasData() || message.data().IsEmpty()) {
518 return RejectWithTypeError(script_state,
519 "Empty NFCMessage was provided.");
520 }
457 521
458 return IsValidNFCRecordArray(message.getAsNFCMessage().data()); 522 return RejectIfInvalidNFCRecordArray(script_state, message.data());
459 } 523 }
460 524
461 return true; 525 return ScriptPromise();
462 } 526 }
463 527
464 bool SetURL(const String& origin, 528 bool SetURL(const String& origin,
465 device::nfc::mojom::blink::NFCMessagePtr& message) { 529 device::nfc::mojom::blink::NFCMessagePtr& message) {
466 KURL origin_url(kParsedURLString, origin); 530 KURL origin_url(kParsedURLString, origin);
467 531
468 if (!message->url.IsEmpty() && origin_url.CanSetPathname()) { 532 if (!message->url.IsEmpty() && origin_url.CanSetPathname()) {
469 origin_url.SetPath(message->url); 533 origin_url.SetPath(message->url);
470 } 534 }
471 535
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 678
615 // https://w3c.github.io/web-nfc/#writing-or-pushing-content 679 // https://w3c.github.io/web-nfc/#writing-or-pushing-content
616 // https://w3c.github.io/web-nfc/#dom-nfc-push 680 // https://w3c.github.io/web-nfc/#dom-nfc-push
617 ScriptPromise NFC::push(ScriptState* script_state, 681 ScriptPromise NFC::push(ScriptState* script_state,
618 const NFCPushMessage& push_message, 682 const NFCPushMessage& push_message,
619 const NFCPushOptions& options) { 683 const NFCPushOptions& options) {
620 ScriptPromise promise = RejectIfNotSupported(script_state); 684 ScriptPromise promise = RejectIfNotSupported(script_state);
621 if (!promise.IsEmpty()) 685 if (!promise.IsEmpty())
622 return promise; 686 return promise;
623 687
624 if (!IsValidNFCPushMessage(push_message)) { 688 ScriptPromise isValidMessage =
625 return ScriptPromise::Reject( 689 RejectIfInvalidNFCPushMessage(script_state, push_message);
626 script_state, V8ThrowException::CreateTypeError( 690 if (!isValidMessage.IsEmpty())
627 script_state->GetIsolate(), 691 return isValidMessage;
628 "Invalid NFCPushMessage type was provided."));
629 }
630 692
631 // https://w3c.github.io/web-nfc/#dom-nfc-push 693 // https://w3c.github.io/web-nfc/#dom-nfc-push
632 // 9. If timeout value is NaN or negative, reject promise with "TypeError" 694 // 9. If timeout value is NaN or negative, reject promise with "TypeError"
633 // and abort these steps. 695 // and abort these steps.
634 if (options.hasTimeout() && 696 if (options.hasTimeout() &&
635 (std::isnan(options.timeout()) || options.timeout() < 0)) { 697 (std::isnan(options.timeout()) || options.timeout() < 0)) {
636 return ScriptPromise::Reject( 698 return RejectWithTypeError(
637 script_state, 699 script_state, "Invalid NFCPushOptions.timeout value was provided.");
638 V8ThrowException::CreateTypeError(
639 script_state->GetIsolate(),
640 "Invalid NFCPushOptions.timeout value was provided."));
641 } 700 }
642 701
643 device::nfc::mojom::blink::NFCMessagePtr message = 702 device::nfc::mojom::blink::NFCMessagePtr message =
644 device::nfc::mojom::blink::NFCMessage::From(push_message); 703 device::nfc::mojom::blink::NFCMessage::From(push_message);
645 if (!message) 704 if (!message) {
646 return ScriptPromise::RejectWithDOMException( 705 return RejectWithDOMException(script_state, kSyntaxError,
647 script_state, DOMException::Create(kSyntaxError)); 706 "Cannot convert NFCMessage.");
707 }
648 708
649 if (!SetURL( 709 if (!SetURL(
650 ExecutionContext::From(script_state)->GetSecurityOrigin()->ToString(), 710 ExecutionContext::From(script_state)->GetSecurityOrigin()->ToString(),
651 message)) 711 message)) {
652 return ScriptPromise::RejectWithDOMException( 712 return RejectWithDOMException(script_state, kSyntaxError,
653 script_state, DOMException::Create(kSyntaxError)); 713 "Cannot set WebNFC Id.");
714 }
654 715
655 if (GetNFCMessageSize(message) > 716 if (GetNFCMessageSize(message) >
656 device::nfc::mojom::blink::NFCMessage::kMaxSize) { 717 device::nfc::mojom::blink::NFCMessage::kMaxSize) {
657 return ScriptPromise::RejectWithDOMException( 718 return RejectWithDOMException(script_state, kNotSupportedError,
658 script_state, DOMException::Create(kNotSupportedError)); 719 "NFCMessage exceeds maximum supported size.");
659 } 720 }
660 721
661 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 722 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
662 requests_.insert(resolver); 723 requests_.insert(resolver);
663 auto callback = ConvertToBaseCallback(WTF::Bind(&NFC::OnRequestCompleted, 724 auto callback = ConvertToBaseCallback(WTF::Bind(&NFC::OnRequestCompleted,
664 WrapPersistent(this), 725 WrapPersistent(this),
665 WrapPersistent(resolver))); 726 WrapPersistent(resolver)));
666 nfc_->Push(std::move(message), 727 nfc_->Push(std::move(message),
667 device::nfc::mojom::blink::NFCPushOptions::From(options), 728 device::nfc::mojom::blink::NFCPushOptions::From(options),
668 callback); 729 callback);
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 769
709 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch 770 // https://w3c.github.io/web-nfc/#dom-nfc-cancelwatch
710 ScriptPromise NFC::cancelWatch(ScriptState* script_state, long id) { 771 ScriptPromise NFC::cancelWatch(ScriptState* script_state, long id) {
711 ScriptPromise promise = RejectIfNotSupported(script_state); 772 ScriptPromise promise = RejectIfNotSupported(script_state);
712 if (!promise.IsEmpty()) 773 if (!promise.IsEmpty())
713 return promise; 774 return promise;
714 775
715 if (id) { 776 if (id) {
716 callbacks_.erase(id); 777 callbacks_.erase(id);
717 } else { 778 } else {
718 return ScriptPromise::RejectWithDOMException( 779 return RejectWithDOMException(script_state, kNotFoundError,
719 script_state, DOMException::Create(kNotFoundError)); 780 "Provided watch id cannot be found.");
720 } 781 }
721 782
722 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); 783 ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
723 requests_.insert(resolver); 784 requests_.insert(resolver);
724 nfc_->CancelWatch(id, ConvertToBaseCallback(WTF::Bind( 785 nfc_->CancelWatch(id, ConvertToBaseCallback(WTF::Bind(
725 &NFC::OnRequestCompleted, WrapPersistent(this), 786 &NFC::OnRequestCompleted, WrapPersistent(this),
726 WrapPersistent(resolver)))); 787 WrapPersistent(resolver))));
727 return resolver->Promise(); 788 return resolver->Promise();
728 } 789 }
729 790
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
774 835
775 // If NFCService is not available or disappears when NFC hardware is 836 // If NFCService is not available or disappears when NFC hardware is
776 // disabled, reject promise with NotSupportedError exception. 837 // disabled, reject promise with NotSupportedError exception.
777 for (ScriptPromiseResolver* resolver : requests_) 838 for (ScriptPromiseResolver* resolver : requests_)
778 resolver->Reject(NFCError::Take( 839 resolver->Reject(NFCError::Take(
779 resolver, device::nfc::mojom::blink::NFCErrorType::NOT_SUPPORTED)); 840 resolver, device::nfc::mojom::blink::NFCErrorType::NOT_SUPPORTED));
780 841
781 requests_.clear(); 842 requests_.clear();
782 } 843 }
783 844
784 void NFC::OnWatch(const WTF::Vector<uint32_t>& ids, 845 void NFC::OnWatch(const Vector<uint32_t>& ids,
785 device::nfc::mojom::blink::NFCMessagePtr message) { 846 device::nfc::mojom::blink::NFCMessagePtr message) {
786 for (const auto& id : ids) { 847 for (const auto& id : ids) {
787 auto it = callbacks_.find(id); 848 auto it = callbacks_.find(id);
788 if (it != callbacks_.end()) { 849 if (it != callbacks_.end()) {
789 MessageCallback* callback = it->value; 850 MessageCallback* callback = it->value;
790 ScriptState* script_state = callback->GetScriptState(); 851 ScriptState* script_state = callback->GetScriptState();
791 DCHECK(script_state); 852 DCHECK(script_state);
792 ScriptState::Scope scope(script_state); 853 ScriptState::Scope scope(script_state);
793 NFCMessage nfc_message = ToNFCMessage(script_state, message); 854 NFCMessage nfc_message = ToNFCMessage(script_state, message);
794 callback->handleMessage(nfc_message); 855 callback->handleMessage(nfc_message);
(...skipping 15 matching lines...) Expand all
810 return false; 871 return false;
811 } 872 }
812 873
813 return true; 874 return true;
814 } 875 }
815 876
816 ScriptPromise NFC::RejectIfNotSupported(ScriptState* script_state) { 877 ScriptPromise NFC::RejectIfNotSupported(ScriptState* script_state) {
817 String error_message; 878 String error_message;
818 if (!IsSupportedInContext(ExecutionContext::From(script_state), 879 if (!IsSupportedInContext(ExecutionContext::From(script_state),
819 error_message)) { 880 error_message)) {
820 return ScriptPromise::RejectWithDOMException( 881 return RejectWithDOMException(script_state, kSecurityError, error_message);
821 script_state, DOMException::Create(kSecurityError, error_message));
822 } 882 }
823 883
824 if (!nfc_) { 884 if (!nfc_) {
825 return ScriptPromise::RejectWithDOMException( 885 return RejectWithDOMException(script_state, kNotSupportedError,
826 script_state, DOMException::Create(kNotSupportedError)); 886 "WebNFC is not supported.");
827 } 887 }
828 888
829 return ScriptPromise(); 889 return ScriptPromise();
830 } 890 }
831 891
832 void NFC::OnWatchRegistered(MessageCallback* callback, 892 void NFC::OnWatchRegistered(MessageCallback* callback,
833 ScriptPromiseResolver* resolver, 893 ScriptPromiseResolver* resolver,
834 uint32_t id, 894 uint32_t id,
835 device::nfc::mojom::blink::NFCErrorPtr error) { 895 device::nfc::mojom::blink::NFCErrorPtr error) {
836 requests_.erase(resolver); 896 requests_.erase(resolver);
(...skipping 17 matching lines...) Expand all
854 } 914 }
855 915
856 DEFINE_TRACE(NFC) { 916 DEFINE_TRACE(NFC) {
857 PageVisibilityObserver::Trace(visitor); 917 PageVisibilityObserver::Trace(visitor);
858 ContextLifecycleObserver::Trace(visitor); 918 ContextLifecycleObserver::Trace(visitor);
859 visitor->Trace(requests_); 919 visitor->Trace(requests_);
860 visitor->Trace(callbacks_); 920 visitor->Trace(callbacks_);
861 } 921 }
862 922
863 } // namespace blink 923 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/modules/nfc/NFC.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698