OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 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 package org.chromium.chrome.browser.omnibox.geo; | 5 package org.chromium.chrome.browser.omnibox.geo; |
6 | 6 |
7 import static org.junit.Assert.assertEquals; | 7 import static org.junit.Assert.assertEquals; |
8 import static org.junit.Assert.assertFalse; | 8 import static org.junit.Assert.assertFalse; |
9 import static org.junit.Assert.assertNotEquals; | 9 import static org.junit.Assert.assertNotEquals; |
10 import static org.junit.Assert.assertNull; | |
10 import static org.junit.Assert.assertTrue; | 11 import static org.junit.Assert.assertTrue; |
11 | 12 |
13 import android.util.Base64; | |
14 | |
15 import com.google.protobuf.nano.MessageNano; | |
16 | |
12 import org.junit.Test; | 17 import org.junit.Test; |
13 import org.junit.runner.RunWith; | 18 import org.junit.runner.RunWith; |
14 import org.robolectric.annotation.Config; | 19 import org.robolectric.annotation.Config; |
15 | 20 |
16 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell; | 21 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell; |
17 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell.Radio Type; | 22 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleCell.Radio Type; |
18 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi; | 23 import org.chromium.chrome.browser.omnibox.geo.VisibleNetworks.VisibleWifi; |
19 import org.chromium.testing.local.LocalRobolectricTestRunner; | 24 import org.chromium.testing.local.LocalRobolectricTestRunner; |
20 | 25 |
21 import java.util.Arrays; | 26 import java.util.Arrays; |
(...skipping 21 matching lines...) Expand all Loading... | |
43 private static final VisibleWifi VISIBLE_WIFI1 = | 48 private static final VisibleWifi VISIBLE_WIFI1 = |
44 VisibleWifi.create(SSID1, BSSID1, LEVEL1, TIMESTAMP1); | 49 VisibleWifi.create(SSID1, BSSID1, LEVEL1, TIMESTAMP1); |
45 private static final VisibleWifi VISIBLE_WIFI2 = | 50 private static final VisibleWifi VISIBLE_WIFI2 = |
46 VisibleWifi.create(SSID2, BSSID2, LEVEL2, TIMESTAMP2); | 51 VisibleWifi.create(SSID2, BSSID2, LEVEL2, TIMESTAMP2); |
47 private static VisibleCell.Builder sVisibleCellCommunBuilder = | 52 private static VisibleCell.Builder sVisibleCellCommunBuilder = |
48 VisibleCell.builder(VisibleCell.GSM_RADIO_TYPE) | 53 VisibleCell.builder(VisibleCell.GSM_RADIO_TYPE) |
49 .setCellId(10) | 54 .setCellId(10) |
50 .setLocationAreaCode(11) | 55 .setLocationAreaCode(11) |
51 .setMobileCountryCode(12) | 56 .setMobileCountryCode(12) |
52 .setMobileNetworkCode(13); | 57 .setMobileNetworkCode(13); |
53 private static final VisibleCell VISIBLE_CELL1 = | 58 private static final VisibleCell VISIBLE_CELL1 = sVisibleCellCommunBuilder.s etPhysicalCellId(14) |
54 sVisibleCellCommunBuilder.setTimestamp(10L).build(); | 59 .setPrimaryScrambli ngCode(15) |
60 .setTrackingAreaCod e(16) | |
61 .setTimestamp(10L) | |
62 .build(); | |
55 private static final VisibleCell VISIBLE_CELL1_DIFFERENT_TIMESTAMP = | 63 private static final VisibleCell VISIBLE_CELL1_DIFFERENT_TIMESTAMP = |
56 sVisibleCellCommunBuilder.setTimestamp(20L).build(); | 64 sVisibleCellCommunBuilder.setTimestamp(20L).build(); |
57 private static final VisibleCell VISIBLE_CELL2 = VisibleCell.builder(Visible Cell.GSM_RADIO_TYPE) | 65 private static final VisibleCell VISIBLE_CELL2 = VisibleCell.builder(Visible Cell.GSM_RADIO_TYPE) |
58 .setCellId(30) | 66 .setCellId(30) |
59 .setLocationAreaCod e(31) | 67 .setLocationAreaCod e(31) |
60 .setMobileCountryCo de(32) | 68 .setMobileCountryCo de(32) |
61 .setMobileNetworkCo de(33) | 69 .setMobileNetworkCo de(33) |
62 .setTimestamp(30L) | 70 .setTimestamp(30L) |
63 .build(); | 71 .build(); |
72 private static final VisibleCell EMPTY_CELL = | |
73 VisibleCell.builder(VisibleCell.UNKNOWN_RADIO_TYPE).build(); | |
74 private static final VisibleWifi EMPTY_WIFI = VisibleWifi.create(null, null, null, null); | |
75 | |
64 private static Set<VisibleCell> sAllVisibleCells = | 76 private static Set<VisibleCell> sAllVisibleCells = |
65 new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2) ); | 77 new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2) ); |
66 private static Set<VisibleCell> sAllVisibleCells2 = new HashSet<VisibleCell> ( | 78 private static Set<VisibleCell> sAllVisibleCells2 = new HashSet<VisibleCell> ( |
67 Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2, VISIBLE_CELL1_DIFFERENT_ TIMESTAMP)); | 79 Arrays.asList(VISIBLE_CELL1, VISIBLE_CELL2, VISIBLE_CELL1_DIFFERENT_ TIMESTAMP)); |
68 private static Set<VisibleWifi> sAllVisibleWifis = | 80 private static Set<VisibleWifi> sAllVisibleWifis = |
69 new HashSet<VisibleWifi>(Arrays.asList(VISIBLE_WIFI1, VISIBLE_WIFI2) ); | 81 new HashSet<VisibleWifi>(Arrays.asList(VISIBLE_WIFI1, VISIBLE_WIFI2) ); |
70 | 82 |
71 private static final VisibleNetworks VISIBLE_NETWORKS1 = VisibleNetworks.cre ate( | 83 private static final VisibleNetworks VISIBLE_NETWORKS1 = VisibleNetworks.cre ate( |
72 VISIBLE_WIFI1, VISIBLE_CELL1, sAllVisibleWifis, sAllVisibleCells); | 84 VISIBLE_WIFI1, VISIBLE_CELL1, sAllVisibleWifis, sAllVisibleCells); |
73 | 85 |
74 private static final VisibleNetworks VISIBLE_NETWORKS2 = VisibleNetworks.cre ate( | 86 private static final VisibleNetworks VISIBLE_NETWORKS2 = VisibleNetworks.cre ate( |
75 VISIBLE_WIFI2, VISIBLE_CELL2, sAllVisibleWifis, sAllVisibleCells2); | 87 VISIBLE_WIFI2, VISIBLE_CELL2, sAllVisibleWifis, sAllVisibleCells2); |
76 | 88 |
89 private static final String VISIBLE_CELL1_PROTO_ENCODED = | |
90 "CAEQDLoBFhIQCAEQChgLIAwoDTAPOA5AEBgBIAo="; | |
91 private static final String VISIBLE_WIFI1_PROTO_ENCODED = | |
92 "CAEQDLoBJAoeChExMToxMToxMToxMToxMToxMRD___________8BGAEgCg=="; | |
93 private static final String EMPTY_CELL_PROTO_ENCODED = "CAEQDLoBBhICCAAYAQ== "; | |
94 private static final String EMPTY_WIFI_PROTO_ENCODED = "CAEQDLoBBAoAGAE="; | |
95 | |
77 @Test | 96 @Test |
78 public void testVisibleWifiCreate() { | 97 public void testVisibleWifiCreate() { |
79 VisibleWifi visibleWifi = VisibleWifi.create(SSID1, BSSID1, LEVEL1, TIME STAMP1); | 98 VisibleWifi visibleWifi = VisibleWifi.create(SSID1, BSSID1, LEVEL1, TIME STAMP1); |
80 assertEquals(SSID1, visibleWifi.ssid()); | 99 assertEquals(SSID1, visibleWifi.ssid()); |
81 assertEquals(BSSID1, visibleWifi.bssid()); | 100 assertEquals(BSSID1, visibleWifi.bssid()); |
82 assertEquals(LEVEL1, visibleWifi.level()); | 101 assertEquals(LEVEL1, visibleWifi.level()); |
83 assertEquals(TIMESTAMP1, visibleWifi.timestampMs()); | 102 assertEquals(TIMESTAMP1, visibleWifi.timestampMs()); |
84 } | 103 } |
85 | 104 |
86 @Test | 105 @Test |
(...skipping 25 matching lines...) Expand all Loading... | |
112 | 131 |
113 @Test | 132 @Test |
114 public void testVisibleWifiHashDifferentLevelAndTimestamp() { | 133 public void testVisibleWifiHashDifferentLevelAndTimestamp() { |
115 VisibleWifi visibleWifi3 = VisibleWifi.create(SSID2, BSSID2, LEVEL1, TIM ESTAMP1); | 134 VisibleWifi visibleWifi3 = VisibleWifi.create(SSID2, BSSID2, LEVEL1, TIM ESTAMP1); |
116 // visibleWifi3 has the same ssid and bssid as VISIBLE_WIFI2 but differe nt level and | 135 // visibleWifi3 has the same ssid and bssid as VISIBLE_WIFI2 but differe nt level and |
117 // timestamp. The level and timestamp are excluded from the VisibleWifi hash function. | 136 // timestamp. The level and timestamp are excluded from the VisibleWifi hash function. |
118 assertEquals(VISIBLE_WIFI2.hashCode(), visibleWifi3.hashCode()); | 137 assertEquals(VISIBLE_WIFI2.hashCode(), visibleWifi3.hashCode()); |
119 } | 138 } |
120 | 139 |
121 @Test | 140 @Test |
141 public void testVisibleWifiToProto() { | |
142 boolean connected = true; | |
143 PartnerLocationDescriptor.VisibleNetwork visibleNetwork = VISIBLE_WIFI1. toProto(connected); | |
144 PartnerLocationDescriptor.VisibleNetwork.WiFi wifi = visibleNetwork.wifi ; | |
145 | |
146 assertEquals(VISIBLE_WIFI1.bssid(), wifi.bssid); | |
147 assertEquals(VISIBLE_WIFI1.level(), wifi.levelDbm); | |
148 assertEquals(VISIBLE_WIFI1.timestampMs(), visibleNetwork.timestampMs); | |
149 assertEquals(connected, visibleNetwork.connected); | |
150 | |
151 assertEquals(VISIBLE_WIFI1_PROTO_ENCODED, encodeVisibleNetwork(visibleNe twork)); | |
152 } | |
153 | |
154 @Test | |
155 public void testVisibleWifiToProtoEmptyWifi() { | |
156 boolean connected = true; | |
157 PartnerLocationDescriptor.VisibleNetwork visibleNetwork = EMPTY_WIFI.toP roto(connected); | |
158 PartnerLocationDescriptor.VisibleNetwork.WiFi wifi = visibleNetwork.wifi ; | |
159 | |
160 assertNull(wifi.bssid); | |
161 assertNull(wifi.levelDbm); | |
162 assertNull(visibleNetwork.timestampMs); | |
163 assertEquals(connected, visibleNetwork.connected); | |
164 | |
165 assertEquals(EMPTY_WIFI_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwo rk)); | |
166 } | |
167 | |
168 @Test | |
122 public void testVisibleCellBuilder() { | 169 public void testVisibleCellBuilder() { |
123 for (@RadioType int radioType : RADIO_TYPES) { | 170 for (@RadioType int radioType : RADIO_TYPES) { |
124 VisibleCell visibleCell = VisibleCell.builder(radioType).build(); | 171 VisibleCell visibleCell = VisibleCell.builder(radioType).build(); |
125 assertEquals(radioType, visibleCell.radioType()); | 172 assertEquals(radioType, visibleCell.radioType()); |
126 } | 173 } |
127 } | 174 } |
128 | 175 |
129 @Test | 176 @Test |
130 public void testVisibleCellEquals() { | 177 public void testVisibleCellEquals() { |
131 VisibleCell copyOfVisibleCell1 = | 178 VisibleCell copyOfVisibleCell1 = |
132 VisibleCell.builder(VISIBLE_CELL1.radioType()) | 179 VisibleCell.builder(VISIBLE_CELL1.radioType()) |
133 .setCellId(VISIBLE_CELL1.cellId()) | 180 .setCellId(VISIBLE_CELL1.cellId()) |
134 .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) | 181 .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) |
135 .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) | 182 .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) |
136 .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) | 183 .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) |
184 .setPhysicalCellId(VISIBLE_CELL1.physicalCellId()) | |
185 .setPrimaryScramblingCode(VISIBLE_CELL1.primaryScramblin gCode()) | |
186 .setTrackingAreaCode(VISIBLE_CELL1.trackingAreaCode()) | |
137 .setTimestamp(VISIBLE_CELL1.timestampMs()) | 187 .setTimestamp(VISIBLE_CELL1.timestampMs()) |
138 .build(); | 188 .build(); |
139 assertNotEquals(VISIBLE_CELL2, VISIBLE_CELL1); | 189 assertNotEquals(VISIBLE_CELL2, VISIBLE_CELL1); |
140 assertEquals(VISIBLE_CELL1, copyOfVisibleCell1); | 190 assertEquals(VISIBLE_CELL1, copyOfVisibleCell1); |
141 } | 191 } |
142 | 192 |
143 @Test | 193 @Test |
144 public void testVisibleCellEqualsDifferentTimestamp() { | 194 public void testVisibleCellEqualsDifferentTimestamp() { |
145 // The timestamp is not included in the VisibleCell equality checks. | 195 // The timestamp is not included in the VisibleCell equality checks. |
146 assertEquals(VISIBLE_CELL1, VISIBLE_CELL1_DIFFERENT_TIMESTAMP); | 196 assertEquals(VISIBLE_CELL1, VISIBLE_CELL1_DIFFERENT_TIMESTAMP); |
147 } | 197 } |
148 | 198 |
149 @Test | 199 @Test |
150 public void testVisibleCellHash() { | 200 public void testVisibleCellHash() { |
151 VisibleCell copyOfVisibleCell1 = | 201 VisibleCell copyOfVisibleCell1 = |
152 VisibleCell.builder(VISIBLE_CELL1.radioType()) | 202 VisibleCell.builder(VISIBLE_CELL1.radioType()) |
153 .setCellId(VISIBLE_CELL1.cellId()) | 203 .setCellId(VISIBLE_CELL1.cellId()) |
154 .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) | 204 .setLocationAreaCode(VISIBLE_CELL1.locationAreaCode()) |
155 .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) | 205 .setMobileCountryCode(VISIBLE_CELL1.mobileCountryCode()) |
156 .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) | 206 .setMobileNetworkCode(VISIBLE_CELL1.mobileNetworkCode()) |
207 .setPhysicalCellId(VISIBLE_CELL1.physicalCellId()) | |
208 .setPrimaryScramblingCode(VISIBLE_CELL1.primaryScramblin gCode()) | |
209 .setTrackingAreaCode(VISIBLE_CELL1.trackingAreaCode()) | |
157 .setTimestamp(VISIBLE_CELL1.timestampMs()) | 210 .setTimestamp(VISIBLE_CELL1.timestampMs()) |
158 .build(); | 211 .build(); |
159 | 212 |
160 assertEquals(VISIBLE_CELL1.hashCode(), copyOfVisibleCell1.hashCode()); | 213 assertEquals(VISIBLE_CELL1.hashCode(), copyOfVisibleCell1.hashCode()); |
161 assertNotEquals(VISIBLE_CELL2.hashCode(), VISIBLE_CELL1.hashCode()); | 214 assertNotEquals(VISIBLE_CELL2.hashCode(), VISIBLE_CELL1.hashCode()); |
162 } | 215 } |
163 | 216 |
164 @Test | 217 @Test |
165 public void testVisibleCellHashDifferentTimestamp() { | 218 public void testVisibleCellHashDifferentTimestamp() { |
166 // The timestamp is not included in the VisibleCell hash function. | 219 // The timestamp is not included in the VisibleCell hash function. |
167 assertEquals(VISIBLE_CELL1.hashCode(), VISIBLE_CELL1_DIFFERENT_TIMESTAMP .hashCode()); | 220 assertEquals(VISIBLE_CELL1.hashCode(), VISIBLE_CELL1_DIFFERENT_TIMESTAMP .hashCode()); |
168 } | 221 } |
169 | 222 |
170 @Test | 223 @Test |
224 public void testVisibleCellToProto() { | |
225 boolean connected = true; | |
226 PartnerLocationDescriptor.VisibleNetwork visibleNetwork = VISIBLE_CELL1. toProto(connected); | |
227 PartnerLocationDescriptor.VisibleNetwork.Cell cell = visibleNetwork.cell ; | |
228 | |
229 assertEquals(VISIBLE_CELL1.cellId(), cell.cellId); | |
230 assertEquals(VISIBLE_CELL1.locationAreaCode(), cell.locationAreaCode); | |
231 assertEquals(VISIBLE_CELL1.mobileCountryCode(), cell.mobileCountryCode); | |
232 assertEquals(VISIBLE_CELL1.mobileNetworkCode(), cell.mobileNetworkCode); | |
233 assertEquals(VISIBLE_CELL1.primaryScramblingCode(), cell.primaryScrambli ngCode); | |
234 assertEquals(VISIBLE_CELL1.physicalCellId(), cell.physicalCellId); | |
235 assertEquals(VISIBLE_CELL1.trackingAreaCode(), cell.trackingAreaCode); | |
236 assertEquals(VISIBLE_CELL1.timestampMs(), visibleNetwork.timestampMs); | |
237 assertEquals(connected, visibleNetwork.connected); | |
238 assertEquals(new Integer(PartnerLocationDescriptor.VisibleNetwork.Cell.G SM), cell.type); | |
Ted C
2017/05/23 14:18:38
do you need this "new Integer("? it should autobo
lbargu
2017/05/23 14:36:47
Compiler complains about ambiguous use of assertEq
| |
239 | |
240 assertEquals(VISIBLE_CELL1_PROTO_ENCODED, encodeVisibleNetwork(visibleNe twork)); | |
241 } | |
242 | |
243 @Test | |
244 public void testVisibleCellToProtoEmptyCell() { | |
245 boolean connected = true; | |
246 PartnerLocationDescriptor.VisibleNetwork visibleNetwork = EMPTY_CELL.toP roto(connected); | |
247 PartnerLocationDescriptor.VisibleNetwork.Cell cell = visibleNetwork.cell ; | |
248 | |
249 assertEquals(new Integer(VisibleCell.UNKNOWN_RADIO_TYPE), cell.type); | |
250 assertNull(cell.cellId); | |
251 assertNull(cell.locationAreaCode); | |
252 assertNull(cell.mobileCountryCode); | |
253 assertNull(cell.mobileNetworkCode); | |
254 assertNull(cell.primaryScramblingCode); | |
255 assertNull(cell.physicalCellId); | |
256 assertNull(cell.trackingAreaCode); | |
257 assertNull(visibleNetwork.timestampMs); | |
258 assertEquals(connected, visibleNetwork.connected); | |
259 | |
260 assertEquals(EMPTY_CELL_PROTO_ENCODED, encodeVisibleNetwork(visibleNetwo rk)); | |
261 } | |
262 | |
263 @Test | |
171 public void testVisibleNetworksCreate() { | 264 public void testVisibleNetworksCreate() { |
172 Set<VisibleCell> expectedVisibleCells = | 265 Set<VisibleCell> expectedVisibleCells = |
173 new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CE LL2)); | 266 new HashSet<VisibleCell>(Arrays.asList(VISIBLE_CELL1, VISIBLE_CE LL2)); |
174 Set<VisibleWifi> expectedVisibleWifis = | 267 Set<VisibleWifi> expectedVisibleWifis = |
175 new HashSet<VisibleWifi>(Arrays.asList(VISIBLE_WIFI1, VISIBLE_WI FI2)); | 268 new HashSet<VisibleWifi>(Arrays.asList(VISIBLE_WIFI1, VISIBLE_WI FI2)); |
176 VisibleNetworks visibleNetworks = VisibleNetworks.create( | 269 VisibleNetworks visibleNetworks = VisibleNetworks.create( |
177 VISIBLE_WIFI1, VISIBLE_CELL1, expectedVisibleWifis, expectedVisi bleCells); | 270 VISIBLE_WIFI1, VISIBLE_CELL1, expectedVisibleWifis, expectedVisi bleCells); |
178 assertEquals(VISIBLE_WIFI1, visibleNetworks.connectedWifi()); | 271 assertEquals(VISIBLE_WIFI1, visibleNetworks.connectedWifi()); |
179 assertEquals(VISIBLE_CELL1, visibleNetworks.connectedCell()); | 272 assertEquals(VISIBLE_CELL1, visibleNetworks.connectedCell()); |
180 assertEquals(expectedVisibleWifis, visibleNetworks.allVisibleWifis()); | 273 assertEquals(expectedVisibleWifis, visibleNetworks.allVisibleWifis()); |
(...skipping 19 matching lines...) Expand all Loading... | |
200 assertEquals(VISIBLE_NETWORKS1.hashCode(), copyOfVisibleNetworks1.hashCo de()); | 293 assertEquals(VISIBLE_NETWORKS1.hashCode(), copyOfVisibleNetworks1.hashCo de()); |
201 assertNotEquals(VISIBLE_NETWORKS1.hashCode(), VISIBLE_NETWORKS2.hashCode ()); | 294 assertNotEquals(VISIBLE_NETWORKS1.hashCode(), VISIBLE_NETWORKS2.hashCode ()); |
202 } | 295 } |
203 | 296 |
204 @Test | 297 @Test |
205 public void testVisibleNetworksIsEmpty() { | 298 public void testVisibleNetworksIsEmpty() { |
206 VisibleNetworks visibleNetworks = VisibleNetworks.create(null, null, nul l, null); | 299 VisibleNetworks visibleNetworks = VisibleNetworks.create(null, null, nul l, null); |
207 assertTrue(visibleNetworks.isEmpty()); | 300 assertTrue(visibleNetworks.isEmpty()); |
208 assertFalse(VISIBLE_NETWORKS1.isEmpty()); | 301 assertFalse(VISIBLE_NETWORKS1.isEmpty()); |
209 } | 302 } |
210 } | 303 |
304 private static String encodeVisibleNetwork( | |
305 PartnerLocationDescriptor.VisibleNetwork visibleNetwork) { | |
306 PartnerLocationDescriptor.LocationDescriptor locationDescriptor = | |
307 new PartnerLocationDescriptor.LocationDescriptor(); | |
308 locationDescriptor.role = PartnerLocationDescriptor.CURRENT_LOCATION; | |
309 locationDescriptor.producer = PartnerLocationDescriptor.DEVICE_LOCATION; | |
310 locationDescriptor.visibleNetwork = new PartnerLocationDescriptor.Visibl eNetwork[1]; | |
311 locationDescriptor.visibleNetwork[0] = visibleNetwork; | |
312 | |
313 return Base64.encodeToString( | |
314 MessageNano.toByteArray(locationDescriptor), Base64.NO_WRAP | Ba se64.URL_SAFE); | |
315 } | |
316 } | |
OLD | NEW |