Merge "[Audiosharing] Use metadata from callback to add source" into main
diff --git a/res/layout/accessibility_text_reading_preview.xml b/res/layout/accessibility_text_reading_preview.xml
index 2532a79..252736e 100644
--- a/res/layout/accessibility_text_reading_preview.xml
+++ b/res/layout/accessibility_text_reading_preview.xml
@@ -46,7 +46,6 @@
                 android:id="@+id/preview_pager"
                 android:layout_width="wrap_content"
                 android:layout_height="217dp"
-                android:contentDescription="@string/preview_pager_content_description"
                 android:nestedScrollingEnabled="true" />
             <LinearLayout
                 android:layout_width="match_parent"
diff --git a/res/layout/accessibility_text_reading_preview_app_grid.xml b/res/layout/accessibility_text_reading_preview_app_grid.xml
index 979c053..52fc574 100644
--- a/res/layout/accessibility_text_reading_preview_app_grid.xml
+++ b/res/layout/accessibility_text_reading_preview_app_grid.xml
@@ -14,14 +14,19 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-
-<com.android.settings.display.AppGridView
+<FrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:numColumns="3"
-    android:gravity="center"
-    android:nestedScrollingEnabled="true"
-    android:importantForAccessibility="noHideDescendants"
-    app:appCount="6"/>
+    android:contentDescription="@string/preview_pager_home_content_description" >
+    <com.android.settings.display.AppGridView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:numColumns="3"
+        android:gravity="center"
+        android:nestedScrollingEnabled="true"
+        android:importantForAccessibility="noHideDescendants"
+        app:appCount="6"/>
+</FrameLayout>
diff --git a/res/layout/accessibility_text_reading_preview_mail_content.xml b/res/layout/accessibility_text_reading_preview_mail_content.xml
index e55d389..db5ee7d 100644
--- a/res/layout/accessibility_text_reading_preview_mail_content.xml
+++ b/res/layout/accessibility_text_reading_preview_mail_content.xml
@@ -14,18 +14,18 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-
 <androidx.core.widget.NestedScrollView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
-    android:importantForAccessibility="noHideDescendants">
+    android:contentDescription="@string/preview_pager_email_content_description">
 
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:orientation="vertical">
+        android:orientation="vertical"
+        android:importantForAccessibility="noHideDescendants">
 
         <TextView
             android:id="@+id/subject"
diff --git a/res/layout/screen_zoom_preview_1.xml b/res/layout/screen_zoom_preview_1.xml
index 97e0863..6e5bff9 100644
--- a/res/layout/screen_zoom_preview_1.xml
+++ b/res/layout/screen_zoom_preview_1.xml
@@ -19,12 +19,13 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:fillViewport="true"
-    android:importantForAccessibility="noHideDescendants">
+    android:contentDescription="@string/preview_pager_message_content_description">
 
     <view class="com.android.settings.TouchBlockingFrameLayout"
         android:id="@+id/frame"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        android:importantForAccessibility="noHideDescendants">
 
         <LinearLayout
             android:layout_width="match_parent"
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 9c9a29c..af7b132 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -84,8 +84,6 @@
     <color name="homepage_location_background">@color/homepage_cyan_bg</color>
     <color name="homepage_accounts_foreground">@color/homepage_cyan_fg</color>
     <color name="homepage_accounts_background">@color/homepage_cyan_bg</color>
-    <color name="homepage_wellbeing_foreground">@color/homepage_cyan_fg</color>
-    <color name="homepage_wellbeing_background">@color/homepage_cyan_bg</color>
     <color name="homepage_supervision_foreground">@color/homepage_cyan_fg</color>
     <color name="homepage_supervision_background">@color/homepage_cyan_bg</color>
     <color name="homepage_safety_foreground">@color/homepage_red_fg</color>
diff --git a/res/values/config.xml b/res/values/config.xml
index ea16af4..4b38044 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -810,23 +810,13 @@
     <!-- Allowed packages to show the confirmation dialog for a system locale suggestion  -->
     <string-array name="allowed_packages_for_locale_confirmation_diallog" translatable="false"/>
 
-    <!-- Array of text reading preview layouts. Must contain at least 1 layout.
-        Add content descriptions in the config_text_reading_preview_content_descriptions together
-        if adding more sample layouts here -->
+    <!-- Array of text reading preview layouts. Must contain at least 1 layout -->
     <array name="config_text_reading_preview_samples">
         <item>@layout/accessibility_text_reading_preview_app_grid</item>
         <item>@layout/screen_zoom_preview_1</item>
         <item>@layout/accessibility_text_reading_preview_mail_content</item>
     </array>
 
-    <!-- Array of text reading preview layouts' content descriptions.
-        The order should be the same as the layouts in config_text_reading_preview_samples -->
-    <array name="config_text_reading_preview_content_descriptions">
-        <item>@string/preview_pager_home_content_description</item>
-        <item>@string/preview_pager_message_content_description</item>
-        <item>@string/preview_pager_email_content_description</item>
-    </array>
-
     <!-- Package responsible for updating Mainline Modules -->
     <string name="config_mainline_module_update_package" translatable="false">com.android.vending</string>
 
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 28e3ba6..6d865c2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -3695,10 +3695,6 @@
     <!-- Summary for when to automatically show hub mode (widgets on lockscreen): docked  [CHAR LIMIT=100] -->
     <string name="when_to_show_hubmode_docked">While docked</string>
 
-    <!-- _satellite_setting_preference_layout -->
-    <!-- _satellite_setting_preference_layout screen title-->
-    <string name="satellite_setting">Satellite messaging</string>
-
     <!-- APN Settings -->
     <!-- APN settings screen title -->
     <string name="apn_settings">APNs</string>
@@ -10914,7 +10910,7 @@
     <string name="apps_summary"><xliff:g id="count" example="24">%1$d</xliff:g> apps installed</string>
 
     <!-- Summary of storage usage [CHAR LIMIT=NONE] -->
-    <string name="storage_summary"><xliff:g id="percentage" example="54%">%1$s</xliff:g> used - <xliff:g id="free_space" example="32GB">%2$s</xliff:g> free</string>
+    <string name="storage_toplevel_summary"><xliff:g id="percentage" example="54%">%1$s</xliff:g> used - <xliff:g id="free_space" example="32GB">%2$s</xliff:g> free</string>
 
     <!-- Summary for Display settings, explaining a few important settings under it [CHAR LIMIT=NONE]-->
     <string name="display_dashboard_summary">Dark theme, font size, brightness</string>
@@ -12687,8 +12683,10 @@
 
     <!-- Summary to show the current network mode is invalid. [CHAR LIMIT=NONE]-->
     <string name="mobile_network_mode_error">Invalid Network Mode <xliff:g id="networkModeId" example="0">%1$d</xliff:g>. Ignore.</string>
-    <!-- Title for satellite setting preference in mobile network settings [CHAR LIMIT=60] -->
-    <string name="satellite_setting_title">Satellite messaging</string>
+
+    <!-- _satellite_setting_preference_layout -->
+    <!-- _satellite_setting_preference_layout screen title-->
+    <string name="satellite_setting">Satellite connectivity</string>
     <!-- Summary for satellite setting preference. [CHAR LIMIT=NONE]-->
     <string name="satellite_setting_enabled_summary">Send and receive text messages by satellite. Included with your account.</string>
     <!-- Summary for satellite setting preference. [CHAR LIMIT=NONE]-->
@@ -12731,14 +12729,14 @@
     <string name="satellite_setting_summary_more_information">A satellite connection may be slower and is available only in some areas. Weather and certain structures may affect the 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>
     <!-- learn more text - more about satellite messaging without emergency messaging support. [CHAR_LIMIT=NONE] -->
     <string name="satellite_setting_summary_more_information_no_emergency_messaging">A satellite connection may be slower and is available only in some areas. Weather and certain structures may affect the connection. Calling by satellite isn\u2019t available. Emergency calls may still connect. Texting with emergency services may not be available in all areas.\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] -->
