Merge "[Output Switcher] [Group by Type] Add MediaItem to store data" into tm-qpr-dev
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
~ Copyright (C) 2022 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/device_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:layout_gravity="center_vertical|start"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginEnd="56dp"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
|
||||||
|
android:textSize="16sp"/>
|
||||||
|
</LinearLayout>
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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 androidx.annotation.IntDef;
|
||||||
|
|
||||||
|
import com.android.settingslib.media.MediaDevice;
|
||||||
|
import com.android.systemui.R;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MediaItem represents an item in OutputSwitcher list (could be a MediaDevice, group divider or
|
||||||
|
* connect new device item).
|
||||||
|
*/
|
||||||
|
public class MediaItem {
|
||||||
|
private final Optional<MediaDevice> mMediaDeviceOptional;
|
||||||
|
private final String mTitle;
|
||||||
|
@MediaItemType
|
||||||
|
private final int mMediaItemType;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
@IntDef({
|
||||||
|
MediaItemType.TYPE_DEVICE,
|
||||||
|
MediaItemType.TYPE_GROUP_DIVIDER,
|
||||||
|
MediaItemType.TYPE_PAIR_NEW_DEVICE})
|
||||||
|
public @interface MediaItemType {
|
||||||
|
int TYPE_DEVICE = 0;
|
||||||
|
int TYPE_GROUP_DIVIDER = 1;
|
||||||
|
int TYPE_PAIR_NEW_DEVICE = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaItem() {
|
||||||
|
this.mMediaDeviceOptional = Optional.empty();
|
||||||
|
this.mTitle = null;
|
||||||
|
this.mMediaItemType = MediaItemType.TYPE_PAIR_NEW_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaItem(String title, int mediaItemType) {
|
||||||
|
this.mMediaDeviceOptional = Optional.empty();
|
||||||
|
this.mTitle = title;
|
||||||
|
this.mMediaItemType = mediaItemType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaItem(MediaDevice mediaDevice) {
|
||||||
|
this.mMediaDeviceOptional = Optional.of(mediaDevice);
|
||||||
|
this.mTitle = mediaDevice.getName();
|
||||||
|
this.mMediaItemType = MediaItemType.TYPE_DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<MediaDevice> getMediaDevice() {
|
||||||
|
return mMediaDeviceOptional;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get layout id based on media item Type.
|
||||||
|
*/
|
||||||
|
public static int getMediaLayoutId(int mediaItemType) {
|
||||||
|
switch (mediaItemType) {
|
||||||
|
case MediaItemType.TYPE_DEVICE:
|
||||||
|
case MediaItemType.TYPE_PAIR_NEW_DEVICE:
|
||||||
|
return R.layout.media_output_list_item_advanced;
|
||||||
|
case MediaItemType.TYPE_GROUP_DIVIDER:
|
||||||
|
default:
|
||||||
|
return R.layout.media_output_list_group_divider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle() {
|
||||||
|
return mTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isMutingExpectedDevice() {
|
||||||
|
return mMediaDeviceOptional.isPresent()
|
||||||
|
&& mMediaDeviceOptional.get().isMutingExpectedDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMediaItemType() {
|
||||||
|
return mMediaItemType;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,9 +24,11 @@ import android.util.Log;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.widget.CompoundButtonCompat;
|
import androidx.core.widget.CompoundButtonCompat;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
|
import com.android.settingslib.media.LocalMediaManager.MediaDeviceState;
|
||||||
import com.android.settingslib.media.MediaDevice;
|
import com.android.settingslib.media.MediaDevice;
|
||||||
@@ -48,29 +50,68 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
|
||||||
int viewType) {
|
int viewType) {
|
||||||
super.onCreateViewHolder(viewGroup, viewType);
|
super.onCreateViewHolder(viewGroup, viewType);
|
||||||
return new MediaDeviceViewHolder(mHolderView);
|
if (mController.isAdvancedLayoutSupported()) {
|
||||||
|
switch (viewType) {
|
||||||
|
case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
|
||||||
|
return new MediaGroupDividerViewHolder(mHolderView);
|
||||||
|
case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
|
||||||
|
case MediaItem.MediaItemType.TYPE_DEVICE:
|
||||||
|
default:
|
||||||
|
return new MediaDeviceViewHolder(mHolderView);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new MediaDeviceViewHolder(mHolderView);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull MediaDeviceBaseViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
final int size = mController.getMediaDevices().size();
|
if (mController.isAdvancedLayoutSupported()) {
|
||||||
if (position == size) {
|
MediaItem currentMediaItem = mController.getMediaItemList().get(position);
|
||||||
viewHolder.onBind(CUSTOMIZED_ITEM_PAIR_NEW, false /* topMargin */,
|
switch (currentMediaItem.getMediaItemType()) {
|
||||||
true /* bottomMargin */);
|
case MediaItem.MediaItemType.TYPE_GROUP_DIVIDER:
|
||||||
} else if (position < size) {
|
((MediaGroupDividerViewHolder) viewHolder).onBind(currentMediaItem.getTitle());
|
||||||
viewHolder.onBind(((List<MediaDevice>) (mController.getMediaDevices())).get(position),
|
break;
|
||||||
position == 0 /* topMargin */, position == (size - 1) /* bottomMargin */,
|
case MediaItem.MediaItemType.TYPE_PAIR_NEW_DEVICE:
|
||||||
position);
|
((MediaDeviceViewHolder) viewHolder).onBind(CUSTOMIZED_ITEM_PAIR_NEW);
|
||||||
} else if (DEBUG) {
|
break;
|
||||||
Log.d(TAG, "Incorrect position: " + position);
|
case MediaItem.MediaItemType.TYPE_DEVICE:
|
||||||
|
((MediaDeviceViewHolder) viewHolder).onBind(
|
||||||
|
currentMediaItem.getMediaDevice().get(),
|
||||||
|
position);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Log.d(TAG, "Incorrect position: " + position);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
final int size = mController.getMediaDevices().size();
|
||||||
|
if (position == size) {
|
||||||
|
((MediaDeviceViewHolder) viewHolder).onBind(CUSTOMIZED_ITEM_PAIR_NEW);
|
||||||
|
} else if (position < size) {
|
||||||
|
((MediaDeviceViewHolder) viewHolder).onBind(
|
||||||
|
((List<MediaDevice>) (mController.getMediaDevices())).get(position),
|
||||||
|
position);
|
||||||
|
} else if (DEBUG) {
|
||||||
|
Log.d(TAG, "Incorrect position: " + position);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getItemId(int position) {
|
public long getItemId(int position) {
|
||||||
|
if (mController.isAdvancedLayoutSupported()) {
|
||||||
|
if (position >= mController.getMediaItemList().size()) {
|
||||||
|
Log.d(TAG, "Incorrect position for item id: " + position);
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
MediaItem currentMediaItem = mController.getMediaItemList().get(position);
|
||||||
|
return currentMediaItem.getMediaDevice().isPresent()
|
||||||
|
? currentMediaItem.getMediaDevice().get().getId().hashCode()
|
||||||
|
: position;
|
||||||
|
}
|
||||||
final int size = mController.getMediaDevices().size();
|
final int size = mController.getMediaDevices().size();
|
||||||
if (position == size) {
|
if (position == size) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -83,10 +124,19 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemViewType(int position) {
|
||||||
|
return mController.isAdvancedLayoutSupported()
|
||||||
|
? mController.getMediaItemList().get(position).getMediaItemType()
|
||||||
|
: super.getItemViewType(position);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
// Add extra one for "pair new"
|
// Add extra one for "pair new"
|
||||||
return mController.getMediaDevices().size() + 1;
|
return mController.isAdvancedLayoutSupported()
|
||||||
|
? mController.getMediaItemList().size()
|
||||||
|
: mController.getMediaDevices().size() + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
|
class MediaDeviceViewHolder extends MediaDeviceBaseViewHolder {
|
||||||
@@ -96,8 +146,8 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
|
void onBind(MediaDevice device, int position) {
|
||||||
super.onBind(device, topMargin, bottomMargin, position);
|
super.onBind(device, position);
|
||||||
boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
|
boolean isMutingExpectedDeviceExist = mController.hasMutingExpectedDevice();
|
||||||
final boolean currentlyConnected = isCurrentlyConnected(device);
|
final boolean currentlyConnected = isCurrentlyConnected(device);
|
||||||
boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
|
boolean isCurrentSeekbarInvisible = mSeekBar.getVisibility() == View.GONE;
|
||||||
@@ -261,7 +311,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
|
void onBind(int customizedItem) {
|
||||||
if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
|
if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
|
||||||
mTitleText.setTextColor(mController.getColorItemContent());
|
mTitleText.setTextColor(mController.getColorItemContent());
|
||||||
mCheckBox.setVisibility(View.GONE);
|
mCheckBox.setVisibility(View.GONE);
|
||||||
@@ -318,4 +368,18 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
|
|||||||
: R.string.accessibility_cast_name, device.getName()));
|
: R.string.accessibility_cast_name, device.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MediaGroupDividerViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
final TextView mTitleText;
|
||||||
|
|
||||||
|
MediaGroupDividerViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
mTitleText = itemView.requireViewById(R.id.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
void onBind(String groupDividerTitle) {
|
||||||
|
mTitleText.setTextColor(mController.getColorItemContent());
|
||||||
|
mTitleText.setText(groupDividerTitle);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ import java.util.List;
|
|||||||
* Base adapter for media output dialog.
|
* Base adapter for media output dialog.
|
||||||
*/
|
*/
|
||||||
public abstract class MediaOutputBaseAdapter extends
|
public abstract class MediaOutputBaseAdapter extends
|
||||||
RecyclerView.Adapter<MediaOutputBaseAdapter.MediaDeviceBaseViewHolder> {
|
RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||||
|
|
||||||
static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
|
static final int CUSTOMIZED_ITEM_PAIR_NEW = 1;
|
||||||
static final int CUSTOMIZED_ITEM_GROUP = 2;
|
static final int CUSTOMIZED_ITEM_GROUP = 2;
|
||||||
@@ -80,11 +80,12 @@ public abstract class MediaOutputBaseAdapter extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MediaDeviceBaseViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
|
||||||
int viewType) {
|
int viewType) {
|
||||||
mContext = viewGroup.getContext();
|
mContext = viewGroup.getContext();
|
||||||
mHolderView = LayoutInflater.from(mContext).inflate(
|
mHolderView = LayoutInflater.from(mContext).inflate(
|
||||||
mController.isAdvancedLayoutSupported() ? R.layout.media_output_list_item_advanced
|
mController.isAdvancedLayoutSupported() ? MediaItem.getMediaLayoutId(
|
||||||
|
viewType) /*R.layout.media_output_list_item_advanced*/
|
||||||
: R.layout.media_output_list_item, viewGroup, false);
|
: R.layout.media_output_list_item, viewGroup, false);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -175,7 +176,7 @@ public abstract class MediaOutputBaseAdapter extends
|
|||||||
initAnimator();
|
initAnimator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void onBind(MediaDevice device, boolean topMargin, boolean bottomMargin, int position) {
|
void onBind(MediaDevice device, int position) {
|
||||||
mDeviceId = device.getId();
|
mDeviceId = device.getId();
|
||||||
mCheckBox.setVisibility(View.GONE);
|
mCheckBox.setVisibility(View.GONE);
|
||||||
mStatusIcon.setVisibility(View.GONE);
|
mStatusIcon.setVisibility(View.GONE);
|
||||||
@@ -196,7 +197,7 @@ public abstract class MediaOutputBaseAdapter extends
|
|||||||
PorterDuff.Mode.SRC_IN));
|
PorterDuff.Mode.SRC_IN));
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract void onBind(int customizedItem, boolean topMargin, boolean bottomMargin);
|
abstract void onBind(int customizedItem);
|
||||||
|
|
||||||
void setSingleLineLayout(CharSequence title) {
|
void setSingleLineLayout(CharSequence title) {
|
||||||
setSingleLineLayout(title, false, false, false, false);
|
setSingleLineLayout(title, false, false, false, false);
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ import java.util.Optional;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -121,6 +122,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
|
final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>();
|
||||||
final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>();
|
final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>();
|
||||||
|
private final List<MediaItem> mMediaItemList = new CopyOnWriteArrayList<>();
|
||||||
private final AudioManager mAudioManager;
|
private final AudioManager mAudioManager;
|
||||||
private final PowerExemptionManager mPowerExemptionManager;
|
private final PowerExemptionManager mPowerExemptionManager;
|
||||||
private final KeyguardManager mKeyGuardManager;
|
private final KeyguardManager mKeyGuardManager;
|
||||||
@@ -212,6 +214,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
mCachedMediaDevices.clear();
|
mCachedMediaDevices.clear();
|
||||||
mMediaDevices.clear();
|
mMediaDevices.clear();
|
||||||
|
mMediaItemList.clear();
|
||||||
}
|
}
|
||||||
mNearbyDeviceInfoMap.clear();
|
mNearbyDeviceInfoMap.clear();
|
||||||
if (mNearbyMediaDevicesManager != null) {
|
if (mNearbyMediaDevicesManager != null) {
|
||||||
@@ -262,6 +265,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
mCachedMediaDevices.clear();
|
mCachedMediaDevices.clear();
|
||||||
mMediaDevices.clear();
|
mMediaDevices.clear();
|
||||||
|
mMediaItemList.clear();
|
||||||
}
|
}
|
||||||
if (mNearbyMediaDevicesManager != null) {
|
if (mNearbyMediaDevicesManager != null) {
|
||||||
mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
|
mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this);
|
||||||
@@ -287,7 +291,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
public void onSelectedDeviceStateChanged(MediaDevice device,
|
public void onSelectedDeviceStateChanged(MediaDevice device,
|
||||||
@LocalMediaManager.MediaDeviceState int state) {
|
@LocalMediaManager.MediaDeviceState int state) {
|
||||||
mCallback.onRouteChanged();
|
mCallback.onRouteChanged();
|
||||||
mMetricLogger.logOutputSuccess(device.toString(), new ArrayList<>(mMediaDevices));
|
if (isAdvancedLayoutSupported()) {
|
||||||
|
mMetricLogger.logOutputItemSuccess(device.toString(), new ArrayList<>(mMediaItemList));
|
||||||
|
} else {
|
||||||
|
mMetricLogger.logOutputSuccess(device.toString(), new ArrayList<>(mMediaDevices));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -298,7 +306,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
@Override
|
@Override
|
||||||
public void onRequestFailed(int reason) {
|
public void onRequestFailed(int reason) {
|
||||||
mCallback.onRouteChanged();
|
mCallback.onRouteChanged();
|
||||||
mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason);
|
if (isAdvancedLayoutSupported()) {
|
||||||
|
mMetricLogger.logOutputItemFailure(new ArrayList<>(mMediaItemList), reason);
|
||||||
|
} else {
|
||||||
|
mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -318,6 +330,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
try {
|
try {
|
||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice);
|
mMediaDevices.removeIf(MediaDevice::isMutingExpectedDevice);
|
||||||
|
mMediaItemList.removeIf((MediaItem::isMutingExpectedDevice));
|
||||||
}
|
}
|
||||||
mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice());
|
mAudioManager.cancelMuteAwaitConnection(mAudioManager.getMutingExpectedDevice());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@@ -547,6 +560,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildMediaDevices(List<MediaDevice> devices) {
|
private void buildMediaDevices(List<MediaDevice> devices) {
|
||||||
|
if (isAdvancedLayoutSupported()) {
|
||||||
|
buildMediaItems(devices);
|
||||||
|
} else {
|
||||||
|
buildDefaultMediaDevices(devices);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildDefaultMediaDevices(List<MediaDevice> devices) {
|
||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
attachRangeInfo(devices);
|
attachRangeInfo(devices);
|
||||||
Collections.sort(devices, Comparator.naturalOrder());
|
Collections.sort(devices, Comparator.naturalOrder());
|
||||||
@@ -603,6 +624,81 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void buildMediaItems(List<MediaDevice> devices) {
|
||||||
|
synchronized (mMediaDevicesLock) {
|
||||||
|
//TODO(b/257851968): do the organization only when there's no suggested sorted order
|
||||||
|
// we get from application
|
||||||
|
attachRangeInfo(devices);
|
||||||
|
Collections.sort(devices, Comparator.naturalOrder());
|
||||||
|
// For the first time building list, to make sure the top device is the connected
|
||||||
|
// device.
|
||||||
|
if (mMediaItemList.isEmpty()) {
|
||||||
|
boolean needToHandleMutingExpectedDevice =
|
||||||
|
hasMutingExpectedDevice() && !isCurrentConnectedDeviceRemote();
|
||||||
|
final MediaDevice connectedMediaDevice =
|
||||||
|
needToHandleMutingExpectedDevice ? null
|
||||||
|
: getCurrentConnectedMediaDevice();
|
||||||
|
if (connectedMediaDevice == null) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "No connected media device or muting expected device exist.");
|
||||||
|
}
|
||||||
|
if (needToHandleMutingExpectedDevice) {
|
||||||
|
for (MediaDevice device : devices) {
|
||||||
|
if (device.isMutingExpectedDevice()) {
|
||||||
|
mMediaItemList.add(0, new MediaItem(device));
|
||||||
|
} else {
|
||||||
|
mMediaItemList.add(new MediaItem(device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mMediaItemList.addAll(
|
||||||
|
devices.stream().map(MediaItem::new).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
categorizeMediaItems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// selected device exist
|
||||||
|
for (MediaDevice device : devices) {
|
||||||
|
if (TextUtils.equals(device.getId(), connectedMediaDevice.getId())) {
|
||||||
|
mMediaItemList.add(0, new MediaItem(device));
|
||||||
|
} else {
|
||||||
|
mMediaItemList.add(new MediaItem(device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
categorizeMediaItems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// To keep the same list order
|
||||||
|
final List<MediaDevice> targetMediaDevices = new ArrayList<>();
|
||||||
|
for (MediaItem originalMediaItem : mMediaItemList) {
|
||||||
|
for (MediaDevice newDevice : devices) {
|
||||||
|
if (originalMediaItem.getMediaDevice().isPresent()
|
||||||
|
&& TextUtils.equals(originalMediaItem.getMediaDevice().get().getId(),
|
||||||
|
newDevice.getId())) {
|
||||||
|
targetMediaDevices.add(newDevice);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (targetMediaDevices.size() != devices.size()) {
|
||||||
|
devices.removeAll(targetMediaDevices);
|
||||||
|
targetMediaDevices.addAll(devices);
|
||||||
|
}
|
||||||
|
mMediaItemList.clear();
|
||||||
|
mMediaItemList.addAll(
|
||||||
|
targetMediaDevices.stream().map(MediaItem::new).collect(Collectors.toList()));
|
||||||
|
categorizeMediaItems();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void categorizeMediaItems() {
|
||||||
|
synchronized (mMediaDevicesLock) {
|
||||||
|
//TODO(255124239): do the categorization here
|
||||||
|
mMediaItemList.add(new MediaItem());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void attachRangeInfo(List<MediaDevice> devices) {
|
private void attachRangeInfo(List<MediaDevice> devices) {
|
||||||
for (MediaDevice mediaDevice : devices) {
|
for (MediaDevice mediaDevice : devices) {
|
||||||
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
|
if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) {
|
||||||
@@ -670,6 +766,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
return mMediaDevices;
|
return mMediaDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<MediaItem> getMediaItemList() {
|
||||||
|
return mMediaItemList;
|
||||||
|
}
|
||||||
|
|
||||||
MediaDevice getCurrentConnectedMediaDevice() {
|
MediaDevice getCurrentConnectedMediaDevice() {
|
||||||
return mLocalMediaManager.getCurrentConnectedDevice();
|
return mLocalMediaManager.getCurrentConnectedDevice();
|
||||||
}
|
}
|
||||||
@@ -749,9 +849,19 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
|
|||||||
|
|
||||||
boolean isAnyDeviceTransferring() {
|
boolean isAnyDeviceTransferring() {
|
||||||
synchronized (mMediaDevicesLock) {
|
synchronized (mMediaDevicesLock) {
|
||||||
for (MediaDevice device : mMediaDevices) {
|
if (isAdvancedLayoutSupported()) {
|
||||||
if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
|
for (MediaItem mediaItem : mMediaItemList) {
|
||||||
return true;
|
if (mediaItem.getMediaDevice().isPresent()
|
||||||
|
&& mediaItem.getMediaDevice().get().getState()
|
||||||
|
== LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (MediaDevice device : mMediaDevices) {
|
||||||
|
if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,6 +95,31 @@ public class MediaOutputMetricLogger {
|
|||||||
mAppliedDeviceCountWithinRemoteGroup);
|
mAppliedDeviceCountWithinRemoteGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the metric logging of content switching success.
|
||||||
|
* @param selectedDeviceType string representation of the target media device
|
||||||
|
* @param deviceItemList media item list for device count updating
|
||||||
|
*/
|
||||||
|
public void logOutputItemSuccess(String selectedDeviceType, List<MediaItem> deviceItemList) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "logOutputSuccess - selected device: " + selectedDeviceType);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLoggingMediaItemCount(deviceItemList);
|
||||||
|
|
||||||
|
SysUiStatsLog.write(
|
||||||
|
SysUiStatsLog.MEDIAOUTPUT_OP_SWITCH_REPORTED,
|
||||||
|
getLoggingDeviceType(mSourceDevice, true),
|
||||||
|
getLoggingDeviceType(mTargetDevice, false),
|
||||||
|
SysUiStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__RESULT__OK,
|
||||||
|
SysUiStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__SUBRESULT__NO_ERROR,
|
||||||
|
getLoggingPackageName(),
|
||||||
|
mWiredDeviceCount,
|
||||||
|
mConnectedBluetoothDeviceCount,
|
||||||
|
mRemoteDeviceCount,
|
||||||
|
mAppliedDeviceCountWithinRemoteGroup);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the metric logging of volume adjustment.
|
* Do the metric logging of volume adjustment.
|
||||||
* @param source the device been adjusted
|
* @param source the device been adjusted
|
||||||
@@ -166,6 +191,31 @@ public class MediaOutputMetricLogger {
|
|||||||
mAppliedDeviceCountWithinRemoteGroup);
|
mAppliedDeviceCountWithinRemoteGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do the metric logging of content switching failure.
|
||||||
|
* @param deviceItemList media item list for device count updating
|
||||||
|
* @param reason the reason of content switching failure
|
||||||
|
*/
|
||||||
|
public void logOutputItemFailure(List<MediaItem> deviceItemList, int reason) {
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.e(TAG, "logRequestFailed - " + reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLoggingMediaItemCount(deviceItemList);
|
||||||
|
|
||||||
|
SysUiStatsLog.write(
|
||||||
|
SysUiStatsLog.MEDIAOUTPUT_OP_SWITCH_REPORTED,
|
||||||
|
getLoggingDeviceType(mSourceDevice, true),
|
||||||
|
getLoggingDeviceType(mTargetDevice, false),
|
||||||
|
SysUiStatsLog.MEDIA_OUTPUT_OP_SWITCH_REPORTED__RESULT__ERROR,
|
||||||
|
getLoggingSwitchOpSubResult(reason),
|
||||||
|
getLoggingPackageName(),
|
||||||
|
mWiredDeviceCount,
|
||||||
|
mConnectedBluetoothDeviceCount,
|
||||||
|
mRemoteDeviceCount,
|
||||||
|
mAppliedDeviceCountWithinRemoteGroup);
|
||||||
|
}
|
||||||
|
|
||||||
private void updateLoggingDeviceCount(List<MediaDevice> deviceList) {
|
private void updateLoggingDeviceCount(List<MediaDevice> deviceList) {
|
||||||
mWiredDeviceCount = mConnectedBluetoothDeviceCount = mRemoteDeviceCount = 0;
|
mWiredDeviceCount = mConnectedBluetoothDeviceCount = mRemoteDeviceCount = 0;
|
||||||
mAppliedDeviceCountWithinRemoteGroup = 0;
|
mAppliedDeviceCountWithinRemoteGroup = 0;
|
||||||
@@ -196,6 +246,37 @@ public class MediaOutputMetricLogger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateLoggingMediaItemCount(List<MediaItem> deviceItemList) {
|
||||||
|
mWiredDeviceCount = mConnectedBluetoothDeviceCount = mRemoteDeviceCount = 0;
|
||||||
|
mAppliedDeviceCountWithinRemoteGroup = 0;
|
||||||
|
|
||||||
|
for (MediaItem mediaItem: deviceItemList) {
|
||||||
|
if (mediaItem.getMediaDevice().isPresent()
|
||||||
|
&& mediaItem.getMediaDevice().get().isConnected()) {
|
||||||
|
switch (mediaItem.getMediaDevice().get().getDeviceType()) {
|
||||||
|
case MediaDevice.MediaDeviceType.TYPE_3POINT5_MM_AUDIO_DEVICE:
|
||||||
|
case MediaDevice.MediaDeviceType.TYPE_USB_C_AUDIO_DEVICE:
|
||||||
|
mWiredDeviceCount++;
|
||||||
|
break;
|
||||||
|
case MediaDevice.MediaDeviceType.TYPE_BLUETOOTH_DEVICE:
|
||||||
|
mConnectedBluetoothDeviceCount++;
|
||||||
|
break;
|
||||||
|
case MediaDevice.MediaDeviceType.TYPE_CAST_DEVICE:
|
||||||
|
case MediaDevice.MediaDeviceType.TYPE_CAST_GROUP_DEVICE:
|
||||||
|
mRemoteDeviceCount++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, "connected devices:" + " wired: " + mWiredDeviceCount
|
||||||
|
+ " bluetooth: " + mConnectedBluetoothDeviceCount
|
||||||
|
+ " remote: " + mRemoteDeviceCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private int getLoggingDeviceType(MediaDevice device, boolean isSourceDevice) {
|
private int getLoggingDeviceType(MediaDevice device, boolean isSourceDevice) {
|
||||||
if (device == null) {
|
if (device == null) {
|
||||||
return isSourceDevice
|
return isSourceDevice
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ import org.junit.runner.RunWith;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
@RunWith(AndroidTestingRunner.class)
|
@RunWith(AndroidTestingRunner.class)
|
||||||
@@ -71,10 +72,13 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
private MediaOutputAdapter mMediaOutputAdapter;
|
private MediaOutputAdapter mMediaOutputAdapter;
|
||||||
private MediaOutputAdapter.MediaDeviceViewHolder mViewHolder;
|
private MediaOutputAdapter.MediaDeviceViewHolder mViewHolder;
|
||||||
private List<MediaDevice> mMediaDevices = new ArrayList<>();
|
private List<MediaDevice> mMediaDevices = new ArrayList<>();
|
||||||
|
private List<MediaItem> mMediaItems = new ArrayList<>();
|
||||||
MediaOutputSeekbar mSpyMediaOutputSeekbar;
|
MediaOutputSeekbar mSpyMediaOutputSeekbar;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(false);
|
||||||
|
when(mMediaOutputController.getMediaItemList()).thenReturn(mMediaItems);
|
||||||
when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
|
when(mMediaOutputController.getMediaDevices()).thenReturn(mMediaDevices);
|
||||||
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
|
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(false);
|
||||||
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(false);
|
when(mMediaOutputController.isAnyDeviceTransferring()).thenReturn(false);
|
||||||
@@ -82,7 +86,6 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
|
when(mMediaOutputController.getDeviceIconCompat(mMediaDevice2)).thenReturn(mIconCompat);
|
||||||
when(mMediaOutputController.getCurrentConnectedMediaDevice()).thenReturn(mMediaDevice1);
|
when(mMediaOutputController.getCurrentConnectedMediaDevice()).thenReturn(mMediaDevice1);
|
||||||
when(mMediaOutputController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(true);
|
when(mMediaOutputController.isActiveRemoteDevice(mMediaDevice1)).thenReturn(true);
|
||||||
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(false);
|
|
||||||
when(mIconCompat.toIcon(mContext)).thenReturn(mIcon);
|
when(mIconCompat.toIcon(mContext)).thenReturn(mIcon);
|
||||||
when(mMediaDevice1.getName()).thenReturn(TEST_DEVICE_NAME_1);
|
when(mMediaDevice1.getName()).thenReturn(TEST_DEVICE_NAME_1);
|
||||||
when(mMediaDevice1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
when(mMediaDevice1.getId()).thenReturn(TEST_DEVICE_ID_1);
|
||||||
@@ -94,6 +97,8 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
|
LocalMediaManager.MediaDeviceState.STATE_DISCONNECTED);
|
||||||
mMediaDevices.add(mMediaDevice1);
|
mMediaDevices.add(mMediaDevice1);
|
||||||
mMediaDevices.add(mMediaDevice2);
|
mMediaDevices.add(mMediaDevice2);
|
||||||
|
mMediaItems.add(new MediaItem(mMediaDevice1));
|
||||||
|
mMediaItems.add(new MediaItem(mMediaDevice2));
|
||||||
|
|
||||||
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
@@ -118,6 +123,26 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
assertThat(mMediaOutputAdapter.getItemId(invalidPosition)).isEqualTo(invalidPosition);
|
assertThat(mMediaOutputAdapter.getItemId(invalidPosition)).isEqualTo(invalidPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_getItemCount_returnsMediaItemSize() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
assertThat(mMediaOutputAdapter.getItemCount()).isEqualTo(mMediaItems.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_getItemId_validPosition_returnCorrespondingId() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
assertThat(mMediaOutputAdapter.getItemId(0)).isEqualTo(mMediaItems.get(
|
||||||
|
0).getMediaDevice().get().getId().hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_getItemId_invalidPosition_returnPosition() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
int invalidPosition = mMediaItems.size() + 1;
|
||||||
|
assertThat(mMediaOutputAdapter.getItemId(invalidPosition)).isEqualTo(invalidPosition);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBindViewHolder_bindPairNew_verifyView() {
|
public void onBindViewHolder_bindPairNew_verifyView() {
|
||||||
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
|
||||||
@@ -158,6 +183,63 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
|
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onBindViewHolder_bindPairNew_verifyView() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
|
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||||
|
mMediaItems.add(new MediaItem());
|
||||||
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
|
||||||
|
|
||||||
|
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mTitleText.getText()).isEqualTo(mContext.getText(
|
||||||
|
R.string.media_output_dialog_pairing_new));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onBindViewHolder_bindGroup_withSessionName_verifyView() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
|
||||||
|
mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
|
||||||
|
Collectors.toList()));
|
||||||
|
when(mMediaOutputController.getSessionName()).thenReturn(TEST_SESSION_NAME);
|
||||||
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
|
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||||
|
mMediaOutputAdapter.getItemCount();
|
||||||
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
|
||||||
|
|
||||||
|
assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onBindViewHolder_bindGroup_noSessionName_verifyView() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
|
||||||
|
mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
|
||||||
|
Collectors.toList()));
|
||||||
|
when(mMediaOutputController.getSessionName()).thenReturn(null);
|
||||||
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
|
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||||
|
mMediaOutputAdapter.getItemCount();
|
||||||
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
|
||||||
|
|
||||||
|
assertThat(mViewHolder.mSeekBar.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(mViewHolder.mTwoLineLayout.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mTitleText.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(mViewHolder.mProgressBar.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
assertThat(mViewHolder.mCheckBox.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBindViewHolder_bindConnectedDevice_verifyView() {
|
public void onBindViewHolder_bindConnectedDevice_verifyView() {
|
||||||
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
|
||||||
@@ -375,6 +457,19 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
verify(mMediaOutputController).launchBluetoothPairing(mViewHolder.mContainerLayout);
|
verify(mMediaOutputController).launchBluetoothPairing(mViewHolder.mContainerLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onItemClick_clickPairNew_verifyLaunchBluetoothPairing() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
|
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||||
|
mMediaItems.add(new MediaItem());
|
||||||
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 2);
|
||||||
|
mViewHolder.mContainerLayout.performClick();
|
||||||
|
|
||||||
|
verify(mMediaOutputController).launchBluetoothPairing(mViewHolder.mContainerLayout);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onItemClick_clickDevice_verifyConnectDevice() {
|
public void onItemClick_clickDevice_verifyConnectDevice() {
|
||||||
assertThat(mMediaDevice2.getState()).isEqualTo(
|
assertThat(mMediaDevice2.getState()).isEqualTo(
|
||||||
@@ -457,6 +552,26 @@ public class MediaOutputAdapterTest extends SysuiTestCase {
|
|||||||
assertThat(mViewHolder.mSeekBar.isEnabled()).isFalse();
|
assertThat(mViewHolder.mSeekBar.isEnabled()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onItemClick_onGroupActionTriggered_verifySeekbarDisabled() {
|
||||||
|
when(mMediaOutputController.isAdvancedLayoutSupported()).thenReturn(true);
|
||||||
|
when(mMediaOutputController.getSelectedMediaDevice()).thenReturn(
|
||||||
|
mMediaItems.stream().map((item) -> item.getMediaDevice().get()).collect(
|
||||||
|
Collectors.toList()));
|
||||||
|
mMediaOutputAdapter = new MediaOutputAdapter(mMediaOutputController);
|
||||||
|
mViewHolder = (MediaOutputAdapter.MediaDeviceViewHolder) mMediaOutputAdapter
|
||||||
|
.onCreateViewHolder(new LinearLayout(mContext), 0);
|
||||||
|
List<MediaDevice> selectableDevices = new ArrayList<>();
|
||||||
|
selectableDevices.add(mMediaDevice1);
|
||||||
|
when(mMediaOutputController.getSelectableMediaDevice()).thenReturn(selectableDevices);
|
||||||
|
when(mMediaOutputController.hasAdjustVolumeUserRestriction()).thenReturn(true);
|
||||||
|
mMediaOutputAdapter.onBindViewHolder(mViewHolder, 0);
|
||||||
|
|
||||||
|
mViewHolder.mContainerLayout.performClick();
|
||||||
|
|
||||||
|
assertThat(mViewHolder.mSeekBar.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onBindViewHolder_volumeControlChangeToEnabled_enableSeekbarAgain() {
|
public void onBindViewHolder_volumeControlChangeToEnabled_enableSeekbarAgain() {
|
||||||
when(mMediaOutputController.isVolumeControlEnabled(mMediaDevice1)).thenReturn(false);
|
when(mMediaOutputController.isVolumeControlEnabled(mMediaDevice1)).thenReturn(false);
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ import com.android.systemui.SysuiTestCase;
|
|||||||
import com.android.systemui.animation.ActivityLaunchAnimator;
|
import com.android.systemui.animation.ActivityLaunchAnimator;
|
||||||
import com.android.systemui.animation.DialogLaunchAnimator;
|
import com.android.systemui.animation.DialogLaunchAnimator;
|
||||||
import com.android.systemui.flags.FeatureFlags;
|
import com.android.systemui.flags.FeatureFlags;
|
||||||
|
import com.android.systemui.flags.Flags;
|
||||||
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
|
import com.android.systemui.media.nearby.NearbyMediaDevicesManager;
|
||||||
import com.android.systemui.plugins.ActivityStarter;
|
import com.android.systemui.plugins.ActivityStarter;
|
||||||
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
|
||||||
@@ -144,6 +145,7 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
mNotifCollection, mDialogLaunchAnimator,
|
mNotifCollection, mDialogLaunchAnimator,
|
||||||
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
|
Optional.of(mNearbyMediaDevicesManager), mAudioManager, mPowerExemptionManager,
|
||||||
mKeyguardManager, mFlags);
|
mKeyguardManager, mFlags);
|
||||||
|
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(false);
|
||||||
mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
|
mLocalMediaManager = spy(mMediaOutputController.mLocalMediaManager);
|
||||||
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
|
mMediaOutputController.mLocalMediaManager = mLocalMediaManager;
|
||||||
MediaDescription.Builder builder = new MediaDescription.Builder();
|
MediaDescription.Builder builder = new MediaDescription.Builder();
|
||||||
@@ -281,6 +283,25 @@ public class MediaOutputControllerTest extends SysuiTestCase {
|
|||||||
verify(mCb).onDeviceListChanged();
|
verify(mCb).onDeviceListChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void advanced_onDeviceListUpdate_verifyDeviceListCallback() {
|
||||||
|
when(mFlags.isEnabled(Flags.OUTPUT_SWITCHER_ADVANCED_LAYOUT)).thenReturn(true);
|
||||||
|
mMediaOutputController.start(mCb);
|
||||||
|
reset(mCb);
|
||||||
|
|
||||||
|
mMediaOutputController.onDeviceListUpdate(mMediaDevices);
|
||||||
|
final List<MediaDevice> devices = new ArrayList<>();
|
||||||
|
for (MediaItem item : mMediaOutputController.getMediaItemList()) {
|
||||||
|
if (item.getMediaDevice().isPresent()) {
|
||||||
|
devices.add(item.getMediaDevice().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assertThat(devices.containsAll(mMediaDevices)).isTrue();
|
||||||
|
assertThat(devices.size()).isEqualTo(mMediaDevices.size());
|
||||||
|
verify(mCb).onDeviceListChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onDeviceListUpdate_isRefreshing_updatesNeedRefreshToTrue() {
|
public void onDeviceListUpdate_isRefreshing_updatesNeedRefreshToTrue() {
|
||||||
mMediaOutputController.start(mCb);
|
mMediaOutputController.start(mCb);
|
||||||
|
|||||||
Reference in New Issue
Block a user