Respect DISALLOW_CONFIG_LOCALE flag
Hide language settings when user has DISALLOW_CONFIG_LOCALE flag
Bug: 281849782
Test: atest com.android.car.settings.language.LanguageSettingsEntryPreferenceControllerTest
Change-Id: I52243ef90895b77b03a25bdd832f0399102752ba
diff --git a/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceController.java b/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceController.java
index 0aa0a8e..8d77c42 100644
--- a/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceController.java
+++ b/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceController.java
@@ -16,11 +16,16 @@
package com.android.car.settings.language;
+import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
+
+import static com.android.car.settings.enterprise.EnterpriseUtils.hasUserRestrictionByUm;
+
import android.app.ActivityManager;
import android.car.drivingstate.CarUxRestrictions;
import android.content.Context;
import android.os.RemoteException;
+import androidx.annotation.VisibleForTesting;
import androidx.preference.Preference;
import com.android.car.settings.common.FragmentController;
@@ -49,11 +54,21 @@
return Preference.class;
}
+ @Override
+ public int getDefaultAvailabilityStatus() {
+ if (hasUserRestrictionByUm(getContext(), DISALLOW_CONFIG_LOCALE)) {
+ return DISABLED_FOR_PROFILE;
+ }
+
+ return AVAILABLE;
+ }
+
/**
* Returns the locale from current system configuration, or the default locale if no system
* locale is available.
*/
- private static Locale getConfiguredLocale() {
+ @VisibleForTesting
+ Locale getConfiguredLocale() {
try {
Locale configLocale =
ActivityManager.getService().getConfiguration().getLocales().get(0);
diff --git a/tests/unit/src/com/android/car/settings/common/PreferenceControllerTestUtil.java b/tests/unit/src/com/android/car/settings/common/PreferenceControllerTestUtil.java
index 5cbce81..aac4a1d 100644
--- a/tests/unit/src/com/android/car/settings/common/PreferenceControllerTestUtil.java
+++ b/tests/unit/src/com/android/car/settings/common/PreferenceControllerTestUtil.java
@@ -21,6 +21,7 @@
import androidx.preference.Preference;
public class PreferenceControllerTestUtil {
+
/**
* Associates a PreferenceController with its Preference.
*/
@@ -28,6 +29,12 @@
controller.setPreference(preference);
}
+ /**
+ * Asserts that the test availability status matches the expected result
+ *
+ * @param actualValue availability returned by the test
+ * @param expectedValue expected availability
+ */
public static void assertAvailability(int actualValue, int expectedValue) {
assertWithMessage("controller availability (%s=%s, %s=%s)",
actualValue, availabilityToString(actualValue),
diff --git a/tests/unit/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceControllerTest.java b/tests/unit/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceControllerTest.java
new file mode 100644
index 0000000..9ef41cd
--- /dev/null
+++ b/tests/unit/src/com/android/car/settings/language/LanguageSettingsEntryPreferenceControllerTest.java
@@ -0,0 +1,171 @@
+/*
+ * 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.car.settings.language;
+
+import static android.os.UserManager.DISALLOW_CONFIG_LOCALE;
+
+import static com.android.car.settings.common.PreferenceController.AVAILABLE;
+import static com.android.car.settings.common.PreferenceController.AVAILABLE_FOR_VIEWING;
+import static com.android.car.settings.common.PreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.android.car.settings.common.PreferenceController.DISABLED_FOR_PROFILE;
+import static com.android.car.settings.common.PreferenceXmlParser.PREF_AVAILABILITY_STATUS_HIDDEN;
+import static com.android.car.settings.common.PreferenceXmlParser.PREF_AVAILABILITY_STATUS_READ;
+import static com.android.car.settings.common.PreferenceXmlParser.PREF_AVAILABILITY_STATUS_WRITE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.car.drivingstate.CarUxRestrictions;
+import android.content.Context;
+import android.os.UserManager;
+
+import androidx.lifecycle.LifecycleOwner;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.car.settings.common.FragmentController;
+import com.android.car.settings.common.PreferenceControllerTestUtil;
+import com.android.car.settings.testutils.EnterpriseTestUtils;
+import com.android.car.settings.testutils.TestLifecycleOwner;
+import com.android.car.ui.preference.CarUiPreference;
+import com.android.internal.app.LocaleHelper;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Locale;
+
+@RunWith(AndroidJUnit4.class)
+public class LanguageSettingsEntryPreferenceControllerTest {
+
+ private Context mContext = spy(ApplicationProvider.getApplicationContext());
+ private LifecycleOwner mLifecycleOwner;
+ private CarUiPreference mPreference;
+ private CarUxRestrictions mCarUxRestrictions;
+ private LanguageSettingsEntryPreferenceController mController;
+
+ @Mock
+ private FragmentController mFragmentController;
+ @Mock
+ private UserManager mMockUserManager;
+
+ @Rule
+ public final MockitoRule rule = MockitoJUnit.rule();
+
+ @Before
+ public void setUp() {
+ mLifecycleOwner = new TestLifecycleOwner();
+
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mMockUserManager);
+ mCarUxRestrictions = new CarUxRestrictions.Builder(/* reqOpt= */ true,
+ CarUxRestrictions.UX_RESTRICTIONS_BASELINE, /* timestamp= */ 0).build();
+
+ mPreference = new CarUiPreference(mContext);
+ mController = new LanguageSettingsEntryPreferenceController(mContext,
+ /* preferenceKey= */ "key", mFragmentController, mCarUxRestrictions);
+ PreferenceControllerTestUtil.assignPreference(mController, mPreference);
+ }
+
+ @Test
+ public void onCreate_setsSummary() {
+ mController.onCreate(mLifecycleOwner);
+
+ Locale locale = mController.getConfiguredLocale();
+ String summary = LocaleHelper.getDisplayName(locale, locale, /* sentenceCase= */ true);
+ assertThat(mPreference.getSummary()).isEqualTo(summary);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noRestriction_zoneWrite_available() {
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, false);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_WRITE);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getAvailabilityStatus(),
+ AVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasRestriction_zoneWrite_disabledForProfile() {
+ when(mContext.getSystemService(UserManager.class)).thenReturn(mMockUserManager);
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, true);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_WRITE);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getDefaultAvailabilityStatus(),
+ DISABLED_FOR_PROFILE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noRestriction_zoneRead_availableForViewing() {
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, false);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_READ);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getAvailabilityStatus(),
+ AVAILABLE_FOR_VIEWING);
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasRestriction_zoneRead_disabledForProfile() {
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, true);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_READ);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getAvailabilityStatus(),
+ DISABLED_FOR_PROFILE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_noRestriction_zoneHidden_conditionallyUnavailable() {
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, false);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_HIDDEN);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getAvailabilityStatus(),
+ CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Test
+ public void getAvailabilityStatus_hasRestriction_zoneHidden_disabledForProfile() {
+ EnterpriseTestUtils
+ .mockUserRestrictionSetByUm(mMockUserManager, DISALLOW_CONFIG_LOCALE, true);
+ mController.setAvailabilityStatusForZone(PREF_AVAILABILITY_STATUS_HIDDEN);
+
+ mController.onCreate(mLifecycleOwner);
+
+ PreferenceControllerTestUtil.assertAvailability(mController.getAvailabilityStatus(),
+ DISABLED_FOR_PROFILE);
+ }
+}