-    <string name="more_about_satellite_messaging">More about <xliff:g id="subject" example="satellite messaging">%1$s</xliff:g></string>
+    <!-- more about satellite connectivity [CHAR_LIMIT=NONE] -->
+    <string name="more_about_satellite_messaging">More about satellite connectivity</string>
     <!-- Title for satellite warning dialog to avoid user using wifi/bluetooth/airplane mode [CHAR_LIMIT=NONE] -->
     <string name="satellite_warning_dialog_title">Can’t 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] -->
     <string name="satellite_warning_dialog_content">To turn on <xliff:g id="function" example="bluetooth">%1$s</xliff:g>, first end the satellite connection</string>
     <!-- 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</string>
     <!-- Title for satellite functions with data transmission in mobile network settings [CHAR LIMIT=60] -->
     <string name="title_satellite_setting_connectivity">Satellite connectivity</string>
     <!-- Description of satellite function with data transmission [CHAR LIMIT=60] -->
@@ -14362,6 +14360,16 @@
     <string name="supervision_web_content_filters_browser_block_explicit_sites_summary">No filter is perfect, but this should help hide sexually explicit sites</string>
     <!-- Title for web content filters browser category allow all sites option [CHAR LIMIT=60] -->
     <string name="supervision_web_content_filters_browser_allow_all_sites_title">Allow all sites</string>
+    <!-- Title for web content filters search category [CHAR LIMIT=60] -->
+    <string name="supervision_web_content_filters_search_title">Google Search</string>
+    <!-- Title for web content filters search category filter on option [CHAR LIMIT=60] -->
+    <string name="supervision_web_content_filters_search_filter_on_title">SafeSearch filtering ON</string>
+    <!-- Summary for web content filters search category filter on option [CHAR LIMIT=None] -->
+    <string name="supervision_web_content_filters_search_filter_on_summary">Helps filter out explicit images, text, and links from search results on this device</string>
+    <!-- Title for web content filters search category filter off option [CHAR LIMIT=60] -->
+    <string name="supervision_web_content_filters_search_filter_off_title">SafeSearch filtering OFF</string>
+    <!-- Summary for web content filters search category filter off option [CHAR LIMIT=None] -->
+    <string name="supervision_web_content_filters_search_filter_off_summary">Account settings may still filter or blur explicit results</string>
     <!-- Generic content description that is attached to the preview illustration at the top of an Accessibility feature toggle page. [CHAR LIMIT=NONE] -->
     <!-- Title for supervision PIN verification screen [CHAR LIMIT=60] -->
     <string name="supervision_full_screen_pin_verification_title">Enter supervision PIN</string>
diff --git a/res/xml/mobile_network_settings.xml b/res/xml/mobile_network_settings.xml
index a0da440..12f3beb 100644
--- a/res/xml/mobile_network_settings.xml
+++ b/res/xml/mobile_network_settings.xml
@@ -210,7 +210,7 @@
             <com.android.settingslib.RestrictedPreference
                 android:key="telephony_satellite_setting_key"
                 android:persistent="false"
-                android:title="@string/satellite_setting_title"
+                android:title="@string/title_satellite_setting_connectivity"
                 settings:keywords="@string/keywords_satellite_setting"
                 settings:controller=
                     "com.android.settings.network.telephony.satellite.SatelliteSettingPreferenceController"/>
diff --git a/res/xml/satellite_setting.xml b/res/xml/satellite_setting.xml
index 74bee71..0650970 100644
--- a/res/xml/satellite_setting.xml
+++ b/res/xml/satellite_setting.xml
@@ -32,7 +32,8 @@
 
     <PreferenceCategory
         android:key="key_category_your_satellite_plan"
-        android:title="@string/category_title_your_satellite_plan">
+        android:title="@string/category_title_your_satellite_plan"
+        settings:controller="com.android.settings.network.telephony.satellite.SatelliteSettingAccountInfoController">
 
         <Preference
             android:key="key_your_satellite_plan"
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewController.java b/src/com/android/settings/accessibility/TextReadingPreviewController.java
index e268aaa..99f1f3f 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewController.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewController.java
@@ -104,13 +104,11 @@
         final boolean isLayoutRtl =
                 origConfig.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
         final int[] previewSamples = getPreviewSampleLayouts(mContext);
-        final int[] previewContentDescriptions = getPreviewSampleContentDescriptions(mContext);
         final PreviewPagerAdapter pagerAdapter = new PreviewPagerAdapter(mContext, isLayoutRtl,
                 previewSamples, createConfig(origConfig));
         mPreviewPreference.setPreviewAdapter(pagerAdapter);
         mPreviewPreference.setCurrentItem(
                 isLayoutRtl ? previewSamples.length - 1 : FRAME_INITIAL_INDEX);
-        mPreviewPreference.setContentDescription(previewContentDescriptions);
 
         final int initialPagerIndex =
                 mLastFontProgress * mDisplaySizeData.getValues().size() + mLastDisplayProgress;
@@ -190,20 +188,6 @@
         return previewSamples;
     }
 
-    @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
-    static int[] getPreviewSampleContentDescriptions(Context context) {
-        TypedArray typedArray = context.getResources().obtainTypedArray(
-                R.array.config_text_reading_preview_content_descriptions);
-        int previewCount = typedArray.length();
-        int[] previewContentDescriptions = new int[previewCount];
-        for (int i = 0; i < previewCount; i++) {
-            previewContentDescriptions[i] =
-                    typedArray.getResourceId(i, R.string.preview_pager_content_description);
-        }
-        typedArray.recycle();
-        return previewContentDescriptions;
-    }
-
     private int getPagerIndex() {
         final int displayDataSize = mDisplaySizeData.getValues().size();
         final int fontSizeProgress = mFontSizePreference.getProgress();
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
index a4676ba..6d60736 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
@@ -43,10 +43,26 @@
     private int mCurrentItem;
     private int mLastLayerIndex;
     private PreviewPagerAdapter mPreviewAdapter;
-    private int[] mContentDescriptions;
 
     private int mLayoutMinHorizontalPadding = 0;
     private int mBackgroundMinHorizontalPadding = 0;
+    private final ViewPager.OnPageChangeListener mPageChangeListener =
+            new ViewPager.OnPageChangeListener() {
+                @Override
+                public void onPageScrolled(int i, float v, int i1) {
+                    // Do nothing
+                }
+
+                @Override
+                public void onPageSelected(int i) {
+                    mCurrentItem = i;
+                }
+
+                @Override
+                public void onPageScrollStateChanged(int i) {
+                    // Do nothing
+                }
+            };
 
     TextReadingPreviewPreference(Context context) {
         super(context);
@@ -78,23 +94,7 @@
         adjustPaddings(previewLayout, backgroundView);
 
         final ViewPager viewPager = (ViewPager) holder.findViewById(R.id.preview_pager);
-        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
-            @Override
-            public void onPageScrolled(int i, float v, int i1) {
-                // Do nothing
-            }
-
-            @Override
-            public void onPageSelected(int i) {
-                mCurrentItem = i;
-                viewPager.setContentDescription(getContext().getString(mContentDescriptions[i]));
-            }
-
-            @Override
-            public void onPageScrollStateChanged(int i) {
-                // Do nothing
-            }
-        });
+        viewPager.addOnPageChangeListener(mPageChangeListener);
         final DotsPageIndicator pageIndicator =
                 (DotsPageIndicator) holder.findViewById(R.id.page_indicator);
         updateAdapterIfNeeded(viewPager, pageIndicator, mPreviewAdapter);
@@ -121,10 +121,6 @@
                 viewPager.setCurrentItem(getCurrentItem() + 1));
         nextButton.setContentDescription(getContext().getString(
                 R.string.preview_pager_next_button));
-
-        // Initialize the content description since the OnPageChangeListener#onPageSelected won't
-        // be called during setup.
-        viewPager.setContentDescription(getContext().getString(mContentDescriptions[0]));
     }
 
     @Override
@@ -173,10 +169,6 @@
         );
     }
 
