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

Commit 7b76aa23 authored by Ayan Ghosh's avatar Ayan Ghosh Committed by Linux Build Service Account
Browse files

AVRCP 1.5 implementation

AVRCP 1.5 Implementation.

Change-Id: I9a21348ec7e0c21735448ea29b781167f01e1580

Bluetooth: Add Total track number.

Add support to add total number of tracks in
Meta-data

Change-Id: I5b1287f791615adcd4f920fe5c7cae0c7c7b04ea
CRs-Fixed: 627869

Bluetooth: Modify Avrcp 1.5 implementation to adapt to latest AOSP changes

Modify Avrcp 1.5 implementation to adapt to latest AOSP changes.

CRs-Fixed: 719567
Change-Id: I0958fb12f573054f1da16df0ac46f3bec7374222

Move media player list management to Audioservice

Move media player list management to Audioservice so that
list is retained even after BT restart.

Change-Id: Ia2455e6def1900b4af2225c50e1b5325a7ce1a98

Update RemoteController on Session update

Update RemoteController on Session update in order to update
AVRCP player list to honor peer initiated browsing command.
This change fixes AVRCP browing failure due stale entry of
player session upated to AVRCP player list after device reboot.

Change-Id: I529a13e2c8a70e4b53319798c952b41f369b8bec

Introduce new interface class for Avrcp Browsing feature

Separate out Avrcp Browsing Apis from SDK interface class to
ensure compatibility with all available apps implementing the
mentioned SDK interface class.

Bluetooth: Access mediaplayerlist in synchronized way

Access mediaplayerlist in synchronized way to make sure no transient
update is tried to be worked upon in multithreaded environment.

Change-Id: I0e7810ac89e0ddc19d57b32c679450aa7cb87273
CRs-Fixed: 979840

Conflicts:
	media/java/android/media/IAudioService.aidl

