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

Commit 0925bfb6 authored by Joseph Pirozzo's avatar Joseph Pirozzo Committed by Gerrit Code Review
Browse files

Merge changes I99ca081f,Ic252ee0b

* changes:
  AVRCP Controller update loop.
  AVRCP Browsing large playlist support
parents d9d86199 5a365939
Loading
Loading
Loading
Loading
+46 −21
Original line number Diff line number Diff line
@@ -33,7 +33,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.Parcelable;
import android.service.media.MediaBrowserService;
import android.util.Log;
import android.util.Pair;
@@ -44,7 +43,6 @@ import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
import com.android.bluetooth.avrcpcontroller.BrowseTree;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -97,6 +95,7 @@ public class A2dpMediaBrowserService extends MediaBrowserService {
    private static final String CUSTOM_ACTION_GET_PLAY_STATUS_NATIVE =
            "com.android.bluetooth.a2dpsink.mbs.CUSTOM_ACTION_GET_PLAY_STATUS_NATIVE";

    private static A2dpMediaBrowserService sA2dpMediaBrowserService;
    private MediaSession mSession;
    private MediaMetadata mA2dpMetadata;

@@ -185,18 +184,41 @@ public class A2dpMediaBrowserService extends MediaBrowserService {
        synchronized (this) {
            mParentIdToRequestMap.clear();
        }
        setA2dpMediaBrowserService(this);

    }

    @Override
    public void onDestroy() {
        if (DBG) Log.d(TAG, "onDestroy");
        setA2dpMediaBrowserService(null);
        mSession.release();
        unregisterReceiver(mBtReceiver);
        super.onDestroy();
    }


    /**
     *  getA2dpMediaBrowserService()
     *  Routine to get direct access to MediaBrowserService from within the same process.
     */
    public static synchronized A2dpMediaBrowserService getA2dpMediaBrowserService() {
        if (sA2dpMediaBrowserService == null) {
            Log.w(TAG, "getA2dpMediaBrowserService(): service is NULL");
            return null;
        }
        if (DBG) Log.d(TAG, "getA2dpMediaBrowserService(): returning " + sA2dpMediaBrowserService);
        return sA2dpMediaBrowserService;
    }

    private static synchronized void setA2dpMediaBrowserService(A2dpMediaBrowserService instance) {
        if (DBG) Log.d(TAG, "setA2dpMediaBrowserService(): set to: " + instance);
        sA2dpMediaBrowserService = instance;
    }

    @Override
    public BrowserRoot onGetRoot(String clientPackageName, int clientUid, Bundle rootHints) {
        if (DBG) Log.d(TAG, "onGetRoot");
        return new BrowserRoot(BrowseTree.ROOT, null);
    }

@@ -210,17 +232,15 @@ public class A2dpMediaBrowserService extends MediaBrowserService {
        }

        if (DBG) Log.d(TAG, "onLoadChildren parentMediaId=" + parentMediaId);
        if (!mAvrcpCtrlSrvc.getChildren(mA2dpDevice, parentMediaId, 0, 0xff)) {
            result.sendResult(Collections.emptyList());
            return;
        }

        // Since we are using this thread from a binder thread we should make sure that
        // we synchronize against other such asynchronous calls.
        synchronized (this) {
        List<MediaItem> contents = mAvrcpCtrlSrvc.getContents(mA2dpDevice, parentMediaId);
        if (contents == null) {
            mParentIdToRequestMap.put(parentMediaId, result);
        }
            result.detach();
        } else {
            result.sendResult(contents);
        }

        return;
    }

    @Override