-    void setContentDescription(int[] stringIds) {
-        mContentDescriptions = stringIds;
-    }
-
     void setPreviewAdapter(PreviewPagerAdapter previewAdapter) {
         if (previewAdapter != mPreviewAdapter) {
             mPreviewAdapter = previewAdapter;
diff --git a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
index 2ac4a18..5ea99ae 100644
--- a/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
+++ b/src/com/android/settings/bluetooth/AlwaysDiscoverable.java
@@ -24,6 +24,8 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import com.android.settingslib.utils.ThreadUtils;
+
 /** Helper class, intended to be used by an Activity, to keep the local Bluetooth adapter in
  *  discoverable mode indefinitely. By default setting the scan mode to
  *  BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE will time out after some time, but some
@@ -55,10 +57,12 @@
         mContext.registerReceiver(this, mIntentFilter,
                 Context.RECEIVER_EXPORTED_UNAUDITED);
         mStarted = true;
-        if (mBluetoothAdapter.getScanMode()
-                != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-            mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-        }
+        ThreadUtils.postOnBackgroundThread(() -> {
+            if (mBluetoothAdapter.getScanMode()
+                    != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+                mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+            }
+        });
     }
 
     public void stop() {
@@ -67,7 +71,8 @@
         }
         mContext.unregisterReceiver(this);
         mStarted = false;
-        mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
+        ThreadUtils.postOnBackgroundThread(
+                () -> mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE));
     }
 
     @Override
@@ -76,9 +81,11 @@
         if (action != BluetoothAdapter.ACTION_SCAN_MODE_CHANGED) {
             return;
         }
-        if (mBluetoothAdapter.getScanMode()
-                != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
-            mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
-        }
+        ThreadUtils.postOnBackgroundThread(() -> {
+            if (mBluetoothAdapter.getScanMode()
+                    != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+                mBluetoothAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
+            }
+        });
     }
 }
diff --git a/src/com/android/settings/contract/SettingsContract.kt b/src/com/android/settings/contract/SettingsContract.kt
index 3a35419..20ff0c0 100644
--- a/src/com/android/settings/contract/SettingsContract.kt
+++ b/src/com/android/settings/contract/SettingsContract.kt
@@ -69,6 +69,12 @@
 /** Contract key for the "Use adaptive connectivity" setting. */
 const val KEY_ADAPTIVE_CONNECTIVITY = "adaptive_connectivity"
 
+/** Contract key for the "Auto-switch Wi-Fi to Cellular" setting. */
+const val KEY_ADAPTIVE_WIFI_SCORER = "adaptive_wifi_scorer"
+
+/** Contract key for the " Auto-switch mobile network for battery life" setting. */
+const val KEY_ADAPTIVE_MOBILE_NETWORK = "adaptive_mobile_network"
+
 /** Contract key for the "WiFi hotspot" setting. */
 const val KEY_WIFI_HOTSPOT = "enable_wifi_ap"
 
diff --git a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
index f61fbb6..4fd8a21 100644
--- a/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
+++ b/src/com/android/settings/dashboard/DashboardFeatureProviderImpl.java
@@ -507,10 +507,6 @@
                     R.dimen.dashboard_tile_image_size);
             drawable.setLayerSize(0, size, size);
             return drawable;
-        } else if (TextUtils.equals(tile.getPackageName(),
-                mPackageManager.getWellbeingPackageName())) {
-            return getRoundedIcon(iconDrawable,
-                    R.color.homepage_wellbeing_foreground, R.color.homepage_wellbeing_background);
         }
 
         Pair<Integer, Integer> colors = getSchemedColors(tile);
diff --git a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
index 1955f36..05e4f25e 100644
--- a/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
+++ b/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceController.java
@@ -93,7 +93,7 @@
     private String getSummary(long usedBytes, long totalBytes) {
         NumberFormat percentageFormat = NumberFormat.getPercentInstance();
 
-        return mContext.getString(R.string.storage_summary,
+        return mContext.getString(R.string.storage_toplevel_summary,
                 totalBytes == 0L ? "0" : percentageFormat.format(((double) usedBytes) / totalBytes),
                 Formatter.formatFileSize(mContext, totalBytes - usedBytes));
     }
diff --git a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
index 22e3431..2a731bf 100644
--- a/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
+++ b/src/com/android/settings/homepage/contextualcards/slices/LowStorageSlice.java
@@ -73,7 +73,7 @@
         if (usedPercentage < LOW_STORAGE_THRESHOLD) {
             // For clients that ignore error checking, a generic storage slice will be given.
             final CharSequence titleStorage = mContext.getText(R.string.storage_settings);
-            final String summaryStorage = mContext.getString(R.string.storage_summary,
+            final String summaryStorage = mContext.getString(R.string.storage_toplevel_summary,
                     percentageString, freeSizeString);
 
             return listBuilder
diff --git a/src/com/android/settings/network/telephony/satellite/SatelliteSetting.java b/src/com/android/settings/network/telephony/satellite/SatelliteSetting.java
index 851038a..5af2658 100644
--- a/src/com/android/settings/network/telephony/satellite/SatelliteSetting.java
+++ b/src/com/android/settings/network/telephony/satellite/SatelliteSetting.java
@@ -28,9 +28,6 @@
 import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.Intent;
-import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.PersistableBundle;
 import android.os.UserManager;
@@ -38,10 +35,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.satellite.SatelliteManager;
-import android.text.SpannableString;
-import android.text.Spanned;
-import android.text.style.StyleSpan;
-import android.text.style.UnderlineSpan;
 import android.util.Log;
 import android.view.View;
 
@@ -53,7 +46,6 @@
 import com.android.settings.R;
 import com.android.settings.dashboard.RestrictedDashboardFragment;
 import com.android.settingslib.HelpUtils;
-import com.android.settingslib.Utils;
 import com.android.settingslib.widget.FooterPreference;
 
 import java.util.Set;
@@ -61,12 +53,7 @@
 /** Handle Satellite Setting Preference Layout. */
 public class SatelliteSetting extends RestrictedDashboardFragment {
     private static final String TAG = "SatelliteSetting";
-    private static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
-            "key_category_your_satellite_plan";
-    private static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
     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_SATELLITE_CONNECTION_GUIDE = "key_satellite_connection_guide";
     private static final String KEY_SUPPORTED_SERVICE = "key_supported_service";
@@ -99,9 +86,15 @@
         mActivity = getActivity();
         mSubId = mActivity.getIntent().getIntExtra(SUB_ID,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
+        mConfigBundle = fetchCarrierConfigData(mSubId);
+        mIsServiceDataType = getIntent().getBooleanExtra(EXTRA_IS_SERVICE_DATA_TYPE, false);
+        mIsSmsAvailableForManualType = getIntent().getBooleanExtra(
+                EXTRA_IS_SMS_AVAILABLE_FOR_MANUAL_TYPE, false);
 
         use(SatelliteAppListCategoryController.class).init();
         use(SatelliteSettingAboutContentController.class).init(mSubId);
+        use(SatelliteSettingAccountInfoController.class).init(mSubId, mConfigBundle,
+                mIsSmsAvailableForManualType, mIsServiceDataType);
     }
 
     @Override
@@ -114,8 +107,6 @@
             return;
         }
 
-        mConfigBundle = fetchCarrierConfigData(mSubId);
-
         if (!isSatelliteAttachSupported(mSubId)) {
             Log.d(TAG, "SatelliteSettings: KEY_SATELLITE_ATTACH_SUPPORTED_BOOL is false, "
                     + "do nothing.");
@@ -123,9 +114,6 @@
             return;
         }
 
-        mIsServiceDataType = getIntent().getBooleanExtra(EXTRA_IS_SERVICE_DATA_TYPE, false);
-        mIsSmsAvailableForManualType = getIntent().getBooleanExtra(
-                EXTRA_IS_SMS_AVAILABLE_FOR_MANUAL_TYPE, false);
         mSimOperatorName = getSystemService(TelephonyManager.class).getSimOperatorName(mSubId);
     }
 
@@ -133,8 +121,6 @@
     public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
         super.onViewCreated(view, savedInstanceState);
         boolean isSatelliteEligible = isSatelliteEligible();
-        updateTitle();
-        updateMobilePlan(isSatelliteEligible);
         updateHowItWorksContent(isSatelliteEligible);
         updateFooterContent();
     }
@@ -149,65 +135,6 @@
         return R.xml.satellite_setting;
     }
 
