From c453826dcd7b1c4278fc14614a1e75635748fff3 Mon Sep 17 00:00:00 2001 From: Arc Wang Date: Fri, 17 Apr 2020 11:36:17 +0800 Subject: [Wi-Fi] Add IMSI privacy protection warning summary If a SIM based Wi-Fi network is not provided with IMSI protection, Wi-Fi detail UI shows the warning summary if the Wi-Fi network is connected. Bug: 148283447 Test: atest com.android.wifitrackerlib Change-Id: Ib98117b50585bb262d48f5313271827ec1e16c81 --- libs/WifiTrackerLib/Android.bp | 1 + libs/WifiTrackerLib/res/values/strings.xml | 5 +- .../android/wifitrackerlib/PasspointWifiEntry.java | 7 +++ .../android/wifitrackerlib/StandardWifiEntry.java | 7 +++ .../src/com/android/wifitrackerlib/Utils.java | 49 ++++++++++++++++++++ .../src/com/android/wifitrackerlib/WifiEntry.java | 5 ++ .../src/com/android/wifitrackerlib/UtilsTest.java | 54 ++++++++++++++++++++++ 7 files changed, 127 insertions(+), 1 deletion(-) (limited to 'libs') diff --git a/libs/WifiTrackerLib/Android.bp b/libs/WifiTrackerLib/Android.bp index 412f182dd..5355d0037 100644 --- a/libs/WifiTrackerLib/Android.bp +++ b/libs/WifiTrackerLib/Android.bp @@ -3,6 +3,7 @@ android_library { srcs: ["src/**/*.java"], static_libs: [ "androidx.preference_preference", + "SettingsLibHelpUtils", ], min_sdk_version: "21", diff --git a/libs/WifiTrackerLib/res/values/strings.xml b/libs/WifiTrackerLib/res/values/strings.xml index 581de3234..c238f663c 100644 --- a/libs/WifiTrackerLib/res/values/strings.xml +++ b/libs/WifiTrackerLib/res/values/strings.xml @@ -170,7 +170,10 @@ Sign-up complete. Connecting\u2026 - This network receives a unique ID that can be used to track device location.\nLearn more + This network receives a unique ID that can be used to track device location. Learn more + + + Very Slow diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java index 0bcd7ccfb..3b2ad3f33 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/PasspointWifiEntry.java @@ -24,6 +24,7 @@ import static com.android.wifitrackerlib.Utils.getAutoConnectDescription; import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation; import static com.android.wifitrackerlib.Utils.getDisconnectedStateDescription; +import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription; import static com.android.wifitrackerlib.Utils.getMeteredDescription; import static com.android.wifitrackerlib.Utils.getNetworkDetailedState; import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration; @@ -178,6 +179,12 @@ public class PasspointWifiEntry extends WifiEntry { return getNetworkDetailedState(mContext, mNetworkInfo); } + @Override + public CharSequence getSecondSummary() { + return getConnectedState() == CONNECTED_STATE_CONNECTED + ? getImsiProtectionDescription(mContext, mWifiConfig) : ""; + } + @Override public int getLevel() { return mLevel; diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java index bc164bf1d..b6afa984a 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/StandardWifiEntry.java @@ -28,6 +28,7 @@ import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId; import static com.android.wifitrackerlib.Utils.getCurrentNetworkCapabilitiesInformation; import static com.android.wifitrackerlib.Utils.getDisconnectedStateDescription; +import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription; import static com.android.wifitrackerlib.Utils.getMeteredDescription; import static com.android.wifitrackerlib.Utils.getNetworkDetailedState; import static com.android.wifitrackerlib.Utils.getSecurityTypeFromWifiConfiguration; @@ -272,6 +273,12 @@ public class StandardWifiEntry extends WifiEntry { return getNetworkDetailedState(mContext, mNetworkInfo); } + @Override + public CharSequence getSecondSummary() { + return getConnectedState() == CONNECTED_STATE_CONNECTED + ? getImsiProtectionDescription(mContext, getWifiConfiguration()) : ""; + } + @Override public int getLevel() { return mLevel; diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java index 382fe02c4..5cdecd48e 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/Utils.java @@ -48,11 +48,18 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.Annotation; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; import android.text.TextUtils; +import android.text.style.ClickableSpan; +import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.settingslib.HelpUtils; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -566,4 +573,46 @@ class Utils { return (bundle.getInt(CarrierConfigManager.IMSI_KEY_AVAILABILITY_INT) & TelephonyManager.KEY_TYPE_WLAN) != 0; } + + static CharSequence getImsiProtectionDescription(Context context, + @Nullable WifiConfiguration wifiConfig) { + if (context == null || wifiConfig == null || !isSimCredential(wifiConfig)) { + return ""; + } + + int subId = getSubIdForConfig(context, wifiConfig); + if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID + || isImsiPrivacyProtectionProvided(context, subId)) { + return ""; + } + + // IMSI protection is not provided, return warning message. + return linkifyAnnotation(context, context.getText(R.string.imsi_protection_warning), "url", + context.getString(R.string.help_url_imsi_protection)); + } + + /** Find the annotation of specified id in rawText and linkify it with helpUriString. */ + static CharSequence linkifyAnnotation(Context context, CharSequence rawText, String id, + String helpUriString) { + SpannableString spannableText = new SpannableString(rawText); + Annotation[] annotations = spannableText.getSpans(0, spannableText.length(), + Annotation.class); + + for (Annotation annotation : annotations) { + if (TextUtils.equals(annotation.getValue(), id)) { + SpannableStringBuilder builder = new SpannableStringBuilder(spannableText); + ClickableSpan link = new ClickableSpan() { + @Override + public void onClick(View view) { + view.startActivityForResult(HelpUtils.getHelpIntent(context, helpUriString, + view.getClass().getName()), 0); + } + }; + builder.setSpan(link, spannableText.getSpanStart(annotation), + spannableText.getSpanEnd(annotation), spannableText.getSpanFlags(link)); + return builder; + } + } + return rawText; + } } diff --git a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java index 78b339bf2..989c764aa 100644 --- a/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java +++ b/libs/WifiTrackerLib/src/com/android/wifitrackerlib/WifiEntry.java @@ -246,6 +246,11 @@ public abstract class WifiEntry implements Comparable { return getSummary(true /* concise */); } + /** Returns the second summary, it's for additional information of the WifiEntry */ + public CharSequence getSecondSummary() { + return ""; + } + /** * Returns the display summary. * @param concise Whether to show more information. e.g., verbose logging. diff --git a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java index 7ed2d1ac6..4d9121239 100644 --- a/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java +++ b/libs/WifiTrackerLib/tests/src/com/android/wifitrackerlib/UtilsTest.java @@ -23,10 +23,12 @@ import static com.android.wifitrackerlib.Utils.getAppLabelForSavedNetwork; import static com.android.wifitrackerlib.Utils.getAutoConnectDescription; import static com.android.wifitrackerlib.Utils.getBestScanResultByLevel; import static com.android.wifitrackerlib.Utils.getCarrierNameForSubId; +import static com.android.wifitrackerlib.Utils.getImsiProtectionDescription; import static com.android.wifitrackerlib.Utils.getMeteredDescription; import static com.android.wifitrackerlib.Utils.getSubIdForConfig; import static com.android.wifitrackerlib.Utils.isImsiPrivacyProtectionProvided; import static com.android.wifitrackerlib.Utils.isSimPresent; +import static com.android.wifitrackerlib.Utils.linkifyAnnotation; import static com.android.wifitrackerlib.Utils.mapScanResultsToKey; import static com.android.wifitrackerlib.WifiEntry.SECURITY_NONE; import static com.android.wifitrackerlib.WifiEntry.SECURITY_PSK; @@ -46,6 +48,7 @@ import android.net.NetworkInfo; import android.net.NetworkScoreManager; import android.net.wifi.ScanResult; import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiEnterpriseConfig; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Handler; @@ -55,6 +58,11 @@ import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; +import android.text.Annotation; +import android.text.SpannableString; +import android.text.SpannableStringBuilder; +import android.text.Spanned; +import android.text.style.ClickableSpan; import org.junit.Before; import org.junit.Ignore; @@ -361,6 +369,52 @@ public class UtilsTest { assertEquals(TEST_SUB_ID, getSubIdForConfig(mMockContext, config)); } + @Test + public void testGetImsiProtectionDescription_isSimCredentialFalse_returnEmptyString() { + final WifiConfiguration wificonfig = new WifiConfiguration(); + + assertEquals(getImsiProtectionDescription(mMockContext, wificonfig), ""); + } + + @Test + public void testGetImsiProtectionDescription_noValidSubId_returnEmptyString() { + final WifiConfiguration mockWifiConfig = mock(WifiConfiguration.class); + final WifiEnterpriseConfig mockWifiEnterpriseConfig = mock(WifiEnterpriseConfig.class); + when(mockWifiEnterpriseConfig.isAuthenticationSimBased()).thenReturn(true); + mockWifiConfig.enterpriseConfig = mockWifiEnterpriseConfig; + + assertEquals(getImsiProtectionDescription(mMockContext, mockWifiConfig), ""); + } + + @Test + public void testLinkifyAnnotation_noAnnotation_returnOriginalText() { + final CharSequence testText = "test text"; + + final CharSequence output = linkifyAnnotation(mMockContext, testText, "id", "url"); + + final SpannableString outputSpannableString = new SpannableString(output); + assertEquals(output, testText); + assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(), + ClickableSpan.class).length, 0); + } + + @Test + public void testLinkifyAnnotation_annotation_returnTextWithClickableSpan() { + final String annotationId = "id"; + final CharSequence testText = "test text "; + final CharSequence testLink = "link"; + final CharSequence expectedText = "test text link"; + final SpannableStringBuilder builder = new SpannableStringBuilder(testText); + builder.append(testLink, new Annotation("key", annotationId), + Spanned.SPAN_INCLUSIVE_INCLUSIVE); + + final CharSequence output = linkifyAnnotation(mMockContext, builder, annotationId, "url"); + + final SpannableString outputSpannableString = new SpannableString(output); + assertEquals(output.toString(), expectedText.toString()); + assertEquals(outputSpannableString.getSpans(0, outputSpannableString.length(), + ClickableSpan.class).length, 1); + } private StandardWifiEntry getStandardWifiEntry(WifiConfiguration config) { final WifiManager mockWifiManager = mock(WifiManager.class); -- cgit v1.2.3