@@ -532,16 +552,8 @@ public class A2dpMediaBrowserService extends MediaBrowserService {

    private void msgFolderList(Intent intent) {
        // Parse the folder list for children list and id.
        List<Parcelable> extraParcelableList =
                (ArrayList<Parcelable>) intent.getParcelableArrayListExtra(
                        AvrcpControllerService.EXTRA_FOLDER_LIST);
        List<MediaItem> folderList = new ArrayList<MediaItem>();
        for (Parcelable p : extraParcelableList) {
            folderList.add((MediaItem) p);
        }

        String id = intent.getStringExtra(AvrcpControllerService.EXTRA_FOLDER_ID);
        if (VDBG) Log.d(TAG, "Parent: " + id + " Folder list: " + folderList);
        if (VDBG) Log.d(TAG, "Parent: " + id);
        synchronized (this) {
            // If we have a result object then we should send the result back
            // to client since it is blocking otherwise we may have gotten more items
@@ -551,11 +563,23 @@ public class A2dpMediaBrowserService extends MediaBrowserService {
                Log.w(TAG, "Request no longer exists, notifying that children changed.");
                    notifyChildrenChanged(id);
            } else {
                List<MediaItem> folderList = mAvrcpCtrlSrvc.getContents(mA2dpDevice, id);
                results.sendResult(folderList);
            }
        }
    }

    /**
     * processInternalEvent(Intent intent)
     * Routine to provide MediaBrowserService with content updates from within the same process.
     */
    public void processInternalEvent(Intent intent) {
        String action = intent.getAction();
        if (AvrcpControllerService.ACTION_FOLDER_LIST.equals(action)) {
            mAvrcpCommandQueue.obtainMessage(MSG_FOLDER_LIST, intent).sendToTarget();
        }
    }

    private void msgDeviceBrowseDisconnect(BluetoothDevice device) {
        if (DBG) Log.d(TAG, "msgDeviceBrowseDisconnect device " + device);
        // Disconnect only if mA2dpDevice is non null
@@ -566,4 +590,5 @@ public class A2dpMediaBrowserService extends MediaBrowserService {
        }
        mBrowseConnected = false;
    }

}
+7 −165
Original line number Diff line number Diff line
@@ -172,8 +172,8 @@ public class AvrcpControllerService extends ProfileService {
    /* Folder navigation directions
     * This is borrowed from AVRCP 1.6 spec and must be kept with same values
     */
    public static final int FOLDER_NAVIGATION_DIRECTION_UP = 0x00;
    public static final int FOLDER_NAVIGATION_DIRECTION_DOWN = 0x01;
    public static final byte FOLDER_NAVIGATION_DIRECTION_UP = 0x00;
    public static final byte FOLDER_NAVIGATION_DIRECTION_DOWN = 0x01;

    /* Folder/Media Item scopes.
     * Keep in sync with AVRCP 1.6 sec. 6.10.1
@@ -398,77 +398,12 @@ public class AvrcpControllerService extends ProfileService {
    }

    /**
     * Fetches the list of children for the parentID node.
     *
     * This function manages the overall tree for browsing structure.
     *
     * Arguments:
     * device - Device to browse content for.
     * parentMediaId - ID of the parent that we need to browse content for. Since most
     * of the players are database unware, fetching a root invalidates all the children.
     * start - number of item to start scanning from
     * items - number of items to fetch
     * Retreive the contents of the directory from the associated bluetooth device.
     */
    public synchronized boolean getChildren(BluetoothDevice device, String parentMediaId, int start,
            int items) {
        if (DBG) {
            Log.d(TAG, "getChildren device = " + device + " parent " + parentMediaId);
        }

        if (device == null) {
            Log.e(TAG, "getChildren device is null");
            return false;
        }

        if (!device.equals(mConnectedDevice)) {
            Log.e(TAG, "getChildren device " + device + " does not match " + mConnectedDevice);
            return false;
        }

        if (!mBrowseConnected) {
            Log.e(TAG, "getChildren browse not yet connected");
            return false;
        }

        if (!mAvrcpCtSm.isConnected()) {
            return false;
        }
        mAvrcpCtSm.getChildren(parentMediaId, start, items);
        return true;
    }

    public synchronized boolean getNowPlayingList(BluetoothDevice device, String id, int start,
            int items) {
        if (DBG) {
            Log.d(TAG, "getNowPlayingList device = " + device + " start = " + start + "items = "
                    + items);
        }

        if (device == null) {
            Log.e(TAG, "getNowPlayingList device is null");
            return false;
        }

        if (!device.equals(mConnectedDevice)) {
            Log.e(TAG,
                    "getNowPlayingList device " + device + " does not match " + mConnectedDevice);
            return false;
    public synchronized List<MediaItem> getContents(BluetoothDevice device, String parentMediaId) {
        return mAvrcpCtSm.getContents(parentMediaId);
    }

        if (!mBrowseConnected) {
            Log.e(TAG, "getNowPlayingList browse not yet connected");
            return false;
        }

        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        Message msg =
                mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.MESSAGE_GET_NOW_PLAYING_LIST,
                        start, items, id);
        mAvrcpCtSm.sendMessage(msg);
        return true;
    }

/*
    public synchronized boolean getFolderList(BluetoothDevice device, String id, int start,
            int items) {
        if (DBG) {
@@ -499,100 +434,7 @@ public class AvrcpControllerService extends ProfileService {
        mAvrcpCtSm.sendMessage(msg);
        return true;
    }

    public synchronized boolean getPlayerList(BluetoothDevice device, int start, int items) {
        if (DBG) {
            Log.d(TAG,
                    "getPlayerList device = " + device + " start = " + start + "items = " + items);
        }

        if (device == null) {
            Log.e(TAG, "getPlayerList device is null");
            return false;
        }

        if (!device.equals(mConnectedDevice)) {
            Log.e(TAG, "getPlayerList device " + device + " does not match " + mConnectedDevice);
            return false;
        }

        if (!mBrowseConnected) {
            Log.e(TAG, "getPlayerList browse not yet connected");
            return false;
        }

        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        Message msg =
                mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.MESSAGE_GET_PLAYER_LIST, start,
                        items);
        mAvrcpCtSm.sendMessage(msg);
        return true;
    }

    public synchronized boolean changeFolderPath(BluetoothDevice device, int direction, String uid,
            String fid) {
        if (DBG) {
            Log.d(TAG, "changeFolderPath device = " + device + " direction " + direction + " uid "
                    + uid);
        }

        if (device == null) {
            Log.e(TAG, "changeFolderPath device is null");
            return false;
        }

        if (!device.equals(mConnectedDevice)) {
            Log.e(TAG, "changeFolderPath device " + device + " does not match " + mConnectedDevice);
            return false;
        }

        if (!mBrowseConnected) {
            Log.e(TAG, "changeFolderPath browse not yet connected");
            return false;
        }

        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        Bundle b = new Bundle();
        b.putString(EXTRA_FOLDER_ID, fid);
        b.putString(EXTRA_FOLDER_BT_ID, uid);
        Message msg =
                mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.MESSAGE_CHANGE_FOLDER_PATH,
                        direction, 0, b);
        mAvrcpCtSm.sendMessage(msg);
        return true;
    }

    public synchronized boolean setBrowsedPlayer(BluetoothDevice device, int id, String fid) {
        if (DBG) {
            Log.d(TAG, "setBrowsedPlayer device = " + device + " id" + id + " fid " + fid);
        }

        if (device == null) {
            Log.e(TAG, "setBrowsedPlayer device is null");
            return false;
        }

        if (!device.equals(mConnectedDevice)) {
            Log.e(TAG, "changeFolderPath device " + device + " does not match " + mConnectedDevice);
            return false;
        }

        if (!mBrowseConnected) {
            Log.e(TAG, "setBrowsedPlayer browse not yet connected");
            return false;
        }

        enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");

        Message msg =
                mAvrcpCtSm.obtainMessage(AvrcpControllerStateMachine.MESSAGE_SET_BROWSED_PLAYER, id,
                        0, fid);
        mAvrcpCtSm.sendMessage(msg);
        return true;
    }

*/
    public synchronized void fetchAttrAndPlayItem(BluetoothDevice device, String uid) {
        if (DBG) {
            Log.d(TAG, "fetchAttrAndPlayItem device = " + device + " uid " + uid);
+167 −561

File changed.

Preview size limit exceeded, changes collapsed.

+10 −2
Original line number Diff line number Diff line
@@ -26,7 +26,8 @@ import java.util.Arrays;
 */
class AvrcpPlayer {
    private static final String TAG = "AvrcpPlayer";
    private static final boolean DBG = true;
    private static final boolean DBG = false;
    private static final boolean VDBG = false;

    public static final int INVALID_ID = -1;

@@ -120,8 +121,15 @@ class AvrcpPlayer {
            .setActions(mAvailableActions).build();
    }

    public synchronized void updateCurrentTrack(TrackInfo update) {
    public synchronized boolean updateCurrentTrack(TrackInfo update) {
        if (update != null && mCurrentTrack != null
                && update.toString().equals(mCurrentTrack.toString())) {
            if (DBG) Log.d(TAG, "Update same as original");
            return false;
        }
        if (VDBG) Log.d(TAG, "Track Changed Was:" + mCurrentTrack + "now " + update);
        mCurrentTrack = update;
        return true;
    }

    public synchronized TrackInfo getCurrentTrack() {
+183 −110

File changed.

Preview size limit exceeded, changes collapsed.