-    private void updateTitle() {
-        findPreference("satellite_setting").setTitle(getSubjectString());
-    }
-
-    private void updateMobilePlan(boolean isSatelliteEligible) {
-        PreferenceCategory prefCategory = findPreference(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
-        if (prefCategory == null || !mConfigBundle.getBoolean(
-                KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL)) {
-            prefCategory.setVisible(false);
-            return;
-        }
-
-        // Your mobile plan
-        prefCategory.setTitle(getResources().getString(R.string.category_title_your_satellite_plan,
-                mSimOperatorName));
-        Preference messagingPreference = findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
-
-        Drawable icon = getContext().getDrawable(R.drawable.ic_check_circle_24px);
-        if (isSatelliteEligible) {
-            /* 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 */
-            messagingPreference.setTitle(R.string.title_have_satellite_plan);
-            if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
-                if (mIsServiceDataType) {
-                    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 {
-            /* Or, it will show the blocked icon with the guidance that satellite is not included
-               in user's mobile plan */
-            messagingPreference.setTitle(R.string.title_no_satellite_plan);
-            /* And, the link url provides more information via web page will be shown */
-            SpannableString spannable = new SpannableString(
-                    getResources().getString(R.string.summary_add_satellite_setting));
-            spannable.setSpan(new UnderlineSpan(), 0, spannable.length(),
-                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-            spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(),
-                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
-            messagingPreference.setSummary(spannable);
-            /* The link will lead users to a guide page */
-            messagingPreference.setOnPreferenceClickListener(pref -> {
-                String url = readSatelliteMoreInfoString();
-                if (!url.isEmpty()) {
-                    Uri uri = Uri.parse(url);
-                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
-                    startActivity(intent);
-                }
-                return true;
-            });
-            icon = getResources().getDrawable(R.drawable.ic_block_24px, null);
-        }
-        icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.textColorPrimary));
-        messagingPreference.setIcon(icon);
-    }
-
     private void updateHowItWorksContent(boolean isSatelliteEligible) {
         /* 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. */
@@ -250,7 +177,7 @@
                 });
 
                 footerPreference.setLearnMoreText(
-                        getString(R.string.more_about_satellite_messaging, getDescriptionString()));
+                        getString(R.string.more_about_satellite_messaging));
             }
         }
     }
@@ -304,32 +231,6 @@
         return mConfigBundle.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) {
         Log.e(TAG, message);
     }
diff --git a/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoController.java b/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoController.java
new file mode 100644
index 0000000..f688a92
--- /dev/null
+++ b/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoController.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony.satellite;
+
+import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL;
+import static android.telephony.CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING;
+
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Typeface;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.PersistableBundle;
+import android.telephony.TelephonyManager;
+import android.telephony.satellite.SatelliteManager;
+import android.text.SpannableString;
+import android.text.Spanned;
+import android.text.style.StyleSpan;
+import android.text.style.UnderlineSpan;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.network.telephony.TelephonyBasePreferenceController;
+import com.android.settingslib.Utils;
+
+import java.util.Set;
+
+/** A controller to control content of "Your mobile plan". */
+public class SatelliteSettingAccountInfoController extends TelephonyBasePreferenceController {
+    private static final String TAG = "SatelliteSettingAccountInfoController";
+    @VisibleForTesting
+    static final String PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN =
+            "key_category_your_satellite_plan";
+    @VisibleForTesting
+    static final String PREF_KEY_YOUR_SATELLITE_PLAN = "key_your_satellite_plan";
+    @VisibleForTesting
+    static final String PREF_KEY_YOUR_SATELLITE_DATA_PLAN = "key_your_satellite_data_plan";
+
+    private PreferenceScreen mScreen;
+    private String mSimOperatorName;
+    private boolean mIsSmsAvailable;
+    private boolean mIsDataAvailable;
+    private boolean mIsSatelliteEligible;
+    private PersistableBundle mConfigBundle = new PersistableBundle();
+
+    public SatelliteSettingAccountInfoController(@NonNull Context context,
+            @NonNull String preferenceKey) {
+        super(context, preferenceKey);
+    }
+
+    /** Initialize the UI settings. */
+    public void init(int subId, @NonNull PersistableBundle configBundle, boolean isSmsAvailable,
+            boolean isDataAvailable) {
+        mSubId = subId;
+        mConfigBundle = configBundle;
+        mSimOperatorName = mContext.getSystemService(TelephonyManager.class).getSimOperatorName(
+                mSubId);
+        mIsSmsAvailable = isSmsAvailable;
+        mIsDataAvailable = isDataAvailable;
+        mIsSatelliteEligible = isSatelliteEligible();
+    }
+
+    @Override
+    public void displayPreference(@NonNull PreferenceScreen screen) {
+        mScreen = screen;
+        super.displayPreference(screen);
+        PreferenceCategory prefCategory = screen.findPreference(
+                PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        // Your mobile plan
+        prefCategory.setTitle(mContext.getString(R.string.category_title_your_satellite_plan,
+                mSimOperatorName));
+
+        if (mIsSatelliteEligible) {
+            handleEligibleUI();
+            return;
+        }
+        handleIneligibleUI();
+    }
+
+    @Override
+    public int getAvailabilityStatus(int subId) {
+        return mConfigBundle.getBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL)
+                ? AVAILABLE
+                : CONDITIONALLY_UNAVAILABLE;
+    }
+
+    private void handleEligibleUI() {
+        Preference messagingPreference = mScreen.findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
+        Drawable icon = mContext.getDrawable(R.drawable.ic_check_circle_24px);
+        /* 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 */
+        messagingPreference.setTitle(R.string.title_have_satellite_plan);
+        if (com.android.settings.flags.Flags.satelliteOemSettingsUxMigration()) {
+            if (mIsDataAvailable) {
+                Preference connectivityPreference = mScreen.findPreference(
+                        PREF_KEY_YOUR_SATELLITE_DATA_PLAN);
+                connectivityPreference.setTitle(R.string.title_have_satellite_data_plan);
+                connectivityPreference.setIcon(icon);
+                connectivityPreference.setVisible(true);
+            }
+        }
+        icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorPrimary));
+        messagingPreference.setIcon(icon);
+    }
+
+    private void handleIneligibleUI() {
+        Preference messagingPreference = mScreen.findPreference(PREF_KEY_YOUR_SATELLITE_PLAN);
+        /* Or, it will show the blocked icon with the guidance that satellite is not included
+               in user's mobile plan */
+        messagingPreference.setTitle(R.string.title_no_satellite_plan);
+        String url = mConfigBundle.getString(KEY_SATELLITE_INFORMATION_REDIRECT_URL_STRING, "");
+        if (!url.isEmpty()) {
+            /* And, the link url provides more information via web page will be shown */
+            SpannableString spannable = new SpannableString(
+                    mContext.getString(R.string.summary_add_satellite_setting));
+            spannable.setSpan(new UnderlineSpan(), 0, spannable.length(),
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            spannable.setSpan(new StyleSpan(Typeface.BOLD), 0, spannable.length(),
+                    Spanned.SPAN_INCLUSIVE_INCLUSIVE);
+            messagingPreference.setSummary(spannable);
+            /* The link will lead users to a guide page */
+            messagingPreference.setOnPreferenceClickListener(pref -> {
+                Uri uri = Uri.parse(url);
+                Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+                mContext.startActivity(intent);
+                return true;
+            });
+        }
+
+        Drawable icon = mContext.getDrawable(R.drawable.ic_block_24px);
+        icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorPrimary));
+        messagingPreference.setIcon(icon);
+    }
+
+    @VisibleForTesting
+    protected boolean isSatelliteEligible() {
+        if (mConfigBundle.getInt(KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT)
+                == CARRIER_ROAMING_NTN_CONNECT_MANUAL) {
+            return mIsSmsAvailable;
+        }
+        SatelliteManager satelliteManager = mContext.getSystemService(SatelliteManager.class);
+        if (satelliteManager == null) {
+            Log.d(TAG, "SatelliteManager is null.");
+            return false;
+        }
+        try {
+            Set<Integer> restrictionReason =
+                    satelliteManager.getAttachRestrictionReasonsForCarrier(mSubId);
+            return !restrictionReason.contains(
+                    SatelliteManager.SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT);
+        } catch (SecurityException | IllegalStateException | IllegalArgumentException ex) {
+            Log.d(TAG, "Error to getAttachRestrictionReasonsForCarrier : " + ex.toString());
+            return false;
+        }
+    }
+}
diff --git a/src/com/android/settings/network/telephony/satellite/SatelliteSettingPreferenceController.java b/src/com/android/settings/network/telephony/satellite/SatelliteSettingPreferenceController.java
index dde35eb..04f2c5f 100644
--- a/src/com/android/settings/network/telephony/satellite/SatelliteSettingPreferenceController.java
+++ b/src/com/android/settings/network/telephony/satellite/SatelliteSettingPreferenceController.java
@@ -145,7 +145,6 @@
     public void updateState(@Nullable Preference preference) {
         super.updateState(preference);
         if (preference != null && preference.getKey().equals(getPreferenceKey())) {
-            updateTitle(preference);
             updateSummary(preference);
         }
     }