Change-Id: I713527ee3622ba28fe92d5bc743b9471632299b3
parent 9e259171
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -222,6 +222,26 @@ public class Media extends BaseCommand {
            System.out.println("onVolumeInfoChanged " + info);
        }

        @Override
        public void onPlayItemResponse(boolean success) throws RemoteException {
            System.out.println("onPlayItemResponse ");
        }

        @Override
        public void onUpdateNowPlayingEntries(long[] playList) throws RemoteException {
            System.out.println("onUpdateNowPlayingEntries ");
        }

        @Override
        public void onUpdateFolderInfoBrowsedPlayer(String stringUri) throws RemoteException {
            System.out.println("onUpdateFolderInfoBrowsedPlayer ");
        }

        @Override
        public void onUpdateNowPlayingContentChange() throws RemoteException {
            System.out.println("onUpdateNowPlayingContentChange ");
        }

        void printUsageMessage() {
            try {
                System.out.println("V2Monitoring session " + mController.getTag()
+54 −2
Original line number Diff line number Diff line
@@ -69,7 +69,6 @@ public class AudioManager {
    private final boolean mUseFixedVolume;
    private static String TAG = "AudioManager";
    private static final AudioPortEventHandler sAudioPortEventHandler = new AudioPortEventHandler();

    /**
     * Broadcast intent, a hint for applications that audio is about to become
     * 'noisy' due to a change in audio outputs. For example, this intent may
@@ -312,6 +311,32 @@ public class AudioManager {
     */
    public static final String EXTRA_ENCODINGS = "android.media.extra.ENCODINGS";

    /**
     * @hide Broadcast intent when RemoteControlClient list is updated.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String RCC_CHANGED_ACTION =
                "org.codeaurora.bluetooth.RCC_CHANGED_ACTION";

    /**
     * @hide Used for sharing the calling package name
     */
    public static final String EXTRA_CALLING_PACKAGE_NAME =
            "org.codeaurora.bluetooth.EXTRA_CALLING_PACKAGE_NAME";

    /**
     * @hide Used for sharing the focus changed value
     */
    public static final String EXTRA_FOCUS_CHANGED_VALUE =
            "org.codeaurora.bluetooth.EXTRA_FOCUS_CHANGED_VALUE";

    /**
     * @hide Used for sharing the availability changed value
     */
    public static final String EXTRA_AVAILABLITY_CHANGED_VALUE =
            "org.codeaurora.bluetooth.EXTRA_AVAILABLITY_CHANGED_VALUE";


    /** The audio stream for phone calls */
    public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
    /** The audio stream for system sounds */
@@ -2504,6 +2529,7 @@ public class AudioManager {

    //====================================================================
    // Remote Control

    /**
     * Register a component to be the sole receiver of MEDIA_BUTTON intents.
     * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
@@ -2522,6 +2548,7 @@ public class AudioManager {
                    "receiver and context package names don't match");
            return;
        }

        // construct a PendingIntent for the media button and register it
        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
        //     the associated intent will be handled by the component being registered
@@ -2531,6 +2558,7 @@ public class AudioManager {
        registerMediaButtonIntent(pi, eventReceiver);
    }


    /**
     * Register a component to be the sole receiver of MEDIA_BUTTON intents.  This is like
     * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows
@@ -2660,6 +2688,13 @@ public class AudioManager {
            return false;
        }
        rctlr.startListeningToSessions();
        IAudioService service = getService();
        try {
            service.updateRemoteControllerOnExistingMediaPlayers();
        } catch (RemoteException e) {
            Log.e(TAG, "Error in calling Audio service interface" +
                "updateRemoteControllerOnExistingMediaPlayers() due to " + e);
        }
        return true;
    }

@@ -2681,6 +2716,24 @@ public class AudioManager {
        rctlr.stopListeningToSessions();
    }

    /**
     * @hide
     */
    public void updateMediaPlayerList(String packageName, boolean toAdd) {
        IAudioService service = getService();
        try {
            if (toAdd) {
                Log.d(TAG, "updateMediaPlayerList: Add RCC " + packageName + " to List");
                service.addMediaPlayerAndUpdateRemoteController(packageName);
            } else {
                Log.d(TAG, "updateMediaPlayerList: Remove RCC " + packageName + " from List");
                service.removeMediaPlayerAndUpdateRemoteController(packageName);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "Exception while executing updateMediaPlayerList: " + e);
        }
    }


    //====================================================================
    // Audio policy
@@ -2734,7 +2787,6 @@ public class AudioManager {
        }
    }


    //====================================================================
    // Recording configuration
    /**
+10 −0
Original line number Diff line number Diff line
@@ -164,5 +164,15 @@ interface IAudioService {

    oneway void unregisterRecordingCallback(in IRecordingConfigDispatcher rcdb);

<<<<<<< HEAD
    List<AudioRecordingConfiguration> getActiveRecordingConfigurations();
=======
    AudioRecordingConfiguration[] getActiveRecordingConfigurations();

    void updateRemoteControllerOnExistingMediaPlayers();

    void addMediaPlayerAndUpdateRemoteController(String packageName);

    void removeMediaPlayerAndUpdateRemoteController(String packageName);
>>>>>>> 810a57e... AVRCP 1.5 implementation
}
+3 −1
Original line number Diff line number Diff line
@@ -440,7 +440,7 @@ import android.util.SparseIntArray;
    protected static final SparseIntArray METADATA_KEYS_TYPE;

    static {
        METADATA_KEYS_TYPE = new SparseIntArray(17);
        METADATA_KEYS_TYPE = new SparseIntArray(18);
        // NOTE: if adding to the list below, make sure you increment the array initialization size
        // keys with long values
        METADATA_KEYS_TYPE.put(
@@ -466,5 +466,7 @@ import android.util.SparseIntArray;
        // keys with Rating values
        METADATA_KEYS_TYPE.put(RATING_KEY_BY_OTHERS, METADATA_TYPE_RATING);
        METADATA_KEYS_TYPE.put(RATING_KEY_BY_USER, METADATA_TYPE_RATING);
        // Meta data for total number of tracks in Album
        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
    }
}
+231 −0
Original line number Diff line number Diff line
@@ -349,6 +349,16 @@ import java.lang.IllegalArgumentException;
     */
    public RemoteControlClient(PendingIntent mediaButtonIntent) {
        mRcMediaIntent = mediaButtonIntent;

        Looper looper;
        if ((looper = Looper.myLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else if ((looper = Looper.getMainLooper()) != null) {
            mEventHandler = new EventHandler(this, looper);
        } else {
            mEventHandler = null;
            Log.e(TAG, "RemoteControlClient() couldn't find main application thread");
        }
    }

    /**
@@ -368,6 +378,8 @@ import java.lang.IllegalArgumentException;
     */
    public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) {
        mRcMediaIntent = mediaButtonIntent;

        mEventHandler = new EventHandler(this, looper);
    }

    /**
@@ -695,6 +707,79 @@ import java.lang.IllegalArgumentException;
        }
    }

    /**
     * @hide
     */
    public void playItemResponse(boolean success) {
        Log.e(TAG, "playItemResponse");
        playItemResponseInt(success);
    }

    private void playItemResponseInt(boolean success) {
        Log.d(TAG, "playItemResponseInt");
        Log.v(TAG, "success: " + success);

        // USE_SESSIONS
        if (mSession != null) {
            mSession.playItemResponse(success);
        }
    }

    /**
     * @hide
     */
    public void updateNowPlayingEntries(long[] playList) {
        Log.e(TAG, "updateNowPlayingEntries: Item numbers: " + playList.length);
        updateNowPlayingEntriesInt(playList);
    }

    private void updateNowPlayingEntriesInt(long[] playList) {
        Log.d(TAG, "updateNowPlayingEntriesInt");

        // USE_SESSIONS
        if (mSession != null) {
            mSession.updateNowPlayingEntries(playList);
        }
    }

    /**
     * @hide
     */
    public void updateFolderInfoBrowsedPlayer(String stringUri) {
        Log.e(TAG, "updateFolderInfoBrowsedPlayer");
        synchronized(mCacheLock) {
            updateFolderInfoBrowsedPlayerInt(stringUri);
        }
    }

    private void updateFolderInfoBrowsedPlayerInt(String stringUri) {
        Log.d(TAG, "updateFolderInfoBrowsedPlayerInt");

        // USE_SESSIONS
        if (mSession != null) {
            mSession.updateFolderInfoBrowsedPlayer(stringUri);
        }
    }

    /**
     * @hide
     */
    public void updateNowPlayingContentChange() {
        Log.e(TAG, "updateNowPlayingContentChange");
        synchronized(mCacheLock) {
            updateNowPlayingContentChangeInt();
        }
    }

    private void updateNowPlayingContentChangeInt() {
        Log.d(TAG, "updateNowPlayingContentChangeInt");

        // USE_SESSIONS
        if (mSession != null) {
            mSession.updateNowPlayingContentChange();
        }
    }

    /**
     * Sets the flags for the media transport control buttons that this client supports.
     * @param transportControlFlags A combination of the following flags:
@@ -753,6 +838,56 @@ import java.lang.IllegalArgumentException;
        }
    }

    /**
     * @hide
     */
    public interface OnGetNowPlayingEntriesListener {
        public abstract void onGetNowPlayingEntries();
    }

    /**
     * @hide
     */
    public void setNowPlayingEntriesUpdateListener(OnGetNowPlayingEntriesListener l) {
        Log.d(TAG, "setNowPlayingEntriesUpdateListener");
        synchronized(mCacheLock) {
            mGetNowPlayingEntriesListener = l;
        }
    }

    /**
     * @hide
     */
    public interface OnSetBrowsedPlayerListener {
        public abstract void onSetBrowsedPlayer();
    }

    /**
     * @hide
     */
    public void setBrowsedPlayerUpdateListener(OnSetBrowsedPlayerListener l) {
        Log.d(TAG, "setBrowsedPlayerUpdateListener");
        synchronized(mCacheLock) {
            mSetBrowsedPlayerListener = l;
        }
    }

    /**
     * @hide
     */
    public interface OnSetPlayItemListener {
        public abstract void onSetPlayItem(int scope, long uid);
    }

    /**
     * @hide
     */
    public void setPlayItemListener(OnSetPlayItemListener l) {
        Log.d(TAG, "setPlayItemListener");
        synchronized(mCacheLock) {
            mSetPlayItemListener = l;
        }
    }

    /**
     * Interface definition for a callback to be invoked when the media playback position is
@@ -893,6 +1028,13 @@ import java.lang.IllegalArgumentException;
    /**
     * The current remote control client generation ID across the system, as known by this object
     */

    private OnSetBrowsedPlayerListener mSetBrowsedPlayerListener;

    private OnSetPlayItemListener mSetPlayItemListener;

    private OnGetNowPlayingEntriesListener mGetNowPlayingEntriesListener;

    private int mCurrentClientGenId = -1;

    /**
@@ -946,8 +1088,67 @@ import java.lang.IllegalArgumentException;
                onUpdateMetadata(mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating);
            }
        }

        @Override
        public void setPlayItem(int scope, long uid) {
            // only post messages, we can't block here
            if (mEventHandler != null) {
                mEventHandler.removeMessages(MSG_SET_PLAY_ITEM);
                mEventHandler.sendMessage(mEventHandler.obtainMessage(
                        MSG_SET_PLAY_ITEM, 0 /* arg1 */, scope /* arg2, ignored */,
                        new Long(uid)));
            }
        }

        @Override
        public void getNowPlayingEntries() {
            // only post messages, we can't block here
            if (mEventHandler != null) {
                mEventHandler.removeMessages(MSG_GET_NOW_PLAYING_ENTRIES);
                mEventHandler.sendMessage(mEventHandler.obtainMessage(
                        MSG_GET_NOW_PLAYING_ENTRIES, 0, 0, null));
            }
        }

        @Override
        public void setBrowsedPlayer() {
            Log.d(TAG, "setBrowsedPlayer in RemoteControlClient");
            if (mEventHandler != null) {
                mEventHandler.sendMessage(mEventHandler.obtainMessage(
                        MSG_SET_BROWSED_PLAYER, 0 /* arg1 */, 0 /* arg2*/, null));
            }
        }
    };

    private EventHandler mEventHandler;
    private final static int MSG_SET_BROWSED_PLAYER = 12;
    private final static int MSG_SET_PLAY_ITEM = 13;
    private final static int MSG_GET_NOW_PLAYING_ENTRIES = 14;

    private class EventHandler extends Handler {
        public EventHandler(RemoteControlClient rcc, Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what) {
                case MSG_SET_BROWSED_PLAYER:
                    Log.d(TAG, "MSG_SET_BROWSED_PLAYER in RemoteControlClient");
                    onSetBrowsedPlayer();
                    break;
                case MSG_SET_PLAY_ITEM:
                    onSetPlayItem(msg.arg2, ((Long)msg.obj).longValue());
                    break;
                case MSG_GET_NOW_PLAYING_ENTRIES:
                    onGetNowPlayingEntries();
                    break;
                default:
                    Log.e(TAG, "Unknown event " + msg.what + " in RemoteControlClient handler");
            }
        }
    }

    //===========================================================
    // Message handlers

