Loading packages/SettingsLib/src/com/android/settingslib/volume/D.java 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * 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); } packages/SystemUI/src/com/android/systemui/volume/MediaSessions.java→packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java +56 −43 Original line number Diff line number Diff line /* * 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. Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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) { Loading @@ -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() + " " 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; Loading Loading @@ -191,7 +205,8 @@ public class MediaSessions { if (appLabel.length() > 0) { return appLabel; } } catch (NameNotFoundException e) { } } catch (NameNotFoundException e) { } return pkg; } Loading Loading @@ -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; Loading @@ -274,8 +271,10 @@ public class MediaSessions { @Override public void onAudioInfoChanged(PlaybackInfo info) { if (D.BUG) Log.d(TAG, cb("onAudioInfoChanged") + Util.playbackInfoToString(info) 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()); Loading Loading @@ -332,14 +331,14 @@ public class MediaSessions { 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(); } Loading @@ -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); } Loading packages/SettingsLib/src/com/android/settingslib/volume/Util.java 0 → 100644 +187 −0 Original line number Diff line number Diff line /* * 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(); } } packages/SystemUI/src/com/android/systemui/volume/Util.java +9 −135 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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(); } } packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading
packages/SettingsLib/src/com/android/settingslib/volume/D.java 0 → 100644 +23 −0 Original line number Diff line number Diff line /* * 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); }
packages/SystemUI/src/com/android/systemui/volume/MediaSessions.java→packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java +56 −43 Original line number Diff line number Diff line /* * 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. Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading @@ -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) { Loading @@ -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() + " " 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; Loading Loading @@ -191,7 +205,8 @@ public class MediaSessions { if (appLabel.length() > 0) { return appLabel; } } catch (NameNotFoundException e) { } } catch (NameNotFoundException e) { } return pkg; } Loading Loading @@ -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; Loading @@ -274,8 +271,10 @@ public class MediaSessions { @Override public void onAudioInfoChanged(PlaybackInfo info) { if (D.BUG) Log.d(TAG, cb("onAudioInfoChanged") + Util.playbackInfoToString(info) 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()); Loading Loading @@ -332,14 +331,14 @@ public class MediaSessions { 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(); } Loading @@ -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); } Loading
packages/SettingsLib/src/com/android/settingslib/volume/Util.java 0 → 100644 +187 −0 Original line number Diff line number Diff line /* * 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(); } }
packages/SystemUI/src/com/android/systemui/volume/Util.java +9 −135 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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(); } }
packages/SystemUI/src/com/android/systemui/volume/VolumeDialogControllerImpl.java +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading