Move MediaSessions from systemui to settingslib

Also add javadocs to pass style check

Bug: 126199571
Test: Build
Change-Id: I78389834760e12fb73b0ae1c8565b8c5d42a5789
This commit is contained in:
jackqdyulei
2019-02-26 13:34:27 -08:00
parent 885c9e7acc
commit 2d7de480a4
5 changed files with 276 additions and 178 deletions

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2019 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.settingslib.volume;
import android.util.Log;
class D {
public static boolean BUG = Log.isLoggable("volume", Log.DEBUG);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* Copyright (C) 2019 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.systemui.volume;
package com.android.settingslib.volume;
import android.app.PendingIntent;
import android.content.Context;
@@ -27,7 +27,6 @@ import android.media.IRemoteVolumeController;
import android.media.MediaMetadata;
import android.media.session.MediaController;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.MediaSession;
import android.media.session.MediaSession.QueueItem;
import android.media.session.MediaSession.Token;
import android.media.session.MediaSessionManager;
@@ -41,7 +40,6 @@ import android.os.RemoteException;
import android.util.Log;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -73,16 +71,24 @@ public class MediaSessions {
mCallbacks = callbacks;
}
/**
* Dump to {@code writer}
*/
public void dump(PrintWriter writer) {
writer.println(getClass().getSimpleName() + " state:");
writer.print(" mInit: "); writer.println(mInit);
writer.print(" mRecords.size: "); writer.println(mRecords.size());
writer.print(" mInit: ");
writer.println(mInit);
writer.print(" mRecords.size: ");
writer.println(mRecords.size());
int i = 0;
for (MediaControllerRecord r : mRecords.values()) {
dump(++i, writer, r.controller);
}
}
/**
* init MediaSessions
*/
public void init() {
if (D.BUG) Log.d(TAG, "init");
// will throw if no permission
@@ -97,12 +103,18 @@ public class MediaSessions {
mHandler.sendEmptyMessage(H.UPDATE_SESSIONS);
}
/**
* Destroy MediaSessions
*/
public void destroy() {
if (D.BUG) Log.d(TAG, "destroy");
mInit = false;
mMgr.removeOnActiveSessionsChangedListener(mSessionsListener);
}
/**
* Set volume {@code level} to remote media {@code token}
*/
public void setVolume(Token token, int level) {
final MediaControllerRecord r = mRecords.get(token);
if (r == null) {
@@ -113,15 +125,17 @@ public class MediaSessions {
r.controller.setVolumeTo(level, 0);
}
private void onRemoteVolumeChangedH(MediaSession.Token sessionToken, int flags) {
private void onRemoteVolumeChangedH(Token sessionToken, int flags) {
final MediaController controller = new MediaController(mContext, sessionToken);
if (D.BUG) Log.d(TAG, "remoteVolumeChangedH " + controller.getPackageName() + " "
+ Util.audioManagerFlagsToString(flags));
if (D.BUG) {
Log.d(TAG, "remoteVolumeChangedH " + controller.getPackageName() + " "
+ Util.audioManagerFlagsToString(flags));
}
final Token token = controller.getSessionToken();
mCallbacks.onRemoteVolumeChanged(token, flags);
}
private void onUpdateRemoteControllerH(MediaSession.Token sessionToken) {
private void onUpdateRemoteControllerH(Token sessionToken) {
final MediaController controller =
sessionToken != null ? new MediaController(mContext, sessionToken) : null;
final String pkg = controller != null ? controller.getPackageName() : null;
@@ -191,7 +205,8 @@ public class MediaSessions {
if (appLabel.length() > 0) {
return appLabel;
}
} catch (NameNotFoundException e) { }
} catch (NameNotFoundException e) {
}
return pkg;
}
@@ -240,29 +255,11 @@ public class MediaSessions {
}
}
public static void dumpMediaSessions(Context context) {
final MediaSessionManager mgr = (MediaSessionManager) context
.getSystemService(Context.MEDIA_SESSION_SERVICE);
try {
final List<MediaController> controllers = mgr.getActiveSessions(null);
final int N = controllers.size();
if (D.BUG) Log.d(TAG, N + " controllers");
for (int i = 0; i < N; i++) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
dump(i + 1, pw, controllers.get(i));
if (D.BUG) Log.d(TAG, sw.toString());
}
} catch (SecurityException e) {
Log.w(TAG, "Not allowed to get sessions", e);
}
}
private final class MediaControllerRecord extends MediaController.Callback {
private final MediaController controller;
public final MediaController controller;
private boolean sentRemote;
private String name;
public boolean sentRemote;
public String name;
private MediaControllerRecord(MediaController controller) {
this.controller = controller;
@@ -274,8 +271,10 @@ public class MediaSessions {
@Override
public void onAudioInfoChanged(PlaybackInfo info) {
if (D.BUG) Log.d(TAG, cb("onAudioInfoChanged") + Util.playbackInfoToString(info)
+ " sentRemote=" + sentRemote);
if (D.BUG) {
Log.d(TAG, cb("onAudioInfoChanged") + Util.playbackInfoToString(info)
+ " sentRemote=" + sentRemote);
}
final boolean remote = isRemote(info);
if (!remote && sentRemote) {
mCallbacks.onRemoteRemoved(controller.getSessionToken());
@@ -324,22 +323,22 @@ public class MediaSessions {
private final OnActiveSessionsChangedListener mSessionsListener =
new OnActiveSessionsChangedListener() {
@Override
public void onActiveSessionsChanged(List<MediaController> controllers) {
onActiveSessionsUpdatedH(controllers);
}
};
@Override
public void onActiveSessionsChanged(List<MediaController> controllers) {
onActiveSessionsUpdatedH(controllers);
}
};
private final IRemoteVolumeController mRvc = new IRemoteVolumeController.Stub() {
@Override
public void remoteVolumeChanged(MediaSession.Token sessionToken, int flags)
public void remoteVolumeChanged(Token sessionToken, int flags)
throws RemoteException {
mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
sessionToken).sendToTarget();
}
@Override
public void updateRemoteController(final MediaSession.Token sessionToken)
public void updateRemoteController(final Token sessionToken)
throws RemoteException {
mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
}
@@ -361,18 +360,32 @@ public class MediaSessions {
onActiveSessionsUpdatedH(mMgr.getActiveSessions(null));
break;
case REMOTE_VOLUME_CHANGED:
onRemoteVolumeChangedH((MediaSession.Token) msg.obj, msg.arg1);
onRemoteVolumeChangedH((Token) msg.obj, msg.arg1);
break;
case UPDATE_REMOTE_CONTROLLER:
onUpdateRemoteControllerH((MediaSession.Token) msg.obj);
onUpdateRemoteControllerH((Token) msg.obj);
break;
}
}
}
/**
* Callback for remote media sessions
*/
public interface Callbacks {
/**
* Invoked when remote media session is updated
*/
void onRemoteUpdate(Token token, String name, PlaybackInfo pi);
/**
* Invoked when remote media session is removed
*/
void onRemoteRemoved(Token t);
/**
* Invoked when remote volume is changed
*/
void onRemoteVolumeChanged(Token token, int flags);
}

View File

@@ -0,0 +1,187 @@
/*
* Copyright (C) 2019 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.settingslib.volume;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.VolumeProvider;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.PlaybackState;
import android.telephony.TelephonyManager;
import android.widget.TextView;
import java.util.Objects;
/**
* Static helpers for the volume dialog.
*/
public class Util {
private static final int[] AUDIO_MANAGER_FLAGS = new int[]{
AudioManager.FLAG_SHOW_UI,
AudioManager.FLAG_VIBRATE,
AudioManager.FLAG_PLAY_SOUND,
AudioManager.FLAG_ALLOW_RINGER_MODES,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE,
AudioManager.FLAG_SHOW_VIBRATE_HINT,
AudioManager.FLAG_SHOW_SILENT_HINT,
AudioManager.FLAG_FROM_KEY,
AudioManager.FLAG_SHOW_UI_WARNINGS,
};
private static final String[] AUDIO_MANAGER_FLAG_NAMES = new String[]{
"SHOW_UI",
"VIBRATE",
"PLAY_SOUND",
"ALLOW_RINGER_MODES",
"REMOVE_SOUND_AND_VIBRATE",
"SHOW_VIBRATE_HINT",
"SHOW_SILENT_HINT",
"FROM_KEY",
"SHOW_UI_WARNINGS",
};
/**
* Extract log tag from {@code c}
*/
public static String logTag(Class<?> c) {
final String tag = "vol." + c.getSimpleName();
return tag.length() < 23 ? tag : tag.substring(0, 23);
}
/**
* Convert media metadata to string
*/
public static String mediaMetadataToString(MediaMetadata metadata) {
if (metadata == null) return null;
return metadata.getDescription().toString();
}
/**
* Convert playback info to string
*/
public static String playbackInfoToString(PlaybackInfo info) {
if (info == null) return null;
final String type = playbackInfoTypeToString(info.getPlaybackType());
final String vc = volumeProviderControlToString(info.getVolumeControl());
return String.format("PlaybackInfo[vol=%s,max=%s,type=%s,vc=%s],atts=%s",
info.getCurrentVolume(), info.getMaxVolume(), type, vc, info.getAudioAttributes());
}
/**
* Convert type of playback info to string
*/
public static String playbackInfoTypeToString(int type) {
switch (type) {
case PlaybackInfo.PLAYBACK_TYPE_LOCAL:
return "LOCAL";
case PlaybackInfo.PLAYBACK_TYPE_REMOTE:
return "REMOTE";
default:
return "UNKNOWN_" + type;
}
}
/**
* Convert state of playback info to string
*/
public static String playbackStateStateToString(int state) {
switch (state) {
case PlaybackState.STATE_NONE:
return "STATE_NONE";
case PlaybackState.STATE_STOPPED:
return "STATE_STOPPED";
case PlaybackState.STATE_PAUSED:
return "STATE_PAUSED";
case PlaybackState.STATE_PLAYING:
return "STATE_PLAYING";
default:
return "UNKNOWN_" + state;
}
}
/**
* Convert volume provider control to string
*/
public static String volumeProviderControlToString(int control) {
switch (control) {
case VolumeProvider.VOLUME_CONTROL_ABSOLUTE:
return "VOLUME_CONTROL_ABSOLUTE";
case VolumeProvider.VOLUME_CONTROL_FIXED:
return "VOLUME_CONTROL_FIXED";
case VolumeProvider.VOLUME_CONTROL_RELATIVE:
return "VOLUME_CONTROL_RELATIVE";
default:
return "VOLUME_CONTROL_UNKNOWN_" + control;
}
}
/**
* Convert {@link PlaybackState} to string
*/
public static String playbackStateToString(PlaybackState playbackState) {
if (playbackState == null) return null;
return playbackStateStateToString(playbackState.getState()) + " " + playbackState;
}
/**
* Convert audio manager flags to string
*/
public static String audioManagerFlagsToString(int value) {
return bitFieldToString(value, AUDIO_MANAGER_FLAGS, AUDIO_MANAGER_FLAG_NAMES);
}
protected static String bitFieldToString(int value, int[] values, String[] names) {
if (value == 0) return "";
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if ((value & values[i]) != 0) {
if (sb.length() > 0) sb.append(',');
sb.append(names[i]);
}
value &= ~values[i];
}
if (value != 0) {
if (sb.length() > 0) sb.append(',');
sb.append("UNKNOWN_").append(value);
}
return sb.toString();
}
private static CharSequence emptyToNull(CharSequence str) {
return str == null || str.length() == 0 ? null : str;
}
/**
* Set text for specific {@link TextView}
*/
public static boolean setText(TextView tv, CharSequence text) {
if (Objects.equals(emptyToNull(tv.getText()), emptyToNull(text))) return false;
tv.setText(text);
return true;
}
/**
* Return {@code true} if it is voice capable
*/
public static boolean isVoiceCapable(Context context) {
final TelephonyManager telephony =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return telephony != null && telephony.isVoiceCapable();
}
}

View File

@@ -16,52 +16,13 @@
package com.android.systemui.volume;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.VolumeProvider;
import android.media.session.MediaController.PlaybackInfo;
import android.media.session.PlaybackState;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.TextView;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Objects;
/**
* Static helpers for the volume dialog.
*/
class Util {
// Note: currently not shown (only used in the text footer)
private static final SimpleDateFormat HMMAA = new SimpleDateFormat("h:mm aa", Locale.US);
private static int[] AUDIO_MANAGER_FLAGS = new int[] {
AudioManager.FLAG_SHOW_UI,
AudioManager.FLAG_VIBRATE,
AudioManager.FLAG_PLAY_SOUND,
AudioManager.FLAG_ALLOW_RINGER_MODES,
AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE,
AudioManager.FLAG_SHOW_VIBRATE_HINT,
AudioManager.FLAG_SHOW_SILENT_HINT,
AudioManager.FLAG_FROM_KEY,
AudioManager.FLAG_SHOW_UI_WARNINGS,
};
private static String[] AUDIO_MANAGER_FLAG_NAMES = new String[] {
"SHOW_UI",
"VIBRATE",
"PLAY_SOUND",
"ALLOW_RINGER_MODES",
"REMOVE_SOUND_AND_VIBRATE",
"SHOW_VIBRATE_HINT",
"SHOW_SILENT_HINT",
"FROM_KEY",
"SHOW_UI_WARNINGS",
};
class Util extends com.android.settingslib.volume.Util {
public static String logTag(Class<?> c) {
final String tag = "vol." + c.getSimpleName();
@@ -70,106 +31,19 @@ class Util {
public static String ringerModeToString(int ringerMode) {
switch (ringerMode) {
case AudioManager.RINGER_MODE_SILENT: return "RINGER_MODE_SILENT";
case AudioManager.RINGER_MODE_VIBRATE: return "RINGER_MODE_VIBRATE";
case AudioManager.RINGER_MODE_NORMAL: return "RINGER_MODE_NORMAL";
default: return "RINGER_MODE_UNKNOWN_" + ringerMode;
case AudioManager.RINGER_MODE_SILENT:
return "RINGER_MODE_SILENT";
case AudioManager.RINGER_MODE_VIBRATE:
return "RINGER_MODE_VIBRATE";
case AudioManager.RINGER_MODE_NORMAL:
return "RINGER_MODE_NORMAL";
default:
return "RINGER_MODE_UNKNOWN_" + ringerMode;
}
}
public static String mediaMetadataToString(MediaMetadata metadata) {
if (metadata == null) return null;
return metadata.getDescription().toString();
}
public static String playbackInfoToString(PlaybackInfo info) {
if (info == null) return null;
final String type = playbackInfoTypeToString(info.getPlaybackType());
final String vc = volumeProviderControlToString(info.getVolumeControl());
return String.format("PlaybackInfo[vol=%s,max=%s,type=%s,vc=%s],atts=%s",
info.getCurrentVolume(), info.getMaxVolume(), type, vc, info.getAudioAttributes());
}
public static String playbackInfoTypeToString(int type) {
switch (type) {
case PlaybackInfo.PLAYBACK_TYPE_LOCAL: return "LOCAL";
case PlaybackInfo.PLAYBACK_TYPE_REMOTE: return "REMOTE";
default: return "UNKNOWN_" + type;
}
}
public static String playbackStateStateToString(int state) {
switch (state) {
case PlaybackState.STATE_NONE: return "STATE_NONE";
case PlaybackState.STATE_STOPPED: return "STATE_STOPPED";
case PlaybackState.STATE_PAUSED: return "STATE_PAUSED";
case PlaybackState.STATE_PLAYING: return "STATE_PLAYING";
default: return "UNKNOWN_" + state;
}
}
public static String volumeProviderControlToString(int control) {
switch (control) {
case VolumeProvider.VOLUME_CONTROL_ABSOLUTE: return "VOLUME_CONTROL_ABSOLUTE";
case VolumeProvider.VOLUME_CONTROL_FIXED: return "VOLUME_CONTROL_FIXED";
case VolumeProvider.VOLUME_CONTROL_RELATIVE: return "VOLUME_CONTROL_RELATIVE";
default: return "VOLUME_CONTROL_UNKNOWN_" + control;
}
}
public static String playbackStateToString(PlaybackState playbackState) {
if (playbackState == null) return null;
return playbackStateStateToString(playbackState.getState()) + " " + playbackState;
}
public static String audioManagerFlagsToString(int value) {
return bitFieldToString(value, AUDIO_MANAGER_FLAGS, AUDIO_MANAGER_FLAG_NAMES);
}
private static String bitFieldToString(int value, int[] values, String[] names) {
if (value == 0) return "";
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < values.length; i++) {
if ((value & values[i]) != 0) {
if (sb.length() > 0) sb.append(',');
sb.append(names[i]);
}
value &= ~values[i];
}
if (value != 0) {
if (sb.length() > 0) sb.append(',');
sb.append("UNKNOWN_").append(value);
}
return sb.toString();
}
public static String getShortTime(long millis) {
return HMMAA.format(new Date(millis));
}
private static CharSequence emptyToNull(CharSequence str) {
return str == null || str.length() == 0 ? null : str;
}
public static boolean setText(TextView tv, CharSequence text) {
if (Objects.equals(emptyToNull(tv.getText()), emptyToNull(text))) return false;
tv.setText(text);
return true;
}
public static final void setVisOrGone(View v, boolean vis) {
if (v == null || (v.getVisibility() == View.VISIBLE) == vis) return;
v.setVisibility(vis ? View.VISIBLE : View.GONE);
}
public static final void setVisOrInvis(View v, boolean vis) {
if (v == null || (v.getVisibility() == View.VISIBLE) == vis) return;
v.setVisibility(vis ? View.VISIBLE : View.INVISIBLE);
}
public static boolean isVoiceCapable(Context context) {
final TelephonyManager telephony =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return telephony != null && telephony.isVoiceCapable();
}
}

View File

@@ -53,6 +53,7 @@ import android.util.Log;
import android.view.accessibility.AccessibilityManager;
import com.android.internal.annotations.GuardedBy;
import com.android.settingslib.volume.MediaSessions;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;