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

Side by Side Diff: device/nfc/android/java/src/org/chromium/device/nfc/NfcTypeConverter.java

Issue 2894373002: [DeviceService] Move //device/nfc to be part of the internal impl of Device Service (Closed)
Patch Set: Modify code comment 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
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.device.nfc;
6
7 import android.net.Uri;
8 import android.nfc.NdefMessage;
9 import android.nfc.NdefRecord;
10 import android.os.Build;
11
12 import org.chromium.base.Log;
13 import org.chromium.device.nfc.mojom.NfcMessage;
14 import org.chromium.device.nfc.mojom.NfcRecord;
15 import org.chromium.device.nfc.mojom.NfcRecordType;
16
17 import java.io.UnsupportedEncodingException;
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21
22 /**
23 * Utility class that provides convesion between Android NdefMessage
24 * and mojo NfcMessage data structures.
25 */
26 public final class NfcTypeConverter {
27 private static final String TAG = "NfcTypeConverter";
28 private static final String DOMAIN = "w3.org";
29 private static final String TYPE = "webnfc";
30 private static final String WEBNFC_URN = DOMAIN + ":" + TYPE;
31 private static final String TEXT_MIME = "text/plain";
32 private static final String JSON_MIME = "application/json";
33 private static final String CHARSET_UTF8 = ";charset=UTF-8";
34 private static final String CHARSET_UTF16 = ";charset=UTF-16";
35
36 /**
37 * Converts mojo NfcMessage to android.nfc.NdefMessage
38 */
39 public static NdefMessage toNdefMessage(NfcMessage message) throws InvalidNf cMessageException {
40 try {
41 List<NdefRecord> records = new ArrayList<NdefRecord>();
42 for (int i = 0; i < message.data.length; ++i) {
43 records.add(toNdefRecord(message.data[i]));
44 }
45 records.add(NdefRecord.createExternal(DOMAIN, TYPE, message.url.getB ytes("UTF-8")));
46 NdefRecord[] ndefRecords = new NdefRecord[records.size()];
47 records.toArray(ndefRecords);
48 return new NdefMessage(ndefRecords);
49 } catch (UnsupportedEncodingException | InvalidNfcMessageException
50 | IllegalArgumentException e) {
51 throw new InvalidNfcMessageException();
52 }
53 }
54
55 /**
56 * Converts android.nfc.NdefMessage to mojo NfcMessage
57 */
58 public static NfcMessage toNfcMessage(NdefMessage ndefMessage)
59 throws UnsupportedEncodingException {
60 NdefRecord[] ndefRecords = ndefMessage.getRecords();
61 NfcMessage nfcMessage = new NfcMessage();
62 List<NfcRecord> nfcRecords = new ArrayList<NfcRecord>();
63
64 for (int i = 0; i < ndefRecords.length; i++) {
65 if ((ndefRecords[i].getTnf() == NdefRecord.TNF_EXTERNAL_TYPE)
66 && (Arrays.equals(ndefRecords[i].getType(), WEBNFC_URN.getBy tes("UTF-8")))) {
67 nfcMessage.url = new String(ndefRecords[i].getPayload(), "UTF-8" );
68 continue;
69 }
70
71 NfcRecord nfcRecord = toNfcRecord(ndefRecords[i]);
72 if (nfcRecord != null) nfcRecords.add(nfcRecord);
73 }
74
75 nfcMessage.data = new NfcRecord[nfcRecords.size()];
76 nfcRecords.toArray(nfcMessage.data);
77 return nfcMessage;
78 }
79
80 /**
81 * Returns charset of mojo NfcRecord. Only applicable for URL and TEXT recor ds.
82 * If charset cannot be determined, UTF-8 charset is used by default.
83 */
84 private static String getCharset(NfcRecord record) {
85 if (record.mediaType.endsWith(CHARSET_UTF8)) return "UTF-8";
86
87 // When 16bit WTF::String data is converted to bytearray, it is in LE by te order, without
88 // BOM. By default, Android interprets UTF-16 charset without BOM as UTF -16BE, thus, use
89 // UTF-16LE as encoding for text data.
90
91 if (record.mediaType.endsWith(CHARSET_UTF16)) return "UTF-16LE";
92
93 Log.w(TAG, "Unknown charset, defaulting to UTF-8.");
94 return "UTF-8";
95 }
96
97 /**
98 * Converts mojo NfcRecord to android.nfc.NdefRecord
99 */
100 private static NdefRecord toNdefRecord(NfcRecord record) throws InvalidNfcMe ssageException,
101 IllegalArgum entException,
102 UnsupportedE ncodingException {
103 switch (record.recordType) {
104 case NfcRecordType.URL:
105 return NdefRecord.createUri(new String(record.data, getCharset(r ecord)));
106 case NfcRecordType.TEXT:
107 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
108 return NdefRecord.createTextRecord(
109 "en-US", new String(record.data, getCharset(record)) );
110 } else {
111 return NdefRecord.createMime(TEXT_MIME, record.data);
112 }
113 case NfcRecordType.JSON:
114 case NfcRecordType.OPAQUE_RECORD:
115 return NdefRecord.createMime(record.mediaType, record.data);
116 default:
117 throw new InvalidNfcMessageException();
118 }
119 }
120
121 /**
122 * Converts android.nfc.NdefRecord to mojo NfcRecord
123 */
124 private static NfcRecord toNfcRecord(NdefRecord ndefRecord)
125 throws UnsupportedEncodingException {
126 switch (ndefRecord.getTnf()) {
127 case NdefRecord.TNF_EMPTY:
128 return createEmptyRecord();
129 case NdefRecord.TNF_MIME_MEDIA:
130 return createMIMERecord(
131 new String(ndefRecord.getType(), "UTF-8"), ndefRecord.ge tPayload());
132 case NdefRecord.TNF_ABSOLUTE_URI:
133 return createURLRecord(ndefRecord.toUri());
134 case NdefRecord.TNF_WELL_KNOWN:
135 return createWellKnownRecord(ndefRecord);
136 }
137 return null;
138 }
139
140 /**
141 * Constructs empty NdefMessage
142 */
143 public static NdefMessage emptyNdefMessage() {
144 return new NdefMessage(new NdefRecord(NdefRecord.TNF_EMPTY, null, null, null));
145 }
146
147 /**
148 * Constructs empty NfcRecord
149 */
150 private static NfcRecord createEmptyRecord() {
151 NfcRecord nfcRecord = new NfcRecord();
152 nfcRecord.recordType = NfcRecordType.EMPTY;
153 nfcRecord.mediaType = "";
154 nfcRecord.data = new byte[0];
155 return nfcRecord;
156 }
157
158 /**
159 * Constructs URL NfcRecord
160 */
161 private static NfcRecord createURLRecord(Uri uri) {
162 if (uri == null) return null;
163 NfcRecord nfcRecord = new NfcRecord();
164 nfcRecord.recordType = NfcRecordType.URL;
165 nfcRecord.mediaType = TEXT_MIME;
166 nfcRecord.data = uri.toString().getBytes();
167 return nfcRecord;
168 }
169
170 /**
171 * Constructs MIME or JSON NfcRecord
172 */
173 private static NfcRecord createMIMERecord(String mediaType, byte[] payload) {
174 NfcRecord nfcRecord = new NfcRecord();
175 if (mediaType.equals(JSON_MIME)) {
176 nfcRecord.recordType = NfcRecordType.JSON;
177 } else {
178 nfcRecord.recordType = NfcRecordType.OPAQUE_RECORD;
179 }
180 nfcRecord.mediaType = mediaType;
181 nfcRecord.data = payload;
182 return nfcRecord;
183 }
184
185 /**
186 * Constructs TEXT NfcRecord
187 */
188 private static NfcRecord createTextRecord(byte[] text) {
189 // Check that text byte array is not empty.
190 if (text.length == 0) {
191 return null;
192 }
193
194 NfcRecord nfcRecord = new NfcRecord();
195 nfcRecord.recordType = NfcRecordType.TEXT;
196 nfcRecord.mediaType = TEXT_MIME;
197 // According to NFCForum-TS-RTD_Text_1.0 specification, section 3.2.1 Sy ntax.
198 // First byte of the payload is status byte, defined in Table 3: Status Byte Encodings.
199 // 0-5: lang code length
200 // 6 : must be zero
201 // 8 : 0 - text is in UTF-8 encoding, 1 - text is in UTF-16 encoding.
202 int langCodeLength = (text[0] & (byte) 0x3F);
203 int textBodyStartPos = langCodeLength + 1;
204 if (textBodyStartPos > text.length) {
205 return null;
206 }
207 nfcRecord.data = Arrays.copyOfRange(text, textBodyStartPos, text.length) ;
208 return nfcRecord;
209 }
210
211 /**
212 * Constructs well known type (TEXT or URI) NfcRecord
213 */
214 private static NfcRecord createWellKnownRecord(NdefRecord record) {
215 if (Arrays.equals(record.getType(), NdefRecord.RTD_URI)) {
216 return createURLRecord(record.toUri());
217 }
218
219 if (Arrays.equals(record.getType(), NdefRecord.RTD_TEXT)) {
220 return createTextRecord(record.getPayload());
221 }
222
223 return null;
224 }
225 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698