diff --git a/Android.bp b/Android.bp
index c966eca2e92..ed094cfae72 100644
--- a/Android.bp
+++ b/Android.bp
@@ -115,6 +115,7 @@ android_library {
"device_policy_aconfig_flags_lib",
"keyboard_flags_lib",
"settings_connectivity_flags",
+ "com_android_systemui_flags_lib",
],
plugins: [
diff --git a/res/drawable/keyboard_arrow_left.xml b/res/drawable/keyboard_arrow_left.xml
new file mode 100644
index 00000000000..77a2bfb6046
--- /dev/null
+++ b/res/drawable/keyboard_arrow_left.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/keyboard_arrow_right.xml b/res/drawable/keyboard_arrow_right.xml
new file mode 100644
index 00000000000..5b0dd3d27dd
--- /dev/null
+++ b/res/drawable/keyboard_arrow_right.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/accessibility_text_reading_preview.xml b/res/layout/accessibility_text_reading_preview.xml
index 830d9e66778..9c3ce31db22 100644
--- a/res/layout/accessibility_text_reading_preview.xml
+++ b/res/layout/accessibility_text_reading_preview.xml
@@ -38,20 +38,45 @@
android:text="@string/screen_zoom_preview_title"
style="@style/AccessibilityTextReadingPreviewTitle" />
-
-
-
+ android:orientation="vertical">
+
+
+
+
+
+
+
diff --git a/res/layout/display_topology_preference.xml b/res/layout/display_topology_preference.xml
index 9f2805d0e83..add84b6b235 100644
--- a/res/layout/display_topology_preference.xml
+++ b/res/layout/display_topology_preference.xml
@@ -14,13 +14,19 @@
limitations under the License.
-->
+
diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml
index 79949ceb85b..4edb6f43688 100644
--- a/res/values-night/colors.xml
+++ b/res/values-night/colors.xml
@@ -82,5 +82,9 @@
@color/settingslib_color_charcoal
@android:color/system_secondary_dark
+
+
+ @android:color/system_accent1_100
+ @android:color/system_accent1_100
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 73efeb232fa..c9e01e5a612 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -222,4 +222,9 @@
@color/settingslib_color_grey100
@android:color/system_secondary_light
+
+
+ @android:color/system_accent1_800
+ @android:color/system_accent1_800
+ @android:color/system_neutral2_50
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 0e88e265867..ddce9e6a9df 100755
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -552,6 +552,7 @@
24dp
+ 24dp
5dp
2dp
10dp
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6f328a341db..694700c3aff 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -78,6 +78,11 @@
Preview
+
+ Previous preview
+
+ Next preview
+
QR code
@@ -12602,6 +12607,12 @@
satellite messaging
Use of data is included with your account
+
+ Supported apps on your phone
+
+ see all apps
+
+ Supported apps on your phone
Access Point Names
diff --git a/res/xml/development_settings.xml b/res/xml/development_settings.xml
index 2f9a9b98585..518e2d16e73 100644
--- a/res/xml/development_settings.xml
+++ b/res/xml/development_settings.xml
@@ -745,32 +745,6 @@
android:title="@string/force_allow_on_external"
android:summary="@string/force_allow_on_external_summary" />
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:order="1200">
+ android:order="1300">
+ android:order="1400">
@@ -857,7 +865,7 @@
+ android:order="1500">
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
index 9161171914a..717da70e49c 100644
--- a/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
+++ b/src/com/android/settings/accessibility/TextReadingPreviewPreference.java
@@ -22,6 +22,7 @@ import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.View;
import android.widget.FrameLayout;
+import android.widget.ImageButton;
import android.widget.LinearLayout;
import androidx.preference.Preference;
@@ -99,6 +100,23 @@ public class TextReadingPreviewPreference extends Preference {
(DotsPageIndicator) holder.findViewById(R.id.page_indicator);
updateAdapterIfNeeded(viewPager, pageIndicator, mPreviewAdapter);
updatePagerAndIndicator(viewPager, pageIndicator);
+ viewPager.setClipToOutline(true);
+
+ int layoutDirection =
+ getContext().getResources().getConfiguration().getLayoutDirection();
+ int previousId = (layoutDirection == View.LAYOUT_DIRECTION_RTL)
+ ? R.id.preview_right_button : R.id.preview_left_button;
+ int nextId = (layoutDirection == View.LAYOUT_DIRECTION_RTL)
+ ? R.id.preview_left_button : R.id.preview_right_button;
+ final ImageButton previousButton = previewLayout.findViewById(previousId);
+ final ImageButton nextButton = previewLayout.findViewById(nextId);
+
+ previousButton.setOnClickListener((view) -> setCurrentItem(getCurrentItem() - 1));
+ previousButton.setContentDescription(getContext().getString(
+ R.string.preview_pager_previous_button));
+ nextButton.setOnClickListener((view) -> setCurrentItem(getCurrentItem() + 1));
+ previousButton.setContentDescription(getContext().getString(
+ R.string.preview_pager_next_button));
}
@Override
@@ -158,7 +176,9 @@ public class TextReadingPreviewPreference extends Preference {
Preconditions.checkNotNull(mPreviewAdapter,
"Preview adapter is null, you should init the preview adapter first");
- if (currentItem != mCurrentItem) {
+ if (currentItem < 0 || currentItem >= mPreviewAdapter.getCount()) {
+ return;
+ } else if (currentItem != mCurrentItem) {
mCurrentItem = currentItem;
notifyChanged();
}
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index 6773fdcf1ce..31ebeb7c705 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -1067,8 +1067,11 @@ public class FingerprintSettings extends SubSettings {
mRemovalSidecar.setListener(mRemovalListener);
}
- mCalibrator = FeatureFactory.getFeatureFactory().getFingerprintFeatureProvider()
- .getUdfpsEnrollCalibrator(getActivity().getApplicationContext(), null, null);
+ if (!mLaunchedConfirm && !mIsEnrolling) {
+ mCalibrator = FeatureFactory.getFeatureFactory().getFingerprintFeatureProvider()
+ .getUdfpsEnrollCalibrator(getActivity().getApplicationContext(), null,
+ null);
+ }
}
private void updatePreferences() {
@@ -1517,6 +1520,11 @@ public class FingerprintSettings extends SubSettings {
intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken);
intent.putExtra(BiometricEnrollBase.EXTRA_KEY_CHALLENGE, mChallenge);
}
+
+ if (mCalibrator != null) {
+ intent.putExtras(mCalibrator.getExtrasForNextIntent());
+ }
+
startActivityForResult(intent, AUTO_ADD_FIRST_FINGERPRINT_REQUEST);
}
diff --git a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
index bd160e17527..dab696e5e0b 100644
--- a/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdater.java
@@ -79,7 +79,8 @@ public class AvailableMediaBluetoothDeviceUpdater extends BluetoothDeviceUpdater
// If device is LE Audio, it is compatible with HFP and A2DP.
// It would show in Available Devices group if the audio sharing flag is disabled or
// the device is not in the audio sharing session.
- if (cachedDevice.isConnectedLeAudioDevice()) {
+ if (cachedDevice.isConnectedLeAudioDevice()
+ || cachedDevice.hasConnectedLeAudioMemberDevice()) {
if (BluetoothUtils.isAudioSharingUIAvailable(mContext)
&& BluetoothUtils.hasConnectedBroadcastSource(
cachedDevice, mLocalBtManager)) {
diff --git a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
index 7cc874caba9..a0f5ea23050 100644
--- a/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdater.java
@@ -77,7 +77,12 @@ public class ConnectedBluetoothDeviceUpdater extends BluetoothDeviceUpdater {
// If device is Hearing Aid or LE Audio, it is compatible with HFP and A2DP.
// It would not show in Connected Devices group.
if (cachedDevice.isConnectedAshaHearingAidDevice()
- || cachedDevice.isConnectedLeAudioDevice()) {
+ || cachedDevice.isConnectedLeAudioDevice()
+ || cachedDevice.hasConnectedLeAudioMemberDevice()) {
+ if (DBG) {
+ Log.d(TAG, "isFilterMatched() device : " + cachedDevice.getName()
+ + ", isFilterMatched : false, ha or lea device");
+ }
return false;
}
// According to the current audio profile type,
diff --git a/src/com/android/settings/communal/CommunalPreferenceController.java b/src/com/android/settings/communal/CommunalPreferenceController.java
index f93746833ff..e44afab90a6 100644
--- a/src/com/android/settings/communal/CommunalPreferenceController.java
+++ b/src/com/android/settings/communal/CommunalPreferenceController.java
@@ -21,7 +21,6 @@ import android.content.Context;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.core.BasePreferenceController;
-import com.android.settings.flags.Flags;
/**
* Controls the top-level Communal settings preference.
@@ -40,14 +39,15 @@ public class CommunalPreferenceController extends BasePreferenceController {
* Returns whether communal preferences are available.
*/
public static boolean isAvailable(Context context) {
+ if (!Utils.canCurrentUserDream(context)) {
+ return false;
+ }
+
if (context.getResources().getBoolean(R.bool.config_show_communal_settings)) {
- return Utils.canCurrentUserDream(context);
+ return true;
}
- if (context.getResources().getBoolean(R.bool.config_show_communal_settings_mobile)) {
- return Flags.enableHubModeSettingsOnMobile() && Utils.canCurrentUserDream(context);
- }
-
- return false;
+ return com.android.systemui.Flags.glanceableHubV2()
+ && context.getResources().getBoolean(R.bool.config_show_communal_settings_mobile);
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
index e5b984d707c..884c7813434 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdater.java
@@ -56,7 +56,8 @@ public class AudioSharingBluetoothDeviceUpdater extends BluetoothDeviceUpdater
// If device is LE audio device and has a broadcast source,
// it would show in audio sharing devices group.
if (BluetoothUtils.isAudioSharingUIAvailable(mContext)
- && cachedDevice.isConnectedLeAudioDevice()
+ && (cachedDevice.isConnectedLeAudioDevice()
+ || cachedDevice.hasConnectedLeAudioMemberDevice())
&& BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, mLocalBtManager)) {
isFilterMatched = true;
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
index 548d17cc9ce..7f12ec84b3b 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdater.java
@@ -62,7 +62,8 @@ public class AudioSharingDeviceVolumeControlUpdater extends BluetoothDeviceUpdat
if (isDeviceConnected(cachedDevice) && isDeviceInCachedDevicesList(cachedDevice)) {
// If device is LE audio device and in a sharing session on current sharing device,
// it would show in volume control group.
- if (cachedDevice.isConnectedLeAudioDevice()
+ if ((cachedDevice.isConnectedLeAudioDevice()
+ || cachedDevice.hasConnectedLeAudioMemberDevice())
&& BluetoothUtils.isBroadcasting(mBtManager)
&& BluetoothUtils.hasConnectedBroadcastSource(cachedDevice, mBtManager)) {
isFilterMatched = true;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
index be0ee0b8b44..7b670a80fba 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java
@@ -51,10 +51,9 @@ import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.bluetooth.VolumeControlProfile;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -73,8 +72,9 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre
private final Executor mExecutor;
private final ContentObserver mSettingsObserver;
@Nullable private PreferenceGroup mPreferenceGroup;
- private List mVolumePreferences = new ArrayList<>();
- private Map mValueMap = new HashMap();
+ private CopyOnWriteArraySet mVolumePreferences =
+ new CopyOnWriteArraySet<>();
+ private ConcurrentHashMap mValueMap = new ConcurrentHashMap<>();
private AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
@VisibleForTesting
@@ -104,8 +104,8 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre
+ finalVolume
+ " for "
+ device.getAnonymizedAddress());
- mContext.getMainExecutor()
- .execute(() -> preference.setProgress(finalVolume));
+ AudioSharingUtils.postOnMainThread(mContext,
+ () -> preference.setProgress(finalVolume));
break;
}
}
@@ -196,7 +196,9 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre
public void onChange(boolean selfChange) {
Log.d(TAG, "onChange, fallback device group id has been changed");
for (AudioSharingDeviceVolumePreference preference : mVolumePreferences) {
- preference.setOrder(getPreferenceOrderForDevice(preference.getCachedDevice()));
+ int order = getPreferenceOrderForDevice(preference.getCachedDevice());
+ Log.d(TAG, "onChange: set order to " + order + " for " + preference);
+ AudioSharingUtils.postOnMainThread(mContext, () -> preference.setOrder(order));
}
}
}
@@ -240,52 +242,54 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre
@Override
public void onDeviceAdded(Preference preference) {
- if (mPreferenceGroup != null) {
- if (mPreferenceGroup.getPreferenceCount() == 0) {
- mPreferenceGroup.setVisible(true);
+ if (!(preference instanceof AudioSharingDeviceVolumePreference)) {
+ Log.d(TAG, "Skip onDeviceAdded, invalid preference type");
+ return;
+ }
+ var volumePref = (AudioSharingDeviceVolumePreference) preference;
+ mVolumePreferences.add(volumePref);
+ AudioSharingUtils.postOnMainThread(mContext, () -> {
+ if (mPreferenceGroup != null) {
+ if (mPreferenceGroup.getPreferenceCount() == 0) {
+ mPreferenceGroup.setVisible(true);
+ }
+ mPreferenceGroup.addPreference(volumePref);
}
- mPreferenceGroup.addPreference(preference);
- }
- if (preference instanceof AudioSharingDeviceVolumePreference) {
- var volumePref = (AudioSharingDeviceVolumePreference) preference;
- CachedBluetoothDevice cachedDevice = volumePref.getCachedDevice();
- volumePref.setOrder(getPreferenceOrderForDevice(cachedDevice));
- mVolumePreferences.add(volumePref);
- if (volumePref.getProgress() > 0) return;
- int volume = mValueMap.getOrDefault(BluetoothUtils.getGroupId(cachedDevice), -1);
- // If the volume is invalid, try to get the volume from AudioManager.STREAM_MUSIC
- int finalVolume = getAudioVolumeIfNeeded(volume);
- Log.d(
- TAG,
- "onDeviceAdded: set volume to "
- + finalVolume
- + " for "
- + cachedDevice.getDevice().getAnonymizedAddress());
- AudioSharingUtils.postOnMainThread(mContext, () -> volumePref.setProgress(finalVolume));
- }
+ });
+ CachedBluetoothDevice cachedDevice = volumePref.getCachedDevice();
+ String address = cachedDevice.getDevice() == null ? "null"
+ : cachedDevice.getDevice().getAnonymizedAddress();
+ int order = getPreferenceOrderForDevice(cachedDevice);
+ Log.d(TAG, "onDeviceAdded: set order to " + order + " for " + address);
+ AudioSharingUtils.postOnMainThread(mContext, () -> volumePref.setOrder(order));
+ int volume = mValueMap.getOrDefault(BluetoothUtils.getGroupId(cachedDevice), -1);
+ // If the volume is invalid, try to get the volume from AudioManager.STREAM_MUSIC
+ int finalVolume = getAudioVolumeIfNeeded(volume);
+ Log.d(TAG, "onDeviceAdded: set volume to " + finalVolume + " for " + address);
+ AudioSharingUtils.postOnMainThread(mContext, () -> volumePref.setProgress(finalVolume));
}
@Override
public void onDeviceRemoved(Preference preference) {
- if (mPreferenceGroup != null) {
- mPreferenceGroup.removePreference(preference);
- if (mPreferenceGroup.getPreferenceCount() == 0) {
- mPreferenceGroup.setVisible(false);
- }
+ if (!(preference instanceof AudioSharingDeviceVolumePreference)) {
+ Log.d(TAG, "Skip onDeviceRemoved, invalid preference type");
+ return;
}
- if (preference instanceof AudioSharingDeviceVolumePreference) {
- var volumePref = (AudioSharingDeviceVolumePreference) preference;
- if (mVolumePreferences.contains(volumePref)) {
- mVolumePreferences.remove(volumePref);
- }
- CachedBluetoothDevice device = volumePref.getCachedDevice();
- Log.d(
- TAG,
- "onDeviceRemoved: "
- + (device == null
- ? "null"
- : device.getDevice().getAnonymizedAddress()));
+ var volumePref = (AudioSharingDeviceVolumePreference) preference;
+ if (mVolumePreferences.contains(volumePref)) {
+ mVolumePreferences.remove(volumePref);
}
+ String address = volumePref.getCachedDevice().getDevice() == null ? "null"
+ : volumePref.getCachedDevice().getDevice().getAnonymizedAddress();
+ Log.d(TAG, "onDeviceRemoved: " + address);
+ AudioSharingUtils.postOnMainThread(mContext, () -> {
+ if (mPreferenceGroup != null) {
+ mPreferenceGroup.removePreference(volumePref);
+ if (mPreferenceGroup.getPreferenceCount() == 0) {
+ mPreferenceGroup.setVisible(false);
+ }
+ }
+ });
}
@Override
diff --git a/src/com/android/settings/connecteddevice/display/DisplayTopologyPreference.kt b/src/com/android/settings/connecteddevice/display/DisplayTopologyPreference.kt
index 42e633f62e7..7894a7e6c0d 100644
--- a/src/com/android/settings/connecteddevice/display/DisplayTopologyPreference.kt
+++ b/src/com/android/settings/connecteddevice/display/DisplayTopologyPreference.kt
@@ -16,9 +16,10 @@
package com.android.settings.connecteddevice.display
-import android.app.WallpaperManager
import com.android.settings.R
+import com.android.settingslib.widget.GroupSectionDividerMixin
+import android.app.WallpaperManager
import android.content.Context
import android.graphics.Bitmap
import android.graphics.PointF
@@ -45,7 +46,7 @@ import kotlin.math.abs
* when there is one or more extended display attached.
*/
class DisplayTopologyPreference(context : Context)
- : Preference(context), ViewTreeObserver.OnGlobalLayoutListener {
+ : Preference(context), ViewTreeObserver.OnGlobalLayoutListener, GroupSectionDividerMixin {
@VisibleForTesting lateinit var mPaneContent : FrameLayout
@VisibleForTesting lateinit var mPaneHolder : FrameLayout
@VisibleForTesting lateinit var mTopologyHint : TextView
@@ -82,6 +83,8 @@ class DisplayTopologyPreference(context : Context)
isPersistent = false
+ isCopyingEnabled = false
+
injector = Injector(context)
}
diff --git a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
index 3a4e4e973b3..246359aa171 100644
--- a/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
+++ b/src/com/android/settings/development/DevelopmentSettingsDashboardFragment.java
@@ -72,10 +72,16 @@ import com.android.settings.development.bluetooth.BluetoothHDAudioPreferenceCont
import com.android.settings.development.bluetooth.BluetoothQualityDialogPreferenceController;
import com.android.settings.development.bluetooth.BluetoothSampleRateDialogPreferenceController;
import com.android.settings.development.bluetooth.BluetoothStackLogPreferenceController;
+import com.android.settings.development.desktopexperience.DesktopExperiencePreferenceController;
+import com.android.settings.development.desktopexperience.DesktopModePreferenceController;
+import com.android.settings.development.desktopexperience.DesktopModeSecondaryDisplayPreferenceController;
+import com.android.settings.development.desktopexperience.FreeformWindowsPreferenceController;
import com.android.settings.development.graphicsdriver.GraphicsDriverEnableAngleAsSystemDriverController;
import com.android.settings.development.linuxterminal.LinuxTerminalPreferenceController;
import com.android.settings.development.qstile.DevelopmentTiles;
import com.android.settings.development.storage.SharedDataPreferenceController;
+import com.android.settings.development.window.NonResizableMultiWindowPreferenceController;
+import com.android.settings.development.window.ResizableActivityPreferenceController;
import com.android.settings.overlay.FeatureFactory;
import com.android.settings.password.ConfirmDeviceCredentialActivity;
import com.android.settings.search.BaseSearchIndexProvider;
diff --git a/src/com/android/settings/development/DesktopExperiencePreferenceController.java b/src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceController.java
similarity index 94%
rename from src/com/android/settings/development/DesktopExperiencePreferenceController.java
rename to src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceController.java
index 28e92fcdac5..4075eaf77f6 100644
--- a/src/com/android/settings/development/DesktopExperiencePreferenceController.java
+++ b/src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_EXPERIENCE_FEATURES;
import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF;
@@ -33,6 +33,9 @@ import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
+import com.android.settings.development.RebootConfirmationDialogHost;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
diff --git a/src/com/android/settings/development/DesktopModePreferenceController.java b/src/com/android/settings/development/desktopexperience/DesktopModePreferenceController.java
similarity index 93%
rename from src/com/android/settings/development/DesktopModePreferenceController.java
rename to src/com/android/settings/development/desktopexperience/DesktopModePreferenceController.java
index 4c6da1ee1cd..50691f60a7a 100644
--- a/src/com/android/settings/development/DesktopModePreferenceController.java
+++ b/src/com/android/settings/development/desktopexperience/DesktopModePreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES;
import static android.window.DesktopModeFlags.ToggleOverride.fromSetting;
@@ -33,6 +33,9 @@ import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
+import com.android.settings.development.RebootConfirmationDialogHost;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
diff --git a/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java b/src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceController.java
similarity index 93%
rename from src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java
rename to src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceController.java
index 899b921e47f..d61d537c533 100644
--- a/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceController.java
+++ b/src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
@@ -29,6 +29,9 @@ import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
+import com.android.settings.development.RebootConfirmationDialogHost;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
diff --git a/src/com/android/settings/development/FreeformWindowsPreferenceController.java b/src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceController.java
similarity index 92%
rename from src/com/android/settings/development/FreeformWindowsPreferenceController.java
rename to src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceController.java
index 6cf1563bce5..60712408322 100644
--- a/src/com/android/settings/development/FreeformWindowsPreferenceController.java
+++ b/src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
@@ -28,6 +28,9 @@ import androidx.preference.TwoStatePreference;
import com.android.settings.R;
import com.android.settings.core.PreferenceControllerMixin;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
+import com.android.settings.development.RebootConfirmationDialogHost;
import com.android.settingslib.development.DeveloperOptionsPreferenceController;
import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
diff --git a/src/com/android/settings/development/desktopexperience/OWNERS b/src/com/android/settings/development/desktopexperience/OWNERS
new file mode 100644
index 00000000000..6be8a6421d2
--- /dev/null
+++ b/src/com/android/settings/development/desktopexperience/OWNERS
@@ -0,0 +1,3 @@
+include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS
\ No newline at end of file
diff --git a/src/com/android/settings/development/NonResizableMultiWindowPreferenceController.java b/src/com/android/settings/development/window/NonResizableMultiWindowPreferenceController.java
similarity index 98%
rename from src/com/android/settings/development/NonResizableMultiWindowPreferenceController.java
rename to src/com/android/settings/development/window/NonResizableMultiWindowPreferenceController.java
index 50d90bdb3e6..f2f2de5c88a 100644
--- a/src/com/android/settings/development/NonResizableMultiWindowPreferenceController.java
+++ b/src/com/android/settings/development/window/NonResizableMultiWindowPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.window;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
diff --git a/src/com/android/settings/development/window/OWNERS b/src/com/android/settings/development/window/OWNERS
new file mode 100644
index 00000000000..c437f15567d
--- /dev/null
+++ b/src/com/android/settings/development/window/OWNERS
@@ -0,0 +1,2 @@
+include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS
\ No newline at end of file
diff --git a/src/com/android/settings/development/ResizableActivityPreferenceController.java b/src/com/android/settings/development/window/ResizableActivityPreferenceController.java
similarity index 94%
rename from src/com/android/settings/development/ResizableActivityPreferenceController.java
rename to src/com/android/settings/development/window/ResizableActivityPreferenceController.java
index 28b1478d49e..06b819eaa81 100644
--- a/src/com/android/settings/development/ResizableActivityPreferenceController.java
+++ b/src/com/android/settings/development/window/ResizableActivityPreferenceController.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.window;
import android.content.Context;
import android.provider.Settings;
@@ -32,9 +32,9 @@ public class ResizableActivityPreferenceController extends DeveloperOptionsPrefe
private static final String FORCE_RESIZABLE_KEY = "force_resizable_activities";
@VisibleForTesting
- final static int SETTING_VALUE_ON = 1;
+ static final int SETTING_VALUE_ON = 1;
@VisibleForTesting
- final static int SETTING_VALUE_OFF = 0;
+ static final int SETTING_VALUE_OFF = 0;
public ResizableActivityPreferenceController(Context context) {
super(context);
diff --git a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
index c0caff7a494..cb8e6fc03b0 100644
--- a/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
+++ b/src/com/android/settings/deviceinfo/storage/StorageItemPreferenceController.java
@@ -475,7 +475,10 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
updatePrivateStorageCategoryPreferencesOrder();
mIsPreferenceOrderedBySize = true;
}
- setPrivateStorageCategoryPreferencesVisibility(true);
+
+ if (isValidPrivateVolume()) {
+ setPrivateStorageCategoryPreferencesVisibility(true);
+ }
}
private StorageCacheHelper.StorageCache getSizeInfo(
diff --git a/src/com/android/settings/network/SatelliteRepository.kt b/src/com/android/settings/network/SatelliteRepository.kt
index c70484a7e7a..994f8ec96d4 100644
--- a/src/com/android/settings/network/SatelliteRepository.kt
+++ b/src/com/android/settings/network/SatelliteRepository.kt
@@ -23,6 +23,7 @@ import android.telephony.satellite.SatelliteModemStateCallback
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.concurrent.futures.CallbackToFutureAdapter
+import com.android.internal.telephony.flags.Flags
import com.google.common.util.concurrent.Futures.immediateFuture
import com.google.common.util.concurrent.ListenableFuture
import java.util.concurrent.Executor
@@ -40,7 +41,7 @@ import kotlinx.coroutines.flow.flowOn
/**
* A repository class for interacting with the SatelliteManager API.
*/
-class SatelliteRepository(
+open class SatelliteRepository(
private val context: Context,
) {
@@ -196,6 +197,28 @@ class SatelliteRepository(
}
}
+ /**
+ * @return A list with application package names which support Satellite service.
+ * e.g. "com.android.settings"
+ */
+ open fun getSatelliteDataOptimizedApps(): List {
+ if (!Flags.satellite25q4Apis()) {
+ return emptyList()
+ }
+ val satelliteManager: SatelliteManager? =
+ context.getSystemService(SatelliteManager::class.java)
+ if (satelliteManager == null) {
+ Log.d(TAG, "SatelliteManager is null")
+ return emptyList()
+ }
+ try {
+ return satelliteManager.getSatelliteDataOptimizedApps();
+ } catch (e: IllegalStateException) {
+ Log.w(TAG, "IllegalStateException $e")
+ }
+ return emptyList()
+ }
+
companion object {
private const val TAG: String = "SatelliteRepository"
diff --git a/src/com/android/settings/network/telephony/SatelliteAppListCategoryController.java b/src/com/android/settings/network/telephony/SatelliteAppListCategoryController.java
new file mode 100644
index 00000000000..4afa7f245ff
--- /dev/null
+++ b/src/com/android/settings/network/telephony/SatelliteAppListCategoryController.java
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.drawable.Drawable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceScreen;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.network.SatelliteRepository;
+import com.android.settingslib.Utils;
+
+import java.util.List;
+
+/** A controller to show some of apps info which supported on Satellite service. */
+public class SatelliteAppListCategoryController extends BasePreferenceController {
+ private static final String TAG = "SatelliteAppListCategoryController";
+ @VisibleForTesting
+ static final int MAXIMUM_OF_PREFERENCE_AMOUNT = 3;
+
+ private List mPackageNameList;
+
+ public SatelliteAppListCategoryController(
+ @NonNull Context context,
+ @NonNull String preferenceKey) {
+ super(context, preferenceKey);
+ }
+
+ /** Initialize the necessary applications' data*/
+ public void init() {
+ SatelliteRepository satelliteRepository = new SatelliteRepository(mContext);
+ init(satelliteRepository);
+ }
+
+ @VisibleForTesting
+ void init(@NonNull SatelliteRepository satelliteRepository) {
+ mPackageNameList = satelliteRepository.getSatelliteDataOptimizedApps();
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ PreferenceCategory preferenceCategory = screen.findPreference(getPreferenceKey());
+ for (int i = 0; i < mPackageNameList.size() && i < MAXIMUM_OF_PREFERENCE_AMOUNT; i++) {
+ String packageName = mPackageNameList.get(i);
+ ApplicationInfo appInfo = getApplicationInfo(mContext, packageName);
+ if (appInfo != null) {
+ Drawable icon = Utils.getBadgedIcon(mContext, appInfo);
+ CharSequence name = appInfo.loadLabel(mContext.getPackageManager());
+ Preference pref = new Preference(mContext);
+ pref.setIcon(icon);
+ pref.setTitle(name);
+ preferenceCategory.addPreference(pref);
+ }
+ }
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ if (!Flags.satellite25q4Apis()) {
+ return CONDITIONALLY_UNAVAILABLE;
+ }
+ return mPackageNameList.isEmpty()
+ ? CONDITIONALLY_UNAVAILABLE
+ : AVAILABLE;
+ }
+
+ static ApplicationInfo getApplicationInfo(Context context, String packageName) {
+ try {
+ PackageManager pm = context.getPackageManager();
+ return pm.getApplicationInfoAsUser(packageName, /* flags= */ 0, context.getUserId());
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ }
+}
diff --git a/src/com/android/settings/network/telephony/SatelliteAppListFragment.java b/src/com/android/settings/network/telephony/SatelliteAppListFragment.java
new file mode 100644
index 00000000000..97f70bb2652
--- /dev/null
+++ b/src/com/android/settings/network/telephony/SatelliteAppListFragment.java
@@ -0,0 +1,126 @@
+/*
+ * 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;
+
+import static com.android.settings.network.telephony.SatelliteAppListCategoryController.getApplicationInfo;
+
+import android.app.settings.SettingsEnums;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.graphics.drawable.Drawable;
+import android.os.UserManager;
+import android.util.Log;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+
+import com.android.settings.R;
+import com.android.settings.core.BasePreferenceController;
+import com.android.settings.dashboard.RestrictedDashboardFragment;
+import com.android.settings.network.SatelliteRepository;
+import com.android.settingslib.Utils;
+import com.android.settingslib.core.AbstractPreferenceController;
+
+import org.checkerframework.checker.nullness.qual.NonNull;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/** Shows all applications which support satellite service. */
+public class SatelliteAppListFragment extends RestrictedDashboardFragment {
+ public SatelliteAppListFragment() {
+ super(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+ }
+
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ use(SatelliteAppListPreferenceController.class).init();
+ }
+
+ @Override
+ protected List createPreferenceControllers(Context context) {
+ SatelliteAppListPreferenceController satelliteAppListPreferenceController =
+ new SatelliteAppListPreferenceController(getContext());
+ return List.of(satelliteAppListPreferenceController);
+ }
+
+ @Override
+ protected int getPreferenceScreenResId() {
+ return R.xml.satellite_settings_apps_list;
+ }
+
+ @Override
+ protected String getLogTag() {
+ return "SatelliteAppListFragment";
+ }
+
+ @Override
+ public int getMetricsCategory() {
+ return SettingsEnums.SATELLITE_APPS_LIST;
+ }
+
+ @VisibleForTesting
+ static class SatelliteAppListPreferenceController extends BasePreferenceController {
+ private static final String TAG = "SatelliteAppListPreferenceController";
+ private static final String KEY = "key_satellite_app_list";
+
+ private List mApplicationInfoList = List.of();
+
+ SatelliteAppListPreferenceController(@NonNull Context context) {
+ super(context, KEY);
+ }
+
+ public void init() {
+ SatelliteRepository satelliteRepository = new SatelliteRepository(mContext);
+ init(satelliteRepository);
+ }
+
+ void init(@NonNull SatelliteRepository satelliteRepository) {
+ mApplicationInfoList =
+ satelliteRepository.getSatelliteDataOptimizedApps()
+ .stream()
+ .map(name -> getApplicationInfo(mContext, name))
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ if (mApplicationInfoList.isEmpty()) {
+ return;
+ }
+ mApplicationInfoList.forEach(appInfo -> {
+ if (appInfo != null) {
+ Log.i(TAG, "Add preference to UI : " + appInfo.packageName);
+ Drawable icon = Utils.getBadgedIcon(mContext, appInfo);
+ CharSequence name = appInfo.loadLabel(mContext.getPackageManager());
+ Preference pref = new Preference(mContext);
+ pref.setIcon(icon);
+ pref.setTitle(name);
+ screen.addPreference(pref);
+ }
+ });
+ }
+
+ @Override
+ public int getAvailabilityStatus() {
+ return AVAILABLE;
+ }
+ }
+}
diff --git a/src/com/android/settings/network/telephony/SatelliteSetting.java b/src/com/android/settings/network/telephony/SatelliteSetting.java
index d4bd212d153..bc10abb212d 100644
--- a/src/com/android/settings/network/telephony/SatelliteSetting.java
+++ b/src/com/android/settings/network/telephony/SatelliteSetting.java
@@ -26,6 +26,7 @@ import static android.telephony.CarrierConfigManager.KEY_SATELLITE_INFORMATION_R
import android.app.Activity;
import android.app.settings.SettingsEnums;
+import android.content.Context;
import android.content.Intent;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
@@ -92,6 +93,12 @@ public class SatelliteSetting extends RestrictedDashboardFragment {
return SettingsEnums.SATELLITE_SETTING;
}
+ @Override
+ public void onAttach(Context context) {
+ super.onAttach(context);
+ use(SatelliteAppListCategoryController.class).init();
+ }
+
@Override
public void onCreate(@NonNull Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
diff --git a/src/com/android/settings/network/telephony/SubscriptionActivationRepository.kt b/src/com/android/settings/network/telephony/SubscriptionActivationRepository.kt
index 185af0c3d09..a7f6a0b5dcb 100644
--- a/src/com/android/settings/network/telephony/SubscriptionActivationRepository.kt
+++ b/src/com/android/settings/network/telephony/SubscriptionActivationRepository.kt
@@ -52,7 +52,7 @@ class SubscriptionActivationRepository(
Log.i(TAG, "Unable to toggle subscription due to unusable subscription ID.")
return
}
- if (!active && isEmergencyCallbackMode(subId)) {
+ if (isEmergencyCallbackMode(subId)) {
val intent = Intent(ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS).apply {
setPackage(Utils.PHONE_PACKAGE_NAME)
}
diff --git a/src/com/android/settings/widget/ValidatedEditTextPreference.java b/src/com/android/settings/widget/ValidatedEditTextPreference.java
index cc344ac67f1..c85e81ef381 100644
--- a/src/com/android/settings/widget/ValidatedEditTextPreference.java
+++ b/src/com/android/settings/widget/ValidatedEditTextPreference.java
@@ -67,6 +67,9 @@ public class ValidatedEditTextPreference extends CustomEditTextPreferenceCompat
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
final EditText editText = view.findViewById(android.R.id.edit);
+ if (editText != null) {
+ editText.setHint(getDialogTitle());
+ }
if (editText != null && !TextUtils.isEmpty(editText.getText())) {
editText.setSelection(editText.getText().length());
}
diff --git a/tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java b/tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java
index e4ebdefb1a5..8e8dba82d7d 100644
--- a/tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java
+++ b/tests/Enable16KbTests/src/com/android/test/Enable16KbTest.java
@@ -51,7 +51,12 @@ public class Enable16KbTest extends BaseHostJUnit4Test {
@Test
@AppModeFull
public void enable16KbToggle() throws Exception {
- assertTrue(isPackageInstalled(APP_PACKAGE));
+ // Wait for 2 mins device to be online
+ getDevice().waitForDeviceOnline(120000);
+ if (!isPackageInstalled(APP_PACKAGE)) {
+ //If test app has failed for some reason, retry installation
+ installTestApp();
+ }
// Check if developer option is enabled otherwise exit
getDevice().enableAdbRoot();
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index 464d9708c0a..bb70a702b6d 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -77,6 +77,7 @@ android_robolectric_test {
"platform-test-annotations",
"testables",
"android.app.flags-aconfig-java",
+ "com_android_systemui_flags_lib",
],
libs: [
diff --git a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
index 2251c3bff5a..87d7aed8f19 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/AvailableMediaBluetoothDeviceUpdaterTest.java
@@ -282,6 +282,28 @@ public class AvailableMediaBluetoothDeviceUpdaterTest {
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
}
+ @Test
+ public void
+ onProfileConnectionStateChanged_hasLeaMemberConnected_notInCallFlagOff_addPref() {
+ mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+ setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
+ .thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+ when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mBroadcastReceiveState));
+ List bisSyncState = new ArrayList<>();
+ bisSyncState.add(1L);
+ when(mBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
@Test
public void onProfileConnectionStateChanged_leaConnected_notInCallNotInSharing_addPref() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
@@ -299,6 +321,25 @@ public class AvailableMediaBluetoothDeviceUpdaterTest {
verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
}
+ @Test
+ public void
+ onProfileConnectionStateChanged_hasLeaMemberConnected_notInCallNotInSharing_addPref() {
+ mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
+ setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class)))
+ .thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+ when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+
+ verify(mBluetoothDeviceUpdater).addPreference(mCachedBluetoothDevice);
+ }
+
@Test
public void onProfileConnectionStateChanged_leaConnected_inCallSharingFlagOff_addPref() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
diff --git a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
index f68a8d4cf6a..b2babc310ae 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/ConnectedBluetoothDeviceUpdaterTest.java
@@ -269,6 +269,20 @@ public class ConnectedBluetoothDeviceUpdaterTest {
verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
}
+ @Test
+ public void onProfileConnectionStateChanged_hasLeaMemberConnected_inCall_removesPreference() {
+ setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_IN_CALL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ }
+
@Test
public void onProfileConnectionStateChanged_leAudioDeviceConnected_notInCall_removesPreference()
{
@@ -282,6 +296,22 @@ public class ConnectedBluetoothDeviceUpdaterTest {
verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
}
+
+ @Test
+ public void
+ onProfileConnectionStateChanged_hasLeaMemberConnected_notInCall_removesPreference() {
+ setUpDeviceUpdaterWithAudioMode(AudioManager.MODE_NORMAL);
+ when(mBluetoothDeviceUpdater
+ .isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+
+ mBluetoothDeviceUpdater.onProfileConnectionStateChanged(mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.LE_AUDIO);
+
+ verify(mBluetoothDeviceUpdater).removePreference(mCachedBluetoothDevice);
+ }
+
@Test
public void onProfileConnectionStateChanged_deviceIsNotInList_inCall_invokesRemovesPreference()
{
diff --git a/tests/robotests/src/com/android/settings/communal/CommunalPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/communal/CommunalPreferenceControllerTest.java
index b88b1aa661b..cc970eb6b1d 100644
--- a/tests/robotests/src/com/android/settings/communal/CommunalPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/communal/CommunalPreferenceControllerTest.java
@@ -17,6 +17,7 @@
package com.android.settings.communal;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_V2;
import static com.google.common.truth.Truth.assertThat;
@@ -34,7 +35,6 @@ import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import com.android.settings.R;
-import com.android.settings.flags.Flags;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowUserManager;
@@ -87,7 +87,7 @@ public class CommunalPreferenceControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HUB_MODE_SETTINGS_ON_MOBILE)
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
public void isAvailable_communalOnMobileEnabled_shouldBeTrueForPrimaryUser() {
setCommunalEnabled(false);
setCommunalOnMobileEnabled(true);
@@ -96,7 +96,7 @@ public class CommunalPreferenceControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HUB_MODE_SETTINGS_ON_MOBILE)
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
public void isAvailable_communalOnMobileEnabled_shouldBeFalseForSecondaryUser() {
setCommunalEnabled(false);
setCommunalOnMobileEnabled(true);
@@ -105,7 +105,7 @@ public class CommunalPreferenceControllerTest {
}
@Test
- @EnableFlags(Flags.FLAG_ENABLE_HUB_MODE_SETTINGS_ON_MOBILE)
+ @EnableFlags(FLAG_GLANCEABLE_HUB_V2)
public void isAvailable_communalOnMobileDisabled_shouldBeFalseForPrimaryUser() {
setCommunalEnabled(false);
setCommunalOnMobileEnabled(false);
@@ -114,8 +114,8 @@ public class CommunalPreferenceControllerTest {
}
@Test
- @DisableFlags(Flags.FLAG_ENABLE_HUB_MODE_SETTINGS_ON_MOBILE)
- public void isAvailable_hubModeSettingsOnMobileFlagDisabled_shouldBeFalseForPrimaryUser() {
+ @DisableFlags(FLAG_GLANCEABLE_HUB_V2)
+ public void isAvailable_glanceableHubV2FlagDisabled_shouldBeFalseForPrimaryUser() {
setCommunalEnabled(false);
setCommunalOnMobileEnabled(true);
mShadowUserManager.setUserForeground(true);
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java
index 12e03d4cd63..84fd820323f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingBluetoothDeviceUpdaterTest.java
@@ -153,6 +153,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDeviceConnected_flagOff_removesPref() {
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -172,6 +177,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaConnected_flagOff_hysteresisMode_removesPref() {
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -191,6 +201,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaConnected_noSource_removesPref() {
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of());
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -210,6 +225,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaConnected_noSource_hysteresisMode_removesPref() {
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of());
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -229,6 +249,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_deviceIsNotInList_removesPref() {
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
mCachedDevices.clear();
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
@@ -249,6 +274,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_deviceIsNotInList_hysteresisMode_removesPref() {
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
mCachedDevices.clear();
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
@@ -269,6 +299,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDisconnected_removesPref() {
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(false);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -288,6 +323,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDisconnected_hysteresisMode_removesPref() {
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(false);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -307,6 +347,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDisconnecting_removesPref() {
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
doReturn(false).when(mCachedBluetoothDevice).isConnectedLeAudioDevice();
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -325,6 +370,11 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDisconnecting_hysteresisMode_removesPref() {
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
doReturn(false).when(mCachedBluetoothDevice).isConnectedLeAudioDevice();
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -344,6 +394,29 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
public void onProfileConnectionStateChanged_leaConnected_hasSource_addsPref() {
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
setupPreferenceMapWithDevice(false);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+
+ verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
+ assertThat(captor.getValue() instanceof BluetoothDevicePreference).isTrue();
+ assertThat(((BluetoothDevicePreference) captor.getValue()).getBluetoothDevice())
+ .isEqualTo(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void onProfileConnectionStateChanged_hasLeaMemberConnected_hasSource_addsPref() {
+ ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
+ setupPreferenceMapWithDevice(false);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
assertThat(captor.getValue() instanceof BluetoothDevicePreference).isTrue();
@@ -355,6 +428,30 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
public void onProfileConnectionStateChanged_leaConnected_hasSource_hysteresisMode_addsPref() {
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
setupPreferenceMapWithDevice(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+
+ verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
+ assertThat(captor.getValue() instanceof BluetoothDevicePreference).isTrue();
+ assertThat(((BluetoothDevicePreference) captor.getValue()).getBluetoothDevice())
+ .isEqualTo(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void
+ onProfileConnectionStateChanged_hasLeaMemberConnected_hasSource_hysteresis_addsPref() {
+ ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
+ setupPreferenceMapWithDevice(true);
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
assertThat(captor.getValue() instanceof BluetoothDevicePreference).isTrue();
@@ -397,10 +494,5 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of(mState));
when(mDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
doReturn(true).when(mCachedBluetoothDevice).isConnectedLeAudioDevice();
- mDeviceUpdater.onProfileConnectionStateChanged(
- mCachedBluetoothDevice,
- BluetoothProfile.STATE_CONNECTED,
- BluetoothProfile.LE_AUDIO);
- shadowOf(Looper.getMainLooper()).idle();
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
index 95e51e99d51..2bdd0da243f 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeControlUpdaterTest.java
@@ -127,6 +127,11 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDeviceConnected_noSharing_removesPref() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mBroadcast.isEnabled(null)).thenReturn(false);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -146,6 +151,11 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDeviceConnected_noSource_removesPref() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of());
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -165,6 +175,11 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void onProfileConnectionStateChanged_deviceIsNotInList_removesPref() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
mCachedDevices.clear();
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(mCachedDevices);
@@ -185,6 +200,11 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDeviceDisconnected_removesPref() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(false);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -204,6 +224,11 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void onProfileConnectionStateChanged_leaDeviceDisconnecting_removesPref() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
@@ -224,6 +249,29 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
public void onProfileConnectionStateChanged_leaDeviceConnected_hasSource_addsPreference() {
ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+
+ verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
+ assertThat(captor.getValue() instanceof AudioSharingDeviceVolumePreference).isTrue();
+ assertThat(((AudioSharingDeviceVolumePreference) captor.getValue()).getCachedDevice())
+ .isEqualTo(mCachedBluetoothDevice);
+ }
+
+ @Test
+ public void onProfileConnectionStateChanged_hasLeaMemberConnected_hasSource_addsPreference() {
+ ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class);
+ setupPreferenceMapWithDevice();
+ when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(false);
+ when(mCachedBluetoothDevice.hasConnectedLeAudioMemberDevice()).thenReturn(true);
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
verify(mDevicePreferenceCallback).onDeviceAdded(captor.capture());
assertThat(captor.getValue() instanceof AudioSharingDeviceVolumePreference).isTrue();
@@ -262,6 +310,12 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
@Test
public void refreshPreference_doNothing() {
setupPreferenceMapWithDevice();
+ mDeviceUpdater.onProfileConnectionStateChanged(
+ mCachedBluetoothDevice,
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.LE_AUDIO);
+ shadowOf(Looper.getMainLooper()).idle();
+
verify(mDevicePreferenceCallback).onDeviceAdded(any(Preference.class));
when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(ImmutableList.of());
mDeviceUpdater.refreshPreference();
@@ -276,10 +330,5 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
when(mAssistant.getAllSources(mBluetoothDevice)).thenReturn(ImmutableList.of(mState));
when(mDeviceUpdater.isDeviceConnected(any(CachedBluetoothDevice.class))).thenReturn(true);
when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
- mDeviceUpdater.onProfileConnectionStateChanged(
- mCachedBluetoothDevice,
- BluetoothProfile.STATE_CONNECTED,
- BluetoothProfile.LE_AUDIO);
- shadowOf(Looper.getMainLooper()).idle();
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
index bac8b30ff16..a739bb3b4fb 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java
@@ -309,6 +309,8 @@ public class AudioSharingDeviceVolumeGroupControllerTest {
when(mPreference1.getProgress()).thenReturn(TEST_VOLUME_VALUE);
mController.setPreferenceGroup(mPreferenceGroup);
mController.onDeviceAdded(mPreference1);
+ shadowOf(Looper.getMainLooper()).idle();
+
verify(mPreferenceGroup).setVisible(true);
assertThat(mPreferenceGroup.isVisible()).isTrue();
}
@@ -365,6 +367,8 @@ public class AudioSharingDeviceVolumeGroupControllerTest {
mPreferenceGroup.addPreference(mPreference1);
mController.setPreferenceGroup(mPreferenceGroup);
mController.onDeviceRemoved(mPreference1);
+ shadowOf(Looper.getMainLooper()).idle();
+
verify(mPreferenceGroup).setVisible(false);
assertThat(mPreferenceGroup.isVisible()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceControllerTest.java
similarity index 97%
rename from tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceControllerTest.java
index 388e9b21f29..d661441a073 100644
--- a/tests/robotests/src/com/android/settings/development/DesktopExperiencePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopExperiencePreferenceControllerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_EXPERIENCE_FEATURES;
import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_OFF;
@@ -44,6 +44,8 @@ import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
import com.android.window.flags.Flags;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModePreferenceControllerTest.java
similarity index 97%
rename from tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModePreferenceControllerTest.java
index 9f718f9db62..ffbe31f0975 100644
--- a/tests/robotests/src/com/android/settings/development/DesktopModePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModePreferenceControllerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_OVERRIDE_DESKTOP_MODE_FEATURES;
import static android.window.DesktopModeFlags.ToggleOverride.OVERRIDE_ON;
@@ -44,6 +44,8 @@ import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.internal.R;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
import com.android.window.flags.Flags;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceControllerTest.java
similarity index 91%
rename from tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceControllerTest.java
index 2284d92cd70..3203b61609a 100644
--- a/tests/robotests/src/com/android/settings/development/DesktopModeSecondaryDisplayPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/desktopexperience/DesktopModeSecondaryDisplayPreferenceControllerTest.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
import static android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS;
-import static com.android.settings.development.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_OFF;
-import static com.android.settings.development.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_ON;
+import static com.android.settings.development.desktopexperience.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_OFF;
+import static com.android.settings.development.desktopexperience.DesktopModeSecondaryDisplayPreferenceController.SETTING_VALUE_ON;
import static com.google.common.truth.Truth.assertThat;
@@ -44,6 +44,8 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.internal.R;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
import com.android.window.flags.Flags;
import org.junit.Before;
@@ -97,9 +99,9 @@ public class DesktopModeSecondaryDisplayPreferenceControllerTest {
when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference);
mController.displayPreference(mScreen);
when(mResources.getBoolean(R.bool.config_isDesktopModeSupported)).thenReturn(false);
- when(mResources
- .getBoolean(com.android.internal.R.bool.config_canInternalDisplayHostDesktops))
- .thenReturn(false);
+ when(mResources.getBoolean(
+ com.android.internal.R.bool.config_canInternalDisplayHostDesktops)).thenReturn(
+ false);
}
@DisableFlags(Flags.FLAG_SHOW_DESKTOP_EXPERIENCE_DEV_OPTION)
diff --git a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceControllerTest.java
similarity index 93%
rename from tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceControllerTest.java
index b4b0bccf832..aacb4b45719 100644
--- a/tests/robotests/src/com/android/settings/development/FreeformWindowsPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/desktopexperience/FreeformWindowsPreferenceControllerTest.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.desktopexperience;
import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
-import static com.android.settings.development.FreeformWindowsPreferenceController.SETTING_VALUE_OFF;
-import static com.android.settings.development.FreeformWindowsPreferenceController.SETTING_VALUE_ON;
+import static com.android.settings.development.desktopexperience.FreeformWindowsPreferenceController.SETTING_VALUE_OFF;
+import static com.android.settings.development.desktopexperience.FreeformWindowsPreferenceController.SETTING_VALUE_ON;
import static com.google.common.truth.Truth.assertThat;
@@ -43,6 +43,8 @@ import androidx.preference.PreferenceScreen;
import androidx.preference.SwitchPreference;
import com.android.internal.R;
+import com.android.settings.development.DevelopmentSettingsDashboardFragment;
+import com.android.settings.development.RebootConfirmationDialogFragment;
import com.android.window.flags.Flags;
import org.junit.Before;
diff --git a/tests/robotests/src/com/android/settings/development/desktopexperience/OWNERS b/tests/robotests/src/com/android/settings/development/desktopexperience/OWNERS
new file mode 100644
index 00000000000..c437f15567d
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/desktopexperience/OWNERS
@@ -0,0 +1,2 @@
+include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/development/NonResizableMultiWindowPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/window/NonResizableMultiWindowPreferenceControllerTest.java
similarity index 93%
rename from tests/robotests/src/com/android/settings/development/NonResizableMultiWindowPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/window/NonResizableMultiWindowPreferenceControllerTest.java
index 7e7a258dd0d..7b8b8ae2698 100644
--- a/tests/robotests/src/com/android/settings/development/NonResizableMultiWindowPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/window/NonResizableMultiWindowPreferenceControllerTest.java
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-package com.android.settings.development;
+package com.android.settings.development.window;
import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_NON_RESIZABLE_MULTI_WINDOW;
-import static com.android.settings.development.NonResizableMultiWindowPreferenceController.SETTING_VALUE_OFF;
-import static com.android.settings.development.NonResizableMultiWindowPreferenceController.SETTING_VALUE_ON;
+import static com.android.settings.development.window.NonResizableMultiWindowPreferenceController.SETTING_VALUE_OFF;
+import static com.android.settings.development.window.NonResizableMultiWindowPreferenceController.SETTING_VALUE_ON;
import static com.google.common.truth.Truth.assertThat;
diff --git a/tests/robotests/src/com/android/settings/development/window/OWNERS b/tests/robotests/src/com/android/settings/development/window/OWNERS
new file mode 100644
index 00000000000..6be8a6421d2
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/development/window/OWNERS
@@ -0,0 +1,3 @@
+include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/OWNERS
+include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/development/ResizableActivityPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/development/window/ResizableActivityPreferenceControllerTest.java
similarity index 98%
rename from tests/robotests/src/com/android/settings/development/ResizableActivityPreferenceControllerTest.java
rename to tests/robotests/src/com/android/settings/development/window/ResizableActivityPreferenceControllerTest.java
index 9a69a0a62dd..5c1f4294f48 100644
--- a/tests/robotests/src/com/android/settings/development/ResizableActivityPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/development/window/ResizableActivityPreferenceControllerTest.java
@@ -1,5 +1,3 @@
-package com.android.settings.development;
-
/*
* Copyright (C) 2017 The Android Open Source Project
*
@@ -16,6 +14,8 @@ package com.android.settings.development;
* limitations under the License.
*/
+package com.android.settings.development.window;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
diff --git a/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt b/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt
index 619d290f0c4..0f845df90e7 100644
--- a/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt
+++ b/tests/robotests/src/com/android/settings/network/SatelliteRepositoryTest.kt
@@ -18,10 +18,12 @@ package com.android.settings.network
import android.content.Context
import android.os.OutcomeReceiver
+import android.platform.test.annotations.EnableFlags
import android.telephony.satellite.SatelliteManager
import android.telephony.satellite.SatelliteManager.SatelliteException
import android.telephony.satellite.SatelliteModemStateCallback
import androidx.test.core.app.ApplicationProvider
+import com.android.internal.telephony.flags.Flags
import com.google.common.truth.Truth.assertThat
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.coroutines.flow.first
@@ -38,10 +40,10 @@ import org.mockito.Mockito.*
import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule
+import org.mockito.kotlin.whenever
import org.robolectric.RobolectricTestRunner
import java.util.concurrent.Executor
-
@RunWith(RobolectricTestRunner::class)
class SatelliteRepositoryTest {
@@ -267,4 +269,35 @@ class SatelliteRepositoryTest {
assertThat(flow.first()).isFalse()
}
-}
\ No newline at end of file
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ fun getSatelliteDataOptimizedApps_returnPackageNameList() = runBlocking {
+ whenever(
+ mockSatelliteManager.getSatelliteDataOptimizedApps()
+ ).thenReturn(
+ listOf(
+ "com.android.settings",
+ "com.android.apps.messaging",
+ "com.android.dialer",
+ "com.android.systemui"
+ )
+ )
+
+ val result = repository.getSatelliteDataOptimizedApps()
+
+ assertThat(result.size == 4).isTrue()
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ fun getSatelliteDataOptimizedApps_noTelephony_returnEmptyList() = runBlocking {
+ whenever(
+ mockSatelliteManager.getSatelliteDataOptimizedApps()
+ ).thenThrow(IllegalStateException("Telephony is null"))
+
+ val result = repository.getSatelliteDataOptimizedApps()
+
+ assertThat(result.isEmpty()).isTrue()
+ }
+}
diff --git a/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionActivationRepositoryTest.kt b/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionActivationRepositoryTest.kt
index 427ab7b1685..01015be7730 100644
--- a/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionActivationRepositoryTest.kt
+++ b/tests/spa_unit/src/com/android/settings/network/telephony/SubscriptionActivationRepositoryTest.kt
@@ -17,12 +17,15 @@
package com.android.settings.network.telephony
import android.content.Context
+import android.content.Intent
+import android.os.UserHandle
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.telephony.TelephonyManager.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.android.settings.network.SatelliteRepository
+import com.android.settings.network.SimOnboardingActivity
import com.android.settingslib.spa.testutils.firstWithTimeoutOrNull
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.flowOf
@@ -33,6 +36,7 @@ import org.mockito.kotlin.any
import org.mockito.kotlin.argThat
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.eq
import org.mockito.kotlin.mock
import org.mockito.kotlin.never
import org.mockito.kotlin.spy
@@ -107,6 +111,17 @@ class SubscriptionActivationRepositoryTest {
verify(context, never()).startActivity(any())
}
+ @Test
+ fun setActive_turnOnAndIsEmergencyCallbackMode() = runBlocking {
+ mockTelephonyManager.stub {
+ on { emergencyCallbackMode } doReturn true
+ }
+
+ repository.setActive(subId = SUB_ID, active = true)
+
+ verify(context).startActivity(argThat { action == ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS })
+ }
+
@Test
fun setActive_turnOffAndIsEmergencyCallbackMode() = runBlocking {
mockTelephonyManager.stub {
@@ -131,6 +146,19 @@ class SubscriptionActivationRepositoryTest {
})
}
+ @Test
+ fun setActive_turnOnAndNotEmergencyCallbackMode() = runBlocking {
+ mockTelephonyManager.stub {
+ on { emergencyCallbackMode } doReturn false
+ }
+
+ repository.setActive(subId = SUB_ID, active = true)
+
+ verify(context).startActivityAsUser(argThat {
+ component?.className == SimOnboardingActivity::class.qualifiedName
+ }, eq(UserHandle.CURRENT))
+ }
+
private companion object {
const val SUB_ID = 1
}
diff --git a/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListCategoryControllerTest.java b/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListCategoryControllerTest.java
new file mode 100644
index 00000000000..74797ae69d3
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListCategoryControllerTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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;
+
+import static com.android.settings.core.BasePreferenceController.AVAILABLE;
+import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE;
+import static com.android.settings.network.telephony.SatelliteAppListCategoryController.MAXIMUM_OF_PREFERENCE_AMOUNT;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Looper;
+import android.platform.test.annotations.EnableFlags;
+
+import androidx.preference.PreferenceCategory;
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.network.SatelliteRepository;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SatelliteAppListCategoryControllerTest {
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ private static final List PACKAGE_NAMES = List.of("com.android.settings",
+ "com.android.apps.messaging", "com.android.dialer", "com.android.systemui");
+ private static final String KEY = "SatelliteAppListCategoryControllerTest";
+
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private SatelliteRepository mRepository;
+
+ private Context mContext;
+ private SatelliteAppListCategoryController mController;
+
+
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public void displayPreference_has4SatSupportedApps_showMaxPreference() throws Exception {
+ when(mRepository.getSatelliteDataOptimizedApps()).thenReturn(PACKAGE_NAMES);
+ when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), anyInt())).thenReturn(
+ new ApplicationInfo());
+ mController = new SatelliteAppListCategoryController(mContext, KEY);
+ mController.init(mRepository);
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+ PreferenceCategory category = new PreferenceCategory(mContext);
+ category.setKey(mController.getPreferenceKey());
+ preferenceScreen.addPreference(category);
+
+ mController.displayPreference(preferenceScreen);
+
+ assertThat(category.getPreferenceCount() == MAXIMUM_OF_PREFERENCE_AMOUNT).isTrue();
+ }
+
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public void getAvailabilityStatus_hasSatSupportedApps_returnAvailable() {
+ when(mRepository.getSatelliteDataOptimizedApps()).thenReturn(PACKAGE_NAMES);
+ mController = new SatelliteAppListCategoryController(mContext, KEY);
+ mController.init(mRepository);
+
+ int result = mController.getAvailabilityStatus();
+
+ assertThat(result).isEqualTo(AVAILABLE);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public void getAvailabilityStatus_noSatSupportedApps_returnUnavailable() {
+ List packageNames = Collections.emptyList();
+ when(mRepository.getSatelliteDataOptimizedApps()).thenReturn(packageNames);
+ mController = new SatelliteAppListCategoryController(mContext, KEY);
+ mController.init(mRepository);
+
+ int result = mController.getAvailabilityStatus();
+
+ assertThat(result).isEqualTo(CONDITIONALLY_UNAVAILABLE);
+ }
+}
diff --git a/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListFragmentTest.java b/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListFragmentTest.java
new file mode 100644
index 00000000000..ba91d179f99
--- /dev/null
+++ b/tests/unit/src/com/android/settings/network/telephony/SatelliteAppListFragmentTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.os.Looper;
+import android.platform.test.annotations.EnableFlags;
+
+import androidx.preference.PreferenceManager;
+import androidx.preference.PreferenceScreen;
+import androidx.test.core.app.ApplicationProvider;
+
+import com.android.internal.telephony.flags.Flags;
+import com.android.settings.network.SatelliteRepository;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.List;
+
+public class SatelliteAppListFragmentTest {
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ private static final List PACKAGE_NAMES = List.of(
+ "com.android.settings",
+ "com.android.apps.messaging",
+ "com.android.dialer",
+ "com.android.systemui"
+ );
+ private static final String KEY = "SatelliteAppListPreferenceController";
+
+ @Mock
+ private PackageManager mPackageManager;
+ @Mock
+ private SatelliteRepository mRepository;
+
+ private Context mContext;
+ private SatelliteAppListFragment.SatelliteAppListPreferenceController mController;
+
+ @Before
+ public void setUp() {
+ if (Looper.myLooper() == null) {
+ Looper.prepare();
+ }
+ mContext = spy(ApplicationProvider.getApplicationContext());
+ when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ }
+
+ @Test
+ @EnableFlags(Flags.FLAG_SATELLITE_25Q4_APIS)
+ public void displayPreference_has4SatSupportedApps_showMaxPreference() throws Exception {
+ when(mRepository.getSatelliteDataOptimizedApps()).thenReturn(PACKAGE_NAMES);
+ when(mPackageManager.getApplicationInfoAsUser(any(), anyInt(), anyInt())).thenReturn(
+ new ApplicationInfo());
+ mController = new SatelliteAppListFragment.SatelliteAppListPreferenceController(mContext);
+ mController.init(mRepository);
+ PreferenceManager preferenceManager = new PreferenceManager(mContext);
+ PreferenceScreen preferenceScreen = preferenceManager.createPreferenceScreen(mContext);
+
+ mController.displayPreference(preferenceScreen);
+
+ assertThat(preferenceScreen.getPreferenceCount() == PACKAGE_NAMES.size()).isTrue();
+ }
+}