@@ -170,12 +169,6 @@
         return false;
     }
 
-    private void updateTitle(Preference preference) {
-        preference.setTitle(mCarrierRoamingNtnModeCallback.isSatelliteServiceDataType()
-                ? R.string.title_satellite_setting_connectivity
-                : R.string.satellite_setting_title);
-    }
-
     private void updateSummary(Preference preference) {
         if (preference == null) {
             logd("updateSummary - no Preference");
diff --git a/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceCategoryController.java b/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceCategoryController.java
index f2fb347..d0cb1bc 100644
--- a/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceCategoryController.java
+++ b/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceCategoryController.java
@@ -159,6 +159,7 @@
                     @Override
                     public void onResult(Boolean result) {
                         mIsSatelliteSupported.set(result);
+                        Log.d(TAG, "Satellite requestIsSupported : " + result);
                         SatelliteSettingsPreferenceCategoryController.this.displayPreference();
                     }
                 });
diff --git a/src/com/android/settings/supervision/SupervisionSafeSearchPreference.kt b/src/com/android/settings/supervision/SupervisionSafeSearchPreference.kt
new file mode 100644
index 0000000..617a345
--- /dev/null
+++ b/src/com/android/settings/supervision/SupervisionSafeSearchPreference.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.supervision
+
+import android.content.Context
+import androidx.preference.Preference
+import com.android.settings.R
+import com.android.settingslib.datastore.KeyValueStore
+import com.android.settingslib.datastore.Permissions
+import com.android.settingslib.datastore.SettingsSecureStore
+import com.android.settingslib.metadata.BooleanValuePreference
+import com.android.settingslib.metadata.PreferenceMetadata
+import com.android.settingslib.metadata.ReadWritePermit
+import com.android.settingslib.metadata.SensitivityLevel
+import com.android.settingslib.preference.PreferenceBinding
+import com.android.settingslib.preference.forEachRecursively
+import com.android.settingslib.widget.SelectorWithWidgetPreference
+
+/** Base class of web content filters SafeSearch preferences. */
+sealed class SupervisionSafeSearchPreference :
+    BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
+    override fun storage(context: Context): KeyValueStore = SettingsSecureStore.get(context)
+
+    override fun getReadPermissions(context: Context) = Permissions.EMPTY
+
+    override fun getWritePermissions(context: Context) = Permissions.EMPTY
+
+    override fun getReadPermit(context: Context, callingPid: Int, callingUid: Int) =
+        ReadWritePermit.ALLOW
+
+    override fun getWritePermit(
+        context: Context,
+        value: Boolean?,
+        callingPid: Int,
+        callingUid: Int,
+    ) = ReadWritePermit.DISALLOW
+
+    override val sensitivityLevel
+        get() = SensitivityLevel.NO_SENSITIVITY
+
+    override fun createWidget(context: Context) = SelectorWithWidgetPreference(context)
+
+    override fun onRadioButtonClicked(emiter: SelectorWithWidgetPreference) {
+        emiter.parent?.forEachRecursively {
+            if (it is SelectorWithWidgetPreference) {
+                it.isChecked = it == emiter
+            }
+        }
+    }
+
+    override fun bind(preference: Preference, metadata: PreferenceMetadata) {
+        super.bind(preference, metadata)
+        (preference as SelectorWithWidgetPreference).also {
+            // TODO(b/401568995): Set the isChecked value using stored values.
+            it.isChecked = (it.key == SupervisionSearchFilterOffPreference.KEY)
+            it.setOnClickListener(this)
+        }
+    }
+}
+
+/** The SafeSearch filter on preference. */
+class SupervisionSearchFilterOnPreference : SupervisionSafeSearchPreference() {
+
+    override val key
+        get() = KEY
+
+    override val title
+        get() = R.string.supervision_web_content_filters_search_filter_on_title
+
+    override val summary
+        get() = R.string.supervision_web_content_filters_search_filter_on_summary
+
+    companion object {
+        const val KEY = "web_content_filters_search_filter_on"
+    }
+}
+
+/** The SafeSearch filter off preference. */
+class SupervisionSearchFilterOffPreference : SupervisionSafeSearchPreference() {
+
+    override val key
+        get() = KEY
+
+    override val title
+        get() = R.string.supervision_web_content_filters_search_filter_off_title
+
+    override val summary
+        get() = R.string.supervision_web_content_filters_search_filter_off_summary
+
+    companion object {
+        const val KEY = "web_content_filters_search_filter_off"
+    }
+}
diff --git a/src/com/android/settings/supervision/SupervisionSafeSitesDataStore.kt b/src/com/android/settings/supervision/SupervisionSafeSitesDataStore.kt
new file mode 100644
index 0000000..4f283b8
--- /dev/null
+++ b/src/com/android/settings/supervision/SupervisionSafeSitesDataStore.kt
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.supervision
+
+import android.content.Context
+import android.provider.Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED
+import com.android.settingslib.datastore.AbstractKeyedDataObservable
+import com.android.settingslib.datastore.HandlerExecutor
+import com.android.settingslib.datastore.KeyValueStore
+import com.android.settingslib.datastore.KeyedObserver
+import com.android.settingslib.datastore.SettingsSecureStore
+import com.android.settingslib.datastore.SettingsStore
+
+/** Datastore of the safe sites preference. */
+@Suppress("UNCHECKED_CAST")
+class SupervisionSafeSitesDataStore(
+    private val context: Context,
+    private val settingsStore: SettingsStore = SettingsSecureStore.get(context),
+) : AbstractKeyedDataObservable<String>(), KeyedObserver<String>, KeyValueStore {
+
+    override fun contains(key: String) =
+        key == SupervisionBlockExplicitSitesPreference.KEY ||
+            key == SupervisionAllowAllSitesPreference.KEY
+
+    override fun <T : Any> getValue(key: String, valueType: Class<T>): T? {
+        val settingValue = (settingsStore.getBoolean(BROWSER_CONTENT_FILTERS_ENABLED) == true)
+        return when (key) {
+            SupervisionAllowAllSitesPreference.KEY -> !settingValue
+
+            SupervisionBlockExplicitSitesPreference.KEY -> settingValue
+
+            else -> null
+        }
+            as T?
+    }
+
+    override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
+        if (value !is Boolean) return
+        when (key) {
+            SupervisionAllowAllSitesPreference.KEY ->
+                settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, !value)
+
+            SupervisionBlockExplicitSitesPreference.KEY ->
+                settingsStore.setBoolean(BROWSER_CONTENT_FILTERS_ENABLED, value)
+        }
+    }
+
+    override fun onFirstObserverAdded() {
+        // observe the underlying storage key
+        settingsStore.addObserver(BROWSER_CONTENT_FILTERS_ENABLED, this, HandlerExecutor.main)
+    }
+
+    override fun onKeyChanged(key: String, reason: Int) {
+        // forward data change to preference hierarchy key
+        notifyChange(SupervisionBlockExplicitSitesPreference.KEY, reason)
+        notifyChange(SupervisionAllowAllSitesPreference.KEY, reason)
+    }
+
+    override fun onLastObserverRemoved() {
+        settingsStore.removeObserver(BROWSER_CONTENT_FILTERS_ENABLED, this)
+    }
+}
diff --git a/src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt b/src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt
index aaa5a33..d78afb2 100644
--- a/src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt
+++ b/src/com/android/settings/supervision/SupervisionSafeSitesPreference.kt
@@ -18,9 +18,7 @@
 import android.content.Context
 import androidx.preference.Preference
 import com.android.settings.R
-import com.android.settingslib.datastore.KeyValueStore
 import com.android.settingslib.datastore.Permissions
-import com.android.settingslib.datastore.SettingsSecureStore
 import com.android.settingslib.metadata.BooleanValuePreference
 import com.android.settingslib.metadata.PreferenceMetadata
 import com.android.settingslib.metadata.ReadWritePermit
@@ -30,9 +28,10 @@
 import com.android.settingslib.widget.SelectorWithWidgetPreference
 
 /** Base class of web content filters Safe sites preferences. */
