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

Commit 970be3d6 authored by timhypeng's avatar timhypeng
Browse files

Add "Stop" button for remote device

-Add "Stop" to stop remote media session
-Refine UI layout
1. Adjust size of head icon and apply defined dimen value
2. Move list padding inside the list to prevent truncating the list
3. Remove group-related view(I will add it in recycle view when the group feature is ready.)
-Add MediaOutputDialogTest
-Rename PAIR_NEW to CUSTOMIZED_ITEM_PAIR_NEW
-Integrate more UI view in setTwoLineLayout()

Bug: 155822415
Test: atest MediaOutputAdapterTest MediaOutputBaseDialogTest MediaOutputControllerTest MediaOutputDialogTest
Change-Id: Ie6a917c56a0ef97f772a8f43742afd2ee61e407f
parent 61510f10
Loading
Loading
Loading
Loading
+1 −23
Original line number Original line Diff line number Diff line
@@ -32,7 +32,7 @@
            android:id="@+id/header_icon"
            android:id="@+id/header_icon"
            android:layout_width="wrap_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_height="wrap_content"
            android:paddingEnd="16dp"/>
            android:paddingEnd="@dimen/media_output_dialog_header_icon_padding"/>


        <LinearLayout
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_width="match_parent"
@@ -70,36 +70,14 @@
        android:id="@+id/device_list"
        android:id="@+id/device_list"
        android:layout_width="match_parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="start|center_vertical"
        android:orientation="vertical">
        android:orientation="vertical">


        <View
            android:layout_width="match_parent"
            android:layout_height="12dp"/>

        <include
            layout="@layout/media_output_list_item"
            android:id="@+id/group_item_controller"
            android:visibility="gone"/>

        <View
            android:id="@+id/group_item_divider"
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="?android:attr/listDivider"
            android:visibility="gone"/>

        <androidx.recyclerview.widget.RecyclerView
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/list_result"
            android:id="@+id/list_result"
            android:scrollbars="vertical"
            android:scrollbars="vertical"
            android:layout_width="match_parent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_height="wrap_content"
            android:overScrollMode="never"/>
            android:overScrollMode="never"/>

        <View
            android:id="@+id/list_bottom_padding"
            android:layout_width="match_parent"
            android:layout_height="12dp"/>
    </LinearLayout>
    </LinearLayout>


    <View
    <View
+2 −1
Original line number Original line Diff line number Diff line
@@ -1368,9 +1368,10 @@
    <dimen name="config_rounded_mask_size_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen>
    <dimen name="config_rounded_mask_size_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen>


    <!-- Output switcher panel related dimensions -->
    <!-- Output switcher panel related dimensions -->
    <dimen name="media_output_dialog_padding_top">11dp</dimen>
    <dimen name="media_output_dialog_list_margin">12dp</dimen>
    <dimen name="media_output_dialog_list_max_height">364dp</dimen>
    <dimen name="media_output_dialog_list_max_height">364dp</dimen>
    <dimen name="media_output_dialog_header_album_icon_size">52dp</dimen>
    <dimen name="media_output_dialog_header_album_icon_size">52dp</dimen>
    <dimen name="media_output_dialog_header_back_icon_size">36dp</dimen>
    <dimen name="media_output_dialog_header_back_icon_size">36dp</dimen>
    <dimen name="media_output_dialog_header_icon_padding">16dp</dimen>
    <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
    <dimen name="media_output_dialog_icon_corner_radius">16dp</dimen>
</resources>
</resources>
+28 −27
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ import java.util.List;
public class MediaOutputAdapter extends MediaOutputBaseAdapter {
public class MediaOutputAdapter extends MediaOutputBaseAdapter {


    private static final String TAG = "MediaOutputAdapter";
    private static final String TAG = "MediaOutputAdapter";
    private static final int PAIR_NEW = 1;
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);


