Tweak volume adjustment rules am: 022081595b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/16220980 Change-Id: Idfb22f293efc840e856615f6f065a535d0e5fcaf
This commit is contained in:
@@ -1908,8 +1908,9 @@
|
||||
STREAM_MUSIC as if it's on TV platform. -->
|
||||
<bool name="config_single_volume">false</bool>
|
||||
|
||||
<!-- Flag indicating whether the volume panel should show remote sessions. -->
|
||||
<bool name="config_volumeShowRemoteSessions">true</bool>
|
||||
<!-- Flag indicating whether platform level volume adjustments are enabled for remote sessions
|
||||
on grouped devices. -->
|
||||
<bool name="config_volumeAdjustmentForRemoteGroupSessions">true</bool>
|
||||
|
||||
<!-- Flag indicating that an outbound call must have a call capable phone account
|
||||
that has declared it can process the call's handle. -->
|
||||
|
||||
@@ -4431,7 +4431,7 @@
|
||||
|
||||
<java-symbol type="dimen" name="config_wallpaperDimAmount" />
|
||||
|
||||
<java-symbol type="bool" name="config_volumeShowRemoteSessions" />
|
||||
<java-symbol type="bool" name="config_volumeAdjustmentForRemoteGroupSessions" />
|
||||
|
||||
<java-symbol type="integer" name="config_customizedMaxCachedProcesses" />
|
||||
|
||||
|
||||
@@ -33,7 +33,11 @@ import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.IAudioService;
|
||||
import android.media.IVolumeController;
|
||||
import android.media.MediaRoute2Info;
|
||||
import android.media.MediaRouter2Manager;
|
||||
import android.media.RoutingSessionInfo;
|
||||
import android.media.VolumePolicy;
|
||||
import android.media.session.MediaController;
|
||||
import android.media.session.MediaController.PlaybackInfo;
|
||||
import android.media.session.MediaSession.Token;
|
||||
import android.net.Uri;
|
||||
@@ -71,6 +75,7 @@ import com.android.systemui.util.concurrency.ThreadFactory;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
@@ -118,6 +123,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
private final Context mContext;
|
||||
private final Looper mWorkerLooper;
|
||||
private final PackageManager mPackageManager;
|
||||
private final MediaRouter2Manager mRouter2Manager;
|
||||
private final WakefulnessLifecycle mWakefulnessLifecycle;
|
||||
private AudioManager mAudio;
|
||||
private IAudioService mAudioService;
|
||||
@@ -179,6 +185,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
mWorkerLooper = theadFactory.buildLooperOnNewThread(
|
||||
VolumeDialogControllerImpl.class.getSimpleName());
|
||||
mWorker = new W(mWorkerLooper);
|
||||
mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
|
||||
mMediaSessionsCallbacksW = new MediaSessionsCallbacks(mContext);
|
||||
mMediaSessions = createMediaSessions(mContext, mWorkerLooper, mMediaSessionsCallbacksW);
|
||||
mAudio = audioManager;
|
||||
@@ -1149,16 +1156,16 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
private final HashMap<Token, Integer> mRemoteStreams = new HashMap<>();
|
||||
|
||||
private int mNextStream = DYNAMIC_STREAM_START_INDEX;
|
||||
private final boolean mShowRemoteSessions;
|
||||
private final boolean mVolumeAdjustmentForRemoteGroupSessions;
|
||||
|
||||
public MediaSessionsCallbacks(Context context) {
|
||||
mShowRemoteSessions = context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_volumeShowRemoteSessions);
|
||||
mVolumeAdjustmentForRemoteGroupSessions = context.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemoteUpdate(Token token, String name, PlaybackInfo pi) {
|
||||
if (mShowRemoteSessions) {
|
||||
if (showForSession(token)) {
|
||||
addStream(token, "onRemoteUpdate");
|
||||
|
||||
int stream = 0;
|
||||
@@ -1190,7 +1197,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
|
||||
@Override
|
||||
public void onRemoteVolumeChanged(Token token, int flags) {
|
||||
if (mShowRemoteSessions) {
|
||||
if (showForSession(token)) {
|
||||
addStream(token, "onRemoteVolumeChanged");
|
||||
int stream = 0;
|
||||
synchronized (mRemoteStreams) {
|
||||
@@ -1214,7 +1221,7 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
|
||||
@Override
|
||||
public void onRemoteRemoved(Token token) {
|
||||
if (mShowRemoteSessions) {
|
||||
if (showForSession(token)) {
|
||||
int stream = 0;
|
||||
synchronized (mRemoteStreams) {
|
||||
if (!mRemoteStreams.containsKey(token)) {
|
||||
@@ -1233,14 +1240,41 @@ public class VolumeDialogControllerImpl implements VolumeDialogController, Dumpa
|
||||
}
|
||||
|
||||
public void setStreamVolume(int stream, int level) {
|
||||
if (mShowRemoteSessions) {
|
||||
final Token t = findToken(stream);
|
||||
if (t == null) {
|
||||
Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
|
||||
return;
|
||||
}
|
||||
mMediaSessions.setVolume(t, level);
|
||||
final Token token = findToken(stream);
|
||||
if (token == null) {
|
||||
Log.w(TAG, "setStreamVolume: No token found for stream: " + stream);
|
||||
return;
|
||||
}
|
||||
if (showForSession(token)) {
|
||||
mMediaSessions.setVolume(token, level);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean showForSession(Token token) {
|
||||
if (mVolumeAdjustmentForRemoteGroupSessions) {
|
||||
return true;
|
||||
}
|
||||
MediaController ctr = new MediaController(mContext, token);
|
||||
String packageName = ctr.getPackageName();
|
||||
List<RoutingSessionInfo> sessions =
|
||||
mRouter2Manager.getRoutingSessions(packageName);
|
||||
boolean foundNonSystemSession = false;
|
||||
boolean isGroup = false;
|
||||
for (RoutingSessionInfo session : sessions) {
|
||||
if (!session.isSystemSession()) {
|
||||
foundNonSystemSession = true;
|
||||
int selectedRouteCount = session.getSelectedRoutes().size();
|
||||
if (selectedRouteCount > 1) {
|
||||
isGroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundNonSystemSession) {
|
||||
Log.d(TAG, "No routing session for " + packageName);
|
||||
return false;
|
||||
}
|
||||
return !isGroup;
|
||||
}
|
||||
|
||||
private Token findToken(int stream) {
|
||||
|
||||
@@ -101,6 +101,11 @@ public class VolumeDialogControllerImplTest extends SysuiTestCase {
|
||||
// Initial non-set value
|
||||
when(mRingerModeLiveData.getValue()).thenReturn(-1);
|
||||
when(mRingerModeInternalLiveData.getValue()).thenReturn(-1);
|
||||
// Enable group volume adjustments
|
||||
mContext.getOrCreateTestableResources().addOverride(
|
||||
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions,
|
||||
true);
|
||||
|
||||
mCallback = mock(VolumeDialogControllerImpl.C.class);
|
||||
mThreadFactory.setLooper(TestableLooper.get(this).getLooper());
|
||||
mVolumeController = new TestableVolumeDialogControllerImpl(mContext,
|
||||
|
||||
@@ -145,6 +145,12 @@ public class MediaSession2Record implements MediaSessionRecordImpl {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandleVolumeKey() {
|
||||
// TODO: Implement when MediaSession2 starts to get key events.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSessionPolicies() {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -26,7 +26,9 @@ import android.media.AudioAttributes;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.MediaMetadata;
|
||||
import android.media.MediaRouter2Manager;
|
||||
import android.media.Rating;
|
||||
import android.media.RoutingSessionInfo;
|
||||
import android.media.VolumeProvider;
|
||||
import android.media.session.ISession;
|
||||
import android.media.session.ISessionCallback;
|
||||
@@ -50,6 +52,7 @@ import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.SystemClock;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
@@ -121,6 +124,7 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
|
||||
private final SessionCb mSessionCb;
|
||||
private final MediaSessionService mService;
|
||||
private final Context mContext;
|
||||
private final boolean mVolumeAdjustmentForRemoteGroupSessions;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final CopyOnWriteArrayList<ISessionControllerCallbackHolder>
|
||||
@@ -180,6 +184,8 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
|
||||
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
|
||||
mAudioAttrs = DEFAULT_ATTRIBUTES;
|
||||
mPolicies = policies;
|
||||
mVolumeAdjustmentForRemoteGroupSessions = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_volumeAdjustmentForRemoteGroupSessions);
|
||||
|
||||
// May throw RemoteException if the session app is killed.
|
||||
mSessionCb.mCb.asBinder().linkToDeath(this, 0);
|
||||
@@ -448,6 +454,33 @@ public class MediaSessionRecord implements IBinder.DeathRecipient, MediaSessionR
|
||||
cb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canHandleVolumeKey() {
|
||||
if (isPlaybackTypeLocal() || mVolumeAdjustmentForRemoteGroupSessions) {
|
||||
return true;
|
||||
}
|
||||
MediaRouter2Manager mRouter2Manager = MediaRouter2Manager.getInstance(mContext);
|
||||
List<RoutingSessionInfo> sessions =
|
||||
mRouter2Manager.getRoutingSessions(mPackageName);
|
||||
boolean foundNonSystemSession = false;
|
||||
boolean isGroup = false;
|
||||
for (RoutingSessionInfo session : sessions) {
|
||||
if (!session.isSystemSession()) {
|
||||
foundNonSystemSession = true;
|
||||
int selectedRouteCount = session.getSelectedRoutes().size();
|
||||
if (selectedRouteCount > 1) {
|
||||
isGroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!foundNonSystemSession) {
|
||||
Log.d(TAG, "No routing session for " + mPackageName);
|
||||
return false;
|
||||
}
|
||||
return !isGroup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSessionPolicies() {
|
||||
synchronized (mLock) {
|
||||
|
||||
@@ -130,6 +130,13 @@ public interface MediaSessionRecordImpl extends AutoCloseable {
|
||||
boolean sendMediaButton(String packageName, int pid, int uid, boolean asSystemService,
|
||||
KeyEvent ke, int sequenceId, ResultReceiver cb);
|
||||
|
||||
/**
|
||||
* Returns whether the media session can handle volume key events.
|
||||
*
|
||||
* @return True if this media session can handle volume key events, false otherwise.
|
||||
*/
|
||||
boolean canHandleVolumeKey();
|
||||
|
||||
/**
|
||||
* Get session policies from custom policy provider set when MediaSessionRecord is instantiated.
|
||||
* If custom policy does not exist, will return null.
|
||||
|
||||
@@ -325,8 +325,7 @@ class MediaSessionStack {
|
||||
int size = records.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
MediaSessionRecord record = records.get(i);
|
||||
// Do not send the volume key events to remote sessions.
|
||||
if (record.checkPlaybackActiveState(true) && record.isPlaybackTypeLocal()) {
|
||||
if (record.checkPlaybackActiveState(true) && record.canHandleVolumeKey()) {
|
||||
mCachedVolumeDefault = record;
|
||||
return record;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user