Snap for 12727401 from 9e3f075c3a to 25Q1-release

Change-Id: I041fe893aceaa71b109a8ad76c727dc8a19e4e31
This commit is contained in:
Android Build Coastguard Worker
2024-11-29 00:17:15 +00:00
23 changed files with 1011 additions and 98 deletions

View File

@@ -2007,6 +2007,8 @@
<string name="external_display_off">Off</string> <string name="external_display_off">Off</string>
<!-- External Display settings. The title of the screen. [CHAR LIMIT=40] --> <!-- External Display settings. The title of the screen. [CHAR LIMIT=40] -->
<string name="external_display_settings_title">External Display</string> <string name="external_display_settings_title">External Display</string>
<!-- Built-in display settings category. Appears in External displays and Connected Displays fragments. -->
<string name="builtin_display_settings_category">Built-in display</string>
<!-- External Display use. The title of the use preference. [CHAR LIMIT=40] --> <!-- External Display use. The title of the use preference. [CHAR LIMIT=40] -->
<string name="external_display_use_title">Use external display</string> <string name="external_display_use_title">Use external display</string>
<!-- External Display resolution settings. The title of the screen. [CHAR LIMIT=40] --> <!-- External Display resolution settings. The title of the screen. [CHAR LIMIT=40] -->
@@ -2871,9 +2873,9 @@
<!-- Display settings screen, screen resolution option for high resolution [CHAR LIMIT=45] --> <!-- Display settings screen, screen resolution option for high resolution [CHAR LIMIT=45] -->
<string name="screen_resolution_option_high">High resolution</string> <string name="screen_resolution_option_high">High resolution</string>
<!-- Display settings screen, screen resolution option for full resolution [CHAR LIMIT=45] --> <!-- Display settings screen, screen resolution option for full resolution [CHAR LIMIT=45] -->
<string name="screen_resolution_option_full">Full resolution</string> <string name="screen_resolution_option_full">Max resolution</string>
<!-- The footer message for switch screen resolution [CHAR LIMIT=NONE] --> <!-- The footer message for switch screen resolution [CHAR LIMIT=NONE] -->
<string name="screen_resolution_footer">Full resolution uses more of your battery. Switching your resolution may cause some apps to restart.</string> <string name="screen_resolution_footer">Max resolution uses more of your battery. Switching your resolution may cause some apps to restart.</string>
<!-- Message announced to a11y users when they selected one resolution [CHAR LIMIT=NONE] --> <!-- Message announced to a11y users when they selected one resolution [CHAR LIMIT=NONE] -->
<string name="screen_resolution_selected_a11y">Selected</string> <string name="screen_resolution_selected_a11y">Selected</string>
@@ -4681,6 +4683,9 @@
<string name="pointer_stroke_style_name_none">None</string> <string name="pointer_stroke_style_name_none">None</string>
<!-- Title for the button to trigger the 'touch gesture' education. [CHAR LIMIT=35] --> <!-- Title for the button to trigger the 'touch gesture' education. [CHAR LIMIT=35] -->
<string name="trackpad_touch_gesture">Learn touchpad gestures</string> <string name="trackpad_touch_gesture">Learn touchpad gestures</string>
<!-- TODO(b/353947750): finalize this string and mark it translatable. -->
<!-- Notice displayed at the end of the touchpad settings page when the user has disabled system navigation gestures. "Pointer & touchpad accessibility" and "Use touchpad gestures" refer to other labels in Settings, and should be translated in exactly the same way. -->
<string name="trackpad_gestures_disabled_footer_text" translatable="false">Some settings are unavailable as touchpad gestures have been turned off. You can turn them on via Pointer &amp; touchpad accessibility > Use touchpad gestures</string>
<!-- Search keywords for "touchpad" --> <!-- Search keywords for "touchpad" -->
<string name="keywords_touchpad">trackpad, track pad, mouse, cursor, scroll, swipe, right click, click, pointer</string> <string name="keywords_touchpad">trackpad, track pad, mouse, cursor, scroll, swipe, right click, click, pointer</string>
<!-- Search keywords for 'Bottom-right tap', the name of the touchpad setting that allows the user to click the bottom right corner of the touchpad for more options. --> <!-- Search keywords for 'Bottom-right tap', the name of the touchpad setting that allows the user to click the bottom right corner of the touchpad for more options. -->
@@ -4963,6 +4968,15 @@
<string name="accessibility_pointer_and_touchpad_summary">Pointer color, pointer size &amp; more</string> <string name="accessibility_pointer_and_touchpad_summary">Pointer color, pointer size &amp; more</string>
<!-- Title for the accessibility pointer color customization page. [CHAR LIMIT=50] --> <!-- Title for the accessibility pointer color customization page. [CHAR LIMIT=50] -->
<string name="accessibility_pointer_color_customization_title">Pointer color customization</string> <string name="accessibility_pointer_color_customization_title">Pointer color customization</string>
<!-- TODO(b/353947750): finalize the four strings below and mark them translatable. -->
<!-- Title for the touchpad section of the accessibility pointer and touchpad page. -->
<string name="accessibility_touchpad_title" translatable="false">Touchpad</string>
<!-- Title for a settings toggle that allows the user to enable or disable system gestures (3- or 4-finger swipes for going home, back, to the overview screen, or between apps) being made on a touchpad. -->
<string name="accessibility_touchpad_system_gestures_enable_title" translatable="false">Use system gestures</string>
<!-- Description text for a settings toggle that allows the user to enable or disable system gestures (3- or 4-finger swipes for going home, back, to the overview screen, or between apps) being made on a touchpad. -->
<string name="accessibility_touchpad_system_gestures_enable_summary" translatable="false">When turned off, 3- or 4-finger gestures are ignored</string>
<!-- List of synonyms used in the settings search bar to find the "Use system gestures" touchpad setting, which allows the user to enable or disable system gestures (3- or 4-finger swipes for going home, back, to the overview screen, or between apps) being made on a touchpad. -->
<string name="keywords_accessibility_touchpad_system_gestures_enable" translatable="false">touchpad, trackpad, swipe</string>
<!-- Title for the accessibility color contrast page. [CHAR LIMIT=50] --> <!-- Title for the accessibility color contrast page. [CHAR LIMIT=50] -->
<string name="accessibility_color_contrast_title">Color contrast</string> <string name="accessibility_color_contrast_title">Color contrast</string>
<!-- Intro for the accessibility color contrast page. [CHAR LIMIT=NONE] --> <!-- Intro for the accessibility color contrast page. [CHAR LIMIT=NONE] -->
@@ -12275,13 +12289,13 @@
<!-- Search keywords for "_satellite_setting_preference_layout" [CHAR_LIMIT=NONE] --> <!-- 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</string>
<!-- Category name "About satellite messaging" [CHAR_LIMIT=NONE] --> <!-- Category name "About satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="category_name_about_satellite_messaging">About satellite messaging</string> <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] --> <!-- Summary for category "About satellite messaging" [CHAR_LIMIT=NONE] -->
<string name="title_about_satellite_setting">You can send and receive text messages by satellite as part of an eligible <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> account</string> <string name="title_about_satellite_setting">You can send and receive text messages by satellite as part of an eligible <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> account</string>
<!-- Category title "Your mobile plan" [CHAR_LIMIT=NONE] --> <!-- Category title "Your mobile plan" [CHAR_LIMIT=NONE] -->
<string name="category_title_your_satellite_plan">Your <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> plan</string> <string name="category_title_your_satellite_plan">Your <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> plan</string>
<!-- Title for category "Your mobile plan when satellite is included in plan" [CHAR_LIMIT=NONE] --> <!-- Title for category "Your mobile plan when satellite is included in plan" [CHAR_LIMIT=NONE] -->
<string name="title_have_satellite_plan">Satellite messaging is included with your account</string> <string name="title_have_satellite_plan">Messaging is included with your account</string>
<!-- Title for category "Your mobile plan when satellite is not included in plan" [CHAR_LIMIT=NONE] --> <!-- Title for category "Your mobile plan when satellite is not included in plan" [CHAR_LIMIT=NONE] -->
<string name="title_no_satellite_plan">Satellite messaging isn\u2019t included with your account</string> <string name="title_no_satellite_plan">Satellite messaging isn\u2019t included with your account</string>
<!-- text view "Learn more" [CHAR_LIMIT=NONE] --> <!-- text view "Learn more" [CHAR_LIMIT=NONE] -->
@@ -12297,9 +12311,9 @@
<!-- Summary for satellite supported service [CHAR_LIMIT=NONE] --> <!-- Summary for satellite supported service [CHAR_LIMIT=NONE] -->
<string name="summary_supported_service">You can text anyone, including emergency services. Your phone will reconnect to a mobile network when available.</string> <string name="summary_supported_service">You can text anyone, including emergency services. Your phone will reconnect to a mobile network when available.</string>
<!-- learn more text - more about satellite messaging [CHAR_LIMIT=NONE] --> <!-- learn more text - more about satellite messaging [CHAR_LIMIT=NONE] -->
<string name="satellite_setting_summary_more_information">Satellite messaging may take longer and is available only in some areas. Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available. Emergency calls may still connect.\n\nIt may take some time for account changes to show in Settings. Contact your carrier for details.</string> <string name="satellite_setting_summary_more_information"><xliff:g id="subject" example="satellite messaging">%1$s</xliff:g> may take longer and is available only in some areas. Weather and certain structures may affect your satellite connection. Calling by satellite isn\u2019t available. Emergency calls may still connect.\n\nIt may take some time for account changes to show in Settings. Contact <xliff:g id="carrier_name" example="T-Mobile">%1$s</xliff:g> for details.</string>
<!-- more about satellite messaging [CHAR_LIMIT=NONE] --> <!-- more about satellite messaging [CHAR_LIMIT=NONE] -->
<string name="more_about_satellite_messaging">More about satellite messaging</string> <string name="more_about_satellite_messaging">More about <xliff:g id="subject" example="satellite messaging">%1$s</xliff:g></string>
<!-- Title for satellite warning dialog to avoid user using wifi/bluetooth/airplane mode [CHAR_LIMIT=NONE] --> <!-- Title for satellite warning dialog to avoid user using wifi/bluetooth/airplane mode [CHAR_LIMIT=NONE] -->
<string name="satellite_warning_dialog_title">Cant turn on <xliff:g id="function" example="bluetooth">%1$s</xliff:g></string> <string name="satellite_warning_dialog_title">Cant turn on <xliff:g id="function" example="bluetooth">%1$s</xliff:g></string>
<!-- Content for satellite warning dialog to avoid user using wifi/bluetooth/airplane mode [CHAR_LIMIT=NONE] --> <!-- Content for satellite warning dialog to avoid user using wifi/bluetooth/airplane mode [CHAR_LIMIT=NONE] -->
@@ -12307,7 +12321,14 @@
<!-- Category title for satellite functions with data transmission in mobile network settings [CHAR LIMIT=60] --> <!-- Category title for satellite functions with data transmission in mobile network settings [CHAR LIMIT=60] -->
<string name="category_title_satellite_connectivity">Satellite connectivity</string> <string name="category_title_satellite_connectivity">Satellite connectivity</string>
<!-- Title for satellite functions with data transmission in mobile network settings [CHAR LIMIT=60] --> <!-- Title for satellite functions with data transmission in mobile network settings [CHAR LIMIT=60] -->
<string name="satellite_setting_connectivity">Satellite connectivity</string> <string name="title_satellite_setting_connectivity">Satellite connectivity</string>
<!-- Description of satellite function with data transmission [CHAR LIMIT=60] -->
<string name="description_satellite_setting_connectivity">satellite connectivity</string>
<!-- Description of satellite function [CHAR LIMIT=60] -->
<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 Apn settings in mobile network settings [CHAR LIMIT=60] --> <!-- Title for Apn settings in mobile network settings [CHAR LIMIT=60] -->

