Loading android/app/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java +46 −21 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading @@ -566,4 +590,5 @@ public class A2dpMediaBrowserService extends MediaBrowserService { } mBrowseConnected = false; } } android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java +7 −165 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading
android/app/src/com/android/bluetooth/a2dpsink/mbs/A2dpMediaBrowserService.java +46 −21 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } Loading @@ -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 Loading Loading @@ -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 Loading @@ -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 Loading @@ -566,4 +590,5 @@ public class A2dpMediaBrowserService extends MediaBrowserService { } mBrowseConnected = false; } }
android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java +7 −165 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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); Loading