Revert "Prioritize alternate charset when de-translating SSIDs"
Revert submission 23579364
Reason for revert: It seems more likely that actual UTF-8 SSIDs will be misinterpreted as GBK, than GBK being misinterpreted as UTF-8. This is because GBK (and the other common extended ASCII charsets like EUC-KR) has valid characters mapped to nearly every 2-byte sequence, which means any UTF-8 string with an even number of bytes has a high likelyhood of being interpreted as GBK.
The use of the "is UTF-8" bit is also not guaranteed (and seems to be uncommon), so the lack of it is not a good indication that the SSID is not UTF-8. Thus to be on the safe side, we should revert back to preferring UTF-8 over the alternate charset (which is also consistent with the OEM GBK solutions).
Reverted changes: /q/submissionid:23579364
Change-Id: Idd0f3bd5a9cd9d6c0ebf577c885c46b35b3342d4
diff --git a/service/java/com/android/server/wifi/SsidTranslator.java b/service/java/com/android/server/wifi/SsidTranslator.java
index efad248..f3b21cd 100644
--- a/service/java/com/android/server/wifi/SsidTranslator.java
+++ b/service/java/com/android/server/wifi/SsidTranslator.java
@@ -48,7 +48,6 @@
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
@@ -81,9 +80,9 @@
private @NonNull Map<String, Charset> mMockCharsetsPerLocaleLanguage = new HashMap<>();
// Maps a translated SSID to all of its BSSIDs using the alternate Charset.
- private @NonNull Map<WifiSsid, Set<MacAddress>> mTranslatedBssidsForSsid = new ArrayMap<>();
+ private @NonNull Map<WifiSsid, Set<MacAddress>> mTranslatedBssids = new ArrayMap<>();
// Maps a translated SSID to all of its BSSIDs not using the alternate Charset.
- private @NonNull Map<WifiSsid, Set<MacAddress>> mUntranslatedBssidsForSsid = new ArrayMap<>();
+ private @NonNull Map<WifiSsid, Set<MacAddress>> mUntranslatedBssids = new ArrayMap<>();
private final Map<Pair<WifiSsid, MacAddress>, Runnable> mUntranslatedBssidTimeoutRunnables =
new ArrayMap<>();
private final Map<Pair<WifiSsid, MacAddress>, Runnable> mTranslatedBssidTimeoutRunnables =
@@ -142,12 +141,12 @@
mWifiHandler.removeCallbacks(runnable);
}
mTranslatedBssidTimeoutRunnables.clear();
- mTranslatedBssidsForSsid.clear();
+ mTranslatedBssids.clear();
for (Runnable runnable : mUntranslatedBssidTimeoutRunnables.values()) {
mWifiHandler.removeCallbacks(runnable);
}
mUntranslatedBssidTimeoutRunnables.clear();
- mUntranslatedBssidsForSsid.clear();
+ mUntranslatedBssids.clear();
mCurrentLocaleAlternateCharset = null;
// Try to find the Charset for the specific language.
String language = null;
@@ -230,13 +229,13 @@
}
// Try translating the SSID from the alternate charset if it hasn't been declared as UTF-8.
if (!isStrictUtf8
- && !(mUntranslatedBssidsForSsid.containsKey(ssid)
- && mUntranslatedBssidsForSsid.get(ssid).contains(bssid))) {
+ && !(mUntranslatedBssids.containsKey(ssid)
+ && mUntranslatedBssids.get(ssid).contains(bssid))) {
WifiSsid translatedSsid =
translateSsid(ssid, mCurrentLocaleAlternateCharset, StandardCharsets.UTF_8);
if (translatedSsid != null) {
if (bssid != null) {
- mTranslatedBssidsForSsid.computeIfAbsent(translatedSsid, k -> new ArraySet<>())
+ mTranslatedBssids.computeIfAbsent(translatedSsid, k -> new ArraySet<>())
.add(bssid);
Pair<WifiSsid, MacAddress> ssidBssidPair = new Pair<>(translatedSsid, bssid);
Runnable oldRunnable = mTranslatedBssidTimeoutRunnables.remove(ssidBssidPair);
@@ -257,7 +256,7 @@
}
// SSID should be used untranslated.
if (bssid != null) {
- mUntranslatedBssidsForSsid.computeIfAbsent(ssid, k -> new ArraySet<>()).add(bssid);
+ mUntranslatedBssids.computeIfAbsent(ssid, k -> new ArraySet<>()).add(bssid);
Pair<WifiSsid, MacAddress> ssidBssidPair = new Pair<>(ssid, bssid);
Runnable oldRunnable = mUntranslatedBssidTimeoutRunnables.remove(ssidBssidPair);
if (oldRunnable != null) {
@@ -285,13 +284,13 @@
return;
}
mTranslatedBssidTimeoutRunnables.remove(mapping);
- Set<MacAddress> bssids = mTranslatedBssidsForSsid.get(ssid);
+ Set<MacAddress> bssids = mTranslatedBssids.get(ssid);
if (bssids == null) {
return;
}
bssids.remove(bssid);
if (bssids.isEmpty()) {
- mTranslatedBssidsForSsid.remove(ssid);
+ mTranslatedBssids.remove(ssid);
}
}
@@ -304,59 +303,53 @@
return;
}
mUntranslatedBssidTimeoutRunnables.remove(mapping);
- Set<MacAddress> bssids = mUntranslatedBssidsForSsid.get(ssid);
+ Set<MacAddress> bssids = mUntranslatedBssids.get(ssid);
if (bssids == null) {
return;
}
bssids.remove(bssid);
if (bssids.isEmpty()) {
- mUntranslatedBssidsForSsid.remove(ssid);
+ mUntranslatedBssids.remove(ssid);
}
}
/**
- * Converts the specified translated SSID back to specified alternate Charset for the current
- * locale language.
+ * Converts the specified translated SSID back to its original Charset if the BSSID is recorded
+ * as translated, or there are translated BSSIDs but no untranslated BSSIDs for this SSID.
*
- * The SSID will be returned as-is if the BSSID was already recorded as untranslated, or if all
- * the BSSIDs associated with the SSID are untranslated, or if the SSID cannot be encoded with
- * the alternate charset.
- *
- * Returns null if the given SSID is not valid both in the alternate Charset and as-is.
+ * If the BSSID has not been recorded at all, then we will return the SSID as-is.
*
* @param translatedSsid translated SSID.
* @param bssid optional BSSID to look up the Charset.
- * @return original SSID.
+ * @return original SSID. May be null if there are no valid translations back to the alternate
+ * Charset and the translated SSID is not a valid SSID.
*/
public synchronized @Nullable WifiSsid getOriginalSsid(
@NonNull WifiSsid translatedSsid, @Nullable MacAddress bssid) {
if (mCurrentLocaleAlternateCharset == null) {
return translatedSsid.getBytes().length <= 32 ? translatedSsid : null;
}
- Set<MacAddress> translatedBssids = mTranslatedBssidsForSsid.get(translatedSsid);
- if (translatedBssids == null) {
- translatedBssids = Collections.emptySet();
- }
- Set<MacAddress> untranslatedBssids = mUntranslatedBssidsForSsid.get(translatedSsid);
- if (untranslatedBssids == null) {
- untranslatedBssids = Collections.emptySet();
- }
- if (!untranslatedBssids.contains(bssid)
- && !(translatedBssids.isEmpty() && !untranslatedBssids.isEmpty())) {
+ boolean ssidWasTranslatedForSomeBssids = mTranslatedBssids.containsKey(translatedSsid);
+ boolean ssidWasTranslatedForThisBssid = ssidWasTranslatedForSomeBssids
+ && mTranslatedBssids.get(translatedSsid).contains(bssid);
+ boolean ssidNotTranslatedForSomeBssids = mUntranslatedBssids.containsKey(translatedSsid);
+ if (ssidWasTranslatedForThisBssid
+ || (ssidWasTranslatedForSomeBssids && !ssidNotTranslatedForSomeBssids)) {
// Try to get the SSID in the alternate Charset.
WifiSsid altCharsetSsid = translateSsid(
translatedSsid, StandardCharsets.UTF_8, mCurrentLocaleAlternateCharset);
- if (altCharsetSsid != null && altCharsetSsid.getBytes().length <= 32) {
+ if (altCharsetSsid == null || altCharsetSsid.getBytes().length > 32) {
+ Log.e(TAG, "Could not translate " + translatedSsid + " back to "
+ + mCurrentLocaleAlternateCharset + " for BSSID " + bssid);
+ } else {
return altCharsetSsid;
}
}
// Use the translated SSID as-is
- if (translatedSsid.getBytes().length <= 32) {
- return translatedSsid;
+ if (translatedSsid.getBytes().length > 32) {
+ return null;
}
- // No valid original SSID.
- Log.e(TAG, "getOriginalSsid: " + translatedSsid + " not a valid SSID!");
- return null;
+ return translatedSsid;
}
/**
@@ -418,14 +411,14 @@
pw.println("mCharsetsPerLocaleLanguage End ---");
pw.println("mTranslatedBssids Begin ---");
for (Map.Entry<WifiSsid, Set<MacAddress>> translatedBssidsEntry
- : mTranslatedBssidsForSsid.entrySet()) {
+ : mTranslatedBssids.entrySet()) {
pw.println("Translated SSID: " + translatedBssidsEntry.getKey() + ", BSSIDS: "
+ Arrays.toString(translatedBssidsEntry.getValue().toArray()));
}
pw.println("mTranslatedBssids End ---");
pw.println("mUntranslatedBssids Begin ---");
for (Map.Entry<WifiSsid, Set<MacAddress>> untranslatedBssidsEntry
- : mUntranslatedBssidsForSsid.entrySet()) {
+ : mUntranslatedBssids.entrySet()) {
pw.println("Translated SSID: " + untranslatedBssidsEntry.getKey() + ", BSSIDS: "
+ Arrays.toString(untranslatedBssidsEntry.getValue().toArray()));
}
diff --git a/service/tests/wifitests/src/com/android/server/wifi/SsidTranslatorTest.java b/service/tests/wifitests/src/com/android/server/wifi/SsidTranslatorTest.java
index 9443956..2280ff9 100644
--- a/service/tests/wifitests/src/com/android/server/wifi/SsidTranslatorTest.java
+++ b/service/tests/wifitests/src/com/android/server/wifi/SsidTranslatorTest.java
@@ -235,26 +235,26 @@
broadcastReceiverCaptor.getValue().onReceive(mWifiContext,
new Intent(Intent.ACTION_LOCALE_CHANGED));
- // BSSID does not match any seen scan results, use GBK.
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(gbkSsid);
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(gbkSsid);
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(gbkSsid);
-
- // Record a BSSID using UTF-8. All non-matching BSSIDs should return UTF-8.
- ssidTranslator.getTranslatedSsidAndRecordBssidCharset(utf8Ssid, utf8MacAddress, true);
- verify(mHandler, times(1)).postDelayed(
- timeoutRunnableCaptor.capture(), eq(SsidTranslator.BSSID_CACHE_TIMEOUT_MS));
- timeoutRunnables.add(timeoutRunnableCaptor.getValue());
+ // BSSID does not match any seen scan results, use UTF-8.
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(utf8Ssid);
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(utf8Ssid);
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(utf8Ssid);
- // Record a BSSID using GBK. The GBK and null BSSIDs should return GBK now.
+ // Record a BSSID using GBK. All non-matching BSSIDs should return GBK.
ssidTranslator.getTranslatedSsidAndRecordBssidCharset(gbkSsid, gbkMacAddress, false);
- verify(mHandler, times(2)).postDelayed(
+ verify(mHandler, times(1)).postDelayed(
timeoutRunnableCaptor.capture(), eq(SsidTranslator.BSSID_CACHE_TIMEOUT_MS));
timeoutRunnables.add(timeoutRunnableCaptor.getValue());
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(gbkSsid);
+
+ // Record a BSSID using UTF-8. The UTF-8 and null BSSIDs should return UTF-8 now.
+ ssidTranslator.getTranslatedSsidAndRecordBssidCharset(utf8Ssid, utf8MacAddress, true);
+ verify(mHandler, times(2)).postDelayed(
+ timeoutRunnableCaptor.capture(), eq(SsidTranslator.BSSID_CACHE_TIMEOUT_MS));
+ timeoutRunnables.add(timeoutRunnableCaptor.getValue());
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(utf8Ssid);
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(utf8Ssid);
assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(gbkSsid);
@@ -264,13 +264,13 @@
(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd, (byte) 0xee, (byte) 0xff});
assertThat(ssidTranslator.getOriginalSsid(unknownSsid, null)).isEqualTo(unknownSsid);
- // Timeout the scan results. Now we should return GBK SSIDs for every BSSID again.
+ // Timeout the scan results. Now we should return UTF-8 SSIDs for every BSSID again.
for (Runnable runnable : timeoutRunnables) {
runnable.run();
}
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(gbkSsid);
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(gbkSsid);
- assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, null)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, utf8MacAddress)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(utf8Ssid, gbkMacAddress)).isEqualTo(utf8Ssid);
// SSID is too long for any encoding, so return null.
assertThat(ssidTranslator.getOriginalSsid(WifiSsid.fromBytes(
@@ -309,59 +309,59 @@
WifiConfiguration.NetworkSelectionStatus status = config.getNetworkSelectionStatus();
status.setCandidate(candidate);
- // BSSID does not match any seen scan results, use GBK.
+ // BSSID does not match any seen scan results, use UTF-8.
status.setNetworkSelectionBSSID(null);
candidate.BSSID = null;
// Using candidate BSSID
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = "any";
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = utf8MacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = gbkMacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
// Using network selection BSSID (should override candidate)
status.setNetworkSelectionBSSID("any");
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
status.setNetworkSelectionBSSID(utf8MacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
status.setNetworkSelectionBSSID(gbkMacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
- // Record a BSSID using UTF-8. All non-matching BSSIDs should return UTF-8.
- ssidTranslator.getTranslatedSsidAndRecordBssidCharset(utf8Ssid, utf8MacAddress, true);
+ // Record a BSSID using GBK. All non-matching BSSIDs should return GBK.
+ ssidTranslator.getTranslatedSsidAndRecordBssidCharset(gbkSsid, gbkMacAddress, false);
verify(mHandler, times(1)).postDelayed(
timeoutRunnableCaptor.capture(), eq(SsidTranslator.BSSID_CACHE_TIMEOUT_MS));
timeoutRunnables.add(timeoutRunnableCaptor.getValue());
status.setNetworkSelectionBSSID(null);
candidate.BSSID = null;
// Using candidate BSSID
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
candidate.BSSID = "any";
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
candidate.BSSID = utf8MacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
candidate.BSSID = gbkMacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
// Using network selection BSSID (should override candidate)
status.setNetworkSelectionBSSID("any");
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
status.setNetworkSelectionBSSID(utf8MacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
status.setNetworkSelectionBSSID(gbkMacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
- // Record a BSSID using GBK. The GBK and null BSSIDs should return GBK now.
- ssidTranslator.getTranslatedSsidAndRecordBssidCharset(gbkSsid, gbkMacAddress, false);
+ // Record a BSSID using UTF-8. The UTF-8 and null BSSIDs should return UTF-8 now.
+ ssidTranslator.getTranslatedSsidAndRecordBssidCharset(utf8Ssid, utf8MacAddress, true);
verify(mHandler, times(2)).postDelayed(
timeoutRunnableCaptor.capture(), eq(SsidTranslator.BSSID_CACHE_TIMEOUT_MS));
timeoutRunnables.add(timeoutRunnableCaptor.getValue());
status.setNetworkSelectionBSSID(null);
candidate.BSSID = null;
// Using candidate BSSID
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = "any";
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = utf8MacAddress.toString();
assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = gbkMacAddress.toString();
@@ -381,7 +381,7 @@
config.SSID = unknownSsid.toString();
assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(unknownSsid);
- // Timeout the scan results. Now we should return GBK SSIDs for every BSSID again.
+ // Timeout the scan results. Now we should return UTF-8 SSIDs for every BSSID again.
for (Runnable runnable : timeoutRunnables) {
runnable.run();
}
@@ -389,20 +389,20 @@
candidate.BSSID = null;
config.SSID = "\"安卓\"";
// Using candidate BSSID
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = "any";
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = utf8MacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
candidate.BSSID = gbkMacAddress.toString();
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
// Using network selection BSSID (should override candidate)
status.setNetworkSelectionBSSID("any");
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
status.setNetworkSelectionBSSID(utf8MacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
status.setNetworkSelectionBSSID(gbkMacAddress.toString());
- assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(gbkSsid);
+ assertThat(ssidTranslator.getOriginalSsid(config)).isEqualTo(utf8Ssid);
// SSID is too long for any encoding, so return null.
config.SSID = "\"こんにちは! This is an SSID!!!!!!!!!!!!!!!!!!!!\"";