Update output chooser for calls
- Hide media routes while in call - Change the title while in call - Add a title while not in call, too Bug: 63096355 Test: manual Change-Id: Ib7bcd314efb010fe903327dd4d9bdbfe521c1f73
This commit is contained in:
@@ -14,7 +14,7 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<!-- extends FrameLayout -->
|
||||
<!-- extends LinearLayout -->
|
||||
<com.android.systemui.volume.OutputChooserLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:sysui="http://schemas.android.com/apk/res-auto"
|
||||
@@ -23,8 +23,17 @@
|
||||
android:minHeight="320dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textDirection="locale"
|
||||
android:textAppearance="@style/TextAppearance.QS.DetailHeader"
|
||||
android:layout_marginBottom="20dp" />
|
||||
|
||||
<com.android.systemui.qs.AutoSizingList
|
||||
android:id="@android:id/list"
|
||||
android:layout_width="match_parent"
|
||||
@@ -42,9 +51,10 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/title"
|
||||
android:id="@+id/empty_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textDirection="locale"
|
||||
android:layout_marginTop="20dp"
|
||||
android:textAppearance="@style/TextAppearance.QS.DetailEmpty"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
android:layout_height="@dimen/qs_detail_item_icon_size"
|
||||
android:layout_marginStart="@dimen/qs_detail_item_icon_marginStart"
|
||||
android:layout_marginEnd="@dimen/qs_detail_item_icon_marginEnd"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:tint="?android:attr/textColorPrimary"/>
|
||||
|
||||
<LinearLayout
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.volume;
|
||||
|
||||
import android.support.v7.media.MediaRouteSelector;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper for final class MediaRouter, for testing.
|
||||
*/
|
||||
public class MediaRouterWrapper {
|
||||
|
||||
private final MediaRouter mRouter;
|
||||
|
||||
public MediaRouterWrapper(MediaRouter router)
|
||||
{
|
||||
mRouter = router;
|
||||
}
|
||||
|
||||
public void addCallback(MediaRouteSelector selector, MediaRouter.Callback callback, int flags) {
|
||||
mRouter.addCallback(selector, callback, flags);
|
||||
}
|
||||
|
||||
public void removeCallback(MediaRouter.Callback callback) {
|
||||
mRouter.removeCallback(callback);
|
||||
}
|
||||
|
||||
public void unselect(int reason) {
|
||||
mRouter.unselect(reason);
|
||||
}
|
||||
|
||||
public List<MediaRouter.RouteInfo> getRoutes() {
|
||||
return mRouter.getRoutes();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2017 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.
|
||||
@@ -40,6 +40,7 @@ import android.os.SystemClock;
|
||||
import android.support.v7.media.MediaControlIntent;
|
||||
import android.support.v7.media.MediaRouteSelector;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
@@ -54,7 +55,6 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
@@ -65,15 +65,17 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
private static final int MAX_DEVICES = 10;
|
||||
|
||||
private static final long UPDATE_DELAY_MS = 300L;
|
||||
static final int MSG_UPDATE_ITEMS = 1;
|
||||
private static final int MSG_UPDATE_ITEMS = 1;
|
||||
|
||||
private final Context mContext;
|
||||
private final BluetoothController mController;
|
||||
private final WifiManager mWifiManager;
|
||||
private final BluetoothController mBluetoothController;
|
||||
private WifiManager mWifiManager;
|
||||
private OutputChooserLayout mView;
|
||||
private final MediaRouter mRouter;
|
||||
private final MediaRouterWrapper mRouter;
|
||||
private final MediaRouterCallback mRouterCallback;
|
||||
private long mLastUpdateTime;
|
||||
private boolean mIsInCall;
|
||||
protected boolean isAttached;
|
||||
|
||||
private final MediaRouteSelector mRouteSelector;
|
||||
private Drawable mDefaultIcon;
|
||||
@@ -81,12 +83,14 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
private Drawable mSpeakerIcon;
|
||||
private Drawable mSpeakerGroupIcon;
|
||||
|
||||
public OutputChooserDialog(Context context) {
|
||||
public OutputChooserDialog(Context context, MediaRouterWrapper router) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mController = Dependency.get(BluetoothController.class);
|
||||
mBluetoothController = Dependency.get(BluetoothController.class);
|
||||
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
mRouter = MediaRouter.getInstance(context);
|
||||
TelecomManager tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
|
||||
mIsInCall = tm.isInCall();
|
||||
mRouter = router;
|
||||
mRouterCallback = new MediaRouterCallback();
|
||||
mRouteSelector = new MediaRouteSelector.Builder()
|
||||
.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)
|
||||
@@ -96,27 +100,38 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
context.registerReceiver(mReceiver, filter);
|
||||
}
|
||||
|
||||
protected void setIsInCall(boolean inCall) {
|
||||
mIsInCall = inCall;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.output_chooser);
|
||||
setCanceledOnTouchOutside(true);
|
||||
setOnDismissListener(this::onDismiss);
|
||||
setTitle(R.string.output_title);
|
||||
|
||||
mView = findViewById(R.id.output_chooser);
|
||||
mView.setCallback(this);
|
||||
|
||||
if (mIsInCall) {
|
||||
mView.setTitle(R.string.output_calls_title);
|
||||
} else {
|
||||
mView.setTitle(R.string.output_title);
|
||||
}
|
||||
|
||||
mDefaultIcon = mContext.getDrawable(R.drawable.ic_cast);
|
||||
mTvIcon = mContext.getDrawable(R.drawable.ic_tv);
|
||||
mSpeakerIcon = mContext.getDrawable(R.drawable.ic_speaker);
|
||||
mSpeakerGroupIcon = mContext.getDrawable(R.drawable.ic_speaker_group);
|
||||
|
||||
final boolean wifiOff = !mWifiManager.isWifiEnabled();
|
||||
final boolean btOff = !mController.isBluetoothEnabled();
|
||||
if (wifiOff || btOff) {
|
||||
final boolean btOff = !mBluetoothController.isBluetoothEnabled();
|
||||
if (wifiOff && btOff) {
|
||||
mView.setEmptyState(getDisabledServicesMessage(wifiOff, btOff));
|
||||
}
|
||||
// time out after 5 seconds
|
||||
mView.postDelayed(() -> updateItems(true), 5000);
|
||||
}
|
||||
|
||||
protected void cleanUp() {}
|
||||
@@ -131,15 +146,19 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
public void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
mRouter.addCallback(mRouteSelector, mRouterCallback,
|
||||
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
|
||||
mController.addCallback(mCallback);
|
||||
if (!mIsInCall) {
|
||||
mRouter.addCallback(mRouteSelector, mRouterCallback,
|
||||
MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN);
|
||||
}
|
||||
mBluetoothController.addCallback(mCallback);
|
||||
isAttached = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromWindow() {
|
||||
isAttached = false;
|
||||
mRouter.removeCallback(mRouterCallback);
|
||||
mController.removeCallback(mCallback);
|
||||
mBluetoothController.removeCallback(mCallback);
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
@@ -154,9 +173,8 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
if (item == null || item.tag == null) return;
|
||||
if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
|
||||
final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
|
||||
if (device != null && device.getMaxConnectionState()
|
||||
== BluetoothProfile.STATE_DISCONNECTED) {
|
||||
mController.connect(device);
|
||||
if (device.getMaxConnectionState() == BluetoothProfile.STATE_DISCONNECTED) {
|
||||
mBluetoothController.connect(device);
|
||||
}
|
||||
} else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
|
||||
final MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) item.tag;
|
||||
@@ -171,18 +189,16 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
if (item == null || item.tag == null) return;
|
||||
if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_BT) {
|
||||
final CachedBluetoothDevice device = (CachedBluetoothDevice) item.tag;
|
||||
if (device != null) {
|
||||
mController.disconnect(device);
|
||||
}
|
||||
mBluetoothController.disconnect(device);
|
||||
} else if (item.deviceType == OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER) {
|
||||
mRouter.unselect(UNSELECT_REASON_DISCONNECTED);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateItems() {
|
||||
private void updateItems(boolean timeout) {
|
||||
if (SystemClock.uptimeMillis() - mLastUpdateTime < UPDATE_DELAY_MS) {
|
||||
mHandler.removeMessages(MSG_UPDATE_ITEMS);
|
||||
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ITEMS),
|
||||
mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_UPDATE_ITEMS, timeout),
|
||||
mLastUpdateTime + UPDATE_DELAY_MS);
|
||||
return;
|
||||
}
|
||||
@@ -194,14 +210,16 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
addBluetoothDevices(items);
|
||||
|
||||
// Add remote displays
|
||||
addRemoteDisplayRoutes(items);
|
||||
if (!mIsInCall) {
|
||||
addRemoteDisplayRoutes(items);
|
||||
}
|
||||
|
||||
Collections.sort(items, ItemComparator.sInstance);
|
||||
items.sort(ItemComparator.sInstance);
|
||||
|
||||
if (items.size() == 0) {
|
||||
if (items.size() == 0 && timeout) {
|
||||
String emptyMessage = mContext.getString(R.string.output_none_found);
|
||||
final boolean wifiOff = !mWifiManager.isWifiEnabled();
|
||||
final boolean btOff = !mController.isBluetoothEnabled();
|
||||
final boolean btOff = !mBluetoothController.isBluetoothEnabled();
|
||||
if (wifiOff || btOff) {
|
||||
emptyMessage = getDisabledServicesMessage(wifiOff, btOff);
|
||||
}
|
||||
@@ -219,12 +237,12 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
}
|
||||
|
||||
private void addBluetoothDevices(List<OutputChooserLayout.Item> items) {
|
||||
final Collection<CachedBluetoothDevice> devices = mController.getDevices();
|
||||
final Collection<CachedBluetoothDevice> devices = mBluetoothController.getDevices();
|
||||
if (devices != null) {
|
||||
int connectedDevices = 0;
|
||||
int count = 0;
|
||||
for (CachedBluetoothDevice device : devices) {
|
||||
if (mController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
|
||||
if (mBluetoothController.getBondState(device) == BluetoothDevice.BOND_NONE) continue;
|
||||
final int majorClass = device.getBtClass().getMajorDeviceClass();
|
||||
if (majorClass != BluetoothClass.Device.Major.AUDIO_VIDEO
|
||||
&& majorClass != BluetoothClass.Device.Major.UNCATEGORIZED) {
|
||||
@@ -328,22 +346,22 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
private final class MediaRouterCallback extends MediaRouter.Callback {
|
||||
@Override
|
||||
public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) {
|
||||
updateItems();
|
||||
updateItems(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) {
|
||||
updateItems();
|
||||
updateItems(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) {
|
||||
updateItems();
|
||||
updateItems(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) {
|
||||
dismiss();
|
||||
updateItems(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,12 +379,12 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
private final BluetoothController.Callback mCallback = new BluetoothController.Callback() {
|
||||
@Override
|
||||
public void onBluetoothStateChange(boolean enabled) {
|
||||
updateItems();
|
||||
updateItems(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBluetoothDevicesChanged() {
|
||||
updateItems();
|
||||
updateItems(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -393,7 +411,7 @@ public class OutputChooserDialog extends SystemUIDialog
|
||||
public void handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case MSG_UPDATE_ITEMS:
|
||||
updateItems();
|
||||
updateItems((Boolean) message.obj);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,8 +29,8 @@ import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.BaseAdapter;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.FontSizeUtils;
|
||||
@@ -40,11 +40,10 @@ import com.android.systemui.qs.AutoSizingList;
|
||||
/**
|
||||
* Limited height list of devices.
|
||||
*/
|
||||
public class OutputChooserLayout extends FrameLayout {
|
||||
public class OutputChooserLayout extends LinearLayout {
|
||||
private static final String TAG = "OutputChooserLayout";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
private final int mQsDetailIconOverlaySize;
|
||||
private final Context mContext;
|
||||
private final H mHandler = new H();
|
||||
private final Adapter mAdapter = new Adapter();
|
||||
@@ -55,6 +54,7 @@ public class OutputChooserLayout extends FrameLayout {
|
||||
private AutoSizingList mItemList;
|
||||
private View mEmpty;
|
||||
private TextView mEmptyText;
|
||||
private TextView mTitle;
|
||||
|
||||
private Item[] mItems;
|
||||
|
||||
@@ -62,8 +62,6 @@ public class OutputChooserLayout extends FrameLayout {
|
||||
super(context, attrs);
|
||||
mContext = context;
|
||||
mTag = TAG;
|
||||
mQsDetailIconOverlaySize = (int) getResources().getDimension(
|
||||
R.dimen.qs_detail_icon_overlay_size);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +72,8 @@ public class OutputChooserLayout extends FrameLayout {
|
||||
mItemList.setAdapter(mAdapter);
|
||||
mEmpty = findViewById(android.R.id.empty);
|
||||
mEmpty.setVisibility(GONE);
|
||||
mEmptyText = mEmpty.findViewById(android.R.id.title);
|
||||
mEmptyText = mEmpty.findViewById(R.id.empty_text);
|
||||
mTitle = findViewById(R.id.title);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -84,17 +83,21 @@ public class OutputChooserLayout extends FrameLayout {
|
||||
int count = mItemList.getChildCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View item = mItemList.getChildAt(i);
|
||||
FontSizeUtils.updateFontSize(item, android.R.id.title,
|
||||
FontSizeUtils.updateFontSize(item, R.id.empty_text,
|
||||
R.dimen.qs_detail_item_primary_text_size);
|
||||
FontSizeUtils.updateFontSize(item, android.R.id.summary,
|
||||
R.dimen.qs_detail_item_secondary_text_size);
|
||||
FontSizeUtils.updateFontSize(item, android.R.id.title,
|
||||
R.dimen.qs_detail_header_text_size);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTitle(int title) {
|
||||
mTitle.setText(title);
|
||||
}
|
||||
|
||||
public void setEmptyState(String text) {
|
||||
mEmpty.post(() -> {
|
||||
mEmptyText.setText(text);
|
||||
});
|
||||
mEmptyText.setText(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -176,11 +179,6 @@ public class OutputChooserLayout extends FrameLayout {
|
||||
} else {
|
||||
iv.setImageResource(item.iconResId);
|
||||
}
|
||||
iv.getOverlay().clear();
|
||||
if (item.overlay != null) {
|
||||
item.overlay.setBounds(0, 0, mQsDetailIconOverlaySize, mQsDetailIconOverlaySize);
|
||||
iv.getOverlay().add(item.overlay);
|
||||
}
|
||||
final TextView title = view.findViewById(android.R.id.title);
|
||||
title.setText(item.line1);
|
||||
final TextView summary = view.findViewById(android.R.id.summary);
|
||||
|
||||
@@ -47,6 +47,7 @@ import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseBooleanArray;
|
||||
@@ -858,7 +859,8 @@ public class VolumeDialogImpl implements VolumeDialog {
|
||||
if (mOutputChooserDialog != null) {
|
||||
return;
|
||||
}
|
||||
mOutputChooserDialog = new OutputChooserDialog(mContext) {
|
||||
mOutputChooserDialog = new OutputChooserDialog(mContext,
|
||||
new MediaRouterWrapper(MediaRouter.getInstance(mContext))) {
|
||||
@Override
|
||||
protected void cleanUp() {
|
||||
synchronized (mOutputChooserLock) {
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
<uses-permission android:name="android.permission.STATUS_BAR" />
|
||||
<uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
|
||||
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
|
||||
|
||||
<application>
|
||||
<uses-library android:name="android.test.runner" />
|
||||
|
||||
@@ -83,7 +83,7 @@ public abstract class SysuiTestCase {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
public SysuiTestableContext getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.volume;
|
||||
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.support.test.annotation.UiThreadTest;
|
||||
import android.support.test.filters.SmallTest;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import android.support.v7.media.MediaRouter;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class OutputChooserDialogTest extends SysuiTestCase {
|
||||
|
||||
OutputChooserDialog mDialog;
|
||||
|
||||
@Mock
|
||||
private BluetoothController mController;
|
||||
@Mock
|
||||
private WifiManager mWifiManager;
|
||||
@Mock
|
||||
private TelecomManager mTelecomManager;
|
||||
|
||||
@Mock
|
||||
private MediaRouterWrapper mRouter;
|
||||
|
||||
|
||||
@Before
|
||||
@UiThreadTest
|
||||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
mController = mDependency.injectMockDependency(BluetoothController.class);
|
||||
when(mWifiManager.isWifiEnabled()).thenReturn(true);
|
||||
|
||||
getContext().addMockSystemService(WifiManager.class, mWifiManager);
|
||||
getContext().addMockSystemService(TelecomManager.class, mTelecomManager);
|
||||
|
||||
mDialog = new OutputChooserDialog(getContext(), mRouter);
|
||||
}
|
||||
|
||||
@After
|
||||
@UiThreadTest
|
||||
public void tearDown() throws Exception {
|
||||
mDialog.dismiss();
|
||||
}
|
||||
|
||||
private void showDialog() {
|
||||
mDialog.show();
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testClickMediaRouterItemConnectsMedia() {
|
||||
showDialog();
|
||||
|
||||
OutputChooserLayout.Item item = new OutputChooserLayout.Item();
|
||||
item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_MEDIA_ROUTER;
|
||||
MediaRouter.RouteInfo info = mock(MediaRouter.RouteInfo.class);
|
||||
when(info.isEnabled()).thenReturn(true);
|
||||
item.tag = info;
|
||||
|
||||
mDialog.onDetailItemClick(item);
|
||||
verify(info, times(1)).select();
|
||||
verify(mController, never()).connect(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testClickBtItemConnectsBt() {
|
||||
showDialog();
|
||||
|
||||
OutputChooserLayout.Item item = new OutputChooserLayout.Item();
|
||||
item.deviceType = OutputChooserLayout.Item.DEVICE_TYPE_BT;
|
||||
CachedBluetoothDevice btDevice = mock(CachedBluetoothDevice.class);
|
||||
when(btDevice.getMaxConnectionState()).thenReturn(BluetoothProfile.STATE_DISCONNECTED);
|
||||
item.tag = btDevice;
|
||||
|
||||
mDialog.onDetailItemClick(item);
|
||||
verify(mController, times(1)).connect(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testTitleNotInCall() {
|
||||
showDialog();
|
||||
|
||||
assertTrue(((TextView) mDialog.findViewById(R.id.title))
|
||||
.getText().toString().contains("Media"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testTitleInCall() {
|
||||
mDialog.setIsInCall(true);
|
||||
showDialog();
|
||||
|
||||
assertTrue(((TextView) mDialog.findViewById(R.id.title))
|
||||
.getText().toString().contains("Phone"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testNoMediaScanIfInCall() {
|
||||
mDialog.setIsInCall(true);
|
||||
mDialog.onAttachedToWindow();
|
||||
|
||||
verify(mRouter, never()).addCallback(any(), any(), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
public void testMediaScanIfNotInCall() {
|
||||
mDialog.setIsInCall(false);
|
||||
mDialog.onAttachedToWindow();
|
||||
|
||||
verify(mRouter, times(1)).addCallback(any(), any(), anyInt());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user