-sealed class SupervisionSafeSitesPreference :
-    BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
-    override fun storage(context: Context): KeyValueStore = SettingsSecureStore.get(context)
+sealed class SupervisionSafeSitesPreference(
+    protected val dataStore: SupervisionSafeSitesDataStore
+) : BooleanValuePreference, SelectorWithWidgetPreference.OnClickListener, PreferenceBinding {
+    override fun storage(context: Context) = dataStore
 
     override fun getReadPermissions(context: Context) = Permissions.EMPTY
 
@@ -64,15 +63,15 @@
     override fun bind(preference: Preference, metadata: PreferenceMetadata) {
         super.bind(preference, metadata)
         (preference as SelectorWithWidgetPreference).also {
-            // TODO(b/401568468): Set the isChecked value using stored values.
-            it.isChecked = (it.key == SupervisionAllowAllSitesPreference.KEY)
+            it.isChecked = (dataStore.getBoolean(it.key) == true)
             it.setOnClickListener(this)
         }
     }
 }
 
 /** The "Try to block explicit sites" preference. */
-class SupervisionBlockExplicitSitesPreference : SupervisionSafeSitesPreference() {
+class SupervisionBlockExplicitSitesPreference(dataStore: SupervisionSafeSitesDataStore) :
+    SupervisionSafeSitesPreference(dataStore) {
 
     override val key
         get() = KEY
@@ -89,7 +88,8 @@
 }
 
 /** The "Allow all sites" preference. */
-class SupervisionAllowAllSitesPreference : SupervisionSafeSitesPreference() {
+class SupervisionAllowAllSitesPreference(dataStore: SupervisionSafeSitesDataStore) :
+    SupervisionSafeSitesPreference(dataStore) {
 
     override val key
         get() = KEY
diff --git a/src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt b/src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt
index 0a2891b..994165a 100644
--- a/src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt
+++ b/src/com/android/settings/supervision/SupervisionWebContentFiltersScreen.kt
@@ -47,14 +47,23 @@
                 R.string.supervision_web_content_filters_browser_title,
             ) +=
                 {
-                    +SupervisionBlockExplicitSitesPreference()
-                    +SupervisionAllowAllSitesPreference()
+                    val dataStore = SupervisionSafeSitesDataStore(context)
+                    +SupervisionBlockExplicitSitesPreference(dataStore)
+                    +SupervisionAllowAllSitesPreference(dataStore)
                 }
-            // TODO(b/401569571) implement the SafeSearch group.
+            +PreferenceCategory(
+                SEARCH_RADIO_BUTTON_GROUP,
+                R.string.supervision_web_content_filters_search_title,
+            ) +=
+                {
+                    +SupervisionSearchFilterOnPreference()
+                    +SupervisionSearchFilterOffPreference()
+                }
         }
 
     companion object {
         const val KEY = "supervision_web_content_filters"
         internal const val BROWSER_RADIO_BUTTON_GROUP = "browser_radio_button_group"
+        internal const val SEARCH_RADIO_BUTTON_GROUP = "search_radio_button_group"
     }
 }
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
index 81c869d..375952f 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewControllerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.settings.accessibility;
 
-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;
@@ -79,15 +77,6 @@
     }
 
     @Test