View File

@@ -46,4 +46,17 @@
settings:keywords="@string/keywords_auto_click" settings:keywords="@string/keywords_auto_click"
settings:controller="com.android.settings.accessibility.AutoclickPreferenceController"/> settings:controller="com.android.settings.accessibility.AutoclickPreferenceController"/>
<PreferenceCategory
android:key="touchpad_category"
android:persistent="false"
android:title="@string/accessibility_touchpad_title">
<SwitchPreferenceCompat
android:key="touchpad_system_gestures_enable"
android:title="@string/accessibility_touchpad_system_gestures_enable_title"
android:summary="@string/accessibility_touchpad_system_gestures_enable_summary"
settings:keywords="@string/keywords_accessibility_touchpad_system_gestures_enable"/>
</PreferenceCategory>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -22,7 +22,7 @@
settings:keywords="@string/keywords_satellite_setting"> settings:keywords="@string/keywords_satellite_setting">
<PreferenceCategory <PreferenceCategory
android:title="@string/category_name_about_satellite_messaging"> android:key="key_category_about_satellite">
<com.android.settingslib.widget.TopIntroPreference <com.android.settingslib.widget.TopIntroPreference
android:key="key_about_satellite_messaging"/> android:key="key_about_satellite_messaging"/>
@@ -35,6 +35,12 @@
<Preference <Preference
android:key="key_your_satellite_plan" android:key="key_your_satellite_plan"
android:icon="?android:attr/textColorPrimary"/> android:icon="?android:attr/textColorPrimary"/>
<Preference
android:key="key_your_satellite_data_plan"
android:icon="?android:attr/textColorPrimary"
settings:isPreferenceVisible="false"/>
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory <PreferenceCategory

View File

@@ -96,4 +96,10 @@
android:key="trackpad_touch_gesture" android:key="trackpad_touch_gesture"
android:title="@string/trackpad_touch_gesture" android:title="@string/trackpad_touch_gesture"
settings:controller="com.android.settings.inputmethod.TouchGesturesButtonPreferenceController"/> settings:controller="com.android.settings.inputmethod.TouchGesturesButtonPreferenceController"/>
<com.android.settingslib.widget.FooterPreference
android:key="trackpad_gestures_disabled_footer"
android:title="@string/trackpad_gestures_disabled_footer_text"
settings:searchable="false"
settings:controller="com.android.settings.inputmethod.TrackpadGesturesDisabledFooterPreferenceController"/>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -43,7 +43,6 @@ import com.android.internal.content.PackageMonitor;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType; import com.android.settings.accessibility.AccessibilityUtil.AccessibilityServiceFragmentType;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.development.Enable16kUtils;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
@@ -96,8 +95,6 @@ public class AccessibilitySettings extends DashboardFragment implements
static final String EXTRA_TIME_FOR_LOGGING = "start_time_to_log_a11y_tool"; static final String EXTRA_TIME_FOR_LOGGING = "start_time_to_log_a11y_tool";
static final String EXTRA_METRICS_CATEGORY = "metrics_category"; static final String EXTRA_METRICS_CATEGORY = "metrics_category";
public static final String VOICE_ACCESS_SERVICE = "android.apps.accessibility.voiceaccess";
// Timeout before we update the services if packages are added/removed // Timeout before we update the services if packages are added/removed
// since the AccessibilityManagerService has to do that processing first // since the AccessibilityManagerService has to do that processing first
// to generate the AccessibilityServiceInfo we need for proper // to generate the AccessibilityServiceInfo we need for proper
@@ -503,11 +500,6 @@ public class AccessibilitySettings extends DashboardFragment implements
String[] services = getResources().getStringArray(key); String[] services = getResources().getStringArray(key);
PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey); PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey);
for (int i = 0; i < services.length; i++) { for (int i = 0; i < services.length; i++) {
// TODO(b/335443194) Voice access is not available in 16kB mode.
if (services[i].contains(VOICE_ACCESS_SERVICE)
&& Enable16kUtils.isPageAgnosticModeOn(getContext())) {
continue;
}
ComponentName component = ComponentName.unflattenFromString(services[i]); ComponentName component = ComponentName.unflattenFromString(services[i]);
mPreBundledServiceComponentToCategoryMap.put(component, category); mPreBundledServiceComponentToCategoryMap.put(component, category);
} }

View File

