Merge "Expose remote volume controller-related APIs" am: ed942b0cd9
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/12927655 Change-Id: Ia722d5598a1172d7850d8b1991181fea54c60df9
This commit is contained in:
229
api/module-lib-current.txt
Normal file
229
api/module-lib-current.txt
Normal file
@@ -0,0 +1,229 @@
|
||||
// Signature format: 2.0
|
||||
package android.app {
|
||||
|
||||
public class ActivityManager {
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
|
||||
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
|
||||
}
|
||||
|
||||
public class AppOpsManager {
|
||||
field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
|
||||
}
|
||||
|
||||
public abstract class HomeVisibilityListener {
|
||||
ctor public HomeVisibilityListener();
|
||||
method public abstract void onHomeVisibilityChanged(boolean);
|
||||
}
|
||||
|
||||
public class NotificationManager {
|
||||
method public boolean hasEnabledNotificationListener(@NonNull String, @NonNull android.os.UserHandle);
|
||||
field public static final String ACTION_NOTIFICATION_LISTENER_ENABLED_CHANGED = "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED";
|
||||
}
|
||||
|
||||
public class StatusBarManager {
|
||||
method @RequiresPermission(android.Manifest.permission.STATUS_BAR) public void setExpansionDisabledForSimNetworkLock(boolean);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.app.role {
|
||||
|
||||
public final class RoleManager {
|
||||
method @Nullable public String getSmsRoleHolder(int);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.content.rollback {
|
||||
|
||||
public class RollbackManagerFrameworkInitializer {
|
||||
method public static void initialize();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.graphics {
|
||||
|
||||
public final class Compatibility {
|
||||
method public static void setTargetSdkVersion(int);
|
||||
}
|
||||
|
||||
public final class ImageDecoder implements java.lang.AutoCloseable {
|
||||
method @AnyThread @NonNull public static android.graphics.ImageDecoder.Source createSource(@NonNull android.content.ContentResolver, @NonNull android.net.Uri, @Nullable android.content.res.Resources);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.media {
|
||||
|
||||
public class AudioManager {
|
||||
method public void adjustStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
|
||||
method public void adjustSuggestedStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
|
||||
method public void setStreamVolumeForUid(int, int, int, @NonNull String, int, int, int);
|
||||
field public static final int FLAG_FROM_KEY = 4096; // 0x1000
|
||||
}
|
||||
|
||||
public class MediaMetadataRetriever implements java.lang.AutoCloseable {
|
||||
field public static final int METADATA_KEY_VIDEO_CODEC_MIME_TYPE = 40; // 0x28
|
||||
}
|
||||
|
||||
@Deprecated public final class MediaParceledListSlice<T extends android.os.Parcelable> implements android.os.Parcelable {
|
||||
ctor @Deprecated public MediaParceledListSlice(@NonNull java.util.List<T>);
|
||||
method @Deprecated public int describeContents();
|
||||
method @Deprecated @NonNull public static <T extends android.os.Parcelable> android.media.MediaParceledListSlice<T> emptyList();
|
||||
method @Deprecated public java.util.List<T> getList();
|
||||
method @Deprecated public void setInlineCountLimit(int);
|
||||
method @Deprecated public void writeToParcel(android.os.Parcel, int);
|
||||
field @Deprecated @NonNull public static final android.os.Parcelable.ClassLoaderCreator<android.media.MediaParceledListSlice> CREATOR;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.media.session {
|
||||
|
||||
public static final class MediaController.PlaybackInfo implements android.os.Parcelable {
|
||||
ctor public MediaController.PlaybackInfo(int, int, @IntRange(from=0) int, @IntRange(from=0) int, @NonNull android.media.AudioAttributes, @Nullable String);
|
||||
}
|
||||
|
||||
public final class MediaSession {
|
||||
field public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 65536; // 0x10000
|
||||
}
|
||||
|
||||
public static final class MediaSession.Token implements android.os.Parcelable {
|
||||
method public int getUid();
|
||||
}
|
||||
|
||||
public final class MediaSessionManager {
|
||||
method public void addOnActiveSessionsChangedListener(@NonNull android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, @Nullable android.content.ComponentName, int, @Nullable android.os.Handler);
|
||||
method public void dispatchMediaKeyEventAsSystemService(@NonNull android.view.KeyEvent);
|
||||
method public boolean dispatchMediaKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
|
||||
method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
|
||||
method public void dispatchVolumeKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
|
||||
method public void registerRemoteVolumeControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
|
||||
method public void unregisterRemoteVolumeControllerCallback(@NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
|
||||
field public static final int RESULT_MEDIA_KEY_HANDLED = 1; // 0x1
|
||||
field public static final int RESULT_MEDIA_KEY_NOT_HANDLED = 0; // 0x0
|
||||
}
|
||||
|
||||
public static interface MediaSessionManager.RemoteVolumeControllerCallback {
|
||||
method public void onSessionChanged(@Nullable android.media.session.MediaSession.Token);
|
||||
method public void onVolumeChanged(@NonNull android.media.session.MediaSession.Token, int);
|
||||
}
|
||||
|
||||
public final class PlaybackState implements android.os.Parcelable {
|
||||
method public boolean isActiveState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.net {
|
||||
|
||||
public final class TetheringConstants {
|
||||
field public static final String EXTRA_ADD_TETHER_TYPE = "extraAddTetherType";
|
||||
field public static final String EXTRA_PROVISION_CALLBACK = "extraProvisionCallback";
|
||||
field public static final String EXTRA_REM_TETHER_TYPE = "extraRemTetherType";
|
||||
field public static final String EXTRA_RUN_PROVISION = "extraRunProvision";
|
||||
field public static final String EXTRA_SET_ALARM = "extraSetAlarm";
|
||||
}
|
||||
|
||||
public class TetheringManager {
|
||||
ctor public TetheringManager(@NonNull android.content.Context, @NonNull java.util.function.Supplier<android.os.IBinder>);
|
||||
method public int getLastTetherError(@NonNull String);
|
||||
method @NonNull public String[] getTetherableBluetoothRegexs();
|
||||
method @NonNull public String[] getTetherableIfaces();
|
||||
method @NonNull public String[] getTetherableUsbRegexs();
|
||||
method @NonNull public String[] getTetherableWifiRegexs();
|
||||
method @NonNull public String[] getTetheredIfaces();
|
||||
method @NonNull public String[] getTetheringErroredIfaces();
|
||||
method public boolean isTetheringSupported();
|
||||
method public boolean isTetheringSupported(@NonNull String);
|
||||
method public void requestLatestTetheringEntitlementResult(int, @NonNull android.os.ResultReceiver, boolean);
|
||||
method @Deprecated public int setUsbTethering(boolean);
|
||||
method @RequiresPermission(anyOf={android.Manifest.permission.TETHER_PRIVILEGED, android.Manifest.permission.WRITE_SETTINGS}) public void startTethering(int, @NonNull java.util.concurrent.Executor, @NonNull android.net.TetheringManager.StartTetheringCallback);
|
||||
method @Deprecated public int tether(@NonNull String);
|
||||
method @Deprecated public int untether(@NonNull String);
|
||||
}
|
||||
|
||||
public static interface TetheringManager.TetheringEventCallback {
|
||||
method public default void onTetherableInterfaceRegexpsChanged(@NonNull android.net.TetheringManager.TetheringInterfaceRegexps);
|
||||
}
|
||||
|
||||
public static class TetheringManager.TetheringInterfaceRegexps {
|
||||
method @NonNull public java.util.List<java.lang.String> getTetherableBluetoothRegexs();
|
||||
method @NonNull public java.util.List<java.lang.String> getTetherableUsbRegexs();
|
||||
method @NonNull public java.util.List<java.lang.String> getTetherableWifiRegexs();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.os {
|
||||
|
||||
public class Binder implements android.os.IBinder {
|
||||
method public final void markVintfStability();
|
||||
}
|
||||
|
||||
public interface Parcelable {
|
||||
method public default int getStability();
|
||||
}
|
||||
|
||||
public class StatsFrameworkInitializer {
|
||||
method public static void registerServiceWrappers();
|
||||
method public static void setStatsServiceManager(@NonNull android.os.StatsServiceManager);
|
||||
}
|
||||
|
||||
public class StatsServiceManager {
|
||||
method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsCompanionServiceRegisterer();
|
||||
method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsManagerServiceRegisterer();
|
||||
method @NonNull public android.os.StatsServiceManager.ServiceRegisterer getStatsdServiceRegisterer();
|
||||
}
|
||||
|
||||
public static class StatsServiceManager.ServiceNotFoundException extends java.lang.Exception {
|
||||
ctor public StatsServiceManager.ServiceNotFoundException(@NonNull String);
|
||||
}
|
||||
|
||||
public static final class StatsServiceManager.ServiceRegisterer {
|
||||
method @Nullable public android.os.IBinder get();
|
||||
method @Nullable public android.os.IBinder getOrThrow() throws android.os.StatsServiceManager.ServiceNotFoundException;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.provider {
|
||||
|
||||
public final class DeviceConfig {
|
||||
field public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager";
|
||||
field public static final String NAMESPACE_APP_STANDBY = "app_standby";
|
||||
field public static final String NAMESPACE_DEVICE_IDLE = "device_idle";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.telephony {
|
||||
|
||||
public abstract class CellSignalStrength {
|
||||
method public static int getNumSignalStrengthLevels();
|
||||
}
|
||||
|
||||
public class TelephonyManager {
|
||||
method @NonNull public static int[] getAllNetworkTypes();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package android.util {
|
||||
|
||||
public class AtomicFile {
|
||||
ctor public AtomicFile(@NonNull java.io.File, @Nullable android.util.SystemConfigFileCommitEventLogger);
|
||||
}
|
||||
|
||||
public final class Log {
|
||||
method public static int logToRadioBuffer(int, @Nullable String, @Nullable String);
|
||||
}
|
||||
|
||||
public class SystemConfigFileCommitEventLogger {
|
||||
ctor public SystemConfigFileCommitEventLogger(@NonNull String);
|
||||
method public void setStartTime(long);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,10 +89,17 @@ package android.media.session {
|
||||
method public boolean dispatchMediaKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
|
||||
method public void dispatchVolumeKeyEventAsSystemService(@NonNull android.view.KeyEvent, int);
|
||||
method public void dispatchVolumeKeyEventToSessionAsSystemService(@NonNull android.view.KeyEvent, @NonNull android.media.session.MediaSession.Token);
|
||||
method public void registerRemoteVolumeControllerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
|
||||
method public void unregisterRemoteVolumeControllerCallback(@NonNull android.media.session.MediaSessionManager.RemoteVolumeControllerCallback);
|
||||
field public static final int RESULT_MEDIA_KEY_HANDLED = 1; // 0x1
|
||||
field public static final int RESULT_MEDIA_KEY_NOT_HANDLED = 0; // 0x0
|
||||
}
|
||||
|
||||
public static interface MediaSessionManager.RemoteVolumeControllerCallback {
|
||||
method public void onSessionChanged(@Nullable android.media.session.MediaSession.Token);
|
||||
method public void onVolumeChanged(@NonNull android.media.session.MediaSession.Token, int);
|
||||
}
|
||||
|
||||
public final class PlaybackState implements android.os.Parcelable {
|
||||
method public boolean isActiveState();
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import android.media.session.MediaSession;
|
||||
* TODO add in better support for multiple remote sessions.
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IRemoteVolumeController {
|
||||
void remoteVolumeChanged(in MediaSession.Token sessionToken, int flags);
|
||||
oneway interface IRemoteVolumeControllerCallback {
|
||||
void onVolumeChanged(in MediaSession.Token sessionToken, int flags);
|
||||
// sets the default session to use with the slider, replaces remoteSliderVisibility
|
||||
// on IVolumeController
|
||||
void updateRemoteController(in MediaSession.Token sessionToken);
|
||||
void onSessionChanged(in MediaSession.Token sessionToken);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ package android.media.session;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.media.IRemoteVolumeController;
|
||||
import android.media.IRemoteVolumeControllerCallback;
|
||||
import android.media.Session2Token;
|
||||
import android.media.session.IActiveSessionsListener;
|
||||
import android.media.session.IOnMediaKeyEventDispatchedListener;
|
||||
@@ -57,8 +57,8 @@ interface ISessionManager {
|
||||
void addSession2TokensListener(in ISession2TokensListener listener, int userId);
|
||||
void removeSession2TokensListener(in ISession2TokensListener listener);
|
||||
|
||||
void registerRemoteVolumeController(in IRemoteVolumeController rvc);
|
||||
void unregisterRemoteVolumeController(in IRemoteVolumeController rvc);
|
||||
void registerRemoteVolumeControllerCallback(in IRemoteVolumeControllerCallback rvc);
|
||||
void unregisterRemoteVolumeControllerCallback(in IRemoteVolumeControllerCallback rvc);
|
||||
|
||||
// For PhoneWindowManager to precheck media keys
|
||||
boolean isGlobalPriorityActive();
|
||||
|
||||
@@ -28,7 +28,7 @@ import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ParceledListSlice;
|
||||
import android.media.AudioManager;
|
||||
import android.media.IRemoteVolumeController;
|
||||
import android.media.IRemoteVolumeControllerCallback;
|
||||
import android.media.MediaFrameworkInitializer;
|
||||
import android.media.MediaSession2;
|
||||
import android.media.Session2Token;
|
||||
@@ -88,6 +88,8 @@ public final class MediaSessionManager {
|
||||
private final OnMediaKeyEventSessionChangedListenerStub
|
||||
mOnMediaKeyEventSessionChangedListenerStub =
|
||||
new OnMediaKeyEventSessionChangedListenerStub();
|
||||
private final RemoteVolumeControllerCallbackStub mRemoteVolumeControllerCallbackStub =
|
||||
new RemoteVolumeControllerCallbackStub();
|
||||
|
||||
private final Object mLock = new Object();
|
||||
@GuardedBy("mLock")
|
||||
@@ -106,6 +108,9 @@ public final class MediaSessionManager {
|
||||
private String mCurMediaKeyEventSessionPackage;
|
||||
@GuardedBy("mLock")
|
||||
private MediaSession.Token mCurMediaKeyEventSession;
|
||||
@GuardedBy("mLock")
|
||||
private final Map<RemoteVolumeControllerCallback, Executor>
|
||||
mRemoteVolumeControllerCallbacks = new ArrayMap<>();
|
||||
|
||||
private Context mContext;
|
||||
private OnVolumeKeyLongPressListenerImpl mOnVolumeKeyLongPressListener;
|
||||
@@ -462,33 +467,62 @@ public final class MediaSessionManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the remote volume controller to receive volume updates on.
|
||||
* Set the remote volume controller callback to receive volume updates on.
|
||||
* Only for use by System UI and Settings application.
|
||||
*
|
||||
* @param rvc The volume controller to receive updates on.
|
||||
* @param callback The volume controller callback to receive updates on.
|
||||
* @hide
|
||||
*/
|
||||
public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
|
||||
try {
|
||||
mService.registerRemoteVolumeController(rvc);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error in registerRemoteVolumeController.", e);
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
public void registerRemoteVolumeControllerCallback(
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull RemoteVolumeControllerCallback callback) {
|
||||
Objects.requireNonNull(executor, "executor shouldn't be null");
|
||||
Objects.requireNonNull(callback, "callback shouldn't be null");
|
||||
boolean shouldRegisterCallback = false;
|
||||
synchronized (mLock) {
|
||||
int prevCallbackCount = mRemoteVolumeControllerCallbacks.size();
|
||||
mRemoteVolumeControllerCallbacks.put(callback, executor);
|
||||
if (prevCallbackCount == 0 && mRemoteVolumeControllerCallbacks.size() == 1) {
|
||||
shouldRegisterCallback = true;
|
||||
}
|
||||
}
|
||||
if (shouldRegisterCallback) {
|
||||
try {
|
||||
mService.registerRemoteVolumeControllerCallback(
|
||||
mRemoteVolumeControllerCallbackStub);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to register remote volume controller callback", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the remote volume controller which was previously registered with
|
||||
* {@link #registerRemoteVolumeController(IRemoteVolumeController)}.
|
||||
* Unregisters the remote volume controller callback which was previously registered with
|
||||
* {@link #registerRemoteVolumeControllerCallback(Executor, RemoteVolumeControllerCallback)}.
|
||||
* Only for use by System UI and Settings application.
|
||||
*
|
||||
* @param rvc The volume controller which was registered.
|
||||
* @param callback The volume controller callback to receive updates on.
|
||||
* @hide
|
||||
*/
|
||||
public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
public void unregisterRemoteVolumeControllerCallback(
|
||||
@NonNull RemoteVolumeControllerCallback callback) {
|
||||
Objects.requireNonNull(callback, "callback shouldn't be null");
|
||||
boolean shouldUnregisterCallback = false;
|
||||
synchronized (mLock) {
|
||||
if (mRemoteVolumeControllerCallbacks.remove(callback) != null
|
||||
&& mRemoteVolumeControllerCallbacks.size() == 0) {
|
||||
shouldUnregisterCallback = true;
|
||||
}
|
||||
}
|
||||
try {
|
||||
mService.unregisterRemoteVolumeController(rvc);
|
||||
if (shouldUnregisterCallback) {
|
||||
mService.unregisterRemoteVolumeControllerCallback(
|
||||
mRemoteVolumeControllerCallbackStub);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error in unregisterRemoteVolumeController.", e);
|
||||
Log.e(TAG, "Failed to unregister remote volume controller callback", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1058,6 +1092,29 @@ public final class MediaSessionManager {
|
||||
@Nullable MediaSession.Token sessionToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to receive changes in the remote volume controller.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
public interface RemoteVolumeControllerCallback {
|
||||
/**
|
||||
* Called when the volume is changed.
|
||||
*
|
||||
* @param sessionToken the remote media session token
|
||||
* @param flags any of the flags from {@link AudioManager}
|
||||
*/
|
||||
void onVolumeChanged(@NonNull MediaSession.Token sessionToken, int flags);
|
||||
|
||||
/**
|
||||
* Called when the session for the default remote controller is changed.
|
||||
*
|
||||
* @param sessionToken the remote media session token
|
||||
*/
|
||||
void onSessionChanged(@Nullable MediaSession.Token sessionToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Information of a remote user of {@link MediaSession} or {@link MediaBrowserService}.
|
||||
* This can be used to decide whether the remote user is trusted app, and also differentiate
|
||||
@@ -1290,4 +1347,29 @@ public final class MediaSessionManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final class RemoteVolumeControllerCallbackStub
|
||||
extends IRemoteVolumeControllerCallback.Stub {
|
||||
@Override
|
||||
public void onVolumeChanged(MediaSession.Token sessionToken, int flags) {
|
||||
Map<RemoteVolumeControllerCallback, Executor> callbacks = new ArrayMap<>();
|
||||
synchronized (mLock) {
|
||||
callbacks.putAll(mRemoteVolumeControllerCallbacks);
|
||||
}
|
||||
for (Map.Entry<RemoteVolumeControllerCallback, Executor> e : callbacks.entrySet()) {
|
||||
e.getValue().execute(() -> e.getKey().onVolumeChanged(sessionToken, flags));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSessionChanged(MediaSession.Token sessionToken) {
|
||||
Map<RemoteVolumeControllerCallback, Executor> callbacks = new ArrayMap<>();
|
||||
synchronized (mLock) {
|
||||
callbacks.putAll(mRemoteVolumeControllerCallbacks);
|
||||
}
|
||||
for (Map.Entry<RemoteVolumeControllerCallback, Executor> e : callbacks.entrySet()) {
|
||||
e.getValue().execute(() -> e.getKey().onSessionChanged(sessionToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settingslib.volume;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -23,20 +25,21 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
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;
|
||||
import android.media.session.MediaSessionManager.OnActiveSessionsChangedListener;
|
||||
import android.media.session.MediaSessionManager.RemoteVolumeControllerCallback;
|
||||
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.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -58,6 +61,7 @@ public class MediaSessions {
|
||||
|
||||
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;
|
||||
@@ -67,6 +71,7 @@ public class MediaSessions {
|
||||
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;
|
||||
}
|
||||
@@ -95,7 +100,8 @@ public class MediaSessions {
|
||||
mMgr.addOnActiveSessionsChangedListener(mSessionsListener, null, mHandler);
|
||||
mInit = true;
|
||||
postUpdateSessions();
|
||||
mMgr.registerRemoteVolumeController(mRvc);
|
||||
mMgr.registerRemoteVolumeControllerCallback(mHandlerExecutor,
|
||||
mRemoteVolumeControllerCallback);
|
||||
}
|
||||
|
||||
protected void postUpdateSessions() {
|
||||
@@ -110,7 +116,7 @@ public class MediaSessions {
|
||||
if (D.BUG) Log.d(TAG, "destroy");
|
||||
mInit = false;
|
||||
mMgr.removeOnActiveSessionsChangedListener(mSessionsListener);
|
||||
mMgr.unregisterRemoteVolumeController(mRvc);
|
||||
mMgr.unregisterRemoteVolumeControllerCallback(mRemoteVolumeControllerCallback);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,19 +336,19 @@ public class MediaSessions {
|
||||
}
|
||||
};
|
||||
|
||||
private final IRemoteVolumeController mRvc = new IRemoteVolumeController.Stub() {
|
||||
@Override
|
||||
public void remoteVolumeChanged(Token sessionToken, int flags)
|
||||
throws RemoteException {
|
||||
mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
|
||||
sessionToken).sendToTarget();
|
||||
}
|
||||
private final RemoteVolumeControllerCallback mRemoteVolumeControllerCallback =
|
||||
new RemoteVolumeControllerCallback() {
|
||||
@Override
|
||||
public void onVolumeChanged(@NonNull MediaSession.Token sessionToken,
|
||||
int flags) {
|
||||
mHandler.obtainMessage(H.REMOTE_VOLUME_CHANGED, flags, 0,
|
||||
sessionToken).sendToTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateRemoteController(final Token sessionToken)
|
||||
throws RemoteException {
|
||||
mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
|
||||
}
|
||||
@Override
|
||||
public void onSessionChanged(@Nullable MediaSession.Token sessionToken) {
|
||||
mHandler.obtainMessage(H.UPDATE_REMOTE_CONTROLLER, sessionToken).sendToTarget();
|
||||
}
|
||||
};
|
||||
|
||||
private final class H extends Handler {
|
||||
|
||||
@@ -44,7 +44,7 @@ import android.content.pm.UserInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioPlaybackConfiguration;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.IRemoteVolumeController;
|
||||
import android.media.IRemoteVolumeControllerCallback;
|
||||
import android.media.Session2Token;
|
||||
import android.media.session.IActiveSessionsListener;
|
||||
import android.media.session.IOnMediaKeyEventDispatchedListener;
|
||||
@@ -146,7 +146,7 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
|
||||
// Used to notify System UI and Settings when remote volume was changed.
|
||||
@GuardedBy("mLock")
|
||||
final RemoteCallbackList<IRemoteVolumeController> mRemoteVolumeControllers =
|
||||
final RemoteCallbackList<IRemoteVolumeControllerCallback> mRemoteVolumeControllers =
|
||||
new RemoteCallbackList<>();
|
||||
|
||||
private SessionPolicyProvider mCustomSessionPolicyProvider;
|
||||
@@ -309,8 +309,9 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
MediaSession.Token token = session.getSessionToken();
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
try {
|
||||
IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
|
||||
cb.remoteVolumeChanged(token, flags);
|
||||
IRemoteVolumeControllerCallback cb =
|
||||
mRemoteVolumeControllers.getBroadcastItem(i);
|
||||
cb.onVolumeChanged(token, flags);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error sending volume change.", e);
|
||||
}
|
||||
@@ -715,8 +716,9 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
|
||||
for (int i = size - 1; i >= 0; i--) {
|
||||
try {
|
||||
IRemoteVolumeController cb = mRemoteVolumeControllers.getBroadcastItem(i);
|
||||
cb.updateRemoteController(token);
|
||||
IRemoteVolumeControllerCallback cb =
|
||||
mRemoteVolumeControllers.getBroadcastItem(i);
|
||||
cb.onSessionChanged(token);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Error sending default remote volume.", e);
|
||||
}
|
||||
@@ -1843,7 +1845,7 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerRemoteVolumeController(IRemoteVolumeController rvc) {
|
||||
public void registerRemoteVolumeControllerCallback(IRemoteVolumeControllerCallback rvc) {
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
@@ -1858,7 +1860,7 @@ public class MediaSessionService extends SystemService implements Monitor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterRemoteVolumeController(IRemoteVolumeController rvc) {
|
||||
public void unregisterRemoteVolumeControllerCallback(IRemoteVolumeControllerCallback rvc) {
|
||||
final int pid = Binder.getCallingPid();
|
||||
final int uid = Binder.getCallingUid();
|
||||
final long token = Binder.clearCallingIdentity();
|
||||
|
||||
Reference in New Issue
Block a user