-    public void numberOfPreviewSamples_numberOfPreviewContentDescription_isEqual() {
-        int[] previewSamples = TextReadingPreviewController.getPreviewSampleLayouts(mContext);
-        int[] previewContentDescriptions =
-                TextReadingPreviewController.getPreviewSampleContentDescriptions(mContext);
-
-        assertThat(previewSamples.length).isEqualTo(previewContentDescriptions.length);
-    }
-
-    @Test
     public void initPreviewerAdapter_verifyAction() {
         when(mPreferenceScreen.findPreference(PREVIEW_KEY)).thenReturn(mPreviewPreference);
         when(mPreferenceScreen.findPreference(FONT_SIZE_KEY)).thenReturn(mFontSizePreference);
diff --git a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
index 9cd8fa2..ac503bd 100644
--- a/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
+++ b/tests/robotests/src/com/android/settings/accessibility/TextReadingPreviewPreferenceTest.java
@@ -49,48 +49,28 @@
  */
 @RunWith(RobolectricTestRunner.class)
 public class TextReadingPreviewPreferenceTest {
-    private Context mContext;
     private TextReadingPreviewPreference mTextReadingPreviewPreference;
     private PreferenceViewHolder mHolder;
     private ViewPager mViewPager;
     private PreviewPagerAdapter mPreviewPagerAdapter;
     private int mPreviewSampleCount;
-    private int[] mPreviewContentDescriptions;
 
     @Before
     public void setUp() {
-        mContext = ApplicationProvider.getApplicationContext();
-        mPreviewContentDescriptions =
-                TextReadingPreviewController.getPreviewSampleContentDescriptions(mContext);
-        final int[] previewSamples = TextReadingPreviewController.getPreviewSampleLayouts(mContext);
+        final Context context = ApplicationProvider.getApplicationContext();
+        final int[] previewSamples = TextReadingPreviewController.getPreviewSampleLayouts(context);
         mPreviewSampleCount = previewSamples.length;
         final Configuration[] configurations = createConfigurations(mPreviewSampleCount);
-        mTextReadingPreviewPreference = new TextReadingPreviewPreference(mContext);
+        mTextReadingPreviewPreference = new TextReadingPreviewPreference(context);
         mPreviewPagerAdapter =
-                spy(new PreviewPagerAdapter(mContext, /* isLayoutRtl= */ false,
+                spy(new PreviewPagerAdapter(context, /* isLayoutRtl= */ false,
                         previewSamples, configurations));
-        final LayoutInflater inflater = LayoutInflater.from(mContext);
+        final LayoutInflater inflater = LayoutInflater.from(context);
         final View view =
                 inflater.inflate(mTextReadingPreviewPreference.getLayoutResource(),
-                        new LinearLayout(mContext), false);
+                        new LinearLayout(context), false);
         mHolder = PreferenceViewHolder.createInstanceForTests(view);
         mViewPager = view.findViewById(R.id.preview_pager);
-        mTextReadingPreviewPreference.setContentDescription(mPreviewContentDescriptions);
-    }
-
-    @Test
-    public void changePreviewPage_getExpectedContentDescription() {
-        mTextReadingPreviewPreference.setPreviewAdapter(mPreviewPagerAdapter);
-        mTextReadingPreviewPreference.onBindViewHolder(mHolder);
-
-        // Verify the initial content description
-        assertThat(mViewPager.getContentDescription().toString())
-                .isEqualTo(mContext.getString(mPreviewContentDescriptions[0]));
-
-        // Change the preview page
-        mViewPager.setCurrentItem(1);
-        assertThat(mViewPager.getContentDescription().toString())
-                .isEqualTo(mContext.getString(mPreviewContentDescriptions[1]));
     }
 
     @Test
diff --git a/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSearchPreferenceTest.kt b/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSearchPreferenceTest.kt
new file mode 100644
index 0000000..371cca3
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSearchPreferenceTest.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settings.supervision
+
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.settings.R
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SupervisionSafeSearchPreferenceTest {
+    private val context: Context = ApplicationProvider.getApplicationContext()
+
+    private val searchFilterOnPreference = SupervisionSearchFilterOnPreference()
+
+    private val searchFilterOffPreference = SupervisionSearchFilterOffPreference()
+
+    @Test
+    fun getTitle_filterOn() {
+        assertThat(searchFilterOnPreference.title)
+            .isEqualTo(R.string.supervision_web_content_filters_search_filter_on_title)
+    }
+
+
+    @Test
+    fun getSummary_filterOn() {
+        assertThat(searchFilterOnPreference.summary)
+            .isEqualTo(R.string.supervision_web_content_filters_search_filter_on_summary)
+    }
+
+    @Test
+    fun getTitle_filterOff() {
+        assertThat(searchFilterOffPreference.title)
+            .isEqualTo(R.string.supervision_web_content_filters_search_filter_off_title)
+    }
+
+    @Test
+    fun getSummary_filterOff() {
+        assertThat(searchFilterOffPreference.summary)
+            .isEqualTo(
+                R.string.supervision_web_content_filters_search_filter_off_summary
+            )
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt b/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt
index 5be7a11..a3aca69 100644
--- a/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt
+++ b/tests/robotests/src/com/android/settings/supervision/SupervisionSafeSitesPreferenceTest.kt
@@ -16,20 +16,33 @@
 package com.android.settings.supervision
 
 import android.content.Context
+import android.provider.Settings
+import android.provider.Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED
+import android.provider.Settings.SettingNotFoundException
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settings.R
+import com.android.settingslib.preference.createAndBindWidget
+import com.android.settingslib.widget.SelectorWithWidgetPreference
 import com.google.common.truth.Truth.assertThat
+import org.junit.Assert.assertThrows
+import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 class SupervisionSafeSitesPreferenceTest {
     private val context: Context = ApplicationProvider.getApplicationContext()
+    private lateinit var dataStore: SupervisionSafeSitesDataStore
+    private lateinit var allowAllSitesPreference: SupervisionAllowAllSitesPreference
+    private lateinit var blockExplicitSitesPreference: SupervisionBlockExplicitSitesPreference
 
-    private val allowAllSitesPreference = SupervisionAllowAllSitesPreference()
-
-    private val blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference()
+    @Before
+    fun setUp() {
+        dataStore = SupervisionSafeSitesDataStore(context)
+        allowAllSitesPreference = SupervisionAllowAllSitesPreference(dataStore)
+        blockExplicitSitesPreference = SupervisionBlockExplicitSitesPreference(dataStore)
+    }
 
     @Test
     fun getTitle_allowAllSites() {
@@ -50,4 +63,64 @@
                 R.string.supervision_web_content_filters_browser_block_explicit_sites_summary
             )
     }
+
+    @Test
+    fun allowAllSitesIsChecked_whenNoValueIsSet() {
+        assertThrows(SettingNotFoundException::class.java) {
+            Settings.Secure.getInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED)
+        }
+        assertThat(getBlockExplicitSitesWidget().isChecked).isFalse()
+        assertThat(getAllowAllSitesWidget().isChecked).isTrue()
+    }
+
+    @Test
+    fun blockExplicitSitesIsChecked_whenPreviouslyEnabled() {
+        Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 1)
+        assertThat(getAllowAllSitesWidget().isChecked).isFalse()
+        assertThat(getBlockExplicitSitesWidget().isChecked).isTrue()
+    }
+
+    @Test
+    fun clickBlockExplicitSites_enablesFilter() {
+        Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 0)
+        val blockExplicitSitesWidget = getBlockExplicitSitesWidget()
+        assertThat(blockExplicitSitesWidget.isChecked).isFalse()
+
+        blockExplicitSitesWidget.performClick()
+
+        assertThat(
+            Settings.Secure.getInt(
+                context.getContentResolver(),
+                BROWSER_CONTENT_FILTERS_ENABLED,
+            )
+        )
+            .isEqualTo(1)
+        assertThat(blockExplicitSitesWidget.isChecked).isTrue()
+    }
+
+    @Test
+    fun clickAllowAllSites_disablesFilter() {
+        Settings.Secure.putInt(context.getContentResolver(), BROWSER_CONTENT_FILTERS_ENABLED, 1)
+        val allowAllSitesWidget = getAllowAllSitesWidget()
+        assertThat(allowAllSitesWidget.isChecked).isFalse()
+
+        allowAllSitesWidget.performClick()
+
+        assertThat(
+            Settings.Secure.getInt(
+                context.getContentResolver(),
+                BROWSER_CONTENT_FILTERS_ENABLED,
+            )
+        )
+            .isEqualTo(0)
+        assertThat(allowAllSitesWidget.isChecked).isTrue()
+    }
+
+    private fun getBlockExplicitSitesWidget(): SelectorWithWidgetPreference {
+        return blockExplicitSitesPreference.createAndBindWidget(context)
+    }
+
+    private fun getAllowAllSitesWidget(): SelectorWithWidgetPreference {
+        return allowAllSitesPreference.createAndBindWidget(context)
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/supervision/SupervisionWebContentFiltersScreenTest.kt b/tests/robotests/src/com/android/settings/supervision/SupervisionWebContentFiltersScreenTest.kt
index 351cbde..31bdbd2 100644
--- a/tests/robotests/src/com/android/settings/supervision/SupervisionWebContentFiltersScreenTest.kt
+++ b/tests/robotests/src/com/android/settings/supervision/SupervisionWebContentFiltersScreenTest.kt
@@ -15,18 +15,32 @@
  */
 package com.android.settings.supervision
 
+import android.app.supervision.flags.Flags
 import android.content.Context
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import androidx.fragment.app.testing.FragmentScenario
 import androidx.test.core.app.ApplicationProvider
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.settings.R
+import com.android.settingslib.widget.SelectorWithWidgetPreference
 import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @RunWith(AndroidJUnit4::class)
 class SupervisionWebContentFiltersScreenTest {
+    @get:Rule val setFlagsRule = SetFlagsRule()
     private val context: Context = ApplicationProvider.getApplicationContext()
-    private val supervisionWebContentFiltersScreen = SupervisionWebContentFiltersScreen()
+    private lateinit var supervisionWebContentFiltersScreen: SupervisionWebContentFiltersScreen
+
+    @Before
+    fun setUp() {
+        supervisionWebContentFiltersScreen = SupervisionWebContentFiltersScreen()
+    }
 
     @Test
     fun key() {
@@ -39,4 +53,40 @@
         assertThat(supervisionWebContentFiltersScreen.title)
             .isEqualTo(R.string.supervision_web_content_filters_title)
     }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
+    fun flagEnabled() {
+        assertThat(supervisionWebContentFiltersScreen.isFlagEnabled(context)).isTrue()
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
+    fun flagDisabled() {
+        assertThat(supervisionWebContentFiltersScreen.isFlagEnabled(context)).isFalse()
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_WEB_CONTENT_FILTERS_SCREEN)
+    fun switchSafeSitesPreferences() {
+        FragmentScenario.launchInContainer(supervisionWebContentFiltersScreen.fragmentClass())
+            .onFragment { fragment ->
+                val allowAllSitesPreference =
+                    fragment.findPreference<SelectorWithWidgetPreference>(
+                        SupervisionAllowAllSitesPreference.KEY
+                    )!!
+                val blockExplicitSitesPreference =
+                    fragment.findPreference<SelectorWithWidgetPreference>(
+                        SupervisionBlockExplicitSitesPreference.KEY
+                    )!!
+
+                assertThat(allowAllSitesPreference.isChecked).isTrue()
+                assertThat(blockExplicitSitesPreference.isChecked).isFalse()
+
+                blockExplicitSitesPreference.performClick()
+
+                assertThat(blockExplicitSitesPreference.isChecked).isTrue()
+                assertThat(allowAllSitesPreference.isChecked).isFalse()
+            }
+    }
 }
diff --git a/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
index 6318c9c..c5c69af 100644
--- a/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/deviceinfo/TopLevelStoragePreferenceControllerTest.java
@@ -103,6 +103,6 @@
         // the background thread.
         TimeUnit.SECONDS.sleep(5);
         assertThat(preference.getSummary()).isEqualTo(ResourcesUtils.getResourcesString(
-                mContext, "storage_summary", percentage, freeSpace));
+                mContext, "storage_toplevel_summary", percentage, freeSpace));
     }
 }