@@ -16,8 +16,6 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.settings.accessibility.AccessibilitySettings.VOICE_ACCESS_SERVICE;
import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityServiceInfo;
import android.accessibilityservice.AccessibilityShortcutInfo; import android.accessibilityservice.AccessibilityShortcutInfo;
import android.app.AppOpsManager; import android.app.AppOpsManager;
@@ -31,7 +29,6 @@ import android.os.UserHandle;
import android.text.TextUtils; import android.text.TextUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.development.Enable16kUtils;
import com.android.settingslib.RestrictedLockUtils; import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedLockUtilsInternal; import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.RestrictedPreference; import com.android.settingslib.RestrictedPreference;
@@ -81,12 +78,6 @@ public class RestrictedPreferenceHelper {
final AccessibilityServiceInfo info = installedServices.get(i); final AccessibilityServiceInfo info = installedServices.get(i);
final ResolveInfo resolveInfo = info.getResolveInfo(); final ResolveInfo resolveInfo = info.getResolveInfo();
final String packageName = resolveInfo.serviceInfo.packageName; final String packageName = resolveInfo.serviceInfo.packageName;
// TODO(b/335443194) Voice access is not available in 16kB mode.
if (packageName.contains(VOICE_ACCESS_SERVICE)
&& Enable16kUtils.isPageAgnosticModeOn(mContext)) {
continue;
}
final ComponentName componentName = new ComponentName(packageName, final ComponentName componentName = new ComponentName(packageName,
resolveInfo.serviceInfo.name); resolveInfo.serviceInfo.name);
final boolean serviceEnabled = enabledServices.contains(componentName); final boolean serviceEnabled = enabledServices.contains(componentName);

View File

@@ -16,7 +16,6 @@
package com.android.settings.connecteddevice.display; package com.android.settings.connecteddevice.display;
import static android.view.Display.INVALID_DISPLAY; import static android.view.Display.INVALID_DISPLAY;
import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.EXTERNAL_DISPLAY_HELP_URL; import static com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.EXTERNAL_DISPLAY_HELP_URL;
@@ -46,6 +45,7 @@ import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragmentBase; import com.android.settings.SettingsPreferenceFragmentBase;
import com.android.settings.accessibility.TextReadingPreferenceFragment;
import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DisplayListener; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.DisplayListener;
import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.Injector; import com.android.settings.connecteddevice.display.ExternalDisplaySettingsConfiguration.Injector;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
@@ -64,6 +64,7 @@ import java.util.List;
public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmentBase { public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmentBase {
static final int EXTERNAL_DISPLAY_SETTINGS_RESOURCE = R.xml.external_display_settings; static final int EXTERNAL_DISPLAY_SETTINGS_RESOURCE = R.xml.external_display_settings;
static final String DISPLAYS_LIST_PREFERENCE_KEY = "displays_list_preference"; static final String DISPLAYS_LIST_PREFERENCE_KEY = "displays_list_preference";
static final String BUILTIN_DISPLAY_LIST_PREFERENCE_KEY = "builtin_display_list_preference";
static final String EXTERNAL_DISPLAY_USE_PREFERENCE_KEY = "external_display_use_preference"; static final String EXTERNAL_DISPLAY_USE_PREFERENCE_KEY = "external_display_use_preference";
static final String EXTERNAL_DISPLAY_ROTATION_KEY = "external_display_rotation"; static final String EXTERNAL_DISPLAY_ROTATION_KEY = "external_display_rotation";
static final String EXTERNAL_DISPLAY_RESOLUTION_PREFERENCE_KEY = "external_display_resolution"; static final String EXTERNAL_DISPLAY_RESOLUTION_PREFERENCE_KEY = "external_display_resolution";
@@ -83,6 +84,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
R.string.external_display_rotation; R.string.external_display_rotation;
static final int EXTERNAL_DISPLAY_RESOLUTION_TITLE_RESOURCE = static final int EXTERNAL_DISPLAY_RESOLUTION_TITLE_RESOURCE =
R.string.external_display_resolution_settings_title; R.string.external_display_resolution_settings_title;
static final int BUILTIN_DISPLAY_SETTINGS_CATEGORY_RESOURCE =
R.string.builtin_display_settings_category;
@VisibleForTesting @VisibleForTesting
static final String PREVIOUSLY_SHOWN_LIST_KEY = "mPreviouslyShownListOfDisplays"; static final String PREVIOUSLY_SHOWN_LIST_KEY = "mPreviouslyShownListOfDisplays";
private boolean mStarted; private boolean mStarted;
@@ -101,6 +104,8 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
@Nullable @Nullable
private PreferenceCategory mDisplaysPreference; private PreferenceCategory mDisplaysPreference;
@Nullable @Nullable
private PreferenceCategory mBuiltinDisplayPreference;
@Nullable
private Injector mInjector; private Injector mInjector;
@Nullable @Nullable
private String[] mRotationEntries; private String[] mRotationEntries;
@@ -200,7 +205,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
} }
@VisibleForTesting @VisibleForTesting
protected void launchDisplaySettings(final int displayId) { protected void launchExternalDisplaySettings(final int displayId) {
final Bundle args = new Bundle(); final Bundle args = new Bundle();
var context = getPrefContext(); var context = getPrefContext();
args.putInt(DISPLAY_ID_ARG, displayId); args.putInt(DISPLAY_ID_ARG, displayId);
@@ -210,6 +215,16 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
.setSourceMetricsCategory(getMetricsCategory()).launch(); .setSourceMetricsCategory(getMetricsCategory()).launch();
} }
@VisibleForTesting
protected void launchBuiltinDisplaySettings() {
final Bundle args = new Bundle();
var context = getPrefContext();
new SubSettingLauncher(context)
.setDestination(TextReadingPreferenceFragment.class.getName())
.setArguments(args)
.setSourceMetricsCategory(getMetricsCategory()).launch();
}
/** /**
* Returns the preference for the footer. * Returns the preference for the footer.
*/ */
@@ -281,6 +296,15 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
return mDisplaysPreference; return mDisplaysPreference;
} }
@NonNull
private PreferenceCategory getBuiltinDisplayListPreference(@NonNull Context context) {
if (mBuiltinDisplayPreference == null) {
mBuiltinDisplayPreference = new PreferenceCategory(context);
mBuiltinDisplayPreference.setPersistent(false);
}
return mBuiltinDisplayPreference;
}
@NonNull Preference getDisplayTopologyPreference(@NonNull Context context) { @NonNull Preference getDisplayTopologyPreference(@NonNull Context context) {
if (mDisplayTopologyPreference == null) { if (mDisplayTopologyPreference == null) {
mDisplayTopologyPreference = new DisplayTopologyPreference(context); mDisplayTopologyPreference = new DisplayTopologyPreference(context);
@@ -310,7 +334,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
@NonNull final PreferenceScreen screen, @NonNull Context context) { @NonNull final PreferenceScreen screen, @NonNull Context context) {
final boolean forceShowList = displayId == INVALID_DISPLAY final boolean forceShowList = displayId == INVALID_DISPLAY
&& mInjector != null && forceShowDisplayList(mInjector.getFlags()); && mInjector != null && forceShowDisplayList(mInjector.getFlags());
final var displaysToShow = getDisplaysToShow(displayId); final var displaysToShow = externalDisplaysToShow(displayId);
if (!forceShowList && displaysToShow.isEmpty() && displayId == INVALID_DISPLAY) { if (!forceShowList && displaysToShow.isEmpty() && displayId == INVALID_DISPLAY) {
showTextWhenNoDisplaysToShow(screen, context); showTextWhenNoDisplaysToShow(screen, context);
@@ -373,9 +397,18 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
private void showDisplaysList(@NonNull List<Display> displaysToShow, private void showDisplaysList(@NonNull List<Display> displaysToShow,
@NonNull PreferenceScreen screen, @NonNull Context context) { @NonNull PreferenceScreen screen, @NonNull Context context) {
if (mInjector != null if (mInjector != null && mInjector.getFlags().displayTopologyPaneInDisplayList()) {
&& mInjector.getFlags().displayTopologyPaneInDisplayList()) {
screen.addPreference(getDisplayTopologyPreference(context)); screen.addPreference(getDisplayTopologyPreference(context));
// If topology is shown, we also show a preference for the built-in display for
// consistency with the topology.
var builtinCategory = getBuiltinDisplayListPreference(context);
builtinCategory.setKey(BUILTIN_DISPLAY_LIST_PREFERENCE_KEY);
builtinCategory.setTitle(BUILTIN_DISPLAY_SETTINGS_CATEGORY_RESOURCE);
builtinCategory.removeAll();
screen.addPreference(builtinCategory);
builtinCategory.addPreference(new BuiltinDisplaySizeAndTextPreference(context));
} }
var pref = getDisplaysListPreference(context); var pref = getDisplaysListPreference(context);
@@ -389,7 +422,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
} }
} }
private List<Display> getDisplaysToShow(int displayIdToShow) { private List<Display> externalDisplaysToShow(int displayIdToShow) {
if (mInjector == null) { if (mInjector == null) {
return List.of(); return List.of();
} }
@@ -530,6 +563,24 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
mInjector.getHandler().removeCallbacks(mUpdateRunnable); mInjector.getHandler().removeCallbacks(mUpdateRunnable);
} }
private class BuiltinDisplaySizeAndTextPreference extends Preference
implements Preference.OnPreferenceClickListener {
BuiltinDisplaySizeAndTextPreference(@NonNull final Context context) {
super(context);
setPersistent(false);
setKey("builtin_display_size_and_text");
setTitle(R.string.accessibility_text_reading_options_title);
setOnPreferenceClickListener(this);
}
@Override
public boolean onPreferenceClick(@NonNull Preference preference) {
launchBuiltinDisplaySettings();
return true;
}
}
@VisibleForTesting @VisibleForTesting
class DisplayPreference extends TwoTargetPreference class DisplayPreference extends TwoTargetPreference
implements Preference.OnPreferenceClickListener { implements Preference.OnPreferenceClickListener {
@@ -538,6 +589,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
DisplayPreference(@NonNull final Context context, @NonNull final Display display) { DisplayPreference(@NonNull final Context context, @NonNull final Display display) {
super(context); super(context);
mDisplayId = display.getDisplayId(); mDisplayId = display.getDisplayId();
setPersistent(false); setPersistent(false);
setKey("display_id_" + mDisplayId); setKey("display_id_" + mDisplayId);
setTitle(display.getName()); setTitle(display.getName());
@@ -548,7 +600,7 @@ public class ExternalDisplayPreferenceFragment extends SettingsPreferenceFragmen
@Override @Override
public boolean onPreferenceClick(@NonNull Preference preference) { public boolean onPreferenceClick(@NonNull Preference preference) {
launchDisplaySettings(mDisplayId); launchExternalDisplaySettings(mDisplayId);
writePreferenceClickMetric(preference); writePreferenceClickMetric(preference);
return true; return true;
} }

View File

@@ -25,14 +25,33 @@ import android.content.Context;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.widget.PreferenceCategoryController;
import com.android.settingslib.core.AbstractPreferenceController;
import com.android.settingslib.search.SearchIndexable; import com.android.settingslib.search.SearchIndexable;
import java.util.List;
/** Accessibility settings for pointer and touchpad. */ /** Accessibility settings for pointer and touchpad. */
@SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC)
public class PointerTouchpadFragment extends DashboardFragment { public class PointerTouchpadFragment extends DashboardFragment {
private static final String TAG = "PointerTouchpadFragment"; private static final String TAG = "PointerTouchpadFragment";
@Override
protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
return buildPreferenceControllers(context);
}
private static List<AbstractPreferenceController> buildPreferenceControllers(Context context) {
TouchpadSystemGesturesPreferenceController systemGesturesController =
new TouchpadSystemGesturesPreferenceController(
context, "touchpad_system_gestures_enable");
return List.of(
systemGesturesController,
new PreferenceCategoryController(context, "touchpad_category")
.setChildren(List.of(systemGesturesController)));
}
@Override @Override
public int getMetricsCategory() { public int getMetricsCategory() {
return SettingsEnums.ACCESSIBILITY_POINTER_TOUCHPAD; return SettingsEnums.ACCESSIBILITY_POINTER_TOUCHPAD;
@@ -54,5 +73,11 @@ public class PointerTouchpadFragment extends DashboardFragment {
protected boolean isPageSearchEnabled(Context context) { protected boolean isPageSearchEnabled(Context context) {
return isTouchpad() || isMouse(); return isTouchpad() || isMouse();
} }
@Override
public List<AbstractPreferenceController> createPreferenceControllers(
Context context) {
return buildPreferenceControllers(context);
}
}; };
} }

View File

@@ -21,6 +21,7 @@ import static com.android.systemui.shared.Flags.newTouchpadGesturesTutorial;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.hardware.input.InputSettings;
import android.os.UserHandle; import android.os.UserHandle;
import android.util.FeatureFlagUtils; import android.util.FeatureFlagUtils;
@@ -75,7 +76,14 @@ public class TouchGesturesButtonPreferenceController extends BasePreferenceContr
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
boolean isTouchpad = InputPeripheralsSettingsUtils.isTouchpad(); boolean isTouchpad = InputPeripheralsSettingsUtils.isTouchpad();
return isTouchpad ? AVAILABLE : CONDITIONALLY_UNAVAILABLE; if (isTouchpad) {
// If the user's disabled touchpad system gestures in the accessibility settings, the
// tutorial won't work or be relevant, so disable the button.
return InputSettings.useTouchpadSystemGestures(mContext) ? AVAILABLE
: DISABLED_DEPENDENT_SETTING;
} else {
return CONDITIONALLY_UNAVAILABLE;
}
} }
private void showTouchpadGestureEducation() { private void showTouchpadGestureEducation() {

View File

@@ -0,0 +1,54 @@
/*
* Copyright 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.inputmethod;
import android.content.Context;
import android.hardware.input.InputSettings;
import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController;
public class TouchpadSystemGesturesPreferenceController extends TogglePreferenceController {
public TouchpadSystemGesturesPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return InputSettings.isTouchpadSystemGestureDisableFeatureFlagEnabled()
&& InputPeripheralsSettingsUtils.isTouchpad() ? AVAILABLE
: CONDITIONALLY_UNAVAILABLE;
}
@Override
public boolean isChecked() {
return InputSettings.useTouchpadSystemGestures(mContext);
}
@Override
public boolean setChecked(boolean isChecked) {
InputSettings.setTouchpadSystemGesturesEnabled(mContext, isChecked);
// TODO(b/353947750): add a metric for when the setting changes.
return true;
}
@Override
public int getSliceHighlightMenuRes() {
return R.string.menu_key_accessibility;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 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.inputmethod;
import android.content.Context;
import android.hardware.input.InputSettings;
import com.android.settings.core.BasePreferenceController;
public class TrackpadGesturesDisabledFooterPreferenceController extends BasePreferenceController {
public TrackpadGesturesDisabledFooterPreferenceController(Context context, String key) {
super(context, key);
}
@Override
public int getAvailabilityStatus() {
return InputSettings.useTouchpadSystemGestures(mContext) ? CONDITIONALLY_UNAVAILABLE
: AVAILABLE;
}
}

View File

@@ -16,9 +16,6 @@
package com.android.settings.network.telephony; package com.android.settings.network.telephony;
import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static androidx.lifecycle.Lifecycle.Event.ON_STOP;
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.getNetworkModePreferenceType;
import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes; import static com.android.settings.network.telephony.EnabledNetworkModePreferenceControllerHelperKt.setAllowedNetworkTypes;
import static com.android.settings.network.telephony.mode.NetworkModes.addNrToLteNetworkMode; import static com.android.settings.network.telephony.mode.NetworkModes.addNrToLteNetworkMode;
@@ -33,15 +30,17 @@ import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.TelephonyCallback; import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteModemStateCallback;
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.OnLifecycleEvent;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.ListPreferenceDialogFragmentCompat; import androidx.preference.ListPreferenceDialogFragmentCompat;
import androidx.preference.Preference; import androidx.preference.Preference;
@@ -67,7 +66,7 @@ import java.util.stream.Stream;
*/ */
public class EnabledNetworkModePreferenceController extends public class EnabledNetworkModePreferenceController extends
BasePreferenceController implements BasePreferenceController implements
ListPreference.OnPreferenceChangeListener, LifecycleObserver, ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver,
SubscriptionsChangeListener.SubscriptionsChangeListenerClient { SubscriptionsChangeListener.SubscriptionsChangeListenerClient {
private static final String LOG_TAG = "EnabledNetworkMode"; private static final String LOG_TAG = "EnabledNetworkMode";
@@ -83,6 +82,43 @@ public class EnabledNetworkModePreferenceController extends
private PhoneCallStateTelephonyCallback mTelephonyCallback; private PhoneCallStateTelephonyCallback mTelephonyCallback;
private FragmentManager mFragmentManager; private FragmentManager mFragmentManager;
private LifecycleOwner mViewLifecycleOwner; private LifecycleOwner mViewLifecycleOwner;
private SatelliteManager mSatelliteManager;
private boolean mIsSatelliteSessionStarted = false;
private boolean mIsCurrentSubscriptionForSatellite = false;
@VisibleForTesting
final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback =
new SelectedNbIotSatelliteSubscriptionCallback() {
@Override
public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId;
updatePreference();
}
};
@VisibleForTesting
final SatelliteModemStateCallback mSatelliteModemStateCallback =
new SatelliteModemStateCallback() {
@Override
public void onSatelliteModemStateChanged(int state) {
switch (state) {
case SatelliteManager.SATELLITE_MODEM_STATE_OFF:
case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE:
case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN:
if (mIsSatelliteSessionStarted) {
mIsSatelliteSessionStarted = false;
updatePreference();
}
break;
default:
if (!mIsSatelliteSessionStarted) {
mIsSatelliteSessionStarted = true;
updatePreference();
}
break;
}
}
};
public EnabledNetworkModePreferenceController(Context context, String key) { public EnabledNetworkModePreferenceController(Context context, String key) {
super(context, key); super(context, key);
@@ -90,6 +126,7 @@ public class EnabledNetworkModePreferenceController extends
if (mTelephonyCallback == null) { if (mTelephonyCallback == null) {
mTelephonyCallback = new PhoneCallStateTelephonyCallback(); mTelephonyCallback = new PhoneCallStateTelephonyCallback();
} }
mSatelliteManager = context.getSystemService(SatelliteManager.class);
} }
@Override @Override
@@ -103,8 +140,22 @@ public class EnabledNetworkModePreferenceController extends
return mCallState == TelephonyManager.CALL_STATE_IDLE; return mCallState == TelephonyManager.CALL_STATE_IDLE;
} }
@OnLifecycleEvent(ON_START) @Override
public void onStart() { public void onStart(@NonNull LifecycleOwner owner) {
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
if (mSatelliteManager != null) {
try {
mSatelliteManager.registerForModemStateChanged(
mContext.getMainExecutor(), mSatelliteModemStateCallback);
mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
mContext.getMainExecutor(),
mSelectedNbIotSatelliteSubscriptionCallback);
} catch (IllegalStateException e) {
Log.w(LOG_TAG, "IllegalStateException : " + e);
}
}
}
mSubscriptionsListener.start(); mSubscriptionsListener.start();
if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) {
return; return;
@@ -113,9 +164,21 @@ public class EnabledNetworkModePreferenceController extends
mTelephonyCallback.register(mTelephonyManager, mSubId); mTelephonyCallback.register(mTelephonyManager, mSubId);
} }
@OnLifecycleEvent(ON_STOP) @Override
public void onStop() { public void onStop(@NonNull LifecycleOwner owner) {
mSubscriptionsListener.stop(); mSubscriptionsListener.stop();
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
if (mSatelliteManager != null) {
try {
mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback);
mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
mSelectedNbIotSatelliteSubscriptionCallback);
} catch (IllegalStateException e) {
Log.w(LOG_TAG, "IllegalStateException : " + e);
}
}
}
if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) { if (mAllowedNetworkTypesListener == null || mTelephonyCallback == null) {
return; return;
} }
@@ -147,7 +210,7 @@ public class EnabledNetworkModePreferenceController extends
listPreference.setEntryValues(mBuilder.getEntryValues()); listPreference.setEntryValues(mBuilder.getEntryValues());
listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue())); listPreference.setValue(Integer.toString(mBuilder.getSelectedEntryValue()));
listPreference.setSummary(mBuilder.getSummary()); listPreference.setSummary(mBuilder.getSummary());
boolean listPreferenceEnabled = isCallStateIdle(); boolean listPreferenceEnabled = isPreferenceShallEnabled();
listPreference.setEnabled(listPreferenceEnabled); listPreference.setEnabled(listPreferenceEnabled);
if (!listPreferenceEnabled) { if (!listPreferenceEnabled) {
// If dialog is already opened when ListPreference disabled, dismiss them. // If dialog is already opened when ListPreference disabled, dismiss them.
@@ -203,6 +266,14 @@ public class EnabledNetworkModePreferenceController extends
} }
} }
private boolean isPreferenceShallEnabled() {
Log.d(LOG_TAG, "isPreferenceShallEnabled, mIsSatelliteSessionStarted : "
+ mIsSatelliteSessionStarted + " / mIsCurrentSubscriptionForSatellite : "
+ mIsCurrentSubscriptionForSatellite);
return isCallStateIdle()
&& !(mIsSatelliteSessionStarted && mIsCurrentSubscriptionForSatellite);
}
private final class PreferenceEntriesBuilder { private final class PreferenceEntriesBuilder {
private CarrierConfigCache mCarrierConfigCache; private CarrierConfigCache mCarrierConfigCache;
private Context mContext; private Context mContext;

View File

@@ -24,10 +24,18 @@ import android.telephony.CarrierConfigManager;
import android.telephony.RadioAccessFamily; import android.telephony.RadioAccessFamily;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.satellite.SatelliteManager;
import android.telephony.satellite.SatelliteModemStateCallback;
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
@@ -38,17 +46,56 @@ import com.android.settings.network.telephony.mode.NetworkModes;
* Preference controller for "Preferred network mode" * Preference controller for "Preferred network mode"
*/ */
public class PreferredNetworkModePreferenceController extends BasePreferenceController public class PreferredNetworkModePreferenceController extends BasePreferenceController
implements ListPreference.OnPreferenceChangeListener { implements ListPreference.OnPreferenceChangeListener, DefaultLifecycleObserver {
private static final String TAG = "PrefNetworkModeCtrl"; private static final String TAG = "PrefNetworkModeCtrl";
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private CarrierConfigCache mCarrierConfigCache; private CarrierConfigCache mCarrierConfigCache;
private TelephonyManager mTelephonyManager; private TelephonyManager mTelephonyManager;
private boolean mIsGlobalCdma; private boolean mIsGlobalCdma;
private SatelliteManager mSatelliteManager;
private Preference mPreference;
private boolean mIsSatelliteSessionStarted = false;
private boolean mIsCurrentSubscriptionForSatellite = false;
@VisibleForTesting
final SelectedNbIotSatelliteSubscriptionCallback mSelectedNbIotSatelliteSubscriptionCallback =
new SelectedNbIotSatelliteSubscriptionCallback() {
@Override
public void onSelectedNbIotSatelliteSubscriptionChanged(int selectedSubId) {
mIsCurrentSubscriptionForSatellite = selectedSubId == mSubId;
updateState(mPreference);
}
};
@VisibleForTesting
final SatelliteModemStateCallback mSatelliteModemStateCallback =
new SatelliteModemStateCallback() {
@Override
public void onSatelliteModemStateChanged(int state) {
switch (state) {
case SatelliteManager.SATELLITE_MODEM_STATE_OFF:
case SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE:
case SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN:
if (mIsSatelliteSessionStarted) {
mIsSatelliteSessionStarted = false;
updateState(mPreference);
}
break;
default:
if (!mIsSatelliteSessionStarted) {
mIsSatelliteSessionStarted = true;
updateState(mPreference);
}
break;
}
}
};
public PreferredNetworkModePreferenceController(Context context, String key) { public PreferredNetworkModePreferenceController(Context context, String key) {
super(context, key); super(context, key);
mCarrierConfigCache = CarrierConfigCache.getInstance(context); mCarrierConfigCache = CarrierConfigCache.getInstance(context);
mSatelliteManager = context.getSystemService(SatelliteManager.class);
} }
@Override @Override
@@ -58,9 +105,19 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
? AVAILABLE : CONDITIONALLY_UNAVAILABLE; ? AVAILABLE : CONDITIONALLY_UNAVAILABLE;
} }
@Override
public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen);
mPreference = screen.findPreference(getPreferenceKey());
}
@Override @Override
public void updateState(Preference preference) { public void updateState(Preference preference) {
if (preference == null) {
return;
}
super.updateState(preference); super.updateState(preference);
preference.setEnabled(!(mIsCurrentSubscriptionForSatellite && mIsSatelliteSessionStarted));
final ListPreference listPreference = (ListPreference) preference; final ListPreference listPreference = (ListPreference) preference;
final int networkMode = getPreferredNetworkMode(); final int networkMode = getPreferredNetworkMode();
listPreference.setValue(Integer.toString(networkMode)); listPreference.setValue(Integer.toString(networkMode));
@@ -90,6 +147,38 @@ public class PreferredNetworkModePreferenceController extends BasePreferenceCont
&& carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL); && carrierConfig.getBoolean(CarrierConfigManager.KEY_SHOW_CDMA_CHOICES_BOOL);
} }
@Override
public void onStart(@NonNull LifecycleOwner owner) {
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
if (mSatelliteManager != null) {
try {
mSatelliteManager.registerForModemStateChanged(
mContext.getMainExecutor(), mSatelliteModemStateCallback);
mSatelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
mContext.getMainExecutor(),
mSelectedNbIotSatelliteSubscriptionCallback);
} catch (IllegalStateException e) {
Log.w(TAG, "IllegalStateException : " + e);
}
}
}
}
@Override
public void onStop(@NonNull LifecycleOwner owner) {
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
if (mSatelliteManager != null) {
try {
mSatelliteManager.unregisterForModemStateChanged(mSatelliteModemStateCallback);
mSatelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
mSelectedNbIotSatelliteSubscriptionCallback);
} catch (IllegalStateException e) {
Log.w(TAG, "IllegalStateException : " + e);
}
}
}
}
private int getPreferredNetworkMode() { private int getPreferredNetworkMode() {
if (mTelephonyManager == null) { if (mTelephonyManager == null) {
Log.w(TAG, "TelephonyManager is null"); Log.w(TAG, "TelephonyManager is null");

View File

@@ -56,20 +56,26 @@ import java.util.Set;
/** Handle Satellite Setting Preference Layout. */ /** Handle Satellite Setting Preference Layout. */
public class SatelliteSetting extends RestrictedDashboardFragment { public class SatelliteSetting extends RestrictedDashboardFragment {
private static final String TAG = "SatelliteSetting"; private static final String TAG = "SatelliteSetting";
public static final String PREF_KEY_ABOUT_SATELLITE_MESSAGING = "key_about_satellite_messaging"; private static final String PREF_KEY_ABOUT_SATELLITE_MESSAGING =
public static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN = "key_about_satellite_messaging";
private static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
"key_category_your_satellite_plan"; "key_category_your_satellite_plan";
public static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan"; private static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
public static final String PREF_KEY_CATEGORY_HOW_IT_WORKS = "key_category_how_it_works"; private static final String PREF_KEY_CATEGORY_HOW_IT_WORKS = "key_category_how_it_works";
private static final String PREF_KEY_YOUR_SATELLITE_DATA_PLAN = "key_your_satellite_data_plan";
private static final String PREF_KEY_CATEGORY_ABOUT_SATELLITE = "key_category_about_satellite";
private static final String KEY_FOOTER_PREFERENCE = "satellite_setting_extra_info_footer_pref"; private static final String KEY_FOOTER_PREFERENCE = "satellite_setting_extra_info_footer_pref";
public static final String SUB_ID = "sub_id";
static final String SUB_ID = "sub_id";
static final String EXTRA_IS_SERVICE_DATA_TYPE = "is_service_data_type";
private Activity mActivity; private Activity mActivity;
private TelephonyManager mTelephonymanager;
private CarrierConfigManager mCarrierConfigManager; private CarrierConfigManager mCarrierConfigManager;
private SatelliteManager mSatelliteManager; private SatelliteManager mSatelliteManager;
private PersistableBundle mConfigBundle; private PersistableBundle mConfigBundle;
private int mSubId; private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private String mSimOperatorName = "";
private boolean mIsServiceDataType = false;
public SatelliteSetting() { public SatelliteSetting() {
super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS); super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
@@ -111,13 +117,19 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
return; return;
} }
mTelephonymanager = mActivity.getSystemService(TelephonyManager.class); mIsServiceDataType = getIntent().getBooleanExtra(EXTRA_IS_SERVICE_DATA_TYPE, false);
mSimOperatorName = getSystemService(TelephonyManager.class).getSimOperatorName(mSubId);
} }
@Override @Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState); super.onViewCreated(view, savedInstanceState);
updateDynamicPreferenceViews(); boolean isSatelliteEligible = isSatelliteEligible();
updateTitle();
updateAboutSatelliteContent();
updateMobilePlan(isSatelliteEligible);
updateHowItWorksContent(isSatelliteEligible);
updateFooterContent();
} }
@Override @Override
@@ -130,31 +142,45 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
return R.xml.satellite_setting; return R.xml.satellite_setting;
} }
private void updateDynamicPreferenceViews() { private void updateTitle() {
String operatorName = mTelephonymanager.getSimOperatorName(mSubId); getActivity().setTitle(getSubjectString());
boolean isSatelliteEligible = isSatelliteEligible(); }
// About satellite content
private void updateAboutSatelliteContent() {
Preference categoryTitle = findPreference(PREF_KEY_CATEGORY_ABOUT_SATELLITE);
categoryTitle.setTitle(
getString(R.string.category_name_about_satellite_messaging,
getDescriptionString()));
// About satellite messaging
Preference preference = findPreference(PREF_KEY_ABOUT_SATELLITE_MESSAGING); Preference preference = findPreference(PREF_KEY_ABOUT_SATELLITE_MESSAGING);
preference.setTitle( preference.setTitle(
getResources().getString(R.string.title_about_satellite_setting, operatorName)); getResources().getString(R.string.title_about_satellite_setting, mSimOperatorName));
}
private void updateMobilePlan(boolean isSatelliteEligible) {
// Your mobile plan // Your mobile plan
PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN); PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan, prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan,
operatorName)); mSimOperatorName));
Preference messagingPreference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
preference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN); Drawable icon = getContext().getDrawable(R.drawable.ic_check_circle_24px);
Drawable icon;
if (isSatelliteEligible) { if (isSatelliteEligible) {
/* In case satellite is allowed by carrier's entitlement server, the page will show /* In case satellite is allowed by carrier's entitlement server, the page will show
the check icon with guidance that satellite is included in user's mobile plan */ the check icon with guidance that satellite is included in user's mobile plan */
preference.setTitle(R.string.title_have_satellite_plan); messagingPreference.setTitle(R.string.title_have_satellite_plan);
icon = getContext().getDrawable(R.drawable.ic_check_circle_24px); if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
Preference connectivityPreference = findPreference(
PREF_KEY_YOUR_SATELLITE_DATA_PLAN);
connectivityPreference.setTitle(R.string.title_have_satellite_data_plan);
connectivityPreference.setIcon(icon);
connectivityPreference.setVisible(true);
}
} else { } else {
/* Or, it will show the blocked icon with the guidance that satellite is not included /* Or, it will show the blocked icon with the guidance that satellite is not included
in user's mobile plan */ in user's mobile plan */
preference.setTitle(R.string.title_no_satellite_plan); messagingPreference.setTitle(R.string.title_no_satellite_plan);
/* And, the link url provides more information via web page will be shown */ /* And, the link url provides more information via web page will be shown */
SpannableString spannable = new SpannableString( SpannableString spannable = new SpannableString(
getResources().getString(R.string.summary_add_satellite_setting)); getResources().getString(R.string.summary_add_satellite_setting));
@@ -162,9 +188,9 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
Spanned.SPAN_INCLUSIVE_INCLUSIVE); Spanned.SPAN_INCLUSIVE_INCLUSIVE);
spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(), spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(),
Spanned.SPAN_INCLUSIVE_INCLUSIVE); Spanned.SPAN_INCLUSIVE_INCLUSIVE);
preference.setSummary(spannable); messagingPreference.setSummary(spannable);
/* The link will lead users to a guide page */ /* The link will lead users to a guide page */
preference.setOnPreferenceClickListener(pref -> { messagingPreference.setOnPreferenceClickListener(pref -> {
String url = readSatelliteMoreInfoString(mSubId); String url = readSatelliteMoreInfoString(mSubId);
if (!url.isEmpty()) { if (!url.isEmpty()) {
Uri uri = Uri.parse(url); Uri uri = Uri.parse(url);
@@ -173,11 +199,13 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
} }
return true; return true;
}); });
icon = getResources().getDrawable(R.drawable.ic_block_24px); icon = getResources().getDrawable(R.drawable.ic_block_24px, null);
} }
icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary)); icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary));
preference.setIcon(icon); messagingPreference.setIcon(icon);
}
private void updateHowItWorksContent(boolean isSatelliteEligible) {
/* Composes "How it works" section, which guides how users can use satellite messaging, when /* Composes "How it works" section, which guides how users can use satellite messaging, when
satellite messaging is included in user's mobile plan, or it'll will be grey out. */ satellite messaging is included in user's mobile plan, or it'll will be grey out. */
if (!isSatelliteEligible) { if (!isSatelliteEligible) {
@@ -185,13 +213,15 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
category.setEnabled(false); category.setEnabled(false);
category.setShouldDisableView(true); category.setShouldDisableView(true);
} }
}
private void updateFooterContent() {
// More about satellite messaging // More about satellite messaging
FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE); FooterPreference footerPreference = findPreference(KEY_FOOTER_PREFERENCE);
if (footerPreference != null) { if (footerPreference != null) {
footerPreference.setSummary( footerPreference.setSummary(
getResources().getString(R.string.satellite_setting_summary_more_information, getResources().getString(R.string.satellite_setting_summary_more_information,
operatorName)); getSubjectString(), mSimOperatorName));
final String[] link = new String[1]; final String[] link = new String[1];
link[0] = readSatelliteMoreInfoString(mSubId); link[0] = readSatelliteMoreInfoString(mSubId);
@@ -205,8 +235,9 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
} }
} }
}); });
footerPreference.setLearnMoreText( footerPreference.setLearnMoreText(
getResources().getString(R.string.more_about_satellite_messaging)); getString(R.string.more_about_satellite_messaging, getDescriptionString()));
} }
} }
} }
@@ -245,6 +276,32 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
return bundle.getBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false); return bundle.getBoolean(KEY_SATELLITE_ATTACH_SUPPORTED_BOOL, false);
} }
// This is for a word which first letter is uppercase. e.g. Satellite messaging.
private String getSubjectString() {
int result;
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
result = mIsServiceDataType
? R.string.title_satellite_setting_connectivity
: R.string.satellite_setting_title;
} else {
result = R.string.satellite_setting_title;
}
return getString(result);
}
// This is for a word without uppercase letter. e.g. satellite messaging.
private String getDescriptionString() {
int result;
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
result = mIsServiceDataType
? R.string.description_satellite_setting_connectivity
: R.string.description_satellite_setting_messaging;
} else {
result = R.string.satellite_setting_title;
}
return getString(result);
}
private static void loge(String message) { private static void loge(String message) {
Log.e(TAG, message); Log.e(TAG, message);
} }

