Snap for 13070131 from 28f5fbb59d to 25Q2-release

Change-Id: I7a14c4cb789ffdc88ef529c91d9d00b35ce07263
This commit is contained in:
Android Build Coastguard Worker
2025-02-14 18:18:02 -08:00
58 changed files with 1131 additions and 155 deletions

View File

@@ -115,6 +115,7 @@ android_library {
"device_policy_aconfig_flags_lib",
"keyboard_flags_lib",
"settings_connectivity_flags",
"com_android_systemui_flags_lib",
],
plugins: [

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal" android:autoMirrored="true">
<path android:fillColor="@android:color/white" android:pathData="M560,720L320,480L560,240L616,296L432,480L616,664L560,720Z"/>
</vector>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="960" android:viewportHeight="960" android:tint="?attr/colorControlNormal" android:autoMirrored="true">
<path android:fillColor="@android:color/white" android:pathData="M504,480L320,296L376,240L616,480L376,720L320,664L504,480Z" />
</vector>

View File

@@ -38,20 +38,45 @@
android:text="@string/screen_zoom_preview_title"
style="@style/AccessibilityTextReadingPreviewTitle" />
<com.android.settings.accessibility.TextReadingPreviewPager
android:id="@+id/preview_pager"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="217dp"
android:contentDescription="@string/preview_pager_content_description"
android:nestedScrollingEnabled="true" />
<com.android.settings.widget.DotsPageIndicator
android:id="@+id/page_indicator"
style="@style/PreviewPagerPageIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="6dp"
android:visibility="gone" />
android:orientation="vertical">
<com.android.settings.accessibility.TextReadingPreviewPager
android:id="@+id/preview_pager"
android:layout_width="wrap_content"
android:layout_height="217dp"
android:contentDescription="@string/preview_pager_content_description"
android:nestedScrollingEnabled="true" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal">
<ImageButton
android:id="@+id/preview_left_button"
android:src="@drawable/keyboard_arrow_left"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
style="?android:attr/borderlessButtonStyle" />
<com.android.settings.widget.DotsPageIndicator
android:id="@+id/page_indicator"
style="@style/PreviewPagerPageIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="6dp"
android:visibility="gone" />
<ImageButton
android:id="@+id/preview_right_button"
android:src="@drawable/keyboard_arrow_right"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center_vertical"
style="?android:attr/borderlessButtonStyle" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</FrameLayout>

View File

@@ -14,13 +14,19 @@
limitations under the License.
-->
<!-- TODO(b/396116157): I cannot find the correct src of ImageView to set to
match the other preference items. I tried
@drawable/android:selectable_item_background but this is private so will
not compile. It should match the other items so that theme migration will
switch to the correct final color. -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/display_topology_pane_holder"
android:importantForAccessibility="no"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingHorizontal="@dimen/display_topology_pane_margin"
android:layout_marginVertical="@dimen/display_topology_pane_vertical_margin"
android:layout_marginHorizontal="@dimen/display_topology_pane_margin"
android:orientation="horizontal">
<ImageView
android:importantForAccessibility="no"

View File

@@ -66,8 +66,9 @@
android:layout_gravity="center_vertical"
android:paddingStart="0dp"
android:paddingEnd="12dp"
android:progressBackgroundTint="@color/settingslib_materialColorOutline"
android:progressTint="@color/settingslib_materialColorPrimaryFixed"
android:thumbTint="@color/seekbar_thumb_tint_color"
android:progressTint="@color/seekbar_progress_tint_color"
android:progressBackgroundTint="@color/seekbar_progress_background_tint_color"
android:layout_width="match_parent"
android:layout_height="48dp"/>

View File

@@ -82,5 +82,9 @@
<!-- Connected displays -->
<color name="display_topology_background_color">@color/settingslib_color_charcoal</color>
<color name="system_secondary">@android:color/system_secondary_dark</color>
<!-- Volume seekbar colors -->
<color name="seekbar_thumb_tint_color">@android:color/system_accent1_100</color>
<color name="seekbar_progress_tint_color">@android:color/system_accent1_100</color>
</resources>

View File

@@ -222,4 +222,9 @@
<!-- Connected displays -->
<color name="display_topology_background_color">@color/settingslib_color_grey100</color>
<color name="system_secondary">@android:color/system_secondary_light</color>
<!-- Volume seekbar colors -->
<color name="seekbar_thumb_tint_color">@android:color/system_accent1_800</color>
<color name="seekbar_progress_tint_color">@android:color/system_accent1_800</color>
<color name="seekbar_progress_background_tint_color">@android:color/system_neutral2_50</color>
</resources>

View File

@@ -552,6 +552,7 @@
<!-- Connected displays -->
<dimen name="display_topology_pane_margin">24dp</dimen>
<dimen name="display_topology_pane_vertical_margin">24dp</dimen>
<dimen name="display_block_padding">5dp</dimen>
<dimen name="display_block_highlight_width">2dp</dimen>
<dimen name="display_block_corner_radius">10dp</dimen>

View File

@@ -78,6 +78,11 @@
<!-- Content description for preview pager. [CHAR LIMIT=NONE] -->
<string name="preview_pager_content_description">Preview</string>
<!-- Previous button for preview pager. [CHAR LIMIT=NONE] -->
<string name="preview_pager_previous_button">Previous preview</string>
<!-- Next button for preview pager. [CHAR LIMIT=NONE] -->
<string name="preview_pager_next_button">Next preview</string>
<!-- Content description for qrcode image. [CHAR LIMIT=none]-->
<string name="qr_code_content_description">QR code</string>
@@ -12602,6 +12607,12 @@
<string name="description_satellite_setting_messaging">satellite messaging</string>
<!-- Title for notifying user's account be able to use data transmission of Satellite" [CHAR_LIMIT=NONE] -->
<string name="title_have_satellite_data_plan">Use of data is included with your account</string>
<!-- Category title for Satellite supported apps info [CHAR LIMIT=60] -->
<string name="category_title_satellite_supported_apps">Supported apps on your phone</string>
<!-- Title for a entry to start apps list page with Satellite service supported. [CHAR LIMIT=60] -->
<string name="title_satellite_supported_app_list_entry">see all apps</string>
<!-- Title for a page of apps list page with Satellite service supported. [CHAR LIMIT=60] -->
<string name="title_satellite_supported_app_list_page">Supported apps on your phone</string>
<!-- Title for Apn settings in mobile network settings [CHAR LIMIT=60] -->
<string name="mobile_network_apn_title">Access Point Names</string>

View File

@@ -745,32 +745,6 @@
android:title="@string/force_allow_on_external"
android:summary="@string/force_allow_on_external_summary" />
<SwitchPreferenceCompat
android:key="force_resizable_activities"
android:title="@string/force_resizable_activities"
android:summary="@string/force_resizable_activities_summary" />
<SwitchPreferenceCompat
android:key="override_desktop_mode_features"
android:title="@string/enable_desktop_mode" />
<SwitchPreferenceCompat
android:key="enable_freeform_support"
android:title="@string/enable_freeform_support" />
<SwitchPreferenceCompat
android:key="override_desktop_experience_features"
android:title="@string/enable_desktop_experience_features"/>
<SwitchPreferenceCompat
android:key="force_desktop_mode_on_external_displays"
android:title="@string/enable_desktop_mode_on_secondary_display"/>
<SwitchPreferenceCompat
android:key="enable_non_resizable_multi_window"
android:title="@string/enable_non_resizable_multi_window"
android:summary="@string/enable_non_resizable_multi_window_summary" />
<SwitchPreferenceCompat
android:key="back_navigation_animation"
android:title="@string/back_navigation_animation"
@@ -792,11 +766,45 @@
</PreferenceCategory>
<PreferenceCategory
android:key="window_management_category"
android:title="@string/window_management_category"
android:order="1100">
<SwitchPreferenceCompat
android:key="force_resizable_activities"
android:title="@string/force_resizable_activities"
android:summary="@string/force_resizable_activities_summary" />
<SwitchPreferenceCompat
android:key="enable_non_resizable_multi_window"
android:title="@string/enable_non_resizable_multi_window"
android:summary="@string/enable_non_resizable_multi_window_summary" />
<SwitchPreferenceCompat
android:key="override_desktop_mode_features"
android:title="@string/enable_desktop_mode" />
<SwitchPreferenceCompat
android:key="enable_freeform_support"
android:title="@string/enable_freeform_support" />
<SwitchPreferenceCompat
android:key="override_desktop_experience_features"
android:title="@string/enable_desktop_experience_features"/>
<SwitchPreferenceCompat
android:key="force_desktop_mode_on_external_displays"
android:title="@string/enable_desktop_mode_on_secondary_display"/>
</PreferenceCategory>
<PreferenceCategory
android:key="debug_autofill_category"
android:title="@string/debug_autofill_category"
settings:searchable="false"
android:order="1100"> <!-- Incremented by 100 from last order (i.e. 1000) -->
android:order="1200"> <!-- Incremented by 100 from last order (i.e. 1000) -->
<ListPreference
android:key="autofill_logging_level"
@@ -821,7 +829,7 @@
<PreferenceCategory
android:key="storage_category"
android:title="@string/storage_category"
android:order="1200">
android:order="1300">
<Preference
android:key="shared_data"
@@ -836,7 +844,7 @@
<PreferenceCategory
android:key="location_category"
android:title="@string/location_category"
android:order="1300">
android:order="1400">
<Preference android:key="mock_location_app"
android:title="@string/mock_location_app" />
@@ -857,7 +865,7 @@
<PreferenceCategory
android:key="input_method_category"
android:title="@string/input_method_category"
android:order="1400">
android:order="1500">
<SwitchPreferenceCompat
android:key="stylus_handwriting"

View File

@@ -62,6 +62,23 @@
android:icon="@drawable/ic_android_satellite_24px"/>
</PreferenceCategory>
<PreferenceCategory
android:key="key_category_satellite_apps"
android:title="@string/category_title_satellite_supported_apps"
settings:isPreferenceVisible="false"
settings:controller="com.android.settings.network.telephony.SatelliteAppListCategoryController"
settings:searchable="false">
<!-- See all satellite apps -->
<Preference
android:key="key_see_all_satellite_apps"
android:title="@string/title_satellite_supported_app_list_entry"
android:icon="@drawable/ic_chevron_right_24dp"
android:fragment="com.android.settings.network.telephony.SatelliteAppListFragment"
android:order="5"
settings:searchable="false"/>
</PreferenceCategory>
<com.android.settingslib.widget.FooterPreference
android:key="satellite_setting_extra_info_footer_pref"
android:layout="@layout/satellite_setting_more_information_layout"

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ 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.
-->
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/tools"
android:key="key_satellite_app_list"
android:title="@string/title_satellite_supported_app_list_page">
</androidx.preference.PreferenceScreen>

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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)) {

View File

@@ -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,

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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<AudioSharingDeviceVolumePreference> mVolumePreferences = new ArrayList<>();
private Map<Integer, Integer> mValueMap = new HashMap<Integer, Integer>();
private CopyOnWriteArraySet<AudioSharingDeviceVolumePreference> mVolumePreferences =
new CopyOnWriteArraySet<>();
private ConcurrentHashMap<Integer, Integer> 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

View File

@@ -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)
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -0,0 +1,2 @@
include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS

