diff options
7 files changed, 127 insertions, 1 deletions
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 @@ <string name="osu_sign_up_complete">Sign-up complete. Connecting\u2026</string> <!-- IMSI protection warning for non-protection network [CHAR LIMIT=NONE] --> - <string name="imsi_protection_warning">This network receives a unique ID that can be used to track device location.\n<annotation id="url">Learn more</annotation></string> + <string name="imsi_protection_warning">This network receives a unique ID that can be used to track device location. <annotation id="url">Learn more</annotation></string> + + <!-- Help URL, IMSI protection [DO NOT TRANSLATE] --> + <string name="help_url_imsi_protection" translatable="false"></string> <!-- Speed label for very slow network speed --> <string name="speed_label_very_slow">Very Slow</string> 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; @@ -179,6 +180,12 @@ public class PasspointWifiEntry extends WifiEntry { } @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; @@ -273,6 +274,12 @@ public class StandardWifiEntry extends WifiEntry { } @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<WifiEntry> { 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); |