    public MediaOutputAdapter(MediaOutputController controller) {
    public MediaOutputAdapter(MediaOutputController controller) {
        super(controller);
        super(controller);
@@ -58,11 +58,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {


    @Override
    @Override
    public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
    public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
        if (mController.isZeroMode() && position == (mController.getMediaDevices().size())) {
        final int size = mController.getMediaDevices().size();
            viewHolder.onBind(PAIR_NEW);
        if (mController.isZeroMode() && position == size) {
        } else if (position < (mController.getMediaDevices().size())) {
            viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
            viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position));
                    true /* bottomMargin */);
        } else {
        } else if (position < size) {
            viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
                    position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */);
        } else if (DEBUG) {
            Log.d(TAG, "Incorrect position: " + position);
            Log.d(TAG, "Incorrect position: " + position);
        }
        }
    }
    }
@@ -83,7 +86,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
    }
    }


    void onItemClick(int customizedItem) {
    void onItemClick(int customizedItem) {
        if (customizedItem == PAIR_NEW) {
        if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
            mController.launchBluetoothPairing();
            mController.launchBluetoothPairing();
        }
        }
    }
    }
@@ -112,51 +115,49 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
        }
        }


        @Override
        @Override
        void onBind(MediaDevice device) {
        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
            super.onBind(device);
            super.onBind(device, topMargin, bottomMargin);
            if (mController.isTransferring()) {
            if (mController.isTransferring()) {
                if (device.getState() == MediaDeviceState.STATE_CONNECTING
                if (device.getState() == MediaDeviceState.STATE_CONNECTING
                        && !mController.hasAdjustVolumeUserRestriction()) {
                        && !mController.hasAdjustVolumeUserRestriction()) {
                    setTwoLineLayout(device, true);
                    setTwoLineLayout(device, null /* title */, true /* bFocused */,
                    mProgressBar.setVisibility(View.VISIBLE);
                            false /* showSeekBar*/, true /* showProgressBar */,
                    mSeekBar.setVisibility(View.GONE);
                            false /* showSubtitle */);
                    mSubTitleText.setVisibility(View.GONE);
                } else {
                } else {
                    setSingleLineLayout(getItemTitle(device), false);
                    setSingleLineLayout(getItemTitle(device), false /* bFocused */);
                }
                }
            } else {
            } else {
                // Set different layout for each device
                // Set different layout for each device
                if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
                if (device.getState() == MediaDeviceState.STATE_CONNECTING_FAILED) {
                    setTwoLineLayout(device, false);
                    setTwoLineLayout(device, null /* title */, false /* bFocused */,
                    mSubTitleText.setVisibility(View.VISIBLE);
                            false /* showSeekBar*/, false /* showProgressBar */,
                    mSeekBar.setVisibility(View.GONE);
                            true /* showSubtitle */);
                    mProgressBar.setVisibility(View.GONE);
                    mSubTitleText.setText(R.string.media_output_dialog_connect_failed);
                    mSubTitleText.setText(R.string.media_output_dialog_connect_failed);
                    mFrameLayout.setOnClickListener(v -> onItemClick(device));
                    mFrameLayout.setOnClickListener(v -> onItemClick(device));
                } else if (!mController.hasAdjustVolumeUserRestriction()
                } else if (!mController.hasAdjustVolumeUserRestriction()
                        && isCurrentConnected(device)) {
                        && isCurrentConnected(device)) {
                    setTwoLineLayout(device, true);
                    setTwoLineLayout(device, null /* title */, true /* bFocused */,
                    mSeekBar.setVisibility(View.VISIBLE);
                            true /* showSeekBar*/, false /* showProgressBar */,
                    mProgressBar.setVisibility(View.GONE);
                            false /* showSubtitle */);
                    mSubTitleText.setVisibility(View.GONE);
                    initSeekbar(device);
                    initSeekbar(device);
                } else {
                } else {
                    setSingleLineLayout(getItemTitle(device), false);
                    setSingleLineLayout(getItemTitle(device), false /* bFocused */);
                    mFrameLayout.setOnClickListener(v -> onItemClick(device));
                    mFrameLayout.setOnClickListener(v -> onItemClick(device));
                }
                }
            }
            }
        }
        }


        @Override
        @Override
        void onBind(int customizedItem) {
        void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
            if (customizedItem == PAIR_NEW) {
            super.onBind(customizedItem, topMargin, bottomMargin);
            if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
                setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
                setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
                        false);
                        false /* bFocused */);
                final Drawable d = mContext.getDrawable(R.drawable.ic_add);
                final Drawable d = mContext.getDrawable(R.drawable.ic_add);
                d.setColorFilter(new PorterDuffColorFilter(
                d.setColorFilter(new PorterDuffColorFilter(
                        Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));
                        Utils.getColorAccentDefaultColor(mContext), PorterDuff.Mode.SRC_IN));
                mTitleIcon.setImageDrawable(d);
                mTitleIcon.setImageDrawable(d);
                mFrameLayout.setOnClickListener(v -> onItemClick(PAIR_NEW));
                mFrameLayout.setOnClickListener(v -> onItemClick(CUSTOMIZED_ITEM_PAIR_NEW));
            }
            }
        }
        }
    }
    }
