Loading android/app/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -371,7 +371,7 @@ android:exported="true" android:enabled="@bool/profile_supported_mcp_server"> <intent-filter> <action android:name="android.bluetooth.IBluetoothMcpService" /> <action android:name="android.bluetooth.IBluetoothMcpServiceManager" /> </intent-filter> </service> <service Loading android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ * limitations under the License. */ package com.android.le_audio; package com.android.bluetooth.le_audio; import java.util.SortedSet; import java.util.TreeSet; Loading android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +13 −0 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.mcp.McpService; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; Loading @@ -62,6 +64,7 @@ public class LeAudioService extends ProfileService { private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BluetoothDevice mPreviousAudioDevice; ServiceFactory mServiceFactory = new ServiceFactory(); LeAudioNativeInterface mLeAudioNativeInterface; AudioManager mAudioManager; Loading Loading @@ -580,6 +583,11 @@ public class LeAudioService extends ProfileService { if (!mGroupIdConnectedMap.getOrDefault(myGroupId, false)) { mGroupIdConnectedMap.put(myGroupId, true); } McpService mcpService = mServiceFactory.getMcpService(); if (mcpService != null) { mcpService.setDeviceAuthorized(device, true); } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); Loading @@ -595,6 +603,11 @@ public class LeAudioService extends ProfileService { } removeStateMachine(device); } McpService mcpService = mServiceFactory.getMcpService(); if (mcpService != null) { mcpService.setDeviceAuthorized(device, false); } } } Loading android/app/src/com/android/bluetooth/mcp/McpService.java +36 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ProfileService; import java.util.HashMap; import java.util.Map; /** * Provides Media Control Profile, as a service in the Bluetooth application. * @hide Loading @@ -31,10 +34,13 @@ import com.android.bluetooth.btservice.ProfileService; public class McpService extends ProfileService { private static final boolean DBG = true; private static final boolean VDBG = false; private static final String TAG = "McpService"; private static final String TAG = "BluetoothMcpService"; private static McpService sMcpService; private static MediaControlProfile mGmcs; private Map<BluetoothDevice, Integer> mDeviceAuthorizations = new HashMap<>(); private static synchronized void setMcpService(McpService instance) { if (VDBG) { Log.d(TAG, "setMcpService(): set to: " + instance); Loading @@ -55,6 +61,10 @@ public class McpService extends ProfileService { return sMcpService; } public static void setMediaControlProfileForTesting(MediaControlProfile mediaControlProfile) { mGmcs = mediaControlProfile; } @Override protected IProfileServiceBinder initBinder() { return new BluetoothMcpServiceBinder(this); Loading @@ -80,6 +90,13 @@ public class McpService extends ProfileService { // Mark service as started setMcpService(this); if (mGmcs == null) { // Initialize the Media Control Service Server mGmcs = new MediaControlProfile(this); // Requires this service to be already started thus we have to make it an async call this.getMainThreadHandler().post(() -> mGmcs.init()); } return true; } Loading @@ -94,9 +111,12 @@ public class McpService extends ProfileService { return true; } if (mGmcs != null) { mGmcs.cleanup(); } // Mark service as stopped setMcpService(null); return true; } Loading @@ -108,17 +128,21 @@ public class McpService extends ProfileService { } public void onDeviceUnauthorized(BluetoothDevice device) { // TODO: For now just reject authorization for other than LeAudio device already authorized. // Consider intent based authorization mechanism for non-LeAudio devices. setDeviceAuthorized(device, false); } public int getDeviceAuthorization(BluetoothDevice device) { return BluetoothDevice.ACCESS_ALLOWED; } public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { int authorization = isAuthorized ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; mDeviceAuthorizations.put(device, authorization); void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { mGmcs.onDeviceAuthorizationSet(device); } public int getDeviceAuthorization(BluetoothDevice device) { // TODO: For now just reject authorization for other than LeAudio device already authorized. // Consider intent based authorization mechanism for non-LeAudio devices. return mDeviceAuthorizations.getOrDefault(device, BluetoothDevice.ACCESS_UNKNOWN); } /** Loading Loading @@ -153,6 +177,9 @@ public class McpService extends ProfileService { @Override public void cleanup() { if (mService != null) { mService.cleanup(); } mService = null; } } Loading @@ -160,5 +187,6 @@ public class McpService extends ProfileService { @Override public void dump(StringBuilder sb) { super.dump(sb); mGmcs.dump(sb); } } android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +11 −3 Original line number Diff line number Diff line Loading @@ -903,8 +903,15 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (mBluetoothGattServer == null) { BluetoothManager manager = mContext.getSystemService(BluetoothManager.class); mBluetoothGattServer = new BluetoothGattServerProxy( manager.openGattServer(mContext, mServerCallback), manager); BluetoothGattServer server = manager.openGattServer(mContext, mServerCallback); if (server == null) { Log.e(TAG, "Failed to start BluetoothGattServer for MCP"); //TODO: This now effectively makes MCP unusable, but fixes tests // Handle this error more gracefully, verify BluetoothInstrumentationTests // are passing after fix is applied return false; } mBluetoothGattServer = new BluetoothGattServerProxy(server, manager); } mGattService = Loading Loading @@ -1237,7 +1244,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (DBG) { Log.d(TAG, "Destroy"); } if (mBluetoothGattServer.removeService(mGattService)) { if (mBluetoothGattServer != null && mBluetoothGattServer.removeService(mGattService)) { if (mCallbacks != null) { mCallbacks.onServiceInstanceUnregistered(ServiceStatus.OK); } Loading Loading
android/app/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -371,7 +371,7 @@ android:exported="true" android:enabled="@bool/profile_supported_mcp_server"> <intent-filter> <action android:name="android.bluetooth.IBluetoothMcpService" /> <action android:name="android.bluetooth.IBluetoothMcpServiceManager" /> </intent-filter> </service> <service Loading
android/app/src/com/android/bluetooth/le_audio/ContentControlIdKeeper.java +1 −1 Original line number Diff line number Diff line Loading @@ -15,7 +15,7 @@ * limitations under the License. */ package com.android.le_audio; package com.android.bluetooth.le_audio; import java.util.SortedSet; import java.util.TreeSet; Loading
android/app/src/com/android/bluetooth/le_audio/LeAudioService.java +13 −0 Original line number Diff line number Diff line Loading @@ -36,7 +36,9 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.AdapterService; import com.android.bluetooth.btservice.ProfileService; import com.android.bluetooth.btservice.ServiceFactory; import com.android.bluetooth.btservice.storage.DatabaseManager; import com.android.bluetooth.mcp.McpService; import com.android.internal.annotations.VisibleForTesting; import java.util.ArrayList; Loading @@ -62,6 +64,7 @@ public class LeAudioService extends ProfileService { private DatabaseManager mDatabaseManager; private HandlerThread mStateMachinesThread; private BluetoothDevice mPreviousAudioDevice; ServiceFactory mServiceFactory = new ServiceFactory(); LeAudioNativeInterface mLeAudioNativeInterface; AudioManager mAudioManager; Loading Loading @@ -580,6 +583,11 @@ public class LeAudioService extends ProfileService { if (!mGroupIdConnectedMap.getOrDefault(myGroupId, false)) { mGroupIdConnectedMap.put(myGroupId, true); } McpService mcpService = mServiceFactory.getMcpService(); if (mcpService != null) { mcpService.setDeviceAuthorized(device, true); } } if (fromState == BluetoothProfile.STATE_CONNECTED && getConnectedDevices().isEmpty()) { setActiveDevice(null); Loading @@ -595,6 +603,11 @@ public class LeAudioService extends ProfileService { } removeStateMachine(device); } McpService mcpService = mServiceFactory.getMcpService(); if (mcpService != null) { mcpService.setDeviceAuthorized(device, false); } } } Loading
android/app/src/com/android/bluetooth/mcp/McpService.java +36 −8 Original line number Diff line number Diff line Loading @@ -24,6 +24,9 @@ import android.util.Log; import com.android.bluetooth.Utils; import com.android.bluetooth.btservice.ProfileService; import java.util.HashMap; import java.util.Map; /** * Provides Media Control Profile, as a service in the Bluetooth application. * @hide Loading @@ -31,10 +34,13 @@ import com.android.bluetooth.btservice.ProfileService; public class McpService extends ProfileService { private static final boolean DBG = true; private static final boolean VDBG = false; private static final String TAG = "McpService"; private static final String TAG = "BluetoothMcpService"; private static McpService sMcpService; private static MediaControlProfile mGmcs; private Map<BluetoothDevice, Integer> mDeviceAuthorizations = new HashMap<>(); private static synchronized void setMcpService(McpService instance) { if (VDBG) { Log.d(TAG, "setMcpService(): set to: " + instance); Loading @@ -55,6 +61,10 @@ public class McpService extends ProfileService { return sMcpService; } public static void setMediaControlProfileForTesting(MediaControlProfile mediaControlProfile) { mGmcs = mediaControlProfile; } @Override protected IProfileServiceBinder initBinder() { return new BluetoothMcpServiceBinder(this); Loading @@ -80,6 +90,13 @@ public class McpService extends ProfileService { // Mark service as started setMcpService(this); if (mGmcs == null) { // Initialize the Media Control Service Server mGmcs = new MediaControlProfile(this); // Requires this service to be already started thus we have to make it an async call this.getMainThreadHandler().post(() -> mGmcs.init()); } return true; } Loading @@ -94,9 +111,12 @@ public class McpService extends ProfileService { return true; } if (mGmcs != null) { mGmcs.cleanup(); } // Mark service as stopped setMcpService(null); return true; } Loading @@ -108,17 +128,21 @@ public class McpService extends ProfileService { } public void onDeviceUnauthorized(BluetoothDevice device) { // TODO: For now just reject authorization for other than LeAudio device already authorized. // Consider intent based authorization mechanism for non-LeAudio devices. setDeviceAuthorized(device, false); } public int getDeviceAuthorization(BluetoothDevice device) { return BluetoothDevice.ACCESS_ALLOWED; } public void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { int authorization = isAuthorized ? BluetoothDevice.ACCESS_ALLOWED : BluetoothDevice.ACCESS_REJECTED; mDeviceAuthorizations.put(device, authorization); void setDeviceAuthorized(BluetoothDevice device, boolean isAuthorized) { mGmcs.onDeviceAuthorizationSet(device); } public int getDeviceAuthorization(BluetoothDevice device) { // TODO: For now just reject authorization for other than LeAudio device already authorized. // Consider intent based authorization mechanism for non-LeAudio devices. return mDeviceAuthorizations.getOrDefault(device, BluetoothDevice.ACCESS_UNKNOWN); } /** Loading Loading @@ -153,6 +177,9 @@ public class McpService extends ProfileService { @Override public void cleanup() { if (mService != null) { mService.cleanup(); } mService = null; } } Loading @@ -160,5 +187,6 @@ public class McpService extends ProfileService { @Override public void dump(StringBuilder sb) { super.dump(sb); mGmcs.dump(sb); } }
android/app/src/com/android/bluetooth/mcp/MediaControlGattService.java +11 −3 Original line number Diff line number Diff line Loading @@ -903,8 +903,15 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (mBluetoothGattServer == null) { BluetoothManager manager = mContext.getSystemService(BluetoothManager.class); mBluetoothGattServer = new BluetoothGattServerProxy( manager.openGattServer(mContext, mServerCallback), manager); BluetoothGattServer server = manager.openGattServer(mContext, mServerCallback); if (server == null) { Log.e(TAG, "Failed to start BluetoothGattServer for MCP"); //TODO: This now effectively makes MCP unusable, but fixes tests // Handle this error more gracefully, verify BluetoothInstrumentationTests // are passing after fix is applied return false; } mBluetoothGattServer = new BluetoothGattServerProxy(server, manager); } mGattService = Loading Loading @@ -1237,7 +1244,8 @@ public class MediaControlGattService implements MediaControlGattServiceInterface if (DBG) { Log.d(TAG, "Destroy"); } if (mBluetoothGattServer.removeService(mGattService)) { if (mBluetoothGattServer != null && mBluetoothGattServer.removeService(mGattService)) { if (mCallbacks != null) { mCallbacks.onServiceInstanceUnregistered(ServiceStatus.OK); } Loading