Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9c0904ac authored by Betty Chang's avatar Betty Chang Committed by Android (Google) Code Review
Browse files

Merge "[LE Audio] To fix the condition of the broadcast icon display" into tm-qpr-dev

parents 2cd733dc d55a7067
Loading
Loading
Loading
Loading
+22 −7
Original line number Diff line number Diff line
@@ -41,15 +41,18 @@ import com.android.settingslib.media.MediaOutputConstants;
 * nearby broadcast sources.
 */
public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {

    public static final String KEY_APP_LABEL = "app_label";
    public static final String KEY_DEVICE_ADDRESS =
            BluetoothFindBroadcastsFragment.KEY_DEVICE_ADDRESS;
    public static final String KEY_MEDIA_STREAMING = "media_streaming";

    private static final String TAG = "BTBroadcastsDialog";
    private static final CharSequence UNKNOWN_APP_LABEL = "unknown";
    private Context mContext;
    private CharSequence mCurrentAppLabel = UNKNOWN_APP_LABEL;
    private String mDeviceAddress;
    private boolean mIsMediaStreaming;
    private LocalBluetoothManager mLocalBluetoothManager;
    private AlertDialog mAlertDialog;

@@ -59,6 +62,7 @@ public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
        mContext = getActivity();
        mCurrentAppLabel = getActivity().getIntent().getCharSequenceExtra(KEY_APP_LABEL);
        mDeviceAddress = getActivity().getIntent().getStringExtra(KEY_DEVICE_ADDRESS);
        mIsMediaStreaming = getActivity().getIntent().getBooleanExtra(KEY_MEDIA_STREAMING, false);
        mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
        setShowsDialog(true);
    }
@@ -75,6 +79,8 @@ public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
                mContext.getString(R.string.bluetooth_broadcast_dialog_broadcast_message));

        Button broadcastBtn = layout.findViewById(com.android.settingslib.R.id.positive_btn);
        if (isBroadcastSupported() && mIsMediaStreaming) {
            broadcastBtn.setVisibility(View.VISIBLE);
            if (TextUtils.isEmpty(mCurrentAppLabel)) {
                broadcastBtn.setText(mContext.getString(R.string.bluetooth_broadcast_dialog_title));
            } else {
@@ -85,6 +91,9 @@ public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
            broadcastBtn.setOnClickListener((view) -> {
                launchMediaOutputBroadcastDialog();
            });
        } else {
            broadcastBtn.setVisibility(View.GONE);
        }

        Button findBroadcastBtn = layout.findViewById(com.android.settingslib.R.id.negative_btn);
        findBroadcastBtn.setText(mContext.getString(R.string.bluetooth_find_broadcast));
@@ -169,4 +178,10 @@ public class BluetoothBroadcastDialog extends InstrumentedDialogFragment {
                .setPackage(MediaOutputConstants.SETTINGS_PACKAGE_NAME)
                .setAction(MediaOutputConstants.ACTION_CLOSE_PANEL));
    }

    boolean isBroadcastSupported() {
        LocalBluetoothLeBroadcast broadcast =
                mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
        return broadcast != null;
    }
}
+4 −6
Original line number Diff line number Diff line
@@ -36,16 +36,15 @@ import android.view.ViewOutlineProvider;
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.StringRes;

import com.android.settings.core.InstrumentedFragment;
import com.android.settingslib.R;
import com.android.settingslib.bluetooth.BluetoothBroadcastUtils;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.core.lifecycle.ObservableFragment;
import com.android.settingslib.qrcode.QrCamera;

import androidx.annotation.NonNull;
import androidx.annotation.StringRes;

public class QrCodeScanModeFragment extends InstrumentedFragment implements
        TextureView.SurfaceTextureListener,
        QrCamera.ScannerCallback {
@@ -232,8 +231,7 @@ public class QrCodeScanModeFragment extends InstrumentedFragment implements
    }

    private void updateSummary() {
        mSummary.setText(getString(R.string.bt_le_audio_scan_qr_code_scanner,
                null /* broadcast_name*/));;
        mSummary.setText(getString(R.string.bt_le_audio_scan_qr_code_scanner));
    }

    @Override
+10 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.builders.ListBuilder;
import androidx.slice.builders.SliceAction;