+32 −4
Original line number Original line Diff line number Diff line
@@ -44,9 +44,12 @@ public abstract class MediaOutputBaseAdapter extends
    private static final String FONT_SELECTED_TITLE = "sans-serif-medium";
    private static final String FONT_SELECTED_TITLE = "sans-serif-medium";
    private static final String FONT_TITLE = "sans-serif";
    private static final String FONT_TITLE = "sans-serif";


    static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;

    final MediaOutputController mController;
    final MediaOutputController mController;


    private boolean mIsDragging;
    private boolean mIsDragging;
    private int mMargin;


    Context mContext;
    Context mContext;
    View mHolderView;
    View mHolderView;
@@ -60,6 +63,8 @@ public abstract class MediaOutputBaseAdapter extends
    public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
    public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
            int viewType) {
            int viewType) {
        mContext = viewGroup.getContext();
        mContext = viewGroup.getContext();
        mMargin = mContext.getResources().getDimensionPixelSize(
                R.dimen.media_output_dialog_list_margin);
        mHolderView = LayoutInflater.from(mContext).inflate(R.layout.media_output_list_item,
        mHolderView = LayoutInflater.from(mContext).inflate(R.layout.media_output_list_item,
                viewGroup, false);
                viewGroup, false);


@@ -106,12 +111,26 @@ public abstract class MediaOutputBaseAdapter extends
            mSeekBar = view.requireViewById(R.id.volume_seekbar);
            mSeekBar = view.requireViewById(R.id.volume_seekbar);
        }
        }


        void onBind(MediaDevice device) {
        void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin) {
            mTitleIcon.setImageIcon(mController.getDeviceIconCompat(device).toIcon(mContext));
            mTitleIcon.setImageIcon(mController.getDeviceIconCompat(device).toIcon(mContext));
            setMargin(topMargin, bottomMargin);
        }
        }


        void onBind(int customizedItem) { }
        void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
            setMargin(topMargin, bottomMargin);
        }


        private void setMargin(boolean topMargin, boolean bottomMargin) {
            ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mFrameLayout
                    .getLayoutParams();
            if (topMargin) {
                params.topMargin = mMargin;
            }
            if (bottomMargin) {
                params.bottomMargin = mMargin;
            }
            mFrameLayout.setLayoutParams(params);
        }
        void setSingleLineLayout(CharSequence title, boolean bFocused) {
        void setSingleLineLayout(CharSequence title, boolean bFocused) {
            mTitleText.setVisibility(View.VISIBLE);
            mTitleText.setVisibility(View.VISIBLE);
            mTwoLineLayout.setVisibility(View.GONE);
            mTwoLineLayout.setVisibility(View.GONE);
@@ -123,10 +142,19 @@ public abstract class MediaOutputBaseAdapter extends
            }
            }
        }
        }


        void setTwoLineLayout(MediaDevice device, boolean bFocused) {
        void setTwoLineLayout(MediaDevice device, CharSequence title, boolean bFocused,
                boolean showSeekBar, boolean showProgressBar, boolean showSubtitle) {
            mTitleText.setVisibility(View.GONE);
            mTitleText.setVisibility(View.GONE);
            mTwoLineLayout.setVisibility(View.VISIBLE);
            mTwoLineLayout.setVisibility(View.VISIBLE);
            mSeekBar.setVisibility(showSeekBar ? View.VISIBLE : View.GONE);
            mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
            mSubTitleText.setVisibility(showSubtitle ? View.VISIBLE : View.GONE);
            if (device == null) {
                mTwoLineTitleText.setText(title);
            } else {
                mTwoLineTitleText.setText(getItemTitle(device));
                mTwoLineTitleText.setText(getItemTitle(device));
            }

            if (bFocused) {
            if (bFocused) {
                mTwoLineTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE,
                mTwoLineTitleText.setTypeface(Typeface.create(FONT_SELECTED_TITLE,
                        Typeface.NORMAL));
                        Typeface.NORMAL));
+7 −14
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@ import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView;
@@ -69,12 +68,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
    private LinearLayout mDeviceListLayout;
    private LinearLayout mDeviceListLayout;
    private Button mDoneButton;
    private Button mDoneButton;
    private Button mStopButton;
    private Button mStopButton;
    private View mListBottomPadding;
    private int mListMaxHeight;
    private int mListMaxHeight;


    MediaOutputBaseAdapter mAdapter;
    MediaOutputBaseAdapter mAdapter;
    FrameLayout mGroupItemController;
    View mGroupDivider;


    private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
    private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
        // Set max height for list
        // Set max height for list
@@ -114,12 +110,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
        mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
        mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
        mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
        mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
        mDevicesRecyclerView = mDialogView.requireViewById(R.id.list_result);
        mDevicesRecyclerView = mDialogView.requireViewById(R.id.list_result);
        mGroupItemController = mDialogView.requireViewById(R.id.group_item_controller);
        mGroupDivider = mDialogView.requireViewById(R.id.group_item_divider);
        mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
        mDeviceListLayout = mDialogView.requireViewById(R.id.device_list);
        mDoneButton = mDialogView.requireViewById(R.id.done);
        mDoneButton = mDialogView.requireViewById(R.id.done);
        mStopButton = mDialogView.requireViewById(R.id.stop);
        mStopButton = mDialogView.requireViewById(R.id.stop);
        mListBottomPadding = mDialogView.requireViewById(R.id.list_bottom_padding);


        mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
        mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
                mDeviceListLayoutListener);
                mDeviceListLayoutListener);
