From 3c54876db70052ec1a3e0210c27ed3b7e6463680 Mon Sep 17 00:00:00 2001 From: Hakjun Choi Date: Sat, 23 Mar 2024 02:56:19 +0000 Subject: [PATCH 1/9] Make satellite more info url carrier configurable guidance url link are vary per each carrier, therefore makes it carrier configurable Bug: 330948681 Test: manually test whether URL works as intended on pixel with TMO/SKT SIM Change-Id: I062b1e9267c6edf3289d85dc58f9ab2d9cff64d8 --- res/values/strings.xml | 2 -- .../network/telephony/SatelliteSetting.java | 23 +++++++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 1894469a80a..9e1ab8a37d8 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -11553,8 +11553,6 @@ Satellite messaging may take longer and is available only in some areas. Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available. Emergency calls may still connect.\n\nIt may take some time for account changes to show in Settings. Contact your carrier for details. More about satellite messaging - - Access Point Names diff --git a/src/com/android/settings/network/telephony/SatelliteSetting.java b/src/com/android/settings/network/telephony/SatelliteSetting.java index b6d018abb84..ad10e0377ea 100644 --- a/src/com/android/settings/network/telephony/SatelliteSetting.java +++ b/src/com/android/settings/network/telephony/SatelliteSetting.java @@ -16,6 +16,8 @@ package com.android.settings.network.telephony; +import static android.telephony.CarrierConfigManager.KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING; + import android.app.Activity; import android.app.settings.SettingsEnums; import android.content.Intent; @@ -23,7 +25,9 @@ import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Bundle; +import android.os.PersistableBundle; import android.os.UserManager; +import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.satellite.SatelliteManager; @@ -60,7 +64,9 @@ public class SatelliteSetting extends RestrictedDashboardFragment { private Activity mActivity; private TelephonyManager mTelephonymanager; + private CarrierConfigManager mCarrierConfigManager; private SatelliteManager mSatelliteManager; + private PersistableBundle mConfigBundle; private int mSubId; public SatelliteSetting() { @@ -78,6 +84,7 @@ public class SatelliteSetting extends RestrictedDashboardFragment { mActivity = getActivity(); mTelephonymanager = mActivity.getSystemService(TelephonyManager.class); + mCarrierConfigManager = mActivity.getSystemService(CarrierConfigManager.class); mSatelliteManager = mActivity.getSystemService(SatelliteManager.class); mSubId = mActivity.getIntent().getIntExtra(SUB_ID, SubscriptionManager.INVALID_SUBSCRIPTION_ID); @@ -134,7 +141,7 @@ public class SatelliteSetting extends RestrictedDashboardFragment { preference.setSummary(spannable); /* The link will lead users to a guide page */ preference.setOnPreferenceClickListener(pref -> { - String url = getResources().getString(R.string.more_info_satellite_messaging_link); + String url = readSatelliteMoreInfoString(mSubId); if (!url.isEmpty()) { Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); @@ -163,7 +170,7 @@ public class SatelliteSetting extends RestrictedDashboardFragment { operatorName)); final String[] link = new String[1]; - link[0] = getResources().getString(R.string.more_info_satellite_messaging_link); + link[0] = readSatelliteMoreInfoString(mSubId); footerPreference.setLearnMoreAction(view -> { if (!link[0].isEmpty()) { Intent helpIntent = HelpUtils.getHelpIntent(mActivity, link[0], @@ -192,6 +199,18 @@ public class SatelliteSetting extends RestrictedDashboardFragment { } } + private String readSatelliteMoreInfoString(int subId) { + if (mConfigBundle == null) { + mConfigBundle = mCarrierConfigManager.getConfigForSubId(subId, + KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING); + if (mConfigBundle.isEmpty()) { + Log.d(TAG, "SatelliteSettings: getDefaultConfig"); + mConfigBundle = CarrierConfigManager.getDefaultConfig(); + } + } + return mConfigBundle.getString(KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING, ""); + } + private static void loge(String message) { Log.e(TAG, message); } From 710a3ddc9442c5210e521015a12b75efe892ea24 Mon Sep 17 00:00:00 2001 From: Jason Chang Date: Mon, 1 Apr 2024 07:58:04 +0000 Subject: [PATCH 2/9] Fix face unlock setup page is abnormal Apply GlifV4Theme.DayNight for FaceEnrollIntroduction related pages. Flag: NONE Bug: 329778849 Test: manully test with reproducible steps: 1. Flash and factory wipe the device with latest build 2. Complete SUW and update all the apps 3. Go to settings > security& privacy > face unlock > observe setup page Change-Id: I73293808d225ecad013d507bd9c38b23324b17ec --- AndroidManifest.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5ffbbf84d01..a936d35578d 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -2643,6 +2643,7 @@ @@ -2653,18 +2654,22 @@ Date: Tue, 2 Apr 2024 00:13:17 +0000 Subject: [PATCH 3/9] [Accessibility] Restore high contrast text Test: local raven device Bug: 241805782 Change-Id: Ie7d807ebc46452beb69ad41ebb3e570c2ff0a186 --- res/xml/accessibility_text_reading_options.xml | 4 ++-- .../TextReadingPreferenceFragment.java | 15 ++++----------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/res/xml/accessibility_text_reading_options.xml b/res/xml/accessibility_text_reading_options.xml index 795c4ffb9fc..1f8c24bf192 100644 --- a/res/xml/accessibility_text_reading_options.xml +++ b/res/xml/accessibility_text_reading_options.xml @@ -56,8 +56,8 @@ + android:summary="@string/accessibility_toggle_maximize_text_contrast_preference_summary" + android:title="@string/accessibility_toggle_maximize_text_contrast_preference_title" /> Date: Tue, 2 Apr 2024 04:08:21 +0000 Subject: [PATCH 4/9] Add SATELLITE_COMMUNICATION to Settings app and fix checkcolor_hook SATELLITE_COMMUNICATION is a signature|privileged permission. Used to get satellite status. Bug: 330585109 Test: presubmit Change-Id: I35b226eeaa7fd018c658148c7496d9638fe8ecb7 Merged-In: I117dab50b8157e2f81de7b1ff6998c45fb84c734 --- AndroidManifest.xml | 1 + color-check-baseline.xml | 156 +++++++++++++++++++++------------------ 2 files changed, 87 insertions(+), 70 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 5ffbbf84d01..36dc7d819bb 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -143,6 +143,7 @@ + @@ -669,7 +669,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -1577,11 +1577,11 @@ priority="4" summary="Using hardcoded color" explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes. This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app." - errorLine1=" <color name="screen_flash_color_button_outer_circle_stroke_color">#FFFFFF</color>" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + errorLine1=" <color name="battery_good_color_light">#43a047</color> <!-- Material Green 600 -->" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -1593,11 +1593,11 @@ priority="4" summary="Using hardcoded color" explanation="Hardcoded color values are bad because theme changes cannot be uniformly applied.Instead use the theme specific colors such as `?android:attr/textColorPrimary` in attributes. This ensures that a theme change from a light to a dark theme can be uniformlyapplied across the app." - errorLine1=" <color name="battery_good_color_light">#43a047</color> <!-- Material Green 600 -->" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> + errorLine1=" <color name="screen_flash_color_button_outer_circle_stroke_color">#FFFFFF</color>" + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -1629,7 +1629,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2269,7 +2269,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2285,7 +2285,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2301,7 +2301,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2317,7 +2317,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2333,7 +2333,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2349,7 +2349,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2365,7 +2365,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2381,7 +2381,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2397,7 +2397,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2413,7 +2413,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2429,7 +2429,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2445,7 +2445,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2461,7 +2461,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2477,7 +2477,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2493,7 +2493,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2509,7 +2509,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2525,7 +2525,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2541,7 +2541,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2557,7 +2557,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2573,7 +2573,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2589,7 +2589,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2605,7 +2605,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2621,7 +2621,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2637,7 +2637,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2653,7 +2653,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2669,7 +2669,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2685,7 +2685,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2701,7 +2701,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2717,7 +2717,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2733,7 +2733,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2749,7 +2749,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2765,7 +2765,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2781,7 +2781,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2797,7 +2797,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2813,7 +2813,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2829,7 +2829,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2845,7 +2845,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2861,7 +2861,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2877,7 +2877,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2893,7 +2893,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2909,7 +2909,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2925,7 +2925,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2941,7 +2941,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2957,7 +2957,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2973,7 +2973,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -2989,7 +2989,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3005,7 +3005,7 @@ errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> @@ -3937,6 +3937,22 @@ column="13"/> + + + + @@ -6141,7 +6157,7 @@ errorLine2=" ^"> @@ -6157,7 +6173,7 @@ errorLine2=" ^"> @@ -6173,7 +6189,7 @@ errorLine2=" ^"> @@ -6189,7 +6205,7 @@ errorLine2=" ^"> @@ -6205,7 +6221,7 @@ errorLine2=" ^"> @@ -6221,7 +6237,7 @@ errorLine2=" ^"> @@ -6237,7 +6253,7 @@ errorLine2=" ^"> @@ -6253,7 +6269,7 @@ errorLine2=" ^"> @@ -6269,7 +6285,7 @@ errorLine2=" ^"> @@ -6285,7 +6301,7 @@ errorLine2=" ^"> @@ -6301,7 +6317,7 @@ errorLine2=" ^"> From 00c21da30edd08a49dbaa1c4e9fb80693721bf5f Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Tue, 2 Apr 2024 17:13:04 +0800 Subject: [PATCH 5/9] Correct the data usage warning - For MATCH_WIFI, only shown non carrier warning when has SIM - For others, restore the previous operator warning Bug: 331184249 Test: manual - on DataUsageList Change-Id: I5d5c6b36c6874a547cc635c025aa77acadf6e1e3 --- res/values/strings.xml | 3 + res/xml/data_usage_list.xml | 3 +- .../settings/datausage/DataUsageList.kt | 16 +++++ .../settings/datausage/DataUsageListTest.kt | 64 ++++++++++++++++++- 4 files changed, 81 insertions(+), 5 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 408ba8c812f..8abd6bee4c3 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -10142,6 +10142,9 @@ ^1 data warning / ^2 data limit + + Carrier data accounting may differ from device accounting + Excludes data used by carrier networks diff --git a/res/xml/data_usage_list.xml b/res/xml/data_usage_list.xml index 62456ed64a4..292d729998f 100644 --- a/res/xml/data_usage_list.xml +++ b/res/xml/data_usage_list.xml @@ -27,8 +27,7 @@ /> diff --git a/src/com/android/settings/datausage/DataUsageList.kt b/src/com/android/settings/datausage/DataUsageList.kt index 3083fb75443..1995097d6f1 100644 --- a/src/com/android/settings/datausage/DataUsageList.kt +++ b/src/com/android/settings/datausage/DataUsageList.kt @@ -34,6 +34,7 @@ import com.android.settings.dashboard.DashboardFragment import com.android.settings.datausage.lib.BillingCycleRepository import com.android.settings.datausage.lib.NetworkUsageData import com.android.settings.network.MobileNetworkRepository +import com.android.settings.network.SubscriptionUtil import com.android.settings.network.mobileDataEnabledFlow import com.android.settingslib.mobile.dataservice.SubscriptionInfoEntity import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle @@ -95,6 +96,18 @@ open class DataUsageList : DashboardFragment() { } chartDataUsagePreferenceController = use(ChartDataUsagePreferenceController::class.java) .apply { init(template) } + + updateWarning() + } + + private fun updateWarning() { + val template = template ?: return + val warningPreference = findPreference(KEY_WARNING)!! + if (template.matchRule != NetworkTemplate.MATCH_WIFI) { + warningPreference.setSummary(R.string.operator_warning) + } else if (SubscriptionUtil.isSimHardwareVisible(context)) { + warningPreference.setSummary(R.string.non_carrier_data_usage_warning) + } } override fun onViewCreated(v: View, savedInstanceState: Bundle?) { @@ -188,5 +201,8 @@ open class DataUsageList : DashboardFragment() { private const val TAG = "DataUsageList" private const val KEY_USAGE_AMOUNT = "usage_amount" + + @VisibleForTesting + const val KEY_WARNING = "warning" } } diff --git a/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt index 29ec0eed352..7274eaa995f 100644 --- a/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt +++ b/tests/spa_unit/src/com/android/settings/datausage/DataUsageListTest.kt @@ -26,8 +26,11 @@ import androidx.core.os.bundleOf import androidx.fragment.app.testing.launchFragment import androidx.fragment.app.testing.withFragment import androidx.lifecycle.Lifecycle +import androidx.preference.Preference import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settings.R +import com.android.settings.datausage.DataUsageList.Companion.KEY_WARNING import com.android.settingslib.spaprivileged.framework.common.userManager import com.google.common.truth.Truth.assertThat import org.junit.Before @@ -38,12 +41,14 @@ import org.mockito.kotlin.mock import org.mockito.kotlin.spy import org.mockito.kotlin.stub -private val mockUserManager: UserManager = mock() +private val mockUserManager = mock() -private val mockContext: Context = spy(ApplicationProvider.getApplicationContext()) { +private val spyContext: Context = spy(ApplicationProvider.getApplicationContext()) { on { userManager } doReturn mockUserManager } +private val spyResources = spy(spyContext.resources) + private var fakeIntent = Intent() @RunWith(AndroidJUnit4::class) @@ -51,6 +56,9 @@ class DataUsageListTest { @Before fun setUp() { + spyContext.stub { + on { resources } doReturn spyResources + } mockUserManager.stub { on { isGuestUser } doReturn false } @@ -122,10 +130,60 @@ class DataUsageListTest { assertThat(activity!!.isFinishing).isFalse() } } + + @Test + fun warning_wifiAndHasSim_displayNonCarrierWarning() { + val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build() + spyResources.stub { + on { getBoolean(R.bool.config_show_sim_info) } doReturn true + } + fakeIntent = Intent().apply { + putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template) + } + + val scenario = launchFragment(initialState = Lifecycle.State.CREATED) + + scenario.withFragment { + assertThat(findPreference(KEY_WARNING)!!.summary) + .isEqualTo(context.getString(R.string.non_carrier_data_usage_warning)) + } + } + + @Test + fun warning_wifiAndNoSim_noWarning() { + val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_WIFI).build() + spyResources.stub { + on { getBoolean(R.bool.config_show_sim_info) } doReturn false + } + fakeIntent = Intent().apply { + putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template) + } + + val scenario = launchFragment(initialState = Lifecycle.State.CREATED) + + scenario.withFragment { + assertThat(findPreference(KEY_WARNING)!!.summary).isNull() + } + } + + @Test + fun warning_mobile_operatorWarning() { + val template = NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE).build() + fakeIntent = Intent().apply { + putExtra(Settings.EXTRA_NETWORK_TEMPLATE, template) + } + + val scenario = launchFragment(initialState = Lifecycle.State.CREATED) + + scenario.withFragment { + assertThat(findPreference(KEY_WARNING)!!.summary) + .isEqualTo(context.getString(R.string.operator_warning)) + } + } } class TestDataUsageList : DataUsageList() { - override fun getContext() = mockContext + override fun getContext() = spyContext override fun getIntent() = fakeIntent } From faeaa7650e917b891c00511cd2791fa531f73ab7 Mon Sep 17 00:00:00 2001 From: Songchun Fan Date: Tue, 2 Apr 2024 14:26:30 -0700 Subject: [PATCH 6/9] [Settings] fix Settings crash on App info for archived apps For archived apps, isClearRestrictionAllowed (introduced in ag/26048774) can throw NameNotFoundException, which causes Settings app to crash if uncaught. This CL fixes that. Test: manual by archiving an app and then try to go to it's app info page BUG: 332397754 Change-Id: I49a39dba36261f36215f0389ffe41523e8a2f4e8 --- .../spa/app/appinfo/AppInfoSettingsMoreOptions.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt index 1ed595909e0..d6399790d92 100644 --- a/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt +++ b/src/com/android/settings/spa/app/appinfo/AppInfoSettingsMoreOptions.kt @@ -20,6 +20,7 @@ import android.app.AppOpsManager import android.app.ecm.EnhancedConfirmationManager import android.content.Context import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager import android.os.UserManager import android.widget.Toast import androidx.compose.runtime.Composable @@ -180,7 +181,12 @@ private fun ApplicationInfo.shouldShowAccessRestrictedSettings(context: Context) return if (android.permission.flags.Flags.enhancedConfirmationModeApisEnabled() && android.security.Flags.extendEcmToAllSettings()) { val manager = context.getSystemService(EnhancedConfirmationManager::class.java)!! - manager.isClearRestrictionAllowed(packageName) + try { + manager.isClearRestrictionAllowed(packageName) + } catch (e: PackageManager.NameNotFoundException) { + // Package might have been archived + false + } } else { context.appOpsManager.noteOpNoThrow( AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS, uid, packageName, null, null From 2101258e8a21e7c983c6b000209f60c22bb3bfd4 Mon Sep 17 00:00:00 2001 From: Weng Su Date: Wed, 3 Apr 2024 10:45:43 +0800 Subject: [PATCH 7/9] Restrict WifiDppConfiguratorActivity - Don't show WifiDppConfiguratorActivity if user has DISALLOW_ADD_WIFI_CONFIG - Don't show AddNetworkFragment if user has DISALLOW_ADD_WIFI_CONFIG Fix: 299931076 Flag: None Test: manual test with TestDPC atest -c SettingsUnitTests:AddNetworkFragmentTest \ SettingsUnitTests:WifiDppConfiguratorActivityTest Change-Id: I34afe0f698e2dc43eba59b25f5f3f4f61e70166a --- .../settings/wifi/AddNetworkFragment.java | 20 +++++ .../wifi/dpp/WifiDppConfiguratorActivity.java | 20 +++++ .../settings/wifi/AddNetworkFragmentTest.java | 74 +++++++++++++++++++ .../dpp/WifiDppConfiguratorActivityTest.java | 74 +++++++++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java create mode 100644 tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java diff --git a/src/com/android/settings/wifi/AddNetworkFragment.java b/src/com/android/settings/wifi/AddNetworkFragment.java index 9fd8626f3bf..f5bf5eec9df 100644 --- a/src/com/android/settings/wifi/AddNetworkFragment.java +++ b/src/com/android/settings/wifi/AddNetworkFragment.java @@ -16,12 +16,17 @@ package com.android.settings.wifi; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.Activity; import android.app.settings.SettingsEnums; +import android.content.Context; import android.content.Intent; import android.net.wifi.WifiConfiguration; import android.net.wifi.WifiManager; import android.os.Bundle; +import android.os.UserManager; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -43,6 +48,7 @@ import com.android.settings.wifi.dpp.WifiDppUtils; */ public class AddNetworkFragment extends InstrumentedFragment implements WifiConfigUiBase2, View.OnClickListener { + private static final String TAG = "AddNetworkFragment"; public static final String WIFI_CONFIG_KEY = "wifi_config_key"; @VisibleForTesting @@ -62,6 +68,10 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getContext())) { + getActivity().finish(); + return; + } } @Override @@ -237,4 +247,14 @@ public class AddNetworkFragment extends InstrumentedFragment implements WifiConf activity.setResult(Activity.RESULT_CANCELED); activity.finish(); } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java index e6f0b31f384..a7527d7332f 100644 --- a/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java +++ b/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivity.java @@ -16,6 +16,8 @@ package com.android.settings.wifi.dpp; +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + import android.app.settings.SettingsEnums; import android.content.Context; import android.content.Intent; @@ -99,6 +101,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } if (savedInstanceState != null) { String qrCode = savedInstanceState.getString(KEY_QR_CODE); @@ -119,6 +125,10 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements @Override protected void handleIntent(Intent intent) { + if (!isAddWifiConfigAllowed(getApplicationContext())) { + finish(); + return; + } if (isGuestUser(getApplicationContext())) { Log.e(TAG, "Guest user is not allowed to configure Wi-Fi!"); EventLog.writeEvent(0x534e4554, "224772890", -1 /* UID */, "User is a guest"); @@ -402,4 +412,14 @@ public class WifiDppConfiguratorActivity extends WifiDppBaseActivity implements if (userManager == null) return false; return userManager.isGuestUser(); } + + @VisibleForTesting + static boolean isAddWifiConfigAllowed(Context context) { + UserManager userManager = context.getSystemService(UserManager.class); + if (userManager != null && userManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)) { + Log.e(TAG, "The user is not allowed to add Wi-Fi configuration."); + return false; + } + return true; + } } diff --git a/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java new file mode 100644 index 00000000000..22d43c9bb4e --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/AddNetworkFragmentTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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; + +import static android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class AddNetworkFragmentTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private AddNetworkFragment mFragment; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mFragment = new AddNetworkFragment(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mFragment.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} diff --git a/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java new file mode 100644 index 00000000000..4d723dc1846 --- /dev/null +++ b/tests/unit/src/com/android/settings/wifi/dpp/WifiDppConfiguratorActivityTest.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2024 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 android.os.UserManager.DISALLOW_ADD_WIFI_CONFIG; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.os.UserManager; + +import androidx.test.annotation.UiThreadTest; +import androidx.test.core.app.ApplicationProvider; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +@RunWith(AndroidJUnit4.class) +@UiThreadTest +public class WifiDppConfiguratorActivityTest { + + @Rule + public final MockitoRule mMockitoRule = MockitoJUnit.rule(); + @Spy + private final Context mContext = ApplicationProvider.getApplicationContext(); + @Mock + private UserManager mUserManager; + + private WifiDppConfiguratorActivity mActivity; + + @Before + public void setUp() { + when(mContext.getSystemService(UserManager.class)).thenReturn(mUserManager); + + mActivity = new WifiDppConfiguratorActivity(); + } + + @Test + public void isAddWifiConfigAllowed_hasNoUserRestriction_returnTrue() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(false); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isTrue(); + } + + @Test + public void isAddWifiConfigAllowed_hasUserRestriction_returnFalse() { + when(mUserManager.hasUserRestriction(DISALLOW_ADD_WIFI_CONFIG)).thenReturn(true); + + assertThat(mActivity.isAddWifiConfigAllowed(mContext)).isFalse(); + } +} From 1635951de2cd671450809f86c0dac0841d7e3b79 Mon Sep 17 00:00:00 2001 From: Les Lee Date: Fri, 22 Mar 2024 05:11:08 +0000 Subject: [PATCH 8/9] 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"); - } -} From 51a4bea7d9288e223c1899ee56979cf220164865 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Wed, 3 Apr 2024 15:23:44 +0800 Subject: [PATCH 9/9] Use SpaDialogWindowTypeActivity for WEP dialog TODO: Set different window type when called from Quick Settings. Bug: 332643450 Test: am start -n com.android.settings/.network.WepNetworkDialogActivity Change-Id: Ie888e7cc116234199316b030fb5f35dea6dbb3ac --- AndroidManifest.xml | 6 ++++-- .../settings/network/WepNetworkDialogActivity.kt | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index f374c386c24..2b2a1b82490 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -5184,9 +5184,11 @@ + android:permission="android.permission.NETWORK_SETTINGS" + android:theme="@style/Theme.SpaLib.Dialog"> diff --git a/src/com/android/settings/network/WepNetworkDialogActivity.kt b/src/com/android/settings/network/WepNetworkDialogActivity.kt index fef93ef7e96..d6fa7953887 100644 --- a/src/com/android/settings/network/WepNetworkDialogActivity.kt +++ b/src/com/android/settings/network/WepNetworkDialogActivity.kt @@ -27,18 +27,21 @@ import androidx.compose.ui.text.style.TextAlign import com.android.settings.R import com.android.settings.core.SubSettingLauncher import com.android.settings.wifi.ConfigureWifiSettings -import com.android.settingslib.spa.SpaBaseDialogActivity +import com.android.settingslib.spa.SpaDialogWindowTypeActivity import com.android.settingslib.spa.widget.dialog.AlertDialogButton -import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogWithIcon +import com.android.settingslib.spa.widget.dialog.SettingsAlertDialogContent import com.android.settingslib.wifi.WifiUtils.Companion.SSID -class WepNetworkDialogActivity : SpaBaseDialogActivity() { +class WepNetworkDialogActivity : SpaDialogWindowTypeActivity() { + + // TODO: Set different window type when called from Quick Settings. + override val dialogWindowType = null + @Composable override fun Content() { val context = LocalContext.current val wifiManager = context.getSystemService(WifiManager::class.java) - SettingsAlertDialogWithIcon( - onDismissRequest = { finish() }, + SettingsAlertDialogContent( confirmButton = AlertDialogButton( getString(R.string.wifi_settings_ssid_block_button_close) ) { finish() }, @@ -67,4 +70,4 @@ class WepNetworkDialogActivity : SpaBaseDialogActivity() { ) }) } -} \ No newline at end of file +}