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

Commit c5354242 authored by Longbo Wei's avatar Longbo Wei Committed by Android (Google) Code Review
Browse files

Merge "audio: Show microphone icon when input device is connected" into main

parents 670fd8e2 4f30728f
Loading
Loading
Loading
Loading
+8 −16
Original line number Diff line number Diff line
@@ -170,12 +170,11 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                // Set different layout for each device
                if (device.isMutingExpectedDevice()
                        && !mController.isCurrentConnectedDeviceRemote()) {
                    updateTitleIcon(R.drawable.media_output_icon_volume,
                            mController.getColorItemContent());
                    updateUnmutedVolumeIcon(device);
                    mCurrentActivePosition = position;
                    updateFullItemClickListener(v -> onItemClick(v, device));
                    setSingleLineLayout(getItemTitle(device));
                    initFakeActiveDevice();
                    initFakeActiveDevice(device);
                } else if (device.hasSubtext()) {
                    boolean isActiveWithOngoingSession =
                            (device.hasOngoingSession() && (currentlyConnected || isDeviceIncluded(
@@ -184,8 +183,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                            && isActiveWithOngoingSession;
                    if (isActiveWithOngoingSession) {
                        mCurrentActivePosition = position;
                        updateTitleIcon(R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                        updateUnmutedVolumeIcon(device);
                        mSubTitleText.setText(device.getSubtextString());
                        updateTwoLineLayoutContentAlpha(DEVICE_CONNECTED_ALPHA);
                        updateEndClickAreaAsSessionEditing(device,
@@ -199,9 +197,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    } else {
                        if (currentlyConnected) {
                            mCurrentActivePosition = position;
                            updateTitleIcon(R.drawable.media_output_icon_volume,
                                    mController.getColorItemContent());
                            initSeekbar(device, isCurrentSeekbarInvisible);
                            updateUnmutedVolumeIcon(device);
                        } else {
                            setUpDeviceIcon(device);
                        }
@@ -243,8 +239,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                    // selected device in group
                    boolean isDeviceDeselectable = isDeviceIncluded(
                            mController.getDeselectableMediaDevice(), device);
                    updateTitleIcon(R.drawable.media_output_icon_volume,
                            mController.getColorItemContent());
                    updateUnmutedVolumeIcon(device);
                    updateGroupableCheckBox(true, isDeviceDeselectable, device);
                    updateEndClickArea(device, isDeviceDeselectable);
                    disableFocusPropertyForView(mContainerLayout);
@@ -264,8 +259,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                        setSingleLineLayout(getItemTitle(device));
                    } else if (device.hasOngoingSession()) {
                        mCurrentActivePosition = position;
                        updateTitleIcon(R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                        updateUnmutedVolumeIcon(device);
                        updateEndClickAreaAsSessionEditing(device, device.isHostForOngoingSession()
                                ? R.drawable.media_output_status_edit_session
                                : R.drawable.ic_sound_bars_anim);
@@ -278,8 +272,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                            && !mController.getSelectableMediaDevice().isEmpty()) {
                        //If device is connected and there's other selectable devices, layout as
                        // one of selected devices.
                        updateTitleIcon(R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                        updateUnmutedVolumeIcon(device);
                        boolean isDeviceDeselectable = isDeviceIncluded(
                                mController.getDeselectableMediaDevice(), device);
                        updateGroupableCheckBox(true, isDeviceDeselectable, device);
@@ -291,8 +284,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
                                true /* showEndTouchArea */);
                        initSeekbar(device, isCurrentSeekbarInvisible);
                    } else {
                        updateTitleIcon(R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                        updateUnmutedVolumeIcon(device);
                        disableFocusPropertyForView(mContainerLayout);
                        setUpContentDescriptionForView(mSeekBar, device);
                        mCurrentActivePosition = position;
+37 −22
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
import androidx.recyclerview.widget.RecyclerView;

import com.android.settingslib.media.InputMediaDevice;
import com.android.settingslib.media.MediaDevice;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.res.R;
@@ -321,18 +322,20 @@ public abstract class MediaOutputBaseAdapter extends
                    // Check if response volume match with the latest request, to ignore obsolete
                    // response
                    if (isCurrentSeekbarInvisible && !mIsInitVolumeFirstTime) {
                        updateTitleIcon(currentVolume == 0 ? R.drawable.media_output_icon_volume_off
                                        : R.drawable.media_output_icon_volume,
                                mController.getColorItemContent());
                        if (currentVolume == 0) {
                            updateMutedVolumeIcon(device);
                        } else {
                            updateUnmutedVolumeIcon(device);
                        }
                    } else {
                        if (!mVolumeAnimator.isStarted()) {
                            int percentage =
                                    (int) ((double) currentVolume * VOLUME_PERCENTAGE_SCALE_SIZE
                                            / (double) mSeekBar.getMax());
                            if (percentage == 0) {
                                updateMutedVolumeIcon();
                                updateMutedVolumeIcon(device);
                            } else {
                                updateUnmutedVolumeIcon();
                                updateUnmutedVolumeIcon(device);
                            }
                            mSeekBar.setVolume(currentVolume);
                            mLatestUpdateVolume = -1;
@@ -340,7 +343,7 @@ public abstract class MediaOutputBaseAdapter extends
                    }
                } else if (currentVolume == 0) {
                    mSeekBar.resetVolume();
                    updateMutedVolumeIcon();
                    updateMutedVolumeIcon(device);
                }
                if (currentVolume == mLatestUpdateVolume) {
                    mLatestUpdateVolume = -1;
@@ -365,7 +368,7 @@ public abstract class MediaOutputBaseAdapter extends
                            R.string.media_output_dialog_volume_percentage, percentage));
                    mVolumeValueText.setVisibility(View.VISIBLE);
                    if (mStartFromMute) {
                        updateUnmutedVolumeIcon();
                        updateUnmutedVolumeIcon(device);
                        mStartFromMute = false;
                    }
                    if (progressToVolume != deviceVolume) {
@@ -390,9 +393,9 @@ public abstract class MediaOutputBaseAdapter extends
                            seekBar.getProgress());
                    if (currentVolume == 0) {
                        seekBar.setProgress(0);
                        updateMutedVolumeIcon();
                        updateMutedVolumeIcon(device);
                    } else {
                        updateUnmutedVolumeIcon();
                        updateUnmutedVolumeIcon(device);
                    }
                    mTitleIcon.setVisibility(View.VISIBLE);
                    mVolumeValueText.setVisibility(View.GONE);
@@ -402,36 +405,48 @@ public abstract class MediaOutputBaseAdapter extends
            });
        }

        void updateMutedVolumeIcon() {
        void updateMutedVolumeIcon(MediaDevice device) {
            mIconAreaLayout.setBackground(
                    mContext.getDrawable(R.drawable.media_output_item_background_active));
            updateTitleIcon(R.drawable.media_output_icon_volume_off,
                    mController.getColorItemContent());
            updateTitleIcon(device, true /* isMutedVolumeIcon */);
        }

        void updateUnmutedVolumeIcon() {
        void updateUnmutedVolumeIcon(MediaDevice device) {
            mIconAreaLayout.setBackground(
                    mContext.getDrawable(R.drawable.media_output_title_icon_area)
            );
            updateTitleIcon(R.drawable.media_output_icon_volume,
                    mController.getColorItemContent());
            updateTitleIcon(device, false /* isMutedVolumeIcon */);
        }

        void updateTitleIcon(@DrawableRes int id, int color) {
        void updateTitleIcon(MediaDevice device, boolean isMutedVolumeIcon) {
            boolean isInputMediaDevice = device instanceof InputMediaDevice;
            int id = getDrawableId(isInputMediaDevice, isMutedVolumeIcon);
            mTitleIcon.setImageDrawable(mContext.getDrawable(id));
            mTitleIcon.setImageTintList(ColorStateList.valueOf(color));
            mTitleIcon.setImageTintList(ColorStateList.valueOf(mController.getColorItemContent()));
            mIconAreaLayout.setBackgroundTintList(
                    ColorStateList.valueOf(mController.getColorSeekbarProgress()));
        }

        @VisibleForTesting
        int getDrawableId(boolean isInputDevice, boolean isMutedVolumeIcon) {
            // Returns the microphone icon when the flag is enabled and the device is an input
            // device.
            if (com.android.media.flags.Flags.enableAudioInputDeviceRoutingAndVolumeControl()
                    && isInputDevice) {
                return isMutedVolumeIcon ? R.drawable.ic_mic_off : R.drawable.ic_mic_26dp;
            }
            return isMutedVolumeIcon
                    ? R.drawable.media_output_icon_volume_off
                    : R.drawable.media_output_icon_volume;
        }

        void updateIconAreaClickListener(View.OnClickListener listener) {
            mIconAreaLayout.setOnClickListener(listener);
        }

        void initFakeActiveDevice() {
        void initFakeActiveDevice(MediaDevice device) {
            disableSeekBar();
            updateTitleIcon(R.drawable.media_output_icon_volume,
                    mController.getColorItemContent());
            updateTitleIcon(device, false /* isMutedIcon */);
            final Drawable backgroundDrawable = mContext.getDrawable(
                                    R.drawable.media_output_item_background_active)
                            .mutate();
@@ -518,13 +533,13 @@ public abstract class MediaOutputBaseAdapter extends
                    mController.logInteractionUnmuteDevice(device);
                    mSeekBar.setVolume(UNMUTE_DEFAULT_VOLUME);
                    mController.adjustVolume(device, UNMUTE_DEFAULT_VOLUME);
                    updateUnmutedVolumeIcon();
                    updateUnmutedVolumeIcon(device);
                    mIconAreaLayout.setOnTouchListener(((iconV, event) -> false));
                } else {
                    mController.logInteractionMuteDevice(device);
                    mSeekBar.resetVolume();
                    mController.adjustVolume(device, 0);
                    updateMutedVolumeIcon();
                    updateMutedVolumeIcon(device);
                    mIconAreaLayout.setOnTouchListener(((iconV, event) -> {
                        mSeekBar.dispatchTouchEvent(event);
                        return false;
+67 −0
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import static org.mockito.Mockito.when;
import android.app.WallpaperColors;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import android.platform.test.annotations.DisableFlags;
import android.platform.test.annotations.EnableFlags;
import android.testing.TestableLooper;
import android.view.View;
import android.widget.LinearLayout;
@@ -44,6 +46,7 @@ import androidx.core.graphics.drawable.IconCompat;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;

import com.android.media.flags.Flags;
import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.SysuiTestCase;
@@ -738,4 +741,68 @@ public class MediaOutputAdapterTest extends SysuiTestCase {

        assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(updatedList.size());
    }

    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagDisabled_InputDeviceMutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(true /* isInputDevice */, true /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume_off);
    }

    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagDisabled_OutputDeviceMutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(false /* isInputDevice */, true /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume_off);
    }

    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagDisabled_InputDeviceUnmutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(true /* isInputDevice */, false /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume);
    }

    @DisableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagDisabled_OutputDeviceUnmutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(false /* isInputDevice */, false /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume);
    }

    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagEnabled_InputDeviceMutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(true /* isInputDevice */, true /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.ic_mic_off);
    }

    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagEnabled_OutputDeviceMutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(false /* isInputDevice */, true /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume_off);
    }

    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagEnabled_InputDeviceUnmutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(true /* isInputDevice */, false /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.ic_mic_26dp);
    }

    @EnableFlags(Flags.FLAG_ENABLE_AUDIO_INPUT_DEVICE_ROUTING_AND_VOLUME_CONTROL)
    @Test
    public void getDrawableId_FlagEnabled_OutputDeviceUnmutedIcon() {
        assertThat(
                mViewHolder.getDrawableId(false /* isInputDevice */, false /* isMutedVolumeIcon */))
                .isEqualTo(R.drawable.media_output_icon_volume);
    }
}