Merge "Add loading screen for Device details fragment to avoid ANR" into main
diff --git a/res/layout/preference_battery_header_text.xml b/res/layout/preference_battery_header_text.xml
index 72bdbf6..616984e 100644
--- a/res/layout/preference_battery_header_text.xml
+++ b/res/layout/preference_battery_header_text.xml
@@ -18,8 +18,9 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:layout_marginStart="?android:attr/listPreferredItemPaddingStart"
- android:layout_marginEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:layout_marginTop="-6dp"
android:paddingBottom="16dp">
<TextView
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 05b3b3f..ea505da 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -12287,7 +12287,7 @@
<!-- Summary for _satellite_setting_preference_layout. [CHAR LIMIT=NONE]-->
<string name="satellite_setting_disabled_summary">Send and receive text messages by satellite. Not included with your account.</string>
<!-- Search keywords for "_satellite_setting_preference_layout" [CHAR_LIMIT=NONE] -->
- <string name="keywords_satellite_setting">Satellite messaging</string>
+ <string name="keywords_satellite_setting">Satellite messaging, satellite connectivity</string>
<!-- Category name "About satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="category_name_about_satellite_messaging">About <xliff:g id="subject" example="satellite messaging">%1$s</xliff:g></string>
<!-- Summary for category "About satellite messaging" [CHAR_LIMIT=NONE] -->
@@ -12328,6 +12328,12 @@
<string name="description_satellite_setting_messaging">satellite messaging</string>
<!-- Title for notifying user's account be able to use data transmission of Satellite" [CHAR_LIMIT=NONE] -->
<string name="title_have_satellite_data_plan">Use of data is included with your account</string>
+ <!-- Title for the entry of Satellite SOS [CHAR_LIMIT=NONE] -->
+ <string name="title_for_satellite_sos_entry">Satellite SOS</string>
+ <!-- Summary for the entry of Satellite SOS [CHAR_LIMIT=NONE] -->
+ <string name="summary_for_satellite_sos_entry">Message with emergency services when you can\u2019t connect to a mobile or Wi\u2011Fi network</string>
+ <!-- Keywords for the entry of Satellite SOS [CHAR_LIMIT=NONE] -->
+ <string name="keywords_satellite_sos">satellite sos, sos</string>
diff --git a/res/xml/accessibility_vibration_intensity_settings.xml b/res/xml/accessibility_vibration_intensity_settings.xml
index f9a5578..ba1bd83 100644
--- a/res/xml/accessibility_vibration_intensity_settings.xml
+++ b/res/xml/accessibility_vibration_intensity_settings.xml
@@ -20,7 +20,7 @@
android:title="@string/accessibility_vibration_settings_title">
<com.android.settingslib.widget.MainSwitchPreference
- android:key="vibration_intensity_switch_main"
+ android:key="vibrate_on"
android:title="@string/accessibility_vibration_primary_switch_title"
app:keywords="@string/keywords_accessibility_vibration_primary_switch"
app:controller="com.android.settings.accessibility.VibrationMainSwitchPreferenceController"/>
diff --git a/res/xml/accessibility_vibration_settings.xml b/res/xml/accessibility_vibration_settings.xml
index 3ce92a6..be45659 100644
--- a/res/xml/accessibility_vibration_settings.xml
+++ b/res/xml/accessibility_vibration_settings.xml
@@ -20,7 +20,7 @@
android:title="@string/accessibility_vibration_settings_title">
<com.android.settingslib.widget.MainSwitchPreference
- android:key="vibration_switch_main"
+ android:key="vibrate_on"
android:title="@string/accessibility_vibration_primary_switch_title"
app:keywords="@string/keywords_accessibility_vibration_primary_switch"
app:controller="com.android.settings.accessibility.VibrationMainSwitchPreferenceController"/>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index 3c1317d..72acbe0 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -217,6 +217,16 @@
settings:controller=
"com.android.settings.network.telephony.SatelliteSettingPreferenceController"/>
+ <com.android.settingslib.RestrictedPreference
+ android:key="telephony_satellite_setting_sos_key"
+ android:persistent="false"
+ android:title="@string/title_for_satellite_sos_entry"
+ android:summary="@string/summary_for_satellite_sos_entry"
+ settings:keywords="@string/keywords_satellite_setting"
+ settings:fragment="com.android.settings.network.telephony.SatelliteSettingsSosFragment"
+ settings:controller=
+ "com.android.settings.network.telephony.SatelliteSettingSosPreferenceController"/>
+
</PreferenceCategory>
<PreferenceCategory
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index c7cf873..21a836d 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -26,7 +26,6 @@
android:title="@string/summary_placeholder"
android:selectable="false"
android:paddingBottom="0px"
- android:persistent="false"
settings:controller="com.android.settings.fuelgauge.BatteryHeaderPreferenceController" />
<com.android.settings.fuelgauge.BatteryHeaderTextPreference
diff --git a/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt b/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt
index 5b732bc..65519e9 100644
--- a/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt
+++ b/src/com/android/settings/accessibility/RemoveAnimationsPreference.kt
@@ -28,6 +28,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.SwitchPreference
class RemoveAnimationsPreference :
@@ -70,6 +71,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
@Suppress("UNCHECKED_CAST")
private class RemoveAnimationsStorage(private val context: Context) :
NoOpKeyedObservable<String>(), KeyValueStore {
diff --git a/src/com/android/settings/accessibility/VibrationIntensityScreen.kt b/src/com/android/settings/accessibility/VibrationIntensityScreen.kt
index 5d7d4fb..0a37230 100644
--- a/src/com/android/settings/accessibility/VibrationIntensityScreen.kt
+++ b/src/com/android/settings/accessibility/VibrationIntensityScreen.kt
@@ -19,18 +19,32 @@
import androidx.fragment.app.Fragment
import com.android.settings.R
import com.android.settings.flags.Flags
+import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenCreator
+/**
+ * Accessibility settings for vibration intensities.
+ */
+// TODO(b/368360218): investigate if we still need this screen once we finish the migration.
+// We might be able to consolidate this into VibrationScreen with PreferenceHierarchy choosing
+// between toggle or slider preferences based on device config, depending on how overlays are done.
+// LINT.IfChange
@ProvidePreferenceScreen
-class VibrationIntensityScreen : PreferenceScreenCreator {
+class VibrationIntensityScreen : PreferenceScreenCreator, PreferenceAvailabilityProvider {
override val key: String
get() = KEY
override val title: Int
get() = R.string.accessibility_vibration_settings_title
+ override val keywords: Int
+ get() = R.string.keywords_vibration
+
+ override fun isAvailable(context: Context) =
+ context.isVibratorAvailable() && context.getSupportedVibrationIntensityLevels() > 1
+
override fun isFlagEnabled(context: Context): Boolean = Flags.catalystVibrationIntensityScreen()
override fun hasCompleteHierarchy() = false
@@ -38,9 +52,12 @@
override fun fragmentClass(): Class<out Fragment>? =
VibrationIntensitySettingsFragment::class.java
- override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {}
+ override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
+ +VibrationMainSwitchPreference()
+ }
companion object {
const val KEY = "vibration_intensity_screen"
}
}
+// LINT.ThenChange(VibrationPreferenceController.java)
diff --git a/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt b/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt
new file mode 100644
index 0000000..70a0033
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationMainSwitchPreference.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.accessibility
+
+import android.content.Context
+import android.os.VibrationAttributes
+import android.os.Vibrator
+import android.provider.Settings
+import android.widget.CompoundButton
+import android.widget.CompoundButton.OnCheckedChangeListener
+import com.android.settings.R
+import com.android.settingslib.datastore.KeyValueStore
+import com.android.settingslib.datastore.KeyedObservableDelegate
+import com.android.settingslib.datastore.SettingsStore
+import com.android.settingslib.datastore.SettingsSystemStore
+import com.android.settingslib.metadata.MainSwitchPreference
+import com.android.settingslib.metadata.PreferenceLifecycleContext
+import com.android.settingslib.metadata.PreferenceLifecycleProvider
+import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.preference.MainSwitchPreferenceBinding
+
+/**
+ * Accessibility settings for vibration.
+ */
+// LINT.IfChange
+class VibrationMainSwitchPreference : MainSwitchPreference(
+ key = Settings.System.VIBRATE_ON,
+ title = R.string.accessibility_vibration_primary_switch_title,
+), PreferenceLifecycleProvider, OnCheckedChangeListener {
+ override val keywords: Int
+ get() = R.string.keywords_accessibility_vibration_primary_switch
+
+ lateinit var vibrator: Vibrator
+
+ override fun storage(context: Context): KeyValueStore =
+ VibrationMainSwitchToggleStorage(SettingsSystemStore.get(context))
+
+ override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
+ ReadWritePermit.ALLOW
+
+ override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
+ ReadWritePermit.ALLOW
+
+ override fun onResume(context: PreferenceLifecycleContext) {
+ vibrator = context.getSystemService(Vibrator::class.java)
+ context.findPreference<com.android.settingslib.widget.MainSwitchPreference>(key)
+ ?.addOnSwitchChangeListener(this)
+ }
+
+ override fun onPause(context: PreferenceLifecycleContext) {
+ context.findPreference<com.android.settingslib.widget.MainSwitchPreference>(key)
+ ?.removeOnSwitchChangeListener(this)
+ }
+
+ override fun onCheckedChanged(button: CompoundButton, isChecked: Boolean) {
+ if (isChecked) {
+ // Play a haptic as preview for the main toggle only when touch feedback is enabled.
+ VibrationPreferenceConfig.playVibrationPreview(
+ vibrator, VibrationAttributes.USAGE_TOUCH
+ )
+ }
+ }
+
+ /** Provides SettingsStore for vibration main switch with custom default value. */
+ @Suppress("UNCHECKED_CAST")
+ private class VibrationMainSwitchToggleStorage(
+ private val settingsStore: SettingsStore,
+ ) : KeyedObservableDelegate<String>(settingsStore), KeyValueStore {
+
+ override fun contains(key: String) = settingsStore.contains(key)
+
+ override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
+ DEFAULT_VALUE as T
+
+ override fun <T : Any> getValue(key: String, valueType: Class<T>) =
+ (settingsStore.getBoolean(key) ?: DEFAULT_VALUE) as T
+
+ override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
+ settingsStore.setBoolean(key, value as Boolean?)
+ }
+ }
+
+ companion object {
+ const val DEFAULT_VALUE = true
+ }
+}
+// LINT.ThenChange(VibrationMainSwitchPreferenceController.java)
diff --git a/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java b/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
index 5b553e3..0f2fb77 100644
--- a/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceController.java
@@ -41,6 +41,7 @@
* will disable the entire settings screen once the settings is turned OFF. All device haptics will
* be disabled by this setting, except the flagged alerts and accessibility touch feedback.
*/
+// LINT.IfChange
public class VibrationMainSwitchPreferenceController extends SettingsMainSwitchPreferenceController
implements LifecycleObserver, OnStart, OnStop {
@@ -106,3 +107,4 @@
return R.string.menu_key_accessibility;
}
}
+// LINT.ThenChange(VibrationMainSwitchPreference.kt)
diff --git a/src/com/android/settings/accessibility/VibrationPreferenceController.java b/src/com/android/settings/accessibility/VibrationPreferenceController.java
index 092ff69..e84543d 100644
--- a/src/com/android/settings/accessibility/VibrationPreferenceController.java
+++ b/src/com/android/settings/accessibility/VibrationPreferenceController.java
@@ -31,6 +31,7 @@
import com.android.settings.core.SubSettingLauncher;
/** Controller for "Vibration & haptics" settings page. */
+// LINT.IfChange
public class VibrationPreferenceController extends BasePreferenceController {
private final boolean mHasVibrator;
@@ -79,3 +80,7 @@
}
+// LINT.ThenChange(
+// VibrationIntensityScreenTest.kt,
+// VibrationScreenTest.kt,
+// )
diff --git a/src/com/android/settings/accessibility/VibrationScreen.kt b/src/com/android/settings/accessibility/VibrationScreen.kt
new file mode 100644
index 0000000..63a7c44
--- /dev/null
+++ b/src/com/android/settings/accessibility/VibrationScreen.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.accessibility
+
+import android.content.Context
+import android.os.Vibrator
+import androidx.fragment.app.Fragment
+import com.android.settings.R
+import com.android.settings.flags.Flags
+import com.android.settingslib.metadata.PreferenceAvailabilityProvider
+import com.android.settingslib.metadata.ProvidePreferenceScreen
+import com.android.settingslib.metadata.preferenceHierarchy
+import com.android.settingslib.preference.PreferenceScreenCreator
+
+/**
+ * Accessibility settings for vibration.
+ */
+// LINT.IfChange
+@ProvidePreferenceScreen
+class VibrationScreen : PreferenceScreenCreator, PreferenceAvailabilityProvider {
+ override val key: String
+ get() = KEY
+
+ override val title: Int
+ get() = R.string.accessibility_vibration_settings_title
+
+ override val keywords: Int
+ get() = R.string.keywords_vibration
+
+ override fun isAvailable(context: Context) =
+ context.isVibratorAvailable() && context.getSupportedVibrationIntensityLevels() == 1
+
+ override fun isFlagEnabled(context: Context): Boolean = Flags.catalystVibrationIntensityScreen()
+
+ override fun hasCompleteHierarchy() = false
+
+ override fun fragmentClass(): Class<out Fragment>? = VibrationSettings::class.java
+
+ override fun getPreferenceHierarchy(context: Context) = preferenceHierarchy(this) {
+ +VibrationMainSwitchPreference()
+ }
+
+ companion object {
+ const val KEY = "vibration_screen"
+ }
+}
+
+/** Returns true if the device has a system vibrator, false otherwise. */
+fun Context.isVibratorAvailable(): Boolean =
+ getSystemService(Vibrator::class.java).hasVibrator()
+
+/** Returns the number of vibration intensity levels supported by this device. */
+fun Context.getSupportedVibrationIntensityLevels(): Int =
+ resources.getInteger(R.integer.config_vibration_supported_intensity_levels)
+
+// LINT.ThenChange(VibrationPreferenceController.java)
diff --git a/src/com/android/settings/accessibility/VibrationSettings.java b/src/com/android/settings/accessibility/VibrationSettings.java
index 48393d9..11e1ddd 100644
--- a/src/com/android/settings/accessibility/VibrationSettings.java
+++ b/src/com/android/settings/accessibility/VibrationSettings.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.os.Vibrator;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
@@ -36,6 +38,11 @@
private static final String TAG = "VibrationSettings";
@Override
+ public @Nullable String getPreferenceScreenBindingKey(@NonNull Context context) {
+ return VibrationScreen.KEY;
+ }
+
+ @Override
public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_VIBRATION;
}
diff --git a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt
index de128e6..e4e38d4 100644
--- a/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt
+++ b/src/com/android/settings/datausage/DataSaverMainSwitchPreference.kt
@@ -24,6 +24,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
class DataSaverMainSwitchPreference(context: Context) :
MainSwitchBarMetadata, PreferenceLifecycleProvider {
@@ -45,6 +46,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun onStart(context: PreferenceLifecycleContext) {
val listener = DataSaverBackend.Listener { context.notifyPreferenceChange(KEY) }
dataSaverBackendListener = listener
diff --git a/src/com/android/settings/display/AdaptiveSleepPreference.kt b/src/com/android/settings/display/AdaptiveSleepPreference.kt
index 71d7749..a160001 100644
--- a/src/com/android/settings/display/AdaptiveSleepPreference.kt
+++ b/src/com/android/settings/display/AdaptiveSleepPreference.kt
@@ -37,6 +37,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.TwoStatePreference
import com.android.settingslib.preference.PreferenceBindingPlaceholder
import com.android.settingslib.preference.SwitchPreferenceBinding
@@ -82,6 +83,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
@Suppress("UNCHECKED_CAST")
private class Storage(
private val context: Context,
diff --git a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt
index 0537e62..e50b00b 100644
--- a/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt
+++ b/src/com/android/settings/display/AmbientDisplayAlwaysOnPreference.kt
@@ -36,6 +36,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.SwitchPreference
// LINT.IfChange
@@ -76,6 +77,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun onCreate(context: PreferenceLifecycleContext) {
val storage = SettingsSecureStore.get(context)
keyMappingObserver =
diff --git a/src/com/android/settings/display/AutoBrightnessScreen.kt b/src/com/android/settings/display/AutoBrightnessScreen.kt
index 385fe20..32d70ad 100644
--- a/src/com/android/settings/display/AutoBrightnessScreen.kt
+++ b/src/com/android/settings/display/AutoBrightnessScreen.kt
@@ -35,6 +35,7 @@
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenBinding
import com.android.settingslib.preference.PreferenceScreenCreator
@@ -70,6 +71,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun isAvailable(context: Context) =
context.resources.getBoolean(
com.android.internal.R.bool.config_automatic_brightness_available
diff --git a/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt
index fd7b037..25623b3 100644
--- a/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt
+++ b/src/com/android/settings/display/BatteryPercentageSwitchPreference.kt
@@ -29,6 +29,7 @@
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.SwitchPreference
import com.android.settingslib.preference.SwitchPreferenceBinding
@@ -54,6 +55,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun bind(preference: Preference, metadata: PreferenceMetadata) {
super.bind(preference, metadata)
preference.onPreferenceChangeListener = this
diff --git a/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt b/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt
index 6dc09f6..3240616 100644
--- a/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt
+++ b/src/com/android/settings/display/PeakRefreshRateSwitchPreference.kt
@@ -34,6 +34,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.SwitchPreference
import kotlin.math.roundToInt
@@ -55,6 +56,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun isAvailable(context: Context) =
context.resources.getBoolean(R.bool.config_show_smooth_display) &&
context.peakRefreshRate > DEFAULT_REFRESH_RATE
diff --git a/src/com/android/settings/display/darkmode/DarkModeScreen.kt b/src/com/android/settings/display/darkmode/DarkModeScreen.kt
index 9166705..7f8087a 100644
--- a/src/com/android/settings/display/darkmode/DarkModeScreen.kt
+++ b/src/com/android/settings/display/darkmode/DarkModeScreen.kt
@@ -37,6 +37,7 @@
import com.android.settingslib.metadata.PreferenceSummaryProvider
import com.android.settingslib.metadata.ProvidePreferenceScreen
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.preferenceHierarchy
import com.android.settingslib.preference.PreferenceScreenBinding
import com.android.settingslib.preference.PreferenceScreenCreator
@@ -76,6 +77,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun isFlagEnabled(context: Context) = Flags.catalystDarkUiMode()
override fun fragmentClass() = DarkModeSettingsFragment::class.java
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt b/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt
index 2a9b0e8..95d73dd 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderPreference.kt
@@ -22,21 +22,27 @@
import com.android.settings.R
import com.android.settings.fuelgauge.BatteryBroadcastReceiver.BatteryUpdateType.BATTERY_NOT_PRESENT
import com.android.settingslib.Utils
+import com.android.settingslib.datastore.KeyValueStore
+import com.android.settingslib.datastore.NoOpKeyedObservable
import com.android.settingslib.fuelgauge.BatteryUtils
+import com.android.settingslib.metadata.PersistentPreference
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.RangeValue
+import com.android.settingslib.metadata.ReadWritePermit
import com.android.settingslib.preference.PreferenceBinding
import com.android.settingslib.widget.UsageProgressBarPreference
// LINT.IfChange
class BatteryHeaderPreference :
+ PersistentPreference<Int>,
PreferenceMetadata,
PreferenceBinding,
- PreferenceLifecycleProvider {
+ PreferenceLifecycleProvider,
+ RangeValue {
- @VisibleForTesting
- var batteryBroadcastReceiver: BatteryBroadcastReceiver? = null
+ @VisibleForTesting var batteryBroadcastReceiver: BatteryBroadcastReceiver? = null
override val key: String
get() = KEY
@@ -58,25 +64,50 @@
override fun onCreate(context: PreferenceLifecycleContext) {
super.onCreate(context)
- batteryBroadcastReceiver = BatteryBroadcastReceiver(context).apply {
- setBatteryChangedListener {
- if (it != BATTERY_NOT_PRESENT) {
- context.notifyPreferenceChange(KEY)
+ batteryBroadcastReceiver =
+ BatteryBroadcastReceiver(context).apply {
+ setBatteryChangedListener {
+ if (it != BATTERY_NOT_PRESENT) {
+ context.notifyPreferenceChange(KEY)
+ }
}
}
- }
}
override fun onStart(context: PreferenceLifecycleContext) {
super.onStart(context)
- batteryBroadcastReceiver?.register();
+ batteryBroadcastReceiver?.register()
}
override fun onStop(context: PreferenceLifecycleContext) {
super.onStop(context)
- batteryBroadcastReceiver?.unRegister();
+ batteryBroadcastReceiver?.unRegister()
}
+ override fun storage(context: Context): KeyValueStore =
+ object : NoOpKeyedObservable<String>(), KeyValueStore {
+ override fun contains(key: String) = BatteryUtils.getBatteryIntent(context) != null
+
+ @Suppress("UNCHECKED_CAST")
+ override fun <T : Any> getValue(key: String, valueType: Class<T>): T? {
+ val batteryIntent = BatteryUtils.getBatteryIntent(context) ?: return null
+ return Utils.getBatteryLevel(batteryIntent) as T
+ }
+
+ override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) =
+ throw UnsupportedOperationException()
+ }
+
+ override fun getMinValue(context: Context): Int = 0
+
+ override fun getMaxValue(context: Context): Int = 100
+
+ override fun getReadPermit(context: Context, myUid: Int, callingUid: Int) =
+ ReadWritePermit.ALLOW
+
+ override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) =
+ ReadWritePermit.DISALLOW
+
companion object {
private const val KEY = "battery_header"
private const val BATTERY_MAX_LEVEL: Long = 100L
diff --git a/src/com/android/settings/fuelgauge/BatteryHeaderTextPreference.java b/src/com/android/settings/fuelgauge/BatteryHeaderTextPreference.java
index 5c81277..516cc71 100644
--- a/src/com/android/settings/fuelgauge/BatteryHeaderTextPreference.java
+++ b/src/com/android/settings/fuelgauge/BatteryHeaderTextPreference.java
@@ -26,9 +26,10 @@
import androidx.preference.PreferenceViewHolder;
import com.android.settings.R;
+import com.android.settingslib.widget.GroupSectionDividerMixin;
/** A preference for battery header text. */
-public class BatteryHeaderTextPreference extends Preference {
+public class BatteryHeaderTextPreference extends Preference implements GroupSectionDividerMixin {
private static final String TAG = "BatteryHeaderTextPreference";
@Nullable private CharSequence mText;
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt
index da401c5..84bba00 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverPreference.kt
@@ -32,6 +32,7 @@
import com.android.settingslib.metadata.PreferenceLifecycleContext
import com.android.settingslib.metadata.PreferenceLifecycleProvider
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
// LINT.IfChange
class BatterySaverPreference :
@@ -49,6 +50,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun isEnabled(context: Context) =
!BatteryStatus(BatteryUtils.getBatteryIntent(context)).isPluggedIn
diff --git a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt
index 159ec0f..c29ec6e 100644
--- a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt
+++ b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt
@@ -26,6 +26,7 @@
import com.android.settingslib.datastore.SettingsStore
import com.android.settingslib.metadata.MainSwitchPreference
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
// LINT.IfChange
class AdaptiveConnectivityTogglePreference :
@@ -40,6 +41,9 @@
override fun getWritePermit(context: Context, value: Boolean?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
@Suppress("UNCHECKED_CAST")
private class AdaptiveConnectivityToggleStorage(
private val context: Context,
diff --git a/src/com/android/settings/network/AirplaneModePreference.kt b/src/com/android/settings/network/AirplaneModePreference.kt
index 2d9fbe9..d9d1bd8 100644
--- a/src/com/android/settings/network/AirplaneModePreference.kt
+++ b/src/com/android/settings/network/AirplaneModePreference.kt
@@ -23,6 +23,7 @@
import com.android.settings.R
import com.android.settingslib.datastore.SettingsGlobalStore
import com.android.settingslib.metadata.PreferenceAvailabilityProvider
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.metadata.SwitchPreference
// LINT.IfChange
@@ -35,6 +36,9 @@
override fun storage(context: Context) = SettingsGlobalStore.get(context)
+ override val sensitivityLevel
+ get() = SensitivityLevel.HIGH_SENSITIVITY
+
override fun isAvailable(context: Context) =
(context.resources.getBoolean(R.bool.config_show_toggle_airplane)
&& !context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK))
diff --git a/src/com/android/settings/network/telephony/MobileNetworkSettings.java b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
index baf16c7..1c4b262 100644
--- a/src/com/android/settings/network/telephony/MobileNetworkSettings.java
+++ b/src/com/android/settings/network/telephony/MobileNetworkSettings.java
@@ -288,6 +288,11 @@
if (satelliteSettingPreferenceController != null) {
satelliteSettingPreferenceController.init(mSubId);
}
+ final SatelliteSettingSosPreferenceController satelliteSettingSosPreferenceController = use(
+ SatelliteSettingSosPreferenceController.class);
+ if (satelliteSettingSosPreferenceController != null) {
+ satelliteSettingSosPreferenceController.init(mSubId);
+ }
use(ApnPreferenceController.class).init(mSubId);
use(CarrierPreferenceController.class).init(mSubId);
use(DataUsagePreferenceController.class).init(mSubId);
diff --git a/src/com/android/settings/network/telephony/SatelliteSettingSosPreferenceController.java b/src/com/android/settings/network/telephony/SatelliteSettingSosPreferenceController.java
new file mode 100644
index 0000000..b9e04d8
--- /dev/null
+++ b/src/com/android/settings/network/telephony/SatelliteSettingSosPreferenceController.java
@@ -0,0 +1,54 @@
+/*
+ * 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.network.telephony;
+
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL;
+
+import android.content.Context;
+import android.os.PersistableBundle;
+
+import com.android.settings.flags.Flags;
+import com.android.settings.network.CarrierConfigCache;
+
+/** A controller for Satellite SOS entry preference. */
+public class SatelliteSettingSosPreferenceController extends TelephonyBasePreferenceController {
+ private static final String TAG = "SatelliteSettingSosPrefController";
+
+ public SatelliteSettingSosPreferenceController(Context context,
+ String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ /** Setup the subscription Id for the UI with specific UI group. */
+ public void init(int subId) {
+ mSubId = subId;
+ }
+
+ @Override
+ public int getAvailabilityStatus(int subId) {
+ if (Flags.satelliteOemSettingsUxMigration()) {
+ CarrierConfigCache carrierConfigCache = CarrierConfigCache.getInstance(mContext);
+ PersistableBundle bundle = carrierConfigCache.getConfigForSubId(subId);
+ if (bundle == null) {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+ boolean isCarrierSupport = bundle.getBoolean(KEY_SATELLITE_ESOS_SUPPORTED_BOOL);
+ return isCarrierSupport ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
+ }
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+}
diff --git a/src/com/android/settings/network/telephony/SatelliteSettingsSosFragment.java b/src/com/android/settings/network/telephony/SatelliteSettingsSosFragment.java
new file mode 100644
index 0000000..911939a
--- /dev/null
+++ b/src/com/android/settings/network/telephony/SatelliteSettingsSosFragment.java
@@ -0,0 +1,26 @@
+/*
+ * 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.network.telephony;
+
+import com.android.settings.SettingsPreferenceFragment;
+
+public class SatelliteSettingsSosFragment extends SettingsPreferenceFragment {
+ @Override
+ public int getMetricsCategory() {
+ return 0;
+ }
+}
diff --git a/src/com/android/settings/notification/CallVolumePreference.kt b/src/com/android/settings/notification/CallVolumePreference.kt
index e09dc9b..031687f 100644
--- a/src/com/android/settings/notification/CallVolumePreference.kt
+++ b/src/com/android/settings/notification/CallVolumePreference.kt
@@ -32,6 +32,7 @@
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.preference.PreferenceBinding
// LINT.IfChange
@@ -81,6 +82,9 @@
override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun getMinValue(context: Context) =
createAudioHelper(context).getMinVolume(getAudioStream(context))
diff --git a/src/com/android/settings/notification/MediaVolumePreference.kt b/src/com/android/settings/notification/MediaVolumePreference.kt
index 2533f0a..a6d9c41 100644
--- a/src/com/android/settings/notification/MediaVolumePreference.kt
+++ b/src/com/android/settings/notification/MediaVolumePreference.kt
@@ -30,6 +30,7 @@
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.preference.PreferenceBinding
// LINT.IfChange
@@ -82,6 +83,9 @@
override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun getMinValue(context: Context) =
createAudioHelper(context).getMinVolume(STREAM_MUSIC)
diff --git a/src/com/android/settings/notification/PhoneRingtonePreferenceController.java b/src/com/android/settings/notification/PhoneRingtonePreferenceController.java
index 7bd78fe..2944b7d 100644
--- a/src/com/android/settings/notification/PhoneRingtonePreferenceController.java
+++ b/src/com/android/settings/notification/PhoneRingtonePreferenceController.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.media.RingtoneManager;
+import android.media.audio.Flags;
import com.android.settings.Utils;
@@ -36,6 +37,9 @@
@Override
public boolean isAvailable() {
+ if (isRingtoneVibrationEnabled()) {
+ return false;
+ }
return Utils.isVoiceCapable(mContext);
}
@@ -43,4 +47,9 @@
public int getRingtoneType() {
return RingtoneManager.TYPE_RINGTONE;
}
+
+ private boolean isRingtoneVibrationEnabled() {
+ return Flags.enableRingtoneHapticsCustomization() && mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported);
+ }
}
diff --git a/src/com/android/settings/notification/SeparateRingVolumePreference.kt b/src/com/android/settings/notification/SeparateRingVolumePreference.kt
index a9c167d..3edb4ac 100644
--- a/src/com/android/settings/notification/SeparateRingVolumePreference.kt
+++ b/src/com/android/settings/notification/SeparateRingVolumePreference.kt
@@ -39,6 +39,7 @@
import com.android.settingslib.metadata.PreferenceMetadata
import com.android.settingslib.metadata.RangeValue
import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
import com.android.settingslib.preference.PreferenceBinding
// LINT.IfChange
@@ -91,6 +92,9 @@
override fun getWritePermit(context: Context, value: Int?, myUid: Int, callingUid: Int) =
ReadWritePermit.ALLOW
+ override val sensitivityLevel
+ get() = SensitivityLevel.NO_SENSITIVITY
+
override fun getMinValue(context: Context) =
createAudioHelper(context).getMinVolume(STREAM_RING)
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt b/tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt
index 99851de..40ed9a3 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationIntensityScreenTest.kt
@@ -15,15 +15,40 @@
*/
package com.android.settings.accessibility
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.res.Resources
+import android.os.Vibrator
+import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.flags.Flags
+import com.android.settings.R
import com.android.settingslib.preference.CatalystScreenTestCase
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+// LINT.IfChange
@RunWith(AndroidJUnit4::class)
class VibrationIntensityScreenTest : CatalystScreenTestCase() {
+ private lateinit var vibrator: Vibrator
+
+ private val resourcesSpy: Resources =
+ spy((ApplicationProvider.getApplicationContext() as Context).resources)
+
+ private val context: Context =
+ object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
+ override fun getSystemService(name: String): Any? =
+ when {
+ name == getSystemServiceName(Vibrator::class.java) -> vibrator
+ else -> super.getSystemService(name)
+ }
+ override fun getResources(): Resources = resourcesSpy
+ }
override val preferenceScreenCreator = VibrationIntensityScreen()
@@ -34,4 +59,33 @@
fun key() {
assertThat(preferenceScreenCreator.key).isEqualTo(VibrationIntensityScreen.KEY)
}
+
+ @Test
+ fun isAvailable_noVibrator_unavailable() {
+ vibrator = mock { on { hasVibrator() } doReturn false }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 3
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isFalse()
+ }
+
+ @Test
+ fun isAvailable_hasVibratorAndSingleIntensityLevel_unavailable() {
+ vibrator = mock { on { hasVibrator() } doReturn true }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 1
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isFalse()
+ }
+
+ @Test
+ fun isAvailable_hasVibratorAndMultipleIntensityLevels_available() {
+ vibrator = mock { on { hasVibrator() } doReturn true }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 2
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isTrue()
+ }
}
+// LINT.ThenChange(VibrationPreferenceControllerTest.java)
+
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceControllerTest.java
index 6f57003..9caa211 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceControllerTest.java
@@ -41,6 +41,7 @@
import org.robolectric.RobolectricTestRunner;
/** Tests for {@link VibrationMainSwitchPreferenceController}. */
+// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class VibrationMainSwitchPreferenceControllerTest {
@@ -104,3 +105,4 @@
return Settings.System.getInt(mContext.getContentResolver(), settingKey);
}
}
+// LINT.ThenChange(VibrationMainSwitchPreferenceTest.kt)
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceTest.kt b/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceTest.kt
new file mode 100644
index 0000000..fd781bc
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationMainSwitchPreferenceTest.kt
@@ -0,0 +1,77 @@
+/*
+ * 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.accessibility
+
+import android.content.Context
+import android.provider.Settings.System.VIBRATE_ON
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settingslib.preference.createAndBindWidget
+import com.android.settingslib.widget.MainSwitchPreference
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+// LINT.IfChange
+@RunWith(AndroidJUnit4::class)
+class VibrationMainSwitchPreferenceTest {
+ private val context: Context = ApplicationProvider.getApplicationContext()
+ private val preference = VibrationMainSwitchPreference()
+
+ @Test
+ fun checked_valueUnset_returnDefaultTrue() {
+ setVibrateOn(null)
+
+ assertThat(getMainSwitchPreference().isChecked).isTrue()
+ }
+
+ @Test
+ fun checked_valueEnabled_returnTrue() {
+ setVibrateOn(true)
+
+ assertThat(getMainSwitchPreference().isChecked).isTrue()
+ }
+
+ @Test
+ fun checked_valueDisabled_returnFalse() {
+ setVibrateOn(false)
+
+ assertThat(getMainSwitchPreference().isChecked).isFalse()
+ }
+
+ @Test
+ fun click_updatesCorrectly() {
+ setVibrateOn(null)
+ val widget = getMainSwitchPreference()
+
+ assertThat(widget.isChecked).isTrue()
+
+ widget.performClick()
+
+ assertThat(widget.isChecked).isFalse()
+
+ widget.performClick()
+
+ assertThat(widget.isChecked).isTrue()
+ }
+
+ private fun getMainSwitchPreference(): MainSwitchPreference =
+ preference.createAndBindWidget(context)
+
+ private fun setVibrateOn(enabled: Boolean?) =
+ preference.storage(context).setValue(VIBRATE_ON, Boolean::class.javaObjectType, enabled)
+}
+// LINT.ThenChange(VibrationMainSwitchPreferenceControllerTest.java)
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
index 59ed486..a0481e5 100644
--- a/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationPreferenceControllerTest.java
@@ -46,6 +46,7 @@
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
+// LINT.IfChange
@RunWith(RobolectricTestRunner.class)
public class VibrationPreferenceControllerTest {
private static final String PREFERENCE_KEY = "preference_key";
@@ -158,3 +159,7 @@
return controller;
}
}
+// LINT.ThenChange(
+// VibrationIntensityScreenTest.kt,
+// VibrationScreenTest.kt,
+// )
diff --git a/tests/robotests/src/com/android/settings/accessibility/VibrationScreenTest.kt b/tests/robotests/src/com/android/settings/accessibility/VibrationScreenTest.kt
new file mode 100644
index 0000000..c6e5265
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/accessibility/VibrationScreenTest.kt
@@ -0,0 +1,90 @@
+/*
+ * 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.accessibility
+
+import android.content.Context
+import android.content.ContextWrapper
+import android.content.res.Resources
+import android.os.Vibrator
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.flags.Flags
+import com.android.settings.R
+import com.android.settingslib.preference.CatalystScreenTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.stub
+
+// LINT.IfChange
+@RunWith(AndroidJUnit4::class)
+class VibrationScreenTest : CatalystScreenTestCase() {
+ private lateinit var vibrator: Vibrator
+
+ private val resourcesSpy: Resources =
+ spy((ApplicationProvider.getApplicationContext() as Context).resources)
+
+ private val context: Context =
+ object : ContextWrapper(ApplicationProvider.getApplicationContext()) {
+ override fun getSystemService(name: String): Any? =
+ when {
+ name == getSystemServiceName(Vibrator::class.java) -> vibrator
+ else -> super.getSystemService(name)
+ }
+ override fun getResources(): Resources = resourcesSpy
+ }
+
+ override val preferenceScreenCreator = VibrationScreen()
+
+ override val flagName: String
+ get() = Flags.FLAG_CATALYST_VIBRATION_INTENSITY_SCREEN
+
+ @Test
+ fun key() {
+ assertThat(preferenceScreenCreator.key).isEqualTo(VibrationScreen.KEY)
+ }
+
+ @Test
+ fun isAvailable_noVibrator_unavailable() {
+ vibrator = mock { on { hasVibrator() } doReturn false }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 1
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isFalse()
+ }
+
+ @Test
+ fun isAvailable_hasVibratorAndMultipleIntensityLevels_unavailable() {
+ vibrator = mock { on { hasVibrator() } doReturn true }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 3
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isFalse()
+ }
+
+ @Test
+ fun isAvailable_hasVibratorAndSingleIntensityLevel_available() {
+ vibrator = mock { on { hasVibrator() } doReturn true }
+ resourcesSpy.stub {
+ on { getInteger(R.integer.config_vibration_supported_intensity_levels) } doReturn 1
+ }
+ assertThat(preferenceScreenCreator.isAvailable(context)).isTrue()
+ }
+}
+// LINT.ThenChange(VibrationPreferenceControllerTest.java)
diff --git a/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java
index 24e8458..9e49653 100644
--- a/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/notification/PhoneRingtonePreferenceControllerTest.java
@@ -21,17 +21,22 @@
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.content.res.Resources;
import android.media.RingtoneManager;
+import android.media.audio.Flags;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
import android.telephony.TelephonyManager;
+
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.shadows.ShadowApplication;
@RunWith(RobolectricTestRunner.class)
public class PhoneRingtonePreferenceControllerTest {
@@ -39,33 +44,60 @@
@Mock
private TelephonyManager mTelephonyManager;
- private Context mContext;
+ @Mock
+ private Context mMockContext;
+
+ @Mock
+ private Resources mMockResources;
+
private PhoneRingtonePreferenceController mController;
+ @Rule
+ public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- ShadowApplication shadowContext = ShadowApplication.getInstance();
- shadowContext.setSystemService(Context.TELEPHONY_SERVICE, mTelephonyManager);
- mContext = RuntimeEnvironment.application;
- mController = new PhoneRingtonePreferenceController(mContext);
+ when(mMockContext.getResources()).thenReturn(mMockResources);
+ when(mMockContext.getSystemService(
+ Context.TELEPHONY_SERVICE)).thenReturn(mTelephonyManager);
+ mController = new PhoneRingtonePreferenceController(mMockContext);
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION)
public void isAvailable_notVoiceCapable_shouldReturnFalse() {
+ when(mMockResources
+ .getBoolean(com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported))
+ .thenReturn(false);
when(mTelephonyManager.isVoiceCapable()).thenReturn(false);
assertThat(mController.isAvailable()).isFalse();
}
@Test
+ @DisableFlags(Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION)
public void isAvailable_VoiceCapable_shouldReturnTrue() {
+ when(mMockResources
+ .getBoolean(com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported))
+ .thenReturn(false);
when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
assertThat(mController.isAvailable()).isTrue();
}
@Test
+ @EnableFlags(Flags.FLAG_ENABLE_RINGTONE_HAPTICS_CUSTOMIZATION)
+ public void isAvailable_vibrationSupported_shouldReturnFalse() {
+ when(mMockResources
+ .getBoolean(com.android.internal.R.bool.config_ringtoneVibrationSettingsSupported))
+ .thenReturn(true);
+ when(mTelephonyManager.isVoiceCapable()).thenReturn(true);
+
+ assertThat(mController.isAvailable()).isFalse();
+ }
+
+ @Test
public void getRingtoneType_shouldReturnRingtone() {
assertThat(mController.getRingtoneType()).isEqualTo(RingtoneManager.TYPE_RINGTONE);
}
diff --git a/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsSosPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsSosPreferenceControllerTest.java
new file mode 100644
index 0000000..5c78a14
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/SatelliteSettingsSosPreferenceControllerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.network.telephony;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.telephony.CarrierConfigManager;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.network.CarrierConfigCache;
+
+import org.junit.Before;
+import org.junit.Ignore;
+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;
+
+@RunWith(AndroidJUnit4.class)
+public class SatelliteSettingsSosPreferenceControllerTest {
+ private static final String KEY = "key";
+ private static final int TEST_SUB_ID = 0;
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Mock
+ private CarrierConfigCache mCarrierConfigCache;
+
+ private Context mContext = null;
+ private SatelliteSettingSosPreferenceController mController = null;
+ private PersistableBundle mCarrierConfig = new PersistableBundle();
+
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ mController = new SatelliteSettingSosPreferenceController(mContext, KEY);
+ CarrierConfigCache.setTestInstance(mContext, mCarrierConfigCache);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
+ public void getAvailabilityStatus_carrierNotSupport_returnUnAvailable() {
+ mCarrierConfig.putBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL,
+ false);
+ when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig);
+ mController.init(TEST_SUB_ID);
+
+ int result = mController.getAvailabilityStatus(TEST_SUB_ID);
+
+ assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+
+ @Ignore("Avoid post submit test failed.")
+ @Test
+ @EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
+ public void getAvailabilityStatus_carrierSupported_returnAvailable() {
+ mCarrierConfig.putBoolean(
+ CarrierConfigManager.KEY_SATELLITE_ESOS_SUPPORTED_BOOL,
+ true);
+ when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig);
+ mController.init(TEST_SUB_ID);
+
+ int result = mController.getAvailabilityStatus(TEST_SUB_ID);
+
+ assertThat(result).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ @DisableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
+ public void getAvailabilityStatus_featureDisabled_returnAvailable() {
+ int result = mController.getAvailabilityStatus(TEST_SUB_ID);
+
+ assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+}