import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.bluetooth.BluetoothBroadcastDialog;
@@ -90,13 +91,16 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont
        return R.drawable.ic_media_stream_off;
    }

    private boolean isSupportEndItem() {
        return getWorker() != null
            && getWorker().getActiveLocalMediaController() != null
            && isConnectedBLEDevice();
    @VisibleForTesting
    boolean isSupportEndItem() {
        return isConnectedBLEDevice();
    }

    private boolean isConnectedBLEDevice() {
        if (getWorker() == null) {
            Log.d(TAG, "The Worker is null");
            return false;
        }
        mMediaDevice = getWorker().getCurrentConnectedMediaDevice();
        if (mMediaDevice != null) {
            return mMediaDevice.isBLEDevice();
@@ -133,6 +137,8 @@ public class MediaVolumePreferenceController extends VolumeSeekBarPreferenceCont
                    Utils.getApplicationLabel(mContext, getWorker().getPackageName()));
            intent.putExtra(BluetoothBroadcastDialog.KEY_DEVICE_ADDRESS,
                    bluetoothDevice.getAddress());
            intent.putExtra(BluetoothBroadcastDialog.KEY_MEDIA_STREAMING, getWorker() != null
                    && getWorker().getActiveLocalMediaController() != null);

            pi = PendingIntent.getActivity(context, 0 /* requestCode */, intent,
                    PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+121 −0
Original line number Diff line number Diff line
@@ -16,29 +16,71 @@

package com.android.settings.notification;

import static com.android.settings.slices.CustomSliceRegistry.VOLUME_MEDIA_URI;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.session.MediaController;
import android.net.Uri;

import androidx.slice.builders.SliceAction;

import com.android.settings.media.MediaOutputIndicatorWorker;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.media.BluetoothMediaDevice;
import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaOutputConstants;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = MediaVolumePreferenceControllerTest.ShadowSliceBackgroundWorker.class)
public class MediaVolumePreferenceControllerTest {

    private static final String ACTION_LAUNCH_BROADCAST_DIALOG =
            "android.settings.MEDIA_BROADCAST_DIALOG";
    private static MediaOutputIndicatorWorker sMediaOutputIndicatorWorker;

    private MediaVolumePreferenceController mController;

    private Context mContext;

    @Mock
    private MediaController mMediaController;
    @Mock
    private MediaDevice mDevice1;
    @Mock
    private MediaDevice mDevice2;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mContext = RuntimeEnvironment.application;
        mController = new MediaVolumePreferenceController(mContext);
        sMediaOutputIndicatorWorker = spy(
                new MediaOutputIndicatorWorker(mContext, VOLUME_MEDIA_URI));
        when(mDevice1.isBLEDevice()).thenReturn(true);
        when(mDevice2.isBLEDevice()).thenReturn(false);
    }

    @Test
@@ -68,4 +110,83 @@ public class MediaVolumePreferenceControllerTest {
    public void isPublicSlice_returnTrue() {
        assertThat(mController.isPublicSlice()).isTrue();
    }

    @Test
    public void isSupportEndItem_withBleDevice_returnsTrue() {
        doReturn(mDevice1).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();

        assertThat(mController.isSupportEndItem()).isTrue();
    }

    @Test
    public void isSupportEndItem_withNonBleDevice_returnsFalse() {
        doReturn(mDevice2).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();

        assertThat(mController.isSupportEndItem()).isFalse();
    }

    @Test
    public void getSliceEndItem_NotSupportEndItem_getsNullSliceAction() {
        doReturn(mDevice2).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();

        final SliceAction sliceAction = mController.getSliceEndItem(mContext);

        assertThat(sliceAction).isNull();
    }

    @Test
    public void getSliceEndItem_deviceIsBroadcasting_getsBroadcastIntent() {
        doReturn(mDevice1).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();
        doReturn(true).when(sMediaOutputIndicatorWorker).isDeviceBroadcasting();
        doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                .getActiveLocalMediaController();

        final SliceAction sliceAction = mController.getSliceEndItem(mContext);

        final PendingIntent endItemPendingIntent = sliceAction.getAction();
        final PendingIntent expectedToggleIntent = getBroadcastIntent(
                MediaOutputConstants.ACTION_LAUNCH_MEDIA_OUTPUT_BROADCAST_DIALOG);
        assertThat(endItemPendingIntent).isEqualTo(expectedToggleIntent);
    }

    @Test
    public void getSliceEndItem_deviceIsNotBroadcasting_getsActivityIntent() {
        final MediaDevice device = mock(BluetoothMediaDevice.class);
        final CachedBluetoothDevice cachedDevice = mock(CachedBluetoothDevice.class);
        when(((BluetoothMediaDevice) device).getCachedDevice()).thenReturn(cachedDevice);
        when(device.isBLEDevice()).thenReturn(true);
        doReturn(device).when(sMediaOutputIndicatorWorker).getCurrentConnectedMediaDevice();
        doReturn(false).when(sMediaOutputIndicatorWorker).isDeviceBroadcasting();
        doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                .getActiveLocalMediaController();

        final SliceAction sliceAction = mController.getSliceEndItem(mContext);

        final PendingIntent endItemPendingIntent = sliceAction.getAction();
        final PendingIntent expectedPendingIntent =
                getActivityIntent(ACTION_LAUNCH_BROADCAST_DIALOG);
        assertThat(endItemPendingIntent).isEqualTo(expectedPendingIntent);
    }

    @Implements(SliceBackgroundWorker.class)
    public static class ShadowSliceBackgroundWorker {

        @Implementation
        public static SliceBackgroundWorker getInstance(Uri uri) {
            return sMediaOutputIndicatorWorker;
        }
    }

    private PendingIntent getBroadcastIntent(String action) {
        final Intent intent = new Intent(action);
        intent.setPackage(MediaOutputConstants.SYSTEMUI_PACKAGE_NAME);
        return PendingIntent.getBroadcast(mContext, 0 /* requestCode */, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
    }

    private PendingIntent getActivityIntent(String action) {
        final Intent intent = new Intent(action);
        return PendingIntent.getActivity(mContext, 0 /* requestCode */, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
    }
}