diff options
author | 2025-02-04 09:06:07 -0800 | |
---|---|---|
committer | 2025-02-04 09:06:07 -0800 | |
commit | 976910dcaa0f245dfb2d190ae370e56528c9342c (patch) | |
tree | 32db3cee01a13015d3d6c675166d3cdb1bcd3bec /packages/SettingsLib/src | |
parent | 63b7d688c1496460106d05d6623e05d5a01bb341 (diff) | |
parent | 1f01fadbfc9d0e898a532629dc2ca2d72d6c9023 (diff) |
Merge "Migrate the MediaSessions file to kotlin" into main
Diffstat (limited to 'packages/SettingsLib/src')
-rw-r--r-- | packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java | 402 | ||||
-rw-r--r-- | packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt | 364 |
2 files changed, 364 insertions, 402 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java deleted file mode 100644 index 89f3cf5e9aab..000000000000 --- a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.java +++ /dev/null @@ -1,402 +0,0 @@ -/* - * 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.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -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; -import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener; -import android.media.session.MediaSessionManager.RemoteSessionCallback; -import android.media.session.PlaybackState; -import android.os.Bundle; -import android.os.Handler; -import android.os.HandlerExecutor; -import android.os.Looper; -import android.os.Message; -import android.util.Log; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; - -/** - * Convenience client for all media session updates. Provides a callback interface for events - * related to remote media sessions. - */ -public class MediaSessions { - private static final String TAG = Util.logTag(MediaSessions.class); - - private static final boolean USE_SERVICE_LABEL = false; - - private final Context mContext; - private final H mHandler; - private final HandlerExecutor mHandlerExecutor; - private final MediaSessionManager mMgr; - private final Map<Token, MediaControllerRecord> mRecords = new HashMap<>(); - private final Callbacks mCallbacks; - - private boolean mInit; - - public MediaSessions(Context context, Looper looper, Callbacks callbacks) { - mContext = context; - mHandler = new H(looper); - mHandlerExecutor = new HandlerExecutor(mHandler); - mMgr = (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE); - 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()); - 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 - mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler); - mInit = true; - postUpdateSessions(); - mMgr.registerRemoteSessionCallback(mHandlerExecutor, - mRemoteSessionCallback); - } - - protected void postUpdateSessions() { - if (!mInit) return; - mHandler.sendEmptyMessage(H.UPDATE_SESSIONS); - } - - /** - * Destroy MediaSessions - */ - public void destroy() { - if (D.BUG) Log.d(TAG, "destroy"); - mInit = false; - mMgr.removeOnActiveSessionsChangedListener(mSessionsListener); - mMgr.unregisterRemoteSessionCallback(mRemoteSessionCallback); - } - - /** - * 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) { - Log.w(TAG, "setVolume: No record found for token " + token); - return; - } - if (D.BUG) Log.d(TAG, "Setting level to " + level); - r.controller.setVolumeTo(level, 0); - } - - 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)); - } - final Token token = controller.getSessionToken(); - mCallbacks.onRemoteVolumeChanged(token, flags); - } - - private void onUpdateRemoteSessionListH(Token sessionToken) { - final MediaController controller = - sessionToken != null ? new MediaController(mContext, sessionToken) : null; - final String pkg = controller != null ? controller.getPackageName() : null; - if (D.BUG) Log.d(TAG, "onUpdateRemoteSessionListH " + pkg); - // this may be our only indication that a remote session is changed, refresh - postUpdateSessions(); - } - - protected void onActiveSessionsUpdatedH(List<MediaController> controllers) { - if (D.BUG) Log.d(TAG, "onActiveSessionsUpdatedH n=" + controllers.size()); - final Set<Token> toRemove = new HashSet<Token>(mRecords.keySet()); - for (MediaController controller : controllers) { - final Token token = controller.getSessionToken(); - final PlaybackInfo pi = controller.getPlaybackInfo(); - toRemove.remove(token); - if (!mRecords.containsKey(token)) { - final MediaControllerRecord r = new MediaControllerRecord(controller); - r.name = getControllerName(controller); - mRecords.put(token, r); - controller.registerCallback(r, mHandler); - } - final MediaControllerRecord r = mRecords.get(token); - final boolean remote = isRemote(pi); - if (remote) { - updateRemoteH(token, r.name, pi); - r.sentRemote = true; - } - } - for (Token t : toRemove) { - final MediaControllerRecord r = mRecords.get(t); - r.controller.unregisterCallback(r); - mRecords.remove(t); - if (D.BUG) Log.d(TAG, "Removing " + r.name + " sentRemote=" + r.sentRemote); - if (r.sentRemote) { - mCallbacks.onRemoteRemoved(t); - r.sentRemote = false; - } - } - } - - private static boolean isRemote(PlaybackInfo pi) { - return pi != null && pi.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; - } - - protected String getControllerName(MediaController controller) { - final PackageManager pm = mContext.getPackageManager(); - final String pkg = controller.getPackageName(); - try { - if (USE_SERVICE_LABEL) { - final List<ResolveInfo> ris = pm.queryIntentServices( - new Intent("android.media.MediaRouteProviderService").setPackage(pkg), 0); - if (ris != null) { - for (ResolveInfo ri : ris) { - if (ri.serviceInfo == null) continue; - if (pkg.equals(ri.serviceInfo.packageName)) { - final String serviceLabel = - Objects.toString(ri.serviceInfo.loadLabel(pm), "").trim(); - if (serviceLabel.length() > 0) { - return serviceLabel; - } - } - } - } - } - final ApplicationInfo ai = pm.getApplicationInfo(pkg, 0); - final String appLabel = Objects.toString(ai.loadLabel(pm), "").trim(); - if (appLabel.length() > 0) { - return appLabel; - } - } catch (NameNotFoundException e) { - } - return pkg; - } - - private void updateRemoteH(Token token, String name, PlaybackInfo pi) { - if (mCallbacks != null) { - mCallbacks.onRemoteUpdate(token, name, pi); - } - } - - private static void dump(int n, PrintWriter writer, MediaController c) { - writer.println(" Controller " + n + ": " + c.getPackageName()); - final Bundle extras = c.getExtras(); - final long flags = c.getFlags(); - final MediaMetadata mm = c.getMetadata(); - final PlaybackInfo pi = c.getPlaybackInfo(); - final PlaybackState playbackState = c.getPlaybackState(); - final List<QueueItem> queue = c.getQueue(); - final CharSequence queueTitle = c.getQueueTitle(); - final int ratingType = c.getRatingType(); - final PendingIntent sessionActivity = c.getSessionActivity(); - - writer.println(" PlaybackState: " + Util.playbackStateToString(playbackState)); - writer.println(" PlaybackInfo: " + Util.playbackInfoToString(pi)); - if (mm != null) { - writer.println(" MediaMetadata.desc=" + mm.getDescription()); - } - writer.println(" RatingType: " + ratingType); - writer.println(" Flags: " + flags); - if (extras != null) { - writer.println(" Extras:"); - for (String key : extras.keySet()) { - writer.println(" " + key + "=" + extras.get(key)); - } - } - if (queueTitle != null) { - writer.println(" QueueTitle: " + queueTitle); - } - if (queue != null && !queue.isEmpty()) { - writer.println(" Queue:"); - for (QueueItem qi : queue) { - writer.println(" " + qi); - } - } - if (pi != null) { - writer.println(" sessionActivity: " + sessionActivity); - } - } - - private final class MediaControllerRecord extends MediaController.Callback { - public final MediaController controller; - - public boolean sentRemote; - public String name; - - private MediaControllerRecord(MediaController controller) { - this.controller = controller; - } - - private String cb(String method) { - return method + " " + controller.getPackageName() + " "; - } - - @Override - public void onAudioInfoChanged(@NonNull PlaybackInfo 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()); - sentRemote = false; - } else if (remote) { - updateRemoteH(controller.getSessionToken(), name, info); - sentRemote = true; - } - } - - @Override - public void onExtrasChanged(Bundle extras) { - if (D.BUG) Log.d(TAG, cb("onExtrasChanged") + extras); - } - - @Override - public void onMetadataChanged(MediaMetadata metadata) { - if (D.BUG) Log.d(TAG, cb("onMetadataChanged") + Util.mediaMetadataToString(metadata)); - } - - @Override - public void onPlaybackStateChanged(PlaybackState state) { - if (D.BUG) Log.d(TAG, cb("onPlaybackStateChanged") + Util.playbackStateToString(state)); - } - - @Override - public void onQueueChanged(List<QueueItem> queue) { - if (D.BUG) Log.d(TAG, cb("onQueueChanged") + queue); - } - - @Override - public void onQueueTitleChanged(CharSequence title) { - if (D.BUG) Log.d(TAG, cb("onQueueTitleChanged") + title); - } - - @Override - public void onSessionDestroyed() { - if (D.BUG) Log.d(TAG, cb("onSessionDestroyed")); - } - - @Override - public void onSessionEvent(String event, Bundle extras) { - if (D.BUG) Log.d(TAG, cb("onSessionEvent") + "event=" + event + " extras=" + extras); - } - } - - private final OnActiveSessionsChangedListener mSessionsListener = - new OnActiveSessionsChangedListener() { - @Override - public void onActiveSessionsChanged(List<MediaController> controllers) { - onActiveSessionsUpdatedH(controllers); - } - }; - - private final RemoteSessionCallback mRemoteSessionCallback = - new RemoteSessionCallback() { - @Override - public void onVolumeChanged(@NonNull MediaSession.Token sessionToken, - int flags) { - mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0, - sessionToken).sendToTarget(); - } - - @Override - public void onDefaultRemoteSessionChanged( - @Nullable MediaSession.Token sessionToken) { - mHandler.obtainMessage(H.UPDATE_REMOTE_SESSION_LIST, - sessionToken).sendToTarget(); - } - }; - - private final class H extends Handler { - private static final int UPDATE_SESSIONS = 1; - private static final int REMOTE_VOLUME_CHANGED = 2; - private static final int UPDATE_REMOTE_SESSION_LIST = 3; - - private H(Looper looper) { - super(looper); - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case UPDATE_SESSIONS: - onActiveSessionsUpdatedH(mMgr.getActiveSessions(null)); - break; - case REMOTE_VOLUME_CHANGED: - onRemoteVolumeChangedH((Token) msg.obj, msg.arg1); - break; - case UPDATE_REMOTE_SESSION_LIST: - onUpdateRemoteSessionListH((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); - } - -} diff --git a/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt new file mode 100644 index 000000000000..10156c404ebf --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/volume/MediaSessions.kt @@ -0,0 +1,364 @@ +/* + * Copyright 2025 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.content.Intent +import android.content.pm.PackageManager +import android.media.MediaMetadata +import android.media.session.MediaController +import android.media.session.MediaSession +import android.media.session.MediaSessionManager +import android.media.session.PlaybackState +import android.os.Bundle +import android.os.Handler +import android.os.HandlerExecutor +import android.os.Looper +import android.os.Message +import android.util.Log +import java.io.PrintWriter +import java.util.Objects + +/** + * Convenience client for all media session updates. Provides a callback interface for events + * related to remote media sessions. + */ +class MediaSessions(context: Context, looper: Looper, callbacks: Callbacks) { + + private val mContext = context + private val mHandler: H = H(looper) + private val mHandlerExecutor: HandlerExecutor = HandlerExecutor(mHandler) + private val mMgr: MediaSessionManager = + mContext.getSystemService(Context.MEDIA_SESSION_SERVICE) as MediaSessionManager + private val mRecords: MutableMap<MediaSession.Token, MediaControllerRecord> = HashMap() + private val mCallbacks: Callbacks = callbacks + private val mSessionsListener = + MediaSessionManager.OnActiveSessionsChangedListener { controllers -> + onActiveSessionsUpdatedH(controllers!!) + } + + private val mRemoteSessionCallback: MediaSessionManager.RemoteSessionCallback = + object : MediaSessionManager.RemoteSessionCallback { + override fun onVolumeChanged(sessionToken: MediaSession.Token, flags: Int) { + mHandler.obtainMessage(REMOTE_VOLUME_CHANGED, flags, 0, sessionToken).sendToTarget() + } + + override fun onDefaultRemoteSessionChanged(sessionToken: MediaSession.Token?) { + mHandler.obtainMessage(UPDATE_REMOTE_SESSION_LIST, sessionToken).sendToTarget() + } + } + + private var mInit = false + + /** Dump to `writer` */ + fun dump(writer: PrintWriter) { + writer.println(javaClass.simpleName + " state:") + writer.print(" mInit: ") + writer.println(mInit) + writer.print(" mRecords.size: ") + writer.println(mRecords.size) + for ((i, r) in mRecords.values.withIndex()) { + r.controller.dump(i + 1, writer) + } + } + + /** init MediaSessions */ + fun init() { + if (D.BUG) { + Log.d(TAG, "init") + } + // will throw if no permission + mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler) + mInit = true + postUpdateSessions() + mMgr.registerRemoteSessionCallback(mHandlerExecutor, mRemoteSessionCallback) + } + + /** Destroy MediaSessions */ + fun destroy() { + if (D.BUG) { + Log.d(TAG, "destroy") + } + mInit = false + mMgr.removeOnActiveSessionsChangedListener(mSessionsListener) + mMgr.unregisterRemoteSessionCallback(mRemoteSessionCallback) + } + + /** Set volume `level` to remote media `token` */ + fun setVolume(token: MediaSession.Token, level: Int) { + val record = mRecords[token] + if (record == null) { + Log.w(TAG, "setVolume: No record found for token $token") + return + } + if (D.BUG) { + Log.d(TAG, "Setting level to $level") + } + record.controller.setVolumeTo(level, 0) + } + + private fun onRemoteVolumeChangedH(sessionToken: MediaSession.Token, flags: Int) { + val controller = MediaController(mContext, sessionToken) + if (D.BUG) { + Log.d( + TAG, + "remoteVolumeChangedH " + + controller.packageName + + " " + + Util.audioManagerFlagsToString(flags), + ) + } + val token = controller.sessionToken + mCallbacks.onRemoteVolumeChanged(token, flags) + } + + private fun onUpdateRemoteSessionListH(sessionToken: MediaSession.Token?) { + if (D.BUG) { + Log.d( + TAG, + "onUpdateRemoteSessionListH ${sessionToken?.let {MediaController(mContext, it)}?.packageName}", + ) + } + // this may be our only indication that a remote session is changed, refresh + postUpdateSessions() + } + + private fun postUpdateSessions() { + if (mInit) { + mHandler.sendEmptyMessage(UPDATE_SESSIONS) + } + } + + private fun onActiveSessionsUpdatedH(controllers: List<MediaController>) { + if (D.BUG) { + Log.d(TAG, "onActiveSessionsUpdatedH n=" + controllers.size) + } + val toRemove: MutableSet<MediaSession.Token> = HashSet(mRecords.keys) + for (controller in controllers) { + val token = controller.sessionToken + val playbackInfo = controller.playbackInfo + toRemove.remove(token) + if (!mRecords.containsKey(token)) { + val record = MediaControllerRecord(controller) + record.name = getControllerName(controller) + mRecords[token] = record + controller.registerCallback(record, mHandler) + } + val record = mRecords[token] + val remote = isRemote(playbackInfo) + if (remote) { + updateRemoteH(token, record!!.name, playbackInfo) + record.sentRemote = true + } + } + for (token in toRemove) { + val record = mRecords[token]!! + record.controller.unregisterCallback(record) + mRecords.remove(token) + if (D.BUG) { + Log.d(TAG, "Removing " + record.name + " sentRemote=" + record.sentRemote) + } + if (record.sentRemote) { + mCallbacks.onRemoteRemoved(token) + record.sentRemote = false + } + } + } + + private fun getControllerName(controller: MediaController): String { + val pm = mContext.packageManager + val pkg = controller.packageName + try { + if (USE_SERVICE_LABEL) { + val services = + pm.queryIntentServices( + Intent("android.media.MediaRouteProviderService").setPackage(pkg), + 0, + ) + if (services != null) { + for (ri in services) { + if (ri.serviceInfo == null) continue + if (pkg == ri.serviceInfo.packageName) { + val serviceLabel = + Objects.toString(ri.serviceInfo.loadLabel(pm), "").trim() + if (serviceLabel.isNotEmpty()) { + return serviceLabel + } + } + } + } + } + val ai = pm.getApplicationInfo(pkg, 0) + val appLabel = Objects.toString(ai.loadLabel(pm), "").trim { it <= ' ' } + if (appLabel.isNotEmpty()) { + return appLabel + } + } catch (_: PackageManager.NameNotFoundException) {} + return pkg + } + + private fun updateRemoteH( + token: MediaSession.Token, + name: String?, + pi: MediaController.PlaybackInfo, + ) = mCallbacks.onRemoteUpdate(token, name, pi) + + private inner class MediaControllerRecord(val controller: MediaController) : + MediaController.Callback() { + var sentRemote: Boolean = false + var name: String? = null + + fun cb(method: String): String { + return method + " " + controller.packageName + " " + } + + override fun onAudioInfoChanged(info: MediaController.PlaybackInfo) { + if (D.BUG) { + Log.d( + TAG, + (cb("onAudioInfoChanged") + + Util.playbackInfoToString(info) + + " sentRemote=" + + sentRemote), + ) + } + val remote = isRemote(info) + if (!remote && sentRemote) { + mCallbacks.onRemoteRemoved(controller.sessionToken) + sentRemote = false + } else if (remote) { + updateRemoteH(controller.sessionToken, name, info) + sentRemote = true + } + } + + override fun onExtrasChanged(extras: Bundle?) { + if (D.BUG) { + Log.d(TAG, cb("onExtrasChanged") + extras) + } + } + + override fun onMetadataChanged(metadata: MediaMetadata?) { + if (D.BUG) { + Log.d(TAG, cb("onMetadataChanged") + Util.mediaMetadataToString(metadata)) + } + } + + override fun onPlaybackStateChanged(state: PlaybackState?) { + if (D.BUG) { + Log.d(TAG, cb("onPlaybackStateChanged") + Util.playbackStateToString(state)) + } + } + + override fun onQueueChanged(queue: List<MediaSession.QueueItem>?) { + if (D.BUG) { + Log.d(TAG, cb("onQueueChanged") + queue) + } + } + + override fun onQueueTitleChanged(title: CharSequence?) { + if (D.BUG) { + Log.d(TAG, cb("onQueueTitleChanged") + title) + } + } + + override fun onSessionDestroyed() { + if (D.BUG) { + Log.d(TAG, cb("onSessionDestroyed")) + } + } + + override fun onSessionEvent(event: String, extras: Bundle?) { + if (D.BUG) { + Log.d(TAG, cb("onSessionEvent") + "event=" + event + " extras=" + extras) + } + } + } + + private inner class H(looper: Looper) : Handler(looper) { + + override fun handleMessage(msg: Message) { + when (msg.what) { + UPDATE_SESSIONS -> onActiveSessionsUpdatedH(mMgr.getActiveSessions(null)) + REMOTE_VOLUME_CHANGED -> + onRemoteVolumeChangedH(msg.obj as MediaSession.Token, msg.arg1) + UPDATE_REMOTE_SESSION_LIST -> + onUpdateRemoteSessionListH(msg.obj as MediaSession.Token?) + } + } + } + + /** Callback for remote media sessions */ + interface Callbacks { + /** Invoked when remote media session is updated */ + fun onRemoteUpdate( + token: MediaSession.Token?, + name: String?, + pi: MediaController.PlaybackInfo?, + ) + + /** Invoked when remote media session is removed */ + fun onRemoteRemoved(token: MediaSession.Token?) + + /** Invoked when remote volume is changed */ + fun onRemoteVolumeChanged(token: MediaSession.Token?, flags: Int) + } + + companion object { + private val TAG: String = Util.logTag(MediaSessions::class.java) + + const val UPDATE_SESSIONS: Int = 1 + const val REMOTE_VOLUME_CHANGED: Int = 2 + const val UPDATE_REMOTE_SESSION_LIST: Int = 3 + + private const val USE_SERVICE_LABEL = false + + private fun isRemote(pi: MediaController.PlaybackInfo?): Boolean = + pi != null && pi.playbackType == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE + } +} + +private fun MediaController.dump(n: Int, writer: PrintWriter) { + writer.println(" Controller $n: $packageName") + + writer.println(" PlaybackState: ${Util.playbackStateToString(playbackState)}") + writer.println(" PlaybackInfo: ${Util.playbackInfoToString(playbackInfo)}") + val metadata = this.metadata + if (metadata != null) { + writer.println(" MediaMetadata.desc=${metadata.description}") + } + writer.println(" RatingType: $ratingType") + writer.println(" Flags: $flags") + + writer.println(" Extras:") + val extras = this.extras + if (extras == null) { + writer.println(" <null>") + } else { + for (key in extras.keySet()) { + writer.println(" $key=${extras[key]}") + } + } + writer.println(" QueueTitle: $queueTitle") + val queue = this.queue + if (!queue.isNullOrEmpty()) { + writer.println(" Queue:") + for (qi in queue) { + writer.println(" $qi") + } + } + writer.println(" sessionActivity: $sessionActivity") +} |