Update OutputSwitcher from MediaOutputSlice to MediaOutputDialog in Settings
-Update entry point at media indicator in volume panel -Update entry point at remote media slice in volume panel -Update entry point at remote volume group in Sound Settings -Update entry point at media output preference in Sound Settings -Hide Media output dialog when the caller is not active Bug: 155822415 Test: make -j50 RunSettingsRoboTests Change-Id: Ib6c86067522925c439f336644e4d027dbae3379c
This commit is contained in:
@@ -66,11 +66,11 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
|
|||||||
final int requestCode = TextUtils.isEmpty(getWorker().getPackageName())
|
final int requestCode = TextUtils.isEmpty(getWorker().getPackageName())
|
||||||
? 0
|
? 0
|
||||||
: getWorker().getPackageName().hashCode();
|
: getWorker().getPackageName().hashCode();
|
||||||
final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
|
final PendingIntent primaryBroadcastIntent = PendingIntent.getBroadcast(mContext,
|
||||||
requestCode,
|
requestCode, getMediaOutputDialogIntent(), FLAG_UPDATE_CURRENT);
|
||||||
getMediaOutputSliceIntent(), FLAG_UPDATE_CURRENT);
|
|
||||||
final SliceAction primarySliceAction = SliceAction.createDeeplink(
|
final SliceAction primarySliceAction = SliceAction.createDeeplink(
|
||||||
primaryActionIntent, icon, ListBuilder.ICON_IMAGE, title);
|
primaryBroadcastIntent, icon, ListBuilder.ICON_IMAGE, title);
|
||||||
|
|
||||||
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
|
@ColorInt final int color = Utils.getColorAccentDefaultColor(mContext);
|
||||||
// To set an empty icon to indent the row
|
// To set an empty icon to indent the row
|
||||||
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
|
final ListBuilder listBuilder = new ListBuilder(mContext, getUri(), ListBuilder.INFINITY)
|
||||||
@@ -84,12 +84,11 @@ public class MediaOutputIndicatorSlice implements CustomSliceable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
Intent getMediaOutputSliceIntent() {
|
Intent getMediaOutputDialogIntent() {
|
||||||
final MediaController mediaController = getWorker().getActiveLocalMediaController();
|
final MediaController mediaController = getWorker().getActiveLocalMediaController();
|
||||||
final Intent intent = new Intent()
|
final Intent intent = new Intent()
|
||||||
.setPackage(Utils.SETTINGS_PACKAGE_NAME)
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
|
||||||
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
|
.setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
if (mediaController != null) {
|
if (mediaController != null) {
|
||||||
intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
|
intent.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
|
||||||
mediaController.getSessionToken());
|
mediaController.getSessionToken());
|
||||||
|
@@ -133,8 +133,7 @@ public class RemoteMediaSlice implements CustomSliceable {
|
|||||||
.setTitle(isMediaOutputDisabled ? spannableTitle : outputTitle)
|
.setTitle(isMediaOutputDisabled ? spannableTitle : outputTitle)
|
||||||
.setSubtitle(info.getName())
|
.setSubtitle(info.getName())
|
||||||
.setTitleItem(emptyIcon, ListBuilder.ICON_IMAGE)
|
.setTitleItem(emptyIcon, ListBuilder.ICON_IMAGE)
|
||||||
.setPrimaryAction(getMediaOutputSliceAction(
|
.setPrimaryAction(getMediaOutputDialogAction(info, isMediaOutputDisabled)));
|
||||||
info.getClientPackageName(), isMediaOutputDisabled)));
|
|
||||||
}
|
}
|
||||||
return listBuilder.build();
|
return listBuilder.build();
|
||||||
}
|
}
|
||||||
@@ -167,23 +166,23 @@ public class RemoteMediaSlice implements CustomSliceable {
|
|||||||
return primarySliceAction;
|
return primarySliceAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SliceAction getMediaOutputSliceAction(
|
private SliceAction getMediaOutputDialogAction(RoutingSessionInfo info,
|
||||||
String packageName, boolean isMediaOutputDisabled) {
|
boolean isMediaOutputDisabled) {
|
||||||
final Intent intent = new Intent()
|
final Intent intent = new Intent()
|
||||||
.setAction(isMediaOutputDisabled
|
.setAction(isMediaOutputDisabled
|
||||||
? ""
|
? "" : MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
|
||||||
: MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
|
||||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
|
||||||
.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME, packageName);
|
info.getClientPackageName());
|
||||||
final IconCompat icon = IconCompat.createWithResource(mContext,
|
final IconCompat icon = IconCompat.createWithResource(mContext,
|
||||||
R.drawable.ic_volume_remote);
|
R.drawable.ic_volume_remote);
|
||||||
final int requestCode = TextUtils.isEmpty(packageName) ? 0 : packageName.hashCode();
|
|
||||||
final PendingIntent primaryActionIntent = PendingIntent.getActivity(mContext,
|
final PendingIntent primaryBroadcastIntent = PendingIntent.getBroadcast(mContext,
|
||||||
requestCode, intent, 0 /* flags */);
|
0 /* requestCode */, intent, 0 /* flags */);
|
||||||
final SliceAction primarySliceAction = SliceAction.createDeeplink(
|
final SliceAction primarySliceAction = SliceAction.createDeeplink(
|
||||||
primaryActionIntent, icon, ListBuilder.ICON_IMAGE,
|
primaryBroadcastIntent, icon, ListBuilder.ICON_IMAGE,
|
||||||
mContext.getString(R.string.media_output_label_title,
|
mContext.getString(R.string.media_output_label_title,
|
||||||
Utils.getApplicationLabel(mContext, packageName)));
|
Utils.getApplicationLabel(mContext, info.getClientPackageName())));
|
||||||
return primarySliceAction;
|
return primarySliceAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,7 @@ import com.android.settings.Utils;
|
|||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
import com.android.settingslib.core.lifecycle.events.OnDestroy;
|
import com.android.settingslib.core.lifecycle.events.OnDestroy;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||||
import com.android.settingslib.media.LocalMediaManager;
|
import com.android.settingslib.media.LocalMediaManager;
|
||||||
import com.android.settingslib.media.MediaDevice;
|
import com.android.settingslib.media.MediaDevice;
|
||||||
import com.android.settingslib.media.MediaOutputSliceConstants;
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
@@ -45,7 +46,7 @@ import java.util.List;
|
|||||||
* {@link com.android.settings.notification.RemoteVolumeSeekBarPreference}
|
* {@link com.android.settings.notification.RemoteVolumeSeekBarPreference}
|
||||||
**/
|
**/
|
||||||
public class RemoteVolumeGroupController extends BasePreferenceController implements
|
public class RemoteVolumeGroupController extends BasePreferenceController implements
|
||||||
Preference.OnPreferenceChangeListener, LifecycleObserver, OnDestroy,
|
Preference.OnPreferenceChangeListener, LifecycleObserver, OnDestroy, OnPause,
|
||||||
LocalMediaManager.DeviceCallback {
|
LocalMediaManager.DeviceCallback {
|
||||||
|
|
||||||
private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group";
|
private static final String KEY_REMOTE_VOLUME_GROUP = "remote_media_group";
|
||||||
@@ -96,6 +97,14 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
// Media output dialog should not show when onPause
|
||||||
|
mContext.sendBroadcast(new Intent()
|
||||||
|
.setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
|
||||||
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
mLocalMediaManager.unregisterCallback(this);
|
mLocalMediaManager.unregisterCallback(this);
|
||||||
@@ -159,11 +168,11 @@ public class RemoteVolumeGroupController extends BasePreferenceController implem
|
|||||||
if (TextUtils.equals(info.getId(),
|
if (TextUtils.equals(info.getId(),
|
||||||
preference.getKey().substring(SWITCHER_PREFIX.length()))) {
|
preference.getKey().substring(SWITCHER_PREFIX.length()))) {
|
||||||
final Intent intent = new Intent()
|
final Intent intent = new Intent()
|
||||||
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
|
.setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
|
||||||
.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
|
.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
|
||||||
info.getClientPackageName());
|
info.getClientPackageName());
|
||||||
mContext.startActivity(intent);
|
mContext.sendBroadcast(intent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.panel;
|
package com.android.settings.panel;
|
||||||
|
|
||||||
|
import static androidx.lifecycle.Lifecycle.Event.ON_PAUSE;
|
||||||
|
|
||||||
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
|
import static com.android.settings.slices.CustomSliceRegistry.MEDIA_OUTPUT_INDICATOR_SLICE_URI;
|
||||||
import static com.android.settings.slices.CustomSliceRegistry.REMOTE_MEDIA_SLICE_URI;
|
import static com.android.settings.slices.CustomSliceRegistry.REMOTE_MEDIA_SLICE_URI;
|
||||||
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_ALARM_URI;
|
import static com.android.settings.slices.CustomSliceRegistry.VOLUME_ALARM_URI;
|
||||||
@@ -29,12 +31,19 @@ import android.content.Intent;
|
|||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleObserver;
|
||||||
|
import androidx.lifecycle.OnLifecycleEvent;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class VolumePanel implements PanelContent {
|
/**
|
||||||
|
* Panel data class for Volume settings.
|
||||||
|
*/
|
||||||
|
public class VolumePanel implements PanelContent, LifecycleObserver {
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
|
||||||
@@ -46,6 +55,15 @@ public class VolumePanel implements PanelContent {
|
|||||||
mContext = context.getApplicationContext();
|
mContext = context.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Invoked when the panel is paused. */
|
||||||
|
@OnLifecycleEvent(ON_PAUSE)
|
||||||
|
public void onPause() {
|
||||||
|
// Media output dialog should not show when onPause
|
||||||
|
mContext.sendBroadcast(new Intent()
|
||||||
|
.setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
|
||||||
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence getTitle() {
|
public CharSequence getTitle() {
|
||||||
return mContext.getText(R.string.sound_settings);
|
return mContext.getText(R.string.sound_settings);
|
||||||
|
@@ -33,6 +33,8 @@ import com.android.settings.R;
|
|||||||
import com.android.settingslib.Utils;
|
import com.android.settingslib.Utils;
|
||||||
import com.android.settingslib.bluetooth.A2dpProfile;
|
import com.android.settingslib.bluetooth.A2dpProfile;
|
||||||
import com.android.settingslib.bluetooth.HearingAidProfile;
|
import com.android.settingslib.bluetooth.HearingAidProfile;
|
||||||
|
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||||
|
import com.android.settingslib.core.lifecycle.events.OnStop;
|
||||||
import com.android.settingslib.media.MediaOutputSliceConstants;
|
import com.android.settingslib.media.MediaOutputSliceConstants;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -45,7 +47,8 @@ import java.util.List;
|
|||||||
* - Media stream captured by remote device
|
* - Media stream captured by remote device
|
||||||
* - During a call.
|
* - During a call.
|
||||||
*/
|
*/
|
||||||
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController {
|
public class MediaOutputPreferenceController extends AudioSwitchPreferenceController
|
||||||
|
implements LifecycleObserver, OnStop {
|
||||||
|
|
||||||
private MediaController mMediaController;
|
private MediaController mMediaController;
|
||||||
|
|
||||||
@@ -63,6 +66,15 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop() {
|
||||||
|
super.onStop();
|
||||||
|
// Media output dialog should not show when onStop
|
||||||
|
mContext.sendBroadcast(new Intent()
|
||||||
|
.setAction(MediaOutputSliceConstants.ACTION_DISMISS_MEDIA_OUTPUT_DIALOG)
|
||||||
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateState(Preference preference) {
|
public void updateState(Preference preference) {
|
||||||
if (preference == null) {
|
if (preference == null) {
|
||||||
@@ -133,10 +145,13 @@ public class MediaOutputPreferenceController extends AudioSwitchPreferenceContro
|
|||||||
@Override
|
@Override
|
||||||
public boolean handlePreferenceTreeClick(Preference preference) {
|
public boolean handlePreferenceTreeClick(Preference preference) {
|
||||||
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
if (TextUtils.equals(preference.getKey(), getPreferenceKey())) {
|
||||||
final Intent intent = new Intent()
|
mContext.sendBroadcast(new Intent()
|
||||||
.setAction(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT)
|
.setAction(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG)
|
||||||
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
.setPackage(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME)
|
||||||
mContext.startActivity(intent);
|
.putExtra(MediaOutputSliceConstants.EXTRA_PACKAGE_NAME,
|
||||||
|
mMediaController.getPackageName())
|
||||||
|
.putExtra(MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN,
|
||||||
|
mMediaController.getSessionToken()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -208,12 +208,14 @@ public class MediaOutputIndicatorSliceTest {
|
|||||||
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE_NAME);
|
||||||
doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
|
doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
|
||||||
.getActiveLocalMediaController();
|
.getActiveLocalMediaController();
|
||||||
final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
|
final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputDialogIntent();
|
||||||
|
|
||||||
assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra(
|
assertThat(TextUtils.equals(TEST_PACKAGE_NAME, intent.getStringExtra(
|
||||||
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
|
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
|
||||||
assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
|
assertThat(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG).isEqualTo(
|
||||||
assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
|
intent.getAction());
|
||||||
|
assertThat(TextUtils.equals(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME,
|
||||||
|
intent.getPackage())).isTrue();
|
||||||
assertThat(mToken == intent.getExtras().getParcelable(
|
assertThat(mToken == intent.getExtras().getParcelable(
|
||||||
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
|
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN)).isTrue();
|
||||||
}
|
}
|
||||||
@@ -222,12 +224,14 @@ public class MediaOutputIndicatorSliceTest {
|
|||||||
public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() {
|
public void getMediaOutputSliceIntent_withoutActiveLocalMedia_verifyIntentExtra() {
|
||||||
doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
|
doReturn(mMediaController).when(sMediaOutputIndicatorWorker)
|
||||||
.getActiveLocalMediaController();
|
.getActiveLocalMediaController();
|
||||||
final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputSliceIntent();
|
final Intent intent = mMediaOutputIndicatorSlice.getMediaOutputDialogIntent();
|
||||||
|
|
||||||
assertThat(TextUtils.isEmpty(intent.getStringExtra(
|
assertThat(TextUtils.isEmpty(intent.getStringExtra(
|
||||||
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
|
MediaOutputSliceConstants.EXTRA_PACKAGE_NAME))).isTrue();
|
||||||
assertThat(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT).isEqualTo(intent.getAction());
|
assertThat(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG).isEqualTo(
|
||||||
assertThat(TextUtils.equals(Utils.SETTINGS_PACKAGE_NAME, intent.getPackage())).isTrue();
|
intent.getAction());
|
||||||
|
assertThat(TextUtils.equals(MediaOutputSliceConstants.SYSTEMUI_PACKAGE_NAME,
|
||||||
|
intent.getPackage())).isTrue();
|
||||||
assertThat(intent.getExtras().getParcelable(
|
assertThat(intent.getExtras().getParcelable(
|
||||||
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
|
MediaOutputSliceConstants.KEY_MEDIA_SESSION_TOKEN) == null).isTrue();
|
||||||
}
|
}
|
||||||
|
@@ -300,9 +300,9 @@ public class MediaOutputPreferenceControllerTest {
|
|||||||
|
|
||||||
mPreference.setKey(TEST_KEY);
|
mPreference.setKey(TEST_KEY);
|
||||||
mController.handlePreferenceTreeClick(mPreference);
|
mController.handlePreferenceTreeClick(mPreference);
|
||||||
verify(mContext).startActivity(intentCaptor.capture());
|
verify(mContext).sendBroadcast(intentCaptor.capture());
|
||||||
assertThat(intentCaptor.getValue().getAction())
|
assertThat(intentCaptor.getValue().getAction())
|
||||||
.isEqualTo(MediaOutputSliceConstants.ACTION_MEDIA_OUTPUT);
|
.isEqualTo(MediaOutputSliceConstants.ACTION_LAUNCH_MEDIA_OUTPUT_DIALOG);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user