From 0183cfd81642626aaa2c9e0d8592f0382ccd1a33 Mon Sep 17 00:00:00 2001 From: Yuxin Hu Date: Sat, 20 May 2023 00:52:11 +0000 Subject: [PATCH 1/3] Fix "Enable ANGLE" switch behavior when Developer Option Switch is off Fix below bugs: 1) When developer option switch is turned off, "Enable ANGLE" switch is not disabled. Fixed it in GraphicsDriverEnableAngleAsSystemDriverController::update(). 2) When user turns off developer option switch, a restart is not always mandatory. However, we should ask user to restart the device is "Enable ANGLE" is forced to change due to developer option switch turning off. Fixed it in DevelopmentSettingsDashboardFragment::onSwitchChanged(). 3) When user turns off developer option switch and the reboot dialog pops up, user can dismiss the dialog by not clicking either POSITIVE_BUTTON or NEGATIVE_BUTTON. We should enforce user to click the button and disallow the option to dimiss the dialog by touching screen areas outside the window's bounds. Fixed it in DisableDevSettingsDialogFragment.java. Did a few clean-up and in GraphicsDriverEnableAngleAsSystemDriverController.java, and updated unit test to reflect new code behavior. Bug: b/270994705 Test: m; flash and device can boot. Test: atest -c GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest Test: atest GraphicsDriverEnableAngleAsSystemDriverControllerTest Test: atest SettingsRoboTests:FreeformWindowsPreferenceControllerTest Test: atest SettingsRoboTests:DesktopModePreferenceControllerTest Change-Id: I199b2fe59b6ad948b753793254c822a293d8b40d --- .../DevelopmentSettingsDashboardFragment.java | 7 ++- .../DisableDevSettingsDialogFragment.java | 4 ++ ...erEnableAngleAsSystemDriverController.java | 57 +++++++++++-------- ...ableAngleAsSystemDriverControllerTest.java | 3 + ...ngleAsSystemDriverControllerJUnitTest.java | 26 +++------ 5 files changed, 55 insertions(+), 42 deletions(-) diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java index 87d8c17e307..f7be1aa47b1 100644 --- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java +++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java @@ -354,13 +354,18 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra final NfcVerboseVendorLogPreferenceController nfcVerboseLogController = getDevelopmentOptionsController( NfcVerboseVendorLogPreferenceController.class); + final GraphicsDriverEnableAngleAsSystemDriverController enableAngleController = + getDevelopmentOptionsController( + GraphicsDriverEnableAngleAsSystemDriverController.class); // If hardware offload isn't default value, we must reboot after disable // developer options. Show a dialog for the user to confirm. if ((a2dpController == null || a2dpController.isDefaultValue()) && (leAudioController == null || leAudioController.isDefaultValue()) && (nfcSnoopLogController == null || nfcSnoopLogController.isDefaultValue()) && (nfcVerboseLogController == null - || nfcVerboseLogController.isDefaultValue())) { + || nfcVerboseLogController.isDefaultValue()) + && (enableAngleController == null + || enableAngleController.isDefaultValue())) { disableDeveloperOptions(); } else { DisableDevSettingsDialogFragment.show(this /* host */); diff --git a/src/com/android/settings/development/DisableDevSettingsDialogFragment.java b/src/com/android/settings/development/DisableDevSettingsDialogFragment.java index 5db2ed4281b..224768b0561 100644 --- a/src/com/android/settings/development/DisableDevSettingsDialogFragment.java +++ b/src/com/android/settings/development/DisableDevSettingsDialogFragment.java @@ -45,6 +45,10 @@ public class DisableDevSettingsDialogFragment extends InstrumentedDialogFragment public static void show(DevelopmentSettingsDashboardFragment host) { final DisableDevSettingsDialogFragment dialog = new DisableDevSettingsDialogFragment(); dialog.setTargetFragment(host, 0 /* requestCode */); + // We need to handle data changes and switch state based on which button user clicks, + // therefore we should enforce user to click one of the buttons + // by disallowing dialog dismiss through tapping outside of dialog bounds. + dialog.setCancelable(false); final FragmentManager manager = host.getActivity().getSupportFragmentManager(); dialog.show(manager, TAG); } diff --git a/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java b/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java index 1a065a96aaa..b3af95ec0cc 100644 --- a/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java +++ b/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverController.java @@ -81,6 +81,11 @@ public class GraphicsDriverEnableAngleAsSystemDriverController this(context, fragment, new Injector()); } + private boolean isAngleSupported() { + return TextUtils.equals( + mSystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED, ""), "true"); + } + @VisibleForTesting GraphicsDriverEnableAngleAsSystemDriverController( Context context, DevelopmentSettingsDashboardFragment fragment, Injector injector) { @@ -118,38 +123,44 @@ public class GraphicsDriverEnableAngleAsSystemDriverController this); } - @Override - public void updateState(Preference preference) { - // set switch on if "persist.graphics.egl" is "angle" and angle is built in /vendor - // set switch off otherwise. + /** Return the default value of "persist.graphics.egl" */ + public boolean isDefaultValue() { + if (!isAngleSupported()) { + return true; + } + final String currentGlesDriver = mSystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL, ""); - final boolean isAngle = TextUtils.equals(ANGLE_DRIVER_SUFFIX, currentGlesDriver); - final boolean isAngleSupported = - TextUtils.equals( - mSystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED, ""), "true"); - ((SwitchPreference) mPreference).setChecked(isAngle && isAngleSupported); - ((SwitchPreference) mPreference).setEnabled(isAngleSupported); + // default value of "persist.graphics.egl" is "" + return TextUtils.isEmpty(currentGlesDriver); } @Override - protected void onDeveloperOptionsSwitchEnabled() { - // only enable the switch if ro.gfx.angle.supported is true - // we use ro.gfx.angle.supported to indicate if ANGLE libs are installed under /vendor - final boolean isAngleSupported = - TextUtils.equals( - mSystemProperties.get(PROPERTY_RO_GFX_ANGLE_SUPPORTED, ""), "true"); - ((SwitchPreference) mPreference).setEnabled(isAngleSupported); + public void updateState(Preference preference) { + super.updateState(preference); + if (isAngleSupported()) { + // set switch on if "persist.graphics.egl" is "angle" and angle is built in /vendor + // set switch off otherwise. + final String currentGlesDriver = + mSystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL, ""); + final boolean isAngle = TextUtils.equals(ANGLE_DRIVER_SUFFIX, currentGlesDriver); + ((SwitchPreference) mPreference).setChecked(isAngle); + } else { + mPreference.setEnabled(false); + ((SwitchPreference) mPreference).setChecked(false); + } } @Override protected void onDeveloperOptionsSwitchDisabled() { - // 1) set the persist.graphics.egl empty string - GraphicsEnvironment.getInstance().toggleAngleAsSystemDriver(false); - // 2) reset the switch - ((SwitchPreference) mPreference).setChecked(false); - // 3) disable switch - ((SwitchPreference) mPreference).setEnabled(false); + // 1) disable the switch + super.onDeveloperOptionsSwitchDisabled(); + if (isAngleSupported()) { + // 2) set the persist.graphics.egl empty string + GraphicsEnvironment.getInstance().toggleAngleAsSystemDriver(false); + // 3) reset the switch + ((SwitchPreference) mPreference).setChecked(false); + } } void toggleSwitchBack() { diff --git a/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerTest.java b/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerTest.java index de380c40c8e..9210b870d77 100644 --- a/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerTest.java +++ b/tests/robotests/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerTest.java @@ -141,6 +141,7 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerTest { @Test public void onDeveloperOptionSwitchDisabled_shouldDisableAngleAsSystemDriver() { + ShadowSystemProperties.override(PROPERTY_RO_GFX_ANGLE_SUPPORTED, "true"); mController.onDeveloperOptionsSwitchDisabled(); final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL); assertThat(systemEGLDriver).isEqualTo(""); @@ -148,12 +149,14 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerTest { @Test public void onDeveloperOptionSwitchDisabled_preferenceShouldNotBeChecked() { + ShadowSystemProperties.override(PROPERTY_RO_GFX_ANGLE_SUPPORTED, "true"); mController.onDeveloperOptionsSwitchDisabled(); verify(mPreference).setChecked(false); } @Test public void onDeveloperOptionsSwitchDisabled_preferenceShouldNotBeEnabled() { + ShadowSystemProperties.override(PROPERTY_RO_GFX_ANGLE_SUPPORTED, "true"); mController.onDeveloperOptionsSwitchDisabled(); verify(mPreference).setEnabled(false); } diff --git a/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java b/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java index c23292ac54a..ae35431fef7 100644 --- a/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java +++ b/tests/unit/src/com/android/settings/development/graphicsdriver/GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest.java @@ -57,7 +57,7 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest { private GraphicsDriverEnableAngleAsSystemDriverController mController; // Signal to wait for SystemProperty values changed - private class PropertyChangeSignal { + private static class PropertyChangeSignal { private CountDownLatch mCountDownLatch; private Runnable mCountDownJob; @@ -217,23 +217,7 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest { } @Test - public void onDeveloperOptionSwitchEnabled_angleSupported_PreferenceShouldEnabled() { - when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())) - .thenReturn("true"); - mController.onDeveloperOptionsSwitchEnabled(); - assertThat(mPreference.isEnabled()).isTrue(); - } - - @Test - public void onDeveloperOptionSwitchEnabled_angleNotSupported_PrefenceShouldDisabled() { - when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())) - .thenReturn("false"); - mController.onDeveloperOptionsSwitchEnabled(); - assertThat(mPreference.isEnabled()).isFalse(); - } - - @Test - public void onDeveloperOptionSwitchDisabled_angleIsNotSystemGLESDriver() { + public void onDeveloperOptionSwitchDisabled_angleShouldNotBeSystemGLESDriver() { // Add a callback when SystemProperty changes. // This allows the thread to wait until // GpuService::toggleAngleAsSystemDriver() updates the persist.graphics.egl. @@ -242,6 +226,8 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest { // Test that onDeveloperOptionSwitchDisabled, // persist.graphics.egl updates to "" + when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())) + .thenReturn("true"); mController.onDeveloperOptionsSwitchDisabled(); propertyChangeSignal1.wait(100); final String systemEGLDriver = SystemProperties.get(PROPERTY_PERSISTENT_GRAPHICS_EGL); @@ -253,12 +239,16 @@ public class GraphicsDriverEnableAngleAsSystemDriverControllerJUnitTest { @Test public void onDeveloperOptionSwitchDisabled_PreferenceShouldNotBeChecked() { + when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())) + .thenReturn("true"); mController.onDeveloperOptionsSwitchDisabled(); assertThat(mPreference.isChecked()).isFalse(); } @Test public void onDeveloperOptionSwitchDisabled_PreferenceShouldDisabled() { + when(mSystemPropertiesMock.get(eq(PROPERTY_RO_GFX_ANGLE_SUPPORTED), any())) + .thenReturn("true"); mController.onDeveloperOptionsSwitchDisabled(); assertThat(mPreference.isEnabled()).isFalse(); } From ce56dcc30bb5adb1e609f5f681ee49ce189b6d32 Mon Sep 17 00:00:00 2001 From: Chaohui Wang Date: Wed, 24 May 2023 19:41:20 +0800 Subject: [PATCH 2/3] Fix crash of PictureInPicture This follows change I3115cf1b99a305efef192a0dcf3e809eb7903d0a PackageManager.getPackageInfoAsUser() will throw exceptions when the package is too large which is a known issue to PackageManager but very low priority given resourcing constraints. As per the PackageManager team suggestion, catch the exception on the app side to alleviate the impact to the PictureInPicture & App info page. Fix: 283076353 Fix: 283354211 Test: Unit test Change-Id: Iad2bf9fbfca6ee7f604fec1c4afa1b9382f6ec7e --- .../spa/app/specialaccess/PictureInPicture.kt | 59 ++++++++++++------- .../app/specialaccess/PictureInPictureTest.kt | 32 ++++++++++ 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt index 9fc358b5cf8..5ed361560d7 100644 --- a/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt +++ b/src/com/android/settings/spa/app/specialaccess/PictureInPicture.kt @@ -23,6 +23,7 @@ import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager.GET_ACTIVITIES import android.content.pm.PackageManager.PackageInfoFlags +import android.util.Log import androidx.compose.runtime.Composable import androidx.compose.runtime.livedata.observeAsState import com.android.settings.R @@ -56,26 +57,21 @@ class PictureInPictureListModel(private val context: Context) : private val packageManager = context.packageManager override fun transform(userIdFlow: Flow, appListFlow: Flow>) = - userIdFlow.map(::getPictureInPicturePackages).combine(appListFlow) { - pictureInPicturePackages, - appList -> - appList.map { app -> - createPictureInPictureRecord( - app = app, - isSupport = app.packageName in pictureInPicturePackages, - ) + userIdFlow.map(::getPictureInPicturePackages) + .combine(appListFlow) { pictureInPicturePackages, appList -> + appList.map { app -> + createPictureInPictureRecord( + app = app, + isSupport = app.packageName in pictureInPicturePackages, + ) + } } - } - override fun transformItem(app: ApplicationInfo): PictureInPictureRecord { - return createPictureInPictureRecord( - app = app, - isSupport = app.installed && - packageManager - .getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId) - .supportsPictureInPicture(), - ) - } + override fun transformItem(app: ApplicationInfo) = createPictureInPictureRecord( + app = app, + isSupport = app.installed && + getPackageAndActivityInfo(app)?.supportsPictureInPicture() == true, + ) private fun createPictureInPictureRecord(app: ApplicationInfo, isSupport: Boolean) = PictureInPictureRecord( @@ -103,13 +99,36 @@ class PictureInPictureListModel(private val context: Context) : } private fun getPictureInPicturePackages(userId: Int): Set = - packageManager - .getInstalledPackagesAsUser(GET_ACTIVITIES_FLAGS, userId) + getPackageAndActivityInfoList(userId) .filter { it.supportsPictureInPicture() } .map { it.packageName } .toSet() + private fun getPackageAndActivityInfo(app: ApplicationInfo): PackageInfo? = try { + packageManager.getPackageInfoAsUser(app.packageName, GET_ACTIVITIES_FLAGS, app.userId) + } catch (e: Exception) { + // Query PackageManager.getPackageInfoAsUser() with GET_ACTIVITIES_FLAGS could cause + // exception sometimes. Since we reply on this flag to retrieve the Picture In Picture + // packages, we need to catch the exception to alleviate the impact before PackageManager + // fixing this issue or provide a better api. + Log.e(TAG, "Exception while getPackageInfoAsUser", e) + null + } + + private fun getPackageAndActivityInfoList(userId: Int): List = try { + packageManager.getInstalledPackagesAsUser(GET_ACTIVITIES_FLAGS, userId) + } catch (e: Exception) { + // Query PackageManager.getPackageInfoAsUser() with GET_ACTIVITIES_FLAGS could cause + // exception sometimes. Since we reply on this flag to retrieve the Picture In Picture + // packages, we need to catch the exception to alleviate the impact before PackageManager + // fixing this issue or provide a better api. + Log.e(TAG, "Exception while getInstalledPackagesAsUser", e) + emptyList() + } + companion object { + private const val TAG = "PictureInPictureListModel" + private fun PackageInfo.supportsPictureInPicture() = activities?.any(ActivityInfo::supportsPictureInPicture) ?: false diff --git a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt index f90d63947d0..fb0fb698045 100644 --- a/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt +++ b/tests/spa_unit/src/com/android/settings/spa/app/specialaccess/PictureInPictureTest.kt @@ -23,6 +23,7 @@ import android.content.pm.ApplicationInfo import android.content.pm.PackageInfo import android.content.pm.PackageManager import android.content.pm.PackageManager.PackageInfoFlags +import android.os.DeadSystemRuntimeException import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settings.R @@ -100,6 +101,23 @@ class PictureInPictureTest { assertThat(record.isSupport).isTrue() } + @Test + fun transform_getInstalledPackagesAsUserThrowsException_treatAsNotSupported() = runTest { + whenever(packageManager.getInstalledPackagesAsUser(any(), anyInt())) + .thenThrow(DeadSystemRuntimeException()) + + val recordListFlow = listModel.transform( + userIdFlow = flowOf(USER_ID), + appListFlow = flowOf(listOf(PICTURE_IN_PICTURE_APP)), + ) + + val recordList = recordListFlow.first() + assertThat(recordList).hasSize(1) + val record = recordList[0] + assertThat(record.app).isSameInstanceAs(PICTURE_IN_PICTURE_APP) + assertThat(record.isSupport).isFalse() + } + @Test fun transformItem() { whenever( @@ -114,6 +132,20 @@ class PictureInPictureTest { assertThat(record.isSupport).isTrue() } + @Test + fun transformItem_getPackageInfoAsUserThrowsException_treatAsNotSupported() { + whenever( + packageManager.getPackageInfoAsUser( + eq(PICTURE_IN_PICTURE_PACKAGE_NAME), any(), eq(USER_ID) + ) + ).thenThrow(DeadSystemRuntimeException()) + + val record = listModel.transformItem(PICTURE_IN_PICTURE_APP) + + assertThat(record.app).isSameInstanceAs(PICTURE_IN_PICTURE_APP) + assertThat(record.isSupport).isFalse() + } + @Test fun filter_isSupport() = runTest { val record = createRecord(isSupport = true) From 97a1fc643e23158f22316ec5a517bbcce278ab79 Mon Sep 17 00:00:00 2001 From: tom hsu Date: Wed, 24 May 2023 16:06:47 +0800 Subject: [PATCH 3/3] [Settings] Use background thread to get VoNr state. - TelephonyManager#isVoNrEnabled may not send back the result in time, so use different thread and timer to prevent ANR. Bug: 282876876 Test: atest passed Change-Id: Ie6cc0f8a459f5ebed930e457dacb9b742df70fad --- ...NrAdvancedCallingPreferenceController.java | 25 +++++++++++++++++-- ...vancedCallingPreferenceControllerTest.java | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java index b585ecec6a4..5786dfc99cd 100644 --- a/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java +++ b/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceController.java @@ -17,6 +17,8 @@ package com.android.settings.network.telephony; import android.content.Context; +import android.os.Handler; +import android.os.Looper; import android.os.PersistableBundle; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; @@ -33,9 +35,10 @@ import com.android.internal.telephony.util.ArrayUtils; import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnStart; import com.android.settingslib.core.lifecycle.events.OnStop; +import com.android.settingslib.utils.ThreadUtils; /** - * Preference controller for "Enhanced 4G LTE" + * Preference controller for "Voice over NR". */ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePreferenceController implements LifecycleObserver, OnStart, OnStop { @@ -50,8 +53,11 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer private boolean mIsVonrVisibleFromCarrierConfig = false; private boolean mIsNrEnableFromCarrierConfig = false; private boolean mHas5gCapability = false; + private boolean mIsVoNrEnabled = false; private Integer mCallState; + private Handler mHandler = new Handler(Looper.getMainLooper()); + public NrAdvancedCallingPreferenceController(Context context, String key) { super(context, key); mTelephonyManager = context.getSystemService(TelephonyManager.class); @@ -94,6 +100,8 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer CarrierConfigManager.KEY_CARRIER_NR_AVAILABILITIES_INT_ARRAY); mIsNrEnableFromCarrierConfig = !ArrayUtils.isEmpty(nrAvailabilities); + updateVoNrState(); + Log.d(TAG, "mHas5gCapability: " + mHas5gCapability + ",mIsNrEnabledFromCarrierConfig: " + mIsNrEnableFromCarrierConfig + ",mIsVonrEnabledFromCarrierConfig: " + mIsVonrEnabledFromCarrierConfig @@ -162,7 +170,7 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer @Override public boolean isChecked() { - return mTelephonyManager.isVoNrEnabled(); + return mIsVoNrEnabled; } @VisibleForTesting @@ -174,6 +182,19 @@ public class NrAdvancedCallingPreferenceController extends TelephonyTogglePrefer return isCallStateIdle(); } + private void updateVoNrState() { + ThreadUtils.postOnBackgroundThread(() -> { + boolean result = mTelephonyManager.isVoNrEnabled(); + if (result != mIsVoNrEnabled) { + Log.i(TAG, "VoNr state : " + result); + mIsVoNrEnabled = result; + mHandler.post(() -> { + updateState(mPreference); + }); + } + }); + } + private class PhoneCallStateTelephonyCallback extends TelephonyCallback implements TelephonyCallback.CallStateListener { diff --git a/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java index 9d4082ecff6..053fb4d8916 100644 --- a/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/NrAdvancedCallingPreferenceControllerTest.java @@ -186,6 +186,7 @@ public class NrAdvancedCallingPreferenceControllerTest { doReturn(true).when(mTelephonyManager).isVoNrEnabled(); mPreference.setChecked(false); + mController.init(SUB_ID); mController.updateState(mPreference); assertThat(mPreference.isChecked()).isTrue();