Loading packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -46,8 +46,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList; Loading @@ -56,7 +54,6 @@ import java.util.concurrent.CopyOnWriteArrayList; */ */ @RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R) public class LocalMediaManager implements BluetoothCallback { public class LocalMediaManager implements BluetoothCallback { private static final Comparator<MediaDevice> COMPARATOR = Comparator.naturalOrder(); private static final String TAG = "LocalMediaManager"; private static final String TAG = "LocalMediaManager"; private static final int MAX_DISCONNECTED_DEVICE_NUM = 5; private static final int MAX_DISCONNECTED_DEVICE_NUM = 5; Loading @@ -65,13 +62,15 @@ public class LocalMediaManager implements BluetoothCallback { MediaDeviceState.STATE_CONNECTING, MediaDeviceState.STATE_CONNECTING, MediaDeviceState.STATE_DISCONNECTED, MediaDeviceState.STATE_DISCONNECTED, MediaDeviceState.STATE_CONNECTING_FAILED, MediaDeviceState.STATE_CONNECTING_FAILED, MediaDeviceState.STATE_SELECTED}) MediaDeviceState.STATE_SELECTED, MediaDeviceState.STATE_GROUPING}) public @interface MediaDeviceState { public @interface MediaDeviceState { int STATE_CONNECTED = 0; int STATE_CONNECTED = 0; int STATE_CONNECTING = 1; int STATE_CONNECTING = 1; int STATE_DISCONNECTED = 2; int STATE_DISCONNECTED = 2; int STATE_CONNECTING_FAILED = 3; int STATE_CONNECTING_FAILED = 3; int STATE_SELECTED = 4; int STATE_SELECTED = 4; int STATE_GROUPING = 5; } } private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>(); private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>(); Loading Loading @@ -322,6 +321,7 @@ public class LocalMediaManager implements BluetoothCallback { * @return If add device successful return {@code true}, otherwise return {@code false} * @return If add device successful return {@code true}, otherwise return {@code false} */ */ public boolean addDeviceToPlayMedia(MediaDevice device) { public boolean addDeviceToPlayMedia(MediaDevice device) { device.setState(MediaDeviceState.STATE_GROUPING); return mInfoMediaManager.addDeviceToPlayMedia(device); return mInfoMediaManager.addDeviceToPlayMedia(device); } } Loading @@ -332,6 +332,7 @@ public class LocalMediaManager implements BluetoothCallback { * @return If device stop successful return {@code true}, otherwise return {@code false} * @return If device stop successful return {@code true}, otherwise return {@code false} */ */ public boolean removeDeviceFromPlayMedia(MediaDevice device) { public boolean removeDeviceFromPlayMedia(MediaDevice device) { device.setState(MediaDeviceState.STATE_GROUPING); return mInfoMediaManager.removeDeviceFromPlayMedia(device); return mInfoMediaManager.removeDeviceFromPlayMedia(device); } } Loading Loading @@ -524,7 +525,6 @@ public class LocalMediaManager implements BluetoothCallback { @Override @Override public void onDeviceListAdded(List<MediaDevice> devices) { public void onDeviceListAdded(List<MediaDevice> devices) { synchronized (mMediaDevicesLock) { synchronized (mMediaDevicesLock) { Collections.sort(devices, COMPARATOR); mMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.addAll(devices); mMediaDevices.addAll(devices); // Add disconnected bluetooth devices only when phone output device is available. // Add disconnected bluetooth devices only when phone output device is available. Loading packages/SystemUI/res/layout/media_output_list_item.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ android:visibility="gone" android:visibility="gone" android:paddingStart="0dp" android:paddingStart="0dp" android:paddingEnd="0dp" android:paddingEnd="0dp" android:background="@null" android:progressDrawable="@drawable/media_output_dialog_seekbar_background" android:progressDrawable="@drawable/media_output_dialog_seekbar_background" android:thumb="@null" android:thumb="@null" android:layout_width="match_parent" android:layout_width="match_parent" Loading packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { true /* showSubtitle */, true /* showStatus */); true /* showSubtitle */, true /* showStatus */); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } else if (device.getState() == MediaDeviceState.STATE_GROUPING) { mProgressBar.getIndeterminateDrawable().setColorFilter( new PorterDuffColorFilter( mController.getColorItemContent(), PorterDuff.Mode.SRC_IN)); setSingleLineLayout(getItemTitle(device), true /* bFocused */, false /* showSeekBar*/, true /* showProgressBar */, false /* showStatus */); } else if (mController.getSelectedMediaDevice().size() > 1 } else if (mController.getSelectedMediaDevice().size() > 1 && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { mTitleText.setTextColor(mController.getColorItemContent()); mTitleText.setTextColor(mController.getColorItemContent()); Loading packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +18 −1 Original line number Original line Diff line number Diff line Loading @@ -184,6 +184,19 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } } }; }; private class LayoutManagerWrapper extends LinearLayoutManager { LayoutManagerWrapper(Context context) { super(context); } @Override public void onLayoutCompleted(RecyclerView.State state) { super.onLayoutCompleted(state); mMediaOutputController.setRefreshing(false); mMediaOutputController.refreshDataSetIfNeeded(); } } public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender, public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender, MediaOutputController mediaOutputController) { MediaOutputController mediaOutputController) { super(context, R.style.Theme_SystemUI_Dialog_Media); super(context, R.style.Theme_SystemUI_Dialog_Media); Loading @@ -192,7 +205,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mContext = getContext(); mContext = getContext(); mBroadcastSender = broadcastSender; mBroadcastSender = broadcastSender; mMediaOutputController = mediaOutputController; mMediaOutputController = mediaOutputController; mLayoutManager = new LinearLayoutManager(mContext); mLayoutManager = new LayoutManagerWrapper(mContext); mListMaxHeight = context.getResources().getDimensionPixelSize( mListMaxHeight = context.getResources().getDimensionPixelSize( R.dimen.media_output_dialog_list_max_height); R.dimen.media_output_dialog_list_max_height); mExecutor = Executors.newSingleThreadExecutor(); mExecutor = Executors.newSingleThreadExecutor(); Loading Loading @@ -274,6 +287,10 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } } void refresh(boolean deviceSetChanged) { void refresh(boolean deviceSetChanged) { if (mMediaOutputController.isRefreshing()) { return; } mMediaOutputController.setRefreshing(true); // Update header icon // Update header icon final int iconRes = getHeaderIconRes(); final int iconRes = getHeaderIconRes(); final IconCompat iconCompat = getHeaderIcon(); final IconCompat iconCompat = getHeaderIcon(); Loading packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +94 −49 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,8 @@ import com.android.systemui.statusbar.phone.SystemUIDialog; import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.Optional; import java.util.Optional; Loading Loading @@ -108,11 +110,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, private final DialogLaunchAnimator mDialogLaunchAnimator; private final DialogLaunchAnimator mDialogLaunchAnimator; private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); private final CommonNotifCollection mNotifCollection; private final CommonNotifCollection mNotifCollection; private final Object mMediaDevicesLock = new Object(); @VisibleForTesting @VisibleForTesting final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>(); private final NearbyMediaDevicesManager mNearbyMediaDevicesManager; private final NearbyMediaDevicesManager mNearbyMediaDevicesManager; private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>(); private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>(); private boolean mIsRefreshing = false; private boolean mNeedRefresh = false; private MediaController mMediaController; private MediaController mMediaController; @VisibleForTesting @VisibleForTesting Callback mCallback; Callback mCallback; Loading Loading @@ -172,7 +178,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } void start(@NonNull Callback cb) { void start(@NonNull Callback cb) { synchronized (mMediaDevicesLock) { mCachedMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.clear(); } mNearbyDeviceInfoMap.clear(); mNearbyDeviceInfoMap.clear(); if (mNearbyMediaDevicesManager != null) { if (mNearbyMediaDevicesManager != null) { mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this); mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this); Loading Loading @@ -211,6 +220,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return routerParams != null && !routerParams.isMediaTransferReceiverEnabled(); return routerParams != null && !routerParams.isMediaTransferReceiverEnabled(); } } void setRefreshing(boolean refreshing) { mIsRefreshing = refreshing; } boolean isRefreshing() { return mIsRefreshing; } void stop() { void stop() { if (mMediaController != null) { if (mMediaController != null) { mMediaController.unregisterCallback(mCb); mMediaController.unregisterCallback(mCb); Loading @@ -219,7 +236,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.stopScan(); mLocalMediaManager.stopScan(); } } synchronized (mMediaDevicesLock) { mCachedMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.clear(); } if (mNearbyMediaDevicesManager != null) { if (mNearbyMediaDevicesManager != null) { mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this); mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this); } } Loading @@ -228,15 +248,23 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @Override @Override public void onDeviceListUpdate(List<MediaDevice> devices) { public void onDeviceListUpdate(List<MediaDevice> devices) { if (mMediaDevices.isEmpty() || !mIsRefreshing) { buildMediaDevices(devices); buildMediaDevices(devices); mCallback.onDeviceListChanged(); mCallback.onDeviceListChanged(); } else { synchronized (mMediaDevicesLock) { mNeedRefresh = true; mCachedMediaDevices.clear(); mCachedMediaDevices.addAll(devices); } } } } @Override @Override 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(), mMediaDevices); mMetricLogger.logOutputSuccess(device.toString(), new ArrayList<>(mMediaDevices)); } } @Override @Override Loading @@ -247,7 +275,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @Override @Override public void onRequestFailed(int reason) { public void onRequestFailed(int reason) { mCallback.onRouteChanged(); mCallback.onRouteChanged(); mMetricLogger.logOutputFailure(mMediaDevices, reason); mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason); } } Drawable getAppSourceIcon() { Drawable getAppSourceIcon() { Loading Loading @@ -399,6 +427,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } } } void refreshDataSetIfNeeded() { if (mNeedRefresh) { buildMediaDevices(mCachedMediaDevices); mCallback.onDeviceListChanged(); mNeedRefresh = false; } } public int getColorConnectedItemBackground() { public int getColorConnectedItemBackground() { return mColorConnectedItemBackground; return mColorConnectedItemBackground; } } Loading Loading @@ -432,7 +468,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } private void buildMediaDevices(List<MediaDevice> devices) { private void buildMediaDevices(List<MediaDevice> devices) { // For the first time building list, to make sure the top device is the connected device. synchronized (mMediaDevicesLock) { attachRangeInfo(devices); Collections.sort(devices, Comparator.naturalOrder()); // For the first time building list, to make sure the top device is the connected // device. if (mMediaDevices.isEmpty()) { if (mMediaDevices.isEmpty()) { final MediaDevice connectedMediaDevice = getCurrentConnectedMediaDevice(); final MediaDevice connectedMediaDevice = getCurrentConnectedMediaDevice(); if (connectedMediaDevice == null) { if (connectedMediaDevice == null) { Loading @@ -452,7 +492,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return; return; } } // To keep the same list order // To keep the same list order final Collection<MediaDevice> targetMediaDevices = new ArrayList<>(); final List<MediaDevice> targetMediaDevices = new ArrayList<>(); for (MediaDevice originalDevice : mMediaDevices) { for (MediaDevice originalDevice : mMediaDevices) { for (MediaDevice newDevice : devices) { for (MediaDevice newDevice : devices) { if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { Loading @@ -467,15 +507,16 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } mMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.addAll(targetMediaDevices); mMediaDevices.addAll(targetMediaDevices); attachRangeInfo(); } } } private void attachRangeInfo() { private void attachRangeInfo(List<MediaDevice> devices) { for (MediaDevice mediaDevice : mMediaDevices) { for (MediaDevice mediaDevice : devices) { if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) { if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) { mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId())); mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId())); } } } } } } List<MediaDevice> getGroupMediaDevices() { List<MediaDevice> getGroupMediaDevices() { Loading Loading @@ -609,15 +650,18 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } boolean isTransferring() { boolean isTransferring() { synchronized (mMediaDevicesLock) { for (MediaDevice device : mMediaDevices) { for (MediaDevice device : mMediaDevices) { if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) { if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) { return true; return true; } } } } } return false; return false; } } boolean isZeroMode() { boolean isZeroMode() { synchronized (mMediaDevicesLock) { if (mMediaDevices.size() == 1) { if (mMediaDevices.size() == 1) { final MediaDevice device = mMediaDevices.iterator().next(); final MediaDevice device = mMediaDevices.iterator().next(); // Add "pair new" only when local output device exists // Add "pair new" only when local output device exists Loading @@ -630,6 +674,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } return false; return false; } } } void launchBluetoothPairing(View view) { void launchBluetoothPairing(View view) { ActivityLaunchAnimator.Controller controller = ActivityLaunchAnimator.Controller controller = Loading Loading
packages/SettingsLib/src/com/android/settingslib/media/LocalMediaManager.java +5 −5 Original line number Original line Diff line number Diff line Loading @@ -46,8 +46,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList; Loading @@ -56,7 +54,6 @@ import java.util.concurrent.CopyOnWriteArrayList; */ */ @RequiresApi(Build.VERSION_CODES.R) @RequiresApi(Build.VERSION_CODES.R) public class LocalMediaManager implements BluetoothCallback { public class LocalMediaManager implements BluetoothCallback { private static final Comparator<MediaDevice> COMPARATOR = Comparator.naturalOrder(); private static final String TAG = "LocalMediaManager"; private static final String TAG = "LocalMediaManager"; private static final int MAX_DISCONNECTED_DEVICE_NUM = 5; private static final int MAX_DISCONNECTED_DEVICE_NUM = 5; Loading @@ -65,13 +62,15 @@ public class LocalMediaManager implements BluetoothCallback { MediaDeviceState.STATE_CONNECTING, MediaDeviceState.STATE_CONNECTING, MediaDeviceState.STATE_DISCONNECTED, MediaDeviceState.STATE_DISCONNECTED, MediaDeviceState.STATE_CONNECTING_FAILED, MediaDeviceState.STATE_CONNECTING_FAILED, MediaDeviceState.STATE_SELECTED}) MediaDeviceState.STATE_SELECTED, MediaDeviceState.STATE_GROUPING}) public @interface MediaDeviceState { public @interface MediaDeviceState { int STATE_CONNECTED = 0; int STATE_CONNECTED = 0; int STATE_CONNECTING = 1; int STATE_CONNECTING = 1; int STATE_DISCONNECTED = 2; int STATE_DISCONNECTED = 2; int STATE_CONNECTING_FAILED = 3; int STATE_CONNECTING_FAILED = 3; int STATE_SELECTED = 4; int STATE_SELECTED = 4; int STATE_GROUPING = 5; } } private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>(); private final Collection<DeviceCallback> mCallbacks = new CopyOnWriteArrayList<>(); Loading Loading @@ -322,6 +321,7 @@ public class LocalMediaManager implements BluetoothCallback { * @return If add device successful return {@code true}, otherwise return {@code false} * @return If add device successful return {@code true}, otherwise return {@code false} */ */ public boolean addDeviceToPlayMedia(MediaDevice device) { public boolean addDeviceToPlayMedia(MediaDevice device) { device.setState(MediaDeviceState.STATE_GROUPING); return mInfoMediaManager.addDeviceToPlayMedia(device); return mInfoMediaManager.addDeviceToPlayMedia(device); } } Loading @@ -332,6 +332,7 @@ public class LocalMediaManager implements BluetoothCallback { * @return If device stop successful return {@code true}, otherwise return {@code false} * @return If device stop successful return {@code true}, otherwise return {@code false} */ */ public boolean removeDeviceFromPlayMedia(MediaDevice device) { public boolean removeDeviceFromPlayMedia(MediaDevice device) { device.setState(MediaDeviceState.STATE_GROUPING); return mInfoMediaManager.removeDeviceFromPlayMedia(device); return mInfoMediaManager.removeDeviceFromPlayMedia(device); } } Loading Loading @@ -524,7 +525,6 @@ public class LocalMediaManager implements BluetoothCallback { @Override @Override public void onDeviceListAdded(List<MediaDevice> devices) { public void onDeviceListAdded(List<MediaDevice> devices) { synchronized (mMediaDevicesLock) { synchronized (mMediaDevicesLock) { Collections.sort(devices, COMPARATOR); mMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.addAll(devices); mMediaDevices.addAll(devices); // Add disconnected bluetooth devices only when phone output device is available. // Add disconnected bluetooth devices only when phone output device is available. Loading
packages/SystemUI/res/layout/media_output_list_item.xml +1 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ android:visibility="gone" android:visibility="gone" android:paddingStart="0dp" android:paddingStart="0dp" android:paddingEnd="0dp" android:paddingEnd="0dp" android:background="@null" android:progressDrawable="@drawable/media_output_dialog_seekbar_background" android:progressDrawable="@drawable/media_output_dialog_seekbar_background" android:thumb="@null" android:thumb="@null" android:layout_width="match_parent" android:layout_width="match_parent" Loading
packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -166,6 +166,14 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter { true /* showSubtitle */, true /* showStatus */); true /* showSubtitle */, true /* showStatus */); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); mSubTitleText.setText(R.string.media_output_dialog_connect_failed); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); mContainerLayout.setOnClickListener(v -> onItemClick(v, device)); } else if (device.getState() == MediaDeviceState.STATE_GROUPING) { mProgressBar.getIndeterminateDrawable().setColorFilter( new PorterDuffColorFilter( mController.getColorItemContent(), PorterDuff.Mode.SRC_IN)); setSingleLineLayout(getItemTitle(device), true /* bFocused */, false /* showSeekBar*/, true /* showProgressBar */, false /* showStatus */); } else if (mController.getSelectedMediaDevice().size() > 1 } else if (mController.getSelectedMediaDevice().size() > 1 && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { && isDeviceIncluded(mController.getSelectedMediaDevice(), device)) { mTitleText.setTextColor(mController.getColorItemContent()); mTitleText.setTextColor(mController.getColorItemContent()); Loading
packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java +18 −1 Original line number Original line Diff line number Diff line Loading @@ -184,6 +184,19 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } } }; }; private class LayoutManagerWrapper extends LinearLayoutManager { LayoutManagerWrapper(Context context) { super(context); } @Override public void onLayoutCompleted(RecyclerView.State state) { super.onLayoutCompleted(state); mMediaOutputController.setRefreshing(false); mMediaOutputController.refreshDataSetIfNeeded(); } } public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender, public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender, MediaOutputController mediaOutputController) { MediaOutputController mediaOutputController) { super(context, R.style.Theme_SystemUI_Dialog_Media); super(context, R.style.Theme_SystemUI_Dialog_Media); Loading @@ -192,7 +205,7 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements mContext = getContext(); mContext = getContext(); mBroadcastSender = broadcastSender; mBroadcastSender = broadcastSender; mMediaOutputController = mediaOutputController; mMediaOutputController = mediaOutputController; mLayoutManager = new LinearLayoutManager(mContext); mLayoutManager = new LayoutManagerWrapper(mContext); mListMaxHeight = context.getResources().getDimensionPixelSize( mListMaxHeight = context.getResources().getDimensionPixelSize( R.dimen.media_output_dialog_list_max_height); R.dimen.media_output_dialog_list_max_height); mExecutor = Executors.newSingleThreadExecutor(); mExecutor = Executors.newSingleThreadExecutor(); Loading Loading @@ -274,6 +287,10 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements } } void refresh(boolean deviceSetChanged) { void refresh(boolean deviceSetChanged) { if (mMediaOutputController.isRefreshing()) { return; } mMediaOutputController.setRefreshing(true); // Update header icon // Update header icon final int iconRes = getHeaderIconRes(); final int iconRes = getHeaderIconRes(); final IconCompat iconCompat = getHeaderIcon(); final IconCompat iconCompat = getHeaderIcon(); Loading
packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java +94 −49 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,8 @@ import com.android.systemui.statusbar.phone.SystemUIDialog; import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.ArrayList; import java.util.Collection; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; import java.util.Optional; import java.util.Optional; Loading Loading @@ -108,11 +110,15 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, private final DialogLaunchAnimator mDialogLaunchAnimator; private final DialogLaunchAnimator mDialogLaunchAnimator; private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); private final List<MediaDevice> mGroupMediaDevices = new CopyOnWriteArrayList<>(); private final CommonNotifCollection mNotifCollection; private final CommonNotifCollection mNotifCollection; private final Object mMediaDevicesLock = new Object(); @VisibleForTesting @VisibleForTesting final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mMediaDevices = new CopyOnWriteArrayList<>(); final List<MediaDevice> mCachedMediaDevices = new CopyOnWriteArrayList<>(); private final NearbyMediaDevicesManager mNearbyMediaDevicesManager; private final NearbyMediaDevicesManager mNearbyMediaDevicesManager; private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>(); private final Map<String, Integer> mNearbyDeviceInfoMap = new ConcurrentHashMap<>(); private boolean mIsRefreshing = false; private boolean mNeedRefresh = false; private MediaController mMediaController; private MediaController mMediaController; @VisibleForTesting @VisibleForTesting Callback mCallback; Callback mCallback; Loading Loading @@ -172,7 +178,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } void start(@NonNull Callback cb) { void start(@NonNull Callback cb) { synchronized (mMediaDevicesLock) { mCachedMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.clear(); } mNearbyDeviceInfoMap.clear(); mNearbyDeviceInfoMap.clear(); if (mNearbyMediaDevicesManager != null) { if (mNearbyMediaDevicesManager != null) { mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this); mNearbyMediaDevicesManager.registerNearbyDevicesCallback(this); Loading Loading @@ -211,6 +220,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return routerParams != null && !routerParams.isMediaTransferReceiverEnabled(); return routerParams != null && !routerParams.isMediaTransferReceiverEnabled(); } } void setRefreshing(boolean refreshing) { mIsRefreshing = refreshing; } boolean isRefreshing() { return mIsRefreshing; } void stop() { void stop() { if (mMediaController != null) { if (mMediaController != null) { mMediaController.unregisterCallback(mCb); mMediaController.unregisterCallback(mCb); Loading @@ -219,7 +236,10 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.unregisterCallback(this); mLocalMediaManager.stopScan(); mLocalMediaManager.stopScan(); } } synchronized (mMediaDevicesLock) { mCachedMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.clear(); } if (mNearbyMediaDevicesManager != null) { if (mNearbyMediaDevicesManager != null) { mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this); mNearbyMediaDevicesManager.unregisterNearbyDevicesCallback(this); } } Loading @@ -228,15 +248,23 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @Override @Override public void onDeviceListUpdate(List<MediaDevice> devices) { public void onDeviceListUpdate(List<MediaDevice> devices) { if (mMediaDevices.isEmpty() || !mIsRefreshing) { buildMediaDevices(devices); buildMediaDevices(devices); mCallback.onDeviceListChanged(); mCallback.onDeviceListChanged(); } else { synchronized (mMediaDevicesLock) { mNeedRefresh = true; mCachedMediaDevices.clear(); mCachedMediaDevices.addAll(devices); } } } } @Override @Override 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(), mMediaDevices); mMetricLogger.logOutputSuccess(device.toString(), new ArrayList<>(mMediaDevices)); } } @Override @Override Loading @@ -247,7 +275,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, @Override @Override public void onRequestFailed(int reason) { public void onRequestFailed(int reason) { mCallback.onRouteChanged(); mCallback.onRouteChanged(); mMetricLogger.logOutputFailure(mMediaDevices, reason); mMetricLogger.logOutputFailure(new ArrayList<>(mMediaDevices), reason); } } Drawable getAppSourceIcon() { Drawable getAppSourceIcon() { Loading Loading @@ -399,6 +427,14 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } } } void refreshDataSetIfNeeded() { if (mNeedRefresh) { buildMediaDevices(mCachedMediaDevices); mCallback.onDeviceListChanged(); mNeedRefresh = false; } } public int getColorConnectedItemBackground() { public int getColorConnectedItemBackground() { return mColorConnectedItemBackground; return mColorConnectedItemBackground; } } Loading Loading @@ -432,7 +468,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } private void buildMediaDevices(List<MediaDevice> devices) { private void buildMediaDevices(List<MediaDevice> devices) { // For the first time building list, to make sure the top device is the connected device. synchronized (mMediaDevicesLock) { attachRangeInfo(devices); Collections.sort(devices, Comparator.naturalOrder()); // For the first time building list, to make sure the top device is the connected // device. if (mMediaDevices.isEmpty()) { if (mMediaDevices.isEmpty()) { final MediaDevice connectedMediaDevice = getCurrentConnectedMediaDevice(); final MediaDevice connectedMediaDevice = getCurrentConnectedMediaDevice(); if (connectedMediaDevice == null) { if (connectedMediaDevice == null) { Loading @@ -452,7 +492,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, return; return; } } // To keep the same list order // To keep the same list order final Collection<MediaDevice> targetMediaDevices = new ArrayList<>(); final List<MediaDevice> targetMediaDevices = new ArrayList<>(); for (MediaDevice originalDevice : mMediaDevices) { for (MediaDevice originalDevice : mMediaDevices) { for (MediaDevice newDevice : devices) { for (MediaDevice newDevice : devices) { if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { if (TextUtils.equals(originalDevice.getId(), newDevice.getId())) { Loading @@ -467,15 +507,16 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } mMediaDevices.clear(); mMediaDevices.clear(); mMediaDevices.addAll(targetMediaDevices); mMediaDevices.addAll(targetMediaDevices); attachRangeInfo(); } } } private void attachRangeInfo() { private void attachRangeInfo(List<MediaDevice> devices) { for (MediaDevice mediaDevice : mMediaDevices) { for (MediaDevice mediaDevice : devices) { if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) { if (mNearbyDeviceInfoMap.containsKey(mediaDevice.getId())) { mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId())); mediaDevice.setRangeZone(mNearbyDeviceInfoMap.get(mediaDevice.getId())); } } } } } } List<MediaDevice> getGroupMediaDevices() { List<MediaDevice> getGroupMediaDevices() { Loading Loading @@ -609,15 +650,18 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } boolean isTransferring() { boolean isTransferring() { synchronized (mMediaDevicesLock) { for (MediaDevice device : mMediaDevices) { for (MediaDevice device : mMediaDevices) { if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) { if (device.getState() == LocalMediaManager.MediaDeviceState.STATE_CONNECTING) { return true; return true; } } } } } return false; return false; } } boolean isZeroMode() { boolean isZeroMode() { synchronized (mMediaDevicesLock) { if (mMediaDevices.size() == 1) { if (mMediaDevices.size() == 1) { final MediaDevice device = mMediaDevices.iterator().next(); final MediaDevice device = mMediaDevices.iterator().next(); // Add "pair new" only when local output device exists // Add "pair new" only when local output device exists Loading @@ -630,6 +674,7 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback, } } return false; return false; } } } void launchBluetoothPairing(View view) { void launchBluetoothPairing(View view) { ActivityLaunchAnimator.Controller controller = ActivityLaunchAnimator.Controller controller = Loading