@@ -162,7 +155,9 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
        }
        }
        if (mHeaderIcon.getVisibility() == View.VISIBLE) {
        if (mHeaderIcon.getVisibility() == View.VISIBLE) {
            final int size = getHeaderIconSize();
            final int size = getHeaderIconSize();
            mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size, size));
            final int padding = mContext.getResources().getDimensionPixelSize(
                    R.dimen.media_output_dialog_header_icon_padding);
            mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size + padding, size));
        }
        }
        // Update title and subtitle
        // Update title and subtitle
        mHeaderTitle.setText(getHeaderText());
        mHeaderTitle.setText(getHeaderText());
@@ -178,12 +173,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
        if (!mAdapter.isDragging()) {
        if (!mAdapter.isDragging()) {
            mAdapter.notifyDataSetChanged();
            mAdapter.notifyDataSetChanged();
        }
        }
        // Add extra padding when device amount is less than 6
        // Show when remote media session is available
        if (mMediaOutputController.getMediaDevices().size() < 6) {
        mStopButton.setVisibility(getStopButtonVisibility());
            mListBottomPadding.setVisibility(View.VISIBLE);
        } else {
            mListBottomPadding.setVisibility(View.GONE);
        }
    }
    }


    abstract int getHeaderIconRes();
    abstract int getHeaderIconRes();
@@ -196,6 +187,8 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements


    abstract CharSequence getHeaderSubtitle();
    abstract CharSequence getHeaderSubtitle();


    abstract int getStopButtonVisibility();

    @Override
    @Override
    public void onMediaChanged() {
    public void onMediaChanged() {
        mMainThreadHandler.post(() -> refresh());
        mMainThreadHandler.post(() -> refresh());
Loading