View File

@@ -16,16 +16,25 @@
package com.android.settings.network.telephony; package com.android.settings.network.telephony;
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.provider.Settings; import android.provider.Settings;
import android.telephony.CarrierConfigManager; import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.satellite.NtnSignalStrength;
import android.telephony.satellite.SatelliteManager; import android.telephony.satellite.SatelliteManager;
import android.util.Log; import android.util.Log;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -33,28 +42,34 @@ import com.android.internal.telephony.flags.Flags;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.network.CarrierConfigCache; import com.android.settings.network.CarrierConfigCache;
import com.android.settingslib.core.lifecycle.LifecycleObserver;
import com.android.settingslib.core.lifecycle.events.OnStart;
import com.android.settingslib.core.lifecycle.events.OnStop;
import java.util.Arrays;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Preference controller for "Satellite Setting" * Preference controller for "Satellite Setting"
*/ */
public class SatelliteSettingPreferenceController extends public class SatelliteSettingPreferenceController extends
TelephonyBasePreferenceController implements LifecycleObserver, OnStart, OnStop { TelephonyBasePreferenceController implements DefaultLifecycleObserver {
private static final String TAG = "SatelliteSettingPreferenceController"; private static final String TAG = "SatelliteSettingPreferenceController";
CarrierConfigCache mCarrierConfigCache; CarrierConfigCache mCarrierConfigCache;
SatelliteManager mSatelliteManager; SatelliteManager mSatelliteManager;
@Nullable private Boolean mIsSatelliteEligible = null; private TelephonyManager mTelephonyManager = null;
@VisibleForTesting
final CarrierRoamingNtnModeCallback mCarrierRoamingNtnModeCallback =
new CarrierRoamingNtnModeCallback();
@Nullable
private Boolean mIsSatelliteEligible = null;
private boolean mIsServiceDataType = false;
public SatelliteSettingPreferenceController(@NonNull Context context, @NonNull String key) { public SatelliteSettingPreferenceController(@NonNull Context context, @NonNull String key) {
super(context, key); super(context, key);
mCarrierConfigCache = CarrierConfigCache.getInstance(context); mCarrierConfigCache = CarrierConfigCache.getInstance(context);
mSatelliteManager = context.getSystemService(SatelliteManager.class); mSatelliteManager = context.getSystemService(SatelliteManager.class);
mTelephonyManager = context.getSystemService(TelephonyManager.class);
} }
@Override @Override
@@ -76,11 +91,18 @@ public class SatelliteSettingPreferenceController extends
} }
@Override @Override
public void onStart() { public void onResume(@NonNull LifecycleOwner owner) {
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
mCarrierRoamingNtnModeCallback);
}
} }
@Override @Override
public void onStop() { public void onPause(@NonNull LifecycleOwner owner) {
if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
mTelephonyManager.unregisterTelephonyCallback(mCarrierRoamingNtnModeCallback);
}
} }
@Override @Override
@@ -93,6 +115,7 @@ public class SatelliteSettingPreferenceController extends
public void updateState(@Nullable Preference preference) { public void updateState(@Nullable Preference preference) {
super.updateState(preference); super.updateState(preference);
if (preference != null) { if (preference != null) {
mCarrierRoamingNtnModeCallback.mPref = preference;
updateSummary(preference); updateSummary(preference);
} }
} }
@@ -106,6 +129,7 @@ public class SatelliteSettingPreferenceController extends
// This will setup the Home and Search affordance // This will setup the Home and Search affordance
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true); intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_AS_SUBSETTING, true);
intent.putExtra(SatelliteSetting.SUB_ID, mSubId); intent.putExtra(SatelliteSetting.SUB_ID, mSubId);
intent.putExtra(SatelliteSetting.EXTRA_IS_SERVICE_DATA_TYPE, mIsServiceDataType);
mContext.startActivity(intent); mContext.startActivity(intent);
return true; return true;
} }
@@ -115,14 +139,20 @@ public class SatelliteSettingPreferenceController extends
/** /**
* Set subId for Satellite Settings page. * Set subId for Satellite Settings page.
*
* @param subId subscription ID. * @param subId subscription ID.
*/ */
public void init(int subId) { public void init(int subId) {
logd("init(), subId=" + subId); logd("init(), subId=" + subId);
mSubId = subId; mSubId = subId;
mTelephonyManager = mTelephonyManager.createForSubscriptionId(subId);
} }
private void updateSummary(Preference preference) { private void updateSummary(Preference preference) {
if (mSatelliteManager == null) {
logd("updateSummary - no SatelliteManager");
return;
}
try { try {
Set<Integer> restrictionReason = Set<Integer> restrictionReason =
mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId); mSatelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
@@ -148,4 +178,46 @@ public class SatelliteSettingPreferenceController extends
private static void loge(String message) { private static void loge(String message) {
Log.e(TAG, message); Log.e(TAG, message);
} }
@VisibleForTesting
class CarrierRoamingNtnModeCallback extends TelephonyCallback implements
TelephonyCallback.CarrierRoamingNtnModeListener {
Preference mPref = null;
@Override
public void onCarrierRoamingNtnAvailableServicesChanged(int[] availableServices) {
CarrierRoamingNtnModeListener.super.onCarrierRoamingNtnAvailableServicesChanged(
availableServices);
List<Integer> availableServicesList = Arrays.stream(availableServices).boxed().toList();
boolean isSmsAvailable = availableServicesList.contains(SERVICE_TYPE_SMS);
boolean isDataAvailable = availableServicesList.contains(SERVICE_TYPE_DATA);
logd("isSmsAvailable : " + isSmsAvailable
+ " / isDataAvailable " + isDataAvailable);
if (mPref == null) {
logd("Satellite preference is not initialized yet");
return;
}
if (isDataAvailable) {
mIsServiceDataType = true;
mPref.setTitle(R.string.title_satellite_setting_connectivity);
} else if (isSmsAvailable) {
mPref.setTitle(R.string.satellite_setting_title);
}
}
@Override
public void onCarrierRoamingNtnEligibleStateChanged(boolean eligible) {
// Do nothing
}
@Override
public void onCarrierRoamingNtnModeChanged(boolean active) {
// Do nothing
}
@Override
public void onCarrierRoamingNtnSignalStrengthChanged(NtnSignalStrength ntnSignalStrength) {
// Do nothing
}
}
} }

View File

@@ -33,6 +33,7 @@ import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.flags.Flags;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -87,14 +88,18 @@ public class SatelliteSettingsPreferenceCategoryController
@Override @Override
public void onResume(@NonNull LifecycleOwner owner) { public void onResume(@NonNull LifecycleOwner owner) {
if (Flags.satelliteOemSettingsUxMigration()) {
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
mCarrierRoamingNtnModeCallback); mCarrierRoamingNtnModeCallback);
} }
}
@Override @Override
public void onPause(@NonNull LifecycleOwner owner) { public void onPause(@NonNull LifecycleOwner owner) {
if (Flags.satelliteOemSettingsUxMigration()) {
mTelephonyManager.unregisterTelephonyCallback(mCarrierRoamingNtnModeCallback); mTelephonyManager.unregisterTelephonyCallback(mCarrierRoamingNtnModeCallback);
} }
}
@VisibleForTesting @VisibleForTesting
class CarrierRoamingNtnModeCallback extends TelephonyCallback implements class CarrierRoamingNtnModeCallback extends TelephonyCallback implements

