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

Commit e521669b authored by Hyundo Moon's avatar Hyundo Moon
Browse files

Introduce ControllerCallbackLink

In order to avoid direct AIDL usages in framework, this CL introduces a
new class ControllerCallbackLink which can prevent usages of
ISessionControllerCallback.

Bug: 122169124
Test: make update-api -j / make -j
      atest CtsMediaTestCases:android.media.cts.MediaSessionTest
      atest CtsMediaTestCases:android.media.cts.MediaControllerTest
Change-Id: I860ea56afc046dd91e065ef207d374c0aa490c8f
parent 2f16d51c
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -3160,6 +3160,34 @@ package android.media.audiopolicy {

package android.media.session {

  public final class ControllerCallbackLink implements android.os.Parcelable {
    ctor public ControllerCallbackLink(android.media.session.ControllerCallbackLink.CallbackStub);
    method public android.os.IBinder asBinder();
    method public int describeContents();
    method public void notifyEvent(java.lang.String, android.os.Bundle);
    method public void notifyExtrasChanged(android.os.Bundle);
    method public void notifyMetadataChanged(android.media.MediaMetadata);
    method public void notifyPlaybackStateChanged(android.media.session.PlaybackState);
    method public void notifyQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
    method public void notifyQueueTitleChanged(java.lang.CharSequence);
    method public void notifySessionDestroyed();
    method public void notifyVolumeInfoChanged(int, android.media.AudioAttributes, int, int, int);
    method public void writeToParcel(android.os.Parcel, int);
    field public static final android.os.Parcelable.Creator<android.media.session.ControllerCallbackLink> CREATOR;
  }

  public static abstract class ControllerCallbackLink.CallbackStub {
    ctor public ControllerCallbackLink.CallbackStub();
    method public void onEvent(java.lang.String, android.os.Bundle);
    method public void onExtrasChanged(android.os.Bundle);
    method public void onMetadataChanged(android.media.MediaMetadata);
    method public void onPlaybackStateChanged(android.media.session.PlaybackState);
    method public void onQueueChanged(java.util.List<android.media.session.MediaSession.QueueItem>);
    method public void onQueueTitleChanged(java.lang.CharSequence);
    method public void onSessionDestroyed();
    method public void onVolumeInfoChanged(int, android.media.AudioAttributes, int, int, int);
  }

  public final class MediaSessionManager {
    method public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, android.os.Handler);
    method public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler);
+25 −18
Original line number Diff line number Diff line
@@ -19,12 +19,12 @@ package com.android.commands.media;

import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
import android.media.session.ControllerCallbackLink;
import android.media.session.ISessionController;
import android.media.session.ISessionControllerCallback;
import android.media.session.ISessionManager;
import android.media.session.ParcelableVolumeInfo;
import android.media.session.MediaSession.QueueItem;
import android.media.session.PlaybackState;
import android.os.Bundle;
import android.os.HandlerThread;
@@ -178,13 +178,7 @@ public class Media extends BaseCommand {
                KeyCharacterMap.VIRTUAL_KEYBOARD, 0, 0, InputDevice.SOURCE_KEYBOARD));
    }

    class ControllerMonitor extends ISessionControllerCallback.Stub {
        private final ISessionController mController;

        public ControllerMonitor(ISessionController controller) {
            mController = controller;
        }

    class ControllerCallbackStub extends ControllerCallbackLink.CallbackStub {
        @Override
        public void onSessionDestroyed() {
            System.out.println("onSessionDestroyed. Enter q to quit.");
@@ -208,24 +202,37 @@ public class Media extends BaseCommand {
        }

        @Override
        public void onQueueChanged(ParceledListSlice queue) throws RemoteException {
        public void onQueueChanged(List<QueueItem> queue) {
            System.out.println("onQueueChanged, "
                    + (queue == null ? "null queue" : " size=" + queue.getList().size()));
                    + (queue == null ? "null queue" : " size=" + queue.size()));
        }

        @Override
        public void onQueueTitleChanged(CharSequence title) throws RemoteException {
        public void onQueueTitleChanged(CharSequence title) {
            System.out.println("onQueueTitleChange " + title);
        }

        @Override
        public void onExtrasChanged(Bundle extras) throws RemoteException {
        public void onExtrasChanged(Bundle extras) {
            System.out.println("onExtrasChanged " + extras);
        }

        @Override
        public void onVolumeInfoChanged(ParcelableVolumeInfo info) throws RemoteException {
            System.out.println("onVolumeInfoChanged " + info);
        public void onVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType,
                int maxVolume, int currentVolume) {
            System.out.println("onVolumeInfoChanged " + "volumeType=" + volumeType + ", attrs="
                    + attrs + ", controlType=" + controlType + ", maxVolume=" + maxVolume
                    + ", currentVolume=" + currentVolume);
        }
    }

    private class ControllerMonitor {
        private final ISessionController mController;
        private final ControllerCallbackLink mControllerCallbackLink;

        ControllerMonitor(ISessionController controller) {
            mController = controller;
            mControllerCallbackLink = new ControllerCallbackLink(new ControllerCallbackStub());
        }

        void printUsageMessage() {
@@ -244,7 +251,7 @@ public class Media extends BaseCommand {
                @Override
                protected void onLooperPrepared() {
                    try {
                        mController.registerCallbackListener(PACKAGE_NAME, ControllerMonitor.this);
                        mController.registerCallbackListener(PACKAGE_NAME, mControllerCallbackLink);
                    } catch (RemoteException e) {
                        System.out.println("Error registering monitor callback");
                    }
@@ -287,7 +294,7 @@ public class Media extends BaseCommand {
            } finally {
                cbThread.getLooper().quit();
                try {
                    mController.unregisterCallbackListener(this);
                    mController.unregisterCallbackListener(mControllerCallbackLink);
                } catch (Exception e) {
                    // ignoring
                }
+18 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 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 android.media.session;

parcelable ControllerCallbackLink;
+240 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 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 android.media.session;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
import android.media.session.MediaSession.QueueItem;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;

import java.util.List;

/**
 * Handles incoming commands to {@link MediaController.Callback}.
 * @hide
 */
@SystemApi
public final class ControllerCallbackLink implements Parcelable {
    CallbackStub mCallbackStub;
    ISessionControllerCallback mIControllerCallback;

    /**
     * Creator for stub (Callee)
     */
    public ControllerCallbackLink(@NonNull CallbackStub callbackStub) {
        mCallbackStub = callbackStub;
        mIControllerCallback = new CallbackStubProxy();
    }

    /**
     * Creator for interface (Caller)
     */
    ControllerCallbackLink(Parcel in) {
        mCallbackStub = null;
        mIControllerCallback = ISessionControllerCallback.Stub.asInterface(in.readStrongBinder());
    }

    /** Interface method for ISessionControllerCallback.notifySessionDestroyed */
    public void notifySessionDestroyed() {
        try {
            mIControllerCallback.notifySessionDestroyed();
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyEvent */
    public void notifyEvent(String event, Bundle extras) {
        try {
            mIControllerCallback.notifyEvent(event, extras);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyPlaybackStateChanged */
    public void notifyPlaybackStateChanged(PlaybackState state) {
        try {
            mIControllerCallback.notifyPlaybackStateChanged(state);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyMetadataChanged */
    public void notifyMetadataChanged(MediaMetadata metadata) {
        try {
            mIControllerCallback.notifyMetadataChanged(metadata);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyQueueChanged */
    public void notifyQueueChanged(List<QueueItem> queue) {
        try {
            mIControllerCallback.notifyQueueChanged(queue);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyQueueTitleChanged */
    public void notifyQueueTitleChanged(CharSequence title) {
        try {
            mIControllerCallback.notifyQueueTitleChanged(title);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyExtrasChanged */
    public void notifyExtrasChanged(Bundle extras) {
        try {
            mIControllerCallback.notifyExtrasChanged(extras);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Interface method for ISessionControllerCallback.notifyVolumeInfoChanged */
    public void notifyVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType,
            int maxVolume, int currentVolume) {
        try {
            mIControllerCallback.notifyVolumeInfoChanged(volumeType, attrs, controlType, maxVolume,
                    currentVolume);
        } catch (RemoteException e) {
            throw new RuntimeException(e);
        }
    }

    /** Gets the binder */
    public IBinder asBinder() {
        return mIControllerCallback.asBinder();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeStrongBinder(mIControllerCallback.asBinder());
    }

    public static final Parcelable.Creator<ControllerCallbackLink> CREATOR =
            new Parcelable.Creator<ControllerCallbackLink>() {
        @Override
        public ControllerCallbackLink createFromParcel(Parcel in) {
            return new ControllerCallbackLink(in);
        }

        @Override
        public ControllerCallbackLink[] newArray(int size) {
            return new ControllerCallbackLink[size];
        }
    };

    /**
     * Class for Stub implementation
     */
    public abstract static class CallbackStub {
        /** Stub method for ISessionControllerCallback.notifySessionDestroyed */
        public void onSessionDestroyed() {
        }

        /** Stub method for ISessionControllerCallback.notifyEvent */
        public void onEvent(String event, Bundle extras) {
        }

        /** Stub method for ISessionControllerCallback.notifyPlaybackStateChanged */
        public void onPlaybackStateChanged(PlaybackState state) {
        }

        /** Stub method for ISessionControllerCallback.notifyMetadataChanged */
        public void onMetadataChanged(MediaMetadata metadata) {
        }

        /** Stub method for ISessionControllerCallback.notifyQueueChanged */
        public void onQueueChanged(List<QueueItem> queue) {
        }

        /** Stub method for ISessionControllerCallback.notifyQueueTitleChanged */
        public void onQueueTitleChanged(CharSequence title) {
        }

        /** Stub method for ISessionControllerCallback.notifyExtrasChanged */
        public void onExtrasChanged(Bundle extras) {
        }

        /** Stub method for ISessionControllerCallback.notifyVolumeInfoChanged */
        public void onVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType,
                int maxVolume, int currentVolume) {
        }
    }

    private class CallbackStubProxy extends ISessionControllerCallback.Stub {
        @Override
        public void notifyEvent(String event, Bundle extras) {
            mCallbackStub.onEvent(event, extras);
        }

        @Override
        public void notifySessionDestroyed() {
            mCallbackStub.onSessionDestroyed();
        }

        @Override
        public void notifyPlaybackStateChanged(PlaybackState state) {
            mCallbackStub.onPlaybackStateChanged(state);
        }

        @Override
        public void notifyMetadataChanged(MediaMetadata metadata) {
            mCallbackStub.onMetadataChanged(metadata);
        }

        @Override
        public void notifyQueueChanged(List<QueueItem> queue) {
            mCallbackStub.onQueueChanged(queue);
        }

        @Override
        public void notifyQueueTitleChanged(CharSequence title) {
            mCallbackStub.onQueueTitleChanged(title);
        }

        @Override
        public void notifyExtrasChanged(Bundle extras) {
            mCallbackStub.onExtrasChanged(extras);
        }

        @Override
        public void notifyVolumeInfoChanged(int volumeType, AudioAttributes attrs, int controlType,
                int maxVolume, int currentVolume) {
            mCallbackStub.onVolumeInfoChanged(volumeType, attrs, controlType, maxVolume,
                    currentVolume);
        }
    }
}
+1 −2
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@
package android.media.session;

import android.app.PendingIntent;
import android.content.pm.ParceledListSlice;
import android.media.AudioAttributes;
import android.media.MediaMetadata;
import android.media.session.ISessionController;
@@ -41,7 +40,7 @@ interface ISession {
    // These commands are for the TransportPerformer
    void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription);
    void setPlaybackState(in PlaybackState state);
    void setQueue(in ParceledListSlice queue);
    void setQueue(in List<MediaSession.QueueItem> queue);
    void setQueueTitle(CharSequence title);
    void setExtras(in Bundle extras);
    void setRatingType(int type);
Loading