Add Media Output Dialog for Output Switcher
-Add MediaOutputBaseDialog to provide common method for different media operations UI -Add MediaOutputDialog for showing Bluetooth device -Add resources for background image, style and layout -Add MediaOutputBaseDialogTest for unit test Bug: 155822415 Test: atest MediaOutputBaseDialogTest Merged-In: I3086a4049f240870ca1ad870946d6848e500b561 Change-Id: I3086a4049f240870ca1ad870946d6848e500b561
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<inset xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shape android:shape="rectangle">
|
||||
<corners android:radius="8dp" />
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
</shape>
|
||||
</inset>
|
||||
136
packages/SystemUI/res/layout/media_output_dialog.xml
Normal file
136
packages/SystemUI/res/layout/media_output_dialog.xml
Normal file
@@ -0,0 +1,136 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2020 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.
|
||||
-->
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/media_output_dialog"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="94dp"
|
||||
android:gravity="start|center_vertical"
|
||||
android:paddingStart="16dp"
|
||||
android:orientation="horizontal">
|
||||
<ImageView
|
||||
android:id="@+id/header_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingEnd="16dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:orientation="vertical">
|
||||
<TextView
|
||||
android:id="@+id/header_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
|
||||
android:textSize="20sp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:fontFamily="roboto-regular"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/device_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="start|center_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
|
||||
android:id="@+id/list_result"
|
||||
android:scrollbars="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:overScrollMode="never"/>
|
||||
|
||||
<View
|
||||
android:id="@+id/list_bottom_padding"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="12dp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="?android:attr/listDivider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/stop"
|
||||
style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="64dp"
|
||||
android:text="@string/keyboard_key_media_stop"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<Space
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/done"
|
||||
style="@*android:style/Widget.DeviceDefault.Button.Borderless.Colored"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:text="@string/inline_done_button"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
@@ -400,6 +400,10 @@
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.SystemUI.Dialog.MediaOutput">
|
||||
<item name="android:windowBackground">@drawable/media_output_dialog_background</item>
|
||||
</style>
|
||||
|
||||
<style name="QSBorderlessButton">
|
||||
<item name="android:padding">12dp</item>
|
||||
<item name="android:background">@drawable/qs_btn_borderless_rect</item>
|
||||
@@ -789,5 +793,4 @@
|
||||
* Title: headline, medium 20sp
|
||||
* Message: body, 16 sp -->
|
||||
<style name="Theme.ControlsRequestDialog" parent="@*android:style/Theme.DeviceDefault.Dialog.Alert"/>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.media.dialog;
|
||||
|
||||
import static android.view.WindowInsets.Type.navigationBars;
|
||||
import static android.view.WindowInsets.Type.statusBars;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowInsets;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.settingslib.R;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
|
||||
/**
|
||||
* Base dialog for media output UI
|
||||
*/
|
||||
public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
|
||||
MediaOutputController.Callback {
|
||||
|
||||
private static final String TAG = "MediaOutputDialog";
|
||||
|
||||
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
|
||||
private final RecyclerView.LayoutManager mLayoutManager;
|
||||
|
||||
final Context mContext;
|
||||
final MediaOutputController mMediaOutputController;
|
||||
|
||||
@VisibleForTesting
|
||||
View mDialogView;
|
||||
private TextView mHeaderTitle;
|
||||
private TextView mHeaderSubtitle;
|
||||
private ImageView mHeaderIcon;
|
||||
private RecyclerView mDevicesRecyclerView;
|
||||
private LinearLayout mDeviceListLayout;
|
||||
private Button mDoneButton;
|
||||
private Button mStopButton;
|
||||
private View mListBottomPadding;
|
||||
private int mListMaxHeight;
|
||||
|
||||
MediaOutputBaseAdapter mAdapter;
|
||||
FrameLayout mGroupItemController;
|
||||
View mGroupDivider;
|
||||
|
||||
private final ViewTreeObserver.OnGlobalLayoutListener mDeviceListLayoutListener = () -> {
|
||||
// Set max height for list
|
||||
if (mDeviceListLayout.getHeight() > mListMaxHeight) {
|
||||
ViewGroup.LayoutParams params = mDeviceListLayout.getLayoutParams();
|
||||
params.height = mListMaxHeight;
|
||||
mDeviceListLayout.setLayoutParams(params);
|
||||
}
|
||||
};
|
||||
|
||||
public MediaOutputBaseDialog(Context context, MediaOutputController mediaOutputController) {
|
||||
super(context, R.style.Theme_SystemUI_Dialog_MediaOutput);
|
||||
mContext = context;
|
||||
mMediaOutputController = mediaOutputController;
|
||||
mLayoutManager = new LinearLayoutManager(mContext);
|
||||
mListMaxHeight = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.media_output_dialog_list_max_height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
mDialogView = LayoutInflater.from(mContext).inflate(R.layout.media_output_dialog, null);
|
||||
final Window window = getWindow();
|
||||
final WindowManager.LayoutParams lp = window.getAttributes();
|
||||
lp.gravity = Gravity.BOTTOM;
|
||||
// Config insets to make sure the layout is above the navigation bar
|
||||
lp.setFitInsetsTypes(statusBars() | navigationBars());
|
||||
lp.setFitInsetsSides(WindowInsets.Side.all());
|
||||
lp.setFitInsetsIgnoringVisibility(true);
|
||||
window.setAttributes(lp);
|
||||
window.setContentView(mDialogView);
|
||||
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||
|
||||
mHeaderTitle = mDialogView.requireViewById(R.id.header_title);
|
||||
mHeaderSubtitle = mDialogView.requireViewById(R.id.header_subtitle);
|
||||
mHeaderIcon = mDialogView.requireViewById(R.id.header_icon);
|
||||
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);
|
||||
mDoneButton = mDialogView.requireViewById(R.id.done);
|
||||
mStopButton = mDialogView.requireViewById(R.id.stop);
|
||||
mListBottomPadding = mDialogView.requireViewById(R.id.list_bottom_padding);
|
||||
|
||||
mDeviceListLayout.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||
mDeviceListLayoutListener);
|
||||
// Init device list
|
||||
mDevicesRecyclerView.setLayoutManager(mLayoutManager);
|
||||
mDevicesRecyclerView.setAdapter(mAdapter);
|
||||
// Init bottom buttons
|
||||
mDoneButton.setOnClickListener(v -> dismiss());
|
||||
mStopButton.setOnClickListener(v -> {
|
||||
mMediaOutputController.releaseSession();
|
||||
dismiss();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
mMediaOutputController.start(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mMediaOutputController.stop();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void refresh() {
|
||||
// Update header icon
|
||||
final int iconRes = getHeaderIconRes();
|
||||
final IconCompat iconCompat = getHeaderIcon();
|
||||
if (iconRes != 0) {
|
||||
mHeaderIcon.setVisibility(View.VISIBLE);
|
||||
mHeaderIcon.setImageResource(iconRes);
|
||||
} else if (iconCompat != null) {
|
||||
mHeaderIcon.setVisibility(View.VISIBLE);
|
||||
mHeaderIcon.setImageIcon(iconCompat.toIcon(mContext));
|
||||
} else {
|
||||
mHeaderIcon.setVisibility(View.GONE);
|
||||
}
|
||||
if (mHeaderIcon.getVisibility() == View.VISIBLE) {
|
||||
final int size = getHeaderIconSize();
|
||||
mHeaderIcon.setLayoutParams(new LinearLayout.LayoutParams(size, size));
|
||||
}
|
||||
// Update title and subtitle
|
||||
mHeaderTitle.setText(getHeaderText());
|
||||
final CharSequence subTitle = getHeaderSubtitle();
|
||||
if (TextUtils.isEmpty(subTitle)) {
|
||||
mHeaderSubtitle.setVisibility(View.GONE);
|
||||
mHeaderTitle.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
|
||||
} else {
|
||||
mHeaderSubtitle.setVisibility(View.VISIBLE);
|
||||
mHeaderSubtitle.setText(subTitle);
|
||||
mHeaderTitle.setGravity(Gravity.NO_GRAVITY);
|
||||
}
|
||||
if (!mAdapter.isDragging()) {
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
// Add extra padding when device amount is less than 6
|
||||
if (mMediaOutputController.getMediaDevices().size() < 6) {
|
||||
mListBottomPadding.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
mListBottomPadding.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
abstract int getHeaderIconRes();
|
||||
|
||||
abstract IconCompat getHeaderIcon();
|
||||
|
||||
abstract int getHeaderIconSize();
|
||||
|
||||
abstract CharSequence getHeaderText();
|
||||
|
||||
abstract CharSequence getHeaderSubtitle();
|
||||
|
||||
@Override
|
||||
public void onMediaChanged() {
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaStoppedOrPaused() {
|
||||
if (isShowing()) {
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteChanged() {
|
||||
mMainThreadHandler.post(() -> refresh());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismissDialog() {
|
||||
dismiss();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.media.dialog;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Dialog for media output transferring.
|
||||
*/
|
||||
@Singleton
|
||||
public class MediaOutputDialog extends MediaOutputBaseDialog {
|
||||
|
||||
MediaOutputDialog(Context context, boolean aboveStatusbar, MediaOutputController
|
||||
mediaOutputController) {
|
||||
super(context, mediaOutputController);
|
||||
mAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||
if (!aboveStatusbar) {
|
||||
getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
|
||||
}
|
||||
show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
mGroupItemController.setVisibility(View.GONE);
|
||||
mGroupDivider.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
int getHeaderIconRes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
IconCompat getHeaderIcon() {
|
||||
return mMediaOutputController.getHeaderIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
int getHeaderIconSize() {
|
||||
return mContext.getResources().getDimensionPixelSize(
|
||||
R.dimen.media_output_dialog_header_album_icon_size);
|
||||
}
|
||||
|
||||
@Override
|
||||
CharSequence getHeaderText() {
|
||||
return mMediaOutputController.getHeaderTitle();
|
||||
}
|
||||
|
||||
@Override
|
||||
CharSequence getHeaderSubtitle() {
|
||||
return mMediaOutputController.getHeaderSubTitle();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.systemui.media.dialog;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.session.MediaSessionManager;
|
||||
import android.os.Bundle;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.media.MediaDevice;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.plugins.ActivityStarter;
|
||||
import com.android.systemui.statusbar.phone.ShadeController;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
public class MediaOutputBaseDialogTest extends SysuiTestCase {
|
||||
|
||||
private static final String TEST_PACKAGE = "test_package";
|
||||
|
||||
// Mock
|
||||
private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class);
|
||||
|
||||
private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
|
||||
private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
|
||||
private ShadeController mShadeController = mock(ShadeController.class);
|
||||
private ActivityStarter mStarter = mock(ActivityStarter.class);
|
||||
|
||||
private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
|
||||
private MediaOutputController mMediaOutputController;
|
||||
private int mHeaderIconRes;
|
||||
private IconCompat mIconCompat;
|
||||
private CharSequence mHeaderTitle;
|
||||
private CharSequence mHeaderSubtitle;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
|
||||
mMediaSessionManager, mLocalBluetoothManager, mShadeController, mStarter);
|
||||
mMediaOutputBaseDialogImpl = new MediaOutputBaseDialogImpl(mContext,
|
||||
mMediaOutputController);
|
||||
mMediaOutputBaseDialogImpl.onCreate(new Bundle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_withIconRes_iconIsVisible() {
|
||||
mHeaderIconRes = 1;
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_icon);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_withIconCompat_iconIsVisible() {
|
||||
mIconCompat = mock(IconCompat.class);
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_icon);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_noIcon_iconLayoutNotVisible() {
|
||||
mHeaderIconRes = 0;
|
||||
mIconCompat = null;
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final ImageView view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_icon);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_checkTitle() {
|
||||
mHeaderTitle = "test_string";
|
||||
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final TextView titleView = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_title);
|
||||
|
||||
assertThat(titleView.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(titleView.getText()).isEqualTo(mHeaderTitle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_withSubtitle_checkSubtitle() {
|
||||
mHeaderSubtitle = "test_string";
|
||||
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final TextView subtitleView = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_subtitle);
|
||||
|
||||
assertThat(subtitleView.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
assertThat(subtitleView.getText()).isEqualTo(mHeaderSubtitle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_noSubtitle_checkSubtitle() {
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final TextView subtitleView = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.header_subtitle);
|
||||
|
||||
assertThat(subtitleView.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_inDragging_notUpdateAdapter() {
|
||||
when(mMediaOutputBaseAdapter.isDragging()).thenReturn(true);
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
|
||||
verify(mMediaOutputBaseAdapter, never()).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_notInDragging_verifyUpdateAdapter() {
|
||||
when(mMediaOutputBaseAdapter.isDragging()).thenReturn(false);
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
|
||||
verify(mMediaOutputBaseAdapter).notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_with6Devices_checkBottomPaddingVisibility() {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
mMediaOutputController.mMediaDevices.add(mock(MediaDevice.class));
|
||||
}
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final View view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.list_bottom_padding);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.GONE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refresh_with5Devices_checkBottomPaddingVisibility() {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
mMediaOutputController.mMediaDevices.add(mock(MediaDevice.class));
|
||||
}
|
||||
mMediaOutputBaseDialogImpl.refresh();
|
||||
final View view = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(
|
||||
R.id.list_bottom_padding);
|
||||
|
||||
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||
}
|
||||
|
||||
class MediaOutputBaseDialogImpl extends MediaOutputBaseDialog {
|
||||
|
||||
MediaOutputBaseDialogImpl(Context context, MediaOutputController mediaOutputController) {
|
||||
super(context, mediaOutputController);
|
||||
|
||||
mAdapter = mMediaOutputBaseAdapter;
|
||||
}
|
||||
|
||||
int getHeaderIconRes() {
|
||||
return mHeaderIconRes;
|
||||
}
|
||||
|
||||
IconCompat getHeaderIcon() {
|
||||
return mIconCompat;
|
||||
}
|
||||
|
||||
int getHeaderIconSize() {
|
||||
return 10;
|
||||
}
|
||||
|
||||
CharSequence getHeaderText() {
|
||||
return mHeaderTitle;
|
||||
}
|
||||
|
||||
CharSequence getHeaderSubtitle() {
|
||||
return mHeaderSubtitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user