View File

@@ -25,18 +25,22 @@ import android.telephony.CarrierConfigManager
import android.telephony.ServiceState import android.telephony.ServiceState
import android.telephony.SubscriptionManager import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.telephony.satellite.SatelliteManager
import android.telephony.satellite.SatelliteModemStateCallback
import android.telephony.satellite.SelectedNbIotSatelliteSubscriptionCallback
import android.util.Log
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.preference.Preference
import androidx.preference.PreferenceScreen
import com.android.settings.R import com.android.settings.R
import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.Settings.NetworkSelectActivity
import com.android.settings.flags.Flags
import com.android.settings.network.CarrierConfigCache import com.android.settings.network.CarrierConfigCache
import com.android.settings.network.telephony.MobileNetworkUtils import com.android.settings.network.telephony.MobileNetworkUtils
import com.android.settings.network.telephony.allowedNetworkTypesFlow import com.android.settings.network.telephony.allowedNetworkTypesFlow
@@ -46,8 +50,6 @@ import com.android.settingslib.spa.framework.compose.OverridableFlow
import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle import com.android.settingslib.spa.framework.util.collectLatestWithLifecycle
import com.android.settingslib.spa.widget.preference.SwitchPreference import com.android.settingslib.spa.widget.preference.SwitchPreference
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
import kotlin.properties.Delegates.notNull
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -59,6 +61,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlin.time.Duration.Companion.seconds
/** /**
* Preference controller for "Auto Select Network" * Preference controller for "Auto Select Network"
@@ -73,9 +76,13 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
private val getConfigForSubId: (subId: Int) -> PersistableBundle = { subId -> private val getConfigForSubId: (subId: Int) -> PersistableBundle = { subId ->
CarrierConfigCache.getInstance(context).getConfigForSubId(subId) CarrierConfigCache.getInstance(context).getConfigForSubId(subId)
}, },
) : ComposePreferenceController(context, key) { ) : ComposePreferenceController(context, key), DefaultLifecycleObserver {
private var isSatelliteSessionStarted = false
private var isSelectedSubIdForSatellite = false
private lateinit var telephonyManager: TelephonyManager private lateinit var telephonyManager: TelephonyManager
private lateinit var satelliteManager: SatelliteManager
private val listeners = mutableListOf<OnNetworkSelectModeListener>() private val listeners = mutableListOf<OnNetworkSelectModeListener>()
@VisibleForTesting @VisibleForTesting
@@ -83,6 +90,21 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID private var subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID
val satelliteModemStateCallback = SatelliteModemStateCallback { state ->
isSatelliteSessionStarted = when (state) {
SatelliteManager.SATELLITE_MODEM_STATE_OFF,
SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE,
SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN -> false
else -> true
}
}
val selectedNbIotSatelliteSubscriptionCallback =
SelectedNbIotSatelliteSubscriptionCallback { selectedSubId ->
isSelectedSubIdForSatellite = selectedSubId == subId
}
/** /**
* Initialization based on given subscription id. * Initialization based on given subscription id.
*/ */
@@ -90,7 +112,7 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
this.subId = subId this.subId = subId
telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!! telephonyManager = mContext.getSystemService(TelephonyManager::class.java)!!
.createForSubscriptionId(subId) .createForSubscriptionId(subId)
satelliteManager = mContext.getSystemService(SatelliteManager::class.java)!!
return this return this
} }
@@ -117,7 +139,10 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
SwitchPreference(object : SwitchPreferenceModel { SwitchPreference(object : SwitchPreferenceModel {
override val title = stringResource(R.string.select_automatically) override val title = stringResource(R.string.select_automatically)
override val summary = { disallowedSummary } override val summary = { disallowedSummary }
override val changeable = { disallowedSummary.isEmpty() } override val changeable = {
disallowedSummary.isEmpty()
&& !(isSatelliteSessionStarted && isSelectedSubIdForSatellite)
}
override val checked = { isAuto } override val checked = { isAuto }
override val onCheckedChange: (Boolean) -> Unit = { newChecked -> override val onCheckedChange: (Boolean) -> Unit = { newChecked ->
if (newChecked) { if (newChecked) {
@@ -132,6 +157,38 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
}) })
} }
override fun onStart(owner: LifecycleOwner) {
if (Flags.satelliteOemSettingsUxMigration()) {
if (satelliteManager != null) {
try {
satelliteManager.registerForModemStateChanged(
mContext.mainExecutor, satelliteModemStateCallback
)
satelliteManager.registerForSelectedNbIotSatelliteSubscriptionChanged(
mContext.mainExecutor, selectedNbIotSatelliteSubscriptionCallback
)
} catch (e: IllegalStateException) {
Log.w(TAG, "IllegalStateException $e")
}
}
}
}
override fun onStop(owner: LifecycleOwner) {
if (Flags.satelliteOemSettingsUxMigration()) {
if (satelliteManager != null) {
try {
satelliteManager.unregisterForModemStateChanged(satelliteModemStateCallback)
satelliteManager.unregisterForSelectedNbIotSatelliteSubscriptionChanged(
selectedNbIotSatelliteSubscriptionCallback
)
} catch (e: IllegalStateException) {
Log.w(TAG, "IllegalStateException $e")
}
}
}
}
private suspend fun getDisallowedSummary(serviceState: ServiceState): String = private suspend fun getDisallowedSummary(serviceState: ServiceState): String =
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
if (!serviceState.roaming && onlyAutoSelectInHome()) { if (!serviceState.roaming && onlyAutoSelectInHome()) {
@@ -213,6 +270,8 @@ class AutoSelectPreferenceController @JvmOverloads constructor(
} }
companion object { companion object {
private const val TAG = "AutoSelectPreferenceController"
private val MINIMUM_DIALOG_TIME = 1.seconds private val MINIMUM_DIALOG_TIME = 1.seconds
} }
} }

View File

@@ -18,10 +18,12 @@ package com.android.settings.network.telephony.gsm
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.platform.test.annotations.EnableFlags
import android.provider.Settings import android.provider.Settings
import android.telephony.CarrierConfigManager import android.telephony.CarrierConfigManager
import android.telephony.ServiceState import android.telephony.ServiceState
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import android.telephony.satellite.SatelliteManager
import androidx.compose.ui.test.assertIsEnabled import androidx.compose.ui.test.assertIsEnabled
import androidx.compose.ui.test.assertIsNotEnabled import androidx.compose.ui.test.assertIsNotEnabled
import androidx.compose.ui.test.assertIsOff import androidx.compose.ui.test.assertIsOff
@@ -36,6 +38,7 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.R import com.android.settings.R
import com.android.settings.Settings.NetworkSelectActivity import com.android.settings.Settings.NetworkSelectActivity
import com.android.settings.flags.Flags
import com.android.settings.spa.preference.ComposePreference import com.android.settings.spa.preference.ComposePreference
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@@ -46,6 +49,8 @@ import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.mockito.junit.MockitoJUnit
import org.mockito.kotlin.any import org.mockito.kotlin.any
import org.mockito.kotlin.argumentCaptor import org.mockito.kotlin.argumentCaptor
import org.mockito.kotlin.doNothing import org.mockito.kotlin.doNothing
@@ -57,6 +62,9 @@ import org.mockito.kotlin.whenever
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class AutoSelectPreferenceControllerTest { class AutoSelectPreferenceControllerTest {
@get:Rule
val mockito = MockitoJUnit.rule()
@get:Rule @get:Rule
val composeTestRule = createComposeRule() val composeTestRule = createComposeRule()
@@ -65,8 +73,12 @@ class AutoSelectPreferenceControllerTest {
on { simOperatorName } doReturn OPERATOR_NAME on { simOperatorName } doReturn OPERATOR_NAME
} }
private val mockSatelliteManager = mock<SatelliteManager> {
}
private val context: Context = spy(ApplicationProvider.getApplicationContext()) { private val context: Context = spy(ApplicationProvider.getApplicationContext()) {
on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager on { getSystemService(TelephonyManager::class.java) } doReturn mockTelephonyManager
on { getSystemService(SatelliteManager::class.java) } doReturn mockSatelliteManager
doNothing().whenever(mock).startActivity(any()) doNothing().whenever(mock).startActivity(any())
} }
@@ -115,7 +127,6 @@ class AutoSelectPreferenceControllerTest {
.assertIsOff() .assertIsOff()
} }
@Test @Test
fun isEnabled_isRoaming_enabled() { fun isEnabled_isRoaming_enabled() {
serviceState.roaming = true serviceState.roaming = true
@@ -158,6 +169,54 @@ class AutoSelectPreferenceControllerTest {
.assertIsNotEnabled() .assertIsNotEnabled()
} }
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
fun isEnabled_isSatelliteSessionStartedAndSelectedSubForSatellite_disabled() {
controller.selectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID)
controller.satelliteModemStateCallback
.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
composeTestRule.setContent {
controller.Content()
}
composeTestRule.onNodeWithText(context.getString(R.string.select_automatically))
.assertIsNotEnabled()
}
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
fun isEnabled_isSatelliteSessionNotStartedButIsSelectedSubForSatellite_enabled() {
controller.selectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID)
controller.satelliteModemStateCallback
.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_OFF)
composeTestRule.setContent {
controller.Content()
}
composeTestRule.onNodeWithText(context.getString(R.string.select_automatically))
.assertIsEnabled()
}
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
fun isEnabled_isSatelliteSessionStartedButNotSelectedSubForSatellite_enabled() {
controller.selectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(0)
controller.satelliteModemStateCallback
.onSatelliteModemStateChanged(SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED)
composeTestRule.setContent {
controller.Content()
}
composeTestRule.onNodeWithText(context.getString(R.string.select_automatically))
.assertIsEnabled()
}
@Test @Test
fun onClick_turnOff_startNetworkSelectActivity() { fun onClick_turnOff_startNetworkSelectActivity() {
serviceState.isManualSelection = false serviceState.isManualSelection = false

View File

@@ -71,6 +71,7 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
private ExternalDisplayPreferenceFragment mFragment; private ExternalDisplayPreferenceFragment mFragment;
private int mPreferenceIdFromResource; private int mPreferenceIdFromResource;
private int mDisplayIdArg = INVALID_DISPLAY; private int mDisplayIdArg = INVALID_DISPLAY;
private boolean mLaunchedBuiltinSettings;
private int mResolutionSelectorDisplayId = INVALID_DISPLAY; private int mResolutionSelectorDisplayId = INVALID_DISPLAY;
@Mock @Mock
private MetricsLogger mMockedMetricsLogger; private MetricsLogger mMockedMetricsLogger;
@@ -106,6 +107,10 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY); pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY);
assertThat(pref).isNull(); assertThat(pref).isNull();
pref = mPreferenceScreen.findPreference(
ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY);
assertThat(pref).isNull();
} }
@Test @Test
@@ -124,6 +129,11 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY); mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY);
assertThat(listPref).isNotNull(); assertThat(listPref).isNotNull();
assertThat(listPref.getPreferenceCount()).isEqualTo(1); assertThat(listPref.getPreferenceCount()).isEqualTo(1);
listPref = mPreferenceScreen.findPreference(
ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY);
assertThat(listPref).isNotNull();
assertThat(listPref.getPreferenceCount()).isEqualTo(1);
} }
@Test @Test
@@ -138,11 +148,18 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
var pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY); var pref = mPreferenceScreen.findPreference(DisplayTopologyKt.PREFERENCE_KEY);
assertThat(pref).isNotNull(); assertThat(pref).isNotNull();
// TODO: add the built-in display to the list, which will cause this preference to not be
// null.
PreferenceCategory listPref = PreferenceCategory listPref =
mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY); mPreferenceScreen.findPreference(DISPLAYS_LIST_PREFERENCE_KEY);
assertThat(listPref).isNull(); assertThat(listPref).isNull();
listPref = mPreferenceScreen.findPreference(
ExternalDisplayPreferenceFragment.BUILTIN_DISPLAY_LIST_PREFERENCE_KEY);
assertThat(listPref).isNotNull();
assertThat(listPref.getPreferenceCount()).isEqualTo(1);
var builtinPref = listPref.getPreference(0);
assertThat(builtinPref.getOnPreferenceClickListener().onPreferenceClick(builtinPref))
.isTrue();
assertThat(mLaunchedBuiltinSettings).isTrue();
} }
@Test @Test
@@ -428,10 +445,15 @@ public class ExternalDisplayPreferenceFragmentTest extends ExternalDisplayTestBa
} }
@Override @Override
protected void launchDisplaySettings(final int displayId) { protected void launchExternalDisplaySettings(final int displayId) {
mDisplayIdArg = displayId; mDisplayIdArg = displayId;
} }
@Override
protected void launchBuiltinDisplaySettings() {
mLaunchedBuiltinSettings = true;
}
@Override @Override
protected void writePreferenceClickMetric(Preference preference) { protected void writePreferenceClickMetric(Preference preference) {
mLogger.writePreferenceClickMetric(preference); mLogger.writePreferenceClickMetric(preference);

View File

@@ -16,6 +16,9 @@
package com.android.settings.network.telephony; package com.android.settings.network.telephony;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;
import static androidx.lifecycle.Lifecycle.Event.ON_START; import static androidx.lifecycle.Lifecycle.Event.ON_START;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA; import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.CDMA;
@@ -29,12 +32,15 @@ import static com.android.settings.network.telephony.TelephonyConstants.RadioAcc
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.platform.test.annotations.EnableFlags;
import android.telephony.CarrierConfigManager; import android.telephony.CarrierConfigManager;
import android.telephony.RadioAccessFamily; import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState; import android.telephony.ServiceState;
@@ -51,6 +57,7 @@ import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.flags.Flags;
import com.android.settings.network.CarrierConfigCache; import com.android.settings.network.CarrierConfigCache;
import com.android.settingslib.core.lifecycle.Lifecycle; import com.android.settingslib.core.lifecycle.Lifecycle;
@@ -294,6 +301,48 @@ public class EnabledNetworkModePreferenceControllerTest {
String.valueOf(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA)); String.valueOf(TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA));
} }
@UiThreadTest
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_satelliteIsStartedAndSelectedSubForSatellite_disablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_CONNECTED);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID);
mController.updateState(mPreference);
assertFalse(mPreference.isEnabled());
}
@UiThreadTest
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_satelliteIsIdle_enablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_OFF);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID);
mController.updateState(mPreference);
assertTrue(mPreference.isEnabled());
}
@UiThreadTest
@Test
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_notSelectedSubForSatellite_enablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_CONNECTED);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(0);
mController.updateState(mPreference);
assertTrue(mPreference.isEnabled());
}
@UiThreadTest @UiThreadTest
@Test @Test
public void onPreferenceChange_updateSuccess() { public void onPreferenceChange_updateSuccess() {

View File

@@ -16,12 +16,17 @@
package com.android.settings.network.telephony; package com.android.settings.network.telephony;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM; import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.GSM;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA; import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.RAF_TD_SCDMA;
import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA; import static com.android.settings.network.telephony.TelephonyConstants.RadioAccessFamily.WCDMA;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times; import static org.mockito.Mockito.times;
@@ -30,15 +35,18 @@ import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.platform.test.annotations.EnableFlags;
import android.telephony.RadioAccessFamily; import android.telephony.RadioAccessFamily;
import android.telephony.ServiceState; import android.telephony.ServiceState;
import android.telephony.SubscriptionManager; import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import androidx.preference.ListPreference; import androidx.preference.ListPreference;
import androidx.test.annotation.UiThreadTest;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.settings.flags.Flags;
import com.android.settings.network.CarrierConfigCache; import com.android.settings.network.CarrierConfigCache;
import com.android.settings.testutils.ResourcesUtils; import com.android.settings.testutils.ResourcesUtils;
@@ -104,6 +112,48 @@ public class PreferredNetworkModePreferenceControllerTest {
"preferred_network_mode_tdscdma_gsm_wcdma_summary")); "preferred_network_mode_tdscdma_gsm_wcdma_summary"));
} }
@Test
@UiThreadTest
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_satelliteIsStartedAndSelectedSubForSatellite_disablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_CONNECTED);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID);
mController.updateState(mPreference);
assertFalse(mPreference.isEnabled());
}
@Test
@UiThreadTest
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_satelliteIsIdle_enablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_OFF);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(SUB_ID);
mController.updateState(mPreference);
assertTrue(mPreference.isEnabled());
}
@Test
@UiThreadTest
@EnableFlags(Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void updateState_notSelectedSubForSatellite_enablePreference() {
mController.mSatelliteModemStateCallback
.onSatelliteModemStateChanged(SATELLITE_MODEM_STATE_CONNECTED);
mController.mSelectedNbIotSatelliteSubscriptionCallback
.onSelectedNbIotSatelliteSubscriptionChanged(0);
mController.updateState(mPreference);
assertTrue(mPreference.isEnabled());
}
@Test @Test
public void onPreferenceChange_updateNetworkMode() { public void onPreferenceChange_updateNetworkMode() {
mController.onPreferenceChange(mPreference, mController.onPreferenceChange(mPreference,

View File

@@ -114,7 +114,7 @@ public class SatelliteSettingsPreferenceCategoryControllerTest {
new int[]{SERVICE_TYPE_DATA}); new int[]{SERVICE_TYPE_DATA});
assertThat(preferenceCategory.getTitle()).isEqualTo( assertThat(preferenceCategory.getTitle()).isEqualTo(
mContext.getString(R.string.satellite_setting_connectivity)); mContext.getString(R.string.title_satellite_setting_connectivity));
} }

View File

@@ -0,0 +1,177 @@
/*
* 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.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.os.PersistableBundle;
import android.platform.test.annotations.EnableFlags;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.telephony.satellite.SatelliteManager;
import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.android.internal.telephony.flags.Flags;
import com.android.settings.R;
import com.android.settings.network.CarrierConfigCache;
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;
@RunWith(AndroidJUnit4.class)
public class SatelliteSettingsPreferenceControllerTest {
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;
@Mock
private TelephonyManager mTelephonyManager;
private Context mContext = null;
private SatelliteManager mSatelliteManager;
private SatelliteSettingPreferenceController mController = null;
private PersistableBundle mCarrierConfig = new PersistableBundle();
@Before
public void setUp() {
if (Looper.myLooper() == null) {
Looper.prepare();
}
mContext = spy(ApplicationProvider.getApplicationContext());
mSatelliteManager = new SatelliteManager(mContext);
CarrierConfigCache.setTestInstance(mContext, mCarrierConfigCache);
when(mContext.getSystemService(SatelliteManager.class)).thenReturn(mSatelliteManager);
when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
when(mTelephonyManager.createForSubscriptionId(TEST_SUB_ID)).thenReturn(mTelephonyManager);
mController = spy(new SatelliteSettingPreferenceController(mContext, KEY));
}
@Test
@EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void getAvailabilityStatus_noSatellite_returnUnsupport() {
when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
mController = new SatelliteSettingPreferenceController(mContext, KEY);
int result = mController.getAvailabilityStatus(TEST_SUB_ID);
assertThat(result).isEqualTo(UNSUPPORTED_ON_DEVICE);
}
@Test
@EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void getAvailabilityStatus_carrierIsNotSupport_returnUnavailable() {
when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
mCarrierConfig.putBoolean(
CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
false);
when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig);
int result = mController.getAvailabilityStatus(TEST_SUB_ID);
assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE);
}
@Test
@EnableFlags(Flags.FLAG_CARRIER_ENABLED_SATELLITE_FLAG)
public void getAvailabilityStatus_carrierIsSupport_returnAvailable() {
when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
mCarrierConfig.putBoolean(
CarrierConfigManager.KEY_SATELLITE_ATTACH_SUPPORTED_BOOL,
true);
when(mCarrierConfigCache.getConfigForSubId(TEST_SUB_ID)).thenReturn(mCarrierConfig);
int result = mController.getAvailabilityStatus(TEST_SUB_ID);
assertThat(result).isEqualTo(AVAILABLE);
}
@Test
@EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void getAvailabilityStatus_registerTelephonyCallback_success() {
mController.init(TEST_SUB_ID);
mController.onResume(null);
verify(mTelephonyManager).registerTelephonyCallback(any(), any());
}
@Test
@EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void getAvailabilityStatus_unregisterTelephonyCallback_success() {
mController.init(TEST_SUB_ID);
mController.onPause(null);
verify(mTelephonyManager).unregisterTelephonyCallback(any());
}
@Test
@EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void getAvailabilityStatus_hasServiceDataType_showDataUi() {
mController.init(TEST_SUB_ID);
Preference preference = new Preference(mContext);
preference.setKey(KEY);
preference.setTitle("test title");
mController.updateState(preference);
mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged(
new int[]{SERVICE_TYPE_SMS, SERVICE_TYPE_DATA});
assertThat(preference.getTitle()).isEqualTo(
mContext.getString(R.string.title_satellite_setting_connectivity));
}
@Test
@EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
public void getAvailabilityStatus_onlyHasServiceSmsType_showSmsUi() {
mController.init(TEST_SUB_ID);
Preference preference = new Preference(mContext);
preference.setKey(KEY);
preference.setTitle("test title");
mController.updateState(preference);
mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged(
new int[]{SERVICE_TYPE_SMS});
assertThat(preference.getTitle()).isEqualTo(
mContext.getString(R.string.satellite_setting_title));
}
}