diff --git a/res/drawable/ic_brightness_auto.xml b/res/drawable/ic_brightness_auto.xml deleted file mode 100644 index 7ace52b5f63..00000000000 --- a/res/drawable/ic_brightness_auto.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - diff --git a/res/drawable/ic_brightness_medium.xml b/res/drawable/ic_brightness_medium.xml deleted file mode 100644 index 3e778857127..00000000000 --- a/res/drawable/ic_brightness_medium.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - \ No newline at end of file diff --git a/res/drawable/ic_suw_brightness_auto.xml b/res/drawable/ic_suw_brightness_auto.xml index a4221c540d1..93f17f54ac6 100644 --- a/res/drawable/ic_suw_brightness_auto.xml +++ b/res/drawable/ic_suw_brightness_auto.xml @@ -21,6 +21,15 @@ android:height="@dimen/accessibility_icon_size" android:color="@color/accessibility_feature_background"/> - + + + + + \ No newline at end of file diff --git a/res/drawable/ic_suw_brightness_level.xml b/res/drawable/ic_suw_brightness_level.xml index 57bd1883849..4ed6374fbe2 100644 --- a/res/drawable/ic_suw_brightness_level.xml +++ b/res/drawable/ic_suw_brightness_level.xml @@ -21,6 +21,15 @@ android:height="@dimen/accessibility_icon_size" android:color="@color/accessibility_feature_background"/> - + + + + + \ No newline at end of file diff --git a/res/values/strings.xml b/res/values/strings.xml index 459ff7a4a4b..8b5e63f4329 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -2869,16 +2869,12 @@ Brightness level Adaptive brightness - - - About adaptive brightness Your screen brightness will automatically adjust to your environment and activities. You can move the slider manually to help adaptive brightness learn your preferences. On Off - Display white balance diff --git a/res/xml/accessibility_settings_for_setup_wizard.xml b/res/xml/accessibility_settings_for_setup_wizard.xml index 25b8a5acf69..250954353f5 100644 --- a/res/xml/accessibility_settings_for_setup_wizard.xml +++ b/res/xml/accessibility_settings_for_setup_wizard.xml @@ -37,11 +37,10 @@ settings:useAdminDisabledSummary="true" settings:userRestriction="no_config_brightness"/> - diff --git a/res/xml/apn_editor.xml b/res/xml/apn_editor.xml deleted file mode 100644 index e5c04e02a24..00000000000 --- a/res/xml/apn_editor.xml +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizard.java b/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizard.java deleted file mode 100644 index 19db2668df9..00000000000 --- a/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizard.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.accessibility; - -import static android.app.Activity.RESULT_CANCELED; - -import android.app.settings.SettingsEnums; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.preference.PreferenceScreen; -import androidx.recyclerview.widget.RecyclerView; - -import com.android.settings.R; -import com.android.settings.display.AutoBrightnessSettings; -import com.android.settingslib.Utils; -import com.android.settingslib.widget.FooterPreference; - -import com.google.android.setupcompat.template.FooterBarMixin; -import com.google.android.setupdesign.GlifPreferenceLayout; - -/** - * Fragment for adaptive brightness settings in the SetupWizard. - */ -public class AutoBrightnessPreferenceFragmentForSetupWizard extends AutoBrightnessSettings { - - private static final String FOOTER_PREFERENCE_KEY = "auto_brightness_footer"; - - @Override - public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - updateFooterContentDescription(); - - if (view instanceof GlifPreferenceLayout) { - final GlifPreferenceLayout layout = (GlifPreferenceLayout) view; - final String title = getContext().getString( - R.string.auto_brightness_title); - final Drawable icon = getContext().getDrawable(R.drawable.ic_accessibility_visibility); - icon.setTintList(Utils.getColorAttr(getContext(), android.R.attr.colorPrimary)); - AccessibilitySetupWizardUtils.updateGlifPreferenceLayout(getContext(), layout, title, - /* description= */ null, icon); - - final FooterBarMixin mixin = layout.getMixin(FooterBarMixin.class); - AccessibilitySetupWizardUtils.setPrimaryButton(getContext(), mixin, R.string.done, - () -> { - setResult(RESULT_CANCELED); - finish(); - }); - } - } - - @NonNull - @Override - public RecyclerView onCreateRecyclerView(@NonNull LayoutInflater inflater, - @NonNull ViewGroup parent, @Nullable Bundle savedInstanceState) { - if (parent instanceof GlifPreferenceLayout) { - final GlifPreferenceLayout layout = (GlifPreferenceLayout) parent; - return layout.onCreateRecyclerView(inflater, parent, savedInstanceState); - } - return super.onCreateRecyclerView(inflater, parent, savedInstanceState); - } - - @Override - public int getMetricsCategory() { - return SettingsEnums.SUW_ACCESSIBILITY_AUTO_BRIGHTNESS; - } - - private void updateFooterContentDescription() { - final PreferenceScreen screen = getPreferenceScreen(); - final FooterPreference footerPreference = screen.findPreference(FOOTER_PREFERENCE_KEY); - if (footerPreference != null) { - String title = getString(R.string.auto_brightness_content_description_title); - final StringBuilder sb = new StringBuilder(); - sb.append(title).append("\n\n").append(footerPreference.getTitle()); - footerPreference.setContentDescription(sb); - } - } -} diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsController.java b/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsController.java index 93e1ff54574..b741f0833f0 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsCompanionAppsController.java @@ -87,6 +87,12 @@ public class BluetoothDetailsCompanionAppsController extends BluetoothDetailsCon mProfilesContainer.setLayoutResource(R.layout.preference_companion_app); } + @Override + public boolean isAvailable() { + // Do not show this preference for now. More details in b/191992001#comment7 + return false; + } + private List getAssociations(String address) { return filter( mCompanionDeviceManager.getAllAssociations(), diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java index 11a337fb616..719d6cb71e6 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceController.java @@ -110,7 +110,10 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP @Override public void onSourceAdded( - @NonNull BluetoothDevice sink, int sourceId, int reason) {} + @NonNull BluetoothDevice sink, int sourceId, int reason) { + Log.d(TAG, "onSourceAdded: updateSummary"); + updateSummary(); + } @Override public void onSourceAddFailed( @@ -138,12 +141,7 @@ public class AudioSharingCallAudioPreferenceController extends AudioSharingBaseP public void onReceiveStateChanged( @NonNull BluetoothDevice sink, int sourceId, - @NonNull BluetoothLeBroadcastReceiveState state) { - if (BluetoothUtils.isConnected(state)) { - Log.d(TAG, "onReceiveStateChanged: synced, updateSummary"); - updateSummary(); - } - } + @NonNull BluetoothLeBroadcastReceiveState state) {} }; public AudioSharingCallAudioPreferenceController(Context context) { diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index 6069d6fac0b..c286ed6114e 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -116,7 +116,18 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Override public void onSourceAdded( - @NonNull BluetoothDevice sink, int sourceId, int reason) {} + @NonNull BluetoothDevice sink, int sourceId, int reason) { + Log.d(TAG, "onSourceAdded: update sharing device list."); + if (mBluetoothDeviceUpdater != null) { + mBluetoothDeviceUpdater.forceUpdate(); + } + if (mDeviceManager != null && mDialogHandler != null) { + CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(sink); + if (cachedDevice != null) { + mDialogHandler.closeOpeningDialogsForLeaDevice(cachedDevice); + } + } + } @Override public void onSourceAddFailed( @@ -173,20 +184,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro public void onReceiveStateChanged( @NonNull BluetoothDevice sink, int sourceId, - @NonNull BluetoothLeBroadcastReceiveState state) { - if (BluetoothUtils.isConnected(state)) { - Log.d(TAG, "onSourceAdded: update sharing device list."); - if (mBluetoothDeviceUpdater != null) { - mBluetoothDeviceUpdater.forceUpdate(); - } - if (mDeviceManager != null && mDialogHandler != null) { - CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(sink); - if (cachedDevice != null) { - mDialogHandler.closeOpeningDialogsForLeaDevice(cachedDevice); - } - } - } - } + @NonNull BluetoothLeBroadcastReceiveState state) {} }; public AudioSharingDevicePreferenceController(Context context) { diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java index 42de10a81b2..be0ee0b8b44 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupController.java @@ -132,7 +132,12 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre @Override public void onSourceAdded( - @NonNull BluetoothDevice sink, int sourceId, int reason) {} + @NonNull BluetoothDevice sink, int sourceId, int reason) { + Log.d(TAG, "onSourceAdded: update volume list."); + if (mBluetoothDeviceUpdater != null) { + mBluetoothDeviceUpdater.forceUpdate(); + } + } @Override public void onSourceAddFailed( @@ -165,14 +170,7 @@ public class AudioSharingDeviceVolumeGroupController extends AudioSharingBasePre public void onReceiveStateChanged( @NonNull BluetoothDevice sink, int sourceId, - @NonNull BluetoothLeBroadcastReceiveState state) { - if (BluetoothUtils.isConnected(state)) { - Log.d(TAG, "onReceiveStateChanged: synced, update volume list."); - if (mBluetoothDeviceUpdater != null) { - mBluetoothDeviceUpdater.forceUpdate(); - } - } - } + @NonNull BluetoothLeBroadcastReceiveState state) {} }; public AudioSharingDeviceVolumeGroupController(Context context) { diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java index 537eee09af0..0a9bc97ed79 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java @@ -177,6 +177,20 @@ public class AudioSharingSwitchBarController extends BasePreferenceController + broadcastId + ", metadata = " + metadata.getBroadcastName()); + if (mAssistant == null + || mAssistant.getAllConnectedDevices().stream() + .anyMatch( + device -> BluetoothUtils + .hasActiveLocalBroadcastSourceForBtDevice( + device, mBtManager))) { + Log.d( + TAG, + "Skip handleOnBroadcastReady: null assistant or " + + "sink has active local source."); + cleanUpStatesForStartSharing(); + return; + } + handleOnBroadcastReady(); } @Override @@ -221,20 +235,6 @@ public class AudioSharingSwitchBarController extends BasePreferenceController + reason + ", broadcastId = " + broadcastId); - if (mAssistant == null - || mAssistant.getAllConnectedDevices().stream() - .anyMatch( - device -> BluetoothUtils - .hasActiveLocalBroadcastSourceForBtDevice( - device, mBtManager))) { - Log.d( - TAG, - "Skip handleOnBroadcastReady: null assistant or " - + "sink has active local source."); - cleanUpStatesForStartSharing(); - return; - } - handleOnBroadcastReady(); } @Override @@ -261,7 +261,30 @@ public class AudioSharingSwitchBarController extends BasePreferenceController @Override public void onSourceAdded( - @NonNull BluetoothDevice sink, int sourceId, int reason) {} + @NonNull BluetoothDevice sink, int sourceId, int reason) { + if (mSinksInAdding.contains(sink)) { + mSinksInAdding.remove(sink); + } + dismissProgressDialogIfNeeded(); + Log.d(TAG, "onSourceAdded(), sink = " + sink + ", remaining sinks = " + + mSinksInAdding); + if (mSinksToWaitFor.contains(sink)) { + mSinksToWaitFor.remove(sink); + if (mSinksToWaitFor.isEmpty()) { + // To avoid users advance to share then pair flow before the + // primary/active sinks successfully join the audio sharing, + // popup dialog till adding source complete for mSinksToWaitFor. + Pair[] eventData = + AudioSharingUtils.buildAudioSharingDialogEventData( + SettingsEnums.AUDIO_SHARING_SETTINGS, + SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE, + /* userTriggered= */ false, + /* deviceCountInSharing= */ 1, + /* candidateDeviceCount= */ 0); + showAudioSharingDialog(eventData); + } + } + } @Override public void onSourceAddFailed( @@ -307,34 +330,9 @@ public class AudioSharingSwitchBarController extends BasePreferenceController @NonNull BluetoothDevice sink, int sourceId, @NonNull BluetoothLeBroadcastReceiveState state) { - if (mStoppingSharing.get()) { - Log.d(TAG, "Skip onReceiveStateChanged, stopping broadcast"); - return; - } - if (BluetoothUtils.isConnected(state)) { - if (mSinksInAdding.contains(sink)) { - mSinksInAdding.remove(sink); - } - dismissProgressDialogIfNeeded(); - Log.d(TAG, "onReceiveStateChanged() connected, sink = " + sink - + ", remaining sinks = " + mSinksInAdding); - if (mSinksToWaitFor.contains(sink)) { - mSinksToWaitFor.remove(sink); - if (mSinksToWaitFor.isEmpty()) { - // To avoid users advance to share then pair flow before the - // primary/active sinks successfully join the audio sharing, - // popup dialog till adding source complete for mSinksToWaitFor. - Pair[] eventData = - AudioSharingUtils.buildAudioSharingDialogEventData( - SettingsEnums.AUDIO_SHARING_SETTINGS, - SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE, - /* userTriggered= */ false, - /* deviceCountInSharing= */ 1, - /* candidateDeviceCount= */ 0); - showAudioSharingDialog(eventData); - } - } - } + Log.d(TAG, + "onReceiveStateChanged(), sink = " + sink + ", sourceId = " + sourceId + + ", state = " + state); } }; diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java index 592c8eb84c5..5a15b6ae51c 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java @@ -46,7 +46,6 @@ import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; import com.android.settingslib.bluetooth.VolumeControlProfile; -import com.android.settingslib.flags.Flags; import java.util.ArrayList; import java.util.Comparator; @@ -222,8 +221,8 @@ public class AudioSharingUtils { Log.d(TAG, "hasActiveConnectedLeadDevice return false due to null device manager."); return false; } - return deviceManager.getCachedDevicesCopy().stream().anyMatch( - BluetoothUtils::isActiveMediaDevice); + return deviceManager.getCachedDevicesCopy().stream() + .anyMatch(BluetoothUtils::isActiveMediaDevice); } /** Build {@link AudioSharingDeviceItem} from {@link CachedBluetoothDevice}. */ @@ -348,17 +347,18 @@ public class AudioSharingUtils { } /** Set {@link CachedBluetoothDevice} as primary device for call audio */ - public static void setPrimary(@NonNull Context context, - @Nullable CachedBluetoothDevice cachedDevice) { + public static void setPrimary( + @NonNull Context context, @Nullable CachedBluetoothDevice cachedDevice) { if (cachedDevice == null) return; cachedDevice.setActive(); - if (Flags.audioSharingHysteresisModeFix()) { + if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context)) { int groupId = BluetoothUtils.getGroupId(cachedDevice); // TODO: use real key name in SettingsProvider - int userPreferredId = Settings.Secure.getInt( - context.getContentResolver(), - BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, - BluetoothCsipSetCoordinator.GROUP_ID_INVALID); + int userPreferredId = + Settings.Secure.getInt( + context.getContentResolver(), + BLUETOOTH_LE_BROADCAST_PRIMARY_DEVICE_GROUP_ID, + BluetoothCsipSetCoordinator.GROUP_ID_INVALID); if (groupId != userPreferredId) { Settings.Secure.putInt( context.getContentResolver(), diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java index 48acf3256d0..f9cce4ce099 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonController.java @@ -16,8 +16,6 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; -import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; - import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; @@ -38,6 +36,7 @@ import com.android.settings.R; import com.android.settings.bluetooth.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.utils.ThreadUtils; @@ -77,7 +76,7 @@ public class AudioStreamButtonController extends BasePreferenceController BluetoothLeBroadcastReceiveState state) { super.onReceiveStateChanged(sink, sourceId, state); boolean shouldUpdateButton = - audioSharingHysteresisModeFix() + BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext) ? AudioStreamsHelper.hasSourcePresent(state) : AudioStreamsHelper.isConnected(state); if (shouldUpdateButton) { @@ -157,7 +156,7 @@ public class AudioStreamButtonController extends BasePreferenceController } List sources = - audioSharingHysteresisModeFix() + BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext) ? mAudioStreamsHelper.getAllPresentSources() : mAudioStreamsHelper.getAllConnectedSources(); boolean isConnected = diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java index 0ee93e7742e..88efff2b6ab 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderController.java @@ -37,6 +37,7 @@ import com.android.settings.bluetooth.Utils; import com.android.settings.core.BasePreferenceController; import com.android.settings.dashboard.DashboardFragment; import com.android.settings.widget.EntityHeaderController; +import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.utils.ThreadUtils; import com.android.settingslib.widget.LayoutPreference; @@ -86,7 +87,7 @@ public class AudioStreamHeaderController extends BasePreferenceController updateSummary(); mAudioStreamsHelper.startMediaService( mContext, mBroadcastId, mBroadcastName); - } else if (audioSharingHysteresisModeFix() + } else if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext) && AudioStreamsHelper.hasSourcePresent(state)) { // if source present but not connected, only update the summary updateSummary(); @@ -171,13 +172,13 @@ public class AudioStreamHeaderController extends BasePreferenceController : mContext.getString( AUDIO_STREAM_HEADER_PRESENT_NOW_SUMMARY)) : mAudioStreamsHelper.getAllConnectedSources().stream() - .map( - BluetoothLeBroadcastReceiveState - ::getBroadcastId) - .anyMatch( - connectedBroadcastId -> - connectedBroadcastId - == mBroadcastId) + .map( + BluetoothLeBroadcastReceiveState + ::getBroadcastId) + .anyMatch( + connectedBroadcastId -> + connectedBroadcastId + == mBroadcastId) ? mContext.getString( AUDIO_STREAM_HEADER_LISTENING_NOW_SUMMARY) : AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY; diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java index 458cfab55ff..563af74f57c 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandler.java @@ -18,8 +18,6 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import static android.text.Spanned.SPAN_EXCLUSIVE_INCLUSIVE; -import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; - import android.os.Handler; import android.os.Looper; import android.text.SpannableString; @@ -98,7 +96,8 @@ class AudioStreamStateHandler { newState == AudioStreamsProgressCategoryController .AudioStreamState.SOURCE_ADDED - || (audioSharingHysteresisModeFix() + || (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable( + preference.getContext()) && newState == AudioStreamsProgressCategoryController .AudioStreamState.SOURCE_PRESENT)); diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java index 0107c6ee49b..f45b63c76f5 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryController.java @@ -31,7 +31,6 @@ import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.LocalBluetoothManager; -import com.android.settingslib.flags.Flags; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -80,13 +79,6 @@ public class AudioStreamsCategoryController extends AudioSharingBasePreferenceCo } } - @Override - public int getAvailabilityStatus() { - return Flags.enableLeAudioQrCodePrivateBroadcastSharing() - ? AVAILABLE - : UNSUPPORTED_ON_DEVICE; - } - @Override public void updateVisibility() { if (mPreference == null) return; diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java index 7c1281f7ac5..25a9135701b 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelper.java @@ -19,7 +19,6 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.BROADCAST_ID; import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.BROADCAST_TITLE; import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamMediaService.DEVICES; -import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; import static java.util.Collections.emptyList; @@ -271,7 +270,8 @@ public class AudioStreamsHelper { List sourceList = assistant.getAllSources(cachedDevice.getDevice()); if (!sourceList.isEmpty() - && (audioSharingHysteresisModeFix() + && (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable( + localBtManager.getContext()) || sourceList.stream().anyMatch(AudioStreamsHelper::isConnected))) { Log.d( TAG, @@ -284,7 +284,8 @@ public class AudioStreamsHelper { List list = assistant.getAllSources(device.getDevice()); if (!list.isEmpty() - && (audioSharingHysteresisModeFix() + && (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable( + localBtManager.getContext()) || list.stream().anyMatch(AudioStreamsHelper::isConnected))) { Log.d( TAG, diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallback.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallback.java index b379d4e7314..f0034316372 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallback.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallback.java @@ -16,19 +16,24 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; -import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.content.Context; + +import com.android.settingslib.bluetooth.BluetoothUtils; public class AudioStreamsProgressCategoryCallback extends AudioStreamsBroadcastAssistantCallback { private static final String TAG = "AudioStreamsProgressCategoryCallback"; + private final Context mContext; private final AudioStreamsProgressCategoryController mCategoryController; public AudioStreamsProgressCategoryCallback( + Context context, AudioStreamsProgressCategoryController audioStreamsProgressCategoryController) { + mContext = context; mCategoryController = audioStreamsProgressCategoryController; } @@ -41,7 +46,8 @@ public class AudioStreamsProgressCategoryCallback extends AudioStreamsBroadcastA mCategoryController.handleSourceConnected(state); } else if (AudioStreamsHelper.isBadCode(state)) { mCategoryController.handleSourceConnectBadCode(state); - } else if (audioSharingHysteresisModeFix() && AudioStreamsHelper.hasSourcePresent(state)) { + } else if (BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(mContext) + && AudioStreamsHelper.hasSourcePresent(state)) { // Keep this check as the last, source might also present in above states mCategoryController.handleSourcePresent(state); } diff --git a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java index 7ab588260d0..f0a0c5b8f7f 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryController.java @@ -16,8 +16,6 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; -import static com.android.settingslib.flags.Flags.audioSharingHysteresisModeFix; - import static java.util.Collections.emptyList; import android.app.AlertDialog; @@ -101,7 +99,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro (p.getAudioStreamState() == AudioStreamsProgressCategoryController .AudioStreamState.SOURCE_ADDED - || (audioSharingHysteresisModeFix() + || (isAudioSharingHysteresisModeFixAvailable(mContext) && p.getAudioStreamState() == AudioStreamsProgressCategoryController .AudioStreamState @@ -147,7 +145,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro mAudioStreamsHelper = new AudioStreamsHelper(mBluetoothManager); mMediaControlHelper = new MediaControlHelper(mContext, mBluetoothManager); mLeBroadcastAssistant = mAudioStreamsHelper.getLeBroadcastAssistant(); - mBroadcastAssistantCallback = new AudioStreamsProgressCategoryCallback(this); + mBroadcastAssistantCallback = new AudioStreamsProgressCategoryCallback(context, this); } @Override @@ -258,7 +256,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro // change it's state. existingPreference.setAudioStreamMetadata(source); if (fromState != AudioStreamState.SOURCE_ADDED - && (!audioSharingHysteresisModeFix() + && (!isAudioSharingHysteresisModeFixAvailable(mContext) || fromState != AudioStreamState.SOURCE_PRESENT)) { Log.w( TAG, @@ -364,7 +362,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro // not, means the source is removed from the sink, we move back the preference to SYNCED // state. if ((preference.getAudioStreamState() == AudioStreamState.SOURCE_ADDED - || (audioSharingHysteresisModeFix() + || (isAudioSharingHysteresisModeFixAvailable(mContext) && preference.getAudioStreamState() == AudioStreamState.SOURCE_PRESENT)) && mAudioStreamsHelper.getAllConnectedSources().stream() @@ -600,7 +598,7 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro // Handle QR code scan, display currently connected streams then start scanning // sequentially handleSourceFromQrCodeIfExists(); - if (audioSharingHysteresisModeFix()) { + if (isAudioSharingHysteresisModeFixAvailable(mContext)) { // With hysteresis mode, we prioritize showing connected sources first. // If no connected sources are found, we then show present sources. List sources = @@ -702,4 +700,8 @@ public class AudioStreamsProgressCategoryController extends BasePreferenceContro dialog.dismiss(); }); } + + private static boolean isAudioSharingHysteresisModeFixAvailable(Context context) { + return BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(context); + } } diff --git a/src/com/android/settings/core/gateway/SettingsGateway.java b/src/com/android/settings/core/gateway/SettingsGateway.java index d43b25c9a08..01fa54853cf 100644 --- a/src/com/android/settings/core/gateway/SettingsGateway.java +++ b/src/com/android/settings/core/gateway/SettingsGateway.java @@ -28,7 +28,6 @@ import com.android.settings.accessibility.AccessibilityDetailsSettingsFragment; import com.android.settings.accessibility.AccessibilityHearingAidsFragment; import com.android.settings.accessibility.AccessibilitySettings; import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard; -import com.android.settings.accessibility.AutoBrightnessPreferenceFragmentForSetupWizard; import com.android.settings.accessibility.CaptioningPropertiesFragment; import com.android.settings.accessibility.ColorAndMotionFragment; import com.android.settings.accessibility.HearingDevicePairingFragment; @@ -268,7 +267,6 @@ public class SettingsGateway { EditShortcutsPreferenceFragment.class.getName(), TextReadingPreferenceFragment.class.getName(), TextReadingPreferenceFragmentForSetupWizard.class.getName(), - AutoBrightnessPreferenceFragmentForSetupWizard.class.getName(), CaptioningPropertiesFragment.class.getName(), ToggleDaltonizerPreferenceFragment.class.getName(), ToggleColorInversionPreferenceFragment.class.getName(), diff --git a/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java b/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java index 7cdf3e0ea35..7afe3ea9d8b 100644 --- a/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java +++ b/src/com/android/settings/display/AutoBrightnessPreferenceControllerForSetupWizard.java @@ -41,4 +41,9 @@ public class AutoBrightnessPreferenceControllerForSetupWizard } return super.getAvailabilityStatus(); } + + @Override + public CharSequence getSummary() { + return ""; + } } diff --git a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt index e1aea8519aa..4ce854672f9 100644 --- a/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt +++ b/src/com/android/settings/network/AdaptiveConnectivityTogglePreference.kt @@ -19,35 +19,43 @@ package com.android.settings.network import android.content.Context import android.net.wifi.WifiManager import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED -import androidx.preference.Preference import com.android.settings.R +import com.android.settingslib.datastore.KeyValueStore +import com.android.settingslib.datastore.KeyedObservableDelegate import com.android.settingslib.datastore.SettingsSecureStore +import com.android.settingslib.datastore.SettingsStore import com.android.settingslib.metadata.MainSwitchPreference -import com.android.settingslib.metadata.PreferenceMetadata -import com.android.settingslib.preference.MainSwitchPreferenceBinding // LINT.IfChange class AdaptiveConnectivityTogglePreference : - MainSwitchPreference( - ADAPTIVE_CONNECTIVITY_ENABLED, - R.string.adaptive_connectivity_main_switch_title, - ), - MainSwitchPreferenceBinding, - Preference.OnPreferenceChangeListener { + MainSwitchPreference(KEY, R.string.adaptive_connectivity_main_switch_title) { - override fun storage(context: Context) = SettingsSecureStore.get(context) + override fun storage(context: Context): KeyValueStore = + AdaptiveConnectivityToggleStorage(context, SettingsSecureStore.get(context)) - override fun bind(preference: Preference, metadata: PreferenceMetadata) { - super.bind(preference, metadata) - preference.onPreferenceChangeListener = this + @Suppress("UNCHECKED_CAST") + private class AdaptiveConnectivityToggleStorage( + private val context: Context, + private val settingsStore: SettingsStore, + ) : KeyedObservableDelegate(settingsStore), KeyValueStore { + + override fun contains(key: String) = settingsStore.contains(KEY) + + override fun getDefaultValue(key: String, valueType: Class) = + DEFAULT_VALUE as T + + override fun getValue(key: String, valueType: Class) = + (settingsStore.getBoolean(key) ?: DEFAULT_VALUE) as T + + override fun setValue(key: String, valueType: Class, value: T?) { + settingsStore.setBoolean(key, value as Boolean) + context.getSystemService(WifiManager::class.java)?.setWifiScoringEnabled(value) + } } - override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean { - val isChecked = newValue as Boolean - preference.context - .getSystemService(WifiManager::class.java) - ?.setWifiScoringEnabled(isChecked) - return true + companion object { + const val KEY = ADAPTIVE_CONNECTIVITY_ENABLED + const val DEFAULT_VALUE = true } } // LINT.ThenChange(AdaptiveConnectivityTogglePreferenceController.java) diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java index 533fd292289..5ae280c37cc 100644 --- a/src/com/android/settings/network/apn/ApnEditor.java +++ b/src/com/android/settings/network/apn/ApnEditor.java @@ -23,88 +23,21 @@ import android.app.settings.SettingsEnums; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.os.PersistableBundle; import android.os.UserManager; import android.provider.Telephony; -import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.util.Log; import androidx.annotation.VisibleForTesting; -import com.android.internal.util.ArrayUtils; import com.android.settings.SettingsPreferenceFragment; import com.android.settings.spa.SpaActivity; -import java.util.Arrays; -import java.util.List; - /** Use to edit apn settings. */ public class ApnEditor extends SettingsPreferenceFragment { private static final String TAG = ApnEditor.class.getSimpleName(); - /** - * APN types for data connections. These are usage categories for an APN - * entry. One APN entry may support multiple APN types, eg, a single APN - * may service regular internet traffic ("default") as well as MMS-specific - * connections.
- * APN_TYPE_ALL is a special type to indicate that this APN entry can - * service all data connections. - */ - public static final String APN_TYPE_ALL = "*"; - /** APN type for default data traffic */ - public static final String APN_TYPE_DEFAULT = "default"; - /** APN type for MMS traffic */ - public static final String APN_TYPE_MMS = "mms"; - /** APN type for SUPL assisted GPS */ - public static final String APN_TYPE_SUPL = "supl"; - /** APN type for DUN traffic */ - public static final String APN_TYPE_DUN = "dun"; - /** APN type for HiPri traffic */ - public static final String APN_TYPE_HIPRI = "hipri"; - /** APN type for FOTA */ - public static final String APN_TYPE_FOTA = "fota"; - /** APN type for IMS */ - public static final String APN_TYPE_IMS = "ims"; - /** APN type for CBS */ - public static final String APN_TYPE_CBS = "cbs"; - /** APN type for IA Initial Attach APN */ - public static final String APN_TYPE_IA = "ia"; - /** APN type for Emergency PDN. This is not an IA apn, but is used - * for access to carrier services in an emergency call situation. */ - public static final String APN_TYPE_EMERGENCY = "emergency"; - /** APN type for Mission Critical Services */ - public static final String APN_TYPE_MCX = "mcx"; - /** APN type for XCAP */ - public static final String APN_TYPE_XCAP = "xcap"; - /** APN type for OEM_PAID networks (Automotive PANS) */ - public static final String APN_TYPE_OEM_PAID = "oem_paid"; - /** APN type for OEM_PRIVATE networks (Automotive PANS) */ - public static final String APN_TYPE_OEM_PRIVATE = "oem_private"; - /** Array of all APN types */ - public static final String[] APN_TYPES = {APN_TYPE_DEFAULT, - APN_TYPE_MMS, - APN_TYPE_SUPL, - APN_TYPE_DUN, - APN_TYPE_HIPRI, - APN_TYPE_FOTA, - APN_TYPE_IMS, - APN_TYPE_CBS, - APN_TYPE_IA, - APN_TYPE_EMERGENCY, - APN_TYPE_MCX, - APN_TYPE_XCAP, - APN_TYPE_OEM_PAID, - APN_TYPE_OEM_PRIVATE, - }; - - /** Array of APN types that are never user-editable */ - private static final String[] ALWAYS_READ_ONLY_APN_TYPES = new String[] { - APN_TYPE_OEM_PAID, - APN_TYPE_OEM_PRIVATE, - }; - @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); @@ -143,43 +76,6 @@ public class ApnEditor extends SettingsPreferenceFragment { } } - /** - * Fetch complete list of read only APN types. - * - * The list primarily comes from carrier config, but is also supplied by APN types which are - * always read only. - */ - static String[] getReadOnlyApnTypes(PersistableBundle b) { - String[] carrierReadOnlyApnTypes = b.getStringArray( - CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY); - return ArrayUtils.concat(String.class, carrierReadOnlyApnTypes, ALWAYS_READ_ONLY_APN_TYPES); - } - - /** - * Check if passed in array of APN types indicates all APN types - * @param apnTypes array of APN types. "*" indicates all types. - * @return true if all apn types are included in the array, false otherwise - */ - static boolean hasAllApns(String[] apnTypes) { - if (ArrayUtils.isEmpty(apnTypes)) { - return false; - } - - final List apnList = Arrays.asList(apnTypes); - if (apnList.contains(APN_TYPE_ALL)) { - Log.d(TAG, "hasAllApns: true because apnList.contains(APN_TYPE_ALL)"); - return true; - } - for (String apn : APN_TYPES) { - if (!apnList.contains(apn)) { - return false; - } - } - - Log.d(TAG, "hasAllApns: true"); - return true; - } - @Override public int getMetricsCategory() { return SettingsEnums.APN_EDITOR; diff --git a/src/com/android/settings/network/apn/ApnSettings.java b/src/com/android/settings/network/apn/ApnSettings.java index 0e3c3a4362d..24f25ecf7ac 100644 --- a/src/com/android/settings/network/apn/ApnSettings.java +++ b/src/com/android/settings/network/apn/ApnSettings.java @@ -23,7 +23,6 @@ import android.app.Dialog; import android.app.ProgressDialog; import android.app.settings.SettingsEnums; import android.content.Context; -import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; @@ -34,7 +33,6 @@ import android.provider.Telephony; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionManager; import android.telephony.data.ApnSetting; -import android.text.TextUtils; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; @@ -51,7 +49,6 @@ import androidx.preference.PreferenceGroup; import com.android.settings.R; import com.android.settings.RestrictedSettingsFragment; -import com.android.settings.flags.Flags; import com.android.settings.network.telephony.SubscriptionRepository; import com.android.settings.spa.SpaActivity; import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; @@ -59,6 +56,7 @@ import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; import kotlin.Unit; import java.util.ArrayList; +import java.util.List; /** Handle each different apn setting. */ public class ApnSettings extends RestrictedSettingsFragment @@ -68,16 +66,12 @@ public class ApnSettings extends RestrictedSettingsFragment public static final String APN_ID = "apn_id"; public static final String APN_LIST = "apn_list"; public static final String SUB_ID = "sub_id"; - public static final String MVNO_TYPE = "mvno_type"; - public static final String MVNO_MATCH_DATA = "mvno_match_data"; private static final String[] CARRIERS_PROJECTION = new String[] { Telephony.Carriers._ID, Telephony.Carriers.NAME, Telephony.Carriers.APN, Telephony.Carriers.TYPE, - Telephony.Carriers.MVNO_TYPE, - Telephony.Carriers.MVNO_MATCH_DATA, Telephony.Carriers.EDITED_STATUS, }; @@ -85,9 +79,7 @@ public class ApnSettings extends RestrictedSettingsFragment private static final int NAME_INDEX = 1; private static final int APN_INDEX = 2; private static final int TYPES_INDEX = 3; - private static final int MVNO_TYPE_INDEX = 4; - private static final int MVNO_MATCH_DATA_INDEX = 5; - private static final int EDITED_INDEX = 6; + private static final int EDITED_INDEX = 4; private static final int MENU_NEW = Menu.FIRST; private static final int MENU_RESTORE = Menu.FIRST + 1; @@ -101,8 +93,6 @@ public class ApnSettings extends RestrictedSettingsFragment private PreferredApnRepository mPreferredApnRepository; @Nullable private String mPreferredApnKey; - private String mMvnoType; - private String mMvnoMatchData; private boolean mUnavailable; @@ -135,9 +125,9 @@ public class ApnSettings extends RestrictedSettingsFragment mHideImsApn = b.getBoolean(CarrierConfigManager.KEY_HIDE_IMS_APN_BOOL); mAllowAddingApns = b.getBoolean(CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL); if (mAllowAddingApns) { - final String[] readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b); + final List readOnlyApnTypes = ApnTypes.getReadOnlyApnTypes(b); // if no apn type can be edited, do not allow adding APNs - if (ApnEditor.hasAllApns(readOnlyApnTypes)) { + if (ApnTypes.hasAllApnTypes(readOnlyApnTypes)) { Log.d(TAG, "not allowing adding APN because all APN types are read only"); mAllowAddingApns = false; } @@ -241,8 +231,6 @@ public class ApnSettings extends RestrictedSettingsFragment final String key = cursor.getString(ID_INDEX); final String type = cursor.getString(TYPES_INDEX); final int edited = cursor.getInt(EDITED_INDEX); - mMvnoType = cursor.getString(MVNO_TYPE_INDEX); - mMvnoMatchData = cursor.getString(MVNO_MATCH_DATA_INDEX); final ApnPreference pref = new ApnPreference(getPrefContext()); @@ -310,20 +298,9 @@ public class ApnSettings extends RestrictedSettingsFragment } private void addNewApn() { - if (Flags.newApnPageEnabled()) { - String route = ApnEditPageProvider.INSTANCE.getRoute( - INSERT_URL, Telephony.Carriers.CONTENT_URI, mSubId); - SpaActivity.startSpaActivity(getContext(), route); - } else { - final Intent intent = new Intent(Intent.ACTION_INSERT, Telephony.Carriers.CONTENT_URI); - intent.putExtra(SUB_ID, mSubId); - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - if (!TextUtils.isEmpty(mMvnoType) && !TextUtils.isEmpty(mMvnoMatchData)) { - intent.putExtra(MVNO_TYPE, mMvnoType); - intent.putExtra(MVNO_MATCH_DATA, mMvnoMatchData); - } - startActivity(intent); - } + String route = ApnEditPageProvider.INSTANCE.getRoute( + INSERT_URL, Telephony.Carriers.CONTENT_URI, mSubId); + SpaActivity.startSpaActivity(getContext(), route); } @Override diff --git a/src/com/android/settings/network/apn/ApnStatus.kt b/src/com/android/settings/network/apn/ApnStatus.kt index 68588bbd975..d33c8b3cc73 100644 --- a/src/com/android/settings/network/apn/ApnStatus.kt +++ b/src/com/android/settings/network/apn/ApnStatus.kt @@ -25,6 +25,7 @@ import android.telephony.CarrierConfigManager import android.util.Log import com.android.settings.R import com.android.settings.network.apn.ApnTypes.getPreSelectedApnType +import com.android.settings.network.apn.ApnTypes.getReadOnlyApnTypes private const val TAG = "ApnStatus" @@ -204,7 +205,7 @@ fun getCarrierCustomizedConfig( CarrierConfigManager.KEY_ALLOW_ADDING_APNS_BOOL ) val customizedConfig = CustomizedConfig( - readOnlyApnTypes = ApnEditor.getReadOnlyApnTypes(b)?.toList() ?: emptyList(), + readOnlyApnTypes = b.getReadOnlyApnTypes(), readOnlyApnFields = b.getStringArray( CarrierConfigManager.KEY_READ_ONLY_APN_FIELDS_STRING_ARRAY )?.toList() ?: emptyList(), diff --git a/src/com/android/settings/network/apn/ApnTypes.kt b/src/com/android/settings/network/apn/ApnTypes.kt index 4f84ac7fa70..ee192b262b4 100644 --- a/src/com/android/settings/network/apn/ApnTypes.kt +++ b/src/com/android/settings/network/apn/ApnTypes.kt @@ -17,6 +17,8 @@ package com.android.settings.network.apn import android.content.Context +import android.os.PersistableBundle +import android.telephony.CarrierConfigManager import android.telephony.data.ApnSetting import android.util.Log import android.widget.Toast @@ -51,9 +53,7 @@ object ApnTypes { private fun splitToList(apnType: String): List { val types = apnType.split(',').map { it.trim().toLowerCase(Locale.current) } - if (ApnSetting.TYPE_ALL_STRING in types || APN_TYPES.all { it in types }) { - return listOf(ApnSetting.TYPE_ALL_STRING) - } + if (hasAllApnTypes(types)) return listOf(ApnSetting.TYPE_ALL_STRING) return APN_TYPES.filter { it in types } } @@ -132,4 +132,32 @@ object ApnTypes { private fun defaultPreSelectedApnTypes(readOnlyApnTypes: List) = if (ApnSetting.TYPE_ALL_STRING in readOnlyApnTypes) emptyList() else PreSelectedTypes.filterNot { it in readOnlyApnTypes } + + /** Array of APN types that are never user-editable */ + private val ALWAYS_READ_ONLY_APN_TYPES = + arrayOf(ApnSetting.TYPE_OEM_PAID_STRING, ApnSetting.TYPE_OEM_PRIVATE_STRING) + + /** + * Fetch complete list of read only APN types. + * + * The list primarily comes from carrier config, but is also supplied by APN types which are + * always read only. + */ + @JvmStatic + fun PersistableBundle.getReadOnlyApnTypes(): List { + val carrierReadOnlyApnTypes = + getStringArray(CarrierConfigManager.KEY_READ_ONLY_APN_TYPES_STRING_ARRAY)?.toList() + ?: emptyList() + return carrierReadOnlyApnTypes + ALWAYS_READ_ONLY_APN_TYPES + } + + /** + * Check if passed in array of APN types indicates all APN types + * + * @param apnTypes array of APN types. "*" indicates all types. + * @return true if all apn types are included in the array, false otherwise + */ + @JvmStatic + fun hasAllApnTypes(apnTypes: List): Boolean = + ApnSetting.TYPE_ALL_STRING in apnTypes || APN_TYPES.all { it in apnTypes } } diff --git a/src/com/android/settings/notification/app/SoundPreferenceController.java b/src/com/android/settings/notification/app/SoundPreferenceController.java index b23b4fc86cb..bc1cb24ce1b 100644 --- a/src/com/android/settings/notification/app/SoundPreferenceController.java +++ b/src/com/android/settings/notification/app/SoundPreferenceController.java @@ -101,6 +101,8 @@ public class SoundPreferenceController extends NotificationPreferenceController public boolean handlePreferenceTreeClick(Preference preference) { if (KEY_SOUND.equals(preference.getKey()) && mFragment != null) { NotificationSoundPreference pref = (NotificationSoundPreference) preference; + // default to notification + pref.setRingtoneType(RingtoneManager.TYPE_NOTIFICATION); if (mChannel != null && mChannel.getAudioAttributes() != null) { if (USAGE_ALARM == mChannel.getAudioAttributes().getUsage()) { pref.setRingtoneType(RingtoneManager.TYPE_ALARM); diff --git a/src/com/android/settings/notification/modes/ZenHelperBackend.java b/src/com/android/settings/notification/modes/ZenHelperBackend.java index 31c1ce40b19..5761d361e33 100644 --- a/src/com/android/settings/notification/modes/ZenHelperBackend.java +++ b/src/com/android/settings/notification/modes/ZenHelperBackend.java @@ -18,6 +18,7 @@ package com.android.settings.notification.modes; import android.annotation.Nullable; import android.app.INotificationManager; +import android.app.ZenBypassingApp; import android.content.ContentProvider; import android.content.Context; import android.content.pm.ParceledListSlice; @@ -30,6 +31,7 @@ import android.os.UserManager; import android.provider.ContactsContract; import android.provider.ContactsContract.Contacts; import android.service.notification.ConversationChannelWrapper; +import android.util.ArrayMap; import android.util.Log; import androidx.annotation.NonNull; @@ -41,8 +43,9 @@ import com.google.common.collect.ImmutableList; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.function.Function; /** @@ -76,16 +79,20 @@ class ZenHelperBackend { } /** - * Returns all of a user's packages that have at least one channel that will bypass DND + * Returns a mapping between a user's packages that have at least one channel that will + * bypass DND, and a Boolean indicating whether all of the package's channels bypass. */ - List getPackagesBypassingDnd(int userId, - boolean includeConversationChannels) { + Map getPackagesBypassingDnd(int userId) { + Map bypassingAppsMap = new HashMap<>(); try { - return mInm.getPackagesBypassingDnd(userId, includeConversationChannels); + List bypassingApps = mInm.getPackagesBypassingDnd(userId).getList(); + for (ZenBypassingApp zba : bypassingApps) { + bypassingAppsMap.put(zba.getPkg(), zba.doAllChannelsBypass()); + } } catch (Exception e) { Log.w(TAG, "Error calling NoMan", e); - return new ArrayList<>(); } + return bypassingAppsMap; } /** Returns all conversation channels for profiles of the current user. */ diff --git a/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceController.java index 922ac5ecf5b..a01406ff836 100644 --- a/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceController.java @@ -22,7 +22,9 @@ import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.UserHandle; +import android.os.UserManager; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.text.BidiFormatter; @@ -35,7 +37,6 @@ import com.android.settings.R; import com.android.settings.applications.AppInfoBase; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.core.SubSettingLauncher; -import com.android.settings.notification.NotificationBackend; import com.android.settings.notification.app.AppChannelsBypassingDndSettings; import com.android.settingslib.applications.AppUtils; import com.android.settingslib.applications.ApplicationsState; @@ -44,7 +45,9 @@ import com.android.settingslib.utils.ThreadUtils; import com.android.settingslib.widget.AppPreference; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Adds a preference to the PreferenceScreen for each notification channel that can bypass DND. @@ -54,7 +57,8 @@ public class ZenModeAllBypassingAppsPreferenceController extends AbstractPrefere public static final String KEY_NO_APPS = "all_none"; private static final String KEY = "zen_mode_bypassing_apps_list"; - @Nullable private final NotificationBackend mNotificationBackend; + @Nullable private final ZenHelperBackend mHelperBackend; + private final UserManager mUserManager; @Nullable @VisibleForTesting ApplicationsState mApplicationsState; @VisibleForTesting PreferenceCategory mPreferenceCategory; @@ -64,18 +68,18 @@ public class ZenModeAllBypassingAppsPreferenceController extends AbstractPrefere @Nullable private Fragment mHostFragment; public ZenModeAllBypassingAppsPreferenceController(Context context, @Nullable Application app, - @Nullable Fragment host, @Nullable NotificationBackend notificationBackend) { - this(context, app == null ? null : ApplicationsState.getInstance(app), host, - notificationBackend); + @Nullable Fragment host, @Nullable ZenHelperBackend helperBackend) { + this(context, app == null ? null : ApplicationsState.getInstance(app), host, helperBackend); } private ZenModeAllBypassingAppsPreferenceController(Context context, @Nullable ApplicationsState appState, @Nullable Fragment host, - @Nullable NotificationBackend notificationBackend) { + @Nullable ZenHelperBackend helperBackend) { super(context); - mNotificationBackend = notificationBackend; mApplicationsState = appState; mHostFragment = host; + mHelperBackend = helperBackend; + mUserManager = context.getSystemService(UserManager.class); if (mApplicationsState != null && host != null) { mAppSession = mApplicationsState.newSession(mAppSessionCallbacks, host.getLifecycle()); @@ -140,19 +144,25 @@ public class ZenModeAllBypassingAppsPreferenceController extends AbstractPrefere } boolean doAnyAppsPassCriteria = false; + Map> packagesBypassingDndByUser = new HashMap<>(); + for (UserHandle userHandle : mUserManager.getUserProfiles()) { + packagesBypassingDndByUser.put(userHandle.getIdentifier(), + mHelperBackend.getPackagesBypassingDnd(userHandle.getIdentifier())); + } for (ApplicationsState.AppEntry app : apps) { String pkg = app.info.packageName; final String key = getKey(pkg, app.info.uid); - final int appChannels = mNotificationBackend.getChannelCount(pkg, app.info.uid); - final int appChannelsBypassingDnd = mNotificationBackend - .getNotificationChannelsBypassingDnd(pkg, app.info.uid).getList().size(); - if (appChannelsBypassingDnd > 0) { + boolean doesAppBypassDnd = false; + int userId = UserHandle.getUserId(app.info.uid); + Map packagesBypassingDnd = + packagesBypassingDndByUser.getOrDefault(userId, new HashMap<>()); + if (packagesBypassingDnd.containsKey(pkg)) { doAnyAppsPassCriteria = true; + doesAppBypassDnd = true; } - Preference pref = mPreferenceCategory.findPreference(key); if (pref == null) { - if (appChannelsBypassingDnd > 0) { + if (doesAppBypassDnd) { // does not exist but should pref = new AppPreference(mPrefContext); pref.setKey(key); @@ -172,14 +182,14 @@ public class ZenModeAllBypassingAppsPreferenceController extends AbstractPrefere }); pref.setTitle(BidiFormatter.getInstance().unicodeWrap(app.label)); updateIcon(pref, app); - if (appChannels > appChannelsBypassingDnd) { - pref.setSummary(R.string.zen_mode_bypassing_apps_summary_some); - } else { + if (packagesBypassingDnd.get(pkg)) { pref.setSummary(R.string.zen_mode_bypassing_apps_summary_all); + } else { + pref.setSummary(R.string.zen_mode_bypassing_apps_summary_some); } mPreferenceCategory.addPreference(pref); } - } else if (appChannelsBypassingDnd == 0) { + } else if (!doesAppBypassDnd) { // exists but shouldn't anymore mPreferenceCategory.removePreference(pref); } diff --git a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java index c133f515f30..e0e36f6495f 100644 --- a/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java +++ b/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceController.java @@ -161,8 +161,7 @@ class ZenModeAppsLinkPreferenceController extends AbstractZenModePreferenceContr Multimap packagesBypassingDnd = HashMultimap.create(); for (UserHandle userHandle : mUserManager.getUserProfiles()) { packagesBypassingDnd.putAll(userHandle.getIdentifier(), - mHelperBackend.getPackagesBypassingDnd(userHandle.getIdentifier(), - /* includeConversationChannels= */ false)); + mHelperBackend.getPackagesBypassingDnd(userHandle.getIdentifier()).keySet()); } return ImmutableList.copyOf( diff --git a/src/com/android/settings/notification/modes/ZenModeSelectBypassingAppsFragment.java b/src/com/android/settings/notification/modes/ZenModeSelectBypassingAppsFragment.java index 1f5438d08eb..21f34a2005d 100644 --- a/src/com/android/settings/notification/modes/ZenModeSelectBypassingAppsFragment.java +++ b/src/com/android/settings/notification/modes/ZenModeSelectBypassingAppsFragment.java @@ -48,15 +48,17 @@ public class ZenModeSelectBypassingAppsFragment extends ZenModeFragmentBase impl } else { app = null; } - return buildPreferenceControllers(context, app, this, new NotificationBackend()); + return buildPreferenceControllers(context, app, this, new NotificationBackend(), + new ZenHelperBackend(context)); } private static List buildPreferenceControllers(Context context, @Nullable Application app, @Nullable Fragment host, - @Nullable NotificationBackend notificationBackend) { + @Nullable NotificationBackend notificationBackend, + @Nullable ZenHelperBackend zenHelperBackend) { final List controllers = new ArrayList<>(); controllers.add(new ZenModeAllBypassingAppsPreferenceController(context, app, host, - notificationBackend)); + zenHelperBackend)); controllers.add(new ZenModeAddBypassingAppsPreferenceController(context, app, host, notificationBackend)); return controllers; @@ -86,7 +88,7 @@ public class ZenModeSelectBypassingAppsFragment extends ZenModeFragmentBase impl @Override public List createPreferenceControllers( Context context) { - return buildPreferenceControllers(context, null, null, null); + return buildPreferenceControllers(context, null, null, null, null); } }; } diff --git a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java index 0909c6f5f2e..4b1ffd095f0 100644 --- a/src/com/android/settings/notification/modes/ZenModesListItemPreference.java +++ b/src/com/android/settings/notification/modes/ZenModesListItemPreference.java @@ -15,6 +15,8 @@ */ package com.android.settings.notification.modes; +import static com.android.settings.Utils.createAccessibleSequence; + import android.app.settings.SettingsEnums; import android.content.Context; import android.widget.TextView; @@ -28,6 +30,7 @@ import com.android.settingslib.RestrictedPreference; import com.android.settingslib.Utils; import com.android.settingslib.notification.modes.ZenIconLoader; import com.android.settingslib.notification.modes.ZenMode; +import com.android.settingslib.notification.modes.ZenModeDescriptions; import com.google.common.base.Strings; @@ -42,6 +45,7 @@ class ZenModesListItemPreference extends RestrictedPreference { private final Context mContext; private final ZenIconLoader mIconLoader; private final Executor mUiExecutor; + private final ZenModeDescriptions mDescriptions; private ZenMode mZenMode; private TextView mTitleView; @@ -58,6 +62,7 @@ class ZenModesListItemPreference extends RestrictedPreference { mContext = context; mIconLoader = iconLoader; mUiExecutor = uiExecutor; + mDescriptions = new ZenModeDescriptions(context); setZenMode(zenMode); setKey(zenMode.getId()); } @@ -89,20 +94,17 @@ class ZenModesListItemPreference extends RestrictedPreference { } setTitle(mZenMode.getName()); - String dynamicDescription = zenMode.getDynamicDescription(mContext); - CharSequence statusText = switch (mZenMode.getStatus()) { - case ENABLED_AND_ACTIVE -> - Strings.isNullOrEmpty(dynamicDescription) - ? mContext.getString(R.string.zen_mode_active_text) - : mContext.getString( - R.string.zen_mode_format_status_and_trigger, - mContext.getString(R.string.zen_mode_active_text), - dynamicDescription); - case ENABLED -> dynamicDescription; - case DISABLED_BY_USER -> mContext.getString(R.string.zen_mode_disabled_by_user); - case DISABLED_BY_OTHER -> mContext.getString(R.string.zen_mode_disabled_needs_setup); - }; - setSummary(statusText); + ZenMode.Status status = zenMode.getStatus(); + String statusText = getStatusText(status, mDescriptions.getTriggerDescription(zenMode)); + String triggerDescriptionForA11y = mDescriptions.getTriggerDescriptionForAccessibility( + zenMode); + + if (triggerDescriptionForA11y != null) { + setSummary(createAccessibleSequence(statusText, + getStatusText(status, triggerDescriptionForA11y))); + } else { + setSummary(statusText); + } setIconSize(ICON_SIZE_SMALL); FutureUtil.whenDone( @@ -116,6 +118,21 @@ class ZenModesListItemPreference extends RestrictedPreference { updateTextColor(zenMode); } + private String getStatusText(ZenMode.Status status, String triggerDescription) { + return switch (status) { + case ENABLED_AND_ACTIVE -> + Strings.isNullOrEmpty(triggerDescription) + ? mContext.getString(R.string.zen_mode_active_text) + : mContext.getString( + R.string.zen_mode_format_status_and_trigger, + mContext.getString(R.string.zen_mode_active_text), + triggerDescription); + case ENABLED -> Strings.nullToEmpty(triggerDescription); + case DISABLED_BY_USER -> mContext.getString(R.string.zen_mode_disabled_by_user); + case DISABLED_BY_OTHER -> mContext.getString(R.string.zen_mode_disabled_needs_setup); + }; + } + private void updateTextColor(@Nullable ZenMode zenMode) { boolean isActive = zenMode != null && zenMode.isActive(); if (mTitleView != null) { diff --git a/tests/robotests/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizardTest.java b/tests/robotests/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizardTest.java deleted file mode 100644 index c0b9dbd2104..00000000000 --- a/tests/robotests/src/com/android/settings/accessibility/AutoBrightnessPreferenceFragmentForSetupWizardTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2024 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.accessibility; - -import static com.google.common.truth.Truth.assertThat; - -import android.app.settings.SettingsEnums; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; - -import androidx.fragment.app.FragmentFactory; -import androidx.fragment.app.testing.FragmentScenario; -import androidx.lifecycle.Lifecycle; -import androidx.preference.Preference; - -import com.android.settings.R; -import com.android.settingslib.widget.FooterPreference; - -import com.google.android.setupcompat.template.FooterBarMixin; -import com.google.android.setupdesign.GlifLayout; -import com.google.android.setupdesign.GlifPreferenceLayout; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.robolectric.RobolectricTestRunner; - -/** Tests for {@link AutoBrightnessPreferenceFragmentForSetupWizard}. */ -@RunWith(RobolectricTestRunner.class) -public class AutoBrightnessPreferenceFragmentForSetupWizardTest { - - // Same as AutoBrightnessPreferenceFragmentForSetupWizard#FOOTER_PREFERENCE_KEY - private static final String FOOTER_PREFERENCE_KEY = "auto_brightness_footer"; - - private FragmentScenario mFragmentScenario; - - private AutoBrightnessPreferenceFragmentForSetupWizard mFragment; - private GlifLayout mGlifLayout; - - @Before - public void setUp() { - mFragmentScenario = FragmentScenario - .launch( - AutoBrightnessPreferenceFragmentForSetupWizard.class, - /* fragmentArgs= */ (Bundle) null, - R.style.GlifTheme, - /* factory= */ (FragmentFactory) null) - .moveToState(Lifecycle.State.RESUMED); - mFragmentScenario.onFragment(fragment -> mFragment = fragment); - - View view = mFragment.getView(); - assertThat(view).isInstanceOf(GlifPreferenceLayout.class); - mGlifLayout = (GlifLayout) view; - } - - @After - public void tearDown() { - mFragmentScenario.close(); - } - - @Test - public void onViewCreated_verifyGlifHerderText() { - assertThat(mGlifLayout.getHeaderText()) - .isEqualTo(mFragment.getString(R.string.auto_brightness_title)); - } - - @Test - public void onViewCreated_verifyGlifFooter() { - FooterBarMixin footerMixin = mGlifLayout.getMixin(FooterBarMixin.class); - assertThat(footerMixin).isNotNull(); - - Button footerButton = footerMixin.getPrimaryButtonView(); - assertThat(footerButton).isNotNull(); - assertThat(footerButton.getText().toString()).isEqualTo(mFragment.getString(R.string.done)); - - footerButton.performClick(); - assertThat(mFragment.getActivity().isFinishing()).isTrue(); - } - - @Test - public void onViewCreated_verifyFooterPreference() { - Preference pref = mFragment.findPreference(FOOTER_PREFERENCE_KEY); - assertThat(pref).isInstanceOf(FooterPreference.class); - - FooterPreference footerPref = (FooterPreference) pref; - String exactTitle = footerPref.getTitle().toString(); - assertThat(exactTitle).isEqualTo(mFragment.getString(R.string.auto_brightness_description)); - - // Ensure that footer content description has "About XXX" prefix for consistency with other - // accessibility suw pages - String expectedContentDescription = - mFragment.getString(R.string.auto_brightness_content_description_title) - + "\n\n" + exactTitle; - assertThat(footerPref.getContentDescription().toString()) - .isEqualTo(expectedContentDescription); - } - - @Test - public void getMetricsCategory_returnsCorrectCategory() { - assertThat(mFragment.getMetricsCategory()).isEqualTo( - SettingsEnums.SUW_ACCESSIBILITY_AUTO_BRIGHTNESS); - } -} diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java index a575d5ab7d7..4dc4dca4ab7 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingCallAudioPreferenceControllerTest.java @@ -527,12 +527,12 @@ public class AudioSharingCallAudioPreferenceControllerTest { shadowOf(Looper.getMainLooper()).idle(); assertThat(mPreference.getSummary().toString()).isEmpty(); - // onReceiveStateChanged will update summary + // onSourceAdded will update summary Settings.Secure.putInt(mContentResolver, TEST_SETTINGS_KEY, TEST_DEVICE_GROUP_ID1); when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice1)); when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); - mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice1, /* sourceId= */ 1, mState); + mController.mBroadcastAssistantCallback.onSourceAdded(mDevice1, /* sourceId= */ + 1, /* reason= */ 1); shadowOf(Looper.getMainLooper()).idle(); assertThat(mPreference.getSummary().toString()) .isEqualTo( @@ -557,8 +557,6 @@ public class AudioSharingCallAudioPreferenceControllerTest { mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceAdded( - mDevice1, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceAddFailed( mDevice1, mSource, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceRemoved( @@ -572,6 +570,8 @@ public class AudioSharingCallAudioPreferenceControllerTest { mController.mBroadcastAssistantCallback.onSourceFound(mSource); mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1); shadowOf(Looper.getMainLooper()).idle(); + mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, + mState); // Above callbacks won't update summary. assertThat(mPreference.getSummary().toString()).isEmpty(); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java index 0bc0b949193..a49d0c13890 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java @@ -521,21 +521,9 @@ public class AudioSharingDevicePreferenceControllerTest { @Test public void testBluetoothLeBroadcastAssistantCallbacks_updateGroup() { - // onReceiveStateChanged with unconnected state will do nothing - when(mState.getBisSyncState()).thenReturn(new ArrayList<>()); - mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice, /* sourceId= */ 1, mState); - shadowOf(Looper.getMainLooper()).idle(); - verify(mBluetoothDeviceUpdater, never()).forceUpdate(); - verify(mDialogHandler, never()).closeOpeningDialogsForLeaDevice(mCachedDevice); - - // onReceiveStateChanged with connected state will update group preference and handle - // stale dialogs - List bisSyncState = new ArrayList<>(); - bisSyncState.add(1L); - when(mState.getBisSyncState()).thenReturn(bisSyncState); - mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice, /* sourceId= */ 1, mState); + // onSourceAdded will update group preference and handle stale dialogs + mController.mBroadcastAssistantCallback.onSourceAdded(mDevice, /* sourceId= */ + 1, /* reason= */ 1); shadowOf(Looper.getMainLooper()).idle(); verify(mBluetoothDeviceUpdater).forceUpdate(); verify(mDialogHandler).closeOpeningDialogsForLeaDevice(mCachedDevice); @@ -572,8 +560,13 @@ public class AudioSharingDevicePreferenceControllerTest { mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceAdded( - mDevice, /* sourceId= */ 1, /* reason= */ 1); + List bisSyncState = new ArrayList<>(); + bisSyncState.add(1L); + when(mState.getBisSyncState()).thenReturn(bisSyncState); + when(mBroadcast.getLatestBroadcastId()).thenReturn(1); + when(mState.getBroadcastId()).thenReturn(1); + mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice, /* sourceId= */ 1, + mState); mController.mBroadcastAssistantCallback.onSourceModified( mDevice, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceModifyFailed( 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 d8c663f6dc2..bac8b30ff16 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDeviceVolumeGroupControllerTest.java @@ -461,18 +461,9 @@ public class AudioSharingDeviceVolumeGroupControllerTest { @Test public void testBluetoothLeBroadcastAssistantCallbacks_updateGroup() { - when(mState.getBisSyncState()).thenReturn(new ArrayList<>()); - // onReceiveStateChanged with unconnected state will do nothing - mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice1, /* sourceId= */ 1, mState); - verify(mDeviceUpdater, never()).forceUpdate(); - - // onReceiveStateChanged with connected state will update group preference - List bisSyncState = new ArrayList<>(); - bisSyncState.add(1L); - when(mState.getBisSyncState()).thenReturn(bisSyncState); - mController.mBroadcastAssistantCallback.onReceiveStateChanged( - mDevice1, /* sourceId= */ 1, mState); + // onSourceAdded will update group preference + mController.mBroadcastAssistantCallback.onSourceAdded(mDevice1, /* sourceId= */ + 1, /* reason= */ 1); verify(mDeviceUpdater).forceUpdate(); // onSourceRemoved will update group preference @@ -487,8 +478,13 @@ public class AudioSharingDeviceVolumeGroupControllerTest { mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceAdded( - mDevice1, /* sourceId= */ 1, /* reason= */ 1); + List bisSyncState = new ArrayList<>(); + bisSyncState.add(1L); + when(mState.getBisSyncState()).thenReturn(bisSyncState); + when(mBroadcast.getLatestBroadcastId()).thenReturn(1); + when(mState.getBroadcastId()).thenReturn(1); + mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, + mState); mController.mBroadcastAssistantCallback.onSourceAddFailed( mDevice1, mSource, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceRemoveFailed( diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java index fb5aa1c957e..7851b2b38f8 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java @@ -476,7 +476,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_notInit_noDialog() { + public void onBroadcastMetadataChanged_notInit_noDialog() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -503,7 +503,7 @@ public class AudioSharingSwitchBarControllerTest { // No progress dialog. assertThat(childFragments).isEmpty(); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mFeatureFactory.metricsFeatureProvider) @@ -515,7 +515,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_hasLocalSource_noDialog() { + public void onBroadcastMetadataChanged_hasLocalSource_noDialog() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -533,7 +533,7 @@ public class AudioSharingSwitchBarControllerTest { assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly( AudioSharingProgressDialogFragment.class.getName()); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mAssistant, never()).addSource(any(), any(), anyBoolean()); @@ -549,7 +549,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_singleActiveDevice_showJoinAudioSharingDialog() { + public void onBroadcastMetadataChanged_singleActiveDevice_showJoinAudioSharingDialog() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -566,15 +566,15 @@ public class AudioSharingSwitchBarControllerTest { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mFeatureFactory.metricsFeatureProvider) .action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING)); when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L)); - mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice2, /* sourceId= */ 1, - mState); + mController.mBroadcastAssistantCallback.onSourceAdded(mDevice2, /* sourceId= */ + 1, /* reason= */ 1); shadowOf(Looper.getMainLooper()).idle(); childFragments = mParentFragment.getChildFragmentManager().getFragments(); @@ -613,7 +613,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_oneActiveOnConnected_showJoinAudioSharingDialog() { + public void onBroadcastMetadataChanged_oneActiveOnConnected_showJoinAudioSharingDialog() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -635,7 +635,7 @@ public class AudioSharingSwitchBarControllerTest { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mFeatureFactory.metricsFeatureProvider) @@ -681,7 +681,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_oneActiveOnConnected_clickShareBtnOnDialog_addSource() { + public void onBroadcastMetadataChanged_oneActiveOnConnected_clickShareBtnOnDialog_addSource() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -694,7 +694,7 @@ public class AudioSharingSwitchBarControllerTest { verify(mBroadcast).startPrivateBroadcast(); when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false); @@ -722,7 +722,7 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void onPlaybackStarted_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() { + public void onBroadcastMetadataChanged_oneActiveOnConnected_clickCancelBtnOnDialog_doNothing() { FeatureFlagUtils.setEnabled( mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); when(mBtnView.isEnabled()).thenReturn(true); @@ -735,7 +735,7 @@ public class AudioSharingSwitchBarControllerTest { verify(mBroadcast).startPrivateBroadcast(); when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false); @@ -835,7 +835,7 @@ public class AudioSharingSwitchBarControllerTest { when(mBroadcast.isEnabled(null)).thenReturn(true); when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false); @@ -868,16 +868,15 @@ public class AudioSharingSwitchBarControllerTest { } @Test - public void testAssistantCallbacks_onReceiveStateChanged_dismissProgressDialog() { + public void testAssistantCallbacks_onSourceAdded_dismissProgressDialog() { AudioSharingProgressDialogFragment.show(mParentFragment, TEST_DEVICE_NAME1); shadowOf(Looper.getMainLooper()).idle(); List childFragments = mParentFragment.getChildFragmentManager().getFragments(); assertThat(childFragments).comparingElementsUsing(CLAZZNAME_EQUALS).containsExactly( AudioSharingProgressDialogFragment.class.getName()); - when(mState.getBisSyncState()).thenReturn(ImmutableList.of(1L)); - mController.mBroadcastAssistantCallback.onReceiveStateChanged(mDevice1, /* sourceId= */ 1, - mState); + mController.mBroadcastAssistantCallback.onSourceAdded(mDevice1, /* sourceId= */ + 1, /* reason= */ 1); shadowOf(Looper.getMainLooper()).idle(); childFragments = mParentFragment.getChildFragmentManager().getFragments(); assertThat(childFragments).isEmpty(); @@ -892,8 +891,6 @@ public class AudioSharingSwitchBarControllerTest { mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceAdded( - mDevice1, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceRemoved( mDevice1, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceRemoveFailed( @@ -1013,7 +1010,7 @@ public class AudioSharingSwitchBarControllerTest { shadowOf(Looper.getMainLooper()).idle(); verify(mBroadcast).startPrivateBroadcast(); - mController.mBroadcastCallback.onPlaybackStarted(0, 0); + mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); shadowOf(Looper.getMainLooper()).idle(); verify(mFeatureFactory.metricsFeatureProvider) diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java index 1d39bc9f0db..4c25c11db70 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamButtonControllerTest.java @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static com.google.common.truth.Truth.assertThat; @@ -31,10 +32,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.settings.SettingsEnums; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.platform.test.flag.junit.SetFlagsRule; import android.view.View; @@ -46,6 +49,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; import com.android.settings.testutils.FakeFeatureFactory; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.core.lifecycle.Lifecycle; @@ -62,6 +66,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; @@ -73,6 +78,7 @@ import java.util.concurrent.Executor; shadows = { ShadowThreadUtils.class, ShadowAudioStreamsHelper.class, + ShadowBluetoothAdapter.class, }) public class AudioStreamButtonControllerTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -95,6 +101,13 @@ public class AudioStreamButtonControllerTest { @Before public void setUp() { mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mAssistant); mFeatureFactory = FakeFeatureFactory.setupForTest(); @@ -261,6 +274,7 @@ public class AudioStreamButtonControllerTest { @Test public void testCallback_onReceiveStateChangedWithSourcePresent_updateButton() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); String address = "11:22:33:44:55:66"; diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderControllerTest.java index 5cdc7974846..54b26ec228a 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamHeaderControllerTest.java @@ -20,6 +20,7 @@ import static com.android.settings.connecteddevice.audiosharing.audiostreams.Aud import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_NOT_LISTENING_SUMMARY; import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamHeaderController.AUDIO_STREAM_HEADER_PRESENT_NOW_SUMMARY; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -28,9 +29,11 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.graphics.drawable.Drawable; import android.platform.test.flag.junit.SetFlagsRule; @@ -41,6 +44,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowEntityHeaderController; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settings.widget.EntityHeaderController; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; @@ -57,6 +61,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; @@ -69,6 +74,7 @@ import java.util.concurrent.Executor; ShadowEntityHeaderController.class, ShadowThreadUtils.class, ShadowAudioStreamsHelper.class, + ShadowBluetoothAdapter.class, }) public class AudioStreamHeaderControllerTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -93,6 +99,13 @@ public class AudioStreamHeaderControllerTest { @Before public void setUp() { mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); ShadowEntityHeaderController.setUseMock(mHeaderController); ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); @@ -260,6 +273,7 @@ public class AudioStreamHeaderControllerTest { @Test public void testCallback_onReceiveStateChangedWithSourcePresent_updateButton() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); String address = "11:22:33:44:55:66"; diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandlerTest.java index bb873d44575..7b53ca6c74c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandlerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamStateHandlerTest.java @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static com.google.common.truth.Truth.assertThat; @@ -31,6 +32,8 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.platform.test.flag.junit.SetFlagsRule; import android.text.SpannableString; @@ -38,6 +41,8 @@ import android.text.SpannableString; import androidx.preference.Preference; import androidx.test.core.app.ApplicationProvider; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -47,8 +52,14 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; @RunWith(RobolectricTestRunner.class) +@Config( + shadows = { + ShadowBluetoothAdapter.class, + }) public class AudioStreamStateHandlerTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); @@ -64,6 +75,13 @@ public class AudioStreamStateHandlerTest { @Before public void setUp() { mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); mHandler = spy(new AudioStreamStateHandler()); } @@ -109,6 +127,7 @@ public class AudioStreamStateHandlerTest { @Test public void testHandleStateChange_setNewState_sourcePresent() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); when(mHandler.getStateEnum()) diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryControllerTest.java index 0e003097a3f..c83c8a2137c 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsCategoryControllerTest.java @@ -135,47 +135,47 @@ public class AudioStreamsCategoryControllerTest { @Test public void getAvailabilityStatus_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); } @Test public void getAvailabilityStatus_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE); } @Test public void onStart_flagOff_doNothing() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.onStart(mLifecycleOwner); verify(mBluetoothEventManager, never()).registerCallback(any()); } @Test public void onStart_flagOn_registerCallback() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.onStart(mLifecycleOwner); verify(mBluetoothEventManager).registerCallback(any()); } @Test public void onStop_flagOff_doNothing() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.onStop(mLifecycleOwner); verify(mBluetoothEventManager, never()).unregisterCallback(any()); } @Test public void onStop_flagOn_unregisterCallback() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.onStop(mLifecycleOwner); verify(mBluetoothEventManager).unregisterCallback(any()); } @Test public void updateVisibility_flagOff_invisible() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.updateVisibility(); shadowOf(Looper.getMainLooper()).idle(); assertThat(mPreference.isVisible()).isFalse(); @@ -183,7 +183,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void updateVisibility_noConnectedLe_invisible() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); mController.updateVisibility(); shadowOf(Looper.getMainLooper()).idle(); assertThat(mPreference.isVisible()).isFalse(); @@ -191,7 +191,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void updateVisibility_isNotProfileReady_invisible() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected( mCachedBluetoothDevice); when(mVolumeControl.isProfileReady()).thenReturn(false); @@ -202,7 +202,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void updateVisibility_isBroadcasting_invisible() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected( mCachedBluetoothDevice); when(mBroadcast.isEnabled(any())).thenReturn(true); @@ -213,7 +213,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void updateVisibility_isBluetoothOff_invisible() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected( mCachedBluetoothDevice); mShadowBluetoothAdapter.setEnabled(false); @@ -224,7 +224,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void updateVisibility_visible() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); ShadowAudioStreamsHelper.setCachedBluetoothDeviceInSharingOrLeConnected( mCachedBluetoothDevice); mController.displayPreference(mScreen); @@ -235,7 +235,7 @@ public class AudioStreamsCategoryControllerTest { @Test public void onProfileConnectionStateChanged_updateVisibility() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_QR_CODE_PRIVATE_BROADCAST_SHARING); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING); ArgumentCaptor argumentCaptor = ArgumentCaptor.forClass(BluetoothCallback.class); mController.onStart(mLifecycleOwner); diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java index fca1137e5c7..abfc4b7cc80 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsHelperTest.java @@ -20,6 +20,7 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static com.google.common.truth.Truth.assertThat; @@ -33,9 +34,11 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; @@ -45,6 +48,7 @@ import androidx.fragment.app.FragmentActivity; import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager; @@ -65,6 +69,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.Collections; @@ -74,6 +79,7 @@ import java.util.List; @Config( shadows = { ShadowThreadUtils.class, + ShadowBluetoothAdapter.class, }) public class AudioStreamsHelperTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -97,6 +103,13 @@ public class AudioStreamsHelperTest { @Before public void setUp() { mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager); when(mLocalBluetoothProfileManager.getLeAudioBroadcastAssistantProfile()) @@ -229,6 +242,7 @@ public class AudioStreamsHelperTest { @Test public void getAllPresentSources_noSource() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); List devices = new ArrayList<>(); @@ -251,6 +265,7 @@ public class AudioStreamsHelperTest { @Test public void getAllPresentSources_returnSource() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); String address = "11:22:33:44:55:66"; diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallbackTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallbackTest.java index 1e645282227..4e962c7deb3 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallbackTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryCallbackTest.java @@ -17,6 +17,7 @@ package com.android.settings.connecteddevice.audiosharing.audiostreams; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; @@ -24,11 +25,18 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; +import android.bluetooth.BluetoothStatusCodes; +import android.content.Context; import android.platform.test.flag.junit.SetFlagsRule; +import androidx.test.core.app.ApplicationProvider; + +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; + import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -37,15 +45,21 @@ import org.mockito.Mock; import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import java.util.ArrayList; import java.util.List; @RunWith(RobolectricTestRunner.class) +@Config( + shadows = { + ShadowBluetoothAdapter.class, + }) public class AudioStreamsProgressCategoryCallbackTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - + private final Context mContext = ApplicationProvider.getApplicationContext(); @Mock private AudioStreamsProgressCategoryController mController; @Mock private BluetoothDevice mDevice; @Mock private BluetoothLeBroadcastReceiveState mState; @@ -56,7 +70,14 @@ public class AudioStreamsProgressCategoryCallbackTest { @Before public void setUp() { mSetFlagsRule.disableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); - mCallback = new AudioStreamsProgressCategoryCallback(mController); + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + mCallback = new AudioStreamsProgressCategoryCallback(mContext, mController); } @Test @@ -71,6 +92,7 @@ public class AudioStreamsProgressCategoryCallbackTest { @Test public void testOnReceiveStateChanged_sourcePresent() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); String address = "11:22:33:44:55:66"; diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryControllerTest.java index 227748ae232..78d4d6e1361 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/audiostreams/AudioStreamsProgressCategoryControllerTest.java @@ -26,6 +26,7 @@ import static com.android.settings.connecteddevice.audiosharing.audiostreams.Aud import static com.android.settings.connecteddevice.audiosharing.audiostreams.AudioStreamsProgressCategoryController.UNSET_BROADCAST_ID; import static com.android.settings.core.BasePreferenceController.AVAILABLE; import static com.android.settingslib.flags.Flags.FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX; +import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING; import static com.google.common.truth.Truth.assertThat; @@ -48,6 +49,7 @@ import android.bluetooth.BluetoothLeAudioContentMetadata; import android.bluetooth.BluetoothLeBroadcastMetadata; import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothStatusCodes; import android.content.Context; import android.os.Looper; import android.platform.test.flag.junit.SetFlagsRule; @@ -62,6 +64,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.R; import com.android.settings.connecteddevice.audiosharing.audiostreams.testshadows.ShadowAudioStreamsHelper; +import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settings.testutils.shadow.ShadowThreadUtils; import com.android.settingslib.bluetooth.BluetoothEventManager; @@ -84,6 +87,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowAlertDialog; import org.robolectric.shadows.androidx.fragment.FragmentController; @@ -97,6 +101,7 @@ import java.util.List; ShadowAudioStreamsHelper.class, ShadowThreadUtils.class, ShadowAlertDialog.class, + ShadowBluetoothAdapter.class, }) public class AudioStreamsProgressCategoryControllerTest { @Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -129,6 +134,13 @@ public class AudioStreamsProgressCategoryControllerTest { @Before public void setUp() { + ShadowBluetoothAdapter shadowBluetoothAdapter = Shadow.extract( + BluetoothAdapter.getDefaultAdapter()); + shadowBluetoothAdapter.setEnabled(true); + shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); + shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported( + BluetoothStatusCodes.FEATURE_SUPPORTED); ShadowAudioStreamsHelper.setUseMock(mAudioStreamsHelper); when(mAudioStreamsHelper.getLeBroadcastAssistant()).thenReturn(mLeBroadcastAssistant); when(mAudioStreamsHelper.getAllConnectedSources()).thenReturn(emptyList()); @@ -292,6 +304,7 @@ public class AudioStreamsProgressCategoryControllerTest { @Test public void testOnStart_initHasDevice_getPresentSources() { + mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING); mSetFlagsRule.enableFlags(FLAG_AUDIO_SHARING_HYSTERESIS_MODE_FIX); // Setup a device diff --git a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceTest.kt b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceTest.kt index d85980efe67..c0ad07eec3b 100644 --- a/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceTest.kt +++ b/tests/robotests/src/com/android/settings/network/AdaptiveConnectivityTogglePreferenceTest.kt @@ -17,68 +17,90 @@ package com.android.settings.network import android.content.Context +import android.content.ContextWrapper import android.net.wifi.WifiManager -import android.platform.test.flag.junit.SetFlagsRule -import android.provider.Settings +import android.provider.Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED import androidx.test.core.app.ApplicationProvider import androidx.test.ext.junit.runners.AndroidJUnit4 import com.android.settingslib.preference.createAndBindWidget import com.android.settingslib.widget.MainSwitchPreference import com.google.common.truth.Truth.assertThat -import org.junit.Before -import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.mockito.kotlin.atLeastOnce import org.mockito.kotlin.mock -import org.mockito.kotlin.spy import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever // LINT.IfChange @RunWith(AndroidJUnit4::class) class AdaptiveConnectivityTogglePreferenceTest { - @get:Rule - val setFlagsRule = SetFlagsRule() + private val mockWifiManager = mock() - private val appContext: Context = spy(ApplicationProvider.getApplicationContext()){} - - private val mockWifiManager: WifiManager = mock() + private val context: Context = + object : ContextWrapper(ApplicationProvider.getApplicationContext()) { + override fun getSystemService(name: String): Any? = + when { + name == getSystemServiceName(WifiManager::class.java) -> mockWifiManager + else -> super.getSystemService(name) + } + } private val adaptiveConnectivityTogglePreference = AdaptiveConnectivityTogglePreference() - @Before - fun setUp() { - whenever(appContext.getSystemService(WifiManager::class.java)).thenReturn(mockWifiManager) + @Test + fun switchClick_defaultDisabled_returnFalse() { + setAdaptiveConnectivityEnabled(false) + + assertThat(getMainSwitchPreference().isChecked).isFalse() } @Test - fun setChecked_withTrue_shouldUpdateSetting() { - Settings.Secure.putInt( - appContext.contentResolver, - Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, 0 - ) + fun switchClick_defaultEnabled_returnTrue() { + setAdaptiveConnectivityEnabled(true) - val mainSwitchPreference = getMainSwitchPreferenceCompat().apply { performClick() } - - assertThat(mainSwitchPreference.isChecked).isTrue() - verify(mockWifiManager, atLeastOnce()).setWifiScoringEnabled(true) + assertThat(getMainSwitchPreference().isChecked).isTrue() } @Test - fun setChecked_withFalse_shouldUpdateSetting() { - Settings.Secure.putInt( - appContext.contentResolver, - Settings.Secure.ADAPTIVE_CONNECTIVITY_ENABLED, 1 - ) + fun setChecked_defaultEnabled_updatesCorrectly() { + val preference = getMainSwitchPreference() + assertThat(preference.isChecked).isTrue() - val mainSwitchPreference = getMainSwitchPreferenceCompat().apply { performClick() } + preference.performClick() - assertThat(mainSwitchPreference.isChecked).isFalse() + assertThat(preference.isChecked).isFalse() + + preference.performClick() + + assertThat(preference.isChecked).isTrue() + } + + @Test + fun storeSetTrue_wifiManagerSetWifiScoringEnabled() { + setAdaptiveConnectivityEnabled(true) + + assertThat(getAdaptiveConnectivityEnabled()).isTrue() + verify(mockWifiManager).setWifiScoringEnabled(true) + } + + @Test + fun storeSetFalse_wifiManagerSetWifiScoringDisabled() { + setAdaptiveConnectivityEnabled(false) + + assertThat(getAdaptiveConnectivityEnabled()).isFalse() verify(mockWifiManager).setWifiScoringEnabled(false) } - private fun getMainSwitchPreferenceCompat(): MainSwitchPreference = - adaptiveConnectivityTogglePreference.createAndBindWidget(appContext) + private fun getMainSwitchPreference(): MainSwitchPreference = + adaptiveConnectivityTogglePreference.createAndBindWidget(context) + + private fun setAdaptiveConnectivityEnabled(enabled: Boolean) = + adaptiveConnectivityTogglePreference + .storage(context) + .setValue(ADAPTIVE_CONNECTIVITY_ENABLED, Boolean::class.javaObjectType, enabled) + + private fun getAdaptiveConnectivityEnabled() = + adaptiveConnectivityTogglePreference + .storage(context) + .getValue(ADAPTIVE_CONNECTIVITY_ENABLED, Boolean::class.javaObjectType) } // LINT.ThenChange(AdaptiveConnectivityTogglePreferenceControllerTest.java) diff --git a/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java index 273bcdbe213..6ec3eb2bec0 100644 --- a/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/app/SoundPreferenceControllerTest.java @@ -302,6 +302,26 @@ public class SoundPreferenceControllerTest { RingtoneManager.EXTRA_RINGTONE_TYPE, 0)); } + @Test + public void testOnPreferenceTreeClick_noAudioAttributes() { + NotificationBackend.AppRow appRow = new NotificationBackend.AppRow(); + NotificationChannel channel = new NotificationChannel("", "", IMPORTANCE_HIGH); + channel.setSound(null, null); + mController.onResume(appRow, channel, null, null, null, null, null); + + AttributeSet attributeSet = Robolectric.buildAttributeSet().build(); + NotificationSoundPreference pref = + spy(new NotificationSoundPreference(mContext, attributeSet)); + pref.setKey(mController.getPreferenceKey()); + mController.handlePreferenceTreeClick(pref); + + ArgumentCaptor intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class); + verify(pref, times(1)).onPrepareRingtonePickerIntent(intentArgumentCaptor.capture()); + assertEquals(RingtoneManager.TYPE_NOTIFICATION, + intentArgumentCaptor.getValue().getIntExtra( + RingtoneManager.EXTRA_RINGTONE_TYPE, 0)); + } + @Test public void testOnActivityResult() { NotificationSoundPreference pref = mock(NotificationSoundPreference.class); diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java index a7d52b16575..f9601d70f6c 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAllBypassingAppsPreferenceControllerTest.java @@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -28,10 +27,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.app.Flags; -import android.app.NotificationChannel; import android.content.Context; import android.content.pm.ApplicationInfo; -import android.content.pm.ParceledListSlice; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; @@ -39,7 +36,6 @@ import androidx.fragment.app.Fragment; import androidx.preference.Preference; import androidx.preference.PreferenceCategory; -import com.android.settings.notification.NotificationBackend; import com.android.settingslib.applications.ApplicationsState; import org.junit.Before; @@ -54,6 +50,7 @@ import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; +import java.util.Map; @RunWith(RobolectricTestRunner.class) @EnableFlags(Flags.FLAG_MODES_UI) @@ -66,7 +63,7 @@ public class ZenModeAllBypassingAppsPreferenceControllerTest { private Context mContext; @Mock - private NotificationBackend mBackend; + private ZenHelperBackend mBackend; @Mock private PreferenceCategory mPreferenceCategory; @Mock @@ -102,18 +99,25 @@ public class ZenModeAllBypassingAppsPreferenceControllerTest { entry2.info.packageName = "test2"; entry2.info.uid = 0; + ApplicationsState.AppEntry entry3= mock(ApplicationsState.AppEntry.class); + entry3.info = new ApplicationInfo(); + entry3.info.packageName = "test3"; + entry3.info.uid = 0; + List appEntries = new ArrayList<>(); appEntries.add(entry1); appEntries.add(entry2); - List channelsBypassing = new ArrayList<>(); - channelsBypassing.add(mock(NotificationChannel.class)); - channelsBypassing.add(mock(NotificationChannel.class)); - when(mBackend.getNotificationChannelsBypassingDnd(anyString(), - anyInt())).thenReturn(new ParceledListSlice<>(channelsBypassing)); + appEntries.add(entry3); + when(mBackend.getPackagesBypassingDnd(anyInt())).thenReturn( + Map.of("test", true, "test2", false)); // THEN there's are two preferences mController.updateAppList(appEntries); - verify(mPreferenceCategory, times(2)).addPreference(any()); + ArgumentCaptor captor = ArgumentCaptor.forClass(Preference.class); + verify(mPreferenceCategory, times(2)).addPreference(captor.capture()); + List prefs = captor.getAllValues(); + assertThat(prefs.get(0).getSummary().toString()).isEqualTo("All notifications"); + assertThat(prefs.get(1).getSummary().toString()).isEqualTo("Some notifications"); } @Test diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java index fa83f309db1..e747b423af5 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModeAppsLinkPreferenceControllerTest.java @@ -77,6 +77,7 @@ import org.robolectric.RuntimeEnvironment; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Random; @RunWith(RobolectricTestRunner.class) @@ -200,8 +201,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { ApplicationsState.AppEntry app2 = createAppEntry("app2", mContext.getUserId()); List allApps = List.of(app1, app2); - when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId(), - false)).thenReturn(List.of("app1")); + when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId())).thenReturn( + Map.of("app1", true)); assertThat(mController.getAppsBypassingDndSortedByName(allApps)).containsExactly(app1); } @@ -213,8 +214,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { ApplicationsState.AppEntry appB = createAppEntry("B", mContext.getUserId()); List allApps = List.of(appC, appA, appB); - when(mHelperBackend.getPackagesBypassingDnd(eq(mContext.getUserId()), anyBoolean())) - .thenReturn(List.of("B", "C", "A")); + when(mHelperBackend.getPackagesBypassingDnd(eq(mContext.getUserId()))) + .thenReturn(Map.of("B", true, "C", false, "A", true)); assertThat(mController.getAppsBypassingDndSortedByName(allApps)) .containsExactly(appA, appB, appC).inOrder(); @@ -234,10 +235,10 @@ public final class ZenModeAppsLinkPreferenceControllerTest { List allApps = List.of(workCopy, personalCopy, otherPersonal, otherWork); - when(mHelperBackend.getPackagesBypassingDnd(eq(mContext.getUserId()), anyBoolean())) - .thenReturn(List.of("app", "p2")); - when(mHelperBackend.getPackagesBypassingDnd(eq(10), anyBoolean())) - .thenReturn(List.of("app")); + when(mHelperBackend.getPackagesBypassingDnd(eq(mContext.getUserId()))) + .thenReturn(Map.of("app", true, "p2", true)); + when(mHelperBackend.getPackagesBypassingDnd(eq(10))) + .thenReturn(Map.of("app", false)); // Personal copy before work copy (names match). assertThat(mController.getAppsBypassingDndSortedByName(allApps)) @@ -253,7 +254,7 @@ public final class ZenModeAppsLinkPreferenceControllerTest { mController.updateState(mPreference, zenMode); verifyNoMoreInteractions(mSession); - verify(mHelperBackend, never()).getPackagesBypassingDnd(anyInt(), anyBoolean()); + verify(mHelperBackend, never()).getPackagesBypassingDnd(anyInt()); assertThat(String.valueOf(mPreference.getSummary())).isEqualTo("None"); } @@ -266,9 +267,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { ArrayList appEntries = new ArrayList<>(); appEntries.add(createAppEntry("test", mContext.getUserId())); - when(mHelperBackend.getPackagesBypassingDnd( - mContext.getUserId(), false)) - .thenReturn(List.of("test")); + when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId())) + .thenReturn(Map.of("test", false)); // Updates the preference with the zen mode. We expect that this causes the app session // to trigger a rebuild (and display a temporary text in the meantime). @@ -286,8 +286,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { ZenMode zenMode = createPriorityChannelsZenMode(); mController.updateState(mPreference, zenMode); - when(mHelperBackend.getPackagesBypassingDnd(anyInt(), anyBoolean())) - .thenReturn(ImmutableList.of("test1", "test2")); + when(mHelperBackend.getPackagesBypassingDnd(anyInt())) + .thenReturn(Map.of("test1", false, "test2", false)); ArrayList appEntries = new ArrayList<>(); appEntries.add(createAppEntry("test1", mContext.getUserId())); appEntries.add(createAppEntry("test2", mContext.getUserId())); @@ -328,8 +328,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { .build(); ArrayList appEntries = new ArrayList<>(); appEntries.add(createAppEntry("test", mContext.getUserId())); - when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId(), false)) - .thenReturn(List.of("test")); + when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId())) + .thenReturn(Map.of("test", true)); mController.updateState(mPreference, zenModeWithNone); @@ -355,8 +355,8 @@ public final class ZenModeAppsLinkPreferenceControllerTest { .build(); ArrayList appEntries = new ArrayList<>(); appEntries.add(createAppEntry("test", mContext.getUserId())); - when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId(), false)) - .thenReturn(List.of("test")); + when(mHelperBackend.getPackagesBypassingDnd(mContext.getUserId())) + .thenReturn(Map.of("test", true)); mController.updateState(mPreference, zenModeWithPriority); diff --git a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java index 3722e416061..4f96bf6da7a 100644 --- a/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/notification/modes/ZenModesListItemPreferenceTest.java @@ -16,12 +16,19 @@ package com.android.settings.notification.modes; +import static android.app.AutomaticZenRule.TYPE_SCHEDULE_TIME; +import static android.service.notification.SystemZenRules.PACKAGE_ANDROID; + import static com.google.common.truth.Truth.assertThat; import android.app.Flags; import android.content.Context; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; +import android.service.notification.SystemZenRules; +import android.service.notification.ZenModeConfig; +import android.text.Spanned; +import android.text.style.TtsSpan; import com.android.settingslib.notification.modes.TestModeBuilder; import com.android.settingslib.notification.modes.ZenIconLoader; @@ -37,6 +44,8 @@ import org.mockito.MockitoAnnotations; import org.robolectric.RobolectricTestRunner; import org.robolectric.RuntimeEnvironment; +import java.util.Calendar; + @RunWith(RobolectricTestRunner.class) @EnableFlags(Flags.FLAG_MODES_UI) public class ZenModesListItemPreferenceTest { @@ -122,6 +131,31 @@ public class ZenModesListItemPreferenceTest { assertThat(preference.getIcon()).isNotNull(); } + @Test + public void setZenMode_scheduleTime_hasCustomTtsInSummary() { + ZenModeConfig.ScheduleInfo scheduleInfo = new ZenModeConfig.ScheduleInfo(); + scheduleInfo.days = new int[] { Calendar.MONDAY, Calendar.TUESDAY, Calendar.WEDNESDAY }; + scheduleInfo.startHour = 11; + scheduleInfo.endHour = 15; + ZenMode mode = new TestModeBuilder() + .setPackage(PACKAGE_ANDROID) + .setType(TYPE_SCHEDULE_TIME) + .setConditionId(ZenModeConfig.toScheduleConditionId(scheduleInfo)) + .setTriggerDescription( + SystemZenRules.getTriggerDescriptionForScheduleTime(mContext, scheduleInfo)) + .build(); + + ZenModesListItemPreference preference = newPreference(mode); + + assertThat(preference.getSummary()).isInstanceOf(Spanned.class); + Spanned summary = (Spanned) preference.getSummary(); + TtsSpan[] ttsSpans = summary.getSpans(0, summary.length(), TtsSpan.class); + assertThat(ttsSpans).hasLength(1); + assertThat(ttsSpans[0].getType()).isEqualTo(TtsSpan.TYPE_TEXT); + assertThat(ttsSpans[0].getArgs().getString(TtsSpan.ARG_TEXT)).isEqualTo( + "Monday to Wednesday, 11:00 AM - 3:00 PM"); + } + private ZenModesListItemPreference newPreference(ZenMode zenMode) { return new ZenModesListItemPreference(mContext, mIconLoader, MoreExecutors.directExecutor(), zenMode); diff --git a/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt b/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt index ce0d0f55ffd..13b5167095c 100644 --- a/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt +++ b/tests/spa_unit/src/com/android/settings/network/apn/ApnTypesTest.kt @@ -91,6 +91,68 @@ class ApnTypesTest { assertThat(apnType).isEqualTo("default,mms,supl,hipri,fota,cbs,xcap") } + @Test + fun hasAllApnTypes_allString() { + val apnTypes = listOf(ApnSetting.TYPE_ALL_STRING) + + val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) + + assertThat(hasAllApnTypes).isTrue() + } + + @Test + fun hasAllApnTypes_allTypes() { + val apnTypes = listOf( + ApnSetting.TYPE_DEFAULT_STRING, + ApnSetting.TYPE_MMS_STRING, + ApnSetting.TYPE_SUPL_STRING, + ApnSetting.TYPE_DUN_STRING, + ApnSetting.TYPE_HIPRI_STRING, + ApnSetting.TYPE_FOTA_STRING, + ApnSetting.TYPE_IMS_STRING, + ApnSetting.TYPE_CBS_STRING, + ApnSetting.TYPE_IA_STRING, + ApnSetting.TYPE_EMERGENCY_STRING, + ApnSetting.TYPE_MCX_STRING, + ApnSetting.TYPE_XCAP_STRING, + ApnSetting.TYPE_VSIM_STRING, + ApnSetting.TYPE_BIP_STRING, + ApnSetting.TYPE_ENTERPRISE_STRING, + ApnSetting.TYPE_OEM_PAID_STRING, + ApnSetting.TYPE_OEM_PRIVATE_STRING, + ) + + val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) + + assertThat(hasAllApnTypes).isTrue() + } + + @Test + fun hasAllApnTypes_allTypesExceptDefault() { + val apnTypes = listOf( + ApnSetting.TYPE_MMS_STRING, + ApnSetting.TYPE_SUPL_STRING, + ApnSetting.TYPE_DUN_STRING, + ApnSetting.TYPE_HIPRI_STRING, + ApnSetting.TYPE_FOTA_STRING, + ApnSetting.TYPE_IMS_STRING, + ApnSetting.TYPE_CBS_STRING, + ApnSetting.TYPE_IA_STRING, + ApnSetting.TYPE_EMERGENCY_STRING, + ApnSetting.TYPE_MCX_STRING, + ApnSetting.TYPE_XCAP_STRING, + ApnSetting.TYPE_VSIM_STRING, + ApnSetting.TYPE_BIP_STRING, + ApnSetting.TYPE_ENTERPRISE_STRING, + ApnSetting.TYPE_OEM_PAID_STRING, + ApnSetting.TYPE_OEM_PRIVATE_STRING, + ) + + val hasAllApnTypes = ApnTypes.hasAllApnTypes(apnTypes) + + assertThat(hasAllApnTypes).isFalse() + } + private companion object { const val APN_TYPE = "type" }