From 94621548c176c2bbba4100134337a9db5fba3d97 Mon Sep 17 00:00:00 2001 From: Riley Jones Date: Wed, 23 Oct 2024 21:25:38 +0000 Subject: [PATCH 1/5] Disabling elements on the A11y Shortcut setting subpage Elements on the subpage get disabled if there are no enabled shortcut targets for the relevant type. In the case of A11y button, the items on its fragment become unsearchable when the setting is disabled. Test: Manually verify conditions described above & in bug Bug: 349180207 Flag: com.android.settings.accessibility.fix_a11y_settings_search Change-Id: Id39e2eda6c9d1de4cdbfcbc22b8a1f443e2822d9 --- res/values/strings.xml | 2 + res/xml/accessibility_shortcuts_settings.xml | 5 +- .../AccessibilityButtonFragment.java | 19 ++++++- ...cessibilityButtonPreferenceController.java | 34 ++++++++++- ...utFromLockscreenPreferenceController.java} | 42 ++++++++++++-- .../AccessibilityButtonFragmentTest.java | 37 +++++++++++- ...ibilityButtonPreferenceControllerTest.java | 32 +++++++++++ ...omLockscreenPreferenceControllerTest.java} | 57 +++++++++++++++---- .../display/ColorContrastFragmentTest.java | 3 +- 9 files changed, 205 insertions(+), 26 deletions(-) rename src/com/android/settings/accessibility/{AccessibilityShortcutPreferenceController.java => HardwareShortcutFromLockscreenPreferenceController.java} (58%) rename tests/{unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java => robotests/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceControllerTest.java} (56%) diff --git a/res/values/strings.xml b/res/values/strings.xml index ce2e3985b4e..7a646e09e70 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -5722,6 +5722,8 @@ Edit accessibility shortcuts Choose your shortcut for %1$s + + To use this, turn on the %1$s shortcut on an accessibility feature\'s page Continue diff --git a/res/xml/accessibility_shortcuts_settings.xml b/res/xml/accessibility_shortcuts_settings.xml index c8070564eb4..18ec9e927ba 100644 --- a/res/xml/accessibility_shortcuts_settings.xml +++ b/res/xml/accessibility_shortcuts_settings.xml @@ -19,7 +19,8 @@ xmlns:settings="http://schemas.android.com/apk/res-auto" android:key="accessibility_shortcuts_settings" android:persistent="false" - android:title="@string/accessibility_shortcuts_settings_title"> + android:title="@string/accessibility_shortcuts_settings_title" + settings:searchable="false"> + settings:controller="com.android.settings.accessibility.HardwareShortcutFromLockscreenPreferenceController"/> diff --git a/src/com/android/settings/accessibility/AccessibilityButtonFragment.java b/src/com/android/settings/accessibility/AccessibilityButtonFragment.java index 60e4bb28fea..116554d735a 100644 --- a/src/com/android/settings/accessibility/AccessibilityButtonFragment.java +++ b/src/com/android/settings/accessibility/AccessibilityButtonFragment.java @@ -16,9 +16,14 @@ package com.android.settings.accessibility; -import android.app.settings.SettingsEnums; -import android.os.Bundle; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; +import android.app.settings.SettingsEnums; +import android.content.Context; +import android.os.Bundle; +import android.provider.Settings; + +import com.android.internal.accessibility.util.ShortcutUtils; import com.android.settings.R; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; @@ -61,5 +66,13 @@ public class AccessibilityButtonFragment extends DashboardFragment { } public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider(R.xml.accessibility_button_settings); + new BaseSearchIndexProvider(R.xml.accessibility_button_settings) { + @Override + protected boolean isPageSearchEnabled(Context context) { + // Page should be unsearchable if there are no active button targets + String targets = Settings.Secure.getStringForUser(context.getContentResolver(), + ShortcutUtils.convertToKey(SOFTWARE), context.getUserId()); + return targets != null && !targets.isEmpty(); + } + }; } diff --git a/src/com/android/settings/accessibility/AccessibilityButtonPreferenceController.java b/src/com/android/settings/accessibility/AccessibilityButtonPreferenceController.java index 68a765c9230..d9ee3cd31f7 100644 --- a/src/com/android/settings/accessibility/AccessibilityButtonPreferenceController.java +++ b/src/com/android/settings/accessibility/AccessibilityButtonPreferenceController.java @@ -16,9 +16,13 @@ package com.android.settings.accessibility; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; + import android.content.Context; import android.content.res.Resources; +import android.view.accessibility.AccessibilityManager; +import androidx.annotation.NonNull; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; @@ -32,14 +36,39 @@ import java.util.List; * Preference controller for accessibility button preference. */ public class AccessibilityButtonPreferenceController extends BasePreferenceController { - public AccessibilityButtonPreferenceController(Context context, String key) { super(context, key); } @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) { + return AVAILABLE; + } else { + if (mContext.getSystemService(AccessibilityManager.class) + .getAccessibilityShortcutTargets(SOFTWARE).isEmpty()) { + return DISABLED_DEPENDENT_SETTING; + } else { + return AVAILABLE; + } + } + } + + @Override + public void updateState(@NonNull Preference preference) { + super.updateState(preference); + refreshSummary(preference); + } + + @Override + public @NonNull CharSequence getSummary() { + if (getAvailabilityStatus() == AVAILABLE) { + return ""; + } else { + return mContext.getString( + R.string.accessibility_shortcut_unassigned_setting_unavailable_summary, + AccessibilityUtil.getShortcutSummaryList(mContext, SOFTWARE)); + } } @Override @@ -47,7 +76,6 @@ public class AccessibilityButtonPreferenceController extends BasePreferenceContr super.displayPreference(screen); final Preference preference = screen.findPreference(getPreferenceKey()); preference.setTitle(getPreferenceTitleResource()); - } @Override diff --git a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java b/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceController.java similarity index 58% rename from src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java rename to src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceController.java index d204bb761db..a6d5b7bc7fe 100644 --- a/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceController.java +++ b/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceController.java @@ -15,6 +15,7 @@ */ package com.android.settings.accessibility; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; @@ -22,16 +23,21 @@ import android.content.ContentResolver; import android.content.Context; import android.os.UserHandle; import android.provider.Settings; +import android.view.accessibility.AccessibilityManager; + +import androidx.annotation.NonNull; +import androidx.preference.Preference; import com.android.settings.R; import com.android.settings.core.TogglePreferenceController; /** - * Settings page for accessibility shortcut + * Setting to allow the hardware shortcut to turn on from the lock screen */ -public class AccessibilityShortcutPreferenceController extends TogglePreferenceController { - - public AccessibilityShortcutPreferenceController(Context context, String preferenceKey) { +public class HardwareShortcutFromLockscreenPreferenceController + extends TogglePreferenceController { + public HardwareShortcutFromLockscreenPreferenceController( + Context context, String preferenceKey) { super(context, preferenceKey); } @@ -56,7 +62,33 @@ public class AccessibilityShortcutPreferenceController extends TogglePreferenceC @Override public int getAvailabilityStatus() { - return AVAILABLE; + if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) { + return AVAILABLE; + } else { + if (mContext.getSystemService(AccessibilityManager.class) + .getAccessibilityShortcutTargets(HARDWARE).isEmpty()) { + return DISABLED_DEPENDENT_SETTING; + } else { + return AVAILABLE; + } + } + } + + @Override + public void updateState(@NonNull Preference preference) { + super.updateState(preference); + refreshSummary(preference); + } + + @Override + public @NonNull CharSequence getSummary() { + if (getAvailabilityStatus() == AVAILABLE) { + return mContext.getString(R.string.accessibility_shortcut_description); + } else { + return mContext.getString( + R.string.accessibility_shortcut_unassigned_setting_unavailable_summary, + AccessibilityUtil.getShortcutSummaryList(mContext, HARDWARE)); + } } @Override diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java index 94312a60eee..386463a5666 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonFragmentTest.java @@ -19,6 +19,8 @@ package com.android.settings.accessibility; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.spy; @@ -39,6 +41,7 @@ import androidx.preference.PreferenceManager; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; +import com.android.internal.accessibility.util.ShortcutUtils; import com.android.settings.R; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowFragment; @@ -132,6 +135,7 @@ public class AccessibilityButtonFragmentTest { } @Test + @DisableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) public void getNonIndexableKeys_existInXmlLayout() { final List niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(mContext); @@ -139,7 +143,38 @@ public class AccessibilityButtonFragmentTest { XmlTestUtils.getKeysFromPreferenceXml(mContext, R.xml.accessibility_button_settings); - assertThat(keys).containsAtLeastElementsIn(niks); + assertThat(keys).isNotNull(); + assertThat(niks).containsAtLeastElementsIn(keys); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getNonIndexableKeys_noTargets_doesNotExistInXmlLayout() { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + ShortcutUtils.convertToKey(SOFTWARE), "", mContext.getUserId()); + final List niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + final List keys = + XmlTestUtils.getKeysFromPreferenceXml(mContext, + R.xml.accessibility_button_settings); + + assertThat(keys).isNotNull(); + assertThat(niks).containsAtLeastElementsIn(keys); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getNonIndexableKeys_hasTargets_expectedKeys() { + Settings.Secure.putStringForUser(mContext.getContentResolver(), + ShortcutUtils.convertToKey(SOFTWARE), "Foo", mContext.getUserId()); + final List niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER + .getNonIndexableKeys(mContext); + + // Some keys should show up anyway, as they're flagged as unsearchable in the xml. + assertThat(niks).containsAtLeast( + "accessibility_button_preview", + "accessibility_button_footer", + "accessibility_button_or_gesture"); } private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment { diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java index 85aa77c1ab8..e5169cd0082 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilityButtonPreferenceControllerTest.java @@ -20,6 +20,10 @@ import static android.provider.Settings.Secure.NAVIGATION_MODE; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE; +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; + import static com.google.common.truth.Truth.assertThat; import static org.mockito.Mockito.when; @@ -31,12 +35,15 @@ import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Flags; import android.provider.Settings; +import android.view.accessibility.AccessibilityManager; import androidx.preference.Preference; import androidx.preference.PreferenceScreen; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; +import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settingslib.search.SearchIndexableRaw; import org.junit.Before; @@ -48,11 +55,17 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.List; /** Tests for {@link AccessibilityButtonPreferenceController}. */ +@Config(shadows = { + SettingsShadowResources.class, + com.android.settings.testutils.shadow.ShadowAccessibilityManager.class +}) @RunWith(RobolectricTestRunner.class) public class AccessibilityButtonPreferenceControllerTest { @@ -68,9 +81,12 @@ public class AccessibilityButtonPreferenceControllerTest { private PreferenceScreen mScreen; private Preference mPreference; private AccessibilityButtonPreferenceController mController; + private ShadowAccessibilityManager mShadowAccessibilityManager; @Before public void setUp() { + mShadowAccessibilityManager = Shadow.extract( + mContext.getSystemService(AccessibilityManager.class)); mController = new AccessibilityButtonPreferenceController(mContext, "test_key"); mPreference = new Preference(mContext); mPreference.setKey("test_key"); @@ -163,4 +179,20 @@ public class AccessibilityButtonPreferenceControllerTest { assertThat(raw.screenTitle).isEqualTo( mResources.getString(R.string.accessibility_shortcuts_settings_title)); } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getAvailabilityStatus_settingEmpty_disabled() { + mShadowAccessibilityManager.setAccessibilityShortcutTargets(SOFTWARE, List.of()); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + @EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getAvailabilityStatus_settingNotEmpty_available() { + mShadowAccessibilityManager.setAccessibilityShortcutTargets(SOFTWARE, List.of("Foo")); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } } diff --git a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceControllerTest.java similarity index 56% rename from tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java rename to tests/robotests/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceControllerTest.java index 7d903ee01a4..30541a6a2b6 100644 --- a/tests/unit/src/com/android/settings/accessibility/AccessibilityShortcutPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/HardwareShortcutFromLockscreenPreferenceControllerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 The Android Open Source Project + * 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. @@ -16,36 +16,57 @@ package com.android.settings.accessibility; +import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.ON; - -import androidx.test.core.app.ApplicationProvider; -import androidx.test.ext.junit.runners.AndroidJUnit4; +import static com.android.settings.core.BasePreferenceController.AVAILABLE; +import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING; import static com.google.common.truth.Truth.assertThat; import android.content.Context; import android.os.UserHandle; +import android.platform.test.annotations.EnableFlags; +import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; +import android.view.accessibility.AccessibilityManager; import androidx.preference.SwitchPreference; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.testutils.shadow.SettingsShadowResources; +import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; -@RunWith(AndroidJUnit4.class) -public class AccessibilityShortcutPreferenceControllerTest { +import java.util.List; - private Context mContext; +@Config(shadows = { + SettingsShadowResources.class, + com.android.settings.testutils.shadow.ShadowAccessibilityManager.class +}) +@RunWith(RobolectricTestRunner.class) +public class HardwareShortcutFromLockscreenPreferenceControllerTest { + @Rule + public SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + + private Context mContext = ApplicationProvider.getApplicationContext(); private SwitchPreference mPreference; - private AccessibilityShortcutPreferenceController mController; + private HardwareShortcutFromLockscreenPreferenceController mController; + private ShadowAccessibilityManager mShadowAccessibilityManager; @Before public void setUp() { - mContext = ApplicationProvider.getApplicationContext(); + mShadowAccessibilityManager = Shadow.extract( + mContext.getSystemService(AccessibilityManager.class)); mPreference = new SwitchPreference(mContext); - mController = new AccessibilityShortcutPreferenceController(mContext, + mController = new HardwareShortcutFromLockscreenPreferenceController(mContext, "accessibility_shortcut_preference"); } @@ -89,4 +110,20 @@ public class AccessibilityShortcutPreferenceControllerTest { Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON, UserHandle.USER_CURRENT)).isEqualTo(OFF); } + + @Test + @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getAvailabilityStatus_settingEmpty_disabled() { + mShadowAccessibilityManager.setAccessibilityShortcutTargets(HARDWARE, List.of()); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING); + } + + @Test + @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + public void getAvailabilityStatus_settingNotEmpty_available() { + mShadowAccessibilityManager.setAccessibilityShortcutTargets(HARDWARE, List.of("Foo")); + + assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); + } } diff --git a/tests/robotests/src/com/android/settings/display/ColorContrastFragmentTest.java b/tests/robotests/src/com/android/settings/display/ColorContrastFragmentTest.java index 47a7363b531..1e6827ba9f3 100644 --- a/tests/robotests/src/com/android/settings/display/ColorContrastFragmentTest.java +++ b/tests/robotests/src/com/android/settings/display/ColorContrastFragmentTest.java @@ -28,7 +28,6 @@ import android.content.Context; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; -import com.android.settings.accessibility.ShortcutsSettingsFragment; import com.android.settings.testutils.XmlTestUtils; import org.junit.Before; @@ -79,7 +78,7 @@ public class ColorContrastFragmentTest { @Test public void getNonIndexableKeys_existInXmlLayout() { final List niks = - ShortcutsSettingsFragment.SEARCH_INDEX_DATA_PROVIDER + ColorContrastFragment.SEARCH_INDEX_DATA_PROVIDER .getNonIndexableKeys(mContext); final List keys = XmlTestUtils.getKeysFromPreferenceXml(mContext, From 33863f8eda3314b370409c03596d2d2306c1c370 Mon Sep 17 00:00:00 2001 From: Shawn Lin Date: Sat, 4 Jan 2025 08:05:22 +0000 Subject: [PATCH 2/5] [Gaze] Support Gaze - Add gaze configs and resources - Extract the logic for setting/getting gaze out from FaceSettingsAttentionPreferenceController to FaceAttentionController Bug: 388686801 Test: make Flag: com.android.settings.flags.biometrics_onboarding_education Change-Id: I2f45c7b01674a28f7f02f614292331ced355cc6f --- res/values/config.xml | 3 + res/values/strings.xml | 4 + .../face/FaceAttentionController.java | 109 ++++++++++++++++++ .../biometrics/face/FaceEnrollEducation.java | 18 ++- ...SettingsAttentionPreferenceController.java | 64 +++++----- 5 files changed, 156 insertions(+), 42 deletions(-) create mode 100644 src/com/android/settings/biometrics/face/FaceAttentionController.java diff --git a/res/values/config.xml b/res/values/config.xml index 95f8eba8f84..9ad203505ed 100644 --- a/res/values/config.xml +++ b/res/values/config.xml @@ -845,4 +845,7 @@ false + + + false diff --git a/res/values/strings.xml b/res/values/strings.xml index ce2e3985b4e..b3699271e51 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -924,6 +924,10 @@ Require eyes to be open To unlock the phone, your eyes must be open + + + + Always require confirmation diff --git a/src/com/android/settings/biometrics/face/FaceAttentionController.java b/src/com/android/settings/biometrics/face/FaceAttentionController.java new file mode 100644 index 00000000000..f035dfd0719 --- /dev/null +++ b/src/com/android/settings/biometrics/face/FaceAttentionController.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2025 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.biometrics.face; + +import static android.hardware.biometrics.BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION; + +import android.content.Context; +import android.hardware.face.FaceManager; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.settings.Utils; + +public class FaceAttentionController { + + @Nullable private byte[] mToken; + private FaceManager mFaceManager; + + public interface OnSetAttentionListener { + /** + * Calls when setting attention is completed from FaceManager. + */ + void onSetAttentionCompleted(boolean success); + } + + public interface OnGetAttentionListener { + /** + * Calls when getting attention is completed from FaceManager. + */ + void onGetAttentionCompleted(boolean success, boolean enabled); + } + + @Nullable private OnSetAttentionListener mSetListener; + @Nullable private OnGetAttentionListener mGetListener; + + private final FaceManager.SetFeatureCallback mSetFeatureCallback = + new FaceManager.SetFeatureCallback() { + @Override + public void onCompleted(boolean success, int feature) { + if (feature == FEATURE_REQUIRE_ATTENTION) { + if (mSetListener != null) { + mSetListener.onSetAttentionCompleted(success); + } + } + } + }; + + private final FaceManager.GetFeatureCallback mGetFeatureCallback = + new FaceManager.GetFeatureCallback() { + @Override + public void onCompleted( + boolean success, @NonNull int[] features, @NonNull boolean[] featureState) { + boolean requireAttentionEnabled = false; + for (int i = 0; i < features.length; i++) { + if (features[i] == FEATURE_REQUIRE_ATTENTION) { + requireAttentionEnabled = featureState[i]; + } + } + if (mGetListener != null) { + mGetListener.onGetAttentionCompleted(success, requireAttentionEnabled); + } + } + }; + + public FaceAttentionController(@NonNull Context context) { + mFaceManager = Utils.getFaceManagerOrNull(context); + } + + /** + * Set the challenge token + */ + public void setToken(@Nullable byte[] token) { + mToken = token; + } + + /** + * Get the gaze status + */ + public void getAttentionStatus(int userId, + @Nullable OnGetAttentionListener listener) { + mGetListener = listener; + mFaceManager.getFeature(userId, FEATURE_REQUIRE_ATTENTION, mGetFeatureCallback); + } + + /** + * Set the gaze status + */ + public void setAttentionStatus( + int userId, boolean enabled, @Nullable OnSetAttentionListener listener) { + mSetListener = listener; + mFaceManager.setFeature(userId, FEATURE_REQUIRE_ATTENTION, enabled, mToken, + mSetFeatureCallback); + } +} diff --git a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java index 6862bc921d7..7b0b8ef0f56 100644 --- a/src/com/android/settings/biometrics/face/FaceEnrollEducation.java +++ b/src/com/android/settings/biometrics/face/FaceEnrollEducation.java @@ -69,6 +69,7 @@ public class FaceEnrollEducation extends BiometricEnrollBase { private View mIllustrationAccessibility; private Intent mResultIntent; private boolean mAccessibilityEnabled; + protected Intent mExtraInfoIntent; private final CompoundButton.OnCheckedChangeListener mSwitchDiversityListener = new CompoundButton.OnCheckedChangeListener() { @@ -171,12 +172,7 @@ public class FaceEnrollEducation extends BiometricEnrollBase { mFooterBarMixin.setPrimaryButton(footerButton); final Button accessibilityButton = findViewById(R.id.accessibility_button); - accessibilityButton.setOnClickListener(view -> { - mSwitchDiversity.setChecked(true); - accessibilityButton.setVisibility(View.GONE); - mSwitchDiversity.setVisibility(View.VISIBLE); - mSwitchDiversity.addOnLayoutChangeListener(mSwitchDiversityOnLayoutChangeListener); - }); + accessibilityButton.setOnClickListener(this::onAccessibilityButtonClicked); mSwitchDiversity = findViewById(R.id.toggle_diversity); mSwitchDiversity.setListener(mSwitchDiversityListener); @@ -263,6 +259,9 @@ public class FaceEnrollEducation extends BiometricEnrollBase { if (mResultIntent != null) { intent.putExtras(mResultIntent); } + if (mExtraInfoIntent != null) { + intent.putExtras(mExtraInfoIntent); + } intent.putExtra(EXTRA_KEY_REQUIRE_DIVERSITY, !mSwitchDiversity.isChecked()); intent.putExtra(BiometricUtils.EXTRA_ENROLL_REASON, @@ -282,6 +281,13 @@ public class FaceEnrollEducation extends BiometricEnrollBase { } + protected void onAccessibilityButtonClicked(View view) { + mSwitchDiversity.setChecked(true); + view.setVisibility(View.GONE); + mSwitchDiversity.setVisibility(View.VISIBLE); + mSwitchDiversity.addOnLayoutChangeListener(mSwitchDiversityOnLayoutChangeListener); + } + protected void onSkipButtonClick(View view) { if (!BiometricUtils.tryStartingNextBiometricEnroll(this, ENROLL_NEXT_BIOMETRIC_REQUEST, "edu_skip")) { diff --git a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java index 71c46787261..c7e2141c53a 100644 --- a/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java +++ b/src/com/android/settings/biometrics/face/FaceSettingsAttentionPreferenceController.java @@ -16,12 +16,8 @@ package com.android.settings.biometrics.face; -import static android.hardware.biometrics.BiometricFaceConstants.FEATURE_REQUIRE_ATTENTION; - import android.content.Context; import android.hardware.face.FaceManager; -import android.hardware.face.FaceManager.GetFeatureCallback; -import android.hardware.face.FaceManager.SetFeatureCallback; import android.provider.Settings; import androidx.annotation.Nullable; @@ -31,6 +27,7 @@ import androidx.preference.TwoStatePreference; import com.android.settings.R; import com.android.settings.Utils; +import com.android.settings.flags.Flags; /** * Preference controller that manages the ability to use face authentication with/without @@ -40,14 +37,13 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe public static final String KEY = "security_settings_face_require_attention"; - private byte[] mToken; - private FaceManager mFaceManager; private TwoStatePreference mPreference; + private boolean mGazeEnabled; - private final SetFeatureCallback mSetFeatureCallback = new SetFeatureCallback() { - @Override - public void onCompleted(boolean success, int feature) { - if (feature == FEATURE_REQUIRE_ATTENTION) { + private FaceAttentionController mFaceAttentionController; + + private final FaceAttentionController.OnSetAttentionListener mSetAttentionListener = + (success) -> { mPreference.setEnabled(true); if (!success) { mPreference.setChecked(!mPreference.isChecked()); @@ -56,31 +52,23 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe Settings.Secure.FACE_UNLOCK_ATTENTION_REQUIRED, mPreference.isChecked() ? 1 : 0, getUserId()); } - } - } - }; + }; - private final GetFeatureCallback mGetFeatureCallback = new GetFeatureCallback() { - @Override - public void onCompleted(boolean success, int[] features, boolean[] featureState) { - boolean requireAttentionEnabled = false; - for (int i = 0; i < features.length; i++) { - if (features[i] == FEATURE_REQUIRE_ATTENTION) { - requireAttentionEnabled = featureState[i]; + private final FaceAttentionController.OnGetAttentionListener mOnGetAttentionListener = + (success, requireAttentionEnabled) -> { + mPreference.setChecked(requireAttentionEnabled); + if (getRestrictingAdmin() != null) { + mPreference.setEnabled(false); + } else { + mPreference.setEnabled(success); } - } - mPreference.setChecked(requireAttentionEnabled); - if (getRestrictingAdmin() != null) { - mPreference.setEnabled(false); - } else { - mPreference.setEnabled(success); - } - } - }; + }; public FaceSettingsAttentionPreferenceController(Context context, String preferenceKey) { super(context, preferenceKey); - mFaceManager = Utils.getFaceManagerOrNull(context); + mFaceAttentionController = new FaceAttentionController(context); + mGazeEnabled = context.getResources().getBoolean(R.bool.config_gazeEnabled) + && Flags.biometricsOnboardingEducation(); } public FaceSettingsAttentionPreferenceController(Context context) { @@ -88,7 +76,9 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe } public void setToken(byte[] token) { - mToken = token; + if (mFaceAttentionController != null) { + mFaceAttentionController.setToken(token); + } } /** @@ -109,6 +99,11 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe if (Utils.isPrivateProfile(getUserId(), mContext)) { preference.setSummary(mContext.getString( R.string.private_space_face_settings_require_attention_details)); + } else if (mGazeEnabled) { + preference.setTitle(mContext.getString( + R.string.security_settings_face_settings_gaze)); + preference.setSummary(mContext.getString( + R.string.security_settings_face_settings_gaze_details)); } } @@ -119,8 +114,7 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe } // Set to disabled until we know the true value. mPreference.setEnabled(false); - mFaceManager.getFeature(getUserId(), FEATURE_REQUIRE_ATTENTION, - mGetFeatureCallback); + mFaceAttentionController.getAttentionStatus(getUserId(), mOnGetAttentionListener); // Ideally returns a cached value. return true; @@ -131,9 +125,7 @@ public class FaceSettingsAttentionPreferenceController extends FaceSettingsPrefe // Optimistically update state and set to disabled until we know it succeeded. mPreference.setEnabled(false); mPreference.setChecked(isChecked); - - mFaceManager.setFeature(getUserId(), FEATURE_REQUIRE_ATTENTION, - isChecked, mToken, mSetFeatureCallback); + mFaceAttentionController.setAttentionStatus(getUserId(), isChecked, mSetAttentionListener); return true; } From 506c3e04e3150e26de3b02ccf86d066693d7aa39 Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Mon, 27 Jan 2025 09:27:20 -0800 Subject: [PATCH 3/5] Cleaned up the flag enable_identifier_disclosure_transparency Cleaned up the 24Q3 flag enable_identifier_disclosure_transparency Bug: 276752426 Test: Basic telephony functionality tests Test: atest FrameworksTelephonyTests Flag: EXEMPT removing flag Change-Id: Id3355ef2416f75df8ca43cc4d261583e92c17fba --- .../network/CellularSecurityPreferenceController.java | 1 - .../CellularSecurityNotificationsDividerController.java | 1 - .../CellularSecurityNotificationsPreferenceController.java | 1 - .../network/CellularSecurityPreferenceControllerTest.java | 4 ---- .../CellularSecurityNotificationsDividerControllerTest.java | 4 ---- ...CellularSecurityNotificationsPreferenceControllerTest.java | 4 ---- 6 files changed, 15 deletions(-) diff --git a/src/com/android/settings/network/CellularSecurityPreferenceController.java b/src/com/android/settings/network/CellularSecurityPreferenceController.java index a184553c0f3..a1edd199249 100644 --- a/src/com/android/settings/network/CellularSecurityPreferenceController.java +++ b/src/com/android/settings/network/CellularSecurityPreferenceController.java @@ -72,7 +72,6 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY) || !Flags.enableIdentifierDisclosureTransparencyUnsolEvents() || !Flags.enableModemCipherTransparencyUnsolEvents() - || !Flags.enableIdentifierDisclosureTransparency() || !Flags.enableModemCipherTransparency()) { return UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java b/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java index 131882704f5..51d91a48a89 100644 --- a/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java +++ b/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerController.java @@ -62,7 +62,6 @@ public class CellularSecurityNotificationsDividerController extends public int getAvailabilityStatus() { if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents() || !Flags.enableModemCipherTransparencyUnsolEvents() - || !Flags.enableIdentifierDisclosureTransparency() || !Flags.enableModemCipherTransparency()) { return UNSUPPORTED_ON_DEVICE; } diff --git a/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java b/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java index 4e2d285b8d5..17aca091b73 100644 --- a/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java +++ b/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceController.java @@ -180,7 +180,6 @@ public class CellularSecurityNotificationsPreferenceController extends private boolean areFlagsEnabled() { if (!Flags.enableIdentifierDisclosureTransparencyUnsolEvents() || !Flags.enableModemCipherTransparencyUnsolEvents() - || !Flags.enableIdentifierDisclosureTransparency() || !Flags.enableModemCipherTransparency()) { return false; } diff --git a/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java index 7f05913cd82..8bc8c84de0f 100644 --- a/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java @@ -169,15 +169,11 @@ public final class CellularSecurityPreferenceControllerTest { mSetFlagsRule.enableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.enableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } else { mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.disableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } } } diff --git a/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerControllerTest.java index 4e2351f1c7d..998f82ef9eb 100644 --- a/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsDividerControllerTest.java @@ -129,15 +129,11 @@ public class CellularSecurityNotificationsDividerControllerTest { mSetFlagsRule.enableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.enableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } else { mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.disableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } } } diff --git a/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceControllerTest.java index 8a72bd5fae3..c520918c665 100644 --- a/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/telephony/CellularSecurityNotificationsPreferenceControllerTest.java @@ -233,15 +233,11 @@ public class CellularSecurityNotificationsPreferenceControllerTest { mSetFlagsRule.enableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.enableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } else { mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags( Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY_UNSOL_EVENTS); mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY); - mSetFlagsRule.disableFlags( - Flags.FLAG_ENABLE_IDENTIFIER_DISCLOSURE_TRANSPARENCY); } } } From d4dc1fed9e42a001fbf7d5ed2460a67c88aa5e71 Mon Sep 17 00:00:00 2001 From: yomna Date: Fri, 6 Dec 2024 04:44:36 +0000 Subject: [PATCH 4/5] Fix broken Safety Center redirect when SafetySourceData is null Bug: b/373942609 Test: m & atest CellularSecurityPreferenceControllerTest Flag: EXEMPT bugfix Change-Id: I2373ccb5cb51bca23815db9f7645efccc3e0cd88 --- AndroidManifest.xml | 1 + .../CellularSecurityPreferenceController.java | 23 +++++++++++++++++-- ...lularSecurityPreferenceControllerTest.java | 17 -------------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 2c62ebd684c..177e750c892 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -132,6 +132,7 @@ + diff --git a/src/com/android/settings/network/CellularSecurityPreferenceController.java b/src/com/android/settings/network/CellularSecurityPreferenceController.java index a184553c0f3..f02e82458db 100644 --- a/src/com/android/settings/network/CellularSecurityPreferenceController.java +++ b/src/com/android/settings/network/CellularSecurityPreferenceController.java @@ -23,6 +23,7 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.safetycenter.SafetyCenterManager; +import android.safetycenter.SafetySourceData; import android.telephony.SubscriptionInfo; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -48,6 +49,7 @@ import java.util.List; public class CellularSecurityPreferenceController extends BasePreferenceController { private static final String LOG_TAG = "CellularSecurityPreferenceController"; + private static final String SAFETY_SOURCE_ID = "AndroidCellularNetworkSecurity"; private @Nullable TelephonyManager mTelephonyManager; @@ -134,13 +136,30 @@ public class CellularSecurityPreferenceController extends BasePreferenceControll if (!TextUtils.equals(preference.getKey(), getPreferenceKey())) { return super.handlePreferenceTreeClick(preference); } - boolean isSafetyCenterSupported = isSafetyCenterSupported(); - if (isSafetyCenterSupported && areNotificationsEnabled()) { + if (!isSafetyCenterSupported()) { + // Realistically, it's unlikely to end up in handlePreferenceTreeClick with SafetyCenter + // being not supported on the device. + return false; + } + // Need to check that both Safety Center is available on device, and also that the HALs are + // enabled before showing the Safety Center UI. Otherwise, we need to take them to the page + // where the HALs can be enabled. + SafetyCenterManager safetyCenterManager = mContext.getSystemService( + SafetyCenterManager.class); + SafetySourceData data = null; + if (safetyCenterManager.isSafetyCenterEnabled()) { + data = safetyCenterManager.getSafetySourceData(SAFETY_SOURCE_ID); + } + // Can only redirect to SafetyCenter if it has received data via the SafetySource, as + // SafetyCenter doesn't support redirecting to a specific page associated with a source + // if it hasn't received data from that source. See b/373942609 for details. + if (data != null && areNotificationsEnabled()) { Intent safetyCenterIntent = new Intent(Intent.ACTION_SAFETY_CENTER); safetyCenterIntent.putExtra(SafetyCenterManager.EXTRA_SAFETY_SOURCES_GROUP_ID, "AndroidCellularNetworkSecuritySources"); mContext.startActivity(safetyCenterIntent); } else { + Log.v(LOG_TAG, "Hardware APIs not enabled, or data source is null."); final Bundle bundle = new Bundle(); bundle.putString(CellularSecuritySettingsFragment.KEY_CELLULAR_SECURITY_PREFERENCE, ""); diff --git a/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java index 7f05913cd82..359019db8e5 100644 --- a/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java +++ b/tests/unit/src/com/android/settings/network/CellularSecurityPreferenceControllerTest.java @@ -26,7 +26,6 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; @@ -50,7 +49,6 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; @@ -148,21 +146,6 @@ public final class CellularSecurityPreferenceControllerTest { assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); } - @Test - public void handlePreferenceTreeClick_safetyCenterSupported_shouldRedirectToSafetyCenter() { - final ArgumentCaptor intentCaptor = ArgumentCaptor.forClass(Intent.class); - - doReturn(true).when(mTelephonyManager).isNullCipherNotificationsEnabled(); - doReturn(true).when(mTelephonyManager) - .isCellularIdentifierDisclosureNotificationsEnabled(); - doReturn(true).when(mTelephonyManager).isNullCipherAndIntegrityPreferenceEnabled(); - boolean prefHandled = mController.handlePreferenceTreeClick(mPreference); - - assertThat(prefHandled).isTrue(); - verify(mContext).startActivity(intentCaptor.capture()); - assertThat(intentCaptor.getValue().getAction()).isEqualTo(Intent.ACTION_SAFETY_CENTER); - } - private void enableFlags(boolean enabled) { if (enabled) { mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_MODEM_CIPHER_TRANSPARENCY_UNSOL_EVENTS); From 0a49a0121006515a5310c9330d7238f70943a341 Mon Sep 17 00:00:00 2001 From: Pierre Barbier de Reuille Date: Fri, 24 Jan 2025 13:05:37 +0000 Subject: [PATCH 5/5] Update when Desktop Mode Dev Option is enabled by default. The new condition requires accessing the context. Bug: 382238347 Flag: EXEMPT Bug fix Test: atest DesktopModePreferenceControllerTest Test: Build and test on devices with only the dev option enabled. Change-Id: If9cacea948ccee2bc5a5b4fae07f3ad69efb0af2 --- .../settings/development/DesktopModePreferenceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/settings/development/DesktopModePreferenceController.java b/src/com/android/settings/development/DesktopModePreferenceController.java index 8012d31b9f6..4c6da1ee1cd 100644 --- a/src/com/android/settings/development/DesktopModePreferenceController.java +++ b/src/com/android/settings/development/DesktopModePreferenceController.java @@ -89,7 +89,7 @@ public class DesktopModePreferenceController extends DeveloperOptionsPreferenceC final boolean shouldDevOptionBeEnabled = switch (toggleOverride) { case OVERRIDE_OFF -> false; case OVERRIDE_ON -> true; - case OVERRIDE_UNSET -> DesktopModeStatus.shouldDevOptionBeEnabledByDefault(); + case OVERRIDE_UNSET -> DesktopModeStatus.shouldDevOptionBeEnabledByDefault(mContext); }; ((TwoStatePreference) mPreference).setChecked(shouldDevOptionBeEnabled); }