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

Commit cfd862db authored by Tim Peng's avatar Tim Peng
Browse files

Tapping on Play media can have up to a 1 minute delay

-Set Output Switcher activity in PendingIntent
-Broadcast is super lagged right after reboot
-Not to send broadcast to itself in order to launch Output Switcher
-Add test case

Bug: 152909957
Test: make -j42 RunSettingsRoboTests
Change-Id: I17280a3bb9e47aa6050cfaf1463c780cd9849ad7
parent 545f08e8
Loading
Loading
Loading
Loading
+20 −30
Original line number Diff line number Diff line
@@ -25,8 +25,8 @@ import android.content.Intent;
import android.graphics.Bitmap;
import android.media.session.MediaController;
import android.net.Uri;
import android.util.Log;

import androidx.annotation.VisibleForTesting;
import androidx.core.graphics.drawable.IconCompat;
import androidx.slice.Slice;
import androidx.slice.builders.ListBuilder;
@@ -36,7 +36,6 @@ import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.slices.CustomSliceable;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.slices.SliceBroadcastReceiver;
import com.android.settingslib.media.MediaOutputSliceConstants;

public class MediaOutputIndicatorSlice implements CustomSliceable {
@@ -60,8 +59,10 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
        final IconCompat icon = IconCompat.createWithResource(mContext,
                com.android.internal.R.drawable.ic_settings_bluetooth);
        final CharSequence title = mContext.getText(R.string.media_output_title);
        final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
                0 /* requestCode */, getMediaOutputSliceIntent(), 0 /* flags */);
        final SliceAction primarySliceAction = SliceAction.createDeeplink(
                getBroadcastIntent(), icon, ListBuilder.ICON_IMAGE, title);
                primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title);
        @ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
        // To set an empty icon to indent the row
        final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
@@ -74,18 +75,27 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
        return listBuilder.build();
    }

    @VisibleForTesting
    Intent getMediaOutputSliceIntent() {
        final MediaController mediaController = getWorker().getActiveLocalMediaController();
        final Intent intent = new Intent()
                .setPackage(Utils.SETTINGS_PACKAGE_NAME)
                .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (mediaController != null) {
            intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
                    mediaController.getSessionToken());
            intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
                    mediaController.getPackageName());
        }
        return intent;
    }

    private IconCompat createEmptyIcon() {
        final Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
        return IconCompat.createWithBitmap(bitmap);
    }

    private PendingIntent getBroadcastIntent() {
        final Intent intent = new Intent(getUri().toString());
        intent.setClass(mContext, SliceBroadcastReceiver.class);
        return PendingIntent.getBroadcast(mContext, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public Uri getUri() {
        return MEDIA_OUTPUT_INDICATOR_SLICE_URI;
@@ -103,26 +113,6 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
        return MediaOutputIndicatorWorker.class;
    }

    @Override
    public void onNotifyChange(Intent i) {
        if (getWorker() == null) {
            Log.d(TAG, "onNotifyChange: Worker is null");
            return;
        }
        final MediaController mediaController = getWorker().getActiveLocalMediaController();
        final Intent intent = new Intent()
                .setPackage(Utils.SETTINGS_PACKAGE_NAME)
                .setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (mediaController != null) {
            intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
                    mediaController.getSessionToken());
            intent.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
                    mediaController.getPackageName());
        }
        mContext.startActivity(intent);
    }

    private MediaOutputIndicatorWorker getWorker() {
        if (mWorker == null) {
            mWorker = SliceBackgroundWorker.getInstance(getUri());
+12 −33
Original line number Diff line number Diff line
@@ -21,11 +21,8 @@ import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDIC

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

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.content.Context;
@@ -48,14 +45,12 @@ import com.android.settings.Utils;
import com.android.settings.slices.SliceBackgroundWorker;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.media.MediaOutputSliceConstants;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
@@ -85,8 +80,6 @@ public class MediaOutputIndicatorSliceTest {
    @Mock
    private MediaController mMediaController;
    @Mock
    private LocalMediaManager mLocalMediaManager;
    @Mock
    private MediaDevice mDevice1;
    @Mock
    private MediaDevice mDevice2;
@@ -193,46 +186,32 @@ public class MediaOutputIndicatorSliceTest {
    }

    @Test
    public void onNotifyChange_noWorker_doNothing() {
        sMediaOutputIndicatorWorker = null;
        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());

        verify(mContext, never()).startActivity(any());
    }

    @Test
    public void onNotifyChange_withActiveLocalMedia_verifyIntentExtra() {
    public void getMediaOutputSliceIntent_withActiveLocalMedia_verifyIntentExtra() {
        when(mMediaController.getSessionToken()).thenReturn(mToken);
        when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
        doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                .getActiveLocalMediaController();
        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();

        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());
        verify(mContext).startActivity(intentCaptor.capture());

        assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intentCaptor.getValue().getStringExtra(
        assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra(
                MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
                .getPackage())).isTrue();
        assertThat(mToken == intentCaptor.getValue().getExtras().getParcelable(
        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
        assertThat(mToken == intent.getExtras().getParcelable(
                MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
    }

    @Test
    public void onNotifyChange_withoutActiveLocalMedia_verifyIntentExtra() {
    public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() {
        doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
                .getActiveLocalMediaController();
        final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();

        final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
        mMediaOutputIndicatorSlice.onNotifyChange(new Intent());
        verify(mContext).startActivity(intentCaptor.capture());

        assertThat(TextUtils.isEmpty(intentCaptor.getValue().getStringExtra(
        assertThat(TextUtils.isEmpty(intent.getStringExtra(
                MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intentCaptor.getValue()
                .getPackage())).isTrue();
        assertThat(intentCaptor.getValue().getExtras().getParcelable(
        assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
        assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
        assertThat(intent.getExtras().getParcelable(
                MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
    }