@@ -967,6 +1168,36 @@ import java.lang.IllegalArgumentException;
        }
    }

    private void onSetPlayItem(int scope, long uid) {
        Log.d(TAG, "onSetPlayItem");
        synchronized (mCacheLock) {
            if (mSetPlayItemListener != null) {
                Log.d(TAG, "mSetPlayItemListener.onSetPlayItem");
                mSetPlayItemListener.onSetPlayItem(scope, uid);
            }
        }
    }

    private void onSetBrowsedPlayer() {
        Log.d(TAG, "onSetBrowsedPlayer");
        synchronized (mCacheLock) {
            if (mSetBrowsedPlayerListener != null) {
                Log.d(TAG, "mSetBrowsedPlayerListener.onSetBrowsedPlayer");
                mSetBrowsedPlayerListener.onSetBrowsedPlayer();
            }
        }
    }

    private void onGetNowPlayingEntries() {
        Log.d(TAG, "onGetNowPlayingEntries");
        synchronized (mCacheLock) {
            if (mGetNowPlayingEntriesListener != null) {
                Log.d(TAG, "mGetNowPlayingEntriesListener.onGetNowPlayingEntries");
                mGetNowPlayingEntriesListener.onGetNowPlayingEntries();
            }
        }
    }

    //===========================================================
    // Internal utilities

Loading