View File

@@ -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);

View File

@@ -475,7 +475,10 @@ public class StorageItemPreferenceController extends AbstractPreferenceControlle
updatePrivateStorageCategoryPreferencesOrder();
mIsPreferenceOrderedBySize = true;
}
setPrivateStorageCategoryPreferencesVisibility(true);
if (isValidPrivateVolume()) {
setPrivateStorageCategoryPreferencesVisibility(true);
}
}
private StorageCacheHelper.StorageCache getSizeInfo(

View File

@@ -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<String> {
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"

View File

@@ -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<String> 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;
}
}
}

View File

@@ -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<AbstractPreferenceController> 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<ApplicationInfo> 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;
}
}
}

View File

@@ -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);

View File

@@ -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)
}

View File

@@ -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());
}

View File

@@ -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();

View File

@@ -77,6 +77,7 @@ android_robolectric_test {
"platform-test-annotations",
"testables",
"android.app.flags-aconfig-java",
"com_android_systemui_flags_lib",
],
libs: [

View File

@@ -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<Long> 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);

View File

@@ -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()
{

View File

@@ -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);

View File

@@ -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<Preference> 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<Preference> 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<Preference> 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<Preference> 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<Preference> 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<Preference> 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<Preference> 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<Preference> captor = ArgumentCaptor.forClass(Preference.class);
@@ -344,6 +394,29 @@ public class AudioSharingBluetoothDeviceUpdaterTest {
public void onProfileConnectionStateChanged_leaConnected_hasSource_addsPref() {
ArgumentCaptor<Preference> 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<Preference> 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<Preference> 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<Preference> 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();
}
}

View File

@@ -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<Preference> 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<Preference> 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<Preference> 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<Preference> captor = ArgumentCaptor.forClass(Preference.class);
@@ -224,6 +249,29 @@ public class AudioSharingDeviceVolumeControlUpdaterTest {
public void onProfileConnectionStateChanged_leaDeviceConnected_hasSource_addsPreference() {
ArgumentCaptor<Preference> 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<Preference> 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();
}
}

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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;

View File

@@ -0,0 +1,2 @@
include platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
include platform/frameworks/base:/libs/WindowManager/Shell/OWNERS

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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()
}
}
@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()
}
}

View File

@@ -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
}

View File

@@ -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<String> 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<String> 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);
}
}

View File

@@ -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<String> 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();
}
}