Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed942b0c authored by Jin Seok Park's avatar Jin Seok Park Committed by Android (Google) Code Review
Browse files

Merge "Expose remote volume controller-related APIs"

parents 04774ea1 18b8febd
Loading
Loading
Loading
Loading
+229 −0
Original line number Diff line number Diff line
// 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);
  }

}
+7 −0
Original line number Diff line number Diff line
@@ -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();
  }
+3 −3
Original line number Diff line number Diff line
@@ -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);
}
+3 −3
Original line number Diff line number Diff line
@@ -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();
+96 −14
Original line number Diff line number Diff line
@@ -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) {
    @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.registerRemoteVolumeController(rvc);
                mService.registerRemoteVolumeControllerCallback(
                        mRemoteVolumeControllerCallbackStub);
            } catch (RemoteException e) {
            Log.e(TAG, "Error in registerRemoteVolumeController.", 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));
            }
        }
    }
}
Loading