diff --git a/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoControllerTest.java
new file mode 100644
index 0000000..331a74c
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingAccountInfoControllerTest.java
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.network.telephony.satellite;
+
+import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.android.settings.network.telephony.satellite.SatelliteSettingAccountInfoController.PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN;
+import static com.android.settings.network.telephony.satellite.SatelliteSettingAccountInfoController.PREF_KEY_YOUR_SATELLITE_DATA_PLAN;
+import static com.android.settings.network.telephony.satellite.SatelliteSettingAccountInfoController.PREF_KEY_YOUR_SATELLITE_PLAN;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.os.Looper;
+import android.os.PersistableBundle;
+import android.telephony.TelephonyManager;
+import android.telephony.satellite.SatelliteManager;
+
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.settings.testutils.ResourcesUtils;
+
+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 SatelliteSettingAccountInfoControllerTest {
+    private static final int TEST_SUB_ID = 5;
+    private static final String TEST_OPERATOR_NAME = "test_operator_name";
+
+    @Rule
+    public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Mock
+    private TelephonyManager mTelephonyManager;
+
+    private Context mContext;
+    private SatelliteSettingAccountInfoController mController;
+    private final PersistableBundle mPersistableBundle = new PersistableBundle();
+
+    @Before
+    public void setUp() {
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+        }
+        mContext = spy(ApplicationProvider.getApplicationContext());
+        mController = new SatelliteSettingAccountInfoController(mContext,
+                PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        when(mContext.getSystemService(TelephonyManager.class)).thenReturn(mTelephonyManager);
+        when(mTelephonyManager.getSimOperatorName(TEST_SUB_ID)).thenReturn(TEST_OPERATOR_NAME);
+    }
+
+    @Test
+    public void getAvailabilityStatus_entitlementNotSupport_returnConditionalUnavailable() {
+        when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
+        mController.init(TEST_SUB_ID, mPersistableBundle, false, false);
+
+        int result = mController.getAvailabilityStatus(TEST_SUB_ID);
+
+        assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+    }
+
+    @Test
+    public void getAvailabilityStatus_entitlementIsSupported_returnConditionalUnavailable() {
+        mPersistableBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+        mController.init(TEST_SUB_ID, mPersistableBundle, false, false);
+
+        int result = mController.getAvailabilityStatus(TEST_SUB_ID);
+
+        assertThat(result).isEqualTo(AVAILABLE);
+    }
+
+    @Test
+    public void displayPreference_showCategoryTitle_correctOperatorName() {
+        mPersistableBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+        when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
+        mController.init(TEST_SUB_ID, mPersistableBundle, false, false);
+
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+        PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
+        preferenceCategory.setKey(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        Preference preference = new Preference(mContext);
+        preference.setKey(PREF_KEY_YOUR_SATELLITE_PLAN);
+        screen.addPreference(preferenceCategory);
+        screen.addPreference(preference);
+
+        mController.displayPreference(screen);
+
+        assertThat(preferenceCategory.getTitle().toString()).isEqualTo(
+                ResourcesUtils.getResourcesString(mContext, "category_title_your_satellite_plan",
+                        TEST_OPERATOR_NAME));
+    }
+
+    @Test
+    public void displayPreference_showEligibleUiButDataUnavailable_showSmsEligibleAccountState() {
+        mPersistableBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+        when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
+        mController = new SatelliteSettingAccountInfoController(mContext,
+                PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN) {
+            @Override
+            protected boolean isSatelliteEligible() {
+                return true;
+            }
+        };
+        mController.init(TEST_SUB_ID, mPersistableBundle, true, false);
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+        PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
+        preferenceCategory.setKey(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        Preference preference = new Preference(mContext);
+        preference.setKey(PREF_KEY_YOUR_SATELLITE_PLAN);
+        Preference preferenceData = new Preference(mContext);
+        preferenceData.setKey(PREF_KEY_YOUR_SATELLITE_DATA_PLAN);
+        screen.addPreference(preferenceCategory);
+        screen.addPreference(preference);
+        screen.addPreference(preferenceData);
+
+        mController.displayPreference(screen);
+
+        assertThat(preference.getTitle().toString()).isEqualTo(
+                ResourcesUtils.getResourcesString(mContext, "title_have_satellite_plan"));
+        assertThat(preferenceData.getTitle()).isEqualTo(null);
+    }
+
+    @Test
+    public void
+            displayPreference_showEligibleUiAndDataAvailable_showSmsAndDataEligibleAccountState() {
+        mPersistableBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+        when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
+        mController = new SatelliteSettingAccountInfoController(mContext,
+                PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN) {
+            @Override
+            protected boolean isSatelliteEligible() {
+                return true;
+            }
+        };
+        mController.init(TEST_SUB_ID, mPersistableBundle, true, true);
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+        PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
+        preferenceCategory.setKey(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        Preference preference = new Preference(mContext);
+        preference.setKey(PREF_KEY_YOUR_SATELLITE_PLAN);
+        Preference preferenceData = new Preference(mContext);
+        preferenceData.setKey(PREF_KEY_YOUR_SATELLITE_DATA_PLAN);
+        screen.addPreference(preferenceCategory);
+        screen.addPreference(preference);
+        screen.addPreference(preferenceData);
+
+        mController.displayPreference(screen);
+
+        assertThat(preference.getTitle().toString()).isEqualTo(
+                ResourcesUtils.getResourcesString(mContext, "title_have_satellite_plan"));
+        assertThat(preferenceData.getTitle().toString()).isEqualTo(
+                ResourcesUtils.getResourcesString(mContext, "title_have_satellite_data_plan"));
+    }
+
+    @Test
+    public void displayPreference_showIneligibleUi_showSmsAccountState() {
+        mPersistableBundle.putBoolean(KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL, true);
+        when(mContext.getSystemService(SatelliteManager.class)).thenReturn(null);
+        mController = new SatelliteSettingAccountInfoController(mContext,
+                PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN) {
+            @Override
+            protected boolean isSatelliteEligible() {
+                return false;
+            }
+        };
+        mController.init(TEST_SUB_ID, mPersistableBundle, false, false);
+        PreferenceScreen screen = new PreferenceManager(mContext).createPreferenceScreen(mContext);
+        PreferenceCategory preferenceCategory = new PreferenceCategory(mContext);
+        preferenceCategory.setKey(PREF_KEY_CATEGORY_YOUR_SATELLITE_PLAN);
+        Preference preference = new Preference(mContext);
+        preference.setKey(PREF_KEY_YOUR_SATELLITE_PLAN);
+        screen.addPreference(preferenceCategory);
+        screen.addPreference(preference);
+
+        mController.displayPreference(screen);
+
+        assertThat(preference.getTitle().toString()).isEqualTo(
+                ResourcesUtils.getResourcesString(mContext, "title_no_satellite_plan"));
+    }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceControllerTest.java
index c527d68..7cb85a5 100644
--- a/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceControllerTest.java
+++ b/tests/unit/src/com/android/settings/network/telephony/satellite/SatelliteSettingsPreferenceControllerTest.java
@@ -19,7 +19,6 @@
 import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_AUTOMATIC;
 import static android.telephony.CarrierConfigManager.CARRIER_ROAMING_NTN_CONNECT_MANUAL;
 import static android.telephony.CarrierConfigManager.KEY_SATELLITE_ENTITLEMENT_SUPPORTED_BOOL;
-import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_DATA;
 import static android.telephony.NetworkRegistrationInfo.SERVICE_TYPE_SMS;
 
 import static com.android.settings.core.BasePreferenceController.AVAILABLE;
@@ -183,40 +182,6 @@
 
     @Test
     @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
-    public void title_hasServiceDataType_showDataUi() {
-        mController.initialize(TEST_SUB_ID);
-        PreferenceManager preferenceManager = new PreferenceManager(mContext);
-        PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
-        Preference preference = new Preference(mContext);
-        preference.setKey(KEY);
-        preference.setTitle("test title");
-        preferenceScreen.addPreference(preference);
-        mController.displayPreference(preferenceScreen);
-        mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged(
-                new int[]{SERVICE_TYPE_SMS, SERVICE_TYPE_DATA});
-
-        assertThat(preference.getTitle()).isEqualTo("Satellite connectivity");
-    }
-
-    @Test
-    @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
-    public void title_onlyHasServiceSmsType_showSmsUi() {
-        mController.initialize(TEST_SUB_ID);
-        PreferenceManager preferenceManager = new PreferenceManager(mContext);
-        PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
-        Preference preference = new Preference(mContext);
-        preference.setKey(KEY);
-        preference.setTitle("test title");
-        preferenceScreen.addPreference(preference);
-        mController.displayPreference(preferenceScreen);
-        mController.mCarrierRoamingNtnModeCallback.onCarrierRoamingNtnAvailableServicesChanged(
-                new int[]{SERVICE_TYPE_SMS});
-
-        assertThat(preference.getTitle()).isEqualTo("Satellite messaging");
-    }
-
-    @Test
-    @EnableFlags(com.android.settings.flags.Flags.FLAG_SATELLITE_OEM_SETTINGS_UX_MIGRATION)
     public void summary_noEntitlementAndTypeIsAuto_showSummaryWithoutEntitlement() {
         mCarrierConfig.putInt(
                 CarrierConfigManager.KEY_CARRIER_ROAMING_NTN_CONNECT_TYPE_INT,