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:
timhypeng
2020-09-26 15:43:11 +08:00
parent 2489494cd3
commit 3084d063f3
7 changed files with 83 additions and 39 deletions

View File

@@ -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());

View File

@@ -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;
} }

View File

@@ -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;
} }
} }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
} }

View File

@@ -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);
} }
/** /**