From 1635951de2cd671450809f86c0dac0841d7e3b79 Mon Sep 17 00:00:00 2001 From: Les Lee Date: Fri, 22 Mar 2024 05:11:08 +0000 Subject: [PATCH] wifi: Using framework uri parsing Bug: 298669190 Test: Manual test. Qr code sacnning works normally. Change-Id: I8e6138971ae6798b42db32930f80e9113a8c0223 --- .../development/AdbQrcodeScannerFragment.java | 19 ++- .../android/settings/wifi/dpp/AdbQrCode.java | 22 +-- .../dpp/WifiDppQrCodeScannerFragment.java | 49 +++--- .../android/settings/wifi/dpp/WifiQrCode.java | 147 ++---------------- .../settings/wifi/dpp/WifiQrCodeTest.java | 74 --------- 5 files changed, 65 insertions(+), 246 deletions(-) delete mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java diff --git a/src/com/android/settings/development/AdbQrcodeScannerFragment.java b/src/com/android/settings/development/AdbQrcodeScannerFragment.java index ca44747f163..1d384544447 100644 --- a/src/com/android/settings/development/AdbQrcodeScannerFragment.java +++ b/src/com/android/settings/development/AdbQrcodeScannerFragment.java @@ -16,6 +16,7 @@ package com.android.settings.development; +import android.annotation.Nullable; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; @@ -26,6 +27,7 @@ import android.debug.IAdbManager; import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.SurfaceTexture; +import android.net.wifi.WifiConfiguration; import android.os.Bundle; import android.os.Handler; import android.os.Message; @@ -47,7 +49,6 @@ import com.android.settings.R; import com.android.settings.SetupWizardUtils; import com.android.settings.wifi.dpp.AdbQrCode; import com.android.settings.wifi.dpp.WifiDppQrCodeBaseFragment; -import com.android.settings.wifi.dpp.WifiNetworkConfig; import com.android.settingslib.qrcode.QrCamera; import com.android.settingslib.qrcode.QrDecorateView; @@ -81,7 +82,8 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen /** QR code data scanned by camera */ private AdbQrCode mAdbQrCode; - private WifiNetworkConfig mAdbConfig; + @Nullable + private WifiConfiguration mAdbConfig; private IAdbManager mAdbManager; @@ -287,13 +289,16 @@ public class AdbQrcodeScannerFragment extends WifiDppQrCodeBaseFragment implemen AdbQrCode.triggerVibrationForQrCodeRecognition(getContext()); mVerifyingTextView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED); try { - mAdbManager.enablePairingByQrCode(mAdbConfig.getSsid(), - mAdbConfig.getPreSharedKey()); + if (mAdbConfig != null) { + mAdbManager.enablePairingByQrCode(mAdbConfig.SSID, + mAdbConfig.preSharedKey); + return; + } } catch (RemoteException e) { - Log.e(TAG, "Unable to enable QR code pairing"); - getActivity().setResult(Activity.RESULT_CANCELED); - getActivity().finish(); + Log.e(TAG, "Unable to enable QR code pairing" + e); } + getActivity().setResult(Activity.RESULT_CANCELED); + getActivity().finish(); } @Override diff --git a/src/com/android/settings/wifi/dpp/AdbQrCode.java b/src/com/android/settings/wifi/dpp/AdbQrCode.java index 65577874e20..2d830b2820a 100644 --- a/src/com/android/settings/wifi/dpp/AdbQrCode.java +++ b/src/com/android/settings/wifi/dpp/AdbQrCode.java @@ -16,8 +16,12 @@ package com.android.settings.wifi.dpp; import android.content.Context; +import android.net.wifi.UriParserResults; +import android.net.wifi.WifiConfiguration; import android.text.TextUtils; +import androidx.annotation.NonNull; + /** * Extension of WifiQrCode to support ADB QR code format. * It will be based on the ZXing format: @@ -27,31 +31,31 @@ import android.text.TextUtils; public class AdbQrCode extends WifiQrCode { static final String SECURITY_ADB = "ADB"; - private WifiNetworkConfig mAdbConfig; + private WifiConfiguration mAdbConfig; public AdbQrCode(String qrCode) throws IllegalArgumentException { super(qrCode); // Only accept the zxing format. - if (!WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(getScheme())) { + if (getScheme() != UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG) { throw new IllegalArgumentException("DPP format not supported for ADB QR code"); } + mAdbConfig = getWifiConfiguration(); - mAdbConfig = getWifiNetworkConfig(); - if (!SECURITY_ADB.equals(mAdbConfig.getSecurity())) { - throw new IllegalArgumentException("Invalid security type"); + if (mAdbConfig == null) { + throw new IllegalArgumentException("Null config when parsing ADB QR code"); } - - if (TextUtils.isEmpty(mAdbConfig.getSsid())) { + if (TextUtils.isEmpty(mAdbConfig.SSID)) { throw new IllegalArgumentException("Empty service name"); } - if (TextUtils.isEmpty(mAdbConfig.getPreSharedKey())) { + if (TextUtils.isEmpty(mAdbConfig.preSharedKey)) { throw new IllegalArgumentException("Empty password"); } } - public WifiNetworkConfig getAdbNetworkConfig() { + @NonNull + public WifiConfiguration getAdbNetworkConfig() { return mAdbConfig; } diff --git a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java index 479c81dafa1..34948dc69dc 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java +++ b/src/com/android/settings/wifi/dpp/WifiDppQrCodeScannerFragment.java @@ -26,6 +26,7 @@ import android.graphics.Matrix; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.net.wifi.EasyConnectStatusCallback; +import android.net.wifi.UriParserResults; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; @@ -183,32 +184,29 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl // one for open network and one for enhanced open network. final WifiManager wifiManager = context.getSystemService(WifiManager.class); - final WifiNetworkConfig qrCodeWifiNetworkConfig = - (WifiNetworkConfig)msg.obj; - final List qrCodeWifiConfigurations = - qrCodeWifiNetworkConfig.getWifiConfigurations(); + final WifiConfiguration qrCodeWifiConfiguration = (WifiConfiguration) msg.obj; // Adds all Wi-Fi networks in QR code to the set of configured networks and // connects to it if it's reachable. boolean hasHiddenOrReachableWifiNetwork = false; - for (WifiConfiguration qrCodeWifiConfiguration : qrCodeWifiConfigurations) { - final int id = wifiManager.addNetwork(qrCodeWifiConfiguration); - if (id == -1) { - continue; - } + final int id = wifiManager.addNetwork(qrCodeWifiConfiguration); + if (id == -1) { + return; + } - if (!canConnectWifi(qrCodeWifiConfiguration.SSID)) return; + if (!canConnectWifi(qrCodeWifiConfiguration.SSID)) { + return; + } - wifiManager.enableNetwork(id, /* attemptConnect */ false); - // WifiTracker only contains a hidden SSID Wi-Fi network if it's saved. - // We can't check if a hidden SSID Wi-Fi network is reachable in advance. - if (qrCodeWifiConfiguration.hiddenSSID || - isReachableWifiNetwork(qrCodeWifiConfiguration)) { - hasHiddenOrReachableWifiNetwork = true; - mEnrolleeWifiConfiguration = qrCodeWifiConfiguration; - wifiManager.connect(id, - /* listener */ WifiDppQrCodeScannerFragment.this); - } + wifiManager.enableNetwork(id, /* attemptConnect */ false); + // WifiTracker only contains a hidden SSID Wi-Fi network if it's saved. + // We can't check if a hidden SSID Wi-Fi network is reachable in advance. + if (qrCodeWifiConfiguration.hiddenSSID + || isReachableWifiNetwork(qrCodeWifiConfiguration)) { + hasHiddenOrReachableWifiNetwork = true; + mEnrolleeWifiConfiguration = qrCodeWifiConfiguration; + wifiManager.connect(id, + /* listener */ WifiDppQrCodeScannerFragment.this); } if (!hasHiddenOrReachableWifiNetwork) { @@ -530,8 +528,9 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl } // It's impossible to provision other device with ZXing Wi-Fi Network config format - final String scheme = mWifiQrCode.getScheme(); - if (mIsConfiguratorMode && WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG.equals(scheme)) { + if (mIsConfiguratorMode + && mWifiQrCode.getScheme() + == UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG) { showErrorMessage(R.string.wifi_dpp_qr_code_is_not_valid_format); return false; } @@ -545,11 +544,11 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl @Override public void handleSuccessfulResult(String qrCode) { switch (mWifiQrCode.getScheme()) { - case WifiQrCode.SCHEME_DPP: + case UriParserResults.URI_SCHEME_DPP: handleWifiDpp(); break; - case WifiQrCode.SCHEME_ZXING_WIFI_NETWORK_CONFIG: + case UriParserResults.URI_SCHEME_ZXING_WIFI_NETWORK_CONFIG: handleZxingWifiFormat(); break; @@ -567,7 +566,7 @@ public class WifiDppQrCodeScannerFragment extends WifiDppQrCodeBaseFragment impl private void handleZxingWifiFormat() { Message message = mHandler.obtainMessage(MESSAGE_SCAN_ZXING_WIFI_FORMAT_SUCCESS); - message.obj = new WifiQrCode(mWifiQrCode.getQrCode()).getWifiNetworkConfig(); + message.obj = new WifiQrCode(mWifiQrCode.getQrCode()).getWifiConfiguration(); mHandler.sendMessageDelayed(message, SHOW_SUCCESS_SQUARE_INTERVAL); } diff --git a/src/com/android/settings/wifi/dpp/WifiQrCode.java b/src/com/android/settings/wifi/dpp/WifiQrCode.java index 70ac96c9025..9b93480fd68 100644 --- a/src/com/android/settings/wifi/dpp/WifiQrCode.java +++ b/src/com/android/settings/wifi/dpp/WifiQrCode.java @@ -16,14 +16,12 @@ package com.android.settings.wifi.dpp; +import android.annotation.NonNull; +import android.net.wifi.UriParserResults; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiUriParser; import android.text.TextUtils; - -import androidx.annotation.VisibleForTesting; - -import java.util.Arrays; -import java.util.List; -import java.util.regex.Pattern; +import android.util.Log; /** * Supports to parse 2 types of QR code @@ -70,19 +68,8 @@ public class WifiQrCode { static final String SECURITY_SAE = "SAE"; private String mQrCode; - - /** - * SCHEME_DPP for standard Wi-Fi device provision protocol; SCHEME_ZXING_WIFI_NETWORK_CONFIG - * for ZXing reader library' Wi-Fi Network config format - */ - private String mScheme; - - // Data from parsed Wi-Fi DPP QR code - private String mPublicKey; - private String mInformation; - - // Data from parsed ZXing reader library's Wi-Fi Network config format - private WifiNetworkConfig mWifiNetworkConfig; + @NonNull + private UriParserResults mUriParserResults; public WifiQrCode(String qrCode) throws IllegalArgumentException { if (TextUtils.isEmpty(qrCode)) { @@ -90,111 +77,14 @@ public class WifiQrCode { } mQrCode = qrCode; - - if (qrCode.startsWith(PREFIX_DPP)) { - mScheme = SCHEME_DPP; - parseWifiDppQrCode(qrCode); - } else if (qrCode.startsWith(PREFIX_ZXING_WIFI_NETWORK_CONFIG)) { - mScheme = SCHEME_ZXING_WIFI_NETWORK_CONFIG; - parseZxingWifiQrCode(qrCode); - } else { + try { + mUriParserResults = WifiUriParser.parseUri(mQrCode); + Log.i("WifiQrCode", "mUriParserResults = " + mUriParserResults); + } catch (IllegalArgumentException ie) { throw new IllegalArgumentException("Invalid scheme"); } } - /** Parses Wi-Fi DPP QR code string */ - private void parseWifiDppQrCode(String qrCode) throws IllegalArgumentException { - List keyValueList = getKeyValueList(qrCode, PREFIX_DPP, DELIMITER_QR_CODE); - - String publicKey = getValueOrNull(keyValueList, PREFIX_DPP_PUBLIC_KEY); - if (TextUtils.isEmpty(publicKey)) { - throw new IllegalArgumentException("Invalid format"); - } - mPublicKey = publicKey; - - mInformation = getValueOrNull(keyValueList, PREFIX_DPP_INFORMATION); - } - - /** Parses ZXing reader library's Wi-Fi Network config format */ - private void parseZxingWifiQrCode(String qrCode) throws IllegalArgumentException { - List keyValueList = getKeyValueList(qrCode, PREFIX_ZXING_WIFI_NETWORK_CONFIG, - DELIMITER_QR_CODE); - - String security = getValueOrNull(keyValueList, PREFIX_ZXING_SECURITY); - String ssid = getValueOrNull(keyValueList, PREFIX_ZXING_SSID); - String password = getValueOrNull(keyValueList, PREFIX_ZXING_PASSWORD); - String hiddenSsidString = getValueOrNull(keyValueList, PREFIX_ZXING_HIDDEN_SSID); - - boolean hiddenSsid = "true".equalsIgnoreCase(hiddenSsidString); - - //"\", ";", "," and ":" are escaped with a backslash "\", should remove at first - security = removeBackSlash(security); - ssid = removeBackSlash(ssid); - password = removeBackSlash(password); - - mWifiNetworkConfig = WifiNetworkConfig.getValidConfigOrNull(security, ssid, password, - hiddenSsid, WifiConfiguration.INVALID_NETWORK_ID, /* isHotspot */ false); - - if (mWifiNetworkConfig == null) { - throw new IllegalArgumentException("Invalid format"); - } - } - - /** - * Splits key/value pairs from qrCode - * - * @param qrCode the QR code raw string - * @param prefixQrCode the string before all key/value pairs in qrCode - * @param delimiter the string to split key/value pairs, can't contain a backslash - * @return a list contains string of key/value (e.g. K:key1) - */ - private List getKeyValueList(String qrCode, String prefixQrCode, - String delimiter) { - String keyValueString = qrCode.substring(prefixQrCode.length()); - - // Should not treat \delimiter as a delimiter - String regex = "(? keyValueList, String prefix) { - for (String keyValue : keyValueList) { - String strippedKeyValue = keyValue.stripLeading(); - if (strippedKeyValue.startsWith(prefix)) { - return strippedKeyValue.substring(prefix.length()); - } - } - - return null; - } - - @VisibleForTesting - String removeBackSlash(String input) { - if (input == null) { - return null; - } - - StringBuilder sb = new StringBuilder(); - boolean backSlash = false; - for (char ch : input.toCharArray()) { - if (ch != '\\') { - sb.append(ch); - backSlash = false; - } else { - if (backSlash) { - sb.append(ch); - backSlash = false; - continue; - } - - backSlash = true; - } - } - - return sb.toString(); - } - String getQrCode() { return mQrCode; } @@ -205,28 +95,23 @@ public class WifiQrCode { * SCHEME_DPP for standard Wi-Fi device provision protocol; SCHEME_ZXING_WIFI_NETWORK_CONFIG * for ZXing reader library' Wi-Fi Network config format */ - public String getScheme() { - return mScheme; + public int getScheme() { + return mUriParserResults.getUriScheme(); } /** Available when {@code getScheme()} returns SCHEME_DPP */ - @VisibleForTesting String getPublicKey() { - return mPublicKey; + return mUriParserResults.getPublicKey(); } /** May be available when {@code getScheme()} returns SCHEME_DPP */ public String getInformation() { - return mInformation; + return mUriParserResults.getInformation(); } /** Available when {@code getScheme()} returns SCHEME_ZXING_WIFI_NETWORK_CONFIG */ - WifiNetworkConfig getWifiNetworkConfig() { - if (mWifiNetworkConfig == null) { - return null; - } - - return new WifiNetworkConfig(mWifiNetworkConfig); + WifiConfiguration getWifiConfiguration() { + return mUriParserResults.getWifiConfiguration(); } static WifiQrCode getValidWifiDppQrCodeOrNull(String qrCode) { diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java deleted file mode 100644 index e3a8ca5646f..00000000000 --- a/tests/unit/src/com/android/settings/wifi/dpp/WifiQrCodeTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2023 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.wifi.dpp; - -import static com.google.common.truth.Truth.assertThat; - -import androidx.test.ext.junit.runners.AndroidJUnit4; - -import org.junit.Test; -import org.junit.runner.RunWith; - -@RunWith(AndroidJUnit4.class) -public class WifiQrCodeTest { - @Test - public void testZxParsing_validCode() { - WifiNetworkConfig config = new WifiQrCode("WIFI:S:testAbC;T:nopass").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("testAbC"); - assertThat(config.getSecurity()).isEqualTo("nopass"); - - config = new WifiQrCode( - "WIFI:S:reallyLONGone;T:WEP;P:somepasswo#%^**123rd").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("reallyLONGone"); - assertThat(config.getSecurity()).isEqualTo("WEP"); - assertThat(config.getPreSharedKey()).isEqualTo("somepasswo#%^**123rd"); - - config = new WifiQrCode("WIFI:S:anotherone;T:WPA;P:3#=3j9asicla").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("anotherone"); - assertThat(config.getSecurity()).isEqualTo("WPA"); - assertThat(config.getPreSharedKey()).isEqualTo("3#=3j9asicla"); - - config = new WifiQrCode("WIFI:S:xx;T:SAE;P:a").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("xx"); - assertThat(config.getSecurity()).isEqualTo("SAE"); - assertThat(config.getPreSharedKey()).isEqualTo("a"); - } - - @Test - public void testZxParsing_invalidCodeButShouldWork() { - WifiNetworkConfig config = new WifiQrCode( - "WIFI:S:testAbC; T:nopass").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("testAbC"); - assertThat(config.getSecurity()).isEqualTo("nopass"); - - config = new WifiQrCode( - "WIFI:S:reallyLONGone;T:WEP; P:somepassword").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("reallyLONGone"); - assertThat(config.getSecurity()).isEqualTo("WEP"); - assertThat(config.getPreSharedKey()).isEqualTo("somepassword"); - - config = new WifiQrCode("WIFI: S:anotherone;T:WPA;P:abcdefghihklmn").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("anotherone"); - assertThat(config.getSecurity()).isEqualTo("WPA"); - assertThat(config.getPreSharedKey()).isEqualTo("abcdefghihklmn"); - - config = new WifiQrCode("WIFI: S:xx; T:SAE; P:a").getWifiNetworkConfig(); - assertThat(config.getSsid()).isEqualTo("xx"); - assertThat(config.getSecurity()).isEqualTo("SAE"); - assertThat(config.getPreSharedKey()).isEqualTo("a"); - } -}