diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
index 918aecddc5db118db3dc25dd89a0d227939ddb31..dd7493a1aee2405267ddd5a534c0f24d4cdaf477 100644
--- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
+++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapContract.java
@@ -56,69 +56,64 @@ import android.net.Uri;
* permission is needed for the provider.
*/
public final class BluetoothMapContract {
- /**
- * Constructor - should not be used
- */
+ /** Constructor - should not be used */
private BluetoothMapContract() {
- /* class should not be instantiated */
+ /* class should not be instantiated */
}
/**
- * Provider interface that should be used as intent-filter action in the provider section
- * of the manifest file.
+ * Provider interface that should be used as intent-filter action in the provider section of the
+ * manifest file.
*/
public static final String PROVIDER_INTERFACE_EMAIL =
"android.bluetooth.action.BLUETOOTH_MAP_PROVIDER";
+
public static final String PROVIDER_INTERFACE_IM =
"android.bluetooth.action.BLUETOOTH_MAP_IM_PROVIDER";
+
/**
- * The Bluetooth Message Access profile allows a remote BT-MAP client to trigger
- * an update of a folder for a specific e-mail account, register for reception
- * of new messages from the server.
+ * The Bluetooth Message Access profile allows a remote BT-MAP client to trigger an update of a
+ * folder for a specific e-mail account, register for reception of new messages from the server.
*
- * Additionally the Bluetooth Message Access profile allows a remote BT-MAP client
- * to push a message to a folder - e.g. outbox or draft. The Bluetooth profile
- * implementation will place a new message in one of these existing folders through
- * the content provider.
+ *
Additionally the Bluetooth Message Access profile allows a remote BT-MAP client to push a
+ * message to a folder - e.g. outbox or draft. The Bluetooth profile implementation will place a
+ * new message in one of these existing folders through the content provider.
*
- * ContentProvider.call() is used for these purposes, and the METHOD_UPDATE_FOLDER
- * method name shall trigger an update of the specified folder for a specified
- * account.
+ *
ContentProvider.call() is used for these purposes, and the METHOD_UPDATE_FOLDER method
+ * name shall trigger an update of the specified folder for a specified account.
*
- * This shall be a non blocking call simply starting the update, and the update should
- * both send and receive messages, depending on what makes sense for the specified
- * folder.
- * Bundle extra parameter will carry two INTEGER (long) values:
- * EXTRA_UPDATE_ACCOUNT_ID containing the account_id
- * EXTRA_UPDATE_FOLDER_ID containing the folder_id of the folder to update
+ *
This shall be a non blocking call simply starting the update, and the update should both
+ * send and receive messages, depending on what makes sense for the specified folder. Bundle
+ * extra parameter will carry two INTEGER (long) values: EXTRA_UPDATE_ACCOUNT_ID containing the
+ * account_id EXTRA_UPDATE_FOLDER_ID containing the folder_id of the folder to update
*
- * The status for send complete of messages shall be reported by updating the sent-flag
- * and e.g. for outbox messages, move them to the sent folder in the message table of the
- * content provider and trigger a change notification to any attached content observer.
+ *
The status for send complete of messages shall be reported by updating the sent-flag and
+ * e.g. for outbox messages, move them to the sent folder in the message table of the content
+ * provider and trigger a change notification to any attached content observer.
*/
public static final String METHOD_UPDATE_FOLDER = "UpdateFolder";
+
public static final String EXTRA_UPDATE_ACCOUNT_ID = "UpdateAccountId";
public static final String EXTRA_UPDATE_FOLDER_ID = "UpdateFolderId";
/**
- * The Bluetooth Message Access profile allows a remote BT-MAP Client to update
- * the owners presence and chat state
+ * The Bluetooth Message Access profile allows a remote BT-MAP Client to update the owners
+ * presence and chat state
*
- * ContentProvider.call() is used for these purposes, and the METHOD_SET_OWNER_STATUS
- * method name shall trigger a change in owner/users presence or chat properties for an
- * account or conversation.
+ *
ContentProvider.call() is used for these purposes, and the METHOD_SET_OWNER_STATUS method
+ * name shall trigger a change in owner/users presence or chat properties for an account or
+ * conversation.
*
- * This shall be a non blocking call simply setting the properties, and the change should
- * be sent to the remote server/users, depending on what property is changed.
- * Bundle extra parameter will carry following values:
- * EXTRA_ACCOUNT_ID containing the account_id
- * EXTRA_PRESENCE_STATE containing the presence state of the owner account
- * EXTRA_PRESENCE_STATUS containing the presence status text from the owner
- * EXTRA_LAST_ACTIVE containing the last activity time stamp of the owner account
- * EXTRA_CHAT_STATE containing the chat state of a specific conversation
- * EXTRA_CONVERSATION_ID containing the conversation that is changed
+ *
This shall be a non blocking call simply setting the properties, and the change should be
+ * sent to the remote server/users, depending on what property is changed. Bundle extra
+ * parameter will carry following values: EXTRA_ACCOUNT_ID containing the account_id
+ * EXTRA_PRESENCE_STATE containing the presence state of the owner account EXTRA_PRESENCE_STATUS
+ * containing the presence status text from the owner EXTRA_LAST_ACTIVE containing the last
+ * activity time stamp of the owner account EXTRA_CHAT_STATE containing the chat state of a
+ * specific conversation EXTRA_CONVERSATION_ID containing the conversation that is changed
*/
public static final String METHOD_SET_OWNER_STATUS = "SetOwnerStatus";
+
public static final String EXTRA_ACCOUNT_ID = "AccountId"; // Is this needed
public static final String EXTRA_PRESENCE_STATE = "PresenceState";
public static final String EXTRA_PRESENCE_STATUS = "PresenceStatus";
@@ -130,73 +125,71 @@ public final class BluetoothMapContract {
* The Bluetooth Message Access profile can inform the messaging application of the Bluetooth
* state, whether is is turned 'on' or 'off'
*
- * ContentProvider.call() is used for these purposes, and the METHOD_SET_BLUETOOTH_STATE
- * method name shall trigger a change in owner/users presence or chat properties for an
- * account or conversation.
+ *
ContentProvider.call() is used for these purposes, and the METHOD_SET_BLUETOOTH_STATE
+ * method name shall trigger a change in owner/users presence or chat properties for an account
+ * or conversation.
*
- * This shall be a non blocking call simply setting the properties.
+ *
This shall be a non blocking call simply setting the properties.
*
- * Bundle extra parameter will carry following values:
- * EXTRA_BLUETOOTH_STATE containing the state of the Bluetooth connectivity
+ *
Bundle extra parameter will carry following values: EXTRA_BLUETOOTH_STATE containing the
+ * state of the Bluetooth connectivity
*/
public static final String METHOD_SET_BLUETOOTH_STATE = "SetBtState";
+
public static final String EXTRA_BLUETOOTH_STATE = "BluetoothState";
/**
- * These column names are used as last path segment of the URI (getLastPathSegment()).
- * Access to a specific row in the tables is done by using the where-clause, hence
- * support for .../#id if not needed for the Email clients.
- * The URI format for accessing the tables are as follows:
- * content://ProviderAuthority/TABLE_ACCOUNT
- * content://ProviderAuthority/account_id/TABLE_MESSAGE
- * content://ProviderAuthority/account_id/TABLE_FOLDER
- * content://ProviderAuthority/account_id/TABLE_CONVERSATION
- * content://ProviderAuthority/account_id/TABLE_CONVOCONTACT
- **/
+ * These column names are used as last path segment of the URI (getLastPathSegment()). Access to
+ * a specific row in the tables is done by using the where-clause, hence support for .../#id if
+ * not needed for the Email clients. The URI format for accessing the tables are as follows:
+ * content://ProviderAuthority/TABLE_ACCOUNT
+ * content://ProviderAuthority/account_id/TABLE_MESSAGE
+ * content://ProviderAuthority/account_id/TABLE_FOLDER
+ * content://ProviderAuthority/account_id/TABLE_CONVERSATION
+ * content://ProviderAuthority/account_id/TABLE_CONVOCONTACT
+ */
/**
- * Build URI representing the given Accounts data-set in a
- * Bluetooth provider. When queried, the direct URI for the account
- * with the given accountID is returned.
+ * Build URI representing the given Accounts data-set in a Bluetooth provider. When queried, the
+ * direct URI for the account with the given accountID is returned.
*/
public static Uri buildAccountUri(String authority) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(TABLE_ACCOUNT)
.build();
}
/**
- * Build URI representing the given Account data-set with specific Id in a
- * Bluetooth provider. When queried, the direct URI for the account
- * with the given accountID is returned.
+ * Build URI representing the given Account data-set with specific Id in a Bluetooth provider.
+ * When queried, the direct URI for the account with the given accountID is returned.
*/
public static Uri buildAccountUriwithId(String authority, String accountId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(TABLE_ACCOUNT)
.appendPath(accountId)
.build();
}
- /**
- * Build URI representing the entire Message table in a
- * Bluetooth provider.
- */
+ /** Build URI representing the entire Message table in a Bluetooth provider. */
public static Uri buildMessageUri(String authority) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(TABLE_MESSAGE)
.build();
}
/**
- * Build URI representing the given Message data-set in a
- * Bluetooth provider. When queried, the URI for the Messages
- * with the given accountID is returned.
+ * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the
+ * URI for the Messages with the given accountID is returned.
*/
public static Uri buildMessageUri(String authority, String accountId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_MESSAGE)
@@ -204,12 +197,12 @@ public final class BluetoothMapContract {
}
/**
- * Build URI representing the given Message data-set with specific messageId in a
- * Bluetooth provider. When queried, the direct URI for the account
- * with the given accountID is returned.
+ * Build URI representing the given Message data-set with specific messageId in a Bluetooth
+ * provider. When queried, the direct URI for the account with the given accountID is returned.
*/
public static Uri buildMessageUriWithId(String authority, String accountId, String messageId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_MESSAGE)
@@ -218,12 +211,12 @@ public final class BluetoothMapContract {
}
/**
- * Build URI representing the given Message data-set in a
- * Bluetooth provider. When queried, the direct URI for the folder
- * with the given accountID is returned.
+ * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the
+ * direct URI for the folder with the given accountID is returned.
*/
public static Uri buildFolderUri(String authority, String accountId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_FOLDER)
@@ -231,12 +224,12 @@ public final class BluetoothMapContract {
}
/**
- * Build URI representing the given Message data-set in a
- * Bluetooth provider. When queried, the direct URI for the conversation
- * with the given accountID is returned.
+ * Build URI representing the given Message data-set in a Bluetooth provider. When queried, the
+ * direct URI for the conversation with the given accountID is returned.
*/
public static Uri buildConversationUri(String authority, String accountId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_CONVERSATION)
@@ -244,24 +237,24 @@ public final class BluetoothMapContract {
}
/**
- * Build URI representing the given Contact data-set in a
- * Bluetooth provider. When queried, the direct URI for the contacts
- * with the given accountID is returned.
+ * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the
+ * direct URI for the contacts with the given accountID is returned.
*/
public static Uri buildConvoContactsUri(String authority) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(TABLE_CONVOCONTACT)
.build();
}
/**
- * Build URI representing the given Contact data-set in a
- * Bluetooth provider. When queried, the direct URI for the contacts
- * with the given accountID is returned.
+ * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the
+ * direct URI for the contacts with the given accountID is returned.
*/
public static Uri buildConvoContactsUri(String authority, String accountId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_CONVOCONTACT)
@@ -269,13 +262,13 @@ public final class BluetoothMapContract {
}
/**
- * Build URI representing the given Contact data-set in a
- * Bluetooth provider. When queried, the direct URI for the contact
- * with the given contactID and accountID is returned.
+ * Build URI representing the given Contact data-set in a Bluetooth provider. When queried, the
+ * direct URI for the contact with the given contactID and accountID is returned.
*/
- public static Uri buildConvoContactsUriWithId(String authority, String accountId,
- String contactId) {
- return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT)
+ public static Uri buildConvoContactsUriWithId(
+ String authority, String accountId, String contactId) {
+ return new Uri.Builder()
+ .scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.appendPath(accountId)
.appendPath(TABLE_CONVOCONTACT)
@@ -283,572 +276,529 @@ public final class BluetoothMapContract {
.build();
}
- /**
- * @hide
- */
+ /** @hide */
public static final String TABLE_ACCOUNT = "Account";
+
public static final String TABLE_MESSAGE = "Message";
public static final String TABLE_MESSAGE_PART = "Part";
public static final String TABLE_FOLDER = "Folder";
public static final String TABLE_CONVERSATION = "Conversation";
public static final String TABLE_CONVOCONTACT = "ConvoContact";
-
/**
- * Mandatory folders for the Bluetooth message access profile.
- * The email client shall at least implement the following root folders.
- * E.g. as a mapping for them such that the naming will match the underlying
- * matching folder ID's.
+ * Mandatory folders for the Bluetooth message access profile. The email client shall at least
+ * implement the following root folders. E.g. as a mapping for them such that the naming will
+ * match the underlying matching folder ID's.
*/
public static final String FOLDER_NAME_INBOX = "inbox";
+
public static final String FOLDER_NAME_SENT = "sent";
public static final String FOLDER_NAME_OUTBOX = "outbox";
public static final String FOLDER_NAME_DRAFT = "draft";
public static final String FOLDER_NAME_DELETED = "deleted";
public static final String FOLDER_NAME_OTHER = "other";
- /**
- * Folder IDs to be used with Instant Messaging virtual folders
- */
+ /** Folder IDs to be used with Instant Messaging virtual folders */
public static final long FOLDER_ID_OTHER = 0;
+
public static final long FOLDER_ID_INBOX = 1;
public static final long FOLDER_ID_SENT = 2;
public static final long FOLDER_ID_DRAFT = 3;
public static final long FOLDER_ID_OUTBOX = 4;
public static final long FOLDER_ID_DELETED = 5;
-
/**
- * To push RFC2822 encoded messages into a folder and read RFC2822 encoded messages from
- * a folder, the openFile() interface will be used as follows:
- * Open a file descriptor to a message.
- * Two modes supported for read: With and without attachments.
- * One mode exist for write and the actual content will be with or without
- * attachments.
+ * To push RFC2822 encoded messages into a folder and read RFC2822 encoded messages from a
+ * folder, the openFile() interface will be used as follows: Open a file descriptor to a
+ * message. Two modes supported for read: With and without attachments. One mode exist for write
+ * and the actual content will be with or without attachments.
*
- * mode will be "r" for read and "w" for write, never "rw".
+ *
mode will be "r" for read and "w" for write, never "rw".
*
- * URI format:
- * The URI scheme is as follows.
- * For reading messages with attachments:
- * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId
- * Note: This shall be an offline operation, including only message parts and attachments
- * already downloaded to the device.
+ *
URI format: The URI scheme is as follows. For reading messages with attachments:
+ * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId Note: This shall be an offline
+ * operation, including only message parts and attachments already downloaded to the device.
*
- * For reading messages without attachments:
- * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_NO_ATTACHMENTS
- * Note: This shall be an offline operation, including only message parts already
- * downloaded to the device.
+ *
For reading messages without attachments:
+ * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_NO_ATTACHMENTS Note: This
+ * shall be an offline operation, including only message parts already downloaded to the device.
*
- * For downloading and reading messages with attachments:
- * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD
- * Note: This shall download the message content and all attachments if possible,
- * else throw an IOException.
+ *
For downloading and reading messages with attachments:
+ * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD Note: This shall
+ * download the message content and all attachments if possible, else throw an IOException.
*
- * For downloading and reading messages without attachments:
- * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD_NO_ATTACHMENTS
- * Note: This shall download the message content if possible, else throw an IOException.
+ *
For downloading and reading messages without attachments:
+ * content://ProviderAuthority/account_id/TABLE_MESSAGE/msgId/FILE_MSG_DOWNLOAD_NO_ATTACHMENTS
+ * Note: This shall download the message content if possible, else throw an IOException.
*
- * When reading from the file descriptor, the content provider shall return a stream
- * of bytes containing a RFC2822 encoded message, as if the message was send to an email
- * server.
+ *
When reading from the file descriptor, the content provider shall return a stream of bytes
+ * containing a RFC2822 encoded message, as if the message was send to an email server.
*
- * When a byte stream is written to the file descriptor, the content provider shall
- * decode the RFC2822 encoded data and insert the message into the TABLE_MESSAGE at the ID
- * supplied in URI - additionally the message content shall be stored in the underlying
- * data base structure as if the message was received from an email server. The Message ID
- * will be created using a insert on the TABLE_MESSAGE prior to calling openFile().
- * Hence the procedure for inserting a message is:
- * - uri/msgId = insert(uri, value: folderId=xxx)
- * - fd = openFile(uri/msgId)
- * - fd.write (RFC2822 encoded data)
+ *
When a byte stream is written to the file descriptor, the content provider shall decode
+ * the RFC2822 encoded data and insert the message into the TABLE_MESSAGE at the ID supplied in
+ * URI - additionally the message content shall be stored in the underlying data base structure
+ * as if the message was received from an email server. The Message ID will be created using a
+ * insert on the TABLE_MESSAGE prior to calling openFile(). Hence the procedure for inserting a
+ * message is: - uri/msgId = insert(uri, value: folderId=xxx) - fd = openFile(uri/msgId) -
+ * fd.write (RFC2822 encoded data)
*
- * The Bluetooth Message Access Client might not know what to put into the From:
- * header nor have a valid time stamp, hence the content provider shall check
- * if the From: and Date: headers have been set by the message written, else
- * it must fill in appropriate values.
+ *
The Bluetooth Message Access Client might not know what to put into the From: header nor
+ * have a valid time stamp, hence the content provider shall check if the From: and Date:
+ * headers have been set by the message written, else it must fill in appropriate values.
*/
public static final String FILE_MSG_NO_ATTACHMENTS = "NO_ATTACHMENTS";
+
public static final String FILE_MSG_DOWNLOAD = "DOWNLOAD";
public static final String FILE_MSG_DOWNLOAD_NO_ATTACHMENTS = "DOWNLOAD_NO_ATTACHMENTS";
/**
- * Account Table
- * The columns needed to supply account information.
- * The e-mail client app may choose to expose all e-mails as being from the same account,
- * but it is not recommended, as this would be a violation of the Bluetooth specification.
- * The Bluetooth Message Access settings activity will provide the user the ability to
- * change the FLAG_EXPOSE values for each account in this table.
- * The Bluetooth Message Access service will read the values when Bluetooth is turned on,
- * and again on every notified change through the content observer interface.
+ * Account Table The columns needed to supply account information. The e-mail client app may
+ * choose to expose all e-mails as being from the same account, but it is not recommended, as
+ * this would be a violation of the Bluetooth specification. The Bluetooth Message Access
+ * settings activity will provide the user the ability to change the FLAG_EXPOSE values for each
+ * account in this table. The Bluetooth Message Access service will read the values when
+ * Bluetooth is turned on, and again on every notified change through the content observer
+ * interface.
*/
public interface AccountColumns {
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
+ *
+ * Type: INTEGER (long)
*/
String _ID = "_id";
/**
- * The account name to display to the user on the device when selecting whether
- * or not to share the account over Bluetooth.
- *
- * The account display name should not reveal any sensitive information e.g. email-
- * address, as it will be added to the Bluetooth SDP record, which can be read by
- * any Bluetooth enabled device. (Access to any account content is only provided to
- * authenticated devices). It is recommended that if the email client uses the email
- * address as account name, then the address should be obfuscated (i.e. replace "@"
- * with ".")
- *
Type: TEXT
- * read-only
+ * The account name to display to the user on the device when selecting whether or not to
+ * share the account over Bluetooth.
+ *
+ * The account display name should not reveal any sensitive information e.g. email-
+ * address, as it will be added to the Bluetooth SDP record, which can be read by any
+ * Bluetooth enabled device. (Access to any account content is only provided to
+ * authenticated devices). It is recommended that if the email client uses the email address
+ * as account name, then the address should be obfuscated (i.e. replace "@" with ".")
+ *
+ *
Type: TEXT read-only
*/
String ACCOUNT_DISPLAY_NAME = "account_display_name";
/**
- * Expose this account to other authenticated Bluetooth devices. If the expose flag
- * is set, this account will be listed as an available account to access from another
- * Bluetooth device.
+ * Expose this account to other authenticated Bluetooth devices. If the expose flag is set,
+ * this account will be listed as an available account to access from another Bluetooth
+ * device.
*
- * This is a read/write flag, that can be set either from within the E-mail client
- * UI or the Bluetooth settings menu.
+ *
This is a read/write flag, that can be set either from within the E-mail client UI or
+ * the Bluetooth settings menu.
*
- * It is recommended to either ask the user whether to expose the account, or set this
- * to "show" as default.
+ *
It is recommended to either ask the user whether to expose the account, or set this to
+ * "show" as default.
*
- * This setting shall not be used to enforce whether or not an account should be shared
- * or not if the account is bound by an administrative security policy. In this case
- * the email app should not list the account at all if it is not to be sharable over BT.
+ *
This setting shall not be used to enforce whether or not an account should be shared
+ * or not if the account is bound by an administrative security policy. In this case the
+ * email app should not list the account at all if it is not to be sharable over BT.
*
- *
Type: INTEGER (boolean) hide = 0, show = 1
+ * Type: INTEGER (boolean) hide = 0, show = 1
*/
String FLAG_EXPOSE = "flag_expose";
-
/**
* The account unique identifier representing this account. For most IM clients this will be
* the fully qualified user name to which an invite message can be sent, from another use.
*
- * e.g.: "map_test_user_12345@gmail.com" - for a Hangouts account
+ *
e.g.: "map_test_user_12345@gmail.com" - for a Hangouts account
*
- * This value will only be visible to authenticated Bluetooth devices, and will be
+ *
This value will only be visible to authenticated Bluetooth devices, and will be
* transmitted using an encrypted link.
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String ACCOUNT_UCI = "account_uci";
-
/**
- * The Bluetooth SIG maintains a list of assigned numbers(text strings) for IM clients.
- * If your client/account has such a string, this is the place to return it.
- * If supported by both devices, the presence of this prefix will make it possible to
- * respond to a message by making a voice-call, using the same account information.
- * (The call will be made using the HandsFree profile)
+ * The Bluetooth SIG maintains a list of assigned numbers(text strings) for IM clients. If
+ * your client/account has such a string, this is the place to return it. If supported by
+ * both devices, the presence of this prefix will make it possible to respond to a message
+ * by making a voice-call, using the same account information. (The call will be made using
+ * the HandsFree profile)
* https://www.bluetooth.org/en-us/specification/assigned-numbers/uniform-caller-identifiers
*
- * e.g.: "hgus" - for Hangouts
+ *
e.g.: "hgus" - for Hangouts
*
- *
Type: TEXT
- * read-only
+ * Type: TEXT read-only
*/
String ACCOUNT_UCI_PREFIX = "account_uci_PREFIX";
-
}
/**
- * Message Data Parts Table
- * The columns needed to contain the actual data of the messageparts in IM messages.
- * Each "part" has its own row and represent a single mime-part in a multipart-mime
+ * Message Data Parts Table The columns needed to contain the actual data of the messageparts in
+ * IM messages. Each "part" has its own row and represent a single mime-part in a multipart-mime
* formatted message.
- *
*/
public interface MessagePartColumns {
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String _ID = "_id";
+
// FIXME add message parts for IM attachments
/**
- * is this a text part yes/no?
- *
Type: TEXT
- * read-only
+ * is this a text part yes/no?
+ *
+ * Type: TEXT read-only
*/
String TEXT = "text";
/**
- * The charset used in the content if it is text or 8BIT if it is
- * binary data
+ * The charset used in the content if it is text or 8BIT if it is binary data
*
- *
Type: TEXT
- * read-only
+ * Type: TEXT read-only
*/
String CHARSET = "charset";
/**
- * The filename representing the data file of the raw data in the database
- * If this is empty, then it must be text and part of the message body.
- * This is the name that the data will have when it is included as attachment
+ * The filename representing the data file of the raw data in the database If this is empty,
+ * then it must be text and part of the message body. This is the name that the data will
+ * have when it is included as attachment
*
- *
Type: TEXT
- * read-only
+ * Type: TEXT read-only
*/
-
String FILENAME = "filename";
/**
- * Identifier for the content in the data. This can be used to
- * refer directly to the data in the body part.
+ * Identifier for the content in the data. This can be used to refer directly to the data in
+ * the body part.
*
- *
Type: TEXT
- * read-only
+ * Type: TEXT read-only
*/
-
String CONTENT_ID = "cid";
/**
* The raw data in either text format or binary format
*
- *
Type: BLOB
- * read-only
+ * Type: BLOB read-only
*/
String RAW_DATA = "raw_data";
-
}
/**
- * The actual message table containing all messages.
- * Content that must support filtering using WHERE clauses:
- * - To, From, Cc, Bcc, Date, ReadFlag, PriorityFlag, folder_id, account_id
- * Additional content that must be supplied:
- * - Subject, AttachmentFlag, LoadedState, MessageSize, AttachmentSize
- * Content that must support update:
- * - FLAG_READ and FOLDER_ID (FOLDER_ID is used to move a message to deleted)
- * Additional insert of a new message with the following values shall be supported:
- * - FOLDER_ID
+ * The actual message table containing all messages. Content that must support filtering using
+ * WHERE clauses: - To, From, Cc, Bcc, Date, ReadFlag, PriorityFlag, folder_id, account_id
+ * Additional content that must be supplied: - Subject, AttachmentFlag, LoadedState,
+ * MessageSize, AttachmentSize Content that must support update: - FLAG_READ and FOLDER_ID
+ * (FOLDER_ID is used to move a message to deleted) Additional insert of a new message with the
+ * following values shall be supported: - FOLDER_ID
*
- * When doing an insert on this table, the actual content of the message (subject,
- * date etc) written through file-i/o takes precedence over the inserted values and should
- * overwrite them.
+ *
When doing an insert on this table, the actual content of the message (subject, date etc)
+ * written through file-i/o takes precedence over the inserted values and should overwrite them.
*/
public interface MessageColumns extends EmailMessageColumns {
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
+ *
+ * Type: INTEGER (long)
*/
String _ID = "_id";
/**
- * The date the message was received as a unix timestamp
- * (miliseconds since 00:00:00 UTC 1/1-1970).
+ * The date the message was received as a unix timestamp (miliseconds since 00:00:00 UTC
+ * 1/1-1970).
*
- *
Type: INTEGER (long)
- * read-only
+ * Type: INTEGER (long) read-only
*/
String DATE = "date";
- //TODO REMOVE WHEN Parts Table is in place
+ // TODO REMOVE WHEN Parts Table is in place
/**
* Message body. Used by Instant Messaging
- *
Type: TEXT
- * read-only.
+ *
+ * Type: TEXT read-only.
*/
String BODY = "body";
/**
* Message subject.
- *
Type: TEXT
- * read-only.
+ *
+ * Type: TEXT read-only.
*/
String SUBJECT = "subject";
/**
* Message Read flag
- *
Type: INTEGER (boolean) unread = 0, read = 1
- * read/write
+ *
+ * Type: INTEGER (boolean) unread = 0, read = 1 read/write
*/
String FLAG_READ = "flag_read";
/**
* Message Priority flag
- *
Type: INTEGER (boolean) normal priority = 0, high priority = 1
- * read-only
+ *
+ * Type: INTEGER (boolean) normal priority = 0, high priority = 1 read-only
*/
String FLAG_HIGH_PRIORITY = "high_priority";
/**
* Reception state - the amount of the message that have been loaded from the server.
- *
Type: TEXT see RECEPTION_STATE_* constants below
- * read-only
+ *
+ * Type: TEXT see RECEPTION_STATE_* constants below read-only
*/
String RECEPTION_STATE = "reception_state";
/**
* Delivery state - the amount of the message that have been loaded from the server.
- *
Type: TEXT see DELIVERY_STATE_* constants below
- * read-only
+ *
+ * Type: TEXT see DELIVERY_STATE_* constants below read-only
*/
String DEVILERY_STATE = "delivery_state";
- /** To be able to filter messages with attachments, we need this flag.
- *
Type: INTEGER (boolean) no attachment = 0, attachment = 1
- * read-only
+ /**
+ * To be able to filter messages with attachments, we need this flag.
+ *
+ * Type: INTEGER (boolean) no attachment = 0, attachment = 1 read-only
*/
String FLAG_ATTACHMENT = "flag_attachment";
- /** The overall size in bytes of the attachments of the message.
- *
Type: INTEGER
+ /**
+ * The overall size in bytes of the attachments of the message.
+ *
+ * Type: INTEGER
*/
String ATTACHMENT_SIZE = "attachment_size";
- /** The mine type of the attachments for the message.
- *
Type: TEXT
- * read-only
+ /**
+ * The mine type of the attachments for the message.
+ *
+ * Type: TEXT read-only
*/
String ATTACHMENT_MINE_TYPES = "attachment_mime_types";
- /** The overall size in bytes of the message including any attachments.
- * This value is informative only and should be the size an email client
- * would display as size for the message.
- *
Type: INTEGER
- * read-only
+ /**
+ * The overall size in bytes of the message including any attachments. This value is
+ * informative only and should be the size an email client would display as size for the
+ * message.
+ *
+ * Type: INTEGER read-only
*/
String MESSAGE_SIZE = "message_size";
- /** Indicates that the message or a part of it is protected by a DRM scheme.
- *
Type: INTEGER (boolean) no DRM = 0, DRM protected = 1
- * read-only
+ /**
+ * Indicates that the message or a part of it is protected by a DRM scheme.
+ *
+ * Type: INTEGER (boolean) no DRM = 0, DRM protected = 1 read-only
*/
String FLAG_PROTECTED = "flag_protected";
/**
- * A comma-delimited list of FROM addresses in RFC2822 format.
- * The list must be compatible with Rfc822Tokenizer.tokenize();
- *
Type: TEXT
- * read-only
+ * A comma-delimited list of FROM addresses in RFC2822 format. The list must be compatible
+ * with Rfc822Tokenizer.tokenize();
+ *
+ * Type: TEXT read-only
*/
String FROM_LIST = "from_list";
/**
- * A comma-delimited list of TO addresses in RFC2822 format.
- * The list must be compatible with Rfc822Tokenizer.tokenize();
- *
Type: TEXT
- * read-only
+ * A comma-delimited list of TO addresses in RFC2822 format. The list must be compatible
+ * with Rfc822Tokenizer.tokenize();
+ *
+ * Type: TEXT read-only
*/
String TO_LIST = "to_list";
/**
* The unique ID for a row in the folder table in which this message belongs.
- *
Type: INTEGER (long)
- * read/write
+ *
+ * Type: INTEGER (long) read/write
*/
String FOLDER_ID = "folder_id";
/**
* The unique ID for a row in the account table which owns this message.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String ACCOUNT_ID = "account_id";
/**
- * The ID identify the thread/conversation a message belongs to.
- * If no thread id is available, set value to "-1"
- *
Type: INTEGER (long)
- * read-only
+ * The ID identify the thread/conversation a message belongs to. If no thread id is
+ * available, set value to "-1"
+ *
+ * Type: INTEGER (long) read-only
*/
String THREAD_ID = "thread_id";
/**
* The Name of the thread/conversation a message belongs to.
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String THREAD_NAME = "thread_name";
}
public interface EmailMessageColumns {
-
/**
- * A comma-delimited list of CC addresses in RFC2822 format.
- * The list must be compatible with Rfc822Tokenizer.tokenize();
- *
Type: TEXT
- * read-only
+ * A comma-delimited list of CC addresses in RFC2822 format. The list must be compatible
+ * with Rfc822Tokenizer.tokenize();
+ *
+ * Type: TEXT read-only
*/
String CC_LIST = "cc_list";
/**
- * A comma-delimited list of BCC addresses in RFC2822 format.
- * The list must be compatible with Rfc822Tokenizer.tokenize();
- *
Type: TEXT
- * read-only
+ * A comma-delimited list of BCC addresses in RFC2822 format. The list must be compatible
+ * with Rfc822Tokenizer.tokenize();
+ *
+ * Type: TEXT read-only
*/
String BCC_LIST = "bcc_list";
/**
- * A comma-delimited list of REPLY-TO addresses in RFC2822 format.
- * The list must be compatible with Rfc822Tokenizer.tokenize();
- *
Type: TEXT
- * read-only
+ * A comma-delimited list of REPLY-TO addresses in RFC2822 format. The list must be
+ * compatible with Rfc822Tokenizer.tokenize();
+ *
+ * Type: TEXT read-only
*/
String REPLY_TO_LIST = "reply_to_List";
-
-
}
- /**
- * Indicates the complete message has been delivered to the recipient.
- */
+ /** Indicates the complete message has been delivered to the recipient. */
public static final String DELIVERY_STATE_DELIVERED = "delivered";
- /**
- * Indicates that the complete message has been sent from the MSE to the remote network.
- */
+
+ /** Indicates that the complete message has been sent from the MSE to the remote network. */
public static final String DELIVERY_STATE_SENT = "sent";
/**
- * Indicates that the message, including any attachments, has been received from the
- * server to the device.
+ * Indicates that the message, including any attachments, has been received from the server to
+ * the device.
*/
public static final String RECEPTION_STATE_COMPLETE = "complete";
- /**
- * Indicates the message is partially received from the email server.
- */
+
+ /** Indicates the message is partially received from the email server. */
public static final String RECEPTION_STATE_FRACTIONED = "fractioned";
- /**
- * Indicates that only a notification about the message have been received.
- */
+
+ /** Indicates that only a notification about the message have been received. */
public static final String RECEPTION_STATE_NOTIFICATION = "notification";
/**
- * Message folder structure
- * MAP enforces use of a folder structure with mandatory folders:
- * - inbox, outbox, sent, deleted, draft
- * User defined folders are supported.
- * The folder table must provide filtering (use of WHERE clauses) of the following entries:
- * - account_id (linking the folder to an e-mail account)
- * - parent_id (linking the folders individually)
- * The folder table must have a folder name for each entry, and the mandatory folders
- * MUST exist for each account_id. The folders may be empty.
- * Use the FOLDER_NAME_xxx constants for the mandatory folders. Their names must
- * not be translated into other languages, as the folder browsing is string based, and
- * many Bluetooth Message Clients will use these strings to navigate to the folders.
+ * Message folder structure MAP enforces use of a folder structure with mandatory folders: -
+ * inbox, outbox, sent, deleted, draft User defined folders are supported. The folder table must
+ * provide filtering (use of WHERE clauses) of the following entries: - account_id (linking the
+ * folder to an e-mail account) - parent_id (linking the folders individually) The folder table
+ * must have a folder name for each entry, and the mandatory folders MUST exist for each
+ * account_id. The folders may be empty. Use the FOLDER_NAME_xxx constants for the mandatory
+ * folders. Their names must not be translated into other languages, as the folder browsing is
+ * string based, and many Bluetooth Message Clients will use these strings to navigate to the
+ * folders.
*/
public interface FolderColumns {
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String _ID = "_id";
/**
* The folder display name to present to the user.
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String NAME = "name";
/**
* The _id-key to the account this folder refers to.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String ACCOUNT_ID = "account_id";
/**
* The _id-key to the parent folder. -1 for root folders.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String PARENT_FOLDER_ID = "parent_id";
}
/**
* Message conversation structure. Enables use of a conversation structure for messages across
- * folders, further binding contacts to conversations.
- * Content that must be supplied:
- * - Name, LastActivity, ReadStatus, VersionCounter
- * Content that must support update:
- * - READ_STATUS, LAST_ACTIVITY and VERSION_COUNTER (VERSION_COUNTER used to validity of _ID)
- * Additional insert of a new conversation with the following values shall be supported:
- * - FOLDER_ID
- * When querying this table, the cursor returned must contain one row for each contact member
- * in a thread.
- * For filter/search parameters attributes to the URI will be used. The following columns must
- * support filtering:
- * - ConvoContactColumns.NAME
- * - ConversationColumns.THREAD_ID
- * - ConversationColumns.LAST_ACTIVITY
- * - ConversationColumns.READ_STATUS
+ * folders, further binding contacts to conversations. Content that must be supplied: - Name,
+ * LastActivity, ReadStatus, VersionCounter Content that must support update: - READ_STATUS,
+ * LAST_ACTIVITY and VERSION_COUNTER (VERSION_COUNTER used to validity of _ID) Additional insert
+ * of a new conversation with the following values shall be supported: - FOLDER_ID When querying
+ * this table, the cursor returned must contain one row for each contact member in a thread. For
+ * filter/search parameters attributes to the URI will be used. The following columns must
+ * support filtering: - ConvoContactColumns.NAME - ConversationColumns.THREAD_ID -
+ * ConversationColumns.LAST_ACTIVITY - ConversationColumns.READ_STATUS
*/
public interface ConversationColumns extends ConvoContactColumns {
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
-// Should not be needed anymore public static final String _ID = "_id";
+ // Should not be needed anymore public static final String _ID = "_id";
/**
* The unique ID for a Thread.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String THREAD_ID = "thread_id";
/**
* The unique ID for a row.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
-// TODO: IS THIS NECESSARY - or do we need the thread ID to hold thread Id from message
-// or can we be sure we are in control and can use the _ID and put that in the message DB
- //public static final String THREAD_ID = "thread_id";
+ // TODO: IS THIS NECESSARY - or do we need the thread ID to hold thread Id from message
+ // or can we be sure we are in control and can use the _ID and put that in the message
+ // DB
+ // public static final String THREAD_ID = "thread_id";
/**
* The type of conversation, see {@link ConversationType}
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
-// TODO: IS THIS NECESSARY - no conversation type is available in the latest,
-// guess it can be found from number of contacts in the conversation
- //public static final String TYPE = "type";
+ // TODO: IS THIS NECESSARY - no conversation type is available in the latest,
+ // guess it can be found from number of contacts in the conversation
+ // public static final String TYPE = "type";
/**
* The name of the conversation, e.g. group name in case of group chat
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String THREAD_NAME = "thread_name";
/**
- * The time stamp of the last activity in the conversation as a unix timestamp
- * (miliseconds since 00:00:00 UTC 1/1-1970)
- *
Type: INTEGER (long)
- * read-only
+ * The time stamp of the last activity in the conversation as a unix timestamp (miliseconds
+ * since 00:00:00 UTC 1/1-1970)
+ *
+ * Type: INTEGER (long) read-only
*/
String LAST_THREAD_ACTIVITY = "last_thread_activity";
/**
* The status on the conversation, either 'read' or 'unread'
- *
Type: INTEGER (boolean) unread = 0, read = 1
- * read/write
+ *
+ * Type: INTEGER (boolean) unread = 0, read = 1 read/write
*/
String READ_STATUS = "read_status";
/**
* A counter that keep tack of version of the table content, count up on ID reuse
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
-// TODO: IS THIS NECESSARY - skal den ligge i databasen?
+ // TODO: IS THIS NECESSARY - skal den ligge i databasen?
// CB: If we need it, it must be in the database, or initialized with a random value at
// BT-ON
// UPDATE: TODO: Change to the last_activity time stamp (as a long value). This will
@@ -856,110 +806,96 @@ public final class BluetoothMapContract {
String VERSION_COUNTER = "version_counter";
/**
- * A short description of the latest activity on conversation - typically
- * part of the last message.
- *
Type: TEXT
- * read-only
+ * A short description of the latest activity on conversation - typically part of the last
+ * message.
+ *
+ * Type: TEXT read-only
*/
String SUMMARY = "convo_summary";
-
-
}
/**
- * MAP enables access to contacts for the conversation
- * The conversation table must provide filtering (using WHERE clauses) of following entries:
- * - convo_id linking contacts to conversations
- * - x_bt_uid linking contacts to PBAP contacts
- * The conversation contact table must have a convo_id and a name for each entry.
+ * MAP enables access to contacts for the conversation The conversation table must provide
+ * filtering (using WHERE clauses) of following entries: - convo_id linking contacts to
+ * conversations - x_bt_uid linking contacts to PBAP contacts The conversation contact table
+ * must have a convo_id and a name for each entry.
*/
public interface ConvoContactColumns extends ChatStatusColumns, PresenceColumns {
/**
* The unique ID for a contact in Conversation
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
-// Should not be needed anymore public static final String _ID = "_id";
+ // Should not be needed anymore public static final String _ID = "_id";
/**
* The ID of the conversation the contact is part of.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String CONVO_ID = "convo_id";
/**
* The name of contact in instant message application
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String NAME = "name";
/**
* The nickname of contact in instant message group chat conversation.
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String NICKNAME = "nickname";
-
/**
* The unique ID for all Bluetooth contacts available through PBAP.
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String X_BT_UID = "x_bt_uid";
/**
- * The unique ID for the contact within the domain of the interfacing service.
- * (UCI: Unique Call Identity)
- * It is expected that a message send to this ID will reach the recipient regardless
- * through which interface the message is send.
- * For E-mail this will be the e-mail address, for Google+ this will be the e-mail address
- * associated with the contact account.
- * This ID
- *
Type: TEXT
- * read-only
+ * The unique ID for the contact within the domain of the interfacing service. (UCI: Unique
+ * Call Identity) It is expected that a message send to this ID will reach the recipient
+ * regardless through which interface the message is send. For E-mail this will be the
+ * e-mail address, for Google+ this will be the e-mail address associated with the contact
+ * account. This ID
+ *
+ * Type: TEXT read-only
*/
String UCI = "x_bt_uci";
}
- /**
- * The name of query parameter used to filter on recipient
- */
+ /** The name of query parameter used to filter on recipient */
public static final String FILTER_RECIPIENT_SUBSTRING = "rec_sub_str";
- /**
- * The name of query parameter used to filter on originator
- */
+ /** The name of query parameter used to filter on originator */
public static final String FILTER_ORIGINATOR_SUBSTRING = "org_sub_str";
/**
- * The name of query parameter used to filter on read status.
- * - true - return only threads with all messages marked as read
- * - false - return only threads with one or more unread messages
- * - omitted as query parameter - do not filter on read status
+ * The name of query parameter used to filter on read status. - true - return only threads with
+ * all messages marked as read - false - return only threads with one or more unread messages -
+ * omitted as query parameter - do not filter on read status
*/
public static final String FILTER_READ_STATUS = "read";
/**
- * Time in ms since epoch. For conversations this will be for last activity
- * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970)
+ * Time in ms since epoch. For conversations this will be for last activity as a unix timestamp
+ * (miliseconds since 00:00:00 UTC 1/1-1970)
*/
public static final String FILTER_PERIOD_BEGIN = "t_begin";
/**
- * Time in ms since epoch. For conversations this will be for last activity
- * as a unix timestamp (miliseconds since 00:00:00 UTC 1/1-1970)
+ * Time in ms since epoch. For conversations this will be for last activity as a unix timestamp
+ * (miliseconds since 00:00:00 UTC 1/1-1970)
*/
public static final String FILTER_PERIOD_END = "t_end";
- /**
- * Filter for a specific ThreadId
- */
+ /** Filter for a specific ThreadId */
public static final String FILTER_THREAD_ID = "thread_id";
-
public interface ChatState {
int UNKNOWN = 0;
int INACITVE = 1;
@@ -970,51 +906,49 @@ public final class BluetoothMapContract {
}
/**
- * Instant Messaging contact chat state information
- * MAP enables access to contacts chat state for the instant messaging application
- * The chat state table must provide filtering (use of WHERE clauses) of the following entries:
- * - contact_id (linking chat state to contacts)
- * - thread_id (linking chat state to conversations and messages)
- * The presence table must have a contact_id for each entry.
+ * Instant Messaging contact chat state information MAP enables access to contacts chat state
+ * for the instant messaging application The chat state table must provide filtering (use of
+ * WHERE clauses) of the following entries: - contact_id (linking chat state to contacts) -
+ * thread_id (linking chat state to conversations and messages) The presence table must have a
+ * contact_id for each entry.
*/
public interface ChatStatusColumns {
-// /**
-// * The contact ID of a instant messaging contact.
-// *
Type: TEXT
-// * read-only
-// */
-// public static final String CONTACT_ID = "contact_id";
-//
-// /**
-// * The thread id for a conversation.
-// * Type: INTEGER (long)
-// * read-only
-// */
-// public static final String CONVO_ID = "convo_id";
+ // /**
+ // * The contact ID of a instant messaging contact.
+ // * Type: TEXT
+ // * read-only
+ // */
+ // public static final String CONTACT_ID = "contact_id";
+ //
+ // /**
+ // * The thread id for a conversation.
+ // * Type: INTEGER (long)
+ // * read-only
+ // */
+ // public static final String CONVO_ID = "convo_id";
/**
* The chat state of contact in conversation, see {@link ChatState}
- * Type: INTERGER
- * read-only
+ *
+ * Type: INTERGER read-only
*/
String CHAT_STATE = "chat_state";
-// /**
-// * The geo location of the contact
-// *
Type: TEXT
-// * read-only
-// */
-//// TODO: IS THIS NEEDED - not in latest specification
-// public static final String GEOLOC = "geoloc";
+ // /**
+ // * The geo location of the contact
+ // * Type: TEXT
+ // * read-only
+ // */
+ //// TODO: IS THIS NEEDED - not in latest specification
+ // public static final String GEOLOC = "geoloc";
/**
* The time stamp of the last time this contact was active in the conversation
- * Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String LAST_ACTIVE = "last_active";
-
}
public interface PresenceState {
@@ -1028,196 +962,183 @@ public final class BluetoothMapContract {
}
/**
- * Instant Messaging contact presence information
- * MAP enables access to contacts presences information for the instant messaging application
- * The presence table must provide filtering (use of WHERE clauses) of the following entries:
- * - contact_id (linking contacts to presence)
+ * Instant Messaging contact presence information MAP enables access to contacts presences
+ * information for the instant messaging application The presence table must provide filtering
+ * (use of WHERE clauses) of the following entries: - contact_id (linking contacts to presence)
* The presence table must have a contact_id for each entry.
*/
public interface PresenceColumns {
-// /**
-// * The contact ID of a instant messaging contact.
-// *
Type: TEXT
-// * read-only
-// */
-// public static final String CONTACT_ID = "contact_id";
+ // /**
+ // * The contact ID of a instant messaging contact.
+ // * Type: TEXT
+ // * read-only
+ // */
+ // public static final String CONTACT_ID = "contact_id";
/**
* The presence state of contact, see {@link PresenceState}
- * Type: INTERGER
- * read-only
+ *
+ * Type: INTERGER read-only
*/
String PRESENCE_STATE = "presence_state";
/**
* The priority of contact presence
- *
Type: INTERGER
- * read-only
+ *
+ * Type: INTERGER read-only
*/
-// TODO: IS THIS NEEDED - not in latest specification
+ // TODO: IS THIS NEEDED - not in latest specification
String PRIORITY = "priority";
/**
* The last status text from contact
- *
Type: TEXT
- * read-only
+ *
+ * Type: TEXT read-only
*/
String STATUS_TEXT = "status_text";
/**
* The time stamp of the last time the contact was online
- *
Type: INTEGER (long)
- * read-only
+ *
+ * Type: INTEGER (long) read-only
*/
String LAST_ONLINE = "last_online";
-
}
+ /** A projection of all the columns in the Message table */
+ public static final String[] BT_MESSAGE_PROJECTION =
+ new String[] {
+ MessageColumns._ID,
+ MessageColumns.DATE,
+ MessageColumns.SUBJECT,
+ // TODO REMOVE WHEN Parts Table is in place
+ MessageColumns.BODY,
+ MessageColumns.MESSAGE_SIZE,
+ MessageColumns.FOLDER_ID,
+ MessageColumns.FLAG_READ,
+ MessageColumns.FLAG_PROTECTED,
+ MessageColumns.FLAG_HIGH_PRIORITY,
+ MessageColumns.FLAG_ATTACHMENT,
+ MessageColumns.ATTACHMENT_SIZE,
+ MessageColumns.FROM_LIST,
+ MessageColumns.TO_LIST,
+ MessageColumns.CC_LIST,
+ MessageColumns.BCC_LIST,
+ MessageColumns.REPLY_TO_LIST,
+ MessageColumns.RECEPTION_STATE,
+ MessageColumns.DEVILERY_STATE,
+ MessageColumns.THREAD_ID
+ };
+
+ public static final String[] BT_INSTANT_MESSAGE_PROJECTION =
+ new String[] {
+ MessageColumns._ID,
+ MessageColumns.DATE,
+ MessageColumns.SUBJECT,
+ MessageColumns.MESSAGE_SIZE,
+ MessageColumns.FOLDER_ID,
+ MessageColumns.FLAG_READ,
+ MessageColumns.FLAG_PROTECTED,
+ MessageColumns.FLAG_HIGH_PRIORITY,
+ MessageColumns.FLAG_ATTACHMENT,
+ MessageColumns.ATTACHMENT_SIZE,
+ MessageColumns.ATTACHMENT_MINE_TYPES,
+ MessageColumns.FROM_LIST,
+ MessageColumns.TO_LIST,
+ MessageColumns.RECEPTION_STATE,
+ MessageColumns.DEVILERY_STATE,
+ MessageColumns.THREAD_ID,
+ MessageColumns.THREAD_NAME
+ };
+
+ /** A projection of all the columns in the Account table */
+ public static final String[] BT_ACCOUNT_PROJECTION =
+ new String[] {
+ AccountColumns._ID, AccountColumns.ACCOUNT_DISPLAY_NAME, AccountColumns.FLAG_EXPOSE,
+ };
/**
- * A projection of all the columns in the Message table
- */
- public static final String[] BT_MESSAGE_PROJECTION = new String[]{
- MessageColumns._ID,
- MessageColumns.DATE,
- MessageColumns.SUBJECT,
- //TODO REMOVE WHEN Parts Table is in place
- MessageColumns.BODY,
- MessageColumns.MESSAGE_SIZE,
- MessageColumns.FOLDER_ID,
- MessageColumns.FLAG_READ,
- MessageColumns.FLAG_PROTECTED,
- MessageColumns.FLAG_HIGH_PRIORITY,
- MessageColumns.FLAG_ATTACHMENT,
- MessageColumns.ATTACHMENT_SIZE,
- MessageColumns.FROM_LIST,
- MessageColumns.TO_LIST,
- MessageColumns.CC_LIST,
- MessageColumns.BCC_LIST,
- MessageColumns.REPLY_TO_LIST,
- MessageColumns.RECEPTION_STATE,
- MessageColumns.DEVILERY_STATE,
- MessageColumns.THREAD_ID
- };
-
- public static final String[] BT_INSTANT_MESSAGE_PROJECTION = new String[]{
- MessageColumns._ID,
- MessageColumns.DATE,
- MessageColumns.SUBJECT,
- MessageColumns.MESSAGE_SIZE,
- MessageColumns.FOLDER_ID,
- MessageColumns.FLAG_READ,
- MessageColumns.FLAG_PROTECTED,
- MessageColumns.FLAG_HIGH_PRIORITY,
- MessageColumns.FLAG_ATTACHMENT,
- MessageColumns.ATTACHMENT_SIZE,
- MessageColumns.ATTACHMENT_MINE_TYPES,
- MessageColumns.FROM_LIST,
- MessageColumns.TO_LIST,
- MessageColumns.RECEPTION_STATE,
- MessageColumns.DEVILERY_STATE,
- MessageColumns.THREAD_ID,
- MessageColumns.THREAD_NAME
- };
-
- /**
- * A projection of all the columns in the Account table
- */
- public static final String[] BT_ACCOUNT_PROJECTION = new String[]{
- AccountColumns._ID, AccountColumns.ACCOUNT_DISPLAY_NAME, AccountColumns.FLAG_EXPOSE,
- };
-
- /**
- * A projection of all the columns in the Account table
- * TODO: Is this the way to differentiate
- */
- public static final String[] BT_IM_ACCOUNT_PROJECTION = new String[]{
- AccountColumns._ID,
- AccountColumns.ACCOUNT_DISPLAY_NAME,
- AccountColumns.FLAG_EXPOSE,
- AccountColumns.ACCOUNT_UCI,
- AccountColumns.ACCOUNT_UCI_PREFIX
- };
-
- /**
- * A projection of all the columns in the Folder table
- */
- public static final String[] BT_FOLDER_PROJECTION = new String[]{
- FolderColumns._ID,
- FolderColumns.NAME,
- FolderColumns.ACCOUNT_ID,
- FolderColumns.PARENT_FOLDER_ID
- };
-
-
- /**
- * A projection of all the columns in the Conversation table
- */
- public static final String[] BT_CONVERSATION_PROJECTION = new String[]{
- /* Thread information */
- ConversationColumns.THREAD_ID,
- ConversationColumns.THREAD_NAME,
- ConversationColumns.READ_STATUS,
- ConversationColumns.LAST_THREAD_ACTIVITY,
- ConversationColumns.VERSION_COUNTER,
- ConversationColumns.SUMMARY,
- /* Contact information */
- ConversationColumns.UCI,
- ConversationColumns.NAME,
- ConversationColumns.NICKNAME,
- ConversationColumns.CHAT_STATE,
- ConversationColumns.LAST_ACTIVE,
- ConversationColumns.X_BT_UID,
- ConversationColumns.PRESENCE_STATE,
- ConversationColumns.STATUS_TEXT,
- ConversationColumns.PRIORITY
- };
-
- /**
- * A projection of the Contact Info and Presence columns in the Contact Info in table
- */
- public static final String[] BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION = new String[]{
- ConvoContactColumns.UCI,
- ConvoContactColumns.CONVO_ID,
- ConvoContactColumns.NAME,
- ConvoContactColumns.NICKNAME,
- ConvoContactColumns.X_BT_UID,
- ConvoContactColumns.CHAT_STATE,
- ConvoContactColumns.LAST_ACTIVE,
- ConvoContactColumns.PRESENCE_STATE,
- ConvoContactColumns.PRIORITY,
- ConvoContactColumns.STATUS_TEXT,
- ConvoContactColumns.LAST_ONLINE
- };
-
- /**
- * A projection of the Contact Info the columns in Contacts Info table
+ * A projection of all the columns in the Account table TODO: Is this the way to differentiate
*/
- public static final String[] BT_CONTACT_PROJECTION = new String[]{
- ConvoContactColumns.UCI,
- ConvoContactColumns.CONVO_ID,
- ConvoContactColumns.X_BT_UID,
- ConvoContactColumns.NAME,
- ConvoContactColumns.NICKNAME
- };
-
-
- /**
- * A projection of all the columns in the Chat Status table
- */
- public static final String[] BT_CHATSTATUS_PROJECTION = new String[]{
- ChatStatusColumns.CHAT_STATE, ChatStatusColumns.LAST_ACTIVE,
- };
-
- /**
- * A projection of all the columns in the Presence table
- */
- public static final String[] BT_PRESENCE_PROJECTION = new String[]{
- PresenceColumns.PRESENCE_STATE,
- PresenceColumns.PRIORITY,
- PresenceColumns.STATUS_TEXT,
- PresenceColumns.LAST_ONLINE
- };
-
+ public static final String[] BT_IM_ACCOUNT_PROJECTION =
+ new String[] {
+ AccountColumns._ID,
+ AccountColumns.ACCOUNT_DISPLAY_NAME,
+ AccountColumns.FLAG_EXPOSE,
+ AccountColumns.ACCOUNT_UCI,
+ AccountColumns.ACCOUNT_UCI_PREFIX
+ };
+
+ /** A projection of all the columns in the Folder table */
+ public static final String[] BT_FOLDER_PROJECTION =
+ new String[] {
+ FolderColumns._ID,
+ FolderColumns.NAME,
+ FolderColumns.ACCOUNT_ID,
+ FolderColumns.PARENT_FOLDER_ID
+ };
+
+ /** A projection of all the columns in the Conversation table */
+ public static final String[] BT_CONVERSATION_PROJECTION =
+ new String[] {
+ /* Thread information */
+ ConversationColumns.THREAD_ID,
+ ConversationColumns.THREAD_NAME,
+ ConversationColumns.READ_STATUS,
+ ConversationColumns.LAST_THREAD_ACTIVITY,
+ ConversationColumns.VERSION_COUNTER,
+ ConversationColumns.SUMMARY,
+ /* Contact information */
+ ConversationColumns.UCI,
+ ConversationColumns.NAME,
+ ConversationColumns.NICKNAME,
+ ConversationColumns.CHAT_STATE,
+ ConversationColumns.LAST_ACTIVE,
+ ConversationColumns.X_BT_UID,
+ ConversationColumns.PRESENCE_STATE,
+ ConversationColumns.STATUS_TEXT,
+ ConversationColumns.PRIORITY
+ };
+
+ /** A projection of the Contact Info and Presence columns in the Contact Info in table */
+ public static final String[] BT_CONTACT_CHATSTATE_PRESENCE_PROJECTION =
+ new String[] {
+ ConvoContactColumns.UCI,
+ ConvoContactColumns.CONVO_ID,
+ ConvoContactColumns.NAME,
+ ConvoContactColumns.NICKNAME,
+ ConvoContactColumns.X_BT_UID,
+ ConvoContactColumns.CHAT_STATE,
+ ConvoContactColumns.LAST_ACTIVE,
+ ConvoContactColumns.PRESENCE_STATE,
+ ConvoContactColumns.PRIORITY,
+ ConvoContactColumns.STATUS_TEXT,
+ ConvoContactColumns.LAST_ONLINE
+ };
+
+ /** A projection of the Contact Info the columns in Contacts Info table */
+ public static final String[] BT_CONTACT_PROJECTION =
+ new String[] {
+ ConvoContactColumns.UCI,
+ ConvoContactColumns.CONVO_ID,
+ ConvoContactColumns.X_BT_UID,
+ ConvoContactColumns.NAME,
+ ConvoContactColumns.NICKNAME
+ };
+
+ /** A projection of all the columns in the Chat Status table */
+ public static final String[] BT_CHATSTATUS_PROJECTION =
+ new String[] {
+ ChatStatusColumns.CHAT_STATE, ChatStatusColumns.LAST_ACTIVE,
+ };
+
+ /** A projection of all the columns in the Presence table */
+ public static final String[] BT_PRESENCE_PROJECTION =
+ new String[] {
+ PresenceColumns.PRESENCE_STATE,
+ PresenceColumns.PRIORITY,
+ PresenceColumns.STATUS_TEXT,
+ PresenceColumns.LAST_ONLINE
+ };
}
diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java
index 29e2f0de6395a1a9a90bf69f427ba36a7d22297d..a5ee32357f8cd3de44fe179f97eb6b7161c44cbf 100644
--- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java
+++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapEmailProvider.java
@@ -38,9 +38,8 @@ import java.util.List;
import java.util.Map;
/**
- * A base implementation of the BluetoothMapEmailContract.
- * A base class for a ContentProvider that allows access to Email messages from a Bluetooth
- * device through the Message Access Profile.
+ * A base implementation of the BluetoothMapEmailContract. A base class for a ContentProvider that
+ * allows access to Email messages from a Bluetooth device through the Message Access Profile.
*/
public abstract class BluetoothMapEmailProvider extends ContentProvider {
@@ -57,32 +56,35 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
private String mAuthority;
private UriMatcher mMatcher;
-
private PipeReader mPipeReader = new PipeReader();
private PipeWriter mPipeWriter = new PipeWriter();
/**
* Write the content of a message to a stream as MIME encoded RFC-2822 data.
+ *
* @param accountId the ID of the account to which the message belong
* @param messageId the ID of the message to write to the stream
* @param includeAttachment true if attachments should be included
- * @param download true if any missing part of the message shall be downloaded
- * before written to the stream. The download flag will determine
- * whether or not attachments shall be downloaded or only the message content.
+ * @param download true if any missing part of the message shall be downloaded before written to
+ * the stream. The download flag will determine whether or not attachments shall be
+ * downloaded or only the message content.
* @param out the FileOurputStream to write to.
* @throws IOException
*/
- protected abstract void WriteMessageToStream(long accountId, long messageId,
- boolean includeAttachment, boolean download, FileOutputStream out) throws IOException;
+ protected abstract void WriteMessageToStream(
+ long accountId,
+ long messageId,
+ boolean includeAttachment,
+ boolean download,
+ FileOutputStream out)
+ throws IOException;
/**
* @return the CONTENT_URI exposed. This will be used to send out notifications.
*/
protected abstract Uri getContentUri();
- /**
- * Implementation is provided by the parent class.
- */
+ /** Implementation is provided by the parent class. */
@Override
public void attachInfo(Context context, ProviderInfo info) {
mAuthority = info.authority;
@@ -105,37 +107,35 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
super.attachInfo(context, info);
}
-
/**
- * Interface to write a stream of data to a pipe. Use with
- * {@link ContentProvider#openPipeHelper}.
+ * Interface to write a stream of data to a pipe. Use with {@link
+ * ContentProvider#openPipeHelper}.
*/
public interface PipeDataReader {
/**
- * Called from a background thread to stream data from a pipe.
- * Note that the pipe is blocking, so this thread can block on
- * reads for an arbitrary amount of time if the client is slow
- * at writing.
+ * Called from a background thread to stream data from a pipe. Note that the pipe is
+ * blocking, so this thread can block on reads for an arbitrary amount of time if the client
+ * is slow at writing.
*
- * @param input The pipe where data should be read. This will be
- * closed for you upon returning from this function.
+ * @param input The pipe where data should be read. This will be closed for you upon
+ * returning from this function.
* @param uri The URI whose data is to be written.
* @param mimeType The desired type of data to be written.
* @param opts Options supplied by caller.
* @param args Your own custom arguments.
*/
- void readDataFromPipe(ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts,
- T args);
+ void readDataFromPipe(
+ ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts, T args);
}
public class PipeReader implements PipeDataReader {
/**
- * Read the data from the pipe and generate a message.
- * Use the message to do an update of the message specified by the URI.
+ * Read the data from the pipe and generate a message. Use the message to do an update of
+ * the message specified by the URI.
*/
@Override
- public void readDataFromPipe(ParcelFileDescriptor input, Uri uri, String mimeType,
- Bundle opts, Cursor args) {
+ public void readDataFromPipe(
+ ParcelFileDescriptor input, Uri uri, String mimeType, Bundle opts, Cursor args) {
Log.v(TAG, "readDataFromPipe(): uri=" + uri.toString());
FileInputStream fIn = null;
try {
@@ -162,29 +162,30 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * Read a MIME encoded RFC-2822 fileStream and update the message content.
- * The Date and/or From headers may not be present in the MIME encoded
- * message, and this function shall add appropriate values if the headers
- * are missing. From should be set to the owner of the account.
+ * Read a MIME encoded RFC-2822 fileStream and update the message content. The Date and/or From
+ * headers may not be present in the MIME encoded message, and this function shall add
+ * appropriate values if the headers are missing. From should be set to the owner of the
+ * account.
*
* @param input the file stream to read data from
* @param accountId the accountId
* @param messageId ID of the message to update
*/
- protected abstract void UpdateMimeMessageFromStream(FileInputStream input, long accountId,
- long messageId) throws IOException;
+ protected abstract void UpdateMimeMessageFromStream(
+ FileInputStream input, long accountId, long messageId) throws IOException;
public class PipeWriter implements PipeDataWriter {
- /**
- * Generate a message based on the cursor, and write the encoded data to the stream.
- */
-
+ /** Generate a message based on the cursor, and write the encoded data to the stream. */
@Override
- public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
- Bundle opts, Cursor c) {
+ public void writeDataToPipe(
+ ParcelFileDescriptor output, Uri uri, String mimeType, Bundle opts, Cursor c) {
if (D) {
- Log.d(TAG, "writeDataToPipe(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.d(
+ TAG,
+ "writeDataToPipe(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
}
FileOutputStream fout = null;
@@ -232,10 +233,11 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * This function shall be called when any Account database content have changed
- * to Notify any attached observers.
- * @param accountId the ID of the account that changed. Null is a valid value,
- * if accountId is unknown or multiple accounts changed.
+ * This function shall be called when any Account database content have changed to Notify any
+ * attached observers.
+ *
+ * @param accountId the ID of the account that changed. Null is a valid value, if accountId is
+ * unknown or multiple accounts changed.
*/
protected void onAccountChanged(String accountId) {
Uri newUri = null;
@@ -255,12 +257,13 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * This function shall be called when any Message database content have changed
- * to notify any attached observers.
- * @param accountId Null is a valid value, if accountId is unknown, but
- * recommended for increased performance.
- * @param messageId Null is a valid value, if multiple messages changed or the
- * messageId is unknown, but recommended for increased performance.
+ * This function shall be called when any Message database content have changed to notify any
+ * attached observers.
+ *
+ * @param accountId Null is a valid value, if accountId is unknown, but recommended for
+ * increased performance.
+ * @param messageId Null is a valid value, if multiple messages changed or the messageId is
+ * unknown, but recommended for increased performance.
*/
protected void onMessageChanged(String accountId, String messageId) {
Uri newUri = null;
@@ -275,61 +278,65 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
if (messageId == null) {
newUri = BluetoothMapContract.buildMessageUri(mAuthority, accountId);
} else {
- newUri = BluetoothMapContract.buildMessageUriWithId(mAuthority, accountId,
- messageId);
+ newUri =
+ BluetoothMapContract.buildMessageUriWithId(
+ mAuthority, accountId, messageId);
}
}
if (D) {
- Log.d(TAG, "onMessageChanged() accountId = " + accountId + " messageId = " + messageId
- + " URI: " + newUri);
+ Log.d(
+ TAG,
+ "onMessageChanged() accountId = "
+ + accountId
+ + " messageId = "
+ + messageId
+ + " URI: "
+ + newUri);
}
mResolver.notifyChange(newUri, null);
}
- /**
- * Not used, this is just a dummy implementation.
- */
+ /** Not used, this is just a dummy implementation. */
@Override
public String getType(Uri uri) {
return "Email";
}
/**
- * Open a file descriptor to a message.
- * Two modes supported for read: With and without attachments.
- * One mode exist for write and the actual content will be with or without
+ * Open a file descriptor to a message. Two modes supported for read: With and without
+ * attachments. One mode exist for write and the actual content will be with or without
* attachments.
*
- * Mode will be "r" or "w".
+ * Mode will be "r" or "w".
*
- * URI format:
- * The URI scheme is as follows.
- * For messages with attachments:
- * content://com.android.mail.bluetoothprovider/Messages/msgId#
+ *
URI format: The URI scheme is as follows. For messages with attachments:
+ * content://com.android.mail.bluetoothprovider/Messages/msgId#
*
- * For messages without attachments:
- * content://com.android.mail.bluetoothprovider/Messages/msgId#/NO_ATTACHMENTS
+ *
For messages without attachments:
+ * content://com.android.mail.bluetoothprovider/Messages/msgId#/NO_ATTACHMENTS
*
- * UPDATE: For write.
- * First create a message in the DB using insert into the message DB
- * Then open a file handle to the #id
- * write the data to a stream created from the fileHandle.
+ *
UPDATE: For write. First create a message in the DB using insert into the message DB Then
+ * open a file handle to the #id write the data to a stream created from the fileHandle.
*
* @param uri the URI to open. ../Messages/#id
- * @param mode the mode to use. The following modes exist: - UPDATE do not work - use URI
- * - "read_with_attachments" - to read an e-mail including any attachments
- * - "read_no_attachments" - to read an e-mail excluding any attachments
- * - "write" - to add a mime encoded message to the database. This write
- * should not trigger the message to be send.
+ * @param mode the mode to use. The following modes exist: - UPDATE do not work - use URI -
+ * "read_with_attachments" - to read an e-mail including any attachments -
+ * "read_no_attachments" - to read an e-mail excluding any attachments - "write" - to add a
+ * mime encoded message to the database. This write should not trigger the message to be
+ * send.
* @return the ParcelFileDescriptor
- * @throws FileNotFoundException
+ * @throws FileNotFoundException
*/
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
final long callingId = Binder.clearCallingIdentity();
if (D) {
- Log.d(TAG, "openFile(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.d(
+ TAG,
+ "openFile(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
}
try {
/* To be able to do abstraction of the file IO, we simply ignore the URI at this
@@ -348,40 +355,42 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * A helper function for implementing {@link #openFile}, for
- * creating a data pipe and background thread allowing you to stream
- * data back from the client. This function returns a new
- * ParcelFileDescriptor that should be returned to the caller (the caller
- * is responsible for closing it).
+ * A helper function for implementing {@link #openFile}, for creating a data pipe and background
+ * thread allowing you to stream data back from the client. This function returns a new
+ * ParcelFileDescriptor that should be returned to the caller (the caller is responsible for
+ * closing it).
*
* @param uri The URI whose data is to be written.
* @param mimeType The desired type of data to be written.
* @param opts Options supplied by caller.
* @param args Your own custom arguments.
- * @param func Interface implementing the function that will actually
- * stream the data.
- * @return Returns a new ParcelFileDescriptor holding the read side of
- * the pipe. This should be returned to the caller for reading; the caller
- * is responsible for closing it when done.
+ * @param func Interface implementing the function that will actually stream the data.
+ * @return Returns a new ParcelFileDescriptor holding the read side of the pipe. This should be
+ * returned to the caller for reading; the caller is responsible for closing it when done.
*/
- private ParcelFileDescriptor openInversePipeHelper(final Uri uri, final String mimeType,
- final Bundle opts, final T args, final PipeDataReader func)
+ private ParcelFileDescriptor openInversePipeHelper(
+ final Uri uri,
+ final String mimeType,
+ final Bundle opts,
+ final T args,
+ final PipeDataReader func)
throws FileNotFoundException {
try {
final ParcelFileDescriptor[] fds = ParcelFileDescriptor.createPipe();
- AsyncTask task = new AsyncTask() {
- @Override
- protected Object doInBackground(Object... params) {
- func.readDataFromPipe(fds[0], uri, mimeType, opts, args);
- try {
- fds[0].close();
- } catch (IOException e) {
- Log.w(TAG, "Failure closing pipe", e);
- }
- return null;
- }
- };
+ AsyncTask task =
+ new AsyncTask() {
+ @Override
+ protected Object doInBackground(Object... params) {
+ func.readDataFromPipe(fds[0], uri, mimeType, opts, args);
+ try {
+ fds[0].close();
+ } catch (IOException e) {
+ Log.w(TAG, "Failure closing pipe", e);
+ }
+ return null;
+ }
+ };
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Object[]) null);
return fds[1];
@@ -392,9 +401,8 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
/**
* The MAP specification states that a delete request from MAP client is a folder shift to the
- * 'deleted' folder.
- * Only use case of delete() is when transparency is requested for push messages, then
- * message should not remain in sent folder and therefore must be deleted
+ * 'deleted' folder. Only use case of delete() is when transparency is requested for push
+ * messages, then message should not remain in sent folder and therefore must be deleted
*/
@Override
public int delete(Uri uri, String where, String[] selectionArgs) {
@@ -413,7 +421,6 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
throw new IllegalArgumentException("Message ID missing in update values!");
}
-
String accountId = getAccountId(uri);
if (accountId == null) {
throw new IllegalArgumentException("Account ID missing in update values!");
@@ -436,6 +443,7 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
/**
* This function deletes a message.
+ *
* @param accountId the ID of the Account
* @param messageId the ID of the message to delete.
* @return the number of messages deleted - 0 if the message was not found.
@@ -443,12 +451,9 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
protected abstract int deleteMessage(String accountId, String messageId);
/**
- * Insert is used to add new messages to the data base.
- * Insert message approach:
- * - Insert an empty message to get an _id with only a folder_id
- * - Open the _id for write
- * - Write the message content
- * (When the writer completes, this provider should do an update of the message)
+ * Insert is used to add new messages to the data base. Insert message approach: - Insert an
+ * empty message to get an _id with only a folder_id - Open the _id for write - Write the
+ * message content (When the writer completes, this provider should do an update of the message)
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
@@ -464,8 +469,12 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
String id; // the id of the entry inserted into the database
final long callingId = Binder.clearCallingIdentity();
- Log.d(TAG, "insert(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.d(
+ TAG,
+ "insert(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
try {
if (table.equals(BluetoothMapContract.TABLE_MESSAGE)) {
id = insertMessage(accountId, folderId.toString());
@@ -482,10 +491,10 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
}
-
/**
- * Inserts an empty message into the Message data base in the specified folder.
- * This is done before the actual message content is written by fileIO.
+ * Inserts an empty message into the Message data base in the specified folder. This is done
+ * before the actual message content is written by fileIO.
+ *
* @param accountId the ID of the account
* @param folderId the ID of the folder to create a new message in.
* @return the message id as a string
@@ -495,9 +504,10 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
/**
* Utility function to build a projection based on a projectionMap.
*
- * "btColumnName" -> "emailColumnName as btColumnName" for each entry.
+ * "btColumnName" -> "emailColumnName as btColumnName" for each entry.
+ *
+ *
This supports SQL statements in the emailColumnName entry.
*
- * This supports SQL statements in the emailColumnName entry.
* @param projection
* @param projectionMap
* @return the converted projection
@@ -511,11 +521,15 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * This query needs to map from the data used in the e-mail client to BluetoothMapContract
- * type of data.
+ * This query needs to map from the data used in the e-mail client to BluetoothMapContract type
+ * of data.
*/
@Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
String sortOrder) {
final long callingId = Binder.clearCallingIdentity();
try {
@@ -538,21 +552,22 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * Query account information.
- * This function shall return only exposable e-mail accounts. Hence shall not
- * return accounts that has policies suggesting not to be shared them.
+ * Query account information. This function shall return only exposable e-mail accounts. Hence
+ * shall not return accounts that has policies suggesting not to be shared them.
+ *
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return a cursor to the accounts that are subject to exposure over BT.
*/
- protected abstract Cursor queryAccount(String[] projection, String selection,
- String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryAccount(
+ String[] projection, String selection, String[] selectionArgs, String sortOrder);
/**
- * Filter out the non usable folders and ensure to name the mandatory folders
- * inbox, outbox, sent, deleted and draft.
+ * Filter out the non usable folders and ensure to name the mandatory folders inbox, outbox,
+ * sent, deleted and draft.
+ *
* @param accountId
* @param projection
* @param selection
@@ -560,20 +575,20 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
* @param sortOrder
* @return
*/
- protected abstract Cursor queryFolder(String accountId, String[] projection, String selection,
- String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryFolder(
+ String accountId,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder);
/**
* For the message table the selection (where clause) can only include the following columns:
- * date: less than, greater than and equals
- * flagRead: = 1 or = 0
- * flagPriority: = 1 or = 0
- * folder_id: the ID of the folder only equals
- * toList: partial name/address search
- * ccList: partial name/address search
- * bccList: partial name/address search
- * fromList: partial name/address search
- * Additionally the COUNT and OFFSET shall be supported.
+ * date: less than, greater than and equals flagRead: = 1 or = 0 flagPriority: = 1 or = 0
+ * folder_id: the ID of the folder only equals toList: partial name/address search ccList:
+ * partial name/address search bccList: partial name/address search fromList: partial
+ * name/address search Additionally the COUNT and OFFSET shall be supported.
+ *
* @param accountId the ID of the account
* @param projection
* @param selection
@@ -581,18 +596,19 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
* @param sortOrder
* @return a cursor to query result
*/
- protected abstract Cursor queryMessage(String accountId, String[] projection, String selection,
- String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryMessage(
+ String accountId,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder);
/**
- * update()
- * Messages can be modified in the following cases:
- * - the folder_key of a message - hence the message can be moved to a new folder,
- * but the content cannot be modified.
- * - the FLAG_READ state can be changed.
- * The selection statement will always be selection of a message ID, when updating a message,
- * hence this function will be called multiple times if multiple messages must be updated
- * due to the nature of the Bluetooth Message Access profile.
+ * update() Messages can be modified in the following cases: - the folder_key of a message -
+ * hence the message can be moved to a new folder, but the content cannot be modified. - the
+ * FLAG_READ state can be changed. The selection statement will always be selection of a message
+ * ID, when updating a message, hence this function will be called multiple times if multiple
+ * messages must be updated due to the nature of the Bluetooth Message Access profile.
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
@@ -608,8 +624,12 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
final long callingId = Binder.clearCallingIdentity();
if (D) {
- Log.w(TAG, "update(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.w(
+ TAG,
+ "update(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
}
try {
if (table.equals(BluetoothMapContract.TABLE_ACCOUNT)) {
@@ -647,8 +667,9 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
}
/**
- * Update an entry in the account table. Only the expose flag will be
- * changed through this interface.
+ * Update an entry in the account table. Only the expose flag will be changed through this
+ * interface.
+ *
* @param accountId the ID of the account to change.
* @param flagExpose the updated value.
* @return the number of entries changed - 0 if account not found or value cannot be changed.
@@ -657,22 +678,28 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
/**
* Update an entry in the message table.
+ *
* @param accountId ID of the account to which the messageId relates
* @param messageId the ID of the message to update
* @param folderId the new folder ID value to set - ignore if null.
* @param flagRead the new flagRead value to set - ignore if null.
* @return
*/
- protected abstract int updateMessage(String accountId, Long messageId, Long folderId,
- Boolean flagRead);
-
+ protected abstract int updateMessage(
+ String accountId, Long messageId, Long folderId, Boolean flagRead);
@Override
public Bundle call(String method, String arg, Bundle extras) {
final long callingId = Binder.clearCallingIdentity();
if (D) {
- Log.d(TAG, "call(): method=" + method + " arg=" + arg + "ThreadId: "
- + Thread.currentThread().getId());
+ Log.d(
+ TAG,
+ "call(): method="
+ + method
+ + " arg="
+ + arg
+ + "ThreadId: "
+ + Thread.currentThread().getId());
}
try {
@@ -701,23 +728,20 @@ public abstract class BluetoothMapEmailProvider extends ContentProvider {
/**
* Trigger a sync of the specified folder.
+ *
* @param accountId the ID of the account that owns the folder
* @param folderId the ID of the folder.
* @return 0 at success
*/
protected abstract int syncFolder(long accountId, long folderId);
- /**
- * Need this to suppress warning in unit tests.
- */
+ /** Need this to suppress warning in unit tests. */
@Override
public void shutdown() {
// Don't call super.shutdown(), which emits a warning...
}
- /**
- * Extract the BluetoothMapContract.AccountColumns._ID from the given URI.
- */
+ /** Extract the BluetoothMapContract.AccountColumns._ID from the given URI. */
public static String getAccountId(Uri uri) {
final List segments = uri.getPathSegments();
if (segments.size() < 1) {
diff --git a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java
index e0e3a5e74cdb4b29d82b4b3b586f7d8a0ee20818..7e4e8d7640c02a42a2deb6222176221889ea5e31 100644
--- a/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java
+++ b/android/app/lib/mapapi/com/android/bluetooth/mapapi/BluetoothMapIMProvider.java
@@ -1,17 +1,17 @@
/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.
-*/
+ * Copyright (C) 2015 Samsung System LSI
+ * 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 com.android.bluetooth.mapapi;
@@ -33,9 +33,8 @@ import java.util.Map.Entry;
import java.util.Set;
/**
- * A base implementation of the BluetoothMapContract.
- * A base class for a ContentProvider that allows access to Instant messages from a Bluetooth
- * device through the Message Access Profile.
+ * A base implementation of the BluetoothMapContract. A base class for a ContentProvider that allows
+ * access to Instant messages from a Bluetooth device through the Message Access Profile.
*/
public abstract class BluetoothMapIMProvider extends ContentProvider {
@@ -58,9 +57,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
*/
protected abstract Uri getContentUri();
- /**
- * Implementation is provided by the parent class.
- */
+ /** Implementation is provided by the parent class. */
@Override
public void attachInfo(Context context, ProviderInfo info) {
mAuthority = info.authority;
@@ -68,10 +65,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mMatcher.addURI(mAuthority, BluetoothMapContract.TABLE_ACCOUNT, MATCH_ACCOUNT);
mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_MESSAGE, MATCH_MESSAGE);
- mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_CONVERSATION,
- MATCH_CONVERSATION);
- mMatcher.addURI(mAuthority, "#/" + BluetoothMapContract.TABLE_CONVOCONTACT,
- MATCH_CONVOCONTACT);
+ mMatcher.addURI(
+ mAuthority, "#/" + BluetoothMapContract.TABLE_CONVERSATION, MATCH_CONVERSATION);
+ mMatcher.addURI(
+ mAuthority, "#/" + BluetoothMapContract.TABLE_CONVOCONTACT, MATCH_CONVOCONTACT);
// Sanity check our setup
if (!info.exported) {
@@ -91,10 +88,11 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
/**
- * This function shall be called when any Account database content have changed
- * to Notify any attached observers.
- * @param accountId the ID of the account that changed. Null is a valid value,
- * if accountId is unknown or multiple accounts changed.
+ * This function shall be called when any Account database content have changed to Notify any
+ * attached observers.
+ *
+ * @param accountId the ID of the account that changed. Null is a valid value, if accountId is
+ * unknown or multiple accounts changed.
*/
protected void onAccountChanged(String accountId) {
Uri newUri = null;
@@ -115,12 +113,13 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
/**
- * This function shall be called when any Message database content have changed
- * to notify any attached observers.
- * @param accountId Null is a valid value, if accountId is unknown, but
- * recommended for increased performance.
- * @param messageId Null is a valid value, if multiple messages changed or the
- * messageId is unknown, but recommended for increased performance.
+ * This function shall be called when any Message database content have changed to notify any
+ * attached observers.
+ *
+ * @param accountId Null is a valid value, if accountId is unknown, but recommended for
+ * increased performance.
+ * @param messageId Null is a valid value, if multiple messages changed or the messageId is
+ * unknown, but recommended for increased performance.
*/
protected void onMessageChanged(String accountId, String messageId) {
Uri newUri = null;
@@ -134,25 +133,32 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
if (messageId == null) {
newUri = BluetoothMapContract.buildMessageUri(mAuthority, accountId);
} else {
- newUri = BluetoothMapContract.buildMessageUriWithId(mAuthority, accountId,
- messageId);
+ newUri =
+ BluetoothMapContract.buildMessageUriWithId(
+ mAuthority, accountId, messageId);
}
}
if (D) {
- Log.d(TAG, "onMessageChanged() accountId = " + accountId + " messageId = " + messageId
- + " URI: " + newUri);
+ Log.d(
+ TAG,
+ "onMessageChanged() accountId = "
+ + accountId
+ + " messageId = "
+ + messageId
+ + " URI: "
+ + newUri);
}
mResolver.notifyChange(newUri, null);
}
-
/**
- * This function shall be called when any Message database content have changed
- * to notify any attached observers.
- * @param accountId Null is a valid value, if accountId is unknown, but
- * recommended for increased performance.
- * @param contactId Null is a valid value, if multiple contacts changed or the
- * contactId is unknown, but recommended for increased performance.
+ * This function shall be called when any Message database content have changed to notify any
+ * attached observers.
+ *
+ * @param accountId Null is a valid value, if accountId is unknown, but recommended for
+ * increased performance.
+ * @param contactId Null is a valid value, if multiple contacts changed or the contactId is
+ * unknown, but recommended for increased performance.
*/
protected void onContactChanged(String accountId, String contactId) {
Uri newUri = null;
@@ -166,20 +172,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
if (contactId == null) {
newUri = BluetoothMapContract.buildConvoContactsUri(mAuthority, accountId);
} else {
- newUri = BluetoothMapContract.buildConvoContactsUriWithId(mAuthority, accountId,
- contactId);
+ newUri =
+ BluetoothMapContract.buildConvoContactsUriWithId(
+ mAuthority, accountId, contactId);
}
}
if (D) {
- Log.d(TAG, "onContactChanged() accountId = " + accountId + " contactId = " + contactId
- + " URI: " + newUri);
+ Log.d(
+ TAG,
+ "onContactChanged() accountId = "
+ + accountId
+ + " contactId = "
+ + contactId
+ + " URI: "
+ + newUri);
}
mResolver.notifyChange(newUri, null);
}
/**
- * Not used, this is just a dummy implementation.
- * TODO: We might need to something intelligent here after introducing IM
+ * Not used, this is just a dummy implementation. TODO: We might need to something intelligent
+ * here after introducing IM
*/
@Override
public String getType(Uri uri) {
@@ -188,9 +201,8 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
/**
* The MAP specification states that a delete request from MAP client is a folder shift to the
- * 'deleted' folder.
- * Only use case of delete() is when transparency is requested for push messages, then
- * message should not remain in sent folder and therefore must be deleted
+ * 'deleted' folder. Only use case of delete() is when transparency is requested for push
+ * messages, then message should not remain in sent folder and therefore must be deleted
*/
@Override
public int delete(Uri uri, String where, String[] selectionArgs) {
@@ -231,6 +243,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
/**
* This function deletes a message.
+ *
* @param accountId the ID of the Account
* @param messageId the ID of the message to delete.
* @return the number of messages deleted - 0 if the message was not found.
@@ -238,12 +251,9 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
protected abstract int deleteMessage(String accountId, String messageId);
/**
- * Insert is used to add new messages to the data base.
- * Insert message approach:
- * - Insert an empty message to get an _id with only a folder_id
- * - Open the _id for write
- * - Write the message content
- * (When the writer completes, this provider should do an update of the message)
+ * Insert is used to add new messages to the data base. Insert message approach: - Insert an
+ * empty message to get an _id with only a folder_id - Open the _id for write - Write the
+ * message content (When the writer completes, this provider should do an update of the message)
*/
@Override
public Uri insert(Uri uri, ContentValues values) {
@@ -261,8 +271,12 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
String id; // the id of the entry inserted into the database
final long callingId = Binder.clearCallingIdentity();
- Log.d(TAG, "insert(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.d(
+ TAG,
+ "insert(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
try {
if (table.equals(BluetoothMapContract.TABLE_MESSAGE)) {
id = insertMessage(accountId, values);
@@ -279,10 +293,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
}
-
/**
- * Inserts an empty message into the Message data base in the specified folder.
- * This is done before the actual message content is written by fileIO.
+ * Inserts an empty message into the Message data base in the specified folder. This is done
+ * before the actual message content is written by fileIO.
+ *
* @param accountId the ID of the account
* @param folderId the ID of the folder to create a new message in.
* @return the message id as a string
@@ -292,9 +306,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
/**
* Utility function to build a projection based on a projectionMap.
*
- * "btColumnName" -> "imColumnName as btColumnName" for each entry.
+ * "btColumnName" -> "imColumnName as btColumnName" for each entry.
+ *
+ *
This supports SQL statements in the column name entry.
*
- * This supports SQL statements in the column name entry.
* @param projection
* @param projectionMap
* @return the converted projection
@@ -308,11 +323,15 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
/**
- * This query needs to map from the data used in the e-mail client to
- * BluetoothMapContract type of data.
+ * This query needs to map from the data used in the e-mail client to BluetoothMapContract type
+ * of data.
*/
@Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
String sortOrder) {
final long callingId = Binder.clearCallingIdentity();
try {
@@ -353,13 +372,20 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
if (value != null) {
threadId = Long.parseLong(value);
}
- return queryConversation(accountId, threadId, read, periodEnd, periodBegin,
- searchString, projection, sortOrder);
+ return queryConversation(
+ accountId,
+ threadId,
+ read,
+ periodEnd,
+ periodBegin,
+ searchString,
+ projection,
+ sortOrder);
case MATCH_CONVOCONTACT:
accountId = getAccountId(uri);
long contactId = 0;
- return queryConvoContact(accountId, contactId, projection, selection,
- selectionArgs, sortOrder);
+ return queryConvoContact(
+ accountId, contactId, projection, selection, selectionArgs, sortOrder);
default:
throw new UnsupportedOperationException("Unsupported Uri " + uri);
}
@@ -369,27 +395,24 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
/**
- * Query account information.
- * This function shall return only exposable e-mail accounts. Hence shall not
- * return accounts that has policies suggesting not to be shared them.
+ * Query account information. This function shall return only exposable e-mail accounts. Hence
+ * shall not return accounts that has policies suggesting not to be shared them.
+ *
* @param projection
* @param selection
* @param selectionArgs
* @param sortOrder
* @return a cursor to the accounts that are subject to exposure over BT.
*/
- protected abstract Cursor queryAccount(String[] projection, String selection,
- String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryAccount(
+ String[] projection, String selection, String[] selectionArgs, String sortOrder);
/**
* For the message table the selection (where clause) can only include the following columns:
- * date: less than, greater than and equals
- * flagRead: = 1 or = 0
- * flagPriority: = 1 or = 0
- * folder_id: the ID of the folder only equals
- * toList: partial name/address search
- * fromList: partial name/address search
- * Additionally the COUNT and OFFSET shall be supported.
+ * date: less than, greater than and equals flagRead: = 1 or = 0 flagPriority: = 1 or = 0
+ * folder_id: the ID of the folder only equals toList: partial name/address search fromList:
+ * partial name/address search Additionally the COUNT and OFFSET shall be supported.
+ *
* @param accountId the ID of the account
* @param projection
* @param selection
@@ -397,17 +420,19 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
* @param sortOrder
* @return a cursor to query result
*/
- protected abstract Cursor queryMessage(String accountId, String[] projection, String selection,
- String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryMessage(
+ String accountId,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder);
/**
- * For the Conversation table the selection (where clause) can only include
- * the following columns:
- * _id: the ID of the conversation only equals
- * name: partial name search
- * last_activity: less than, greater than and equals
- * version_counter: updated IDs are regenerated
- * Additionally the COUNT and OFFSET shall be supported.
+ * For the Conversation table the selection (where clause) can only include the following
+ * columns: _id: the ID of the conversation only equals name: partial name search last_activity:
+ * less than, greater than and equals version_counter: updated IDs are regenerated Additionally
+ * the COUNT and OFFSET shall be supported.
+ *
* @param accountId the ID of the account
* @param threadId the ID of the conversation
* @param projection
@@ -416,51 +441,46 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
* @param sortOrder
* @return a cursor to query result
*/
-// abstract protected Cursor queryConversation(Long threadId, String[] projection,
-// String selection, String[] selectionArgs, String sortOrder);
+ // abstract protected Cursor queryConversation(Long threadId, String[] projection,
+ // String selection, String[] selectionArgs, String sortOrder);
/**
- * Query for conversations with contact information. The expected result is a cursor pointing
- * to one row for each contact in a conversation.
- * E.g.:
- * ThreadId | ThreadName | ... | ContactName | ContactPrecence | ... |
- * 1 | "Bowling" | ... | Hans | 1 | ... |
- * 1 | "Bowling" | ... | Peter | 2 | ... |
- * 2 | "" | ... | Peter | 2 | ... |
- * 3 | "" | ... | Hans | 1 | ... |
+ * Query for conversations with contact information. The expected result is a cursor pointing to
+ * one row for each contact in a conversation. E.g.: ThreadId | ThreadName | ... | ContactName |
+ * ContactPrecence | ... | 1 | "Bowling" | ... | Hans | 1 | ... | 1 | "Bowling" | ... | Peter |
+ * 2 | ... | 2 | "" | ... | Peter | 2 | ... | 3 | "" | ... | Hans | 1 | ... |
*
* @param accountId the ID of the account
* @param threadId filter on a single threadId - null if no filtering is needed.
- * @param read filter on a read status:
- * null: no filtering on read is needed.
- * true: return only threads that has NO unread messages.
- * false: return only threads that has unread messages.
- * @param periodEnd last_activity time stamp of the the newest thread to include in the
- * result.
+ * @param read filter on a read status: null: no filtering on read is needed. true: return only
+ * threads that has NO unread messages. false: return only threads that has unread messages.
+ * @param periodEnd last_activity time stamp of the the newest thread to include in the result.
* @param periodBegin last_activity time stamp of the the oldest thread to include in the
- * result.
+ * result.
* @param searchString if not null, include only threads that has contacts that matches the
- * searchString as part of the contact name or nickName.
+ * searchString as part of the contact name or nickName.
* @param projection A list of the columns that is needed in the result
- * @param sortOrder the sort order
+ * @param sortOrder the sort order
* @return a Cursor representing the query result.
*/
- protected abstract Cursor queryConversation(String accountId, Long threadId, Boolean read,
- Long periodEnd, Long periodBegin, String searchString, String[] projection,
+ protected abstract Cursor queryConversation(
+ String accountId,
+ Long threadId,
+ Boolean read,
+ Long periodEnd,
+ Long periodBegin,
+ String searchString,
+ String[] projection,
String sortOrder);
/**
- * For the ConvoContact table the selection (where clause) can only include the
- * following columns:
- * _id: the ID of the contact only equals
- * convo_id: id of conversation contact is part of
- * name: partial name search
- * x_bt_uid: the ID of the bt uid only equals
- * chat_state: active, inactive, gone, composing, paused
- * last_active: less than, greater than and equals
- * presence_state: online, do_not_disturb, away, offline
- * priority: level of priority 0 - 100
- * last_online: less than, greater than and equals
+ * For the ConvoContact table the selection (where clause) can only include the following
+ * columns: _id: the ID of the contact only equals convo_id: id of conversation contact is part
+ * of name: partial name search x_bt_uid: the ID of the bt uid only equals chat_state: active,
+ * inactive, gone, composing, paused last_active: less than, greater than and equals
+ * presence_state: online, do_not_disturb, away, offline priority: level of priority 0 - 100
+ * last_online: less than, greater than and equals
+ *
* @param accountId the ID of the account
* @param contactId the ID of the contact
* @param projection
@@ -469,27 +489,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
* @param sortOrder
* @return a cursor to query result
*/
- protected abstract Cursor queryConvoContact(String accountId, Long contactId,
- String[] projection, String selection, String[] selectionArgs, String sortOrder);
+ protected abstract Cursor queryConvoContact(
+ String accountId,
+ Long contactId,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder);
/**
- * update()
- * Messages can be modified in the following cases:
- * - the folder_key of a message - hence the message can be moved to a new folder,
- * but the content cannot be modified.
- * - the FLAG_READ state can be changed.
- * Conversations can be modified in the following cases:
- * - the read status - changing between read, unread
- * - the last activity - the time stamp of last message sent of received in the conversation
- * ConvoContacts can be modified in the following cases:
- * - the chat_state - chat status of the contact in conversation
- * - the last_active - the time stamp of last action in the conversation
- * - the presence_state - the time stamp of last time contact online
- * - the status - the status text of the contact available in a conversation
- * - the last_online - the time stamp of last time contact online
- * The selection statement will always be selection of a message ID, when updating a message,
- * hence this function will be called multiple times if multiple messages must be updated
- * due to the nature of the Bluetooth Message Access profile.
+ * update() Messages can be modified in the following cases: - the folder_key of a message -
+ * hence the message can be moved to a new folder, but the content cannot be modified. - the
+ * FLAG_READ state can be changed. Conversations can be modified in the following cases: - the
+ * read status - changing between read, unread - the last activity - the time stamp of last
+ * message sent of received in the conversation ConvoContacts can be modified in the following
+ * cases: - the chat_state - chat status of the contact in conversation - the last_active - the
+ * time stamp of last action in the conversation - the presence_state - the time stamp of last
+ * time contact online - the status - the status text of the contact available in a conversation
+ * - the last_online - the time stamp of last time contact online The selection statement will
+ * always be selection of a message ID, when updating a message, hence this function will be
+ * called multiple times if multiple messages must be updated due to the nature of the Bluetooth
+ * Message Access profile.
*/
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
@@ -505,8 +525,12 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
final long callingId = Binder.clearCallingIdentity();
if (D) {
- Log.w(TAG, "update(): uri=" + uri.toString() + " - getLastPathSegment() = "
- + uri.getLastPathSegment());
+ Log.w(
+ TAG,
+ "update(): uri="
+ + uri.toString()
+ + " - getLastPathSegment() = "
+ + uri.getLastPathSegment());
}
try {
if (table.equals(BluetoothMapContract.TABLE_ACCOUNT)) {
@@ -551,8 +575,9 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
}
/**
- * Update an entry in the account table. Only the expose flag will be
- * changed through this interface.
+ * Update an entry in the account table. Only the expose flag will be changed through this
+ * interface.
+ *
* @param accountId the ID of the account to change.
* @param flagExpose the updated value.
* @return the number of entries changed - 0 if account not found or value cannot be changed.
@@ -561,26 +586,27 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
/**
* Update an entry in the message table.
+ *
* @param accountId ID of the account to which the messageId relates
* @param messageId the ID of the message to update
* @param folderId the new folder ID value to set - ignore if null.
* @param flagRead the new flagRead value to set - ignore if null.
* @return
*/
- protected abstract int updateMessage(String accountId, Long messageId, Long folderId,
- Boolean flagRead);
+ protected abstract int updateMessage(
+ String accountId, Long messageId, Long folderId, Boolean flagRead);
/**
- * Utility function to Creates a ContentValues object based on a modified valuesSet.
- * To be used after changing the keys and optionally values of a valueSet obtained
- * from a ContentValues object received in update().
+ * Utility function to Creates a ContentValues object based on a modified valuesSet. To be used
+ * after changing the keys and optionally values of a valueSet obtained from a ContentValues
+ * object received in update().
+ *
* @param valueSet the values as received in the contentProvider
* @param keyMap the key map
- * @return a new ContentValues object with the keys replaced as specified in the
- * keyMap
+ * @return a new ContentValues object with the keys replaced as specified in the keyMap
*/
- protected ContentValues createContentValues(Set> valueSet,
- Map keyMap) {
+ protected ContentValues createContentValues(
+ Set> valueSet, Map keyMap) {
ContentValues values = new ContentValues(valueSet.size());
for (Entry ent : valueSet) {
String key = keyMap.get(ent.getKey()); // Convert the key name
@@ -616,8 +642,14 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
public Bundle call(String method, String arg, Bundle extras) {
final long callingId = Binder.clearCallingIdentity();
if (D) {
- Log.w(TAG, "call(): method=" + method + " arg=" + arg + "ThreadId: "
- + Thread.currentThread().getId());
+ Log.w(
+ TAG,
+ "call(): method="
+ + method
+ + " arg="
+ + arg
+ + "ThreadId: "
+ + Thread.currentThread().getId());
}
int ret = -1;
try {
@@ -658,6 +690,7 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
/**
* Trigger a sync of the specified folder.
+ *
* @param accountId the ID of the account that owns the folder
* @param folderId the ID of the folder.
* @return 0 at success
@@ -665,9 +698,10 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
protected abstract int syncFolder(long accountId, long folderId);
/**
- * Set the properties that should change presence or chat state of owner
- * e.g. when the owner is active on a BT client device but not on the BT server device
- * where the IM application is installed, it should still be possible to show an active status.
+ * Set the properties that should change presence or chat state of owner e.g. when the owner is
+ * active on a BT client device but not on the BT server device where the IM application is
+ * installed, it should still be possible to show an active status.
+ *
* @param presenceState should follow the contract specified values
* @param presenceStatus string the owners current status
* @param lastActive time stamp of the owners last activity
@@ -675,28 +709,28 @@ public abstract class BluetoothMapIMProvider extends ContentProvider {
* @param convoId ID to the conversation to change
* @return 0 at success
*/
- protected abstract int setOwnerStatus(int presenceState, String presenceStatus, long lastActive,
- int chatState, String convoId);
+ protected abstract int setOwnerStatus(
+ int presenceState,
+ String presenceStatus,
+ long lastActive,
+ int chatState,
+ String convoId);
/**
* Notify the application of the Bluetooth state
+ *
* @param bluetoothState 'on' of 'off'
* @return 0 at success
*/
protected abstract int setBluetoothStatus(boolean bluetoothState);
-
- /**
- * Need this to suppress warning in unit tests.
- */
+ /** Need this to suppress warning in unit tests. */
@Override
public void shutdown() {
// Don't call super.shutdown(), which emits a warning...
}
- /**
- * Extract the BluetoothMapContract.AccountColumns._ID from the given URI.
- */
+ /** Extract the BluetoothMapContract.AccountColumns._ID from the given URI. */
public static String getAccountId(Uri uri) {
final List segments = uri.getPathSegments();
if (segments.size() < 1) {
diff --git a/android/app/src/com/android/bluetooth/AlertActivity.java b/android/app/src/com/android/bluetooth/AlertActivity.java
index cb5e15eff3028342c8e76904b372ec42e69cf0d8..0bcc9bfea5966718a45791556a43ab5585ee23c6 100644
--- a/android/app/src/com/android/bluetooth/AlertActivity.java
+++ b/android/app/src/com/android/bluetooth/AlertActivity.java
@@ -38,14 +38,12 @@ import com.android.internal.annotations.VisibleForTesting;
* @see #setupAlert()
*/
@SuppressLint("AndroidFrameworkBluetoothPermission")
-public abstract class AlertActivity extends Activity implements DialogInterface.OnDismissListener,
- DialogInterface.OnCancelListener {
+public abstract class AlertActivity extends Activity
+ implements DialogInterface.OnDismissListener, DialogInterface.OnCancelListener {
- /**
- * The model for the alert.
- *
- */
+ /** The model for the alert. */
protected AlertDialog.Builder mAlertBuilder;
+
private AlertDialog mAlert;
public AlertActivity() {}
@@ -80,14 +78,15 @@ public abstract class AlertActivity extends Activity implements DialogInterface.
return dispatchPopulateAccessibilityEvent(this, event);
}
- private static boolean dispatchPopulateAccessibilityEvent(Activity act,
- AccessibilityEvent event) {
+ private static boolean dispatchPopulateAccessibilityEvent(
+ Activity act, AccessibilityEvent event) {
event.setClassName(Dialog.class.getName());
event.setPackageName(act.getPackageName());
ViewGroup.LayoutParams params = act.getWindow().getAttributes();
- boolean isFullScreen = (params.width == ViewGroup.LayoutParams.MATCH_PARENT)
- && (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
+ boolean isFullScreen =
+ (params.width == ViewGroup.LayoutParams.MATCH_PARENT)
+ && (params.height == ViewGroup.LayoutParams.MATCH_PARENT);
event.setFullScreen(isFullScreen);
return false;
@@ -102,6 +101,7 @@ public abstract class AlertActivity extends Activity implements DialogInterface.
if (mAlert == null) return;
mAlert.setIconAttribute(attrId);
}
+
protected void changeTitle(CharSequence title) {
if (mAlert == null) return;
mAlert.setTitle(title);
@@ -134,5 +134,4 @@ public abstract class AlertActivity extends Activity implements DialogInterface.
}
super.onDestroy();
}
-
}
diff --git a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
index 22604dde37a42d71bddf1873ab0868af2fe67c8c..c4591ef0007fbd49a59c9f0d3ce2d120002fed53 100644
--- a/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
+++ b/android/app/src/com/android/bluetooth/BluetoothEventLogger.java
@@ -36,8 +36,7 @@ public class BluetoothEventLogger {
}
public String toString() {
- return (new StringBuilder(mTimeStamp)
- .append(" ").append(mMsg).toString());
+ return (new StringBuilder(mTimeStamp).append(" ").append(mMsg).toString());
}
}
diff --git a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
index 4965baf89ca14533afaeaa3c1ced43a65b8ae75b..39a324ca2f046f398615ce0b7a369a478d28ef25 100644
--- a/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
+++ b/android/app/src/com/android/bluetooth/BluetoothMethodProxy.java
@@ -57,16 +57,13 @@ import java.io.OutputStream;
import java.util.List;
import java.util.Set;
-/**
- * Proxy class for method calls to help with unit testing
- */
+/** Proxy class for method calls to help with unit testing */
public class BluetoothMethodProxy {
private static final String TAG = BluetoothMethodProxy.class.getSimpleName();
private static final Object INSTANCE_LOCK = new Object();
private static BluetoothMethodProxy sInstance;
- private BluetoothMethodProxy() {
- }
+ private BluetoothMethodProxy() {}
/**
* Get the singleton instance of proxy
@@ -96,52 +93,55 @@ public class BluetoothMethodProxy {
}
}
- /**
- * Proxies {@link ContentResolver#query(Uri, String[], String, String[], String)}.
- */
- public Cursor contentResolverQuery(ContentResolver contentResolver, final Uri contentUri,
- final String[] projection, final String selection, final String[] selectionArgs,
+ /** Proxies {@link ContentResolver#query(Uri, String[], String, String[], String)}. */
+ public Cursor contentResolverQuery(
+ ContentResolver contentResolver,
+ final Uri contentUri,
+ final String[] projection,
+ final String selection,
+ final String[] selectionArgs,
final String sortOrder) {
return contentResolver.query(contentUri, projection, selection, selectionArgs, sortOrder);
}
- /**
- * Proxies {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}.
- */
- public Cursor contentResolverQuery(ContentResolver contentResolver, final Uri contentUri,
- final String[] projection, final Bundle queryArgs,
+ /** Proxies {@link ContentResolver#query(Uri, String[], Bundle, CancellationSignal)}. */
+ public Cursor contentResolverQuery(
+ ContentResolver contentResolver,
+ final Uri contentUri,
+ final String[] projection,
+ final Bundle queryArgs,
final CancellationSignal cancellationSignal) {
return contentResolver.query(contentUri, projection, queryArgs, cancellationSignal);
}
- /**
- * Proxies {@link ContentResolver#insert(Uri, ContentValues)}.
- */
- public Uri contentResolverInsert(ContentResolver contentResolver, final Uri contentUri,
+ /** Proxies {@link ContentResolver#insert(Uri, ContentValues)}. */
+ public Uri contentResolverInsert(
+ ContentResolver contentResolver,
+ final Uri contentUri,
final ContentValues contentValues) {
return contentResolver.insert(contentUri, contentValues);
}
- /**
- * Proxies {@link ContentResolver#update(Uri, ContentValues, String, String[])}.
- */
- public int contentResolverUpdate(ContentResolver contentResolver, final Uri contentUri,
- final ContentValues contentValues, String where, String[] selectionArgs) {
+ /** Proxies {@link ContentResolver#update(Uri, ContentValues, String, String[])}. */
+ public int contentResolverUpdate(
+ ContentResolver contentResolver,
+ final Uri contentUri,
+ final ContentValues contentValues,
+ String where,
+ String[] selectionArgs) {
return contentResolver.update(contentUri, contentValues, where, selectionArgs);
}
- /**
- * Proxies {@link ContentResolver#delete(Uri, String, String[])}.
- */
- public int contentResolverDelete(ContentResolver contentResolver, final Uri url,
+ /** Proxies {@link ContentResolver#delete(Uri, String, String[])}. */
+ public int contentResolverDelete(
+ ContentResolver contentResolver,
+ final Uri url,
final String where,
final String[] selectionArgs) {
return contentResolver.delete(url, where, selectionArgs);
}
- /**
- * Proxies {@link BluetoothAdapter#isEnabled()}.
- */
+ /** Proxies {@link BluetoothAdapter#isEnabled()}. */
public boolean bluetoothAdapterIsEnabled(BluetoothAdapter adapter) {
return adapter.isEnabled();
}
@@ -153,86 +153,65 @@ public class BluetoothMethodProxy {
return BluetoothAdapter.getDefaultAdapter().getRemoteLeDevice(address, addressType);
}
- /**
- * Proxies {@link ContentResolver#openFileDescriptor(Uri, String)}.
- */
- public ParcelFileDescriptor contentResolverOpenFileDescriptor(ContentResolver contentResolver,
- final Uri uri, final String mode) throws FileNotFoundException {
+ /** Proxies {@link ContentResolver#openFileDescriptor(Uri, String)}. */
+ public ParcelFileDescriptor contentResolverOpenFileDescriptor(
+ ContentResolver contentResolver, final Uri uri, final String mode)
+ throws FileNotFoundException {
return contentResolver.openFileDescriptor(uri, mode);
}
- /**
- * Proxies {@link ContentResolver#openAssetFileDescriptor(Uri, String)}.
- */
+ /** Proxies {@link ContentResolver#openAssetFileDescriptor(Uri, String)}. */
public AssetFileDescriptor contentResolverOpenAssetFileDescriptor(
ContentResolver contentResolver, final Uri uri, final String mode)
throws FileNotFoundException {
return contentResolver.openAssetFileDescriptor(uri, mode);
}
- /**
- * Proxies {@link ContentResolver#openInputStream(Uri)}.
- */
- public InputStream contentResolverOpenInputStream(ContentResolver contentResolver,
- final Uri uri) throws FileNotFoundException {
+ /** Proxies {@link ContentResolver#openInputStream(Uri)}. */
+ public InputStream contentResolverOpenInputStream(
+ ContentResolver contentResolver, final Uri uri) throws FileNotFoundException {
return contentResolver.openInputStream(uri);
}
- /**
- * Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}.
- */
+ /** Proxies {@link ContentResolver#acquireUnstableContentProviderClient(String)}. */
public ContentProviderClient contentResolverAcquireUnstableContentProviderClient(
ContentResolver contentResolver, @NonNull String name) {
return contentResolver.acquireUnstableContentProviderClient(name);
}
- /**
- * Proxies {@link ContentResolver#openOutputStream(Uri)}.
- */
+ /** Proxies {@link ContentResolver#openOutputStream(Uri)}. */
public OutputStream contentResolverOpenOutputStream(ContentResolver contentResolver, Uri uri)
throws FileNotFoundException {
return contentResolver.openOutputStream(uri);
}
- /**
- * Proxies {@link Context#sendBroadcast(Intent)}.
- */
+ /** Proxies {@link Context#sendBroadcast(Intent)}. */
public void contextSendBroadcast(Context context, @RequiresPermission Intent intent) {
context.sendBroadcast(intent);
}
- /**
- * Proxies {@link Handler#sendEmptyMessage(int)}}.
- */
+ /** Proxies {@link Handler#sendEmptyMessage(int)}}. */
public boolean handlerSendEmptyMessage(Handler handler, final int what) {
return handler.sendEmptyMessage(what);
}
- /**
- * Proxies {@link Handler#sendMessageDelayed(Message, long)}.
- */
- public boolean handlerSendMessageDelayed(Handler handler, final int what,
- final long delayMillis) {
+ /** Proxies {@link Handler#sendMessageDelayed(Message, long)}. */
+ public boolean handlerSendMessageDelayed(
+ Handler handler, final int what, final long delayMillis) {
return handler.sendMessageDelayed(handler.obtainMessage(what), delayMillis);
}
- /**
- * Proxies {@link HeaderSet#getHeader}.
- */
+ /** Proxies {@link HeaderSet#getHeader}. */
public Object getHeader(HeaderSet headerSet, int headerId) throws IOException {
return headerSet.getHeader(headerId);
}
- /**
- * Proxies {@link Context#getSystemService(Class)}.
- */
+ /** Proxies {@link Context#getSystemService(Class)}. */
public T getSystemService(Context context, Class serviceClass) {
return context.getSystemService(serviceClass);
}
- /**
- * Proxies {@link Telephony.Threads#getOrCreateThreadId(Context, Set )}.
- */
+ /** Proxies {@link Telephony.Threads#getOrCreateThreadId(Context, Set )}. */
public long telephonyGetOrCreateThreadId(Context context, Set recipients) {
return Telephony.Threads.getOrCreateThreadId(context, recipients);
}
@@ -250,9 +229,13 @@ public class BluetoothMethodProxy {
* Proxies {@link PeriodicAdvertisingManager#registerSync(ScanResult, int, int,
* PeriodicAdvertisingCallback, Handler)}.
*/
- public void periodicAdvertisingManagerRegisterSync(PeriodicAdvertisingManager manager,
- ScanResult scanResult, int skip, int timeout,
- PeriodicAdvertisingCallback callback, Handler handler) {
+ public void periodicAdvertisingManagerRegisterSync(
+ PeriodicAdvertisingManager manager,
+ ScanResult scanResult,
+ int skip,
+ int timeout,
+ PeriodicAdvertisingCallback callback,
+ Handler handler) {
manager.registerSync(scanResult, skip, timeout, callback, handler);
}
@@ -261,20 +244,23 @@ public class BluetoothMethodProxy {
PeriodicAdvertisingManager manager, PeriodicAdvertisingCallback callback) {
manager.unregisterSync(callback);
}
- /**
- * Proxies {@link PeriodicAdvertisingManager#transferSync}.
- */
- public void periodicAdvertisingManagerTransferSync(PeriodicAdvertisingManager manager,
- BluetoothDevice bda, int serviceData, int syncHandle) {
+
+ /** Proxies {@link PeriodicAdvertisingManager#transferSync}. */
+ public void periodicAdvertisingManagerTransferSync(
+ PeriodicAdvertisingManager manager,
+ BluetoothDevice bda,
+ int serviceData,
+ int syncHandle) {
manager.transferSync(bda, serviceData, syncHandle);
}
- /**
- * Proxies {@link PeriodicAdvertisingManager#transferSetInfo}.
- */
+ /** Proxies {@link PeriodicAdvertisingManager#transferSetInfo}. */
public void periodicAdvertisingManagerTransferSetInfo(
- PeriodicAdvertisingManager manager, BluetoothDevice bda, int serviceData,
- int advHandle, PeriodicAdvertisingCallback callback) {
+ PeriodicAdvertisingManager manager,
+ BluetoothDevice bda,
+ int serviceData,
+ int advHandle,
+ PeriodicAdvertisingCallback callback) {
manager.transferSetInfo(bda, serviceData, advHandle, callback);
}
diff --git a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
index 3516cc98d6bf433f9e375ca09eda545305107c27..a635612fe2b97b8ea058ac051832df04d510c9eb 100644
--- a/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
+++ b/android/app/src/com/android/bluetooth/BluetoothObexTransport.java
@@ -1,17 +1,17 @@
/*
-* Copyright (C) 2014 Samsung System LSI
-* 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.
-*/
+ * Copyright (C) 2014 Samsung System LSI
+ * 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 com.android.bluetooth;
@@ -26,16 +26,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-/**
- * Generic Obex Transport class, to be used in OBEX based Bluetooth
- * Profiles.
- */
+/** Generic Obex Transport class, to be used in OBEX based Bluetooth Profiles. */
public class BluetoothObexTransport implements ObexTransport {
private BluetoothSocket mSocket = null;
- /**
- * Will default at the maximum packet length.
- */
+ /** Will default at the maximum packet length. */
public static final int PACKET_SIZE_UNSPECIFIED = -1;
private int mMaxTransmitPacketSize = PACKET_SIZE_UNSPECIFIED;
@@ -79,20 +74,16 @@ public class BluetoothObexTransport implements ObexTransport {
}
@Override
- public void connect() throws IOException {
- }
+ public void connect() throws IOException {}
@Override
- public void create() throws IOException {
- }
+ public void create() throws IOException {}
@Override
- public void disconnect() throws IOException {
- }
+ public void disconnect() throws IOException {}
@Override
- public void listen() throws IOException {
- }
+ public void listen() throws IOException {}
public boolean isConnected() throws IOException {
return true;
@@ -101,8 +92,7 @@ public class BluetoothObexTransport implements ObexTransport {
@Override
public int getMaxTransmitPacketSize() {
if (mSocket.getConnectionType() != BluetoothSocket.TYPE_L2CAP
- || (mIsCoverArt
- && mMaxTransmitPacketSize != PACKET_SIZE_UNSPECIFIED)) {
+ || (mIsCoverArt && mMaxTransmitPacketSize != PACKET_SIZE_UNSPECIFIED)) {
return mMaxTransmitPacketSize;
}
return mSocket.getMaxTransmitPacketSize();
diff --git a/android/app/src/com/android/bluetooth/BluetoothPrefs.java b/android/app/src/com/android/bluetooth/BluetoothPrefs.java
index 2c7c87aaa779330ed9aa277f2ec57d9328e69094..715144b8de561a401d955852d5af8a53625dcc89 100644
--- a/android/app/src/com/android/bluetooth/BluetoothPrefs.java
+++ b/android/app/src/com/android/bluetooth/BluetoothPrefs.java
@@ -20,9 +20,7 @@ import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
-/**
- * Activity that routes to Bluetooth settings when launched
- */
+/** Activity that routes to Bluetooth settings when launched */
public class BluetoothPrefs extends Activity {
public static final String BLUETOOTH_SETTING_ACTION = "android.settings.BLUETOOTH_SETTINGS";
diff --git a/android/app/src/com/android/bluetooth/ChangeIds.java b/android/app/src/com/android/bluetooth/ChangeIds.java
index 0416784d79325c75ceddb15cc8487dacbb4dd2d1..4c06486deea628102df43dbf60d44eb809188f88 100644
--- a/android/app/src/com/android/bluetooth/ChangeIds.java
+++ b/android/app/src/com/android/bluetooth/ChangeIds.java
@@ -19,9 +19,7 @@ package com.android.bluetooth;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
-/**
- * All the {@link ChangeId} used for Bluetooth App.
- */
+/** All the {@link ChangeId} used for Bluetooth App. */
public class ChangeIds {
/**
* Starting with {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE}, BLUETOOTH_CONNECT
diff --git a/android/app/src/com/android/bluetooth/IObexConnectionHandler.java b/android/app/src/com/android/bluetooth/IObexConnectionHandler.java
index 66f078d4b8e01c836d7011c1543fc769e972b288..f5ba88aa577da6dc8953cf8377a26e3dc1121b4a 100644
--- a/android/app/src/com/android/bluetooth/IObexConnectionHandler.java
+++ b/android/app/src/com/android/bluetooth/IObexConnectionHandler.java
@@ -1,17 +1,17 @@
/*
-* Copyright (C) 2014 Samsung System LSI
-* 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.
-*/
+ * Copyright (C) 2014 Samsung System LSI
+ * 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 com.android.bluetooth;
import android.bluetooth.BluetoothDevice;
@@ -23,17 +23,15 @@ public interface IObexConnectionHandler {
* Called to validate if a connection to the Bluetooth device should be accepted.
*
* @param device the connecting BluetoothDevice. Use .getType() to determine the type of
- * connection.
- * @return Shall return TRUE if the connection should be accepted.
- * FALSE otherwise
+ * connection.
+ * @return Shall return TRUE if the connection should be accepted. FALSE otherwise
*/
boolean onConnect(BluetoothDevice device, BluetoothSocket socket);
/**
- * Will be called in case the accept call fails.
- * When called, at lease one of the accept threads are about to terminate.
- * The behavior needed is to shutdown the ObexServerSockets object, and create a
- * new one.
+ * Will be called in case the accept call fails. When called, at lease one of the accept threads
+ * are about to terminate. The behavior needed is to shutdown the ObexServerSockets object, and
+ * create a new one.
*/
void onAcceptFailed();
}
diff --git a/android/app/src/com/android/bluetooth/ObexRejectServer.java b/android/app/src/com/android/bluetooth/ObexRejectServer.java
index ed50b76889a1ac5bbf7ac282a77aa35a60eea6fa..cc38c2d1dbcc0e50d07fc992e56a713c48a900dc 100644
--- a/android/app/src/com/android/bluetooth/ObexRejectServer.java
+++ b/android/app/src/com/android/bluetooth/ObexRejectServer.java
@@ -1,17 +1,17 @@
/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.
-*/
+ * Copyright (C) 2015 Samsung System LSI
+ * 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 com.android.bluetooth;
@@ -28,11 +28,11 @@ import com.android.obex.ServerRequestHandler;
import java.io.IOException;
/**
- * A simple ObexServer used to handle connection rejection in two cases:
- * - A profile cannot handle a new connection, as it is already connected to another device.
- * - The user rejected access to the resources needed by the profile.
+ * A simple ObexServer used to handle connection rejection in two cases: - A profile cannot handle a
+ * new connection, as it is already connected to another device. - The user rejected access to the
+ * resources needed by the profile.
*
- * Will reject the OBEX connection, start a timer, and at timeout close the socket.
+ * Will reject the OBEX connection, start a timer, and at timeout close the socket.
*/
public class ObexRejectServer extends ServerRequestHandler implements Handler.Callback {
@@ -51,8 +51,9 @@ public class ObexRejectServer extends ServerRequestHandler implements Handler.Ca
super();
mResult = result;
mSocket = socket;
- mHandlerThread = new HandlerThread("TestTimeoutHandler",
- android.os.Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread =
+ new HandlerThread(
+ "TestTimeoutHandler", android.os.Process.THREAD_PRIORITY_BACKGROUND);
mHandlerThread.start();
Looper timeoutLooper = mHandlerThread.getLooper();
mMessageHandler = new Handler(timeoutLooper, this);
diff --git a/android/app/src/com/android/bluetooth/ObexServerSockets.java b/android/app/src/com/android/bluetooth/ObexServerSockets.java
index bb4633f3a39278cd0125040a9a939590d18b06f2..b58b35d8637b62a5083fd410197103b90b174e35 100644
--- a/android/app/src/com/android/bluetooth/ObexServerSockets.java
+++ b/android/app/src/com/android/bluetooth/ObexServerSockets.java
@@ -1,17 +1,17 @@
/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.
-*/
+ * Copyright (C) 2015 Samsung System LSI
+ * 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 com.android.bluetooth;
import android.annotation.RequiresPermission;
@@ -27,22 +27,22 @@ import com.android.obex.ServerSession;
import java.io.IOException;
/**
- * Wraps multiple BluetoothServerSocket objects to make it possible to accept connections on
- * both a RFCOMM and L2CAP channel in parallel.
+ * Wraps multiple BluetoothServerSocket objects to make it possible to accept connections on both a
+ * RFCOMM and L2CAP channel in parallel.
* Create an instance using {@link #create()}, which will block until the sockets have been created
* and channel numbers have been assigned.
- * Use {@link #getRfcommChannel()} and {@link #getL2capPsm()} to get the channel numbers to
- * put into the SDP record.
- * Call {@link #shutdown(boolean)} to terminate the accept threads created by the call to
- * {@link #create(IObexConnectionHandler)}.
+ * Use {@link #getRfcommChannel()} and {@link #getL2capPsm()} to get the channel numbers to put into
+ * the SDP record.
+ * Call {@link #shutdown(boolean)} to terminate the accept threads created by the call to {@link
+ * #create(IObexConnectionHandler)}.
* A reference to an object of this type cannot be reused, and the {@link BluetoothServerSocket}
* object references passed to this object will be closed by this object, hence cannot be reused
* either (This is needed, as the only way to interrupt an accept call is to close the socket...)
*
- * When a connection is accepted,
- * {@link IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
- * If the an error occur while waiting for an incoming connection
- * {@link IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
+ * When a connection is accepted, {@link IObexConnectionHandler#onConnect(BluetoothDevice,
+ * BluetoothSocket)} will be called.
+ * If the an error occur while waiting for an incoming connection {@link
+ * IObexConnectionHandler#onConnect(BluetoothDevice, BluetoothSocket)} will be called.
* In both cases the {@link ObexServerSockets} object have terminated, and a new must be created.
*/
public class ObexServerSockets {
@@ -56,8 +56,9 @@ public class ObexServerSockets {
private SocketAcceptThread mRfcommThread;
private SocketAcceptThread mL2capThread;
-
- private ObexServerSockets(IObexConnectionHandler conHandler, BluetoothServerSocket rfcommSocket,
+ private ObexServerSockets(
+ IObexConnectionHandler conHandler,
+ BluetoothServerSocket rfcommSocket,
BluetoothServerSocket l2capSocket) {
mConHandler = conHandler;
mRfcommSocket = rfcommSocket;
@@ -66,27 +67,35 @@ public class ObexServerSockets {
/**
* Creates an RFCOMM {@link BluetoothServerSocket} and a L2CAP {@link BluetoothServerSocket}
- * @param validator a reference to the {@link IObexConnectionHandler} object to call
- * to validate an incoming connection.
+ *
+ * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate
+ * an incoming connection.
* @return a reference to a {@link ObexServerSockets} object instance.
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public static ObexServerSockets create(IObexConnectionHandler validator) {
- return create(validator, BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
- BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, true);
+ return create(
+ validator,
+ BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
+ BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
+ true);
}
/**
- * Creates an Insecure RFCOMM {@link BluetoothServerSocket} and a L2CAP
- * {@link BluetoothServerSocket}
- * @param validator a reference to the {@link IObexConnectionHandler} object to call
- * to validate an incoming connection.
+ * Creates an Insecure RFCOMM {@link BluetoothServerSocket} and a L2CAP {@link
+ * BluetoothServerSocket}
+ *
+ * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate
+ * an incoming connection.
* @return a reference to a {@link ObexServerSockets} object instance.
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public static ObexServerSockets createInsecure(IObexConnectionHandler validator) {
- return create(validator, BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
- BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, false);
+ return create(
+ validator,
+ BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
+ BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP,
+ false);
}
private static final int CREATE_RETRY_TIME = 10;
@@ -96,17 +105,17 @@ public class ObexServerSockets {
* with specific l2cap and RFCOMM channel numbers. It is the responsibility of the caller to
* ensure the numbers are free and can be used, e.g. by calling {@link #getL2capPsm()} and
* {@link #getRfcommChannel()} in {@link ObexServerSockets}.
- * @param validator a reference to the {@link IObexConnectionHandler} object to call
- * to validate an incoming connection.
+ *
+ * @param validator a reference to the {@link IObexConnectionHandler} object to call to validate
+ * an incoming connection.
* @param isSecure boolean flag to determine whther socket would be secured or inseucure.
* @return a reference to a {@link ObexServerSockets} object instance.
- *
- * TODO: Make public when it becomes possible to determine that the listen-call
- * failed due to channel-in-use.
+ *
TODO: Make public when it becomes possible to determine that the listen-call failed
+ * due to channel-in-use.
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- private static ObexServerSockets create(IObexConnectionHandler validator, int rfcommChannel,
- int l2capPsm, boolean isSecure) {
+ private static ObexServerSockets create(
+ IObexConnectionHandler validator, int rfcommChannel, int l2capPsm, boolean isSecure) {
Log.d(TAG, "create(rfcomm = " + rfcommChannel + ", l2capPsm = " + l2capPsm + ")");
BluetoothAdapter bt = BluetoothAdapter.getDefaultAdapter();
if (bt == null) {
@@ -145,8 +154,8 @@ public class ObexServerSockets {
if (!initSocketOK) {
// Need to break out of this loop if BT is being turned off.
int state = bt.getState();
- if ((state != BluetoothAdapter.STATE_TURNING_ON) && (state
- != BluetoothAdapter.STATE_ON)) {
+ if ((state != BluetoothAdapter.STATE_TURNING_ON)
+ && (state != BluetoothAdapter.STATE_ON)) {
Log.w(TAG, "initServerSockets failed as BT is (being) turned off");
break;
}
@@ -175,6 +184,7 @@ public class ObexServerSockets {
/**
* Returns the channel number assigned to the RFCOMM socket. This will be a static value, that
* should be reused for multiple connections.
+ *
* @return the RFCOMM channel number
*/
public int getRfcommChannel() {
@@ -184,6 +194,7 @@ public class ObexServerSockets {
/**
* Returns the channel number assigned to the L2CAP socket. This will be a static value, that
* should be reused for multiple connections.
+ *
* @return the L2CAP channel number
*/
public int getL2capPsm() {
@@ -191,9 +202,9 @@ public class ObexServerSockets {
}
/**
- * Initiate the accept threads.
- * Will create a thread for each socket type. an incoming connection will be signaled to
- * the {@link IObexConnectionValidator#onConnect()}, at which point both threads will exit.
+ * Initiate the accept threads. Will create a thread for each socket type. an incoming
+ * connection will be signaled to the {@link IObexConnectionValidator#onConnect()}, at which
+ * point both threads will exit.
*/
private void startAccept() {
Log.d(TAG, "startAccept()");
@@ -207,6 +218,7 @@ public class ObexServerSockets {
/**
* Called from the AcceptThreads to signal an incoming connection.
+ *
* @param device the connecting device.
* @param conSocket the socket associated with the connection.
* @return true if the connection is accepted, false otherwise.
@@ -216,9 +228,7 @@ public class ObexServerSockets {
return mConHandler.onConnect(device, conSocket);
}
- /**
- * Signal to the {@link IObexConnectionHandler} that an error have occurred.
- */
+ /** Signal to the {@link IObexConnectionHandler} that an error have occurred. */
private synchronized void onAcceptFailed() {
shutdown(false);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
@@ -230,8 +240,8 @@ public class ObexServerSockets {
/**
* Terminate any running accept threads
- * @param block Set true to block the calling thread until the AcceptThreads
- * has ended execution
+ *
+ * @param block Set true to block the calling thread until the AcceptThreads has ended execution
*/
public synchronized void shutdown(boolean block) {
Log.d(TAG, "shutdown(block = " + block + ")");
@@ -263,10 +273,9 @@ public class ObexServerSockets {
}
/**
- * A thread that runs in the background waiting for remote an incoming
- * connect. Once a remote socket connects, this thread will be
- * shutdown. When the remote disconnect, this thread shall be restarted to
- * accept a new connection.
+ * A thread that runs in the background waiting for remote an incoming connect. Once a remote
+ * socket connects, this thread will be shutdown. When the remote disconnect, this thread shall
+ * be restarted to accept a new connection.
*/
private class SocketAcceptThread extends Thread {
@@ -275,6 +284,7 @@ public class ObexServerSockets {
/**
* Create a SocketAcceptThread
+ *
* @param serverSocket shall never be null.
* @throws IllegalArgumentException if {@code serverSocket} is null
*/
@@ -286,8 +296,8 @@ public class ObexServerSockets {
}
/**
- * Run until shutdown of BT.
- * Accept incoming connections and reject if needed. Keep accepting incoming connections.
+ * Run until shutdown of BT. Accept incoming connections and reject if needed. Keep
+ * accepting incoming connections.
*/
@Override
public void run() {
@@ -332,9 +342,11 @@ public class ObexServerSockets {
new BluetoothObexTransport(connSocket);
// Create and detach a selfdestructing ServerSession to respond to any
// incoming OBEX signals.
- new ServerSession(obexTrans,
- new ObexRejectServer(ResponseCodes.OBEX_HTTP_UNAVAILABLE,
- connSocket), null);
+ new ServerSession(
+ obexTrans,
+ new ObexRejectServer(
+ ResponseCodes.OBEX_HTTP_UNAVAILABLE, connSocket),
+ null);
// now wait for a new connect
} else {
// now wait for a new connect
@@ -356,8 +368,8 @@ public class ObexServerSockets {
/**
* Shuts down the accept threads, and closes the ServerSockets, causing all related
- * BluetoothSockets to disconnect, hence do not call until all all accepted connections
- * are ready to be disconnected.
+ * BluetoothSockets to disconnect, hence do not call until all all accepted connections are
+ * ready to be disconnected.
*/
public void shutdown() {
if (!mStopped) {
diff --git a/android/app/src/com/android/bluetooth/SignedLongLong.java b/android/app/src/com/android/bluetooth/SignedLongLong.java
index 40bf20e7ff647d8ea8f3dc91b97e20257667709d..c84757f1f8df48e2e09d73b89ecd33900d1c85ec 100644
--- a/android/app/src/com/android/bluetooth/SignedLongLong.java
+++ b/android/app/src/com/android/bluetooth/SignedLongLong.java
@@ -1,18 +1,17 @@
/*
-* Copyright (C) 2015 Samsung System LSI
-* 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.
-*/
-
+ * Copyright (C) 2015 Samsung System LSI
+ * 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 com.android.bluetooth;
@@ -22,10 +21,9 @@ import java.io.UnsupportedEncodingException;
import java.util.Objects;
/**
- * Class to represent a 128bit value using two long member variables.
- * Has functionality to convert to/from hex-strings.
- * Mind that since signed variables are used to store the value internally
- * is used, the MSB/LSB long values can be negative.
+ * Class to represent a 128bit value using two long member variables. Has functionality to convert
+ * to/from hex-strings. Mind that since signed variables are used to store the value internally is
+ * used, the MSB/LSB long values can be negative.
*/
public class SignedLongLong implements Comparable {
@@ -39,6 +37,7 @@ public class SignedLongLong implements Comparable {
/**
* Create a SignedLongLong from a Hex-String without "0x" prefix
+ *
* @param value the hex-string
* @return the created object
* @throws UnsupportedEncodingException if "US-ASCII" charset is not supported,
@@ -92,7 +91,6 @@ public class SignedLongLong implements Comparable {
}
/**
- *
* @return a hex-string representation of the object values
*/
public String toHexString() {
@@ -132,5 +130,4 @@ public class SignedLongLong implements Comparable {
public long getLeastSignificantBits() {
return mLeastSigBits;
}
-
}
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
index 13d1bddf351db939b98fcb403f10f03c0ff8bdd0..bfab4d6e9f322f2ff5adab2722303cfb8b3912b1 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java
@@ -64,11 +64,11 @@ class A2dpCodecConfig {
AudioManager audioManager = mContext.getSystemService(AudioManager.class);
if (audioManager == null) {
- Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager");
- return;
+ Log.w(TAG, "Can't obtain the codec offloading prefernece from null AudioManager");
+ return;
}
- mCodecConfigOffloading = audioManager.getHwOffloadFormatsSupportedForA2dp()
- .toArray(mCodecConfigOffloading);
+ mCodecConfigOffloading =
+ audioManager.getHwOffloadFormatsSupportedForA2dp().toArray(mCodecConfigOffloading);
}
BluetoothCodecConfig[] codecConfigPriorities() {
@@ -79,23 +79,24 @@ class A2dpCodecConfig {
return mCodecConfigOffloading;
}
- void setCodecConfigPreference(BluetoothDevice device,
- BluetoothCodecStatus codecStatus,
- BluetoothCodecConfig newCodecConfig) {
+ void setCodecConfigPreference(
+ BluetoothDevice device,
+ BluetoothCodecStatus codecStatus,
+ BluetoothCodecConfig newCodecConfig) {
Objects.requireNonNull(codecStatus);
// Check whether the codecConfig is selectable for this Bluetooth device.
List selectableCodecs = codecStatus.getCodecsSelectableCapabilities();
- if (!selectableCodecs.stream().anyMatch(codec ->
- codec.isMandatoryCodec())) {
+ if (!selectableCodecs.stream().anyMatch(codec -> codec.isMandatoryCodec())) {
// Do not set codec preference to native if the selectableCodecs not contain mandatory
// codec. The reason could be remote codec negotiation is not completed yet.
Log.w(TAG, "setCodecConfigPreference: must have mandatory codec before changing.");
return;
}
if (!codecStatus.isCodecConfigSelectable(newCodecConfig)) {
- Log.w(TAG, "setCodecConfigPreference: invalid codec "
- + Objects.toString(newCodecConfig));
+ Log.w(
+ TAG,
+ "setCodecConfigPreference: invalid codec " + Objects.toString(newCodecConfig));
return;
}
@@ -104,8 +105,9 @@ class A2dpCodecConfig {
BluetoothCodecConfig currentCodecConfig = codecStatus.getCodecConfig();
if (prioritizedCodecType == currentCodecConfig.getCodecType()
&& (prioritizedCodecType != newCodecConfig.getCodecType()
- || (currentCodecConfig.similarCodecFeedingParameters(newCodecConfig)
- && currentCodecConfig.sameCodecSpecificParameters(newCodecConfig)))) {
+ || (currentCodecConfig.similarCodecFeedingParameters(newCodecConfig)
+ && currentCodecConfig.sameCodecSpecificParameters(
+ newCodecConfig)))) {
// Same codec with same parameters, no need to send this request to native.
Log.w(TAG, "setCodecConfigPreference: codec not changed.");
return;
@@ -118,8 +120,10 @@ class A2dpCodecConfig {
void enableOptionalCodecs(BluetoothDevice device, BluetoothCodecConfig currentCodecConfig) {
if (currentCodecConfig != null && !currentCodecConfig.isMandatoryCodec()) {
- Log.i(TAG, "enableOptionalCodecs: already using optional codec "
- + BluetoothCodecConfig.getCodecName(currentCodecConfig.getCodecType()));
+ Log.i(
+ TAG,
+ "enableOptionalCodecs: already using optional codec "
+ + BluetoothCodecConfig.getCodecName(currentCodecConfig.getCodecType()));
return;
}
@@ -162,8 +166,8 @@ class A2dpCodecConfig {
}
// Get the codec type of the highest priority of selectableCodecs and codecConfig.
- private int getPrioitizedCodecType(BluetoothCodecConfig codecConfig,
- List selectableCodecs) {
+ private int getPrioitizedCodecType(
+ BluetoothCodecConfig codecConfig, List selectableCodecs) {
BluetoothCodecConfig prioritizedCodecConfig = codecConfig;
for (BluetoothCodecConfig config : selectableCodecs) {
if (prioritizedCodecConfig == null) {
@@ -185,62 +189,67 @@ class A2dpCodecConfig {
int value;
try {
- value = SystemProperties.getInt(
- "bluetooth.a2dp.source.sbc_priority.config",
- resources.getInteger(R.integer.a2dp_source_codec_priority_sbc));
+ value =
+ SystemProperties.getInt(
+ "bluetooth.a2dp.source.sbc_priority.config",
+ resources.getInteger(R.integer.a2dp_source_codec_priority_sbc));
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPrioritySbc = value;
}
try {
- value = SystemProperties.getInt(
- "bluetooth.a2dp.source.aac_priority.config",
- resources.getInteger(R.integer.a2dp_source_codec_priority_aac));
+ value =
+ SystemProperties.getInt(
+ "bluetooth.a2dp.source.aac_priority.config",
+ resources.getInteger(R.integer.a2dp_source_codec_priority_aac));
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPriorityAac = value;
}
try {
- value = SystemProperties.getInt(
- "bluetooth.a2dp.source.aptx_priority.config",
- resources.getInteger(R.integer.a2dp_source_codec_priority_aptx));
+ value =
+ SystemProperties.getInt(
+ "bluetooth.a2dp.source.aptx_priority.config",
+ resources.getInteger(R.integer.a2dp_source_codec_priority_aptx));
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPriorityAptx = value;
}
try {
- value = SystemProperties.getInt(
- "bluetooth.a2dp.source.aptx_hd_priority.config",
- resources.getInteger(R.integer.a2dp_source_codec_priority_aptx_hd));
+ value =
+ SystemProperties.getInt(
+ "bluetooth.a2dp.source.aptx_hd_priority.config",
+ resources.getInteger(R.integer.a2dp_source_codec_priority_aptx_hd));
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPriorityAptxHd = value;
}
try {
- value = SystemProperties.getInt(
- "bluetooth.a2dp.source.ldac_priority.config",
- resources.getInteger(R.integer.a2dp_source_codec_priority_ldac));
+ value =
+ SystemProperties.getInt(
+ "bluetooth.a2dp.source.ldac_priority.config",
+ resources.getInteger(R.integer.a2dp_source_codec_priority_ldac));
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPriorityLdac = value;
}
@@ -249,43 +258,48 @@ class A2dpCodecConfig {
} catch (NotFoundException e) {
value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
}
- if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
- < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
+ if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED)
+ && (value < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
mA2dpSourceCodecPriorityOpus = value;
}
BluetoothCodecConfig codecConfig;
- BluetoothCodecConfig[] codecConfigArray =
- new BluetoothCodecConfig[6];
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
- .setCodecPriority(mA2dpSourceCodecPrioritySbc)
- .build();
+ BluetoothCodecConfig[] codecConfigArray = new BluetoothCodecConfig[6];
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)
+ .setCodecPriority(mA2dpSourceCodecPrioritySbc)
+ .build();
codecConfigArray[0] = codecConfig;
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
- .setCodecPriority(mA2dpSourceCodecPriorityAac)
- .build();
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC)
+ .setCodecPriority(mA2dpSourceCodecPriorityAac)
+ .build();
codecConfigArray[1] = codecConfig;
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX)
- .setCodecPriority(mA2dpSourceCodecPriorityAptx)
- .build();
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX)
+ .setCodecPriority(mA2dpSourceCodecPriorityAptx)
+ .build();
codecConfigArray[2] = codecConfig;
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD)
- .setCodecPriority(mA2dpSourceCodecPriorityAptxHd)
- .build();
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD)
+ .setCodecPriority(mA2dpSourceCodecPriorityAptxHd)
+ .build();
codecConfigArray[3] = codecConfig;
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
- .setCodecPriority(mA2dpSourceCodecPriorityLdac)
- .build();
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
+ .setCodecPriority(mA2dpSourceCodecPriorityLdac)
+ .build();
codecConfigArray[4] = codecConfig;
- codecConfig = new BluetoothCodecConfig.Builder()
- .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
- .setCodecPriority(mA2dpSourceCodecPriorityOpus)
- .build();
+ codecConfig =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
+ .setCodecPriority(mA2dpSourceCodecPriorityOpus)
+ .build();
codecConfigArray[5] = codecConfig;
return codecConfigArray;
@@ -293,14 +307,13 @@ class A2dpCodecConfig {
public void switchCodecByBufferSize(
BluetoothDevice device, boolean isLowLatency, int currentCodecType) {
- if ((isLowLatency
- && currentCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
+ if ((isLowLatency && currentCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
|| (!isLowLatency
- && currentCodecType != BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)) {
+ && currentCodecType != BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)) {
return;
}
BluetoothCodecConfig[] codecConfigArray = assignCodecConfigPriorities();
- for (int i = 0; i < codecConfigArray.length; i++){
+ for (int i = 0; i < codecConfigArray.length; i++) {
BluetoothCodecConfig codecConfig = codecConfigArray[i];
if (codecConfig.getCodecType() == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS) {
if (isLowLatency) {
@@ -315,4 +328,3 @@ class A2dpCodecConfig {
mA2dpNativeInterface.setCodecConfigPreference(device, codecConfigArray);
}
}
-
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
index e1c7669b61781999c2bfa36a239f99fec0dcdd1e..aa0c8dad3c3796f7de179e10a779815e3a085f32 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java
@@ -39,9 +39,7 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
-/**
- * A2DP Native Interface to/from JNI.
- */
+/** A2DP Native Interface to/from JNI. */
public class A2dpNativeInterface {
private static final String TAG = A2dpNativeInterface.class.getSimpleName();
private BluetoothAdapter mAdapter;
@@ -60,13 +58,13 @@ public class A2dpNativeInterface {
if (mAdapter == null) {
Log.wtf(TAG, "No Bluetooth Adapter Available");
}
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when A2dpNativeInterface init");
+ mAdapterService =
+ Objects.requireNonNull(
+ AdapterService.getAdapterService(),
+ "AdapterService cannot be null when A2dpNativeInterface init");
}
- /**
- * Get singleton instance.
- */
+ /** Get singleton instance. */
public static A2dpNativeInterface getInstance() {
synchronized (INSTANCE_LOCK) {
if (sInstance == null) {
@@ -155,14 +153,12 @@ public class A2dpNativeInterface {
* Sets the codec configuration preferences.
*
* @param device the remote Bluetooth device
- * @param codecConfigArray an array with the codec configurations to
- * configure.
+ * @param codecConfigArray an array with the codec configurations to configure.
* @return true on success, otherwise false.
*/
- public boolean setCodecConfigPreference(BluetoothDevice device,
- BluetoothCodecConfig[] codecConfigArray) {
- return setCodecConfigPreferenceNative(getByteAddress(device),
- codecConfigArray);
+ public boolean setCodecConfigPreference(
+ BluetoothDevice device, BluetoothCodecConfig[] codecConfigArray) {
+ return setCodecConfigPreferenceNative(getByteAddress(device), codecConfigArray);
}
private BluetoothDevice getDevice(byte[] address) {
@@ -212,15 +208,18 @@ public class A2dpNativeInterface {
sendMessageToService(event);
}
- private void onCodecConfigChanged(byte[] address,
+ private void onCodecConfigChanged(
+ byte[] address,
BluetoothCodecConfig newCodecConfig,
BluetoothCodecConfig[] codecsLocalCapabilities,
BluetoothCodecConfig[] codecsSelectableCapabilities) {
A2dpStackEvent event = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED);
event.device = getDevice(address);
- event.codecStatus = new BluetoothCodecStatus(newCodecConfig,
- Arrays.asList(codecsLocalCapabilities),
- Arrays.asList(codecsSelectableCapabilities));
+ event.codecStatus =
+ new BluetoothCodecStatus(
+ newCodecConfig,
+ Arrays.asList(codecsLocalCapabilities),
+ Arrays.asList(codecsSelectableCapabilities));
Log.d(TAG, "onCodecConfigChanged: " + event);
sendMessageToService(event);
}
@@ -239,17 +238,23 @@ public class A2dpNativeInterface {
}
// Native methods that call into the JNI interface
- private native void initNative(int maxConnectedAudioDevices,
- BluetoothCodecConfig[] codecConfigPriorities,
- BluetoothCodecConfig[] codecConfigOffloading);
+ private native void initNative(
+ int maxConnectedAudioDevices,
+ BluetoothCodecConfig[] codecConfigPriorities,
+ BluetoothCodecConfig[] codecConfigOffloading);
+
private native void cleanupNative();
private native BluetoothCodecType[] getSupportedCodecTypesNative();
private native boolean connectA2dpNative(byte[] address);
+
private native boolean disconnectA2dpNative(byte[] address);
+
private native boolean setSilenceDeviceNative(byte[] address, boolean silence);
+
private native boolean setActiveDeviceNative(byte[] address);
- private native boolean setCodecConfigPreferenceNative(byte[] address,
- BluetoothCodecConfig[] codecConfigArray);
+
+ private native boolean setCodecConfigPreferenceNative(
+ byte[] address, BluetoothCodecConfig[] codecConfigArray);
}
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
index 24f8f1e4536637f63cb47d92f8a12fce80c0a182..a4f89375c1a5f6fcd25d06c22876b33e1b40a086 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -77,9 +77,7 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-/**
- * Provides Bluetooth A2DP profile, as a service in the Bluetooth application.
- */
+/** Provides Bluetooth A2DP profile, as a service in the Bluetooth application. */
public class A2dpService extends ProfileService {
private static final String TAG = A2dpService.class.getSimpleName();
@@ -97,8 +95,7 @@ public class A2dpService extends ProfileService {
private HandlerThread mStateMachinesThread;
private Handler mHandler = null;
- @VisibleForTesting
- ServiceFactory mFactory = new ServiceFactory();
+ @VisibleForTesting ServiceFactory mFactory = new ServiceFactory();
private A2dpCodecConfig mA2dpCodecConfig;
@GuardedBy("mStateMachines")
@@ -273,8 +270,7 @@ public class A2dpService extends ProfileService {
Log.e(TAG, "Cannot connect to " + device + " : CONNECTION_POLICY_FORBIDDEN");
return false;
}
- if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device),
- BluetoothUuid.A2DP_SINK)) {
+ if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device), BluetoothUuid.A2DP_SINK)) {
Log.e(TAG, "Cannot connect to " + device + " : Remote does not have A2DP Sink UUID");
return false;
}
@@ -283,10 +279,13 @@ public class A2dpService extends ProfileService {
if (!connectionAllowedCheckMaxDevices(device)) {
// when mMaxConnectedAudioDevices is one, disconnect current device first.
if (mMaxConnectedAudioDevices == 1) {
- List sinks = getDevicesMatchingConnectionStates(
- new int[] {BluetoothProfile.STATE_CONNECTED,
- BluetoothProfile.STATE_CONNECTING,
- BluetoothProfile.STATE_DISCONNECTING});
+ List sinks =
+ getDevicesMatchingConnectionStates(
+ new int[] {
+ BluetoothProfile.STATE_CONNECTED,
+ BluetoothProfile.STATE_CONNECTING,
+ BluetoothProfile.STATE_DISCONNECTING
+ });
for (BluetoothDevice sink : sinks) {
if (sink.equals(device)) {
Log.w(TAG, "Connecting to device " + device + " : disconnect skipped");
@@ -342,8 +341,8 @@ public class A2dpService extends ProfileService {
}
/**
- * Check whether can connect to a peer device.
- * The check considers the maximum number of connected peers.
+ * Check whether can connect to a peer device. The check considers the maximum number of
+ * connected peers.
*
* @param device the peer device to connect to
* @return true if connection is allowed, otherwise false
@@ -357,7 +356,7 @@ public class A2dpService extends ProfileService {
case BluetoothProfile.STATE_CONNECTING:
case BluetoothProfile.STATE_CONNECTED:
if (Objects.equals(device, sm.getDevice())) {
- return true; // Already connected or accounted for
+ return true; // Already connected or accounted for
}
connected++;
break;
@@ -370,12 +369,12 @@ public class A2dpService extends ProfileService {
}
/**
- * Check whether can connect to a peer device.
- * The check considers a number of factors during the evaluation.
+ * Check whether can connect to a peer device. The check considers a number of factors during
+ * the evaluation.
*
* @param device the peer device to connect to
- * @param isOutgoingRequest if true, the check is for outgoing connection
- * request, otherwise is for incoming connection request
+ * @param isOutgoingRequest if true, the check is for outgoing connection request, otherwise is
+ * for incoming connection request
* @return true if connection is allowed, otherwise false
*/
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -388,8 +387,9 @@ public class A2dpService extends ProfileService {
}
// Check if too many devices
if (!connectionAllowedCheckMaxDevices(device)) {
- Log.e(TAG, "okToConnect: cannot connect to " + device
- + " : too many connected devices");
+ Log.e(
+ TAG,
+ "okToConnect: cannot connect to " + device + " : too many connected devices");
return false;
}
// Check connectionPolicy and accept or reject the connection.
@@ -405,8 +405,10 @@ public class A2dpService extends ProfileService {
if (!isOutgoingRequest) {
HeadsetService headsetService = HeadsetService.getHeadsetService();
if (headsetService != null && headsetService.okToAcceptConnection(device, true)) {
- Log.d(TAG, "okToConnect: return false,"
- + " Fallback connection to allowed HFP profile");
+ Log.d(
+ TAG,
+ "okToConnect: return false,"
+ + " Fallback connection to allowed HFP profile");
headsetService.connect(device);
return false;
}
@@ -429,8 +431,8 @@ public class A2dpService extends ProfileService {
}
synchronized (mStateMachines) {
for (BluetoothDevice device : bondedDevices) {
- if (!Utils.arrayContains(mAdapterService.getRemoteUuids(device),
- BluetoothUuid.A2DP_SINK)) {
+ if (!Utils.arrayContains(
+ mAdapterService.getRemoteUuids(device), BluetoothUuid.A2DP_SINK)) {
continue;
}
int connectionState = BluetoothProfile.STATE_DISCONNECTED;
@@ -492,14 +494,18 @@ public class A2dpService extends ProfileService {
updateAndBroadcastActiveDevice(null);
// Make sure the Audio Manager knows the previous active device is no longer active.
- mAudioManager.handleBluetoothActiveDeviceChanged(null, previousActiveDevice,
+ mAudioManager.handleBluetoothActiveDeviceChanged(
+ null,
+ previousActiveDevice,
BluetoothProfileConnectionInfo.createA2dpInfo(!stopAudio, -1));
synchronized (mStateMachines) {
// Make sure the Active device in native layer is set to null and audio is off
if (!mNativeInterface.setActiveDevice(null)) {
- Log.w(TAG, "setActiveDevice(null): Cannot remove active device in native "
- + "layer");
+ Log.w(
+ TAG,
+ "setActiveDevice(null): Cannot remove active device in native "
+ + "layer");
return false;
}
}
@@ -547,21 +553,34 @@ public class A2dpService extends ProfileService {
BluetoothDevice previousActiveDevice = null;
synchronized (mStateMachines) {
if (Objects.equals(device, mActiveDevice)) {
- Log.i(TAG, "setActiveDevice(" + device + "): current is " + mActiveDevice
- + " no changed");
+ Log.i(
+ TAG,
+ "setActiveDevice("
+ + device
+ + "): current is "
+ + mActiveDevice
+ + " no changed");
// returns true since the device is activated even double attempted
return true;
}
Log.d(TAG, "setActiveDevice(" + device + "): current is " + mActiveDevice);
sm = mStateMachines.get(device);
if (sm == null) {
- Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active: "
- + "no state machine");
+ Log.e(
+ TAG,
+ "setActiveDevice("
+ + device
+ + "): Cannot set as active: "
+ + "no state machine");
return false;
}
if (sm.getConnectionState() != BluetoothProfile.STATE_CONNECTED) {
- Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active: "
- + "device is not connected");
+ Log.e(
+ TAG,
+ "setActiveDevice("
+ + device
+ + "): Cannot set as active: "
+ + "device is not connected");
return false;
}
previousActiveDevice = mActiveDevice;
@@ -576,8 +595,12 @@ public class A2dpService extends ProfileService {
BluetoothDevice newActiveDevice = null;
synchronized (mStateMachines) {
if (!mNativeInterface.setActiveDevice(device)) {
- Log.e(TAG, "setActiveDevice(" + device + "): Cannot set as active in native "
- + "layer");
+ Log.e(
+ TAG,
+ "setActiveDevice("
+ + device
+ + "): Cannot set as active in native "
+ + "layer");
// Remove active device and stop playing audio.
removeActiveDevice(true);
return false;
@@ -593,15 +616,18 @@ public class A2dpService extends ProfileService {
// Tasks of Bluetooth are done, and now restore the AudioManager side.
int rememberedVolume = -1;
if (mFactory.getAvrcpTargetService() != null) {
- rememberedVolume = mFactory.getAvrcpTargetService()
- .getRememberedVolumeForDevice(newActiveDevice);
+ rememberedVolume =
+ mFactory.getAvrcpTargetService()
+ .getRememberedVolumeForDevice(newActiveDevice);
}
// Make sure the Audio Manager knows the previous Active device is disconnected,
// and the new Active device is connected.
// And inform the Audio Service about the codec configuration
// change, so the Audio Service can reset accordingly the audio
// feeding parameters in the Audio HAL to the Bluetooth stack.
- mAudioManager.handleBluetoothActiveDeviceChanged(newActiveDevice, previousActiveDevice,
+ mAudioManager.handleBluetoothActiveDeviceChanged(
+ newActiveDevice,
+ previousActiveDevice,
BluetoothProfileConnectionInfo.createA2dpInfo(true, rememberedVolume));
}
return true;
@@ -625,15 +651,14 @@ public class A2dpService extends ProfileService {
}
/**
- * Set connection policy of the profile and connects it if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
+ * Set connection policy of the profile and connects it if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
*
- * The device should already be paired.
- * Connection policy can be one of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The device should already be paired. Connection policy can be one of: {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device Paired bluetooth device
* @param connectionPolicy is the connection policy to set to for this profile
@@ -641,12 +666,12 @@ public class A2dpService extends ProfileService {
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
- if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.A2DP,
- connectionPolicy)) {
+ if (!mDatabaseManager.setProfileConnectionPolicy(
+ device, BluetoothProfile.A2DP, connectionPolicy)) {
return false;
}
if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
@@ -660,17 +685,15 @@ public class A2dpService extends ProfileService {
/**
* Get the connection policy of the profile.
*
- *
The connection policy can be any of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
+ * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device Bluetooth device
* @return connection policy of the device
*/
public int getConnectionPolicy(BluetoothDevice device) {
- return mDatabaseManager
- .getProfileConnectionPolicy(device, BluetoothProfile.A2DP);
+ return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP);
}
public void setAvrcpAbsoluteVolume(int volume) {
@@ -700,8 +723,8 @@ public class A2dpService extends ProfileService {
/**
* Gets the current codec status (configuration and capability).
*
- * @param device the remote Bluetooth device. If null, use the current
- * active A2DP Bluetooth device.
+ * @param device the remote Bluetooth device. If null, use the current active A2DP Bluetooth
+ * device.
* @return the current codec status
*/
public BluetoothCodecStatus getCodecStatus(BluetoothDevice device) {
@@ -724,14 +747,12 @@ public class A2dpService extends ProfileService {
/**
* Sets the codec configuration preference.
*
- * @param device the remote Bluetooth device. If null, use the currect
- * active A2DP Bluetooth device.
+ * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth
+ * device.
* @param codecConfig the codec configuration preference
*/
- public void setCodecConfigPreference(BluetoothDevice device,
- BluetoothCodecConfig codecConfig) {
- Log.d(TAG, "setCodecConfigPreference(" + device + "): "
- + Objects.toString(codecConfig));
+ public void setCodecConfigPreference(BluetoothDevice device, BluetoothCodecConfig codecConfig) {
+ Log.d(TAG, "setCodecConfigPreference(" + device + "): " + Objects.toString(codecConfig));
if (device == null) {
device = mActiveDevice;
}
@@ -754,8 +775,8 @@ public class A2dpService extends ProfileService {
/**
* Enables the optional codecs.
*
- * @param device the remote Bluetooth device. If null, use the currect
- * active A2DP Bluetooth device.
+ * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth
+ * device.
*/
public void enableOptionalCodecs(BluetoothDevice device) {
Log.d(TAG, "enableOptionalCodecs(" + device + ")");
@@ -782,8 +803,8 @@ public class A2dpService extends ProfileService {
/**
* Disables the optional codecs.
*
- * @param device the remote Bluetooth device. If null, use the currect
- * active A2DP Bluetooth device.
+ * @param device the remote Bluetooth device. If null, use the currect active A2DP Bluetooth
+ * device.
*/
public void disableOptionalCodecs(BluetoothDevice device) {
Log.d(TAG, "disableOptionalCodecs(" + device + ")");
@@ -811,18 +832,20 @@ public class A2dpService extends ProfileService {
* Checks whether optional codecs are supported
*
* @param device is the remote bluetooth device.
- * @return whether optional codecs are supported. Possible values are:
- * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORTED},
- * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_NOT_SUPPORTED},
- * {@link OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORT_UNKNOWN}.
+ * @return whether optional codecs are supported. Possible values are: {@link
+ * OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORTED}, {@link
+ * OptionalCodecsSupportStatus#OPTIONAL_CODECS_NOT_SUPPORTED}, {@link
+ * OptionalCodecsSupportStatus#OPTIONAL_CODECS_SUPPORT_UNKNOWN}.
*/
public @OptionalCodecsSupportStatus int getSupportsOptionalCodecs(BluetoothDevice device) {
return mDatabaseManager.getA2dpSupportsOptionalCodecs(device);
}
public void setSupportsOptionalCodecs(BluetoothDevice device, boolean doesSupport) {
- int value = doesSupport ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED
- : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
+ int value =
+ doesSupport
+ ? BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED
+ : BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
mDatabaseManager.setA2dpSupportsOptionalCodecs(device, value);
}
@@ -830,10 +853,10 @@ public class A2dpService extends ProfileService {
* Checks whether optional codecs are enabled
*
* @param device is the remote bluetooth device
- * @return whether the optional codecs are enabled. Possible values are:
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED},
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED},
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}.
+ * @return whether the optional codecs are enabled. Possible values are: {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}.
*/
public @OptionalCodecsPreferenceStatus int getOptionalCodecsEnabled(BluetoothDevice device) {
return mDatabaseManager.getA2dpOptionalCodecsEnabled(device);
@@ -843,13 +866,13 @@ public class A2dpService extends ProfileService {
* Sets the optional codecs to be set to the passed in value
*
* @param device is the remote bluetooth device
- * @param value is the new status for the optional codecs. Possible values are:
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED},
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED},
- * {@link OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}.
+ * @param value is the new status for the optional codecs. Possible values are: {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_ENABLED}, {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_DISABLED}, {@link
+ * OptionalCodecsPreferenceStatus#OPTIONAL_CODECS_PREF_UNKNOWN}.
*/
- public void setOptionalCodecsEnabled(BluetoothDevice device,
- @OptionalCodecsPreferenceStatus int value) {
+ public void setOptionalCodecsEnabled(
+ BluetoothDevice device, @OptionalCodecsPreferenceStatus int value) {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
@@ -862,15 +885,15 @@ public class A2dpService extends ProfileService {
/**
* Get dynamic audio buffer size supported type
*
- * @return support
Possible values are
- * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE},
- * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD},
- * {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
+ * @return support
+ *
Possible values are {@link BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_NONE}, {@link
+ * BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD}, {@link
+ * BluetoothA2dp#DYNAMIC_BUFFER_SUPPORT_A2DP_SOFTWARE_ENCODING}.
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public int getDynamicBufferSupport() {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
return mAdapterService.getDynamicBufferSupport();
}
@@ -881,8 +904,8 @@ public class A2dpService extends ProfileService {
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public BufferConstraints getBufferConstraints() {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
return mAdapterService.getBufferConstraints();
}
@@ -895,8 +918,8 @@ public class A2dpService extends ProfileService {
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setBufferLengthMillis(int codec, int value) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
return mAdapterService.setBufferLengthMillis(codec, value);
}
@@ -913,8 +936,11 @@ public class A2dpService extends ProfileService {
case A2dpStackEvent.CONNECTION_STATE_CONNECTING:
// Create a new state machine only when connecting to a device
if (!connectionAllowedCheckMaxDevices(device)) {
- Log.e(TAG, "Cannot connect to " + device
- + " : too many connected devices");
+ Log.e(
+ TAG,
+ "Cannot connect to "
+ + device
+ + " : too many connected devices");
return;
}
sm = getOrCreateStateMachine(device);
@@ -937,30 +963,45 @@ public class A2dpService extends ProfileService {
*
* @param device the remote device
* @param codecStatus the new codec status
- * @param sameAudioFeedingParameters if true the audio feeding parameters
- * haven't been changed
+ * @param sameAudioFeedingParameters if true the audio feeding parameters haven't been changed
*/
@VisibleForTesting
- public void codecConfigUpdated(BluetoothDevice device, BluetoothCodecStatus codecStatus,
- boolean sameAudioFeedingParameters) {
+ public void codecConfigUpdated(
+ BluetoothDevice device,
+ BluetoothCodecStatus codecStatus,
+ boolean sameAudioFeedingParameters) {
// Log codec config and capability metrics
BluetoothCodecConfig codecConfig = codecStatus.getCodecConfig();
int metricId = mAdapterService.getMetricId(device);
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED,
- mAdapterService.obfuscateAddress(device), codecConfig.getCodecType(),
- codecConfig.getCodecPriority(), codecConfig.getSampleRate(),
- codecConfig.getBitsPerSample(), codecConfig.getChannelMode(),
- codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(),
- codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId);
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED,
+ mAdapterService.obfuscateAddress(device),
+ codecConfig.getCodecType(),
+ codecConfig.getCodecPriority(),
+ codecConfig.getSampleRate(),
+ codecConfig.getBitsPerSample(),
+ codecConfig.getChannelMode(),
+ codecConfig.getCodecSpecific1(),
+ codecConfig.getCodecSpecific2(),
+ codecConfig.getCodecSpecific3(),
+ codecConfig.getCodecSpecific4(),
+ metricId);
List codecCapabilities =
codecStatus.getCodecsSelectableCapabilities();
for (BluetoothCodecConfig codecCapability : codecCapabilities) {
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED,
- mAdapterService.obfuscateAddress(device), codecCapability.getCodecType(),
- codecCapability.getCodecPriority(), codecCapability.getSampleRate(),
- codecCapability.getBitsPerSample(), codecCapability.getChannelMode(),
- codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(),
- codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId);
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED,
+ mAdapterService.obfuscateAddress(device),
+ codecCapability.getCodecType(),
+ codecCapability.getCodecPriority(),
+ codecCapability.getSampleRate(),
+ codecCapability.getBitsPerSample(),
+ codecCapability.getChannelMode(),
+ codecConfig.getCodecSpecific1(),
+ codecConfig.getCodecSpecific2(),
+ codecConfig.getCodecSpecific3(),
+ codecConfig.getCodecSpecific4(),
+ metricId);
}
broadcastCodecConfig(device, codecStatus);
@@ -973,8 +1014,8 @@ public class A2dpService extends ProfileService {
// restart the session even if feeding parameter are the same. (sameAudioFeedingParameters
// is left unused until there)
if (isActiveDevice(device)) {
- mAudioManager.handleBluetoothActiveDeviceChanged(device, device,
- BluetoothProfileConnectionInfo.createA2dpInfo(false, -1));
+ mAudioManager.handleBluetoothActiveDeviceChanged(
+ device, device, BluetoothProfileConnectionInfo.createA2dpInfo(false, -1));
}
}
@@ -990,8 +1031,10 @@ public class A2dpService extends ProfileService {
}
// Limit the maximum number of state machines to avoid DoS attack
if (mStateMachines.size() >= MAX_A2DP_STATE_MACHINES) {
- Log.e(TAG, "Maximum number of A2DP state machines reached: "
- + MAX_A2DP_STATE_MACHINES);
+ Log.e(
+ TAG,
+ "Maximum number of A2DP state machines reached: "
+ + MAX_A2DP_STATE_MACHINES);
return null;
}
Log.d(TAG, "Creating a new state machine for " + device);
@@ -1026,8 +1069,12 @@ public class A2dpService extends ProfileService {
byte[] addressBytes = Utils.getBytesFromAddress(address);
BluetoothDevice device = mAdapterService.getDeviceFromByte(addressBytes);
- Log.d(TAG, " onAudioDevicesAdded: " + device + ", device type: "
- + deviceInfo.getType());
+ Log.d(
+ TAG,
+ " onAudioDevicesAdded: "
+ + device
+ + ", device type: "
+ + deviceInfo.getType());
/* Don't expose already exposed active device */
if (device.equals(mExposedActiveDevice)) {
@@ -1035,11 +1082,16 @@ public class A2dpService extends ProfileService {
return;
}
-
if (!device.equals(mActiveDevice)) {
- Log.e(TAG, "Added device does not match to the one activated here. ("
- + device + " != " + mActiveDevice
- + " / " + mActiveDevice+ ")");
+ Log.e(
+ TAG,
+ "Added device does not match to the one activated here. ("
+ + device
+ + " != "
+ + mActiveDevice
+ + " / "
+ + mActiveDevice
+ + ")");
continue;
}
@@ -1070,9 +1122,14 @@ public class A2dpService extends ProfileService {
mExposedActiveDevice = null;
- Log.d(TAG, " onAudioDevicesRemoved: " + address + ", device type: "
- + deviceInfo.getType()
- + ", mActiveDevice: " + mActiveDevice);
+ Log.d(
+ TAG,
+ " onAudioDevicesRemoved: "
+ + address
+ + ", device type: "
+ + deviceInfo.getType()
+ + ", mActiveDevice: "
+ + mActiveDevice);
}
}
}
@@ -1089,13 +1146,16 @@ public class A2dpService extends ProfileService {
mAdapterService.handleActiveDeviceChange(BluetoothProfile.A2DP, device);
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED,
- BluetoothProfile.A2DP, mAdapterService.obfuscateAddress(device),
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_ACTIVE_DEVICE_CHANGED,
+ BluetoothProfile.A2DP,
+ mAdapterService.obfuscateAddress(device),
mAdapterService.getMetricId(device));
Intent intent = new Intent(BluetoothA2dp.ACTION_ACTIVE_DEVICE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ intent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
}
@@ -1105,7 +1165,8 @@ public class A2dpService extends ProfileService {
Intent intent = new Intent(BluetoothA2dp.ACTION_CODEC_CONFIG_CHANGED);
intent.putExtra(BluetoothCodecStatus.EXTRA_CODEC_STATUS, codecStatus);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ intent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
sendBroadcast(intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
}
@@ -1118,10 +1179,9 @@ public class A2dpService extends ProfileService {
* Process a change in the bonding state for a device.
*
* @param device the device whose bonding state has changed
- * @param bondState the new bond state for the device. Possible values are:
- * {@link BluetoothDevice#BOND_NONE},
- * {@link BluetoothDevice#BOND_BONDING},
- * {@link BluetoothDevice#BOND_BONDED}.
+ * @param bondState the new bond state for the device. Possible values are: {@link
+ * BluetoothDevice#BOND_NONE}, {@link BluetoothDevice#BOND_BONDING}, {@link
+ * BluetoothDevice#BOND_BONDED}.
*/
@VisibleForTesting
void bondStateChanged(BluetoothDevice device, int bondState) {
@@ -1149,8 +1209,9 @@ public class A2dpService extends ProfileService {
synchronized (mStateMachines) {
A2dpStateMachine sm = mStateMachines.get(device);
if (sm == null) {
- Log.w(TAG, "removeStateMachine: device " + device
- + " does not have a state machine");
+ Log.w(
+ TAG,
+ "removeStateMachine: device " + device + " does not have a state machine");
return;
}
Log.i(TAG, "removeStateMachine: removing state machine for device: " + device);
@@ -1160,7 +1221,6 @@ public class A2dpService extends ProfileService {
}
}
-
/**
* Update and initiate optional codec status change to native.
*
@@ -1197,8 +1257,8 @@ public class A2dpService extends ProfileService {
}
if (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN
- || supportsOptional != (previousSupport
- == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) {
+ || supportsOptional
+ != (previousSupport == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED)) {
setSupportsOptionalCodecs(device, supportsOptional);
}
if (supportsOptional) {
@@ -1219,9 +1279,9 @@ public class A2dpService extends ProfileService {
}
/**
- * Check for low-latency codec support and inform AdapterService
+ * Check for low-latency codec support and inform AdapterService
*
- * @param device device whose audio low latency will be allowed or disallowed
+ * @param device device whose audio low latency will be allowed or disallowed
*/
@VisibleForTesting
public void updateLowLatencyAudioSupport(BluetoothDevice device) {
@@ -1232,9 +1292,10 @@ public class A2dpService extends ProfileService {
}
BluetoothCodecStatus codecStatus = sm.getCodecStatus();
boolean lowLatencyAudioAllow = false;
- BluetoothCodecConfig lowLatencyCodec = new BluetoothCodecConfig.Builder()
- .setCodecType(SOURCE_CODEC_TYPE_OPUS) // remove in U
- .build();
+ BluetoothCodecConfig lowLatencyCodec =
+ new BluetoothCodecConfig.Builder()
+ .setCodecType(SOURCE_CODEC_TYPE_OPUS) // remove in U
+ .build();
if (codecStatus != null
&& codecStatus.isCodecConfigSelectable(lowLatencyCodec)
@@ -1296,22 +1357,17 @@ public class A2dpService extends ProfileService {
device, BluetoothProfile.A2DP, toState, fromState);
}
- /**
- * Retrieves the most recently connected device in the A2DP connected devices list.
- */
+ /** Retrieves the most recently connected device in the A2DP connected devices list. */
public BluetoothDevice getFallbackDevice() {
DatabaseManager dbManager = mAdapterService.getDatabase();
- return dbManager != null ? dbManager
- .getMostRecentlyConnectedDevicesInList(getConnectedDevices())
- : null;
+ return dbManager != null
+ ? dbManager.getMostRecentlyConnectedDevicesInList(getConnectedDevices())
+ : null;
}
- /**
- * Binder object: must be a static class or memory leak may occur.
- */
+ /** Binder object: must be a static class or memory leak may occur. */
@VisibleForTesting
- static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub
- implements IProfileServiceBinder {
+ static class BluetoothA2dpBinder extends IBluetoothA2dp.Stub implements IProfileServiceBinder {
private A2dpService mService;
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -1486,8 +1542,10 @@ public class A2dpService extends ProfileService {
}
@Override
- public void setCodecConfigPreference(BluetoothDevice device,
- BluetoothCodecConfig codecConfig, AttributionSource source) {
+ public void setCodecConfigPreference(
+ BluetoothDevice device,
+ BluetoothCodecConfig codecConfig,
+ AttributionSource source) {
A2dpService service = getService(source);
if (service == null) {
return;
@@ -1500,8 +1558,12 @@ public class A2dpService extends ProfileService {
+ " setCodecConfigPreference without a CompanionDeviceManager"
+ " service");
}
- enforceCdmAssociation(service.mCompanionDeviceManager, service,
- source.getPackageName(), Binder.getCallingUid(), device);
+ enforceCdmAssociation(
+ service.mCompanionDeviceManager,
+ service,
+ source.getPackageName(),
+ Binder.getCallingUid(),
+ device);
}
service.setCodecConfigPreference(device, codecConfig);
}
@@ -1513,8 +1575,8 @@ public class A2dpService extends ProfileService {
return;
}
- if (checkCallerTargetSdk(mService, source.getPackageName(),
- Build.VERSION_CODES.TIRAMISU)) {
+ if (checkCallerTargetSdk(
+ mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
enforceBluetoothPrivilegedPermission(service);
}
service.enableOptionalCodecs(device);
@@ -1527,8 +1589,8 @@ public class A2dpService extends ProfileService {
return;
}
- if (checkCallerTargetSdk(mService, source.getPackageName(),
- Build.VERSION_CODES.TIRAMISU)) {
+ if (checkCallerTargetSdk(
+ mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
enforceBluetoothPrivilegedPermission(service);
}
service.disableOptionalCodecs(device);
@@ -1563,15 +1625,15 @@ public class A2dpService extends ProfileService {
}
@Override
- public void setOptionalCodecsEnabled(BluetoothDevice device, int value,
- AttributionSource source) {
+ public void setOptionalCodecsEnabled(
+ BluetoothDevice device, int value, AttributionSource source) {
A2dpService service = getService(source);
if (service == null) {
return;
}
- if (checkCallerTargetSdk(mService, source.getPackageName(),
- Build.VERSION_CODES.TIRAMISU)) {
+ if (checkCallerTargetSdk(
+ mService, source.getPackageName(), Build.VERSION_CODES.TIRAMISU)) {
enforceBluetoothPrivilegedPermission(service);
}
service.setOptionalCodecsEnabled(device, value);
@@ -1616,9 +1678,12 @@ public class A2dpService extends ProfileService {
if (mA2dpCodecConfig != null) {
ProfileService.println(sb, "codecConfigPriorities:");
for (BluetoothCodecConfig codecConfig : mA2dpCodecConfig.codecConfigPriorities()) {
- ProfileService.println(sb, " " + BluetoothCodecConfig.getCodecName(
- codecConfig.getCodecType()) + ": "
- + codecConfig.getCodecPriority());
+ ProfileService.println(
+ sb,
+ " "
+ + BluetoothCodecConfig.getCodecName(codecConfig.getCodecType())
+ + ": "
+ + codecConfig.getCodecPriority());
}
ProfileService.println(sb, "mA2dpOffloadEnabled: " + mA2dpOffloadEnabled);
if (mA2dpOffloadEnabled) {
@@ -1644,11 +1709,11 @@ public class A2dpService extends ProfileService {
}
/**
- * Sends the preferred audio profile change requested from a call to
- * {@link BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio
- * framework to apply the change. The audio framework will call
- * {@link BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the
- * change is successfully applied.
+ * Sends the preferred audio profile change requested from a call to {@link
+ * BluetoothAdapter#setPreferredAudioProfiles(BluetoothDevice, Bundle)} to the audio framework
+ * to apply the change. The audio framework will call {@link
+ * BluetoothAdapter#notifyActiveDeviceChangeApplied(BluetoothDevice)} once the change is
+ * successfully applied.
*
* @return the number of requests sent to the audio framework
*/
@@ -1658,7 +1723,9 @@ public class A2dpService extends ProfileService {
Log.e(TAG, "sendPreferredAudioProfileChangeToAudioFramework: no active device");
return 0;
}
- mAudioManager.handleBluetoothActiveDeviceChanged(mActiveDevice, mActiveDevice,
+ mAudioManager.handleBluetoothActiveDeviceChanged(
+ mActiveDevice,
+ mActiveDevice,
BluetoothProfileConnectionInfo.createA2dpInfo(false, -1));
return 1;
}
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
index 4ebd82a0c48c02cda0a88cb324776ed1684072fa..9da6a213ea843043c949268f7a923ea16b5bb80f 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStackEvent.java
@@ -20,8 +20,8 @@ import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
/**
- * Stack event sent via a callback from JNI to Java, or generated
- * internally by the A2DP State Machine.
+ * Stack event sent via a callback from JNI to Java, or generated internally by the A2DP State
+ * Machine.
*/
public class A2dpStackEvent {
// Event types for STACK_EVENT message (coming from native)
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
index 3610984362559d41f85fc52bc268fa3ed334f779..502596c1ba3403f9b09752cf0f58af8723aeeb89 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java
@@ -15,34 +15,18 @@
*/
/**
- * Bluetooth A2DP StateMachine. There is one instance per remote device.
- * - "Disconnected" and "Connected" are steady states.
- * - "Connecting" and "Disconnecting" are transient states until the
- * connection / disconnection is completed.
+ * Bluetooth A2DP StateMachine. There is one instance per remote device. - "Disconnected" and
+ * "Connected" are steady states. - "Connecting" and "Disconnecting" are transient states until the
+ * connection / disconnection is completed.
*
+ * (Disconnected) | ^ CONNECT | | DISCONNECTED V | (Connecting)<--->(Disconnecting) | ^ CONNECTED
+ * | | DISCONNECT V | (Connected) NOTES: - If state machine is in "Connecting" state and the remote
+ * device sends DISCONNECT request, the state machine transitions to "Disconnecting" state. -
+ * Similarly, if the state machine is in "Disconnecting" state and the remote device sends CONNECT
+ * request, the state machine transitions to "Connecting" state.
*
- * (Disconnected)
- * | ^
- * CONNECT | | DISCONNECTED
- * V |
- * (Connecting)<--->(Disconnecting)
- * | ^
- * CONNECTED | | DISCONNECT
- * V |
- * (Connected)
- * NOTES:
- * - If state machine is in "Connecting" state and the remote device sends
- * DISCONNECT request, the state machine transitions to "Disconnecting" state.
- * - Similarly, if the state machine is in "Disconnecting" state and the remote device
- * sends CONNECT request, the state machine transitions to "Connecting" state.
- *
- * DISCONNECT
- * (Connecting) ---------------> (Disconnecting)
- * <---------------
- * CONNECT
- *
+ *
DISCONNECT (Connecting) ---------------> (Disconnecting) <--------------- CONNECT
*/
-
package com.android.bluetooth.a2dp;
import static android.Manifest.permission.BLUETOOTH_CONNECT;
@@ -78,13 +62,11 @@ final class A2dpStateMachine extends StateMachine {
static final int CONNECT = 1;
static final int DISCONNECT = 2;
- @VisibleForTesting
- static final int STACK_EVENT = 101;
+ @VisibleForTesting static final int STACK_EVENT = 101;
private static final int CONNECT_TIMEOUT = 201;
// NOTE: the value is not "final" - it is modified in the unit tests
- @VisibleForTesting
- static int sConnectTimeoutMs = 30000; // 30s
+ @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s
private Disconnected mDisconnected;
private Connecting mConnecting;
@@ -95,14 +77,16 @@ final class A2dpStateMachine extends StateMachine {
private A2dpService mA2dpService;
private A2dpNativeInterface mA2dpNativeInterface;
- @VisibleForTesting
- boolean mA2dpOffloadEnabled = false;
+ @VisibleForTesting boolean mA2dpOffloadEnabled = false;
private final BluetoothDevice mDevice;
private boolean mIsPlaying = false;
private BluetoothCodecStatus mCodecStatus;
- A2dpStateMachine(BluetoothDevice device, A2dpService a2dpService,
- A2dpNativeInterface a2dpNativeInterface, Looper looper) {
+ A2dpStateMachine(
+ BluetoothDevice device,
+ A2dpService a2dpService,
+ A2dpNativeInterface a2dpNativeInterface,
+ Looper looper) {
super(TAG, looper);
// Let the logging framework enforce the log level. TAG is set above in the parent
@@ -127,11 +111,14 @@ final class A2dpStateMachine extends StateMachine {
setInitialState(mDisconnected);
}
- static A2dpStateMachine make(BluetoothDevice device, A2dpService a2dpService,
- A2dpNativeInterface a2dpNativeInterface, Looper looper) {
+ static A2dpStateMachine make(
+ BluetoothDevice device,
+ A2dpService a2dpService,
+ A2dpNativeInterface a2dpNativeInterface,
+ Looper looper) {
Log.i(TAG, "make for device " + device);
- A2dpStateMachine a2dpSm = new A2dpStateMachine(device, a2dpService, a2dpNativeInterface,
- looper);
+ A2dpStateMachine a2dpSm =
+ new A2dpStateMachine(device, a2dpService, a2dpNativeInterface, looper);
a2dpSm.start();
return a2dpSm;
}
@@ -142,8 +129,7 @@ final class A2dpStateMachine extends StateMachine {
// Stop if auido is still playing
log("doQuit: stopped playing " + mDevice);
mIsPlaying = false;
- broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING,
- BluetoothA2dp.STATE_PLAYING);
+ broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING);
}
quitNow();
}
@@ -157,8 +143,14 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void enter() {
Message currentMessage = getCurrentMessage();
- Log.i(TAG, "Enter Disconnected(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ Log.i(
+ TAG,
+ "Enter Disconnected("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mConnectionState = BluetoothProfile.STATE_DISCONNECTED;
removeDeferredMessages(DISCONNECT);
@@ -169,8 +161,8 @@ final class A2dpStateMachine extends StateMachine {
if (mIsPlaying) {
Log.i(TAG, "Disconnected: stopped playing: " + mDevice);
mIsPlaying = false;
- broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING,
- BluetoothA2dp.STATE_PLAYING);
+ broadcastAudioState(
+ BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING);
}
}
@@ -180,15 +172,23 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void exit() {
Message currentMessage = getCurrentMessage();
- log("Exit Disconnected(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ log(
+ "Exit Disconnected("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED;
}
@Override
public boolean processMessage(Message message) {
- log("Disconnected process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(
+ "Disconnected process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
@@ -294,8 +294,14 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void enter() {
Message currentMessage = getCurrentMessage();
- Log.i(TAG, "Enter Connecting(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ Log.i(
+ TAG,
+ "Enter Connecting("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
mConnectionState = BluetoothProfile.STATE_CONNECTING;
broadcastConnectionState(mConnectionState, mLastConnectionState);
@@ -304,33 +310,43 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void exit() {
Message currentMessage = getCurrentMessage();
- log("Exit Connecting(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ log(
+ "Exit Connecting("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mLastConnectionState = BluetoothProfile.STATE_CONNECTING;
removeMessages(CONNECT_TIMEOUT);
}
@Override
public boolean processMessage(Message message) {
- log("Connecting process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(
+ "Connecting process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
deferMessage(message);
break;
- case CONNECT_TIMEOUT: {
- Log.w(TAG, "Connecting connection timeout: " + mDevice);
- mA2dpNativeInterface.disconnectA2dp(mDevice);
- A2dpStackEvent event =
- new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- event.device = mDevice;
- event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, event);
- MetricsLogger.getInstance().count(
- BluetoothProtoEnums.A2DP_CONNECTION_TIMEOUT, 1);
- break;
- }
+ case CONNECT_TIMEOUT:
+ {
+ Log.w(TAG, "Connecting connection timeout: " + mDevice);
+ mA2dpNativeInterface.disconnectA2dp(mDevice);
+ A2dpStackEvent event =
+ new A2dpStackEvent(
+ A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+ event.device = mDevice;
+ event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED;
+ sendMessage(STACK_EVENT, event);
+ MetricsLogger.getInstance()
+ .count(BluetoothProtoEnums.A2DP_CONNECTION_TIMEOUT, 1);
+ break;
+ }
case DISCONNECT:
// Cancel connection
Log.i(TAG, "Connecting: connection canceled to " + mDevice);
@@ -392,8 +408,14 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void enter() {
Message currentMessage = getCurrentMessage();
- Log.i(TAG, "Enter Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ Log.i(
+ TAG,
+ "Enter Disconnecting("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
mConnectionState = BluetoothProfile.STATE_DISCONNECTING;
broadcastConnectionState(mConnectionState, mLastConnectionState);
@@ -402,31 +424,41 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void exit() {
Message currentMessage = getCurrentMessage();
- log("Exit Disconnecting(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ log(
+ "Exit Disconnecting("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING;
removeMessages(CONNECT_TIMEOUT);
}
@Override
public boolean processMessage(Message message) {
- log("Disconnecting process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(
+ "Disconnecting process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
deferMessage(message);
break;
- case CONNECT_TIMEOUT: {
- Log.w(TAG, "Disconnecting connection timeout: " + mDevice);
- mA2dpNativeInterface.disconnectA2dp(mDevice);
- A2dpStackEvent event =
- new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
- event.device = mDevice;
- event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED;
- sendMessage(STACK_EVENT, event);
- break;
- }
+ case CONNECT_TIMEOUT:
+ {
+ Log.w(TAG, "Disconnecting connection timeout: " + mDevice);
+ mA2dpNativeInterface.disconnectA2dp(mDevice);
+ A2dpStackEvent event =
+ new A2dpStackEvent(
+ A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
+ event.device = mDevice;
+ event.valueInt = A2dpStackEvent.CONNECTION_STATE_DISCONNECTED;
+ sendMessage(STACK_EVENT, event);
+ break;
+ }
case DISCONNECT:
deferMessage(message);
break;
@@ -497,8 +529,14 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void enter() {
Message currentMessage = getCurrentMessage();
- Log.i(TAG, "Enter Connected(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ Log.i(
+ TAG,
+ "Enter Connected("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mConnectionState = BluetoothProfile.STATE_CONNECTED;
removeDeferredMessages(CONNECT);
@@ -518,8 +556,13 @@ final class A2dpStateMachine extends StateMachine {
@Override
public void exit() {
Message currentMessage = getCurrentMessage();
- log("Exit Connected(" + mDevice + "): " + (currentMessage == null ? "null"
- : messageWhatToString(currentMessage.what)));
+ log(
+ "Exit Connected("
+ + mDevice
+ + "): "
+ + (currentMessage == null
+ ? "null"
+ : messageWhatToString(currentMessage.what)));
mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
}
@@ -531,17 +574,19 @@ final class A2dpStateMachine extends StateMachine {
case CONNECT:
Log.w(TAG, "Connected: CONNECT ignored: " + mDevice);
break;
- case DISCONNECT: {
- Log.i(TAG, "Disconnecting from " + mDevice);
- if (!mA2dpNativeInterface.disconnectA2dp(mDevice)) {
- // If error in the native stack, transition directly to Disconnected state.
- Log.e(TAG, "Connected: error disconnecting from " + mDevice);
- transitionTo(mDisconnected);
- break;
+ case DISCONNECT:
+ {
+ Log.i(TAG, "Disconnecting from " + mDevice);
+ if (!mA2dpNativeInterface.disconnectA2dp(mDevice)) {
+ // If error in the native stack, transition directly to Disconnected
+ // state.
+ Log.e(TAG, "Connected: error disconnecting from " + mDevice);
+ transitionTo(mDisconnected);
+ break;
+ }
+ transitionTo(mDisconnecting);
}
- transitionTo(mDisconnecting);
- }
- break;
+ break;
case STACK_EVENT:
A2dpStackEvent event = (A2dpStackEvent) message.obj;
log("Connected: stack event: " + event);
@@ -600,8 +645,8 @@ final class A2dpStateMachine extends StateMachine {
if (!mIsPlaying) {
Log.i(TAG, "Connected: started playing: " + mDevice);
mIsPlaying = true;
- broadcastAudioState(BluetoothA2dp.STATE_PLAYING,
- BluetoothA2dp.STATE_NOT_PLAYING);
+ broadcastAudioState(
+ BluetoothA2dp.STATE_PLAYING, BluetoothA2dp.STATE_NOT_PLAYING);
}
}
break;
@@ -611,8 +656,8 @@ final class A2dpStateMachine extends StateMachine {
if (mIsPlaying) {
Log.i(TAG, "Connected: stopped playing: " + mDevice);
mIsPlaying = false;
- broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING,
- BluetoothA2dp.STATE_PLAYING);
+ broadcastAudioState(
+ BluetoothA2dp.STATE_NOT_PLAYING, BluetoothA2dp.STATE_PLAYING);
}
}
break;
@@ -679,10 +724,13 @@ final class A2dpStateMachine extends StateMachine {
// The following is a large enough debug operation such that we want to guard it was an
// isLoggable check
if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "A2DP Codec Config: " + prevCodecConfig + "->"
- + newCodecStatus.getCodecConfig());
- for (BluetoothCodecConfig codecConfig :
- newCodecStatus.getCodecsLocalCapabilities()) {
+ Log.d(
+ TAG,
+ "A2DP Codec Config: "
+ + prevCodecConfig
+ + "->"
+ + newCodecStatus.getCodecConfig());
+ for (BluetoothCodecConfig codecConfig : newCodecStatus.getCodecsLocalCapabilities()) {
Log.d(TAG, "A2DP Codec Local Capability: " + codecConfig);
}
for (BluetoothCodecConfig codecConfig :
@@ -707,17 +755,17 @@ final class A2dpStateMachine extends StateMachine {
} else if (!newCodecConfig.sameAudioFeedingParameters(prevCodecConfig)) {
update = true;
} else if ((newCodecConfig.getCodecType()
- == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
+ == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC)
&& (prevCodecConfig != null)
&& (prevCodecConfig.getCodecSpecific1()
- != newCodecConfig.getCodecSpecific1())) {
+ != newCodecConfig.getCodecSpecific1())) {
update = true;
} else if ((newCodecConfig.getCodecType()
- == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
+ == BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS)
&& (prevCodecConfig != null)
// check framesize field
&& (prevCodecConfig.getCodecSpecific1()
- != newCodecConfig.getCodecSpecific1())) {
+ != newCodecConfig.getCodecSpecific1())) {
update = true;
}
if (update) {
@@ -733,14 +781,20 @@ final class A2dpStateMachine extends StateMachine {
// This method does not check for error condition (newState == prevState)
private void broadcastConnectionState(int newState, int prevState) {
- log("Connection state " + mDevice + ": " + profileStateToString(prevState)
- + "->" + profileStateToString(newState));
+ log(
+ "Connection state "
+ + mDevice
+ + ": "
+ + profileStateToString(prevState)
+ + "->"
+ + profileStateToString(newState));
Intent intent = new Intent(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, newState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ intent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
| Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mA2dpService.handleConnectionStateChanged(mDevice, prevState, newState);
mA2dpService.sendBroadcast(
@@ -748,8 +802,13 @@ final class A2dpStateMachine extends StateMachine {
}
private void broadcastAudioState(int newState, int prevState) {
- log("A2DP Playing state : device: " + mDevice + " State:" + audioStateToString(prevState)
- + "->" + audioStateToString(newState));
+ log(
+ "A2DP Playing state : device: "
+ + mDevice
+ + " State:"
+ + audioStateToString(prevState)
+ + "->"
+ + audioStateToString(newState));
Intent intent = new Intent(BluetoothA2dp.ACTION_PLAYING_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, prevState);
@@ -773,8 +832,8 @@ final class A2dpStateMachine extends StateMachine {
return builder.toString();
}
- private static boolean sameSelectableCodec(BluetoothCodecStatus prevCodecStatus,
- BluetoothCodecStatus newCodecStatus) {
+ private static boolean sameSelectableCodec(
+ BluetoothCodecStatus prevCodecStatus, BluetoothCodecStatus newCodecStatus) {
if (prevCodecStatus == null || newCodecStatus == null) {
return false;
}
@@ -838,16 +897,23 @@ final class A2dpStateMachine extends StateMachine {
public void dump(StringBuilder sb) {
boolean isActive = Objects.equals(mDevice, mA2dpService.getActiveDevice());
- ProfileService.println(sb,
- "=== A2dpStateMachine for " + mDevice + (isActive ? " (Active) ===" : " ==="));
- ProfileService.println(sb,
- " getConnectionPolicy: " + mA2dpService.getConnectionPolicy(mDevice));
- ProfileService.println(sb, " mConnectionState: " + profileStateToString(mConnectionState)
- + ", mLastConnectionState: " + profileStateToString(mLastConnectionState));
+ ProfileService.println(
+ sb, "=== A2dpStateMachine for " + mDevice + (isActive ? " (Active) ===" : " ==="));
+ ProfileService.println(
+ sb, " getConnectionPolicy: " + mA2dpService.getConnectionPolicy(mDevice));
+ ProfileService.println(
+ sb,
+ " mConnectionState: "
+ + profileStateToString(mConnectionState)
+ + ", mLastConnectionState: "
+ + profileStateToString(mLastConnectionState));
ProfileService.println(sb, " mIsPlaying: " + mIsPlaying);
- ProfileService.println(sb,
- " getSupportsOptionalCodecs: " + mA2dpService.getSupportsOptionalCodecs(mDevice)
- + ", getOptionalCodecsEnabled: " + mA2dpService.getOptionalCodecsEnabled(mDevice));
+ ProfileService.println(
+ sb,
+ " getSupportsOptionalCodecs: "
+ + mA2dpService.getSupportsOptionalCodecs(mDevice)
+ + ", getOptionalCodecsEnabled: "
+ + mA2dpService.getOptionalCodecsEnabled(mDevice));
synchronized (this) {
if (mCodecStatus != null) {
ProfileService.println(sb, " mCodecConfig: " + mCodecStatus.getCodecConfig());
@@ -861,7 +927,7 @@ final class A2dpStateMachine extends StateMachine {
// Dump the state machine logs
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
- super.dump(new FileDescriptor(), printWriter, new String[]{});
+ super.dump(new FileDescriptor(), printWriter, new String[] {});
printWriter.flush();
stringWriter.flush();
ProfileService.println(sb, " StateMachineLog:");
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
index 944291a2829b06e787d6a25188443b933ffc4e7c..1f599fa1c4463feca6d7e539095b759881dce643 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkNativeInterface.java
@@ -27,9 +27,7 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.Objects;
-/**
- * A2DP Sink Native Interface to/from JNI.
- */
+/** A2DP Sink Native Interface to/from JNI. */
public class A2dpSinkNativeInterface {
private static final String TAG = A2dpSinkNativeInterface.class.getSimpleName();
private AdapterService mAdapterService;
@@ -40,13 +38,13 @@ public class A2dpSinkNativeInterface {
private static final Object INSTANCE_LOCK = new Object();
private A2dpSinkNativeInterface() {
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when A2dpSinkNativeInterface init");
+ mAdapterService =
+ Objects.requireNonNull(
+ AdapterService.getAdapterService(),
+ "AdapterService cannot be null when A2dpSinkNativeInterface init");
}
- /**
- * Get singleton instance.
- */
+ /** Get singleton instance. */
public static A2dpSinkNativeInterface getInstance() {
synchronized (INSTANCE_LOCK) {
if (sInstance == null) {
@@ -73,9 +71,7 @@ public class A2dpSinkNativeInterface {
initNative(maxConnectedAudioDevices);
}
- /**
- * Cleanup the native interface.
- */
+ /** Cleanup the native interface. */
public void cleanup() {
cleanupNative();
}
@@ -115,10 +111,10 @@ public class A2dpSinkNativeInterface {
/**
* Set a BluetoothDevice as the active device
*
- * The active device is the only one that will receive passthrough commands and the only one
+ *
The active device is the only one that will receive passthrough commands and the only one
* that will have its audio decoded.
*
- * Sending null for the active device will make no device active.
+ *
Sending null for the active device will make no device active.
*
* @param device
* @return True if the active device request has been scheduled
@@ -152,9 +148,7 @@ public class A2dpSinkNativeInterface {
informAudioTrackGainNative(gain);
}
- /**
- * Send a stack event up to the A2DP Sink Service
- */
+ /** Send a stack event up to the A2DP Sink Service */
private void sendMessageToService(StackEvent event) {
A2dpSinkService service = A2dpSinkService.getA2dpSinkService();
if (service != null) {
@@ -164,41 +158,40 @@ public class A2dpSinkNativeInterface {
}
}
- /**
- * For the JNI to send messages about connection state changes
- */
+ /** For the JNI to send messages about connection state changes */
public void onConnectionStateChanged(byte[] address, int state) {
- StackEvent event =
- StackEvent.connectionStateChanged(getDevice(address), state);
+ StackEvent event = StackEvent.connectionStateChanged(getDevice(address), state);
Log.d(TAG, "onConnectionStateChanged: " + event);
sendMessageToService(event);
}
- /**
- * For the JNI to send messages about audio stream state changes
- */
+ /** For the JNI to send messages about audio stream state changes */
public void onAudioStateChanged(byte[] address, int state) {
StackEvent event = StackEvent.audioStateChanged(getDevice(address), state);
Log.d(TAG, "onAudioStateChanged: " + event);
sendMessageToService(event);
}
- /**
- * For the JNI to send messages about audio configuration changes
- */
+ /** For the JNI to send messages about audio configuration changes */
public void onAudioConfigChanged(byte[] address, int sampleRate, int channelCount) {
- StackEvent event = StackEvent.audioConfigChanged(
- getDevice(address), sampleRate, channelCount);
+ StackEvent event =
+ StackEvent.audioConfigChanged(getDevice(address), sampleRate, channelCount);
Log.d(TAG, "onAudioConfigChanged: " + event);
sendMessageToService(event);
}
// Native methods that call into the JNI interface
private native void initNative(int maxConnectedAudioDevices);
+
private native void cleanupNative();
+
private native boolean connectA2dpNative(byte[] address);
+
private native boolean disconnectA2dpNative(byte[] address);
+
private native boolean setActiveDeviceNative(byte[] address);
+
private native void informAudioFocusStateNative(int focusGranted);
+
private native void informAudioTrackGainNative(float gain);
}
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
index 1bb970577bbf88e375c70a86f3c91da5ce06c243..0965e07c6533b7c1befdfdd171dda7619d9fa252 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkService.java
@@ -44,9 +44,7 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-/**
- * Provides Bluetooth A2DP Sink profile, as a service in the Bluetooth application.
- */
+/** Provides Bluetooth A2DP Sink profile, as a service in the Bluetooth application. */
public class A2dpSinkService extends ProfileService {
private static final String TAG = A2dpSinkService.class.getSimpleName();
@@ -131,17 +129,13 @@ public class A2dpSinkService extends ProfileService {
return sService;
}
- /**
- * Testing API to inject a mockA2dpSinkService.
- */
+ /** Testing API to inject a mockA2dpSinkService. */
@VisibleForTesting
public static synchronized void setA2dpSinkService(A2dpSinkService service) {
sService = service;
}
- /**
- * Set the device that should be allowed to actively stream
- */
+ /** Set the device that should be allowed to actively stream */
public boolean setActiveDevice(BluetoothDevice device) {
Log.i(TAG, "setActiveDevice(device=" + device + ")");
synchronized (mActiveDeviceLock) {
@@ -153,18 +147,14 @@ public class A2dpSinkService extends ProfileService {
}
}
- /**
- * Get the device that is allowed to be actively streaming
- */
+ /** Get the device that is allowed to be actively streaming */
public BluetoothDevice getActiveDevice() {
synchronized (mActiveDeviceLock) {
return mActiveDevice;
}
}
- /**
- * Request audio focus such that the designated device can stream audio
- */
+ /** Request audio focus such that the designated device can stream audio */
public void requestAudioFocus(BluetoothDevice device, boolean request) {
synchronized (mStreamHandlerLock) {
if (mA2dpSinkStreamHandler == null) return;
@@ -199,7 +189,7 @@ public class A2dpSinkService extends ProfileService {
return new A2dpSinkServiceBinder(this);
}
- //Binder object: Must be static class or memory leak may occur
+ // Binder object: Must be static class or memory leak may occur
@VisibleForTesting
static class A2dpSinkServiceBinder extends IBluetoothA2dpSink.Stub
implements IProfileServiceBinder {
@@ -322,14 +312,13 @@ public class A2dpSinkService extends ProfileService {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean connect(BluetoothDevice device) {
Log.d(TAG, "connect device=" + device);
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
if (device == null) {
throw new IllegalArgumentException("Null device");
}
if (getConnectionPolicy(device) == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- Log.w(TAG, "Connection not allowed: <" + device
- + "> is CONNECTION_POLICY_FORBIDDEN");
+ Log.w(TAG, "Connection not allowed: <" + device + "> is CONNECTION_POLICY_FORBIDDEN");
return false;
}
@@ -339,8 +328,11 @@ public class A2dpSinkService extends ProfileService {
return true;
} else {
// a state machine instance doesn't exist yet, and the max has been reached.
- Log.e(TAG, "Maxed out on the number of allowed A2DP Sink connections. "
- + "Connect request rejected on " + device);
+ Log.e(
+ TAG,
+ "Maxed out on the number of allowed A2DP Sink connections. "
+ + "Connect request rejected on "
+ + device);
return false;
}
}
@@ -388,7 +380,7 @@ public class A2dpSinkService extends ProfileService {
}
public List getConnectedDevices() {
- return getDevicesMatchingConnectionStates(new int[]{BluetoothAdapter.STATE_CONNECTED});
+ return getDevicesMatchingConnectionStates(new int[] {BluetoothAdapter.STATE_CONNECTED});
}
protected A2dpSinkStateMachine getOrCreateStateMachine(BluetoothDevice device) {
@@ -425,8 +417,12 @@ public class A2dpSinkService extends ProfileService {
}
}
}
- Log.d(TAG, "getDevicesMatchingConnectionStates(" + Arrays.toString(states) + "): Found "
- + deviceList.toString());
+ Log.d(
+ TAG,
+ "getDevicesMatchingConnectionStates("
+ + Arrays.toString(states)
+ + "): Found "
+ + deviceList.toString());
return deviceList;
}
@@ -434,28 +430,28 @@ public class A2dpSinkService extends ProfileService {
* Get the current connection state of the profile
*
* @param device is the remote bluetooth device
- * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected,
- * {@link BluetoothProfile#STATE_CONNECTING} if this profile is being connected,
- * {@link BluetoothProfile#STATE_CONNECTED} if this profile is connected, or
- * {@link BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected
+ * @return {@link BluetoothProfile#STATE_DISCONNECTED} if this profile is disconnected, {@link
+ * BluetoothProfile#STATE_CONNECTING} if this profile is being connected, {@link
+ * BluetoothProfile#STATE_CONNECTED} if this profile is connected, or {@link
+ * BluetoothProfile#STATE_DISCONNECTING} if this profile is being disconnected
*/
public int getConnectionState(BluetoothDevice device) {
if (device == null) return BluetoothProfile.STATE_DISCONNECTED;
A2dpSinkStateMachine stateMachine = mDeviceStateMap.get(device);
- return (stateMachine == null) ? BluetoothProfile.STATE_DISCONNECTED
+ return (stateMachine == null)
+ ? BluetoothProfile.STATE_DISCONNECTED
: stateMachine.getState();
}
/**
- * Set connection policy of the profile and connects it if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
+ * Set connection policy of the profile and connects it if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
*
- * The device should already be paired.
- * Connection policy can be one of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The device should already be paired. Connection policy can be one of: {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device Paired bluetooth device
* @param connectionPolicy is the connection policy to set to for this profile
@@ -467,8 +463,8 @@ public class A2dpSinkService extends ProfileService {
BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
- if (!mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK,
- connectionPolicy)) {
+ if (!mDatabaseManager.setProfileConnectionPolicy(
+ device, BluetoothProfile.A2DP_SINK, connectionPolicy)) {
return false;
}
if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
@@ -489,11 +485,9 @@ public class A2dpSinkService extends ProfileService {
public int getConnectionPolicy(BluetoothDevice device) {
enforceCallingOrSelfPermission(
BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
- return mDatabaseManager
- .getProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK);
+ return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.A2DP_SINK);
}
-
@Override
public void dump(StringBuilder sb) {
super.dump(sb);
@@ -501,8 +495,8 @@ public class A2dpSinkService extends ProfileService {
ProfileService.println(sb, "Max Connected Devices = " + mMaxConnectedAudioDevices);
ProfileService.println(sb, "Devices Tracked = " + mDeviceStateMap.size());
for (A2dpSinkStateMachine stateMachine : mDeviceStateMap.values()) {
- ProfileService.println(sb,
- "==== StateMachine for " + stateMachine.getDevice() + " ====");
+ ProfileService.println(
+ sb, "==== StateMachine for " + stateMachine.getDevice() + " ====");
stateMachine.dump(sb);
}
}
@@ -517,9 +511,7 @@ public class A2dpSinkService extends ProfileService {
return stateMachine.getAudioConfig();
}
- /**
- * Receive and route a stack event from the JNI
- */
+ /** Receive and route a stack event from the JNI */
protected void messageFromNative(StackEvent event) {
switch (event.mType) {
case StackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED:
@@ -553,12 +545,14 @@ public class A2dpSinkService extends ProfileService {
Log.e(TAG, "Received audio state change before we've been started");
return;
} else if (state == StackEvent.AUDIO_STATE_STARTED) {
- mA2dpSinkStreamHandler.obtainMessage(
- A2dpSinkStreamHandler.SRC_STR_START).sendToTarget();
+ mA2dpSinkStreamHandler
+ .obtainMessage(A2dpSinkStreamHandler.SRC_STR_START)
+ .sendToTarget();
} else if (state == StackEvent.AUDIO_STATE_STOPPED
|| state == StackEvent.AUDIO_STATE_REMOTE_SUSPEND) {
- mA2dpSinkStreamHandler.obtainMessage(
- A2dpSinkStreamHandler.SRC_STR_STOP).sendToTarget();
+ mA2dpSinkStreamHandler
+ .obtainMessage(A2dpSinkStreamHandler.SRC_STR_STOP)
+ .sendToTarget();
} else {
Log.w(TAG, "Unhandled audio state change, state=" + state);
}
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
index f08c13a9511598d67ad7155cda5775d9670a0c52..927dcefefb967c5cd19a500a5b6c10fb465f99a6 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStateMachine.java
@@ -98,9 +98,7 @@ class A2dpSinkStateMachine extends StateMachine {
return mMostRecentState;
}
- /**
- * get current audio config
- */
+ /** get current audio config */
BluetoothAudioConfig getAudioConfig() {
return mAudioConfig;
}
@@ -131,17 +129,24 @@ class A2dpSinkStateMachine extends StateMachine {
/**
* Dump the current State Machine to the string builder.
+ *
* @param sb output string
*/
public void dump(StringBuilder sb) {
- ProfileService.println(sb, "mDevice: " + mDevice + "("
- + Utils.getName(mDevice) + ") " + this.toString());
+ ProfileService.println(
+ sb, "mDevice: " + mDevice + "(" + Utils.getName(mDevice) + ") " + this.toString());
}
@Override
protected void unhandledMessage(Message msg) {
- Log.w(TAG, "[" + mDevice + "] unhandledMessage state=" + getCurrentState() + ", msg.what="
- + msg.what);
+ Log.w(
+ TAG,
+ "["
+ + mDevice
+ + "] unhandledMessage state="
+ + getCurrentState()
+ + ", msg.what="
+ + msg.what);
}
class Disconnected extends State {
@@ -179,8 +184,12 @@ class A2dpSinkStateMachine extends StateMachine {
case StackEvent.CONNECTION_STATE_CONNECTING:
if (mService.getConnectionPolicy(mDevice)
== BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
- Log.w(TAG, "[" + mDevice + "] Ignore incoming connection, profile"
- + " is turned off");
+ Log.w(
+ TAG,
+ "["
+ + mDevice
+ + "] Ignore incoming connection, profile"
+ + " is turned off");
mNativeInterface.disconnectA2dpSink(mDevice);
} else {
mConnecting.mIncomingConnection = true;
@@ -224,8 +233,12 @@ class A2dpSinkStateMachine extends StateMachine {
transitionTo(mDisconnected);
return true;
case DISCONNECT:
- Log.d(TAG, "[" + mDevice + "] Received disconnect message while connecting."
- + "deferred");
+ Log.d(
+ TAG,
+ "["
+ + mDevice
+ + "] Received disconnect message while connecting."
+ + "deferred");
deferMessage(message);
return true;
}
@@ -245,12 +258,12 @@ class A2dpSinkStateMachine extends StateMachine {
}
}
}
+
@Override
public void exit() {
removeMessages(CONNECT_TIMEOUT);
mIncomingConnection = false;
}
-
}
class Connected extends State {
@@ -287,8 +300,11 @@ class A2dpSinkStateMachine extends StateMachine {
}
break;
case StackEvent.EVENT_TYPE_AUDIO_CONFIG_CHANGED:
- mAudioConfig = new BluetoothAudioConfig(event.mSampleRate, event.mChannelCount,
- AudioFormat.ENCODING_PCM_16BIT);
+ mAudioConfig =
+ new BluetoothAudioConfig(
+ event.mSampleRate,
+ event.mChannelCount,
+ AudioFormat.ENCODING_PCM_16BIT);
break;
}
}
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
index 754ec28817600d5d07322a51abfa1638cff218bf..6cf7d99643ae8c01509cbe787b6c531c0980e63d 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/A2dpSinkStreamHandler.java
@@ -32,20 +32,20 @@ import com.android.bluetooth.avrcpcontroller.AvrcpControllerService;
/**
* Bluetooth A2DP SINK Streaming Handler.
*
- * This handler defines how the stack behaves once the A2DP connection is established and both
+ *
This handler defines how the stack behaves once the A2DP connection is established and both
* devices are ready for streaming. For simplification we assume that the connection can either
* stream music immediately (i.e. data packets coming in or have potential to come in) or it cannot
* stream (i.e. Idle and Open states are treated alike). See Fig 4-1 of GAVDP Spec 1.0.
*
- * Note: There are several different audio tracks that a connected phone may like to transmit over
- * the A2DP stream including Music, Navigation, Assistant, and Notifications. Music is the only
+ *
Note: There are several different audio tracks that a connected phone may like to transmit
+ * over the A2DP stream including Music, Navigation, Assistant, and Notifications. Music is the only
* track that is almost always accompanied with an AVRCP play/pause command.
*
- * Streaming is initiated by either an explicit play command from user interaction or audio coming
- * from the phone. Streaming is terminated when either the user pauses the audio, the audio stream
- * from the phone ends, the phone disconnects, or audio focus is lost. During playback if there is
- * a change to audio focus playback may be temporarily paused and then resumed when focus is
- * restored.
+ *
Streaming is initiated by either an explicit play command from user interaction or audio
+ * coming from the phone. Streaming is terminated when either the user pauses the audio, the audio
+ * stream from the phone ends, the phone disconnects, or audio focus is lost. During playback if
+ * there is a change to audio focus playback may be temporarily paused and then resumed when focus
+ * is restored.
*/
public class A2dpSinkStreamHandler extends Handler {
private static final String TAG = A2dpSinkStreamHandler.class.getSimpleName();
@@ -89,25 +89,25 @@ public class A2dpSinkStreamHandler extends Handler {
private MediaPlayer mMediaPlayer = null;
// Focus changes when we are currently holding focus.
- private OnAudioFocusChangeListener mAudioFocusListener = new OnAudioFocusChangeListener() {
- @Override
- public void onAudioFocusChange(int focusChange) {
- Log.d(TAG, "onAudioFocusChangeListener(focusChange= " + focusChange + ")");
- A2dpSinkStreamHandler.this.obtainMessage(AUDIO_FOCUS_CHANGE, focusChange)
- .sendToTarget();
- }
- };
+ private OnAudioFocusChangeListener mAudioFocusListener =
+ new OnAudioFocusChangeListener() {
+ @Override
+ public void onAudioFocusChange(int focusChange) {
+ Log.d(TAG, "onAudioFocusChangeListener(focusChange= " + focusChange + ")");
+ A2dpSinkStreamHandler.this
+ .obtainMessage(AUDIO_FOCUS_CHANGE, focusChange)
+ .sendToTarget();
+ }
+ };
- public A2dpSinkStreamHandler(A2dpSinkService a2dpSinkService,
- A2dpSinkNativeInterface nativeInterface) {
+ public A2dpSinkStreamHandler(
+ A2dpSinkService a2dpSinkService, A2dpSinkNativeInterface nativeInterface) {
mA2dpSinkService = a2dpSinkService;
mNativeInterface = nativeInterface;
mAudioManager = mA2dpSinkService.getSystemService(AudioManager.class);
}
- /**
- * Safely clean up this stream handler object
- */
+ /** Safely clean up this stream handler object */
public void cleanup() {
abandonAudioFocus();
removeCallbacksAndMessages(null);
@@ -124,7 +124,7 @@ public class A2dpSinkStreamHandler extends Handler {
boolean isPlaying() {
return (mStreamAvailable
&& (mAudioFocus == AudioManager.AUDIOFOCUS_GAIN
- || mAudioFocus == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK));
+ || mAudioFocus == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK));
}
@Override
@@ -177,8 +177,12 @@ public class A2dpSinkStreamHandler extends Handler {
case AUDIO_FOCUS_CHANGE:
final int focusChangeCode = (int) message.obj;
- Log.d(TAG, "New audioFocus = " + focusChangeCode
- + " Previous audio focus = " + mAudioFocus);
+ Log.d(
+ TAG,
+ "New audioFocus = "
+ + focusChangeCode
+ + " Previous audio focus = "
+ + mAudioFocus);
mAudioFocus = focusChangeCode;
// message.obj is the newly granted audio focus.
switch (mAudioFocus) {
@@ -189,8 +193,10 @@ public class A2dpSinkStreamHandler extends Handler {
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
// Make the volume duck.
- int duckPercent = mA2dpSinkService.getResources()
- .getInteger(R.integer.a2dp_sink_duck_percent);
+ int duckPercent =
+ mA2dpSinkService
+ .getResources()
+ .getInteger(R.integer.a2dp_sink_duck_percent);
if (duckPercent < 0 || duckPercent > 100) {
Log.e(TAG, "Invalid duck percent using default.");
duckPercent = DEFAULT_DUCK_PERCENT;
@@ -226,9 +232,7 @@ public class A2dpSinkStreamHandler extends Handler {
}
}
- /**
- * Utility functions.
- */
+ /** Utility functions. */
private void requestAudioFocusIfNone() {
Log.d(TAG, "requestAudioFocusIfNone()");
if (mAudioFocus != AudioManager.AUDIOFOCUS_GAIN) {
@@ -241,21 +245,22 @@ public class A2dpSinkStreamHandler extends Handler {
// Bluetooth A2DP may carry Music, Audio Books, Navigation, or other sounds so mark content
// type unknown.
AudioAttributes streamAttributes =
- new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
+ new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
.build();
// Bluetooth ducking is handled at the native layer at the request of AudioManager.
AudioFocusRequest focusRequest =
- new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN).setAudioAttributes(
- streamAttributes)
+ new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+ .setAudioAttributes(streamAttributes)
.setOnAudioFocusChangeListener(mAudioFocusListener, this)
.build();
int focusRequestStatus = mAudioManager.requestAudioFocus(focusRequest);
// If the request is granted begin streaming immediately and schedule an upgrade.
if (focusRequestStatus == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
mAudioFocus = AudioManager.AUDIOFOCUS_GAIN;
- final Message a2dpSinkStreamHandlerMessage = A2dpSinkStreamHandler.this
- .obtainMessage(AUDIO_FOCUS_CHANGE, mAudioFocus);
+ final Message a2dpSinkStreamHandlerMessage =
+ A2dpSinkStreamHandler.this.obtainMessage(AUDIO_FOCUS_CHANGE, mAudioFocus);
A2dpSinkStreamHandler.this.sendMessageAtFrontOfQueue(a2dpSinkStreamHandlerMessage);
} else {
Log.e(TAG, "Audio focus was not granted:" + focusRequestStatus);
@@ -267,32 +272,36 @@ public class A2dpSinkStreamHandler extends Handler {
* Plays a silent audio sample so that MediaSessionService will be aware of the fact that
* Bluetooth is playing audio.
*
- * Creates a new MediaPlayer if one does not already exist. Repeat calls to this function are
+ *
Creates a new MediaPlayer if one does not already exist. Repeat calls to this function are
* safe and will result in the silent audio sample again.
*
- * This allows the MediaSession in AVRCP Controller to be routed media key events, if we've
+ *
This allows the MediaSession in AVRCP Controller to be routed media key events, if we've
* chosen to use it.
*/
private synchronized void requestMediaKeyFocus() {
Log.d(TAG, "requestMediaKeyFocus()");
if (mMediaPlayer == null) {
- AudioAttributes attrs = new AudioAttributes.Builder()
- .setUsage(AudioAttributes.USAGE_MEDIA)
- .build();
-
- mMediaPlayer = MediaPlayer.create(mA2dpSinkService, R.raw.silent, attrs,
- mAudioManager.generateAudioSessionId());
+ AudioAttributes attrs =
+ new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+ mMediaPlayer =
+ MediaPlayer.create(
+ mA2dpSinkService,
+ R.raw.silent,
+ attrs,
+ mAudioManager.generateAudioSessionId());
if (mMediaPlayer == null) {
Log.e(TAG, "Failed to initialize media player. You may not get media key events");
return;
}
mMediaPlayer.setLooping(false);
- mMediaPlayer.setOnErrorListener((mp, what, extra) -> {
- Log.e(TAG, "Silent media player error: " + what + ", " + extra);
- releaseMediaKeyFocus();
- return false;
- });
+ mMediaPlayer.setOnErrorListener(
+ (mp, what, extra) -> {
+ Log.e(TAG, "Silent media player error: " + what + ", " + extra);
+ releaseMediaKeyFocus();
+ return false;
+ });
}
mMediaPlayer.start();
@@ -306,8 +315,8 @@ public class A2dpSinkStreamHandler extends Handler {
}
/**
- * Destroys the silent audio sample MediaPlayer, notifying MediaSessionService of the fact
- * we're no longer playing audio.
+ * Destroys the silent audio sample MediaPlayer, notifying MediaSessionService of the fact we're
+ * no longer playing audio.
*/
private synchronized void releaseMediaKeyFocus() {
Log.d(TAG, "releaseMediaKeyFocus()");
@@ -335,17 +344,20 @@ public class A2dpSinkStreamHandler extends Handler {
}
private boolean isIotDevice() {
- return mA2dpSinkService.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_EMBEDDED);
+ return mA2dpSinkService
+ .getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_EMBEDDED);
}
private boolean isTvDevice() {
- return mA2dpSinkService.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LEANBACK);
+ return mA2dpSinkService
+ .getPackageManager()
+ .hasSystemFeature(PackageManager.FEATURE_LEANBACK);
}
private boolean shouldRequestFocus() {
- return mA2dpSinkService.getResources()
+ return mA2dpSinkService
+ .getResources()
.getBoolean(R.bool.a2dp_sink_automatically_request_audio_focus);
}
}
diff --git a/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java b/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java
index 5d0947f03e1dcb531d0380bb1bac11cc6f0e572f..93ade754394f1b2ecb59b9bc4e7cb29817df8f8f 100644
--- a/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java
+++ b/android/app/src/com/android/bluetooth/a2dpsink/StackEvent.java
@@ -56,8 +56,11 @@ final class StackEvent {
s += "EVENT_TYPE_AUDIO_STATE_CHANGED, state=" + mState;
break;
case EVENT_TYPE_AUDIO_CONFIG_CHANGED:
- s += "EVENT_TYPE_AUDIO_CONFIG_CHANGED, sampleRate=" + mSampleRate
- + ", channelCount=" + mChannelCount;
+ s +=
+ "EVENT_TYPE_AUDIO_CONFIG_CHANGED, sampleRate="
+ + mSampleRate
+ + ", channelCount="
+ + mChannelCount;
break;
default:
s += "Unknown";
@@ -81,8 +84,7 @@ final class StackEvent {
return event;
}
- static StackEvent audioConfigChanged(BluetoothDevice device, int sampleRate,
- int channelCount) {
+ static StackEvent audioConfigChanged(BluetoothDevice device, int sampleRate, int channelCount) {
StackEvent event = new StackEvent(StackEvent.EVENT_TYPE_AUDIO_CONFIG_CHANGED);
event.mDevice = device;
event.mSampleRate = sampleRate;
diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
index 4e113433b75ae8e2555c4abda124feac366850c4..6386a0ce89f670773fdfa063df62d0660dc86b99 100644
--- a/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
+++ b/android/app/src/com/android/bluetooth/audio_util/BrowsablePlayerConnector.java
@@ -32,14 +32,13 @@ import java.util.List;
import java.util.Set;
/**
- * This class provides a way to connect to multiple browsable players at a time.
- * It will attempt to simultaneously connect to a list of services that support
- * the MediaBrowserService. After a timeout, the list of connected players will
- * be returned via callback.
+ * This class provides a way to connect to multiple browsable players at a time. It will attempt to
+ * simultaneously connect to a list of services that support the MediaBrowserService. After a
+ * timeout, the list of connected players will be returned via callback.
*
- * The main use of this class is to check whether a player can be browsed despite
- * using the MediaBrowserService. This way we do not have to do the same checks
- * when constructing BrowsedPlayerWrappers by hand.
+ *
The main use of this class is to check whether a player can be browsed despite using the
+ * MediaBrowserService. This way we do not have to do the same checks when constructing
+ * BrowsedPlayerWrappers by hand.
*/
public class BrowsablePlayerConnector extends Handler {
private static final String TAG = "AvrcpBrowsablePlayerConnector";
@@ -66,10 +65,7 @@ public class BrowsablePlayerConnector extends Handler {
}
static BrowsablePlayerConnector connectToPlayers(
- Context context,
- Looper looper,
- List players,
- PlayerListCallback cb) {
+ Context context, Looper looper, List players, PlayerListCallback cb) {
if (sInjectConnector != null) {
return sInjectConnector;
}
@@ -82,19 +78,23 @@ public class BrowsablePlayerConnector extends Handler {
// Try to start connecting all the browsed player wrappers
for (ResolveInfo info : players) {
- BrowsedPlayerWrapper player = BrowsedPlayerWrapper.wrap(
- context,
- looper,
- info.serviceInfo.packageName,
- info.serviceInfo.name);
+ BrowsedPlayerWrapper player =
+ BrowsedPlayerWrapper.wrap(
+ context, looper, info.serviceInfo.packageName, info.serviceInfo.name);
newConnector.mPendingPlayers.add(player);
- player.connect((int status, BrowsedPlayerWrapper wrapper) -> {
- // Use the handler to avoid concurrency issues
- Log.d(TAG, "Browse player callback called: package="
- + info.serviceInfo.packageName
- + " : status=" + status);
- newConnector.obtainMessage(MSG_CONNECT_CB, status, 0, wrapper).sendToTarget();
- });
+ player.connect(
+ (int status, BrowsedPlayerWrapper wrapper) -> {
+ // Use the handler to avoid concurrency issues
+ Log.d(
+ TAG,
+ "Browse player callback called: package="
+ + info.serviceInfo.packageName
+ + " : status="
+ + status);
+ newConnector
+ .obtainMessage(MSG_CONNECT_CB, status, 0, wrapper)
+ .sendToTarget();
+ });
}
newConnector.sendEmptyMessageDelayed(MSG_TIMEOUT, CONNECT_TIMEOUT_MS);
@@ -125,62 +125,71 @@ public class BrowsablePlayerConnector extends Handler {
@Override
public void handleMessage(Message msg) {
Log.d(TAG, "Received a message: msg.what=" + msg.what);
- switch(msg.what) {
- case MSG_GET_FOLDER_ITEMS_CB: {
- int status = msg.arg1;
- int results_size = msg.arg2;
- BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj;
-
- // If we failed to remove the wrapper from the pending set, that
- // means a timeout occurred and the callback was triggered afterwards
- // or the connector was cleaned up.
- if (!mPendingPlayers.remove(wrapper)) {
- return;
- }
-
- if (status == BrowsedPlayerWrapper.STATUS_SUCCESS && results_size != 0) {
- Log.i(TAG, "Successfully added package to results: "
- + wrapper.getPackageName());
- mResults.add(wrapper);
- }
- break;
- }
-
- case MSG_CONNECT_CB: {
- BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj;
+ switch (msg.what) {
+ case MSG_GET_FOLDER_ITEMS_CB:
+ {
+ int status = msg.arg1;
+ int results_size = msg.arg2;
+ BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj;
- if (msg.arg1 != BrowsedPlayerWrapper.STATUS_SUCCESS) {
- Log.i(TAG, wrapper.getPackageName() + " is not browsable");
// If we failed to remove the wrapper from the pending set, that
// means a timeout occurred and the callback was triggered afterwards
+ // or the connector was cleaned up.
if (!mPendingPlayers.remove(wrapper)) {
return;
}
+
+ if (status == BrowsedPlayerWrapper.STATUS_SUCCESS && results_size != 0) {
+ Log.i(
+ TAG,
+ "Successfully added package to results: "
+ + wrapper.getPackageName());
+ mResults.add(wrapper);
+ }
break;
}
- // Check to see if the root folder has any items
- Log.i(TAG, "Checking root contents for " + wrapper.getPackageName());
- wrapper.getFolderItems(wrapper.getRootId(),
- (int status, String mediaId, List results) -> {
- // Send the response as a message so that it is properly
- // synchronized
- obtainMessage(MSG_GET_FOLDER_ITEMS_CB, status, results.size(), wrapper)
- .sendToTarget();
- });
- break;
- }
-
- case MSG_TIMEOUT: {
- Log.v(TAG, "Timed out waiting for players");
- removePendingPlayers();
- break;
- }
+ case MSG_CONNECT_CB:
+ {
+ BrowsedPlayerWrapper wrapper = (BrowsedPlayerWrapper) msg.obj;
+
+ if (msg.arg1 != BrowsedPlayerWrapper.STATUS_SUCCESS) {
+ Log.i(TAG, wrapper.getPackageName() + " is not browsable");
+ // If we failed to remove the wrapper from the pending set, that
+ // means a timeout occurred and the callback was triggered afterwards
+ if (!mPendingPlayers.remove(wrapper)) {
+ return;
+ }
+ break;
+ }
+
+ // Check to see if the root folder has any items
+ Log.i(TAG, "Checking root contents for " + wrapper.getPackageName());
+ wrapper.getFolderItems(
+ wrapper.getRootId(),
+ (int status, String mediaId, List results) -> {
+ // Send the response as a message so that it is properly
+ // synchronized
+ obtainMessage(
+ MSG_GET_FOLDER_ITEMS_CB,
+ status,
+ results.size(),
+ wrapper)
+ .sendToTarget();
+ });
+ break;
+ }
+
+ case MSG_TIMEOUT:
+ {
+ Log.v(TAG, "Timed out waiting for players");
+ removePendingPlayers();
+ break;
+ }
}
if (mPendingPlayers.size() == 0) {
- Log.i(TAG, "Successfully connected to "
- + mResults.size() + " browsable players.");
+ Log.i(TAG, "Successfully connected to " + mResults.size() + " browsable players.");
removeMessages(MSG_TIMEOUT);
mCallback.run(mResults);
}
diff --git a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
index 19c6f89e51fbd7f28536d322b05bfebbce68cf0b..2bd3c66aa264bb57ba652546bc88ca2f5fc3e7e7 100644
--- a/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/BrowsedPlayerWrapper.java
@@ -102,20 +102,21 @@ class BrowsedPlayerWrapper {
// TODO (apanicke): Investigate if there is a way to create this just by passing in the
// MediaBrowser. Right now there is no obvious way to create the browser then update the
// connection callback without being forced to re-create the object every time.
- private BrowsedPlayerWrapper(Context context, Looper looper, String packageName,
- String className) {
+ private BrowsedPlayerWrapper(
+ Context context, Looper looper, String packageName, String className) {
mContext = context;
mPackageName = packageName;
mLooper = looper;
- mWrappedBrowser = MediaBrowserFactory.make(
- context,
- new ComponentName(packageName, className),
- new MediaConnectionCallback(),
- null);
+ mWrappedBrowser =
+ MediaBrowserFactory.make(
+ context,
+ new ComponentName(packageName, className),
+ new MediaConnectionCallback(),
+ null);
}
- static BrowsedPlayerWrapper wrap(Context context, Looper looper, String packageName,
- String className) {
+ static BrowsedPlayerWrapper wrap(
+ Context context, Looper looper, String packageName, String className) {
Log.i(TAG, "Wrapping Media Browser " + packageName);
BrowsedPlayerWrapper wrapper =
new BrowsedPlayerWrapper(context, looper, packageName, className);
@@ -125,7 +126,7 @@ class BrowsedPlayerWrapper {
/**
* Connect to the media application's MediaBrowserService
*
- * Connections are asynchronous in nature. The given callback will be invoked once the
+ * Connections are asynchronous in nature. The given callback will be invoked once the
* connection is established. The connection will be torn down once your callback is executed
* when using this function. If you wish to control the lifecycle of the connection on your own
* then use {@link #setCallbackAndConnect(ConnectionCallback)} instead.
@@ -135,19 +136,19 @@ class BrowsedPlayerWrapper {
*/
boolean connect(ConnectionCallback cb) {
if (cb == null) {
- Log.wtf(TAG, "connect: Trying to connect to " + mPackageName
- + "with null callback");
+ Log.wtf(TAG, "connect: Trying to connect to " + mPackageName + "with null callback");
}
- return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> {
- cb.run(status, wrapper);
- disconnect();
- });
+ return setCallbackAndConnect(
+ (int status, BrowsedPlayerWrapper wrapper) -> {
+ cb.run(status, wrapper);
+ disconnect();
+ });
}
/**
* Disconnect from the media application's MediaBrowserService
*
- * This clears any pending requests. This function is safe to call even if a connection isn't
+ *
This clears any pending requests. This function is safe to call even if a connection isn't
* currently open.
*/
void disconnect() {
@@ -205,26 +206,32 @@ class BrowsedPlayerWrapper {
*/
public boolean playItem(String mediaId) {
Log.d(TAG, "playItem: Play item from media ID: " + mediaId);
- return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> {
- Log.d(TAG, "playItem: Connected to browsable player " + mPackageName);
- MediaController controller = MediaControllerFactory.make(mContext,
- wrapper.mWrappedBrowser.getSessionToken());
- MediaController.TransportControls ctrl = controller.getTransportControls();
- Log.i(TAG, "playItem: Playing " + mediaId);
- ctrl.playFromMediaId(mediaId, null);
-
- MediaPlaybackListener mpl = new MediaPlaybackListener(mLooper, controller);
- mpl.waitForPlayback((int playbackStatus) -> {
- Log.i(TAG, "playItem: Media item playback returned, status: " + playbackStatus);
- disconnect();
- });
- });
+ return setCallbackAndConnect(
+ (int status, BrowsedPlayerWrapper wrapper) -> {
+ Log.d(TAG, "playItem: Connected to browsable player " + mPackageName);
+ MediaController controller =
+ MediaControllerFactory.make(
+ mContext, wrapper.mWrappedBrowser.getSessionToken());
+ MediaController.TransportControls ctrl = controller.getTransportControls();
+ Log.i(TAG, "playItem: Playing " + mediaId);
+ ctrl.playFromMediaId(mediaId, null);
+
+ MediaPlaybackListener mpl = new MediaPlaybackListener(mLooper, controller);
+ mpl.waitForPlayback(
+ (int playbackStatus) -> {
+ Log.i(
+ TAG,
+ "playItem: Media item playback returned, status: "
+ + playbackStatus);
+ disconnect();
+ });
+ });
}
/**
* Request the contents of a folder item identified by the given media ID
*
- * Contents must be loaded from a service and are returned asynchronously.
+ *
Contents must be loaded from a service and are returned asynchronously.
*
* @param mediaId A string indicating the piece of media you would like to play
* @param cb A Callback that returns the loaded contents of the requested media ID
@@ -244,18 +251,22 @@ class BrowsedPlayerWrapper {
}
if (cb == null) {
- Log.wtf(TAG, "getFolderItems: Trying to connect to " + mPackageName
- + "with null browse callback");
+ Log.wtf(
+ TAG,
+ "getFolderItems: Trying to connect to "
+ + mPackageName
+ + "with null browse callback");
}
Log.d(TAG, "getFolderItems: Connecting to browsable player: " + mPackageName);
- return setCallbackAndConnect((int status, BrowsedPlayerWrapper wrapper) -> {
- Log.i(TAG, "getFolderItems: Connected to browsable player: " + mPackageName);
- if (status != STATUS_SUCCESS) {
- cb.run(status, "", new ArrayList());
- }
- getFolderItemsInternal(mediaId, cb);
- });
+ return setCallbackAndConnect(
+ (int status, BrowsedPlayerWrapper wrapper) -> {
+ Log.i(TAG, "getFolderItems: Connected to browsable player: " + mPackageName);
+ if (status != STATUS_SUCCESS) {
+ cb.run(status, "", new ArrayList());
+ }
+ getFolderItemsInternal(mediaId, cb);
+ });
}
// Internal function to call once the Browser is connected
@@ -279,7 +290,6 @@ class BrowsedPlayerWrapper {
executeCallback(STATUS_SUCCESS, BrowsedPlayerWrapper.this);
}
-
@Override
public void onConnectionFailed() {
Log.w(TAG, "onConnectionFailed: Connection Failed with " + mPackageName);
@@ -362,8 +372,8 @@ class BrowsedPlayerWrapper {
Log.d(TAG, "MediaPlayback: Waiting for media to play for " + mPackageName);
mTimeoutHandler = new TimeoutHandler(mLooper, mPlaybackCallback);
mController.registerCallback(this, mTimeoutHandler);
- mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT,
- TimeoutHandler.CALLBACK_TIMEOUT_MS);
+ mTimeoutHandler.sendEmptyMessageDelayed(
+ TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.CALLBACK_TIMEOUT_MS);
} else {
Log.d(TAG, "MediaPlayback: Media is already playing for " + mPackageName);
mPlaybackCallback.run(STATUS_SUCCESS);
@@ -412,8 +422,8 @@ class BrowsedPlayerWrapper {
mBrowseCallback = cb;
mLooper = looper;
mTimeoutHandler = new TimeoutHandler(mLooper, cb, mediaId);
- mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT,
- TimeoutHandler.SUBSCRIPTION_TIMEOUT_MS);
+ mTimeoutHandler.sendEmptyMessageDelayed(
+ TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.SUBSCRIPTION_TIMEOUT_MS);
}
@Override
@@ -426,8 +436,11 @@ class BrowsedPlayerWrapper {
Log.d(TAG, "onChildrenLoaded: mediaId=" + parentId + " size= " + children.size());
if (mBrowseCallback == null) {
- Log.w(TAG, "onChildrenLoaded: " + mPackageName
- + " children loaded while callback is null");
+ Log.w(
+ TAG,
+ "onChildrenLoaded: "
+ + mPackageName
+ + " children loaded while callback is null");
}
// TODO (apanicke): Instead of always unsubscribing, only unsubscribe from folders
@@ -438,8 +451,13 @@ class BrowsedPlayerWrapper {
ArrayList return_list = new ArrayList();
for (MediaItem item : children) {
- Log.d(TAG, "onChildrenLoaded: Child=\"" + item.toString()
- + "\", ID=\"" + item.getMediaId() + "\"");
+ Log.d(
+ TAG,
+ "onChildrenLoaded: Child=\""
+ + item.toString()
+ + "\", ID=\""
+ + item.getMediaId()
+ + "\"");
if (item.isBrowsable()) {
CharSequence titleCharSequence = item.getDescription().getTitle();
diff --git a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
index efb58f56e64c6c24f848f130894b6c4980584fc7..33c680e7df1530f762bce6d30ce248ebaf962479 100644
--- a/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/GPMWrapper.java
@@ -23,8 +23,8 @@ import android.util.Log;
/**
* Google Play Music hides some of the metadata behind a specific key in the Extras of the
- * MediaDescription in the MediaSession.QueueItem. This class exists to provide alternate
- * methods to allow Google Play Music to match the default behaviour of MediaPlayerWrapper.
+ * MediaDescription in the MediaSession.QueueItem. This class exists to provide alternate methods to
+ * allow Google Play Music to match the default behaviour of MediaPlayerWrapper.
*/
class GPMWrapper extends MediaPlayerWrapper {
private static final String TAG = "AvrcpGPMWrapper";
diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
index 8eacb6782588a204e30dac102620b5f0b5a23763..7b6b6bbd29db06a1e37f3c1e688e265ed06ebe9d 100644
--- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
+++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerList.java
@@ -52,16 +52,16 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * This class is directly responsible of maintaining the list of Browsable Players as well as
- * the list of Addressable Players. This variation of the list doesn't actually list all the
- * available players for a getAvailableMediaPlayers request. Instead it only reports one media
- * player with ID=0 and all the other browsable players are folders in the root of that player.
+ * This class is directly responsible of maintaining the list of Browsable Players as well as the
+ * list of Addressable Players. This variation of the list doesn't actually list all the available
+ * players for a getAvailableMediaPlayers request. Instead it only reports one media player with
+ * ID=0 and all the other browsable players are folders in the root of that player.
*
- * Changing the directory to a browsable player will allow you to traverse that player as normal.
+ * Changing the directory to a browsable player will allow you to traverse that player as normal.
* By only having one root player, we never have to send Addressed Player Changed notifications,
* UIDs Changed notifications, or Available Players Changed notifications.
*
- * TODO (apanicke): Add non-browsable players as song items to the root folder. Selecting that
+ *
TODO (apanicke): Add non-browsable players as song items to the root folder. Selecting that
* player would effectively cause player switch by sending a play command to that player.
*/
public class MediaPlayerList {
@@ -116,6 +116,7 @@ public class MediaPlayerList {
public interface MediaUpdateCallback {
void run(MediaData data);
+
void run(boolean availablePlayers, boolean addressedPlayers, boolean uids);
}
@@ -127,13 +128,9 @@ public class MediaPlayerList {
void run(String parentId, List items);
}
- /**
- * Listener for PlayerSettingsManager.
- */
+ /** Listener for PlayerSettingsManager. */
public interface MediaPlayerSettingsEventListener {
- /**
- * Called when the active player has changed.
- */
+ /** Called when the active player has changed. */
void onActivePlayerChanged(MediaPlayerWrapper player);
}
@@ -224,40 +221,52 @@ public class MediaPlayerList {
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
}
List playerList =
- mContext
- .getApplicationContext()
- .getPackageManager()
- .queryIntentServices(intent, PackageManager.MATCH_ALL);
-
- mBrowsablePlayerConnector = BrowsablePlayerConnector.connectToPlayers(mContext, mLooper,
- playerList, (List players) -> {
- Log.i(TAG, "init: Browsable Player list size is " + players.size());
-
- // Check to see if the list has been cleaned up before this completed
- if (mMediaSessionManager == null) {
- return;
- }
-
- for (BrowsedPlayerWrapper wrapper : players) {
- // Generate new id and add the browsable player
- if (!havePlayerId(wrapper.getPackageName())) {
- mMediaPlayerIds.put(wrapper.getPackageName(), getFreeMediaPlayerId());
- }
-
- d("Adding Browser Wrapper for " + wrapper.getPackageName() + " with id "
- + mMediaPlayerIds.get(wrapper.getPackageName()));
-
- mBrowsablePlayers.put(mMediaPlayerIds.get(wrapper.getPackageName()), wrapper);
-
- wrapper.getFolderItems(wrapper.getRootId(),
- (int status, String mediaId, List results) -> {
- d("Got the contents for: " + mediaId + " : num results="
- + results.size());
- });
- }
-
- constructCurrentPlayers();
- });
+ mContext.getApplicationContext()
+ .getPackageManager()
+ .queryIntentServices(intent, PackageManager.MATCH_ALL);
+
+ mBrowsablePlayerConnector =
+ BrowsablePlayerConnector.connectToPlayers(
+ mContext,
+ mLooper,
+ playerList,
+ (List players) -> {
+ Log.i(TAG, "init: Browsable Player list size is " + players.size());
+
+ // Check to see if the list has been cleaned up before this completed
+ if (mMediaSessionManager == null) {
+ return;
+ }
+
+ for (BrowsedPlayerWrapper wrapper : players) {
+ // Generate new id and add the browsable player
+ if (!havePlayerId(wrapper.getPackageName())) {
+ mMediaPlayerIds.put(
+ wrapper.getPackageName(), getFreeMediaPlayerId());
+ }
+
+ d(
+ "Adding Browser Wrapper for "
+ + wrapper.getPackageName()
+ + " with id "
+ + mMediaPlayerIds.get(wrapper.getPackageName()));
+
+ mBrowsablePlayers.put(
+ mMediaPlayerIds.get(wrapper.getPackageName()), wrapper);
+
+ wrapper.getFolderItems(
+ wrapper.getRootId(),
+ (int status, String mediaId, List results) -> {
+ d(
+ "Got the contents for: "
+ + mediaId
+ + " : num results="
+ + results.size());
+ });
+ }
+
+ constructCurrentPlayers();
+ });
}
public void cleanup() {
@@ -340,16 +349,20 @@ public class MediaPlayerList {
BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(BLUETOOTH_PLAYER_ID + 1);
String itemId = wrapper.getRootId();
- wrapper.getFolderItems(itemId, (status, id, results) -> {
- if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
- cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0);
- return;
- }
- cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size());
- });
+ wrapper.getFolderItems(
+ itemId,
+ (status, id, results) -> {
+ if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
+ cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", 0);
+ return;
+ }
+ cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", results.size());
+ });
return;
}
- /** @} */
+ /**
+ * @}
+ */
cb.run(playerId, playerId == BLUETOOTH_PLAYER_ID, "", mBrowsablePlayers.size());
}
@@ -392,8 +405,10 @@ public class MediaPlayerList {
if (state == null
|| state.getActiveQueueItemId() == MediaSession.QueueItem.UNKNOWN_ID
|| queue.size() == 0) {
- d("getCurrentMediaId: No active queue item Id sending empty mediaId: PlaybackState="
- + state);
+ d(
+ "getCurrentMediaId: No active queue item Id sending empty mediaId:"
+ + " PlaybackState="
+ + state);
return "";
}
@@ -427,10 +442,11 @@ public class MediaPlayerList {
if (mAudioPlaybackIsActive
&& (state == null || state.getState() != PlaybackState.STATE_PLAYING)) {
return new PlaybackState.Builder()
- .setState(PlaybackState.STATE_PLAYING,
- state == null ? 0 : state.getPosition(),
- 1.0f)
- .build();
+ .setState(
+ PlaybackState.STATE_PLAYING,
+ state == null ? 0 : state.getPosition(),
+ 1.0f)
+ .build();
}
return state;
}
@@ -484,8 +500,9 @@ public class MediaPlayerList {
Matcher m = regex.matcher(mediaId);
if (!m.find()) {
// This should never happen since we control the media ID's reported
- Log.wtf(TAG, "playNowPlayingItem: Couldn't match mediaId to pattern: mediaId="
- + mediaId);
+ Log.wtf(
+ TAG,
+ "playNowPlayingItem: Couldn't match mediaId to pattern: mediaId=" + mediaId);
}
long queueItemId = Long.parseLong(m.group(1));
@@ -521,8 +538,10 @@ public class MediaPlayerList {
e("playFolderItem: Failed to start playback with an empty media id.");
return;
}
- Log.i(TAG, "playFolderItem: Empty media id, trying with the root id for "
- + wrapper.getPackageName());
+ Log.i(
+ TAG,
+ "playFolderItem: Empty media id, trying with the root id for "
+ + wrapper.getPackageName());
}
wrapper.playItem(itemId);
}
@@ -574,16 +593,20 @@ public class MediaPlayerList {
itemId = wrapper.getRootId();
}
- wrapper.getFolderItems(itemId, (status, id, results) -> {
- if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
- cb.run(mediaId, new ArrayList());
- return;
- }
- cb.run(mediaId, results);
- });
+ wrapper.getFolderItems(
+ itemId,
+ (status, id, results) -> {
+ if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
+ cb.run(mediaId, new ArrayList());
+ return;
+ }
+ cb.run(mediaId, results);
+ });
return;
}
- /** @} */
+ /**
+ * @}
+ */
// The device is requesting the content of the root folder. This folder contains a list of
// Browsable Media Players displayed as folders with their contents contained within.
@@ -605,27 +628,28 @@ public class MediaPlayerList {
if (haveMediaBrowser(playerIndex)) {
BrowsedPlayerWrapper wrapper = mBrowsablePlayers.get(playerIndex);
if (itemId.equals("")) {
- Log.i(TAG, "Empty media id, getting the root for "
- + wrapper.getPackageName());
+ Log.i(TAG, "Empty media id, getting the root for " + wrapper.getPackageName());
itemId = wrapper.getRootId();
}
- wrapper.getFolderItems(itemId, (status, id, results) -> {
- if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
- cb.run(mediaId, new ArrayList());
- return;
- }
+ wrapper.getFolderItems(
+ itemId,
+ (status, id, results) -> {
+ if (status != BrowsedPlayerWrapper.STATUS_SUCCESS) {
+ cb.run(mediaId, new ArrayList());
+ return;
+ }
- String playerPrefix = String.format("%02d", playerIndex);
- for (ListItem item : results) {
- if (item.isFolder) {
- item.folder.mediaId = playerPrefix.concat(item.folder.mediaId);
- } else {
- item.song.mediaId = playerPrefix.concat(item.song.mediaId);
- }
- }
- cb.run(mediaId, results);
- });
+ String playerPrefix = String.format("%02d", playerIndex);
+ for (ListItem item : results) {
+ if (item.isFolder) {
+ item.folder.mediaId = playerPrefix.concat(item.folder.mediaId);
+ } else {
+ item.song.mediaId = playerPrefix.concat(item.song.mediaId);
+ }
+ }
+ cb.run(mediaId, results);
+ });
return;
} else {
cb.run(mediaId, new ArrayList());
@@ -669,13 +693,15 @@ public class MediaPlayerList {
return playerId;
}
- MediaPlayerWrapper newPlayer = MediaPlayerWrapperFactory.wrap(
- mContext,
- controller,
- mLooper);
+ MediaPlayerWrapper newPlayer =
+ MediaPlayerWrapperFactory.wrap(mContext, controller, mLooper);
- Log.i(TAG, "Adding wrapped media player: " + packageName + " at key: "
- + mMediaPlayerIds.get(controller.getPackageName()));
+ Log.i(
+ TAG,
+ "Adding wrapped media player: "
+ + packageName
+ + " at key: "
+ + mMediaPlayerIds.get(controller.getPackageName()));
mMediaPlayers.put(playerId, newPlayer);
return playerId;
@@ -745,11 +771,7 @@ public class MediaPlayerList {
mActivePlayerId = NO_ACTIVE_PLAYER;
List queue = new ArrayList();
queue.add(Util.empty_data());
- MediaData newData = new MediaData(
- Util.empty_data(),
- null,
- queue
- );
+ MediaData newData = new MediaData(Util.empty_data(), null, queue);
sendMediaUpdate(newData);
}
@@ -785,8 +807,8 @@ public class MediaPlayerList {
mActivePlayerId = playerId;
getActivePlayer().registerCallback(mMediaPlayerCallback);
- mActivePlayerLogger.logd(TAG, "setActivePlayer(): setting player to "
- + getActivePlayer().getPackageName());
+ mActivePlayerLogger.logd(
+ TAG, "setActivePlayer(): setting player to " + getActivePlayer().getPackageName());
if (mPlayerSettingsListener != null) {
mPlayerSettingsListener.onActivePlayerChanged(getActivePlayer());
@@ -811,8 +833,8 @@ public class MediaPlayerList {
}
/** Informs AVRCP service that there has been an update in browsable players. */
- private void sendFolderUpdate(boolean availablePlayers, boolean addressedPlayers,
- boolean uids) {
+ private void sendFolderUpdate(
+ boolean availablePlayers, boolean addressedPlayers, boolean uids) {
d("sendFolderUpdate");
if (mCallback == null) {
return;
@@ -853,49 +875,55 @@ public class MediaPlayerList {
* See {@link #onMediaKeyEventSessionChanged}.
*/
@VisibleForTesting
- final MediaSessionManager.OnActiveSessionsChangedListener
- mActiveSessionsChangedListener =
+ final MediaSessionManager.OnActiveSessionsChangedListener mActiveSessionsChangedListener =
new MediaSessionManager.OnActiveSessionsChangedListener() {
- @Override
- public void onActiveSessionsChanged(
- List newControllers) {
- synchronized (MediaPlayerList.this) {
- Log.v(TAG, "onActiveSessionsChanged: number of controllers: "
- + newControllers.size());
- if (newControllers.size() == 0) {
- if (mPlayerSettingsListener != null) {
- mPlayerSettingsListener.onActivePlayerChanged(null);
- }
- return;
- }
+ @Override
+ public void onActiveSessionsChanged(
+ List newControllers) {
+ synchronized (MediaPlayerList.this) {
+ Log.v(
+ TAG,
+ "onActiveSessionsChanged: number of controllers: "
+ + newControllers.size());
+ if (newControllers.size() == 0) {
+ if (mPlayerSettingsListener != null) {
+ mPlayerSettingsListener.onActivePlayerChanged(null);
+ }
+ return;
+ }
- // Apps are allowed to have multiple MediaControllers. If an app does have
- // multiple controllers then newControllers contains them in highest
- // priority order. Since we only want to keep the highest priority one,
- // we keep track of which controllers we updated and skip over ones
- // we've already looked at.
- HashSet addedPackages = new HashSet();
-
- for (int i = 0; i < newControllers.size(); i++) {
- if ((newControllers.get(i).getFlags()
- & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY) != 0) {
- Log.d(TAG, "onActiveSessionsChanged: controller: "
- + newControllers.get(i).getPackageName()
- + " ignored due to global priority flag");
- continue;
- }
- Log.d(TAG, "onActiveSessionsChanged: controller: "
- + newControllers.get(i).getPackageName());
- if (addedPackages.contains(newControllers.get(i).getPackageName())) {
- continue;
+ // Apps are allowed to have multiple MediaControllers. If an app does have
+ // multiple controllers then newControllers contains them in highest
+ // priority order. Since we only want to keep the highest priority one,
+ // we keep track of which controllers we updated and skip over ones
+ // we've already looked at.
+ HashSet addedPackages = new HashSet();
+
+ for (int i = 0; i < newControllers.size(); i++) {
+ if ((newControllers.get(i).getFlags()
+ & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)
+ != 0) {
+ Log.d(
+ TAG,
+ "onActiveSessionsChanged: controller: "
+ + newControllers.get(i).getPackageName()
+ + " ignored due to global priority flag");
+ continue;
+ }
+ Log.d(
+ TAG,
+ "onActiveSessionsChanged: controller: "
+ + newControllers.get(i).getPackageName());
+ if (addedPackages.contains(newControllers.get(i).getPackageName())) {
+ continue;
+ }
+
+ addedPackages.add(newControllers.get(i).getPackageName());
+ addMediaPlayer(newControllers.get(i));
+ }
}
-
- addedPackages.add(newControllers.get(i).getPackageName());
- addMediaPlayer(newControllers.get(i));
}
- }
- }
- };
+ };
/**
* {@link android.content.BroadcastReceiver} to catch intents indicating package add, change and
@@ -910,32 +938,33 @@ public class MediaPlayerList {
* See {@link #removeMediaPlayer} and {@link
* #addMediaPlayer(android.media.session.MediaController)}
*/
- private final BroadcastReceiver mPackageChangedBroadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- Log.v(TAG, "mPackageChangedBroadcastReceiver: action: " + action);
-
- if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
- || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) {
- if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) return;
-
- String packageName = intent.getData().getSchemeSpecificPart();
- if (haveMediaPlayer(packageName)) {
- removeMediaPlayer(mMediaPlayerIds.get(packageName));
- }
- } else if (action.equals(Intent.ACTION_PACKAGE_ADDED)
- || action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
- String packageName = intent.getData().getSchemeSpecificPart();
- if (packageName != null) {
- Log.d(TAG, "Name of package changed: " + packageName);
- // TODO (apanicke): Handle either updating or adding the new package.
- // Check if its browsable and send the UIDS changed to update the
- // root folder
+ private final BroadcastReceiver mPackageChangedBroadcastReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ Log.v(TAG, "mPackageChangedBroadcastReceiver: action: " + action);
+
+ if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ || action.equals(Intent.ACTION_PACKAGE_DATA_CLEARED)) {
+ if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) return;
+
+ String packageName = intent.getData().getSchemeSpecificPart();
+ if (haveMediaPlayer(packageName)) {
+ removeMediaPlayer(mMediaPlayerIds.get(packageName));
+ }
+ } else if (action.equals(Intent.ACTION_PACKAGE_ADDED)
+ || action.equals(Intent.ACTION_PACKAGE_CHANGED)) {
+ String packageName = intent.getData().getSchemeSpecificPart();
+ if (packageName != null) {
+ Log.d(TAG, "Name of package changed: " + packageName);
+ // TODO (apanicke): Handle either updating or adding the new package.
+ // Check if its browsable and send the UIDS changed to update the
+ // root folder
+ }
+ }
}
- }
- }
- };
+ };
/**
* Retrieves and sends the current {@link MediaData} of the active player (if present) to the
@@ -948,35 +977,32 @@ public class MediaPlayerList {
PlaybackState currState = null;
if (getActivePlayer() == null) {
Log.d(TAG, "updateMediaForAudioPlayback: no active player");
- PlaybackState.Builder builder = new PlaybackState.Builder()
- .setState(PlaybackState.STATE_STOPPED, 0L, 0f);
+ PlaybackState.Builder builder =
+ new PlaybackState.Builder().setState(PlaybackState.STATE_STOPPED, 0L, 0f);
List queue = new ArrayList();
queue.add(Util.empty_data());
- currMediaData = new MediaData(
- Util.empty_data(),
- builder.build(),
- queue
- );
+ currMediaData = new MediaData(Util.empty_data(), builder.build(), queue);
} else {
currMediaData = getActivePlayer().getCurrentMediaData();
currState = currMediaData.state;
}
- if (currState != null
- && currState.getState() == PlaybackState.STATE_PLAYING) {
+ if (currState != null && currState.getState() == PlaybackState.STATE_PLAYING) {
Log.i(TAG, "updateMediaForAudioPlayback: Active player is playing, drop it");
return;
}
if (mAudioPlaybackIsActive) {
- PlaybackState.Builder builder = new PlaybackState.Builder()
- .setState(PlaybackState.STATE_PLAYING,
- currState == null ? 0 : currState.getPosition(),
- 1.0f);
+ PlaybackState.Builder builder =
+ new PlaybackState.Builder()
+ .setState(
+ PlaybackState.STATE_PLAYING,
+ currState == null ? 0 : currState.getPosition(),
+ 1.0f);
currMediaData.state = builder.build();
}
- mAudioPlaybackStateLogger.logd(TAG, "updateMediaForAudioPlayback: update state="
- + currMediaData.state);
+ mAudioPlaybackStateLogger.logd(
+ TAG, "updateMediaForAudioPlayback: update state=" + currMediaData.state);
sendMediaUpdate(currMediaData);
}
@@ -1000,35 +1026,40 @@ public class MediaPlayerList {
*/
private final AudioManager.AudioPlaybackCallback mAudioPlaybackCallback =
new AudioManager.AudioPlaybackCallback() {
- @Override
- public void onPlaybackConfigChanged(List configs) {
- if (configs == null) {
- return;
- }
- boolean isActive = false;
- AudioPlaybackConfiguration activeConfig = null;
- for (AudioPlaybackConfiguration config : configs) {
- if (config.isActive() && (config.getAudioAttributes().getUsage()
- == AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
- && (config.getAudioAttributes().getContentType()
- == AudioAttributes.CONTENT_TYPE_SPEECH)) {
- activeConfig = config;
- isActive = true;
- }
- }
- if (isActive != mAudioPlaybackIsActive) {
- mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: "
- + (mAudioPlaybackIsActive ? "Active" : "Non-active") + " -> "
- + (isActive ? "Active" : "Non-active"));
- if (isActive) {
- mAudioPlaybackStateLogger.logd(TAG, "onPlaybackConfigChanged: "
- + "active config: " + activeConfig);
+ @Override
+ public void onPlaybackConfigChanged(List configs) {
+ if (configs == null) {
+ return;
+ }
+ boolean isActive = false;
+ AudioPlaybackConfiguration activeConfig = null;
+ for (AudioPlaybackConfiguration config : configs) {
+ if (config.isActive()
+ && (config.getAudioAttributes().getUsage()
+ == AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
+ && (config.getAudioAttributes().getContentType()
+ == AudioAttributes.CONTENT_TYPE_SPEECH)) {
+ activeConfig = config;
+ isActive = true;
+ }
+ }
+ if (isActive != mAudioPlaybackIsActive) {
+ mAudioPlaybackStateLogger.logd(
+ TAG,
+ "onPlaybackConfigChanged: "
+ + (mAudioPlaybackIsActive ? "Active" : "Non-active")
+ + " -> "
+ + (isActive ? "Active" : "Non-active"));
+ if (isActive) {
+ mAudioPlaybackStateLogger.logd(
+ TAG,
+ "onPlaybackConfigChanged: " + "active config: " + activeConfig);
+ }
+ mAudioPlaybackIsActive = isActive;
+ updateMediaForAudioPlayback();
+ }
}
- mAudioPlaybackIsActive = isActive;
- updateMediaForAudioPlayback();
- }
- }
- };
+ };
/**
* Callback from {@link MediaPlayerWrapper}.
@@ -1040,33 +1071,34 @@ public class MediaPlayerList {
*/
private final MediaPlayerWrapper.Callback mMediaPlayerCallback =
new MediaPlayerWrapper.Callback() {
- @Override
- public void mediaUpdatedCallback(MediaData data) {
- if (data.metadata == null) {
- Log.d(TAG, "mediaUpdatedCallback(): metadata is null");
- return;
- }
+ @Override
+ public void mediaUpdatedCallback(MediaData data) {
+ if (data.metadata == null) {
+ Log.d(TAG, "mediaUpdatedCallback(): metadata is null");
+ return;
+ }
- if (data.state == null) {
- Log.w(TAG, "mediaUpdatedCallback(): Tried to update with null state");
- return;
- }
+ if (data.state == null) {
+ Log.w(TAG, "mediaUpdatedCallback(): Tried to update with null state");
+ return;
+ }
- if (mAudioPlaybackIsActive && (data.state.getState() != PlaybackState.STATE_PLAYING)) {
- Log.d(TAG, "Some audio playbacks are still active, drop it");
- return;
- }
- sendMediaUpdate(data);
- }
+ if (mAudioPlaybackIsActive
+ && (data.state.getState() != PlaybackState.STATE_PLAYING)) {
+ Log.d(TAG, "Some audio playbacks are still active, drop it");
+ return;
+ }
+ sendMediaUpdate(data);
+ }
- @Override
- public void sessionUpdatedCallback(String packageName) {
- if (haveMediaPlayer(packageName)) {
- Log.d(TAG, "sessionUpdatedCallback(): packageName: " + packageName);
- removeMediaPlayer(mMediaPlayerIds.get(packageName));
- }
- }
- };
+ @Override
+ public void sessionUpdatedCallback(String packageName) {
+ if (haveMediaPlayer(packageName)) {
+ Log.d(TAG, "sessionUpdatedCallback(): packageName: " + packageName);
+ removeMediaPlayer(mMediaPlayerIds.get(packageName));
+ }
+ }
+ };
/**
* Listens for Media key events session changes.
@@ -1086,51 +1118,68 @@ public class MediaPlayerList {
@VisibleForTesting
final MediaSessionManager.OnMediaKeyEventSessionChangedListener
mMediaKeyEventSessionChangedListener =
- new MediaSessionManager.OnMediaKeyEventSessionChangedListener() {
- @Override
- public void onMediaKeyEventSessionChanged(String packageName,
- MediaSession.Token token) {
- if (mMediaSessionManager == null) {
- Log.w(TAG, "onMediaKeyEventSessionChanged(): Unexpected callback "
- + "from the MediaSessionManager, pkg" + packageName);
- return;
- }
- if (TextUtils.isEmpty(packageName)) {
- return;
- }
- if (token != null) {
- android.media.session.MediaController controller =
- new android.media.session.MediaController(mContext, token);
- if ((controller.getFlags() & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)
- != 0) {
- // Skip adding controller for GLOBAL_PRIORITY session.
- Log.i(TAG, "onMediaKeyEventSessionChanged,"
- + " ignoring global priority session");
- return;
- }
- if (!haveMediaPlayer(controller.getPackageName())) {
- // Since we have a controller, we can try to to recover by adding the
- // player and then setting it as active.
- Log.w(TAG, "onMediaKeyEventSessionChanged(Token): Addressed Player "
- + "changed to a player we didn't have a session for");
- addMediaPlayer(controller);
- }
-
- Log.i(TAG, "onMediaKeyEventSessionChanged: token="
- + controller.getPackageName());
- setActivePlayer(mMediaPlayerIds.get(controller.getPackageName()));
- } else {
- if (!haveMediaPlayer(packageName)) {
- e("onMediaKeyEventSessionChanged(PackageName): Media key event session "
- + "changed to a player we don't have a session for");
- return;
+ new MediaSessionManager.OnMediaKeyEventSessionChangedListener() {
+ @Override
+ public void onMediaKeyEventSessionChanged(
+ String packageName, MediaSession.Token token) {
+ if (mMediaSessionManager == null) {
+ Log.w(
+ TAG,
+ "onMediaKeyEventSessionChanged(): Unexpected callback "
+ + "from the MediaSessionManager, pkg"
+ + packageName);
+ return;
+ }
+ if (TextUtils.isEmpty(packageName)) {
+ return;
+ }
+ if (token != null) {
+ android.media.session.MediaController controller =
+ new android.media.session.MediaController(mContext, token);
+ if ((controller.getFlags()
+ & MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)
+ != 0) {
+ // Skip adding controller for GLOBAL_PRIORITY session.
+ Log.i(
+ TAG,
+ "onMediaKeyEventSessionChanged,"
+ + " ignoring global priority session");
+ return;
+ }
+ if (!haveMediaPlayer(controller.getPackageName())) {
+ // Since we have a controller, we can try to to recover by
+ // adding the
+ // player and then setting it as active.
+ Log.w(
+ TAG,
+ "onMediaKeyEventSessionChanged(Token): Addressed Player"
+ + " changed to a player we didn't have a session"
+ + " for");
+ addMediaPlayer(controller);
+ }
+
+ Log.i(
+ TAG,
+ "onMediaKeyEventSessionChanged: token="
+ + controller.getPackageName());
+ setActivePlayer(mMediaPlayerIds.get(controller.getPackageName()));
+ } else {
+ if (!haveMediaPlayer(packageName)) {
+ e(
+ "onMediaKeyEventSessionChanged(PackageName): Media key"
+ + " event session changed to a player we don't have"
+ + " a session for");
+ return;
+ }
+
+ Log.i(
+ TAG,
+ "onMediaKeyEventSessionChanged: packageName="
+ + packageName);
+ setActivePlayer(mMediaPlayerIds.get(packageName));
+ }
}
-
- Log.i(TAG, "onMediaKeyEventSessionChanged: packageName=" + packageName);
- setActivePlayer(mMediaPlayerIds.get(packageName));
- }
- }
- };
+ };
/** Dumps all players and browsable players currently listed in this class. */
public void dump(StringBuilder sb) {
diff --git a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
index 2dd965d64e271c90b8ea28cdce59e2f3076c5eb6..ae0afdeb0129027b356abaeedb84b9026fb0896d 100644
--- a/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
+++ b/android/app/src/com/android/bluetooth/audio_util/MediaPlayerWrapper.java
@@ -57,11 +57,13 @@ public class MediaPlayerWrapper {
@GuardedBy("mCallbackLock")
private MediaControllerListener mControllerCallbacks = null;
+
private final Object mCallbackLock = new Object();
private Callback mRegisteredCallback = null;
public interface Callback {
void mediaUpdatedCallback(MediaData data);
+
void sessionUpdatedCallback(String packageName);
}
@@ -163,18 +165,17 @@ public class MediaPlayerWrapper {
// We don't return the cached info here in order to always provide the freshest data.
MediaData getCurrentMediaData() {
- MediaData data = new MediaData(
- getCurrentMetadata(),
- getPlaybackState(),
- getCurrentQueue());
+ MediaData data = new MediaData(getCurrentMetadata(), getPlaybackState(), getCurrentQueue());
return data;
}
void playItemFromQueue(long qid) {
// Return immediately if no queue exists.
if (getQueue() == null) {
- Log.w(TAG, "playItemFromQueue: Trying to play item for player that has no queue: "
- + mPackageName);
+ Log.w(
+ TAG,
+ "playItemFromQueue: Trying to play item for player that has no queue: "
+ + mPackageName);
return;
}
@@ -253,9 +254,7 @@ public class MediaPlayerWrapper {
return;
}
- /**
- * Return whether the queue, metadata, and queueID are all in sync.
- */
+ /** Return whether the queue, metadata, and queueID are all in sync. */
boolean isMetadataSynced() {
List queue = getQueue();
if (queue != null && getActiveQueueID() != -1) {
@@ -293,8 +292,8 @@ public class MediaPlayerWrapper {
}
/**
- * Register a callback which gets called when media updates happen. The callbacks are
- * called on the same Looper that was passed in to create this object.
+ * Register a callback which gets called when media updates happen. The callbacks are called on
+ * the same Looper that was passed in to create this object.
*/
void registerCallback(Callback callback) {
if (callback == null) {
@@ -308,19 +307,18 @@ public class MediaPlayerWrapper {
// Update the current data since it could have changed while we weren't registered for
// updates
- mCurrentData = new MediaData(
- Util.toMetadata(mContext, getMetadata()),
- getPlaybackState(),
- Util.toMetadataList(mContext, getQueue()));
+ mCurrentData =
+ new MediaData(
+ Util.toMetadata(mContext, getMetadata()),
+ getPlaybackState(),
+ Util.toMetadataList(mContext, getQueue()));
synchronized (mCallbackLock) {
mControllerCallbacks = new MediaControllerListener(mMediaController, mLooper);
}
}
- /**
- * Unregisters from updates. Note, this doesn't require the looper to be shut down.
- */
+ /** Unregisters from updates. Note, this doesn't require the looper to be shut down. */
void unregisterCallback() {
// Prevent a race condition where a callback could be called while shutting down
synchronized (mCallbackLock) {
@@ -346,10 +344,11 @@ public class MediaPlayerWrapper {
// Update the current data since it could be different on the new controller for the
// player
- mCurrentData = new MediaData(
- Util.toMetadata(mContext, getMetadata()),
- getPlaybackState(),
- Util.toMetadataList(mContext, getQueue()));
+ mCurrentData =
+ new MediaData(
+ Util.toMetadata(mContext, getMetadata()),
+ getPlaybackState(),
+ Util.toMetadataList(mContext, getQueue()));
mControllerCallbacks = new MediaControllerListener(mMediaController, mLooper);
}
@@ -357,10 +356,11 @@ public class MediaPlayerWrapper {
}
private void sendMediaUpdate() {
- MediaData newData = new MediaData(
- Util.toMetadata(mContext, getMetadata()),
- getPlaybackState(),
- Util.toMetadataList(mContext, getQueue()));
+ MediaData newData =
+ new MediaData(
+ Util.toMetadata(mContext, getMetadata()),
+ getPlaybackState(),
+ Util.toMetadataList(mContext, getQueue()));
if (newData.equals(mCurrentData)) {
// This may happen if the controller is fully synced by the time the
@@ -371,8 +371,7 @@ public class MediaPlayerWrapper {
synchronized (mCallbackLock) {
if (mRegisteredCallback == null) {
- Log.e(TAG, mPackageName
- + ": Trying to send an update with no registered callback");
+ Log.e(TAG, mPackageName + ": Trying to send an update with no registered callback");
return;
}
@@ -399,7 +398,7 @@ public class MediaPlayerWrapper {
}
Log.e(TAG, "Timeout while waiting for metadata to sync for " + mPackageName);
- Log.e(TAG, " └ Current Metadata: " + Util.toMetadata(mContext, getMetadata()));
+ Log.e(TAG, " └ Current Metadata: " + Util.toMetadata(mContext, getMetadata()));
Log.e(TAG, " └ Current Playstate: " + getPlaybackState());
List current_queue = Util.toMetadataList(mContext, getQueue());
for (int i = 0; i < current_queue.size(); i++) {
@@ -446,8 +445,8 @@ public class MediaPlayerWrapper {
if (!isMetadataSynced()) {
d("trySendMediaUpdate(): Starting media update timeout");
- mTimeoutHandler.sendEmptyMessageDelayed(TimeoutHandler.MSG_TIMEOUT,
- TimeoutHandler.CALLBACK_TIMEOUT_MS);
+ mTimeoutHandler.sendEmptyMessageDelayed(
+ TimeoutHandler.MSG_TIMEOUT, TimeoutHandler.CALLBACK_TIMEOUT_MS);
return;
}
}
@@ -466,8 +465,12 @@ public class MediaPlayerWrapper {
return;
}
- Log.v(TAG, "onMetadataChanged(): " + mPackageName + " : "
- + Util.toMetadata(mContext, mediaMetadata));
+ Log.v(
+ TAG,
+ "onMetadataChanged(): "
+ + mPackageName
+ + " : "
+ + Util.toMetadata(mContext, mediaMetadata));
if (!Objects.equals(mediaMetadata, getMetadata())) {
e("The callback metadata doesn't match controller metadata");
@@ -482,8 +485,11 @@ public class MediaPlayerWrapper {
// twice in a row with the only difference being that the song duration is rounded to
// the nearest second.
if (Objects.equals(Util.toMetadata(mContext, mediaMetadata), mCurrentData.metadata)) {
- Log.w(TAG, "onMetadataChanged(): " + mPackageName
- + " tried to update with no new data");
+ Log.w(
+ TAG,
+ "onMetadataChanged(): "
+ + mPackageName
+ + " tried to update with no new data");
return;
}
@@ -509,8 +515,11 @@ public class MediaPlayerWrapper {
}
if (playstateEquals(state, mCurrentData.state)) {
- Log.w(TAG, "onPlaybackStateChanged(): " + mPackageName
- + " tried to update with no new data");
+ Log.w(
+ TAG,
+ "onPlaybackStateChanged(): "
+ + mPackageName
+ + " tried to update with no new data");
return;
}
@@ -526,8 +535,7 @@ public class MediaPlayerWrapper {
@Override
public void onQueueChanged(@Nullable List queue) {
if (!isPlaybackStateReady() || !isMetadataReady()) {
- Log.v(TAG, "onQueueChanged(): " + mPackageName
- + " tried to update with no queue");
+ Log.v(TAG, "onQueueChanged(): " + mPackageName + " tried to update with no queue");
return;
}
@@ -539,8 +547,9 @@ public class MediaPlayerWrapper {
List current_queue = Util.toMetadataList(mContext, queue);
if (current_queue.equals(mCurrentData.queue)) {
- Log.w(TAG, "onQueueChanged(): " + mPackageName
- + " tried to update with no new data");
+ Log.w(
+ TAG,
+ "onQueueChanged(): " + mPackageName + " tried to update with no new data");
return;
}
@@ -572,14 +581,16 @@ public class MediaPlayerWrapper {
* certain amount of deviation between the position fields of the PlaybackStates. This is to
* prevent matches from failing when updates happen in quick succession.
*
- * The maximum allowed deviation is defined by PLAYSTATE_BOUNCE_IGNORE_PERIOD and is measured
+ * The maximum allowed deviation is defined by PLAYSTATE_BOUNCE_IGNORE_PERIOD and is measured
* in milliseconds.
*/
private static final long PLAYSTATE_BOUNCE_IGNORE_PERIOD = 500;
+
public static boolean playstateEquals(PlaybackState a, PlaybackState b) {
if (a == b) return true;
- if (a != null && b != null
+ if (a != null
+ && b != null
&& a.getState() == b.getState()
&& a.getActiveQueueItemId() == b.getActiveQueueItemId()
&& Math.abs(a.getPosition() - b.getPosition()) < PLAYSTATE_BOUNCE_IGNORE_PERIOD) {
diff --git a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
index 1da13649bc84a825c6a289887a688a7a12cd6ed0..43733ec15ed8b358edcd99033ada7275fa56e432 100644
--- a/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
+++ b/android/app/src/com/android/bluetooth/audio_util/PlayerSettingsManager.java
@@ -23,9 +23,7 @@ import android.util.Log;
import com.android.bluetooth.avrcp.AvrcpTargetService;
-/**
- * Manager class for player apps.
- */
+/** Manager class for player apps. */
public class PlayerSettingsManager {
private static final String TAG = PlayerSettingsManager.class.getSimpleName();
@@ -49,8 +47,10 @@ public class PlayerSettingsManager {
MediaPlayerWrapper wrapper = mMediaPlayerList.getActivePlayer();
if (wrapper != null) {
- mActivePlayerController = new MediaControllerCompat(mService,
- MediaSessionCompat.Token.fromToken(wrapper.getSessionToken()));
+ mActivePlayerController =
+ new MediaControllerCompat(
+ mService,
+ MediaSessionCompat.Token.fromToken(wrapper.getSessionToken()));
if (!registerMediaControllerCallback(mActivePlayerController, mControllerCallback)) {
mActivePlayerController = null;
}
@@ -59,9 +59,7 @@ public class PlayerSettingsManager {
}
}
- /**
- * Unregister callbacks
- */
+ /** Unregister callbacks */
public void cleanup() {
updateRemoteDevice();
if (mActivePlayerController != null) {
@@ -69,16 +67,17 @@ public class PlayerSettingsManager {
}
}
- /**
- * Updates the active player controller.
- */
+ /** Updates the active player controller. */
private void activePlayerChanged(MediaPlayerWrapper mediaPlayerWrapper) {
if (mActivePlayerController != null) {
unregisterMediaControllerCallback(mActivePlayerController, mControllerCallback);
}
if (mediaPlayerWrapper != null) {
- mActivePlayerController = new MediaControllerCompat(mService,
- MediaSessionCompat.Token.fromToken(mediaPlayerWrapper.getSessionToken()));
+ mActivePlayerController =
+ new MediaControllerCompat(
+ mService,
+ MediaSessionCompat.Token.fromToken(
+ mediaPlayerWrapper.getSessionToken()));
if (!registerMediaControllerCallback(mActivePlayerController, mControllerCallback)) {
mActivePlayerController = null;
updateRemoteDevice();
@@ -92,12 +91,9 @@ public class PlayerSettingsManager {
/**
* Sends the MediaController values of the active player to the remote device.
*
- * This is called when:
- * - The class is created and the session is ready
- * - The class is destroyed
- * - The active player changed and the session is ready
- * - The last active player has been removed
- * - The repeat / shuffle player state changed
+ *
This is called when: - The class is created and the session is ready - The class is
+ * destroyed - The active player changed and the session is ready - The last active player has
+ * been removed - The repeat / shuffle player state changed
*/
private void updateRemoteDevice() {
int repeatMode = getPlayerRepeatMode();
@@ -111,9 +107,7 @@ public class PlayerSettingsManager {
mService.sendPlayerSettings(repeatMode, shuffleMode);
}
- /**
- * Called from remote device to set the active player repeat mode.
- */
+ /** Called from remote device to set the active player repeat mode. */
public boolean setPlayerRepeatMode(int repeatMode) {
if (mActivePlayerController == null) {
return false;
@@ -144,9 +138,7 @@ public class PlayerSettingsManager {
}
}
- /**
- * Called from remote device to set the active player shuffle mode.
- */
+ /** Called from remote device to set the active player shuffle mode. */
public boolean setPlayerShuffleMode(int shuffleMode) {
if (mActivePlayerController == null) {
Log.i(TAG, "setPlayerShuffleMode: no active player");
@@ -283,58 +275,36 @@ public class PlayerSettingsManager {
}
}
- /**
- * Class containing all the Shuffle/Repeat values as defined in the BT spec.
- */
+ /** Class containing all the Shuffle/Repeat values as defined in the BT spec. */
public static final class PlayerSettingsValues {
- /**
- * Repeat setting, as defined by Bluetooth specification.
- */
+ /** Repeat setting, as defined by Bluetooth specification. */
public static final int SETTING_REPEAT = 2;
- /**
- * Shuffle setting, as defined by Bluetooth specification.
- */
+ /** Shuffle setting, as defined by Bluetooth specification. */
public static final int SETTING_SHUFFLE = 3;
- /**
- * Repeat OFF state, as defined by Bluetooth specification.
- */
+ /** Repeat OFF state, as defined by Bluetooth specification. */
public static final int STATE_REPEAT_OFF = 1;
- /**
- * Single track repeat, as defined by Bluetooth specification.
- */
+ /** Single track repeat, as defined by Bluetooth specification. */
public static final int STATE_REPEAT_SINGLE_TRACK = 2;
- /**
- * All track repeat, as defined by Bluetooth specification.
- */
+ /** All track repeat, as defined by Bluetooth specification. */
public static final int STATE_REPEAT_ALL_TRACK = 3;
- /**
- * Group repeat, as defined by Bluetooth specification.
- */
+ /** Group repeat, as defined by Bluetooth specification. */
public static final int STATE_REPEAT_GROUP = 4;
- /**
- * Shuffle OFF state, as defined by Bluetooth specification.
- */
+ /** Shuffle OFF state, as defined by Bluetooth specification. */
public static final int STATE_SHUFFLE_OFF = 1;
- /**
- * All track shuffle, as defined by Bluetooth specification.
- */
+ /** All track shuffle, as defined by Bluetooth specification. */
public static final int STATE_SHUFFLE_ALL_TRACK = 2;
- /**
- * Group shuffle, as defined by Bluetooth specification.
- */
+ /** Group shuffle, as defined by Bluetooth specification. */
public static final int STATE_SHUFFLE_GROUP = 3;
- /**
- * Default state off.
- */
+ /** Default state off. */
public static final int STATE_DEFAULT_OFF = 1;
}
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
index 1b53eec236774261b3d51cf7829ad6867cf98521..fc106e9a956a186b59832e4de88c24e61c357fc4 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Image.java
@@ -30,7 +30,7 @@ import java.io.InputStream;
/**
* An object to represent an image from the Media Framework
*
- * This object abstracts away the method used to get the bitmap and provides a way for us to
+ *
This object abstracts away the method used to get the bitmap and provides a way for us to
* determine image equality in an application/folder/item agnostic way.
*/
public class Image {
@@ -49,9 +49,7 @@ public class Image {
// solution has picked for this image and pass this object on directly.
private String mImageHandle = null;
- /**
- * Create an Image object from a MediaMetadata object
- */
+ /** Create an Image object from a MediaMetadata object */
public Image(Context context, MediaMetadata metadata) {
mContext = context;
@@ -83,9 +81,7 @@ public class Image {
}
}
- /**
- * Create an image out of a bundle of MediaMetadata keyed values
- */
+ /** Create an image out of a bundle of MediaMetadata keyed values */
public Image(Context context, Bundle bundle) {
mContext = context;
@@ -117,9 +113,7 @@ public class Image {
}
}
- /**
- * Create an Image object from a MediaDescription object
- */
+ /** Create an Image object from a MediaDescription object */
public Image(Context context, MediaDescription desc) {
mContext = context;
Uri uri = desc.getIconUri();
@@ -131,34 +125,26 @@ public class Image {
}
}
- /**
- * Create an Image object from a raw image uri
- */
+ /** Create an Image object from a raw image uri */
public Image(Context context, Uri uri) {
mContext = context;
setImage(uri);
}
- /**
- * Create an Image object from a raw image
- */
+ /** Create an Image object from a raw image */
public Image(Context context, Bitmap image) {
mContext = context;
setImage(image);
}
- /**
- * Set the image by resolving a URI to a bitmap
- */
+ /** Set the image by resolving a URI to a bitmap */
private void setImage(String uriString) {
if (uriString == null) return;
Uri uri = Uri.parse(uriString);
setImage(uri);
}
- /**
- * Set the image by resolving a URI to a bitmap
- */
+ /** Set the image by resolving a URI to a bitmap */
private void setImage(Uri uri) {
if (uri == null) return;
Bitmap image = getImageFromUri(uri);
@@ -167,18 +153,14 @@ public class Image {
setSource(SOURCE_URI);
}
- /**
- * Set the image directly from a bitmap
- */
+ /** Set the image directly from a bitmap */
private void setImage(Bitmap image) {
if (image == null) return;
mImage = image;
setSource(SOURCE_BITMAP);
}
- /**
- * Get the bitmap associated with this Image
- */
+ /** Get the bitmap associated with this Image */
public Bitmap getImage() {
return mImage;
}
@@ -186,7 +168,7 @@ public class Image {
/**
* Get an image Bitmap from a Uri
*
- * Used to convert Uris into the images they represent
+ *
Used to convert Uris into the images they represent
*
* @param uri A Uri pointing to an image
* @return A Bitmap object representing the image at the given Uri
@@ -216,7 +198,7 @@ public class Image {
/**
* Get the source of the image, if known
*
- * Images currently come from either raw bitmaps or a URI that points to a ContentProvider.
+ *
Images currently come from either raw bitmaps or a URI that points to a ContentProvider.
* This allows us to set where it came from, largely used for debug purposes.
*/
public int getSource() {
@@ -226,30 +208,24 @@ public class Image {
/**
* Set the source of the image.
*
- * Images currently come from either raw bitmaps or a URI that points to a ContentProvider.
+ *
Images currently come from either raw bitmaps or a URI that points to a ContentProvider.
* This allows us to set where it came from, largely used for debug purposes.
*/
private void setSource(int source) {
mSource = source;
}
- /**
- * Assign a handle value from your storage solution to this image
- */
+ /** Assign a handle value from your storage solution to this image */
public void setImageHandle(String handle) {
mImageHandle = handle;
}
- /**
- * Get the handle value associated with this image from your storage situation
- */
+ /** Get the handle value associated with this image from your storage situation */
public String getImageHandle() {
return mImageHandle;
}
- /**
- * Determine if two image objects are the same.
- */
+ /** Determine if two image objects are the same. */
public static boolean sameAs(Image l, Image r) {
if (l == null && r == null) return true;
if (l == null || r == null) return false;
@@ -258,9 +234,7 @@ public class Image {
return bmp.sameAs(r.getImage());
}
- /**
- * Get a string representation of the image and its metadata
- */
+ /** Get a string representation of the image and its metadata */
@Override
public String toString() {
return "";
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java
index fb3b25ca2e759cdfe5278288084d5f6c22dfdcc9..d894ae82885bd8a415aa193169107135e156d45c 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Metadata.java
@@ -93,14 +93,26 @@ public class Metadata implements Cloneable {
@Override
public String toString() {
- return "{ mediaId=\"" + mediaId + "\" title=\"" + title + "\" artist=\"" + artist
- + "\" album=\"" + album + "\" duration=" + duration
- + " trackPosition=" + trackNum + "/" + numTracks + " image=" + image + " }";
+ return "{ mediaId=\""
+ + mediaId
+ + "\" title=\""
+ + title
+ + "\" artist=\""
+ + artist
+ + "\" album=\""
+ + album
+ + "\" duration="
+ + duration
+ + " trackPosition="
+ + trackNum
+ + "/"
+ + numTracks
+ + " image="
+ + image
+ + " }";
}
- /**
- * Replaces default values by {@code filledMetadata} non default values.
- */
+ /** Replaces default values by {@code filledMetadata} non default values. */
public void replaceDefaults(Metadata filledMetadata) {
if (filledMetadata == null) {
return;
@@ -137,32 +149,24 @@ public class Metadata implements Cloneable {
}
}
- /**
- * A Builder object to populate a Metadata from various different Media Framework objects
- */
+ /** A Builder object to populate a Metadata from various different Media Framework objects */
public static class Builder {
private Metadata mMetadata = new Metadata();
private Context mContext = null;
- /**
- * Set the Media ID fot the Metadata Object
- */
+ /** Set the Media ID fot the Metadata Object */
public Builder setMediaId(String id) {
mMetadata.mediaId = id;
return this;
}
- /**
- * Set the context this builder should use when resolving images
- */
+ /** Set the context this builder should use when resolving images */
public Builder useContext(Context context) {
mContext = context;
return this;
}
- /**
- * Extract the fields from a MediaMetadata object into a Metadata, if they exist
- */
+ /** Extract the fields from a MediaMetadata object into a Metadata, if they exist */
public Builder fromMediaMetadata(MediaMetadata data) {
if (data == null) return this;
@@ -194,10 +198,12 @@ public class Metadata implements Cloneable {
if (data.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
mMetadata.duration = "" + data.getLong(MediaMetadata.METADATA_KEY_DURATION);
}
- if ((mContext != null && Util.areUriImagesSupported(mContext)
- && (data.containsKey(MediaMetadata.METADATA_KEY_ART_URI)
- || data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)
- || data.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI)))
+ if ((mContext != null
+ && Util.areUriImagesSupported(mContext)
+ && (data.containsKey(MediaMetadata.METADATA_KEY_ART_URI)
+ || data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)
+ || data.containsKey(
+ MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI)))
|| data.containsKey(MediaMetadata.METADATA_KEY_ART)
|| data.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)
|| data.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON)) {
@@ -206,17 +212,13 @@ public class Metadata implements Cloneable {
return this;
}
- /**
- * Extract the fields from a MediaItem object into a Metadata, if they exist
- */
+ /** Extract the fields from a MediaItem object into a Metadata, if they exist */
public Builder fromMediaItem(MediaItem item) {
if (item == null) return this;
return fromMediaDescription(item.getDescription()).setMediaId(item.getMediaId());
}
- /**
- * Extract the fields from a MediaDescription object into a Metadata, if they exist
- */
+ /** Extract the fields from a MediaDescription object into a Metadata, if they exist */
public Builder fromMediaDescription(MediaDescription desc) {
if (desc == null) return this;
@@ -228,7 +230,8 @@ public class Metadata implements Cloneable {
// Check for artwork
if (desc.getIconBitmap() != null) {
mMetadata.image = new Image(mContext, desc.getIconBitmap());
- } else if (mContext != null && Util.areUriImagesSupported(mContext)
+ } else if (mContext != null
+ && Util.areUriImagesSupported(mContext)
&& desc.getIconUri() != null) {
mMetadata.image = new Image(mContext, desc.getIconUri());
}
@@ -275,10 +278,12 @@ public class Metadata implements Cloneable {
if (bundle.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
mMetadata.duration = "" + bundle.getLong(MediaMetadata.METADATA_KEY_DURATION);
}
- if ((mContext != null && Util.areUriImagesSupported(mContext)
- && (bundle.containsKey(MediaMetadata.METADATA_KEY_ART_URI)
- || bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)
- || bundle.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI)))
+ if ((mContext != null
+ && Util.areUriImagesSupported(mContext)
+ && (bundle.containsKey(MediaMetadata.METADATA_KEY_ART_URI)
+ || bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART_URI)
+ || bundle.containsKey(
+ MediaMetadata.METADATA_KEY_DISPLAY_ICON_URI)))
|| bundle.containsKey(MediaMetadata.METADATA_KEY_ART)
|| bundle.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)
|| bundle.containsKey(MediaMetadata.METADATA_KEY_DISPLAY_ICON)) {
@@ -287,17 +292,14 @@ public class Metadata implements Cloneable {
return this;
}
- /**
- * Elect to use default values in the Metadata in place of any missing values
- */
+ /** Elect to use default values in the Metadata in place of any missing values */
public Builder useDefaults() {
if (mMetadata.mediaId == null) {
mMetadata.mediaId = EMPTY_MEDIA_ID;
}
if (mMetadata.title == null) {
mMetadata.title =
- mContext != null ? mContext.getString(R.string.not_provided)
- : EMPTY_TITLE;
+ mContext != null ? mContext.getString(R.string.not_provided) : EMPTY_TITLE;
}
if (mMetadata.artist == null) mMetadata.artist = EMPTY_ARTIST;
if (mMetadata.album == null) mMetadata.album = EMPTY_ALBUM;
@@ -309,9 +311,7 @@ public class Metadata implements Cloneable {
return this;
}
- /**
- * Get the final Metadata objects you're building
- */
+ /** Get the final Metadata objects you're building */
public Metadata build() {
return mMetadata.clone();
}
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
index 75a760bb55f3e62954042413551d7d83d5a2f0cb..adca4be6a9ad82f17b1e50fbba8e9328649275e6 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayStatus.java
@@ -18,9 +18,7 @@ package com.android.bluetooth.audio_util;
import android.media.session.PlaybackState;
-/**
- * Carries the playback status information in a custom object.
- */
+/** Carries the playback status information in a custom object. */
// TODO(apanicke): Send the current active song ID along with this object so that all information
// is carried by our custom types.
public class PlayStatus {
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
index a653e96cc85029674f9c328606330904eb174787..ada64292f71e17d9ee13c972d7a4a9d2eedb7553 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/PlayerInfo.java
@@ -16,9 +16,7 @@
package com.android.bluetooth.audio_util;
-/**
- * Carries Media Player Information
- */
+/** Carries Media Player Information */
public class PlayerInfo {
public int id;
public String name;
diff --git a/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java b/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java
index efe155f7f0cdf5ed357f1dd72bd9b977f93d90a7..32597edc75e8e33445fec1a390b62d304d85b8e7 100644
--- a/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java
+++ b/android/app/src/com/android/bluetooth/audio_util/helpers/Util.java
@@ -34,17 +34,13 @@ class Util {
// TODO (apanicke): Remove this prefix later, for now it makes debugging easier.
public static final String NOW_PLAYING_PREFIX = "NowPlayingId";
- /**
- * Get an empty set of Metadata
- */
+ /** Get an empty set of Metadata */
public static final Metadata empty_data() {
Metadata.Builder builder = new Metadata.Builder();
return builder.useDefaults().build();
}
- /**
- * Determine if a set of Metadata is "empty" as defined by audio_util.
- */
+ /** Determine if a set of Metadata is "empty" as defined by audio_util. */
public static final boolean isEmptyData(Metadata data) {
if (data == null) return true;
// Note: We need both equals() and an explicit media id check because equals() does
@@ -55,16 +51,14 @@ class Util {
/**
* Get whether or not Bluetooth is configured to support URI images or not.
*
- * Note that creating URI images will dramatically increase memory usage.
+ * Note that creating URI images will dramatically increase memory usage.
*/
public static boolean areUriImagesSupported(Context context) {
if (context == null) return false;
return context.getResources().getBoolean(R.bool.avrcp_target_cover_art_uri_images);
}
- /**
- * Translate a MediaItem to audio_util's Metadata
- */
+ /** Translate a MediaItem to audio_util's Metadata */
public static Metadata toMetadata(Context context, MediaItem item) {
Metadata.Builder builder = new Metadata.Builder();
try {
@@ -75,9 +69,7 @@ class Util {
}
}
- /**
- * Translate a MediaSession.QueueItem to audio_util's Metadata
- */
+ /** Translate a MediaSession.QueueItem to audio_util's Metadata */
public static Metadata toMetadata(Context context, MediaSession.QueueItem item) {
Metadata.Builder builder = new Metadata.Builder();
@@ -95,28 +87,27 @@ class Util {
return builder.build();
}
- /**
- * Translate a MediaMetadata to audio_util's Metadata
- */
+ /** Translate a MediaMetadata to audio_util's Metadata */
public static Metadata toMetadata(Context context, MediaMetadata data) {
Metadata.Builder builder = new Metadata.Builder();
// This will always be currsong. The AVRCP service will overwrite the mediaId if it needs to
// TODO (apanicke): Remove when the service is ready, right now it makes debugging much more
// convenient
try {
- return builder.useContext(context).useDefaults().fromMediaMetadata(data)
- .setMediaId("currsong").build();
+ return builder.useContext(context)
+ .useDefaults()
+ .fromMediaMetadata(data)
+ .setMediaId("currsong")
+ .build();
} catch (Exception e) {
Log.e(TAG, "Failed to build Metadata from MediaMetadata, returning empty data", e);
return empty_data();
}
}
- /**
- * Translate a list of MediaSession.QueueItem to a list of audio_util's Metadata
- */
- public static List toMetadataList(Context context,
- List items) {
+ /** Translate a list of MediaSession.QueueItem to a list of audio_util's Metadata */
+ public static List toMetadataList(
+ Context context, List items) {
ArrayList list = new ArrayList<>();
if (items == null) return list;
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
index 6dc617af69a1ec5f992d7f8458403a954c9fb5be..30d23b655771c8c5de78329235eeb470440e027c 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowser.java
@@ -26,134 +26,103 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
/**
- * Provide a mockable interface in order to test classes that use MediaBrowser.
- * We need this class due to the fact that the MediaController class is marked as final and
- * there is no way to currently mock final classes in Android. Once this is possible this class
- * can be deleted.
+ * Provide a mockable interface in order to test classes that use MediaBrowser. We need this class
+ * due to the fact that the MediaController class is marked as final and there is no way to
+ * currently mock final classes in Android. Once this is possible this class can be deleted.
*/
public class MediaBrowser {
android.media.browse.MediaBrowser mDelegate;
- /**
- * Wrap a real MediaBrowser object
- */
+ /** Wrap a real MediaBrowser object */
public MediaBrowser(android.media.browse.MediaBrowser delegate) {
mDelegate = delegate;
}
- /**
- * Create a real MediaBrowser object and wrap it
- */
- public MediaBrowser(Context context, ComponentName serviceComponent,
- ConnectionCallback callback, Bundle rootHints) {
- mDelegate = new android.media.browse.MediaBrowser(context, serviceComponent, callback,
- rootHints);
+ /** Create a real MediaBrowser object and wrap it */
+ public MediaBrowser(
+ Context context,
+ ComponentName serviceComponent,
+ ConnectionCallback callback,
+ Bundle rootHints) {
+ mDelegate =
+ new android.media.browse.MediaBrowser(
+ context, serviceComponent, callback, rootHints);
}
- /**
- * Wrapper for MediaBrowser.ConnectionCallback
- */
- public abstract static class ConnectionCallback extends
- android.media.browse.MediaBrowser.ConnectionCallback {}
+ /** Wrapper for MediaBrowser.ConnectionCallback */
+ public abstract static class ConnectionCallback
+ extends android.media.browse.MediaBrowser.ConnectionCallback {}
- /**
- * Wrapper for MediaBrowser.ItemCallback
- */
- public abstract static class ItemCallback extends
- android.media.browse.MediaBrowser.ItemCallback {}
+ /** Wrapper for MediaBrowser.ItemCallback */
+ public abstract static class ItemCallback
+ extends android.media.browse.MediaBrowser.ItemCallback {}
- /**
- * Wrapper for MediaBrowser.SubscriptionCallback
- */
- public abstract static class SubscriptionCallback extends
- android.media.browse.MediaBrowser.SubscriptionCallback {
- /**
- * Wrapper for MediaBrowser.SubscriptionCallback.getTimeoutHandler()
- */
+ /** Wrapper for MediaBrowser.SubscriptionCallback */
+ public abstract static class SubscriptionCallback
+ extends android.media.browse.MediaBrowser.SubscriptionCallback {
+ /** Wrapper for MediaBrowser.SubscriptionCallback.getTimeoutHandler() */
public abstract Handler getTimeoutHandler();
}
- /**
- * Wrapper for MediaBrowser.connect()
- */
+ /** Wrapper for MediaBrowser.connect() */
public void connect() {
mDelegate.connect();
}
- /**
- * Wrapper for MediaBrowser.disconnect()
- */
+ /** Wrapper for MediaBrowser.disconnect() */
public void disconnect() {
mDelegate.disconnect();
}
- /**
- * Wrapper for MediaBrowser.getExtras()
- */
+ /** Wrapper for MediaBrowser.getExtras() */
public Bundle getExtras() {
return mDelegate.getExtras();
}
- /**
- * Wrapper for MediaBrowser.getItem(String mediaId, ItemCallback callback)
- */
+ /** Wrapper for MediaBrowser.getItem(String mediaId, ItemCallback callback) */
public void getItem(String mediaId, ItemCallback callback) {
mDelegate.getItem(mediaId, callback);
}
- /**
- * Wrapper for MediaBrowser.getRoot()
- */
+ /** Wrapper for MediaBrowser.getRoot() */
public String getRoot() {
return mDelegate.getRoot();
}
- /**
- * Wrapper for MediaBrowser.getServiceComponent()
- */
+ /** Wrapper for MediaBrowser.getServiceComponent() */
public ComponentName getServiceComponent() {
return mDelegate.getServiceComponent();
}
- /**
- * Wrapper for MediaBrowser.getSessionToken()
- */
+ /** Wrapper for MediaBrowser.getSessionToken() */
public MediaSession.Token getSessionToken() {
return mDelegate.getSessionToken();
}
- /**
- * Wrapper for MediaBrowser.isConnected()
- */
+
+ /** Wrapper for MediaBrowser.isConnected() */
public boolean isConnected() {
return mDelegate.isConnected();
}
/**
- * Wrapper for MediaBrowser.subscribe(String parentId, Bundle options,
- * SubscriptionCallback callback)
+ * Wrapper for MediaBrowser.subscribe(String parentId, Bundle options, SubscriptionCallback
+ * callback)
*/
public void subscribe(String parentId, Bundle options, SubscriptionCallback callback) {
mDelegate.subscribe(parentId, options, callback);
}
- /**
- * Wrapper for MediaBrowser.subscribe(String parentId, SubscriptionCallback callback)
- */
+ /** Wrapper for MediaBrowser.subscribe(String parentId, SubscriptionCallback callback) */
public void subscribe(String parentId, SubscriptionCallback callback) {
mDelegate.subscribe(parentId, callback);
}
- /**
- * Wrapper for MediaBrowser.unsubscribe(String parentId)
- */
+ /** Wrapper for MediaBrowser.unsubscribe(String parentId) */
public void unsubscribe(String parentId) {
mDelegate.unsubscribe(parentId);
}
-
- /**
- * Wrapper for MediaBrowser.unsubscribe(String parentId, SubscriptionCallback callback)
- */
+ /** Wrapper for MediaBrowser.unsubscribe(String parentId, SubscriptionCallback callback) */
public void unsubscribe(String parentId, SubscriptionCallback callback) {
mDelegate.unsubscribe(parentId, callback);
}
@@ -163,8 +132,11 @@ public class MediaBrowser {
* MediaBrowserFactory.make()
*/
@VisibleForTesting
- public void testInit(Context context, ComponentName serviceComponent,
- ConnectionCallback callback, Bundle rootHints) {
+ public void testInit(
+ Context context,
+ ComponentName serviceComponent,
+ ConnectionCallback callback,
+ Bundle rootHints) {
// This is only used by Mockito to capture the constructor arguments on creation
Log.wtf("AvrcpMockMediaBrowser", "This function should never be called");
}
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
index aa2f76c252cb7cf17059288a22e427a7d835daec..4570af982a91c6b2a715c41d631ddff7cb3a9903 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaBrowserFactory.java
@@ -23,10 +23,9 @@ import android.os.Bundle;
import com.android.internal.annotations.VisibleForTesting;
/**
- * Provide a method to inject custom MediaBrowser objects for testing. By using the factory
- * methods instead of calling the constructor of MediaBrowser directly, we can inject a custom
- * MediaBrowser that can be used with JUnit and Mockito to set expectations and validate
- * behaviour in tests.
+ * Provide a method to inject custom MediaBrowser objects for testing. By using the factory methods
+ * instead of calling the constructor of MediaBrowser directly, we can inject a custom MediaBrowser
+ * that can be used with JUnit and Mockito to set expectations and validate behaviour in tests.
*/
public final class MediaBrowserFactory {
private static MediaBrowser sInjectedBrowser;
@@ -36,8 +35,11 @@ public final class MediaBrowserFactory {
return (delegate != null) ? new MediaBrowser(delegate) : null;
}
- static MediaBrowser make(Context context, ComponentName serviceComponent,
- MediaBrowser.ConnectionCallback callback, Bundle rootHints) {
+ static MediaBrowser make(
+ Context context,
+ ComponentName serviceComponent,
+ MediaBrowser.ConnectionCallback callback,
+ Bundle rootHints) {
if (sInjectedBrowser != null) {
sInjectedBrowser.testInit(context, serviceComponent, callback, rootHints);
return sInjectedBrowser;
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
index 232f3edbd17edb794d29bc2e9f936b969094198e..a0081b219011fdc6d9ff67fda4039c9d722824d3 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaController.java
@@ -35,10 +35,9 @@ import java.util.List;
import java.util.Objects;
/**
- * Provide a mockable interface in order to test classes that use MediaController.
- * We need this class due to the fact that the MediaController class is marked as final and
- * there is no way to currently mock final classes in Android. Once this is possible this class
- * can be deleted.
+ * Provide a mockable interface in order to test classes that use MediaController. We need this
+ * class due to the fact that the MediaController class is marked as final and there is no way to
+ * currently mock final classes in Android. Once this is possible this class can be deleted.
*/
public class MediaController {
@NonNull public android.media.session.MediaController mDelegate;
@@ -66,169 +65,123 @@ public class MediaController {
return mTransportControls;
}
- /**
- * Wrapper for MediaController.dispatchMediaButtonEvent(KeyEvent keyEvent)
- */
+ /** Wrapper for MediaController.dispatchMediaButtonEvent(KeyEvent keyEvent) */
public boolean dispatchMediaButtonEvent(@NonNull KeyEvent keyEvent) {
return mDelegate.dispatchMediaButtonEvent(keyEvent);
}
- /**
- * Wrapper for MediaController.getPlaybackState()
- */
+ /** Wrapper for MediaController.getPlaybackState() */
@Nullable
public PlaybackState getPlaybackState() {
return mDelegate.getPlaybackState();
}
-
- /**
- * Wrapper for MediaController.getMetadata()
- */
+ /** Wrapper for MediaController.getMetadata() */
@Nullable
public MediaMetadata getMetadata() {
return mDelegate.getMetadata();
}
- /**
- * Wrapper for MediaController.getQueue()
- */
+ /** Wrapper for MediaController.getQueue() */
@Nullable
public List getQueue() {
return mDelegate.getQueue();
}
- /**
- * Wrapper for MediaController.getQueueTitle()
- */
+ /** Wrapper for MediaController.getQueueTitle() */
@Nullable
public CharSequence getQueueTitle() {
return mDelegate.getQueueTitle();
}
- /**
- * Wrapper for MediaController.getExtras()
- */
+ /** Wrapper for MediaController.getExtras() */
@Nullable
public Bundle getExtras() {
return mDelegate.getExtras();
}
- /**
- * Wrapper for MediaController.getRatingType()
- */
+ /** Wrapper for MediaController.getRatingType() */
public int getRatingType() {
return mDelegate.getRatingType();
}
- /**
- * Wrapper for MediaController.getFlags()
- */
+ /** Wrapper for MediaController.getFlags() */
public long getFlags() {
return mDelegate.getFlags();
}
- /**
- * Wrapper for MediaController.getPlaybackInfo()
- */
+ /** Wrapper for MediaController.getPlaybackInfo() */
@Nullable
public android.media.session.MediaController.PlaybackInfo getPlaybackInfo() {
return mDelegate.getPlaybackInfo();
}
-
- /**
- * Wrapper for MediaController.getSessionActivity()
- */
+ /** Wrapper for MediaController.getSessionActivity() */
@Nullable
public PendingIntent getSessionActivity() {
return mDelegate.getSessionActivity();
}
- /**
- * Wrapper for MediaController.getSessionToken()
- */
+ /** Wrapper for MediaController.getSessionToken() */
@NonNull
public MediaSession.Token getSessionToken() {
return mDelegate.getSessionToken();
}
- /**
- * Wrapper for MediaController.setVolumeTo(int value, int flags)
- */
+ /** Wrapper for MediaController.setVolumeTo(int value, int flags) */
public void setVolumeTo(int value, int flags) {
mDelegate.setVolumeTo(value, flags);
}
- /**
- * Wrapper for MediaController.adjustVolume(int direction, int flags)
- */
+ /** Wrapper for MediaController.adjustVolume(int direction, int flags) */
public void adjustVolume(int direction, int flags) {
mDelegate.adjustVolume(direction, flags);
}
- /**
- * Wrapper for MediaController.registerCallback(Callback callback)
- */
+ /** Wrapper for MediaController.registerCallback(Callback callback) */
public void registerCallback(@NonNull Callback callback) {
- //TODO(apanicke): Add custom callback struct to be able to analyze and
+ // TODO(apanicke): Add custom callback struct to be able to analyze and
// delegate callbacks
mDelegate.registerCallback(callback);
}
- /**
- * Wrapper for MediaController.registerCallback(Callback callback, Handler handler)
- */
+ /** Wrapper for MediaController.registerCallback(Callback callback, Handler handler) */
public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) {
mDelegate.registerCallback(callback, handler);
}
- /**
- * Wrapper for MediaController.unregisterCallback(Callback callback)
- */
+ /** Wrapper for MediaController.unregisterCallback(Callback callback) */
public void unregisterCallback(@NonNull Callback callback) {
mDelegate.unregisterCallback(callback);
}
- /**
- * Wrapper for MediaController.sendCommand(String command, Bundle args, ResultReceiver cb)
- */
- public void sendCommand(@NonNull String command, @Nullable Bundle args,
- @Nullable ResultReceiver cb) {
+ /** Wrapper for MediaController.sendCommand(String command, Bundle args, ResultReceiver cb) */
+ public void sendCommand(
+ @NonNull String command, @Nullable Bundle args, @Nullable ResultReceiver cb) {
mDelegate.sendCommand(command, args, cb);
}
- /**
- * Wrapper for MediaController.getPackageName()
- */
+ /** Wrapper for MediaController.getPackageName() */
public String getPackageName() {
return mDelegate.getPackageName();
}
- /**
- * Wrapper for MediaController.getTag()
- */
+ /** Wrapper for MediaController.getTag() */
public String getTag() {
return mDelegate.getTag();
}
- /**
- * Wrapper for MediaController.controlsSameSession(MediaController other)
- */
+ /** Wrapper for MediaController.controlsSameSession(MediaController other) */
public boolean controlsSameSession(MediaController other) {
return mDelegate.getSessionToken().equals(other.getWrappedInstance().getSessionToken());
}
- /**
- * Wrapper for MediaController.controlsSameSession(MediaController other)
- */
+ /** Wrapper for MediaController.controlsSameSession(MediaController other) */
public boolean controlsSameSession(android.media.session.MediaController other) {
return mDelegate.getSessionToken().equals(other.getSessionToken());
}
- /**
- * Wrapper for MediaController.equals(Object other)
- */
+ /** Wrapper for MediaController.equals(Object other) */
@Override
public boolean equals(Object o) {
if (o instanceof android.media.session.MediaController) {
@@ -240,175 +193,130 @@ public class MediaController {
return false;
}
- /**
- * Wrapper for MediaController.hashCode()
- */
+ /** Wrapper for MediaController.hashCode() */
@Override
public int hashCode() {
return Objects.hash(mDelegate);
}
- /**
- * Wrapper for MediaController.toString()
- */
+ /** Wrapper for MediaController.toString() */
@Override
public String toString() {
MediaMetadata data = getMetadata();
MediaDescription desc = (data == null) ? null : data.getDescription();
- return "MediaController (" + getPackageName() + "@" + Integer.toHexString(
- mDelegate.hashCode()) + ") " + desc;
+ return "MediaController ("
+ + getPackageName()
+ + "@"
+ + Integer.toHexString(mDelegate.hashCode())
+ + ") "
+ + desc;
}
- /**
- * Wrapper for MediaController.Callback
- */
+ /** Wrapper for MediaController.Callback */
public abstract static class Callback extends android.media.session.MediaController.Callback {}
- /**
- * Wrapper for MediaController.TransportControls
- */
+ /** Wrapper for MediaController.TransportControls */
public class TransportControls {
- /**
- * Wrapper for MediaController.TransportControls.prepare()
- */
+ /** Wrapper for MediaController.TransportControls.prepare() */
public void prepare() {
mTransportDelegate.prepare();
}
- /**
- * Wrapper for MediaController.TransportControls.prepareFromMediaId()
- */
+ /** Wrapper for MediaController.TransportControls.prepareFromMediaId() */
public void prepareFromMediaId(String mediaId, Bundle extras) {
mTransportDelegate.prepareFromMediaId(mediaId, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.prepareFromSearch()
- */
+ /** Wrapper for MediaController.TransportControls.prepareFromSearch() */
public void prepareFromSearch(String query, Bundle extras) {
mTransportDelegate.prepareFromSearch(query, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.prepareFromUri()
- */
+ /** Wrapper for MediaController.TransportControls.prepareFromUri() */
public void prepareFromUri(Uri uri, Bundle extras) {
mTransportDelegate.prepareFromUri(uri, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.play()
- */
+ /** Wrapper for MediaController.TransportControls.play() */
public void play() {
mTransportDelegate.play();
}
- /**
- * Wrapper for MediaController.TransportControls.playFromMediaId()
- */
+ /** Wrapper for MediaController.TransportControls.playFromMediaId() */
public void playFromMediaId(String mediaId, Bundle extras) {
mTransportDelegate.playFromMediaId(mediaId, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.playFromSearch()
- */
+ /** Wrapper for MediaController.TransportControls.playFromSearch() */
public void playFromSearch(String query, Bundle extras) {
mTransportDelegate.playFromSearch(query, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.playFromUri()
- */
+ /** Wrapper for MediaController.TransportControls.playFromUri() */
public void playFromUri(Uri uri, Bundle extras) {
mTransportDelegate.playFromUri(uri, extras);
}
- /**
- * Wrapper for MediaController.TransportControls.skipToQueueItem()
- */
+ /** Wrapper for MediaController.TransportControls.skipToQueueItem() */
public void skipToQueueItem(long id) {
mTransportDelegate.skipToQueueItem(id);
}
- /**
- * Wrapper for MediaController.TransportControls.pause()
- */
+ /** Wrapper for MediaController.TransportControls.pause() */
public void pause() {
mTransportDelegate.pause();
}
- /**
- * Wrapper for MediaController.TransportControls.stop()
- */
+ /** Wrapper for MediaController.TransportControls.stop() */
public void stop() {
mTransportDelegate.stop();
}
- /**
- * Wrapper for MediaController.TransportControls.seekTo()
- */
+ /** Wrapper for MediaController.TransportControls.seekTo() */
public void seekTo(long pos) {
mTransportDelegate.seekTo(pos);
}
- /**
- * Wrapper for MediaController.TransportControls.fastForward()
- */
+ /** Wrapper for MediaController.TransportControls.fastForward() */
public void fastForward() {
mTransportDelegate.fastForward();
}
- /**
- * Wrapper for MediaController.TransportControls.skipToNext()
- */
+ /** Wrapper for MediaController.TransportControls.skipToNext() */
public void skipToNext() {
mTransportDelegate.skipToNext();
}
- /**
- * Wrapper for MediaController.TransportControls.rewind()
- */
+ /** Wrapper for MediaController.TransportControls.rewind() */
public void rewind() {
mTransportDelegate.rewind();
}
- /**
- * Wrapper for MediaController.TransportControls.skipToPrevious()
- */
+ /** Wrapper for MediaController.TransportControls.skipToPrevious() */
public void skipToPrevious() {
mTransportDelegate.skipToPrevious();
}
- /**
- * Wrapper for MediaController.TransportControls.setRating()
- */
+ /** Wrapper for MediaController.TransportControls.setRating() */
public void setRating(Rating rating) {
mTransportDelegate.setRating(rating);
}
- /**
- * Wrapper for MediaController.TransportControls.setPlaybackSpeed(float speed)
- */
+ /** Wrapper for MediaController.TransportControls.setPlaybackSpeed(float speed) */
public void setPlaybackSpeed(float speed) {
mTransportDelegate.setPlaybackSpeed(speed);
}
- /**
- * Wrapper for MediaController.TransportControls.sendCustomAction()
- */
- public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
- @Nullable Bundle args) {
+ /** Wrapper for MediaController.TransportControls.sendCustomAction() */
+ public void sendCustomAction(
+ @NonNull PlaybackState.CustomAction customAction, @Nullable Bundle args) {
mTransportDelegate.sendCustomAction(customAction, args);
}
- /**
- * Wrapper for MediaController.TransportControls.sendCustomAction()
- */
+ /** Wrapper for MediaController.TransportControls.sendCustomAction() */
public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
mTransportDelegate.sendCustomAction(action, args);
}
}
}
-
diff --git a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
index 5784ee227b74a4de87549768f934567b9107d0f2..cb2798bdc32c218ac0cb1970825317707cee2e7b 100644
--- a/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
+++ b/android/app/src/com/android/bluetooth/audio_util/mockable/MediaPlayerWrapperFactory.java
@@ -51,4 +51,3 @@ public final class MediaPlayerWrapperFactory {
sInjectedWrapper = wrapper;
}
}
-
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
index e495c4a06322e02cfe76338e8291176d0c8a7e6d..497b738bfd82f46a766505b639949109dc934d8f 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpBipObexServer.java
@@ -31,33 +31,32 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
-/**
- * A class responsible for handling requests from a specific client connection
- */
+/** A class responsible for handling requests from a specific client connection */
public class AvrcpBipObexServer extends ServerRequestHandler {
private static final String TAG = AvrcpBipObexServer.class.getSimpleName();
private final AvrcpCoverArtService mAvrcpCoverArtService;
// AVRCP Controller BIP Image Initiator/Cover Art UUID - AVRCP 1.6 Section 5.14.2.1
- private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] {
- (byte) 0x71,
- (byte) 0x63,
- (byte) 0xDD,
- (byte) 0x54,
- (byte) 0x4A,
- (byte) 0x7E,
- (byte) 0x11,
- (byte) 0xE2,
- (byte) 0xB4,
- (byte) 0x7C,
- (byte) 0x00,
- (byte) 0x50,
- (byte) 0xC2,
- (byte) 0x49,
- (byte) 0x00,
- (byte) 0x48
- };
+ private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART =
+ new byte[] {
+ (byte) 0x71,
+ (byte) 0x63,
+ (byte) 0xDD,
+ (byte) 0x54,
+ (byte) 0x4A,
+ (byte) 0x7E,
+ (byte) 0x11,
+ (byte) 0xE2,
+ (byte) 0xB4,
+ (byte) 0x7C,
+ (byte) 0x00,
+ (byte) 0x50,
+ (byte) 0xC2,
+ (byte) 0x49,
+ (byte) 0x00,
+ (byte) 0x48
+ };
private static final String TYPE_GET_LINKED_THUMBNAIL = "x-bt/img-thm";
private static final String TYPE_GET_IMAGE_PROPERTIES = "x-bt/img-properties";
@@ -68,22 +67,15 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
private final Callback mCallback;
- /**
- * A set of callbacks to notify the creator of important AVRCP BIP events.
- */
+ /** A set of callbacks to notify the creator of important AVRCP BIP events. */
public interface Callback {
- /**
- * Receive a notification when this server session connects to a device
- */
+ /** Receive a notification when this server session connects to a device */
void onConnected();
- /**
- * Receive a notification when this server session disconnects with a device
- */
+ /** Receive a notification when this server session disconnects with a device */
void onDisconnected();
- /**
- * Receive a notification when this server session closes a connection with a device
- */
+
+ /** Receive a notification when this server session closes a connection with a device */
void onClose();
}
@@ -164,8 +156,8 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
}
@Override
- public int onSetPath(final HeaderSet request, HeaderSet reply, final boolean backup,
- final boolean create) {
+ public int onSetPath(
+ final HeaderSet request, HeaderSet reply, final boolean backup, final boolean create) {
return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
}
@@ -180,9 +172,9 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
/**
* Determine if a given image handle is valid in format
*
- * An image handle a 9 character string of numbers 0-9 only. Anything else is invalid. This is
- * defined in section 4.4.4 (Image Handles) of the BIP specification, which is inherited by the
- * AVRCP specification.
+ * An image handle a 9 character string of numbers 0-9 only. Anything else is invalid. This
+ * is defined in section 4.4.4 (Image Handles) of the BIP specification, which is inherited by
+ * the AVRCP specification.
*
* @return True if the image handle is valid, false otherwise.
*/
@@ -195,7 +187,7 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
return true;
}
- private int handleGetImageThumbnail(Operation op)throws IOException {
+ private int handleGetImageThumbnail(Operation op) throws IOException {
HeaderSet request = op.getReceivedHeader();
String imageHandle = (String) request.getHeader(HEADER_ID_IMG_HANDLE);
@@ -312,9 +304,7 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
return sendResponse(op, replyHeaders, imageBytes);
}
- /**
- * Send a response to the given operation using the given headers and bytes.
- */
+ /** Send a response to the given operation using the given headers and bytes. */
private int sendResponse(Operation op, HeaderSet replyHeaders, byte[] bytes) {
if (op != null && bytes != null && replyHeaders != null) {
OutputStream outStream = null;
@@ -337,7 +327,8 @@ public class AvrcpBipObexServer extends ServerRequestHandler {
if (outStream != null) {
try {
outStream.close();
- } catch (IOException e) { }
+ } catch (IOException e) {
+ }
}
}
// If we didn't write everything then send the error code
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
index 867706d309b89cfcfa0057ea60b626f27b10ee53..c2db89ba19da0602a8db77fd36ba598c4589e269 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtService.java
@@ -33,8 +33,8 @@ import java.util.HashMap;
/**
* The AVRCP Cover Art Service
*
- * This service handles allocation of image handles and storage of images. It also owns the
- * BIP OBEX server that handles requests to get AVRCP cover artwork.
+ *
This service handles allocation of image handles and storage of images. It also owns the BIP
+ * OBEX server that handles requests to get AVRCP cover artwork.
*/
public class AvrcpCoverArtService {
private static final String TAG = AvrcpCoverArtService.class.getSimpleName();
@@ -42,8 +42,8 @@ public class AvrcpCoverArtService {
private static final int COVER_ART_STORAGE_MAX_ITEMS = 32;
/**
- * Limiting transmit packet size because some carkits are disconnected if
- * AVRCP Cover Art OBEX packet size exceed 1024 bytes.
+ * Limiting transmit packet size because some carkits are disconnected if AVRCP Cover Art OBEX
+ * packet size exceed 1024 bytes.
*/
private static final int MAX_TRANSMIT_PACKET_SIZE = 1024;
@@ -71,7 +71,7 @@ public class AvrcpCoverArtService {
/**
* Start the AVRCP Cover Art Service.
*
- * This will start up a BIP OBEX server and record the l2cap psm in the SDP record, and begin
+ *
This will start up a BIP OBEX server and record the l2cap psm in the SDP record, and begin
* accepting connections.
*/
public boolean start() {
@@ -87,7 +87,7 @@ public class AvrcpCoverArtService {
/**
* Stop the AVRCP Cover Art Service.
*
- * Tear down existing connections, remove ourselved from the SDP record.
+ *
Tear down existing connections, remove ourselved from the SDP record.
*/
public boolean stop() {
debug("Stopping service");
@@ -142,35 +142,27 @@ public class AvrcpCoverArtService {
}
}
- /**
- * Store an image with the service and gets the image handle it's associated with.
- */
+ /** Store an image with the service and gets the image handle it's associated with. */
public String storeImage(Image image) {
debug("storeImage(image='" + image + "')");
if (image == null || image.getImage() == null) return null;
return mStorage.storeImage(new CoverArt(image));
}
- /**
- * Get the image stored at the given image handle, if it exists
- */
+ /** Get the image stored at the given image handle, if it exists */
public CoverArt getImage(String imageHandle) {
debug("getImage(" + imageHandle + ")");
return mStorage.getImage(imageHandle);
}
- /**
- * Add a BIP L2CAP PSM to the AVRCP Target SDP Record
- */
+ /** Add a BIP L2CAP PSM to the AVRCP Target SDP Record */
private void registerBipServer(int psm) {
debug("Add our PSM (" + psm + ") to the AVRCP Target SDP record");
mNativeInterface.registerBipServer(psm);
return;
}
- /**
- * Remove any BIP L2CAP PSM from the AVRCP Target SDP Record
- */
+ /** Remove any BIP L2CAP PSM from the AVRCP Target SDP Record */
private void unregisterBipServer() {
debug("Remove the PSM remove the AVRCP Target SDP record");
mNativeInterface.unregisterBipServer();
@@ -180,8 +172,8 @@ public class AvrcpCoverArtService {
/**
* Connect a device with the server
*
- * Since the server cannot explicitly make clients connect, this function is internal only and
- * provides a place for us to do required book keeping when we've decided to accept a client
+ *
Since the server cannot explicitly make clients connect, this function is internal only
+ * and provides a place for us to do required book keeping when we've decided to accept a client
*/
private boolean connect(BluetoothDevice device, BluetoothSocket socket) {
debug("Connect '" + device + "'");
@@ -210,9 +202,11 @@ public class AvrcpCoverArtService {
disconnect(device);
}
});
- BluetoothObexTransport transport = new BluetoothObexTransport(socket,
- MAX_TRANSMIT_PACKET_SIZE,
- BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED);
+ BluetoothObexTransport transport =
+ new BluetoothObexTransport(
+ socket,
+ MAX_TRANSMIT_PACKET_SIZE,
+ BluetoothObexTransport.PACKET_SIZE_UNSPECIFIED);
transport.setConnectionForCoverArt(true);
try {
ServerSession session = new ServerSession(transport, s, null);
@@ -225,9 +219,7 @@ public class AvrcpCoverArtService {
}
}
- /**
- * Explicitly disconnect a device from our BIP server if its connected.
- */
+ /** Explicitly disconnect a device from our BIP server if its connected. */
public void disconnect(BluetoothDevice device) {
debug("disconnect '" + device + "'");
// Closing the server session closes the underlying transport, which closes the underlying
@@ -245,7 +237,7 @@ public class AvrcpCoverArtService {
/**
* A Socket Acceptor to handle incoming connections to our BIP Server.
*
- * If we are accepting connections and the device is permitted, then this class will create a
+ *
If we are accepting connections and the device is permitted, then this class will create a
* session with our AvrcpBipObexServer.
*/
private class SocketAcceptor implements IObexConnectionHandler {
@@ -269,9 +261,7 @@ public class AvrcpCoverArtService {
}
}
- /**
- * Dump useful debug information about this service to a string
- */
+ /** Dump useful debug information about this service to a string */
public void dump(StringBuilder sb) {
int psm = getL2capPsm();
sb.append("AvrcpCoverArtService:");
@@ -283,16 +273,12 @@ public class AvrcpCoverArtService {
sb.append("\n");
}
- /**
- * Print a message to DEBUG if debug output is enabled
- */
+ /** Print a message to DEBUG if debug output is enabled */
private void debug(String msg) {
Log.d(TAG, msg);
}
- /**
- * Print a message to ERROR
- */
+ /** Print a message to ERROR */
private void error(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
index 3348da981fe5f000168fdd515001ca4550870c96..9c53bc50ffe164c903a2118fee3c933ce683c86b 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpCoverArtStorage.java
@@ -22,9 +22,7 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
-/**
- * A class abstracting the storage method of cover art images
- */
+/** A class abstracting the storage method of cover art images */
final class AvrcpCoverArtStorage {
private static final String TAG = AvrcpCoverArtStorage.class.getSimpleName();
@@ -36,16 +34,12 @@ final class AvrcpCoverArtStorage {
private final Map mImageHandles;
private final Map mImages;
- /**
- * Make an image storage object with no bounds on the amount of images it can store
- */
+ /** Make an image storage object with no bounds on the amount of images it can store */
AvrcpCoverArtStorage() {
this(0);
}
- /**
- * Make an image storage object with a bound on the amount of images it can store
- */
+ /** Make an image storage object with a bound on the amount of images it can store */
AvrcpCoverArtStorage(int maxSize) {
if (maxSize < 0) {
throw new IllegalArgumentException("maxSize < 0");
@@ -60,9 +54,7 @@ final class AvrcpCoverArtStorage {
mImages = new LinkedHashMap(0, 0.75f /* default load factor */, true);
}
- /**
- * Store an image and get the image handle it's been associated with.
- */
+ /** Store an image and get the image handle it's been associated with. */
public String storeImage(CoverArt coverArt) {
debug("storeImage(CoverArt='" + coverArt + "')");
if (coverArt == null || coverArt.getImage() == null) {
@@ -103,9 +95,7 @@ final class AvrcpCoverArtStorage {
return imageHandle;
}
- /**
- * Get the image stored at the given image handle, if it exists
- */
+ /** Get the image stored at the given image handle, if it exists */
public CoverArt getImage(String imageHandle) {
debug("getImage(" + imageHandle + ")");
if (imageHandle == null) return null;
@@ -116,9 +106,7 @@ final class AvrcpCoverArtStorage {
}
}
- /**
- * Clear out all stored images and image handles
- */
+ /** Clear out all stored images and image handles */
public void clear() {
synchronized (mImagesLock) {
mImages.clear();
@@ -147,8 +135,8 @@ final class AvrcpCoverArtStorage {
/**
* Get the next available image handle value if one is available.
*
- * Values are integers in the domain [0, 9999999], represented as zero-padded strings. Getting
- * an image handle assumes you will use it.
+ * Values are integers in the domain [0, 9999999], represented as zero-padded strings.
+ * Getting an image handle assumes you will use it.
*/
private String getNextImageHandle() {
synchronized (mHandlesLock) {
@@ -193,16 +181,12 @@ final class AvrcpCoverArtStorage {
sb.append("\n\tImage bytes: " + bytes);
}
- /**
- * Print a message to DEBUG if debug output is enabled
- */
+ /** Print a message to DEBUG if debug output is enabled */
private void debug(String msg) {
Log.d(TAG, msg);
}
- /**
- * Print a message to ERROR
- */
+ /** Print a message to ERROR */
private void error(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
index 0afdeacf808d8d4e1e2e17ebb8aec7392a48f144..448bb6001094a699cb0c3577712e78e9eb3d993c 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpNativeInterface.java
@@ -34,8 +34,7 @@ import java.util.List;
import java.util.Objects;
/**
- * Native Interface to communicate with the JNI layer. This class should never be passed null
- * data.
+ * Native Interface to communicate with the JNI layer. This class should never be passed null data.
*/
public class AvrcpNativeInterface {
private static final String TAG = AvrcpNativeInterface.class.getSimpleName();
@@ -49,8 +48,10 @@ public class AvrcpNativeInterface {
private AdapterService mAdapterService;
private AvrcpNativeInterface() {
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when AvrcpNativeInterface init");
+ mAdapterService =
+ Objects.requireNonNull(
+ AdapterService.getAdapterService(),
+ "AdapterService cannot be null when AvrcpNativeInterface init");
}
static AvrcpNativeInterface getInstance() {
@@ -175,15 +176,19 @@ public class AvrcpNativeInterface {
// anything internally. It just returns the number of items in the root folder.
void setBrowsedPlayer(int playerId) {
d("setBrowsedPlayer: playerId=" + playerId);
- mAvrcpService.getPlayerRoot(playerId, (a, b, c, d) ->
- setBrowsedPlayerResponse(a, b, c, d));
+ mAvrcpService.getPlayerRoot(playerId, (a, b, c, d) -> setBrowsedPlayerResponse(a, b, c, d));
}
void setBrowsedPlayerResponse(int playerId, boolean success, String rootId, int numItems) {
- d("setBrowsedPlayerResponse: playerId=" + playerId
- + " success=" + success
- + " rootId=" + rootId
- + " numItems=" + numItems);
+ d(
+ "setBrowsedPlayerResponse: playerId="
+ + playerId
+ + " success="
+ + success
+ + " rootId="
+ + rootId
+ + " numItems="
+ + numItems);
setBrowsedPlayerResponseNative(playerId, success, rootId, numItems);
}
@@ -198,16 +203,24 @@ public class AvrcpNativeInterface {
}
void sendMediaUpdate(boolean metadata, boolean playStatus, boolean queue) {
- d("sendMediaUpdate: metadata=" + metadata
- + " playStatus=" + playStatus
- + " queue=" + queue);
+ d(
+ "sendMediaUpdate: metadata="
+ + metadata
+ + " playStatus="
+ + playStatus
+ + " queue="
+ + queue);
sendMediaUpdateNative(metadata, playStatus, queue);
}
void sendFolderUpdate(boolean availablePlayers, boolean addressedPlayers, boolean uids) {
- d("sendFolderUpdate: availablePlayers=" + availablePlayers
- + " addressedPlayers=" + addressedPlayers
- + " uids=" + uids);
+ d(
+ "sendFolderUpdate: availablePlayers="
+ + availablePlayers
+ + " addressedPlayers="
+ + addressedPlayers
+ + " uids="
+ + uids);
sendFolderUpdateNative(availablePlayers, addressedPlayers, uids);
}
@@ -231,13 +244,15 @@ public class AvrcpNativeInterface {
}
void setActiveDevice(String bdaddr) {
- BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
+ BluetoothDevice device =
+ mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
d("setActiveDevice: device=" + device);
mAvrcpService.setActiveDevice(device);
}
void deviceConnected(String bdaddr, boolean absoluteVolume) {
- BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
+ BluetoothDevice device =
+ mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
d("deviceConnected: device=" + device + " absoluteVolume=" + absoluteVolume);
if (mAvrcpService == null) {
Log.w(TAG, "deviceConnected: AvrcpTargetService is null");
@@ -248,7 +263,8 @@ public class AvrcpNativeInterface {
}
void deviceDisconnected(String bdaddr) {
- BluetoothDevice device = mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
+ BluetoothDevice device =
+ mAdapterService.getDeviceFromByte(Utils.getBytesFromAddress(bdaddr));
d("deviceDisconnected: device=" + device);
if (mAvrcpService == null) {
Log.w(TAG, "deviceDisconnected: AvrcpTargetService is null");
@@ -307,8 +323,7 @@ public class AvrcpNativeInterface {
valuesArray = new byte[1];
valuesArray[0] = PlayerSettingsValues.STATE_DEFAULT_OFF;
}
- listPlayerSettingValuesResponseNative(
- settingRequest, valuesArray);
+ listPlayerSettingValuesResponseNative(settingRequest, valuesArray);
}
/** Request from remote current values for player settings. */
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
index 2c3096390ebe80e4199d7ce5ea6dfd1d187ed3a9..cbe855fbf0fbfcd52f1eb6071d540413444f5d36 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpTargetService.java
@@ -117,16 +117,21 @@ public class AvrcpTargetService extends ProfileService {
boolean state = !MediaPlayerWrapper.playstateEquals(mCurrentData.state, data.state);
boolean queue = !Objects.equals(mCurrentData.queue, data.queue);
- Log.d(TAG, "onMediaUpdated: track_changed=" + metadata
- + " state=" + state + " queue=" + queue);
+ Log.d(
+ TAG,
+ "onMediaUpdated: track_changed="
+ + metadata
+ + " state="
+ + state
+ + " queue="
+ + queue);
mCurrentData = data;
mNativeInterface.sendMediaUpdate(metadata, state, queue);
}
@Override
- public void run(boolean availablePlayers, boolean addressedPlayers,
- boolean uids) {
+ public void run(boolean availablePlayers, boolean addressedPlayers, boolean uids) {
if (mNativeInterface == null) return;
mNativeInterface.sendFolderUpdate(availablePlayers, addressedPlayers, uids);
@@ -403,7 +408,8 @@ public class AvrcpTargetService extends ProfileService {
/** Returns the current play status of the active player from {@link MediaPlayerList}. */
PlayStatus getPlayState() {
- return PlayStatus.fromPlaybackState(mMediaPlayerList.getCurrentPlayStatus(),
+ return PlayStatus.fromPlaybackState(
+ mMediaPlayerList.getCurrentPlayStatus(),
Long.parseLong(getCurrentSongInfo().duration));
}
diff --git a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
index 9a7786d671696931c4dd7bd04758f756394b7d4a..f96f68c29ed4194e94375b4ea5fff1603767c58d 100644
--- a/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
+++ b/android/app/src/com/android/bluetooth/avrcp/AvrcpVolumeManager.java
@@ -59,8 +59,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
private static final String VOLUME_MAP = "bluetooth_volume_map";
private static final String VOLUME_CHANGE_LOG_TITLE = "BTAudio Volume Events";
- @VisibleForTesting
- static final int AVRCP_MAX_VOL = 127;
+ @VisibleForTesting static final int AVRCP_MAX_VOL = 127;
private static final int STREAM_MUSIC = AudioManager.STREAM_MUSIC;
private static final int VOLUME_CHANGE_LOGGER_SIZE = 30;
private static int sDeviceMaxVolume = 0;
@@ -156,8 +155,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
// If absolute volume for the device is supported, set the volume for the device
if (mDeviceMap.get(device)) {
int avrcpVolume = systemToAvrcpVolume(savedVolume);
- mVolumeEventLogger.logd(TAG,
- "switchVolumeDevice: Updating device volume: avrcpVolume=" + avrcpVolume);
+ mVolumeEventLogger.logd(
+ TAG, "switchVolumeDevice: Updating device volume: avrcpVolume=" + avrcpVolume);
mNativeInterface.sendVolumeChanged(device, avrcpVolume);
}
}
@@ -168,8 +167,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
*
Fills {@code mVolumeMap} with content from {@link #getVolumeMap}, removing unbonded
* devices if necessary.
*/
- AvrcpVolumeManager(Context context, AudioManager audioManager,
- AvrcpNativeInterface nativeInterface) {
+ AvrcpVolumeManager(
+ Context context, AudioManager audioManager, AvrcpNativeInterface nativeInterface) {
mContext = context;
mAudioManager = audioManager;
mNativeInterface = nativeInterface;
@@ -207,8 +206,12 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
return;
}
SharedPreferences.Editor pref = getVolumeMap().edit();
- mVolumeEventLogger.logd(TAG, "storeVolume: Storing stream volume level for device "
- + device + " : " + storeVolume);
+ mVolumeEventLogger.logd(
+ TAG,
+ "storeVolume: Storing stream volume level for device "
+ + device
+ + " : "
+ + storeVolume);
mVolumeMap.put(device, storeVolume);
pref.putInt(device.getAddress(), storeVolume);
// Always use apply() since it is asynchronous, otherwise the call can hang waiting for
@@ -221,7 +224,7 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
* #storeVolumeForDevice(BluetoothDevice, int)} with {@code device}.
*/
synchronized void storeVolumeForDevice(@NonNull BluetoothDevice device) {
- int storeVolume = mAudioManager.getLastAudibleStreamVolume(STREAM_MUSIC);
+ int storeVolume = mAudioManager.getLastAudibleStreamVolume(STREAM_MUSIC);
storeVolumeForDevice(device, storeVolume);
}
@@ -234,8 +237,8 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
return;
}
SharedPreferences.Editor pref = getVolumeMap().edit();
- mVolumeEventLogger.logd(TAG,
- "RemoveStoredVolume: Remove stored stream volume level for device " + device);
+ mVolumeEventLogger.logd(
+ TAG, "RemoveStoredVolume: Remove stored stream volume level for device " + device);
mVolumeMap.remove(device);
pref.remove(device.getAddress());
// Always use apply() since it is asynchronous, otherwise the call can hang waiting for
@@ -273,14 +276,22 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
*/
void setVolume(@NonNull BluetoothDevice device, int avrcpVolume) {
int deviceVolume = avrcpToSystemVolume(avrcpVolume);
- mVolumeEventLogger.logd(TAG, "setVolume:"
- + " device=" + device
- + " avrcpVolume=" + avrcpVolume
- + " deviceVolume=" + deviceVolume
- + " sDeviceMaxVolume=" + sDeviceMaxVolume);
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, deviceVolume,
+ mVolumeEventLogger.logd(
+ TAG,
+ "setVolume:"
+ + " device="
+ + device
+ + " avrcpVolume="
+ + avrcpVolume
+ + " deviceVolume="
+ + deviceVolume
+ + " sDeviceMaxVolume="
+ + sDeviceMaxVolume);
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_MUSIC,
+ deviceVolume,
(deviceVolume != getVolume(device, -1) ? AudioManager.FLAG_SHOW_UI : 0)
- | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
+ | AudioManager.FLAG_BLUETOOTH_ABS_VOLUME);
storeVolumeForDevice(device);
}
@@ -297,11 +308,17 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
return;
}
int avrcpVolume = systemToAvrcpVolume(deviceVolume);
- mVolumeEventLogger.logd(TAG, "sendVolumeChanged:"
- + " device=" + device
- + " avrcpVolume=" + avrcpVolume
- + " deviceVolume=" + deviceVolume
- + " sDeviceMaxVolume=" + sDeviceMaxVolume);
+ mVolumeEventLogger.logd(
+ TAG,
+ "sendVolumeChanged:"
+ + " device="
+ + device
+ + " avrcpVolume="
+ + avrcpVolume
+ + " deviceVolume="
+ + deviceVolume
+ + " sDeviceMaxVolume="
+ + sDeviceMaxVolume);
mNativeInterface.sendVolumeChanged(device, avrcpVolume);
storeVolumeForDevice(device);
}
@@ -403,13 +420,15 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
sb.append(" mCurrentDevice: " + mCurrentDevice + "\n");
sb.append(" Current System Volume: " + mAudioManager.getStreamVolume(STREAM_MUSIC) + "\n");
sb.append(" Device Volume Memory Map:\n");
- sb.append(String.format(" %-17s : %-14s : %3s : %s\n",
- "Device Address", "Device Name", "Vol", "AbsVol"));
+ sb.append(
+ String.format(
+ " %-17s : %-14s : %3s : %s\n",
+ "Device Address", "Device Name", "Vol", "AbsVol"));
Map allKeys = getVolumeMap().getAll();
for (Map.Entry entry : allKeys.entrySet()) {
Object value = entry.getValue();
- BluetoothDevice d = BluetoothAdapter.getDefaultAdapter()
- .getRemoteDevice(entry.getKey());
+ BluetoothDevice d =
+ BluetoothAdapter.getDefaultAdapter().getRemoteDevice(entry.getKey());
String deviceName = d.getName();
if (deviceName == null) {
@@ -424,8 +443,10 @@ class AvrcpVolumeManager extends AudioDeviceCallback {
}
if (value instanceof Integer) {
- sb.append(String.format(" %-17s : %-14s : %3d : %s\n",
- d.getAddress(), deviceName, (Integer) value, absoluteVolume));
+ sb.append(
+ String.format(
+ " %-17s : %-14s : %3d : %s\n",
+ d.getAddress(), deviceName, (Integer) value, absoluteVolume));
}
}
diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java
index a0d90d77853659d7240de41a32ff80fb0932cf73..4fe5c89a17bf49640f5ca5a0ac88901fbb399649 100644
--- a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java
+++ b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpPassthrough.java
@@ -126,7 +126,7 @@ public class AvrcpPassthrough {
case BluetoothAvrcp.PASSTHROUGH_ID_ANGLE:
case BluetoothAvrcp.PASSTHROUGH_ID_SUBPICT:
case BluetoothAvrcp.PASSTHROUGH_ID_VENDOR:
- // Fallthrough for all unknown key mappings
+ // Fallthrough for all unknown key mappings
default:
return KeyEvent.KEYCODE_UNKNOWN;
}
diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java
index 67378f843b817c1fbd04a1fd32a7259e5805400e..a3ab9192e9a75d3d34e7ae8c61362821ab355d06 100644
--- a/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java
+++ b/android/app/src/com/android/bluetooth/avrcp/helpers/AvrcpVersion.java
@@ -18,9 +18,7 @@ package com.android.bluetooth.avrcp;
import android.os.SystemProperties;
-/**
- * A class to represent an AVRCP version
- */
+/** A class to represent an AVRCP version */
final class AvrcpVersion {
public static final AvrcpVersion AVRCP_VERSION_1_3 = new AvrcpVersion(1, 3);
public static final AvrcpVersion AVRCP_VERSION_1_4 = new AvrcpVersion(1, 4);
diff --git a/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java b/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java
index d20da981661ac1fbe975e929c2d26717550545c5..0a38467f16603bbf258c837f7ac632a28cceea50 100644
--- a/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java
+++ b/android/app/src/com/android/bluetooth/avrcp/helpers/CoverArt.java
@@ -33,10 +33,10 @@ import java.security.NoSuchAlgorithmException;
/**
* An object to represent a piece of cover artwork/
*
- * This object abstracts away the actual storage method and provides a means for others to
+ * This object abstracts away the actual storage method and provides a means for others to
* understand available formats and get the underlying image in a particular format.
*
- * All return values are ready to use by a BIP server.
+ *
All return values are ready to use by a BIP server.
*/
public class CoverArt {
private static final String TAG = CoverArt.class.getSimpleName();
@@ -45,9 +45,7 @@ public class CoverArt {
private String mImageHandle = null;
private Bitmap mImage = null;
- /**
- * Create a CoverArt object from an audio_util Image abstraction
- */
+ /** Create a CoverArt object from an audio_util Image abstraction */
CoverArt(Image image) {
// Create a scaled version of the image for now, as consumers don't need
// anything larger than this at the moment. Also makes each image gathered
@@ -58,7 +56,7 @@ public class CoverArt {
/**
* Get the image handle that has been associated with this image.
*
- * If this returns null then you will fail to generate image properties
+ *
If this returns null then you will fail to generate image properties
*/
public String getImageHandle() {
return mImageHandle;
@@ -67,26 +65,22 @@ public class CoverArt {
/**
* Set the image handle that has been associated with this image.
*
- * This is required to generate image properties
+ *
This is required to generate image properties
*/
public void setImageHandle(String handle) {
mImageHandle = handle;
}
- /**
- * Covert a Bitmap to a byte array with an image format without lossy compression
- */
+ /** Covert a Bitmap to a byte array with an image format without lossy compression */
private byte[] toByteArray(Bitmap bitmap) {
if (bitmap == null) return null;
- ByteArrayOutputStream buffer = new ByteArrayOutputStream(
- bitmap.getWidth() * bitmap.getHeight());
+ ByteArrayOutputStream buffer =
+ new ByteArrayOutputStream(bitmap.getWidth() * bitmap.getHeight());
bitmap.compress(Bitmap.CompressFormat.PNG, 100, buffer);
return buffer.toByteArray();
}
- /**
- * Get a hash code of this CoverArt image
- */
+ /** Get a hash code of this CoverArt image */
public String getImageHash() {
byte[] image = toByteArray(mImage);
if (image == null) return null;
@@ -107,9 +101,7 @@ public class CoverArt {
return hash;
}
- /**
- * Get the cover artwork image bytes in the native format
- */
+ /** Get the cover artwork image bytes in the native format */
public byte[] getImage() {
debug("GetImage(native)");
if (mImage == null) return null;
@@ -118,9 +110,7 @@ public class CoverArt {
return outputStream.toByteArray();
}
- /**
- * Get the cover artwork image bytes in the given encoding and pixel size
- */
+ /** Get the cover artwork image bytes in the given encoding and pixel size */
public byte[] getImage(BipImageDescriptor descriptor) {
debug("GetImage(descriptor=" + descriptor);
if (mImage == null) return null;
@@ -135,9 +125,7 @@ public class CoverArt {
return outputStream.toByteArray();
}
- /**
- * Determine if a given image descriptor is valid
- */
+ /** Determine if a given image descriptor is valid */
private boolean isDescriptorValid(BipImageDescriptor descriptor) {
debug("isDescriptorValid(descriptor=" + descriptor + ")");
if (descriptor == null) return false;
@@ -151,9 +139,7 @@ public class CoverArt {
return false;
}
- /**
- * Get the cover artwork image bytes as a 200 x 200 JPEG thumbnail
- */
+ /** Get the cover artwork image bytes as a 200 x 200 JPEG thumbnail */
public byte[] getThumbnail() {
debug("GetImageThumbnail()");
if (mImage == null) return null;
@@ -162,9 +148,7 @@ public class CoverArt {
return outputStream.toByteArray();
}
- /**
- * Get the set of image properties that the cover artwork can be turned into
- */
+ /** Get the set of image properties that the cover artwork can be turned into */
public BipImageProperties getImageProperties() {
debug("GetImageProperties()");
if (mImage == null) {
@@ -187,9 +171,7 @@ public class CoverArt {
return properties;
}
- /**
- * Get the storage size of this image in bytes
- */
+ /** Get the storage size of this image in bytes */
public int size() {
return mImage != null ? mImage.getAllocationByteCount() : 0;
}
@@ -199,16 +181,12 @@ public class CoverArt {
return "{handle=" + mImageHandle + ", size=" + size() + " }";
}
- /**
- * Print a message to DEBUG if debug output is enabled
- */
+ /** Print a message to DEBUG if debug output is enabled */
private void debug(String msg) {
Log.d(TAG, msg);
}
- /**
- * Print a message to ERROR
- */
+ /** Print a message to ERROR */
private void error(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java
index 3b54b09a3d8921cecb48a55e6f8b1f8ac6e9df6e..dede3928babf3efa8c6e9978caa70af6f3bde2b1 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpBipClient.java
@@ -38,34 +38,35 @@ import java.lang.ref.WeakReference;
* A client to a remote device's BIP Image Pull Server, as defined by a PSM passed in at
* construction time.
*
- * Once the client connection is established you can use this client to get image properties and
+ *
Once the client connection is established you can use this client to get image properties and
* download images. The connection to the server is held open to service multiple requests.
*
- * Client is good for one connection lifecycle. Please call shutdown() to clean up safely. Once a
+ *
Client is good for one connection lifecycle. Please call shutdown() to clean up safely. Once a
* disconnection has occurred, please create a new client.
*/
public class AvrcpBipClient {
private static final String TAG = AvrcpBipClient.class.getSimpleName();
// AVRCP Controller BIP Image Initiator/Cover Art UUID - AVRCP 1.6 Section 5.14.2.1
- private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART = new byte[] {
- (byte) 0x71,
- (byte) 0x63,
- (byte) 0xDD,
- (byte) 0x54,
- (byte) 0x4A,
- (byte) 0x7E,
- (byte) 0x11,
- (byte) 0xE2,
- (byte) 0xB4,
- (byte) 0x7C,
- (byte) 0x00,
- (byte) 0x50,
- (byte) 0xC2,
- (byte) 0x49,
- (byte) 0x00,
- (byte) 0x48
- };
+ private static final byte[] BLUETOOTH_UUID_AVRCP_COVER_ART =
+ new byte[] {
+ (byte) 0x71,
+ (byte) 0x63,
+ (byte) 0xDD,
+ (byte) 0x54,
+ (byte) 0x4A,
+ (byte) 0x7E,
+ (byte) 0x11,
+ (byte) 0xE2,
+ (byte) 0xB4,
+ (byte) 0x7C,
+ (byte) 0x00,
+ (byte) 0x50,
+ (byte) 0xC2,
+ (byte) 0x49,
+ (byte) 0x00,
+ (byte) 0x48
+ };
private static final int CONNECT = 0;
private static final int DISCONNECT = 1;
@@ -85,9 +86,7 @@ public class AvrcpBipClient {
private final Callback mCallback;
- /**
- * Callback object used to be notified of when a request has been completed.
- */
+ /** Callback object used to be notified of when a request has been completed. */
interface Callback {
/**
@@ -104,8 +103,8 @@ public class AvrcpBipClient {
* @param status A status code to indicate a success or error
* @param properties The BipImageProperties object returned if successful, null otherwise
*/
- void onGetImagePropertiesComplete(int status, String imageHandle,
- BipImageProperties properties);
+ void onGetImagePropertiesComplete(
+ int status, String imageHandle, BipImageProperties properties);
/**
* Notify of a get image operation completing
@@ -141,9 +140,7 @@ public class AvrcpBipClient {
mHandler = new AvrcpBipClientHandler(looper, this);
}
- /**
- * Refreshes this client's OBEX session
- */
+ /** Refreshes this client's OBEX session */
public void refreshSession() {
debug("Refresh client session");
if (!isConnected()) {
@@ -159,9 +156,7 @@ public class AvrcpBipClient {
}
}
- /**
- * Safely disconnects the client from the server
- */
+ /** Safely disconnects the client from the server */
public void shutdown() {
debug("Shutdown client");
try {
@@ -201,11 +196,9 @@ public class AvrcpBipClient {
return mPsm;
}
- /**
- * Retrieve the image properties associated with the given imageHandle
- */
+ /** Retrieve the image properties associated with the given imageHandle */
public boolean getImageProperties(String imageHandle) {
- RequestGetImageProperties request = new RequestGetImageProperties(imageHandle);
+ RequestGetImageProperties request = new RequestGetImageProperties(imageHandle);
boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request));
if (!status) {
error("Adding messages failed, connection state: " + isConnected());
@@ -214,11 +207,9 @@ public class AvrcpBipClient {
return true;
}
- /**
- * Download the image object associated with the given imageHandle
- */
+ /** Download the image object associated with the given imageHandle */
public boolean getImage(String imageHandle, BipImageDescriptor descriptor) {
- RequestGetImage request = new RequestGetImage(imageHandle, descriptor);
+ RequestGetImage request = new RequestGetImage(imageHandle, descriptor);
boolean status = mHandler.sendMessage(mHandler.obtainMessage(REQUEST, request));
if (!status) {
error("Adding messages failed, connection state: " + isConnected());
@@ -227,9 +218,7 @@ public class AvrcpBipClient {
return true;
}
- /**
- * Update our client's connection state and notify of the new status
- */
+ /** Update our client's connection state and notify of the new status */
@VisibleForTesting
void setConnectionState(int state) {
int oldState = -1;
@@ -237,7 +226,7 @@ public class AvrcpBipClient {
oldState = mState;
mState = state;
}
- if (oldState != state) {
+ if (oldState != state) {
mCallback.onConnectionStateChanged(oldState, mState);
}
}
@@ -247,9 +236,7 @@ public class AvrcpBipClient {
mHandler.obtainMessage(CONNECT).sendToTarget();
}
- /**
- * Connects to the remote device's BIP Image Pull server
- */
+ /** Connects to the remote device's BIP Image Pull server */
private synchronized void connect() {
debug("Connect using psm: " + mPsm);
if (isConnected()) {
@@ -284,9 +271,7 @@ public class AvrcpBipClient {
}
}
- /**
- * Disconnect and reconnect the OBEX session.
- */
+ /** Disconnect and reconnect the OBEX session. */
private synchronized void refreshObexSession() {
if (mSession == null) return;
@@ -359,8 +344,7 @@ public class AvrcpBipClient {
private void executeRequest(BipRequest request) {
if (!isConnected()) {
- error("Cannot execute request " + request.toString()
- + ", we're not connected");
+ error("Cannot execute request " + request.toString() + ", we're not connected");
notifyCaller(request);
return;
}
@@ -397,9 +381,7 @@ public class AvrcpBipClient {
}
}
- /**
- * Handles this AVRCP BIP Image Pull Client's requests
- */
+ /** Handles this AVRCP BIP Image Pull Client's requests */
private static class AvrcpBipClientHandler extends Handler {
WeakReference mInst;
@@ -457,27 +439,27 @@ public class AvrcpBipClient {
@Override
public String toString() {
- return "";
+ return "";
}
- /**
- * Print to debug if debug is enabled for this class
- */
+ /** Print to debug if debug is enabled for this class */
private void debug(String msg) {
Log.d(TAG, "[" + mDevice + "] " + msg);
}
- /**
- * Print to warn
- */
+ /** Print to warn */
private void warn(String msg) {
Log.w(TAG, "[" + mDevice + "] " + msg);
}
- /**
- * Print to error
- */
+ /** Print to error */
private void error(String msg) {
Log.e(TAG, "[" + mDevice + "] " + msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
index 8330f626c225ed09cbcb730c10e6d0f506a2fab3..e0dd4f9632f96ead015c533bec9e0d69613ca4f7 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerService.java
@@ -49,19 +49,16 @@ import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
-/**
- * Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application.
- */
+/** Provides Bluetooth AVRCP Controller profile, as a service in the Bluetooth application. */
public class AvrcpControllerService extends ProfileService {
static final String TAG = AvrcpControllerService.class.getSimpleName();
static final int MAXIMUM_CONNECTED_DEVICES = 5;
- /**
- * Owned Components
- */
+ /** Owned Components */
private static final String ON_ERROR_SETTINGS_ACTIVITY =
BluetoothPrefs.class.getCanonicalName();
+
private static final String COVER_ART_PROVIDER = AvrcpCoverArtProvider.class.getCanonicalName();
/* Folder/Media Item scopes.
@@ -115,18 +112,24 @@ public class AvrcpControllerService extends ProfileService {
private class ImageDownloadCallback implements AvrcpCoverArtManager.Callback {
@Override
- public void onImageDownloadComplete(BluetoothDevice device,
- AvrcpCoverArtManager.DownloadEvent event) {
- Log.d(TAG, "Image downloaded [device: " + device + ", uuid: " + event.getUuid()
- + ", uri: " + event.getUri());
+ public void onImageDownloadComplete(
+ BluetoothDevice device, AvrcpCoverArtManager.DownloadEvent event) {
+ Log.d(
+ TAG,
+ "Image downloaded [device: "
+ + device
+ + ", uuid: "
+ + event.getUuid()
+ + ", uri: "
+ + event.getUri());
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine == null) {
Log.e(TAG, "No state machine found for device " + device);
mCoverArtManager.removeImage(device, event.getUuid());
return;
}
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_IMAGE_DOWNLOADED,
- event);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_IMAGE_DOWNLOADED, event);
}
}
@@ -195,18 +198,14 @@ public class AvrcpControllerService extends ProfileService {
sService = service;
}
- /**
- * Get the current active device
- */
+ /** Get the current active device */
public BluetoothDevice getActiveDevice() {
synchronized (mActiveDeviceLock) {
return mActiveDevice;
}
}
- /**
- * Set the current active device, notify devices of activity status
- */
+ /** Set the current active device, notify devices of activity status */
@VisibleForTesting
boolean setActiveDevice(BluetoothDevice device) {
Log.d(TAG, "setActiveDevice(device=" + device + ")");
@@ -250,7 +249,6 @@ public class AvrcpControllerService extends ProfileService {
return false;
}
-
protected void getCurrentMetadataIfNoCoverArt(BluetoothDevice device) {
if (device == null) return;
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
@@ -316,10 +314,17 @@ public class AvrcpControllerService extends ProfileService {
}
}
- Log.d(TAG, "getContents(" + parentMediaId + "): "
- + (requestedNode == null
- ? "Failed to find node"
- : "node=" + requestedNode + ", device=" + requestedNode.getDevice()));
+ Log.d(
+ TAG,
+ "getContents("
+ + parentMediaId
+ + "): "
+ + (requestedNode == null
+ ? "Failed to find node"
+ : "node="
+ + requestedNode
+ + ", device="
+ + requestedNode.getDevice()));
// If we don't find a node in the tree then do not have any way to browse for the contents.
// Return an empty list instead.
@@ -346,18 +351,21 @@ public class AvrcpControllerService extends ProfileService {
*/
return new BrowseResult(contents, BrowseResult.DOWNLOAD_PENDING);
}
- Log.d(TAG, "getContents(" + parentMediaId + "): return node, contents="
- + requestedNode.getContents());
+ Log.d(
+ TAG,
+ "getContents("
+ + parentMediaId
+ + "): return node, contents="
+ + requestedNode.getContents());
return new BrowseResult(contents, BrowseResult.SUCCESS);
}
-
@Override
protected IProfileServiceBinder initBinder() {
return new AvrcpControllerServiceBinder(this);
}
- //Binder object: Must be static class or memory leak may occur
+ // Binder object: Must be static class or memory leak may occur
@VisibleForTesting
static class AvrcpControllerServiceBinder extends IBluetoothAvrcpController.Stub
implements IProfileServiceBinder {
@@ -537,8 +545,8 @@ public class AvrcpControllerService extends ProfileService {
item.setCoverArtUuid(mCoverArtManager.getUuidForHandle(device, handle));
}
}
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED,
- item);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_TRACK_CHANGED, item);
}
}
@@ -550,7 +558,8 @@ public class AvrcpControllerService extends ProfileService {
if (stateMachine != null) {
stateMachine.sendMessage(
AvrcpControllerStateMachine.MESSAGE_PROCESS_PLAY_POS_CHANGED,
- songLen, currSongPosition);
+ songLen,
+ currSongPosition);
}
}
@@ -596,7 +605,8 @@ public class AvrcpControllerService extends ProfileService {
void onAvailablePlayerChanged(BluetoothDevice device) {
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine != null) {
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED);
}
}
@@ -617,16 +627,16 @@ public class AvrcpControllerService extends ProfileService {
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine != null) {
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS,
- itemsList);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_FOLDER_ITEMS, itemsList);
}
}
void handleGetPlayerItemsRsp(BluetoothDevice device, List itemsList) {
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine != null) {
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS,
- itemsList);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_GET_PLAYER_ITEMS, itemsList);
}
}
@@ -634,8 +644,8 @@ public class AvrcpControllerService extends ProfileService {
void handleChangeFolderRsp(BluetoothDevice device, int count) {
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine != null) {
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_FOLDER_PATH,
- count);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_FOLDER_PATH, count);
}
}
@@ -643,8 +653,8 @@ public class AvrcpControllerService extends ProfileService {
void handleSetBrowsedPlayerRsp(BluetoothDevice device, int items, int depth) {
AvrcpControllerStateMachine stateMachine = getStateMachine(device);
if (stateMachine != null) {
- stateMachine.sendMessage(AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_BROWSED_PLAYER,
- items, depth);
+ stateMachine.sendMessage(
+ AvrcpControllerStateMachine.MESSAGE_PROCESS_SET_BROWSED_PLAYER, items, depth);
}
}
@@ -697,9 +707,7 @@ public class AvrcpControllerService extends ProfileService {
return true;
}
- /**
- * Remove state machine from device map once it is no longer needed.
- */
+ /** Remove state machine from device map once it is no longer needed. */
public void removeStateMachine(AvrcpControllerStateMachine stateMachine) {
if (stateMachine == null) {
return;
@@ -713,7 +721,7 @@ public class AvrcpControllerService extends ProfileService {
}
public List getConnectedDevices() {
- return getDevicesMatchingConnectionStates(new int[]{BluetoothAdapter.STATE_CONNECTED});
+ return getDevicesMatchingConnectionStates(new int[] {BluetoothAdapter.STATE_CONNECTED});
}
protected AvrcpControllerStateMachine getStateMachine(BluetoothDevice device) {
@@ -764,14 +772,19 @@ public class AvrcpControllerService extends ProfileService {
}
}
}
- Log.d(TAG, "getDevicesMatchingConnectionStates(states=" + Arrays.toString(states)
- + "): Found " + deviceList.toString());
+ Log.d(
+ TAG,
+ "getDevicesMatchingConnectionStates(states="
+ + Arrays.toString(states)
+ + "): Found "
+ + deviceList.toString());
return deviceList;
}
synchronized int getConnectionState(BluetoothDevice device) {
AvrcpControllerStateMachine stateMachine = mDeviceStateMap.get(device);
- return (stateMachine == null) ? BluetoothProfile.STATE_DISCONNECTED
+ return (stateMachine == null)
+ ? BluetoothProfile.STATE_DISCONNECTED
: stateMachine.getState();
}
@@ -782,8 +795,8 @@ public class AvrcpControllerService extends ProfileService {
ProfileService.println(sb, "Active Device = " + mActiveDevice);
for (AvrcpControllerStateMachine stateMachine : mDeviceStateMap.values()) {
- ProfileService.println(sb,
- "==== StateMachine for " + stateMachine.getDevice() + " ====");
+ ProfileService.println(
+ sb, "==== StateMachine for " + stateMachine.getDevice() + " ====");
stateMachine.dump(sb);
}
sb.append("\n BrowseTree:\n");
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
index 0fe95238fc8a5003db71ef6a59dc0f28f06c72e6..7a380bba4590c36e50341e8fefff441f5cee7792 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerStateMachine.java
@@ -56,18 +56,18 @@ import java.util.Set;
class AvrcpControllerStateMachine extends StateMachine {
static final String TAG = AvrcpControllerStateMachine.class.getSimpleName();
- //0->99 Events from Outside
+ // 0->99 Events from Outside
public static final int CONNECT = 1;
public static final int DISCONNECT = 2;
public static final int ACTIVE_DEVICE_CHANGE = 3;
public static final int AUDIO_FOCUS_STATE_CHANGE = 4;
- //100->199 Internal Events
+ // 100->199 Internal Events
protected static final int CLEANUP = 100;
private static final int CONNECT_TIMEOUT = 101;
static final int MESSAGE_INTERNAL_ABS_VOL_TIMEOUT = 102;
- //200->299 Events from Native
+ // 200->299 Events from Native
static final int STACK_EVENT = 200;
static final int MESSAGE_INTERNAL_CMD_TIMEOUT = 201;
@@ -90,14 +90,14 @@ class AvrcpControllerStateMachine extends StateMachine {
static final int MESSAGE_PROCESS_AVAILABLE_PLAYER_CHANGED = 219;
static final int MESSAGE_PROCESS_RECEIVED_COVER_ART_PSM = 220;
- //300->399 Events for Browsing
+ // 300->399 Events for Browsing
static final int MESSAGE_GET_FOLDER_ITEMS = 300;
static final int MESSAGE_PLAY_ITEM = 301;
static final int MSG_AVRCP_PASSTHRU = 302;
static final int MSG_AVRCP_SET_SHUFFLE = 303;
static final int MSG_AVRCP_SET_REPEAT = 304;
- //400->499 Events for Cover Artwork
+ // 400->499 Events for Cover Artwork
static final int MESSAGE_PROCESS_IMAGE_DOWNLOADED = 400;
/*
@@ -139,10 +139,10 @@ class AvrcpControllerStateMachine extends StateMachine {
GetFolderList mGetFolderList = null;
- //Number of items to get in a single fetch
+ // Number of items to get in a single fetch
static final int ITEM_PAGE_SIZE = 20;
static final int CMD_TIMEOUT_MILLIS = 10000;
- static final int ABS_VOL_TIMEOUT_MILLIS = 1000; //1s
+ static final int ABS_VOL_TIMEOUT_MILLIS = 1000; // 1s
AvrcpControllerStateMachine(
BluetoothDevice device,
@@ -215,9 +215,7 @@ class AvrcpControllerStateMachine extends StateMachine {
return mDevice;
}
- /**
- * send the connection event asynchronously
- */
+ /** send the connection event asynchronously */
public boolean connect(StackEvent event) {
if (event.mBrowsingConnected) {
onBrowsingConnected();
@@ -227,16 +225,12 @@ class AvrcpControllerStateMachine extends StateMachine {
return true;
}
- /**
- * send the Disconnect command asynchronously
- */
+ /** send the Disconnect command asynchronously */
public void disconnect() {
sendMessage(DISCONNECT);
}
- /**
- * Get the current playing track
- */
+ /** Get the current playing track */
public AvrcpItem getCurrentTrack() {
return mAddressedPlayer.getCurrentTrack();
}
@@ -257,13 +251,15 @@ class AvrcpControllerStateMachine extends StateMachine {
* @param sb output string
*/
public void dump(StringBuilder sb) {
- ProfileService.println(sb, "mDevice: " + mDevice + "("
- + Utils.getName(mDevice) + ") " + this.toString());
+ ProfileService.println(
+ sb, "mDevice: " + mDevice + "(" + Utils.getName(mDevice) + ") " + this.toString());
ProfileService.println(sb, "isActive: " + isActive());
ProfileService.println(sb, "Control: " + mRemoteControlConnected);
ProfileService.println(sb, "Browsing: " + mBrowsingConnected);
- ProfileService.println(sb, "Cover Art: "
- + (mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED));
+ ProfileService.println(
+ sb,
+ "Cover Art: "
+ + (mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED));
ProfileService.println(sb, "Addressed Player ID: " + mAddressedPlayerId);
ProfileService.println(sb, "Available Players (" + mAvailablePlayerList.size() + "): ");
@@ -285,17 +281,18 @@ class AvrcpControllerStateMachine extends StateMachine {
return mDevice.equals(mService.getActiveDevice());
}
- /**
- * Attempt to set the active status for this device
- */
+ /** Attempt to set the active status for this device */
public void setDeviceState(int state) {
sendMessage(ACTIVE_DEVICE_CHANGE, state);
}
@Override
protected void unhandledMessage(Message msg) {
- warn("Unhandled message, state=" + getCurrentState() + "msg.what="
- + eventToString(msg.what));
+ warn(
+ "Unhandled message, state="
+ + getCurrentState()
+ + "msg.what="
+ + eventToString(msg.what));
}
synchronized void onBrowsingConnected() {
@@ -322,7 +319,8 @@ class AvrcpControllerStateMachine extends StateMachine {
synchronized void connectCoverArt() {
// Called from "connected" state, which assumes either control or browse is connected
- if (mCoverArtManager != null && mCoverArtPsm != 0
+ if (mCoverArtManager != null
+ && mCoverArtPsm != 0
&& mCoverArtManager.getState(mDevice) != BluetoothProfile.STATE_CONNECTED) {
debug("Attempting to connect to AVRCP BIP, psm: " + mCoverArtPsm);
mCoverArtManager.connect(mDevice, /* psm */ mCoverArtPsm);
@@ -330,7 +328,8 @@ class AvrcpControllerStateMachine extends StateMachine {
}
synchronized void refreshCoverArt() {
- if (mCoverArtManager != null && mCoverArtPsm != 0
+ if (mCoverArtManager != null
+ && mCoverArtPsm != 0
&& mCoverArtManager.getState(mDevice) == BluetoothProfile.STATE_CONNECTED) {
debug("Attempting to refresh AVRCP BIP OBEX session, psm: " + mCoverArtPsm);
mCoverArtManager.refreshSession(mDevice);
@@ -363,8 +362,8 @@ class AvrcpControllerStateMachine extends StateMachine {
}
/**
- * Queries the browse tree for unused uuids and removes the associated images from storage
- * if the uuid is not used by the current track.
+ * Queries the browse tree for unused uuids and removes the associated images from storage if
+ * the uuid is not used by the current track.
*/
synchronized void removeUnusedArtworkFromBrowseTree() {
debug("removeUnusedArtworkFromBrowseTree()");
@@ -384,8 +383,7 @@ class AvrcpControllerStateMachine extends StateMachine {
// updates are fine at any time
int scope = node.getScope();
if (scope != AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING
- || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING
- && isActive())) {
+ || (scope == AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING && isActive())) {
BluetoothMediaBrowserService.notifyChanged(node);
}
}
@@ -452,7 +450,6 @@ class AvrcpControllerStateMachine extends StateMachine {
}
}
-
class Connected extends State {
private int mCurrentlyHeldKey = 0;
@@ -486,14 +483,15 @@ class AvrcpControllerStateMachine extends StateMachine {
// If we switch to a device that is playing and we don't have focus, pause
int focusState = getFocusState();
if (mAddressedPlayer.getPlaybackState().getState()
- == PlaybackStateCompat.STATE_PLAYING
+ == PlaybackStateCompat.STATE_PLAYING
&& focusState == AudioManager.AUDIOFOCUS_NONE) {
- sendMessage(MSG_AVRCP_PASSTHRU,
+ sendMessage(
+ MSG_AVRCP_PASSTHRU,
AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
}
} else {
- sendMessage(MSG_AVRCP_PASSTHRU,
- AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
mShouldSendPlayOnFocusRecovery = false;
}
return true;
@@ -506,7 +504,8 @@ class AvrcpControllerStateMachine extends StateMachine {
// Begin playing audio again if we paused the remote
if (mShouldSendPlayOnFocusRecovery) {
debug("Connected: Regained focus, establishing play status");
- sendMessage(MSG_AVRCP_PASSTHRU,
+ sendMessage(
+ MSG_AVRCP_PASSTHRU,
AvrcpControllerService.PASS_THRU_CMD_ID_PLAY);
}
mShouldSendPlayOnFocusRecovery = false;
@@ -517,9 +516,11 @@ class AvrcpControllerStateMachine extends StateMachine {
// note we should recover
if (mAddressedPlayer.getPlaybackState().getState()
== PlaybackStateCompat.STATE_PLAYING) {
- debug("Connected: Transient loss, temporarily pause with intent to "
- + "recover");
- sendMessage(MSG_AVRCP_PASSTHRU,
+ debug(
+ "Connected: Transient loss, temporarily pause with intent"
+ + " to recover");
+ sendMessage(
+ MSG_AVRCP_PASSTHRU,
AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
mShouldSendPlayOnFocusRecovery = true;
}
@@ -531,7 +532,8 @@ class AvrcpControllerStateMachine extends StateMachine {
debug("Connected: Lost focus, send a courtesy pause");
if (mAddressedPlayer.getPlaybackState().getState()
== PlaybackStateCompat.STATE_PLAYING) {
- sendMessage(MSG_AVRCP_PASSTHRU,
+ sendMessage(
+ MSG_AVRCP_PASSTHRU,
AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
}
mShouldSendPlayOnFocusRecovery = false;
@@ -541,8 +543,7 @@ class AvrcpControllerStateMachine extends StateMachine {
case MESSAGE_PROCESS_SET_ABS_VOL_CMD:
removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT);
- sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT,
- ABS_VOL_TIMEOUT_MILLIS);
+ sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, ABS_VOL_TIMEOUT_MILLIS);
handleAbsVolumeRequest(msg.arg1, msg.arg2);
return true;
@@ -560,7 +561,7 @@ class AvrcpControllerStateMachine extends StateMachine {
return true;
case MESSAGE_PLAY_ITEM:
- //Set Addressed Player
+ // Set Addressed Player
processPlayItem((BrowseTree.BrowseNode) msg.obj);
return true;
@@ -593,12 +594,13 @@ class AvrcpControllerStateMachine extends StateMachine {
return true;
case MESSAGE_PROCESS_PLAY_STATUS_CHANGED:
- debug("Connected: Playback status = "
- + AvrcpControllerUtils.playbackStateToString(msg.arg1));
+ debug(
+ "Connected: Playback status = "
+ + AvrcpControllerUtils.playbackStateToString(msg.arg1));
mAddressedPlayer.setPlayStatus(msg.arg1);
if (!isActive()) {
- sendMessage(MSG_AVRCP_PASSTHRU,
- AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
return true;
}
@@ -606,18 +608,19 @@ class AvrcpControllerStateMachine extends StateMachine {
int focusState = getFocusState();
if (focusState == AudioManager.ERROR) {
- sendMessage(MSG_AVRCP_PASSTHRU,
- AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
return true;
}
if (mAddressedPlayer.getPlaybackState().getState()
- == PlaybackStateCompat.STATE_PLAYING
+ == PlaybackStateCompat.STATE_PLAYING
&& focusState == AudioManager.AUDIOFOCUS_NONE) {
if (shouldRequestFocus()) {
mSessionCallbacks.onPrepare();
} else {
- sendMessage(MSG_AVRCP_PASSTHRU,
+ sendMessage(
+ MSG_AVRCP_PASSTHRU,
AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
}
}
@@ -633,16 +636,20 @@ class AvrcpControllerStateMachine extends StateMachine {
case MESSAGE_PROCESS_ADDRESSED_PLAYER_CHANGED:
int oldAddressedPlayerId = mAddressedPlayerId;
mAddressedPlayerId = msg.arg1;
- debug("Connected: AddressedPlayer changed " + oldAddressedPlayerId + " -> "
- + mAddressedPlayerId);
+ debug(
+ "Connected: AddressedPlayer changed "
+ + oldAddressedPlayerId
+ + " -> "
+ + mAddressedPlayerId);
// The now playing list is tied to the addressed player by specification in
// AVRCP 5.9.1. A new addressed player means our now playing content is now
// invalid
mBrowseTree.mNowPlayingNode.setCached(false);
if (isActive()) {
- debug("Connected: Addressed player change has invalidated the now playing"
- + " list");
+ debug(
+ "Connected: Addressed player change has invalidated the now playing"
+ + " list");
BluetoothMediaBrowserService.notifyChanged(mBrowseTree.mNowPlayingNode);
}
removeUnusedArtworkFromBrowseTree();
@@ -652,8 +659,9 @@ class AvrcpControllerStateMachine extends StateMachine {
// isn't there then we need to ensure that a default Addressed AvrcpPlayer is
// created to represent it. It can be updated if/when we do fetch the player.
if (!mAvailablePlayerList.contains(mAddressedPlayerId)) {
- debug("Connected: Available player set does not contain the new Addressed"
- + " Player");
+ debug(
+ "Connected: Available player set does not contain the new Addressed"
+ + " Player");
AvrcpPlayer.Builder apb = new AvrcpPlayer.Builder();
apb.setDevice(mDevice);
apb.setPlayerId(mAddressedPlayerId);
@@ -738,7 +746,6 @@ class AvrcpControllerStateMachine extends StateMachine {
default:
return super.processMessage(msg);
}
-
}
private void processPlayItem(BrowseTree.BrowseNode node) {
@@ -750,8 +757,11 @@ class AvrcpControllerStateMachine extends StateMachine {
}
private synchronized void passThru(int cmd) {
- debug("Connected: Send passthrough command, id= " + cmd + ", key="
- + AvrcpControllerUtils.passThruIdToString(cmd));
+ debug(
+ "Connected: Send passthrough command, id= "
+ + cmd
+ + ", key="
+ + AvrcpControllerUtils.passThruIdToString(cmd));
// Some keys should be held until the next event.
if (mCurrentlyHeldKey != 0) {
mNativeInterface.sendPassThroughCommand(
@@ -865,8 +875,7 @@ class AvrcpControllerStateMachine extends StateMachine {
case MESSAGE_PROCESS_GET_FOLDER_ITEMS:
ArrayList folderList = (ArrayList) msg.obj;
int endIndicator = mBrowseNode.getExpectedChildren() - 1;
- debug("GetFolderList: End " + endIndicator
- + " received " + folderList.size());
+ debug("GetFolderList: End " + endIndicator + " received " + folderList.size());
// Queue up image download if the item has an image and we don't have it yet
// Only do this if the feature is enabled.
@@ -884,7 +893,8 @@ class AvrcpControllerStateMachine extends StateMachine {
debug("GetFolderList: Added " + newSize + " items to the browse tree");
notifyChanged(mBrowseNode);
- if (mBrowseNode.getChildrenCount() >= endIndicator || folderList.size() == 0
+ if (mBrowseNode.getChildrenCount() >= endIndicator
+ || folderList.size() == 0
|| mAbort) {
// If we have fetched all the elements or if the remotes sends us 0 elements
// (which can lead us into a loop since mCurrInd does not proceed) we simply
@@ -955,12 +965,14 @@ class AvrcpControllerStateMachine extends StateMachine {
// will replace it and re-download metadata. If not, we'll re-use the old
// player to save the metadata queries.
if (!mAvailablePlayerList.contains(mAddressedPlayerId)) {
- debug("GetFolderList: Available player set doesn't contain the"
- + " addressed player");
+ debug(
+ "GetFolderList: Available player set doesn't contain the"
+ + " addressed player");
mAvailablePlayerList.put(mAddressedPlayerId, mAddressedPlayer);
} else {
- debug("GetFolderList: Update addressed player with new available player"
- + " metadata");
+ debug(
+ "GetFolderList: Update addressed player with new available"
+ + " player metadata");
mAddressedPlayer = mAvailablePlayerList.get(mAddressedPlayerId);
mNativeInterface.getCurrentMetadata(mDeviceAddress);
mNativeInterface.getPlaybackState(mDeviceAddress);
@@ -1004,8 +1016,11 @@ class AvrcpControllerStateMachine extends StateMachine {
mAbort = true;
}
deferMessage(msg);
- debug("GetFolderList: Enqueue new request for node=" + requested
- + ", abort=" + mAbort);
+ debug(
+ "GetFolderList: Enqueue new request for node="
+ + requested
+ + ", abort="
+ + mAbort);
} else {
debug("GetFolderList: Ignore request, node=" + requested);
}
@@ -1013,8 +1028,9 @@ class AvrcpControllerStateMachine extends StateMachine {
default:
// All of these messages should be handled by parent state immediately.
- debug("GetFolderList: Passing message to parent state, type="
- + eventToString(msg.what));
+ debug(
+ "GetFolderList: Passing message to parent state, type="
+ + eventToString(msg.what));
return false;
}
return true;
@@ -1024,14 +1040,13 @@ class AvrcpControllerStateMachine extends StateMachine {
* shouldAbort calculates the cases where fetching the current directory is no longer
* necessary.
*
- * @return true: a new folder in the same scope
- * a new player while fetching contents of a folder
- * false: other cases, specifically Now Playing while fetching a folder
+ * @return true: a new folder in the same scope a new player while fetching contents of a
+ * folder false: other cases, specifically Now Playing while fetching a folder
*/
private boolean shouldAbort(int currentScope, int fetchScope) {
if ((currentScope == fetchScope)
|| (currentScope == AvrcpControllerService.BROWSE_SCOPE_VFS
- && fetchScope == AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST)) {
+ && fetchScope == AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST)) {
return true;
}
return false;
@@ -1039,11 +1054,23 @@ class AvrcpControllerStateMachine extends StateMachine {
private void fetchContents(BrowseTree.BrowseNode target) {
int start = target.getChildrenCount();
- int end = Math.min(target.getExpectedChildren(), target.getChildrenCount()
- + ITEM_PAGE_SIZE) - 1;
- debug("GetFolderList: fetchContents(title=" + target.getID() + ", scope="
- + target.getScope() + ", start=" + start + ", end=" + end + ", expected="
- + target.getExpectedChildren() + ")");
+ int end =
+ Math.min(
+ target.getExpectedChildren(),
+ target.getChildrenCount() + ITEM_PAGE_SIZE)
+ - 1;
+ debug(
+ "GetFolderList: fetchContents(title="
+ + target.getID()
+ + ", scope="
+ + target.getScope()
+ + ", start="
+ + start
+ + ", end="
+ + end
+ + ", expected="
+ + target.getExpectedChildren()
+ + ")");
switch (target.getScope()) {
case AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST:
mNativeInterface.getPlayerList(mDeviceAddress, start, end);
@@ -1055,8 +1082,7 @@ class AvrcpControllerStateMachine extends StateMachine {
mNativeInterface.getFolderList(mDeviceAddress, start, end);
break;
default:
- error("GetFolderList: Scope " + target.getScope()
- + " cannot be handled here.");
+ error("GetFolderList: Scope " + target.getScope() + " cannot be handled here.");
}
}
@@ -1073,10 +1099,11 @@ class AvrcpControllerStateMachine extends StateMachine {
*/
private void navigateToFolderOrRetrieve(BrowseTree.BrowseNode target) {
mNextStep = mBrowseTree.getNextStepToFolder(target);
- debug("GetFolderList: NAVIGATING From "
- + mBrowseTree.getCurrentBrowsedFolder().toString()
- + ", NAVIGATING Toward "
- + target.toString());
+ debug(
+ "GetFolderList: NAVIGATING From "
+ + mBrowseTree.getCurrentBrowsedFolder().toString()
+ + ", NAVIGATING Toward "
+ + target.toString());
if (mNextStep == null) {
return;
} else if (target.equals(mBrowseTree.mNowPlayingNode)
@@ -1142,9 +1169,9 @@ class AvrcpControllerStateMachine extends StateMachine {
}
/**
- * Handle a request to align our local volume with the volume of a remote device. If
- * we're assuming the source volume is fixed then a response of ABS_VOL_MAX will always be
- * sent and no volume adjustment action will be taken on the sink side.
+ * Handle a request to align our local volume with the volume of a remote device. If we're
+ * assuming the source volume is fixed then a response of ABS_VOL_MAX will always be sent and no
+ * volume adjustment action will be taken on the sink side.
*
* @param absVol A volume level based on a domain of [0, ABS_VOL_MAX]
* @param label Volume notification label
@@ -1156,8 +1183,7 @@ class AvrcpControllerStateMachine extends StateMachine {
absVol = ABS_VOL_BASE;
} else {
removeMessages(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT);
- sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT,
- ABS_VOL_TIMEOUT_MILLIS);
+ sendMessageDelayed(MESSAGE_INTERNAL_ABS_VOL_TIMEOUT, ABS_VOL_TIMEOUT_MILLIS);
setAbsVolume(absVol);
}
mNativeInterface.sendAbsVolRsp(mDeviceAddress, absVol, label);
@@ -1188,8 +1214,8 @@ class AvrcpControllerStateMachine extends StateMachine {
* no action is required
*/
if (reqLocalVolume != curLocalVolume) {
- mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, reqLocalVolume,
- AudioManager.FLAG_SHOW_UI);
+ mAudioManager.setStreamVolume(
+ AudioManager.STREAM_MUSIC, reqLocalVolume, AudioManager.FLAG_SHOW_UI);
}
}
@@ -1204,8 +1230,7 @@ class AvrcpControllerStateMachine extends StateMachine {
}
private boolean shouldDownloadBrowsedImages() {
- return mService.getResources()
- .getBoolean(R.bool.avrcp_controller_cover_art_browsed_images);
+ return mService.getResources().getBoolean(R.bool.avrcp_controller_cover_art_browsed_images);
}
private void downloadImageIfNeeded(AvrcpItem track) {
@@ -1231,112 +1256,119 @@ class AvrcpControllerStateMachine extends StateMachine {
return focusState;
}
- MediaSessionCompat.Callback mSessionCallbacks = new MediaSessionCompat.Callback() {
- @Override
- public void onPlay() {
- debug("onPlay");
- onPrepare();
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY);
- }
-
- @Override
- public void onPause() {
- debug("onPause");
- // If we receive a local pause/stop request and send it out then we need to signal that
- // the intent is to stay paused if we recover focus from a transient loss
- if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
- debug("Received a pause while in a transient loss. Do not recover anymore.");
- mShouldSendPlayOnFocusRecovery = false;
- }
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
- }
+ MediaSessionCompat.Callback mSessionCallbacks =
+ new MediaSessionCompat.Callback() {
+ @Override
+ public void onPlay() {
+ debug("onPlay");
+ onPrepare();
+ sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PLAY);
+ }
- @Override
- public void onSkipToNext() {
- debug("onSkipToNext");
- onPrepare();
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FORWARD);
- }
+ @Override
+ public void onPause() {
+ debug("onPause");
+ // If we receive a local pause/stop request and send it out then we need to
+ // signal that
+ // the intent is to stay paused if we recover focus from a transient loss
+ if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
+ debug(
+ "Received a pause while in a transient loss. Do not recover"
+ + " anymore.");
+ mShouldSendPlayOnFocusRecovery = false;
+ }
+ sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
+ }
- @Override
- public void onSkipToPrevious() {
- debug("onSkipToPrevious");
- onPrepare();
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_BACKWARD);
- }
+ @Override
+ public void onSkipToNext() {
+ debug("onSkipToNext");
+ onPrepare();
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FORWARD);
+ }
- @Override
- public void onSkipToQueueItem(long id) {
- debug("onSkipToQueueItem(id=" + id + ")");
- onPrepare();
- BrowseTree.BrowseNode node = mBrowseTree.getTrackFromNowPlayingList((int) id);
- if (node != null) {
- sendMessage(MESSAGE_PLAY_ITEM, node);
- }
- }
+ @Override
+ public void onSkipToPrevious() {
+ debug("onSkipToPrevious");
+ onPrepare();
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_BACKWARD);
+ }
- @Override
- public void onStop() {
- debug("onStop");
- // If we receive a local pause/stop request and send it out then we need to signal that
- // the intent is to stay paused if we recover focus from a transient loss
- if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
- debug("Received a stop while in a transient loss. Do not recover anymore.");
- mShouldSendPlayOnFocusRecovery = false;
- }
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_STOP);
- }
+ @Override
+ public void onSkipToQueueItem(long id) {
+ debug("onSkipToQueueItem(id=" + id + ")");
+ onPrepare();
+ BrowseTree.BrowseNode node = mBrowseTree.getTrackFromNowPlayingList((int) id);
+ if (node != null) {
+ sendMessage(MESSAGE_PLAY_ITEM, node);
+ }
+ }
- @Override
- public void onPrepare() {
- debug("onPrepare");
- A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
- if (a2dpSinkService != null) {
- a2dpSinkService.requestAudioFocus(mDevice, true);
- }
- }
+ @Override
+ public void onStop() {
+ debug("onStop");
+ // If we receive a local pause/stop request and send it out then we need to
+ // signal that
+ // the intent is to stay paused if we recover focus from a transient loss
+ if (getFocusState() == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
+ debug("Received a stop while in a transient loss. Do not recover anymore.");
+ mShouldSendPlayOnFocusRecovery = false;
+ }
+ sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_STOP);
+ }
- @Override
- public void onRewind() {
- debug("onRewind");
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_REWIND);
- }
+ @Override
+ public void onPrepare() {
+ debug("onPrepare");
+ A2dpSinkService a2dpSinkService = A2dpSinkService.getA2dpSinkService();
+ if (a2dpSinkService != null) {
+ a2dpSinkService.requestAudioFocus(mDevice, true);
+ }
+ }
- @Override
- public void onFastForward() {
- debug("onFastForward");
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FF);
- }
+ @Override
+ public void onRewind() {
+ debug("onRewind");
+ sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_REWIND);
+ }
- @Override
- public void onPlayFromMediaId(String mediaId, Bundle extras) {
- debug("onPlayFromMediaId(mediaId=" + mediaId + ")");
- // Play the item if possible.
- onPrepare();
- BrowseTree.BrowseNode node = mBrowseTree.findBrowseNodeByID(mediaId);
- if (node != null) {
- // node was found on this bluetooth device
- sendMessage(MESSAGE_PLAY_ITEM, node);
- } else {
- // node was not found on this device, pause here, and play on another device
- sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
- mService.playItem(mediaId);
- }
- }
+ @Override
+ public void onFastForward() {
+ debug("onFastForward");
+ sendMessage(MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_FF);
+ }
- @Override
- public void onSetRepeatMode(int repeatMode) {
- debug("onSetRepeatMode(repeatMode=" + repeatMode + ")");
- sendMessage(MSG_AVRCP_SET_REPEAT, repeatMode);
- }
+ @Override
+ public void onPlayFromMediaId(String mediaId, Bundle extras) {
+ debug("onPlayFromMediaId(mediaId=" + mediaId + ")");
+ // Play the item if possible.
+ onPrepare();
+ BrowseTree.BrowseNode node = mBrowseTree.findBrowseNodeByID(mediaId);
+ if (node != null) {
+ // node was found on this bluetooth device
+ sendMessage(MESSAGE_PLAY_ITEM, node);
+ } else {
+ // node was not found on this device, pause here, and play on another device
+ sendMessage(
+ MSG_AVRCP_PASSTHRU, AvrcpControllerService.PASS_THRU_CMD_ID_PAUSE);
+ mService.playItem(mediaId);
+ }
+ }
- @Override
- public void onSetShuffleMode(int shuffleMode) {
- debug("onSetShuffleMode(shuffleMode=" + shuffleMode + ")");
- sendMessage(MSG_AVRCP_SET_SHUFFLE, shuffleMode);
+ @Override
+ public void onSetRepeatMode(int repeatMode) {
+ debug("onSetRepeatMode(repeatMode=" + repeatMode + ")");
+ sendMessage(MSG_AVRCP_SET_REPEAT, repeatMode);
+ }
- }
- };
+ @Override
+ public void onSetShuffleMode(int shuffleMode) {
+ debug("onSetShuffleMode(shuffleMode=" + shuffleMode + ")");
+ sendMessage(MSG_AVRCP_SET_SHUFFLE, shuffleMode);
+ }
+ };
protected void broadcastConnectionStateChanged(int currentState) {
if (mMostRecentState == currentState) {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java
index 017ecc445547ba1477a2358fb2b80959bf3a6331..f8e6308ebfa8f508f880768497f56ba7471f003e 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpControllerUtils.java
@@ -18,14 +18,10 @@ package com.android.bluetooth.avrcpcontroller;
import android.support.v4.media.session.PlaybackStateCompat;
-/**
- * A package global set of utilities for the AVRCP Controller implementation to leverage
- */
+/** A package global set of utilities for the AVRCP Controller implementation to leverage */
public final class AvrcpControllerUtils {
- /**
- * Convert an AVRCP Passthrough command id to a human readable version of the key
- */
+ /** Convert an AVRCP Passthrough command id to a human readable version of the key */
public static String passThruIdToString(int id) {
StringBuilder sb = new StringBuilder();
switch (id) {
@@ -64,9 +60,7 @@ public final class AvrcpControllerUtils {
return sb.toString();
}
- /**
- * Convert an entire PlaybackStateCompat to a string that contains human readable states
- */
+ /** Convert an entire PlaybackStateCompat to a string that contains human readable states */
public static String playbackStateCompatToString(PlaybackStateCompat playbackState) {
if (playbackState == null) {
return null;
@@ -87,9 +81,7 @@ public final class AvrcpControllerUtils {
return sb.toString();
}
- /**
- * Convert a playback state constant to a human readable version of the state
- */
+ /** Convert a playback state constant to a human readable version of the state */
public static String playbackStateToString(int playbackState) {
StringBuilder sb = new StringBuilder();
switch (playbackState) {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
index b251ab000be09fef49d16e1df91b5bbe80010a7d..e0331f6a7856c3b6d22e0ecbc19beaeddcbd0317 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtManager.java
@@ -34,7 +34,7 @@ import java.util.concurrent.ConcurrentHashMap;
* Manager of all AVRCP Controller connections to remote devices' BIP servers for retrieving cover
* art.
*
- * When given an image handle and device, this manager will negotiate the downloaded image
+ * When given an image handle and device, this manager will negotiate the downloaded image
* properties, download the image, and place it into a Content Provider for others to retrieve from
*/
public class AvrcpCoverArtManager {
@@ -60,13 +60,16 @@ public class AvrcpCoverArtManager {
public class DownloadEvent {
final String mImageUuid;
final Uri mUri;
+
public DownloadEvent(String uuid, Uri uri) {
mImageUuid = uuid;
mUri = uri;
}
+
public String getUuid() {
return mImageUuid;
}
+
public Uri getUri() {
return mUri;
}
@@ -83,10 +86,10 @@ public class AvrcpCoverArtManager {
}
/**
- * A thread-safe collection of BIP connection specific imformation meant to be cleared each
- * time a client disconnects from the Target's BIP OBEX server.
+ * A thread-safe collection of BIP connection specific imformation meant to be cleared each time
+ * a client disconnects from the Target's BIP OBEX server.
*
- * Currently contains the mapping of image handles seen to assigned UUIDs.
+ *
Currently contains the mapping of image handles seen to assigned UUIDs.
*/
private class AvrcpBipSession {
private Map mUuids = new ConcurrentHashMap<>(1); /* handle -> UUID */
@@ -118,7 +121,7 @@ public class AvrcpCoverArtManager {
/**
* Validate an image handle meets the AVRCP and BIP specifications
*
- * By the BIP specification that AVRCP uses, "Image handles are 7 character long strings
+ * By the BIP specification that AVRCP uses, "Image handles are 7 character long strings
* containing only the digits 0 to 9."
*
* @return True if the input string is a valid image handle
@@ -137,8 +140,7 @@ public class AvrcpCoverArtManager {
mService = service;
mCoverArtStorage = new AvrcpCoverArtStorage(mService);
mCallback = callback;
- mDownloadScheme =
- SystemProperties.get(AVRCP_CONTROLLER_COVER_ART_SCHEME, SCHEME_THUMBNAIL);
+ mDownloadScheme = SystemProperties.get(AVRCP_CONTROLLER_COVER_ART_SCHEME, SCHEME_THUMBNAIL);
mCoverArtStorage.clear();
}
@@ -199,7 +201,7 @@ public class AvrcpCoverArtManager {
/**
* Cleanup all cover art related resources
*
- * Please call when you've committed to shutting down the service.
+ *
Please call when you've committed to shutting down the service.
*/
public synchronized void cleanup() {
debug("Clean up and shutdown");
@@ -220,21 +222,21 @@ public class AvrcpCoverArtManager {
return client.getState();
}
- /**
+ /**
* Get the UUID for an image handle coming from a particular device.
*
- * This UUID is used to request and track downloads.
+ *
This UUID is used to request and track downloads.
*
- * Image handles are only good for the life of the BIP client. Since this connection is torn
- * down frequently by specification, we have a layer of indirection to the images in the form
- * of an UUID. This UUID will allow images to be identified outside the connection lifecycle.
- * It also allows handles to be reused by the target in ways that won't impact image consumer's
+ *
Image handles are only good for the life of the BIP client. Since this connection is torn
+ * down frequently by specification, we have a layer of indirection to the images in the form of
+ * an UUID. This UUID will allow images to be identified outside the connection lifecycle. It
+ * also allows handles to be reused by the target in ways that won't impact image consumer's
* cache schemes.
*
* @param device The Bluetooth device you want a handle from
* @param handle The image handle you want a UUID for
* @return A string UUID by which the handle can be identified during the life of the BIP
- * connection.
+ * connection.
*/
public String getUuidForHandle(BluetoothDevice device, String handle) {
AvrcpBipSession session = getSession(device);
@@ -245,7 +247,7 @@ public class AvrcpCoverArtManager {
/**
* Get the handle thats associated with a particular UUID.
*
- * The handle must have been seen during this connection.
+ *
The handle must have been seen during this connection.
*
* @param device The Bluetooth device you want a handle from
* @param uuid The UUID you want the associated handle for
@@ -280,16 +282,15 @@ public class AvrcpCoverArtManager {
/**
* Download an image from a remote device and make it findable via the given uri
*
- * Downloading happens in three steps:
- * 1) Get the available image formats by requesting the Image Properties
- * 2) Determine the specific format we want the image in and turn it into an image descriptor
- * 3) Get the image using the chosen descriptor
+ *
Downloading happens in three steps: 1) Get the available image formats by requesting the
+ * Image Properties 2) Determine the specific format we want the image in and turn it into an
+ * image descriptor 3) Get the image using the chosen descriptor
*
- * Getting image properties and the image are both asynchronous in nature.
+ *
Getting image properties and the image are both asynchronous in nature.
*
* @param device The remote Bluetooth device you wish to download from
* @param imageUuid The UUID associated with the image you wish to download. This will be
- * translated into an image handle.
+ * translated into an image handle.
* @return A Uri that will be assign to the image once the download is complete
*/
public Uri downloadImage(BluetoothDevice device, String imageUuid) {
@@ -365,8 +366,8 @@ public class AvrcpCoverArtManager {
* Determines our preferred download descriptor from the list of available image download
* formats presented in the image properties object.
*
- * Our goal is ensure the image arrives in a format Android can consume and to minimize transfer
- * size if possible.
+ *
Our goal is ensure the image arrives in a format Android can consume and to minimize
+ * transfer size if possible.
*
* @param properties The set of available formats and image is downloadable in
* @return A descriptor containing the desirable download format
@@ -377,10 +378,10 @@ public class AvrcpCoverArtManager {
}
BipImageDescriptor.Builder builder = new BipImageDescriptor.Builder();
switch (mDownloadScheme) {
- // BIP Specification says a blank/null descriptor signals to pull the native format
+ // BIP Specification says a blank/null descriptor signals to pull the native format
case SCHEME_NATIVE:
return null;
- // AVRCP 1.6.2 defined "thumbnail" size is guaranteed so we'll do that for now
+ // AVRCP 1.6.2 defined "thumbnail" size is guaranteed so we'll do that for now
case SCHEME_THUMBNAIL:
default:
builder.setEncoding(BipEncoding.JPEG);
@@ -390,9 +391,7 @@ public class AvrcpCoverArtManager {
return builder.build();
}
- /**
- * Callback for facilitating image download
- */
+ /** Callback for facilitating image download */
class BipClientCallback implements AvrcpBipClient.Callback {
final BluetoothDevice mDevice;
@@ -422,11 +421,15 @@ public class AvrcpCoverArtManager {
}
@Override
- public void onGetImagePropertiesComplete(int status, String imageHandle,
- BipImageProperties properties) {
+ public void onGetImagePropertiesComplete(
+ int status, String imageHandle, BipImageProperties properties) {
if (status != ResponseCodes.OBEX_HTTP_OK || properties == null) {
- warn(mDevice + ": GetImageProperties() failed - Handle: " + imageHandle
- + ", Code: " + status);
+ warn(
+ mDevice
+ + ": GetImageProperties() failed - Handle: "
+ + imageHandle
+ + ", Code: "
+ + status);
return;
}
BipImageDescriptor descriptor = determineImageDescriptor(properties);
@@ -434,8 +437,11 @@ public class AvrcpCoverArtManager {
AvrcpBipClient client = getClient(mDevice);
if (client == null) {
- warn(mDevice + ": Could not getImage() for " + imageHandle
- + " because client has disconnected.");
+ warn(
+ mDevice
+ + ": Could not getImage() for "
+ + imageHandle
+ + " because client has disconnected.");
return;
}
client.getImage(imageHandle, descriptor);
@@ -444,13 +450,23 @@ public class AvrcpCoverArtManager {
@Override
public void onGetImageComplete(int status, String imageHandle, BipImage image) {
if (status != ResponseCodes.OBEX_HTTP_OK) {
- warn(mDevice + ": GetImage() failed - Handle: " + imageHandle
- + ", Code: " + status);
+ warn(
+ mDevice
+ + ": GetImage() failed - Handle: "
+ + imageHandle
+ + ", Code: "
+ + status);
return;
}
String imageUuid = getUuidForHandle(mDevice, imageHandle);
- debug(mDevice + ": Received image data for handle: " + imageHandle
- + ", uuid: " + imageUuid + ", image: " + image);
+ debug(
+ mDevice
+ + ": Received image data for handle: "
+ + imageHandle
+ + ", uuid: "
+ + imageUuid
+ + ", image: "
+ + image);
Uri uri = mCoverArtStorage.addImage(mDevice, imageUuid, image.getImage());
if (uri == null) {
error("Could not store downloaded image");
@@ -479,23 +495,17 @@ public class AvrcpCoverArtManager {
return s;
}
- /**
- * Print to debug if debug is enabled for this class
- */
+ /** Print to debug if debug is enabled for this class */
private void debug(String msg) {
Log.d(TAG, msg);
}
- /**
- * Print to warn
- */
+ /** Print to warn */
private void warn(String msg) {
Log.w(TAG, msg);
}
- /**
- * Print to error
- */
+ /** Print to error */
private void error(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
index ea73cf8b4d7029b4aa339113f3b57875cd2f739f..71728e29db309163a32908d590c5138767b4efe4 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtProvider.java
@@ -33,15 +33,15 @@ import java.io.IOException;
/**
* A provider of downloaded cover art images.
*
- * Cover art images are downloaded from remote devices and are promised to be "good" for the life of
- * a connection.
+ *
Cover art images are downloaded from remote devices and are promised to be "good" for the life
+ * of a connection.
*
- * Android applications are provided a Uri with their MediaMetadata and MediaItem objects that
+ *
Android applications are provided a Uri with their MediaMetadata and MediaItem objects that
* points back to this provider. Uris are in the following format:
*
- * content://com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider//
+ * content://com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider//
*
- * It's expected by the Media framework that artwork at URIs will be available using the
+ * It's expected by the Media framework that artwork at URIs will be available using the
* ContentResolver#openInputStream and BitmapFactory#decodeStream functions. Our provider must
* enable that usage pattern.
*/
@@ -50,8 +50,7 @@ public class AvrcpCoverArtProvider extends ContentProvider {
private BluetoothAdapter mAdapter;
- public AvrcpCoverArtProvider() {
- }
+ public AvrcpCoverArtProvider() {}
static final String AUTHORITY = "com.android.bluetooth.avrcpcontroller.AvrcpCoverArtProvider";
static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
@@ -65,9 +64,12 @@ public class AvrcpCoverArtProvider extends ContentProvider {
*/
public static Uri getImageUri(BluetoothDevice device, String imageUuid) {
if (device == null || imageUuid == null || "".equals(imageUuid)) return null;
- Uri uri = CONTENT_URI.buildUpon().appendQueryParameter("device", device.getAddress())
- .appendQueryParameter("uuid", imageUuid)
- .build();
+ Uri uri =
+ CONTENT_URI
+ .buildUpon()
+ .appendQueryParameter("device", device.getAddress())
+ .appendQueryParameter("uuid", imageUuid)
+ .build();
debug("getImageUri -> " + uri.toString());
return uri;
}
@@ -97,19 +99,20 @@ public class AvrcpCoverArtProvider extends ContentProvider {
}
final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
- Thread transferThread = new Thread() {
- public void run() {
- try {
- FileOutputStream fout =
- new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
- image.compress(Bitmap.CompressFormat.PNG, 100, fout);
- fout.flush();
- fout.close();
- } catch (IOException e) {
- /* Something bad must have happened writing the image data */
- }
- }
- };
+ Thread transferThread =
+ new Thread() {
+ public void run() {
+ try {
+ FileOutputStream fout =
+ new ParcelFileDescriptor.AutoCloseOutputStream(pipe[1]);
+ image.compress(Bitmap.CompressFormat.PNG, 100, fout);
+ fout.flush();
+ fout.close();
+ } catch (IOException e) {
+ /* Something bad must have happened writing the image data */
+ }
+ }
+ };
transferThread.start();
return pipe[0];
}
@@ -150,7 +153,11 @@ public class AvrcpCoverArtProvider extends ContentProvider {
}
@Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
String sortOrder) {
return null;
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
index 765112ff69e33697b79f4c4cf3cfa12318462efd..402134098ad821fec3881dc87bca33515a7b54c6 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpCoverArtStorage.java
@@ -25,9 +25,7 @@ import android.util.Log;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-/**
- * An abstraction of the cover art image storage mechanism.
- */
+/** An abstraction of the cover art image storage mechanism. */
public class AvrcpCoverArtStorage {
private static final String TAG = AvrcpCoverArtStorage.class.getSimpleName();
@@ -42,9 +40,7 @@ public class AvrcpCoverArtStorage {
private final Map> mDeviceImages =
new ConcurrentHashMap<>(1);
- /**
- * Create and initialize this Cover Art storage interface
- */
+ /** Create and initialize this Cover Art storage interface */
public AvrcpCoverArtStorage(Context context) {
mContext = context;
}
@@ -141,9 +137,7 @@ public class AvrcpCoverArtStorage {
mDeviceImages.remove(device);
}
- /**
- * Clear the entirety of storage
- */
+ /** Clear the entirety of storage */
public void clear() {
debug("Clearing all images");
mDeviceImages.clear();
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
index 59fbd604ad242708fd3184d4be84c1c7368370b9..7d248b005811a31eacf3c224acec3af65923d22d 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpItem.java
@@ -29,7 +29,7 @@ import java.util.Objects;
/**
* An object representing a single item returned from an AVRCP folder listing in the VFS scope.
*
- * This object knows how to turn itself into each of the Android Media Framework objects so the
+ * This object knows how to turn itself into each of the Android Media Framework objects so the
* metadata can easily be shared with the system.
*/
public class AvrcpItem {
@@ -94,8 +94,7 @@ public class AvrcpItem {
// Our own internal Uri value that points to downloaded cover art image
private Uri mImageUri;
- private AvrcpItem() {
- }
+ private AvrcpItem() {}
public BluetoothDevice getDevice() {
return mDevice;
@@ -177,9 +176,7 @@ public class AvrcpItem {
mImageUri = uri;
}
- /**
- * Convert this item an Android Media Framework MediaMetadata
- */
+ /** Convert this item an Android Media Framework MediaMetadata */
public MediaMetadataCompat toMediaMetadata() {
MediaMetadataCompat.Builder metaDataBuilder = new MediaMetadataCompat.Builder();
Uri coverArtUri = getCoverArtLocation();
@@ -202,9 +199,7 @@ public class AvrcpItem {
return metaDataBuilder.build();
}
- /**
- * Convert this item an Android Media Framework MediaItem
- */
+ /** Convert this item an Android Media Framework MediaItem */
public MediaItem toMediaItem() {
MediaDescriptionCompat.Builder descriptionBuilder = new MediaDescriptionCompat.Builder();
@@ -237,12 +232,35 @@ public class AvrcpItem {
@Override
public String toString() {
- return "AvrcpItem{mUuid=" + mUuid + ", mUid=" + mUid + ", mItemType=" + mItemType
- + ", mType=" + mType + ", mDisplayableName=" + mDisplayableName
- + ", mTitle=" + mTitle + " mPlayingTime=" + mPlayingTime + " mTrack="
- + mTrackNumber + "/" + mTotalNumberOfTracks + ", mPlayable=" + mPlayable
- + ", mBrowsable=" + mBrowsable + ", mCoverArtHandle=" + getCoverArtHandle()
- + ", mImageUuid=" + mImageUuid + ", mImageUri" + mImageUri + "}";
+ return "AvrcpItem{mUuid="
+ + mUuid
+ + ", mUid="
+ + mUid
+ + ", mItemType="
+ + mItemType
+ + ", mType="
+ + mType
+ + ", mDisplayableName="
+ + mDisplayableName
+ + ", mTitle="
+ + mTitle
+ + " mPlayingTime="
+ + mPlayingTime
+ + " mTrack="
+ + mTrackNumber
+ + "/"
+ + mTotalNumberOfTracks
+ + ", mPlayable="
+ + mPlayable
+ + ", mBrowsable="
+ + mBrowsable
+ + ", mCoverArtHandle="
+ + getCoverArtHandle()
+ + ", mImageUuid="
+ + mImageUuid
+ + ", mImageUri"
+ + mImageUri
+ + "}";
}
@Override
@@ -275,9 +293,7 @@ public class AvrcpItem {
&& Objects.equals(mImageUri, other.getCoverArtLocation());
}
- /**
- * Builder for an AvrcpItem
- */
+ /** Builder for an AvrcpItem */
public static class Builder {
private static final String TAG = "AvrcpItem.Builder";
@@ -298,7 +314,7 @@ public class AvrcpItem {
* item attributes
*
* @param attrIds The array of AVRCP specification defined IDs in the order they match to
- * the value string attrMap
+ * the value string attrMap
* @param attrMap The mapped values for each ID
* @return This object so you can continue building
*/
@@ -351,7 +367,7 @@ public class AvrcpItem {
/**
* Set the item type for the AvrcpItem you are building
*
- * Type can be one of PLAYER, FOLDER, or MEDIA
+ *
Type can be one of PLAYER, FOLDER, or MEDIA
*
* @param itemType The item type as an AvrcpItem.* type value
* @return This object, so you can continue building
@@ -364,7 +380,7 @@ public class AvrcpItem {
/**
* Set the type for the AvrcpItem you are building
*
- * This is the type of the PLAYER, FOLDER, or MEDIA item.
+ *
This is the type of the PLAYER, FOLDER, or MEDIA item.
*
* @param type The type as one of the AvrcpItem.MEDIA_* or FOLDER_* types
* @return This object, so you can continue building
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
index 2922f2c8179b361c61777c314ba5527f357b20c2..7a2800eb3e6e44f6753abf63907773c14a4fad12 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/AvrcpPlayer.java
@@ -73,8 +73,8 @@ class AvrcpPlayer {
mId = id;
mName = name;
mPlayerFeatures = Arrays.copyOf(playerFeatures, playerFeatures.length);
- PlaybackStateCompat.Builder playbackStateBuilder = new PlaybackStateCompat.Builder()
- .setActions(mAvailableActions);
+ PlaybackStateCompat.Builder playbackStateBuilder =
+ new PlaybackStateCompat.Builder().setActions(mAvailableActions);
mPlaybackStateCompat = playbackStateBuilder.build();
updateAvailableActions();
setPlayStatus(playStatus);
@@ -94,9 +94,10 @@ class AvrcpPlayer {
public void setPlayTime(int playTime) {
mPlayTime = playTime;
- mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat).setState(
- mPlayStatus, mPlayTime,
- mPlaySpeed).build();
+ mPlaybackStateCompat =
+ new PlaybackStateCompat.Builder(mPlaybackStateCompat)
+ .setState(mPlayStatus, mPlayTime, mPlaySpeed)
+ .build();
}
public long getPlayTime() {
@@ -105,8 +106,10 @@ class AvrcpPlayer {
public void setPlayStatus(int playStatus) {
if (mPlayTime != PlaybackStateCompat.PLAYBACK_POSITION_UNKNOWN) {
- mPlayTime += mPlaySpeed * (SystemClock.elapsedRealtime()
- - mPlaybackStateCompat.getLastPositionUpdateTime());
+ mPlayTime +=
+ mPlaySpeed
+ * (SystemClock.elapsedRealtime()
+ - mPlaybackStateCompat.getLastPositionUpdateTime());
}
mPlayStatus = playStatus;
switch (mPlayStatus) {
@@ -127,9 +130,10 @@ class AvrcpPlayer {
break;
}
- mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat).setState(
- mPlayStatus, mPlayTime,
- mPlaySpeed).build();
+ mPlaybackStateCompat =
+ new PlaybackStateCompat.Builder(mPlaybackStateCompat)
+ .setState(mPlayStatus, mPlayTime, mPlaySpeed)
+ .build();
}
public void setSupportedPlayerApplicationSettings(
@@ -143,10 +147,12 @@ class AvrcpPlayer {
Log.d(TAG, "Play application settings changed, settings=" + playerApplicationSettings);
mCurrentPlayerApplicationSettings = playerApplicationSettings;
MediaSessionCompat session = BluetoothMediaBrowserService.getSession();
- session.setRepeatMode(mCurrentPlayerApplicationSettings.getSetting(
- PlayerApplicationSettings.REPEAT_STATUS));
- session.setShuffleMode(mCurrentPlayerApplicationSettings.getSetting(
- PlayerApplicationSettings.SHUFFLE_STATUS));
+ session.setRepeatMode(
+ mCurrentPlayerApplicationSettings.getSetting(
+ PlayerApplicationSettings.REPEAT_STATUS));
+ session.setShuffleMode(
+ mCurrentPlayerApplicationSettings.getSetting(
+ PlayerApplicationSettings.SHUFFLE_STATUS));
}
public int getPlayStatus() {
@@ -171,9 +177,10 @@ class AvrcpPlayer {
public synchronized void updateCurrentTrack(AvrcpItem update) {
if (update != null) {
long trackNumber = update.getTrackNumber();
- mPlaybackStateCompat = new PlaybackStateCompat.Builder(
- mPlaybackStateCompat).setActiveQueueItemId(
- trackNumber - 1).build();
+ mPlaybackStateCompat =
+ new PlaybackStateCompat.Builder(mPlaybackStateCompat)
+ .setActiveQueueItemId(trackNumber - 1)
+ .build();
}
mCurrentTrack = update;
}
@@ -224,22 +231,28 @@ class AvrcpPlayer {
PlayerApplicationSettings.SHUFFLE_STATUS)) {
mAvailableActions |= PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE;
}
- mPlaybackStateCompat = new PlaybackStateCompat.Builder(mPlaybackStateCompat)
- .setActions(mAvailableActions).build();
+ mPlaybackStateCompat =
+ new PlaybackStateCompat.Builder(mPlaybackStateCompat)
+ .setActions(mAvailableActions)
+ .build();
Log.d(TAG, "Supported Actions = " + mAvailableActions);
}
@Override
public String toString() {
- return "";
+ + AvrcpControllerUtils.playbackStateCompatToString(mPlaybackStateCompat)
+ + ">";
}
- /**
- * A Builder object for an AvrcpPlayer
- */
+ /** A Builder object for an AvrcpPlayer */
public static class Builder {
private BluetoothDevice mDevice = null;
private int mPlayerId = AvrcpPlayer.DEFAULT_ID;
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
index c4f54f02f99aef5726d35fc164e740d9d41fe666..538c7446135a60d5071e1536e466a493334fafb7 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/BluetoothMediaBrowserService.java
@@ -41,17 +41,15 @@ import java.util.List;
/**
* Implements the MediaBrowserService interface to AVRCP and A2DP
*
- * This service provides a means for external applications to access A2DP and AVRCP.
- * The applications are expected to use MediaBrowser (see API) and all the music
+ * This service provides a means for external applications to access A2DP and AVRCP. The
+ * applications are expected to use MediaBrowser (see API) and all the music
* browsing/playback/metadata can be controlled via MediaBrowser and MediaController.
*
- * The current behavior of MediaSessionCompat exposed by this service is as follows:
- * 1. MediaSessionCompat is active (i.e. SystemUI and other overview UIs can see updates) when
- * device is connected and first starts playing. Before it starts playing we do not activate the
- * session.
- * 1.1 The session is active throughout the duration of connection.
- * 2. The session is de-activated when the device disconnects. It will be connected again when (1)
- * happens.
+ *
The current behavior of MediaSessionCompat exposed by this service is as follows: 1.
+ * MediaSessionCompat is active (i.e. SystemUI and other overview UIs can see updates) when device
+ * is connected and first starts playing. Before it starts playing we do not activate the session.
+ * 1.1 The session is active throughout the duration of connection. 2. The session is de-activated
+ * when the device disconnects. It will be connected again when (1) happens.
*/
public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
private static final String TAG = BluetoothMediaBrowserService.class.getSimpleName();
@@ -117,8 +115,9 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
// Create and configure the MediaSessionCompat
mSession = new MediaSessionCompat(this, TAG);
setSessionToken(mSession.getSessionToken());
- mSession.setFlags(MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
- | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
+ mSession.setFlags(
+ MediaSessionCompat.FLAG_HANDLES_MEDIA_BUTTONS
+ | MediaSessionCompat.FLAG_HANDLES_TRANSPORT_CONTROLS);
mSession.setQueueTitle(getString(R.string.bluetooth_a2dp_sink_queue_name));
mSession.setQueue(mMediaQueue);
setErrorPlaybackState();
@@ -139,17 +138,15 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
/**
- * BrowseResult is used to return the contents of a node along with a status. The status is
- * used to indicate success, a pending download, or error conditions. BrowseResult is used in
+ * BrowseResult is used to return the contents of a node along with a status. The status is used
+ * to indicate success, a pending download, or error conditions. BrowseResult is used in
* onLoadChildren() and getContents() in BluetoothMediaBrowserService and in getContents() in
- * AvrcpControllerService.
- * The following statuses have been implemented:
- * 1. SUCCESS - Contents have been retrieved successfully.
- * 2. DOWNLOAD_PENDING - Download is in progress and may or may not have contents to return.
- * 3. NO_DEVICE_CONNECTED - If no device is connected there are no contents to be retrieved.
- * 4. ERROR_MEDIA_ID_INVALID - Contents could not be retrieved as the media ID is invalid.
- * 5. ERROR_NO_AVRCP_SERVICE - Contents could not be retrieved as AvrcpControllerService is not
- * connected.
+ * AvrcpControllerService. The following statuses have been implemented: 1. SUCCESS - Contents
+ * have been retrieved successfully. 2. DOWNLOAD_PENDING - Download is in progress and may or
+ * may not have contents to return. 3. NO_DEVICE_CONNECTED - If no device is connected there are
+ * no contents to be retrieved. 4. ERROR_MEDIA_ID_INVALID - Contents could not be retrieved as
+ * the media ID is invalid. 5. ERROR_NO_AVRCP_SERVICE - Contents could not be retrieved as
+ * AvrcpControllerService is not connected.
*/
public static class BrowseResult {
// Possible statuses for onLoadChildren
@@ -206,20 +203,21 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
private void setErrorPlaybackState() {
Bundle extras = new Bundle();
- extras.putString(ERROR_RESOLUTION_ACTION_LABEL,
- getString(R.string.bluetooth_connect_action));
+ extras.putString(
+ ERROR_RESOLUTION_ACTION_LABEL, getString(R.string.bluetooth_connect_action));
Intent launchIntent = new Intent();
launchIntent.setAction(BluetoothPrefs.BLUETOOTH_SETTING_ACTION);
launchIntent.addCategory(BluetoothPrefs.BLUETOOTH_SETTING_CATEGORY);
int flags = PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE;
- PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
- launchIntent, flags);
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(getApplicationContext(), 0, launchIntent, flags);
extras.putParcelable(ERROR_RESOLUTION_ACTION_INTENT, pendingIntent);
- PlaybackStateCompat errorState = new PlaybackStateCompat.Builder()
- .setErrorMessage(getString(R.string.bluetooth_disconnected))
- .setExtras(extras)
- .setState(PlaybackStateCompat.STATE_ERROR, 0, 0)
- .build();
+ PlaybackStateCompat errorState =
+ new PlaybackStateCompat.Builder()
+ .setErrorMessage(getString(R.string.bluetooth_disconnected))
+ .setExtras(extras)
+ .setState(PlaybackStateCompat.STATE_ERROR, 0, 0)
+ .build();
mSession.setPlaybackState(errorState);
}
@@ -232,8 +230,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
@Override
- public synchronized void onLoadChildren(final String parentMediaId,
- final Result> result) {
+ public synchronized void onLoadChildren(
+ final String parentMediaId, final Result> result) {
Log.d(TAG, "Request for contents, id= " + parentMediaId);
BrowseResult contents = getContents(parentMediaId);
byte status = contents.getStatus();
@@ -242,8 +240,14 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
Log.i(TAG, "Download pending - no results, id= " + parentMediaId);
result.detach();
} else {
- Log.d(TAG, "Received Contents, id= " + parentMediaId + ", status= "
- + contents.getStatusString() + ", results=" + results);
+ Log.d(
+ TAG,
+ "Received Contents, id= "
+ + parentMediaId
+ + ", status= "
+ + contents.getStatusString()
+ + ", results="
+ + results);
result.sendResult(results);
}
}
@@ -260,9 +264,9 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
mMediaQueue.clear();
if (songList != null && songList.size() > 0) {
for (MediaItem song : songList) {
- mMediaQueue.add(new MediaSessionCompat.QueueItem(
- song.getDescription(),
- mMediaQueue.size()));
+ mMediaQueue.add(
+ new MediaSessionCompat.QueueItem(
+ song.getDescription(), mMediaQueue.size()));
}
mSession.setQueue(mMediaQueue);
} else {
@@ -314,8 +318,10 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
static synchronized void notifyChanged(PlaybackStateCompat playbackState) {
- Log.d(TAG, "Playback State Changed, state="
- + AvrcpControllerUtils.playbackStateCompatToString(playbackState));
+ Log.d(
+ TAG,
+ "Playback State Changed, state="
+ + AvrcpControllerUtils.playbackStateCompatToString(playbackState));
if (sBluetoothMediaBrowserService != null) {
sBluetoothMediaBrowserService.mSession.setPlaybackState(playbackState);
} else {
@@ -323,9 +329,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Send AVRCP Play command
- */
+ /** Send AVRCP Play command */
public static synchronized void play() {
if (sBluetoothMediaBrowserService != null) {
sBluetoothMediaBrowserService.mSession.getController().getTransportControls().play();
@@ -334,9 +338,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Send AVRCP Pause command
- */
+ /** Send AVRCP Pause command */
public static synchronized void pause() {
if (sBluetoothMediaBrowserService != null) {
sBluetoothMediaBrowserService.mSession.getController().getTransportControls().pause();
@@ -345,9 +347,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Get playback state
- */
+ /** Get playback state */
public static synchronized PlaybackStateCompat getPlaybackState() {
if (sBluetoothMediaBrowserService != null) {
MediaSessionCompat session = sBluetoothMediaBrowserService.getSession();
@@ -360,9 +360,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
return null;
}
- /**
- * Get object for controlling playback
- */
+ /** Get object for controlling playback */
public static synchronized MediaControllerCompat.TransportControls getTransportControls() {
if (sBluetoothMediaBrowserService != null) {
return sBluetoothMediaBrowserService.mSession.getController().getTransportControls();
@@ -372,9 +370,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Set Media session active whenever we have Focus of any kind
- */
+ /** Set Media session active whenever we have Focus of any kind */
public static synchronized void setActive(boolean active) {
if (sBluetoothMediaBrowserService != null) {
Log.d(TAG, "Setting the session active state to:" + active);
@@ -386,6 +382,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
/**
* Checks if the media session is active or not.
+ *
* @return true if media session is active, false otherwise.
*/
@VisibleForTesting
@@ -395,9 +392,8 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
return false;
}
- /**
- * Get Media session for updating state
- */
+
+ /** Get Media session for updating state */
public static synchronized MediaSessionCompat getSession() {
if (sBluetoothMediaBrowserService != null) {
return sBluetoothMediaBrowserService.mSession;
@@ -407,9 +403,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Reset the state of BluetoothMediaBrowserService to that before a device connected
- */
+ /** Reset the state of BluetoothMediaBrowserService to that before a device connected */
public static synchronized void reset() {
if (sBluetoothMediaBrowserService != null) {
sBluetoothMediaBrowserService.clearNowPlayingQueue();
@@ -422,9 +416,7 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
}
}
- /**
- * Get the state of the BluetoothMediaBrowserService as a debug string
- */
+ /** Get the state of the BluetoothMediaBrowserService as a debug string */
public static synchronized String dump() {
StringBuilder sb = new StringBuilder();
sb.append(TAG + ":");
@@ -439,24 +431,30 @@ public class BluetoothMediaBrowserService extends MediaBrowserServiceCompat {
if (metadata != null) {
sb.append("\n track={");
sb.append("title=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_TITLE));
- sb.append(", artist="
- + metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
+ sb.append(
+ ", artist=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_ARTIST));
sb.append(", album=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM));
- sb.append(", duration="
- + metadata.getString(MediaMetadataCompat.METADATA_KEY_DURATION));
- sb.append(", track_number="
- + metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
- sb.append(", total_tracks="
- + metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
+ sb.append(
+ ", duration="
+ + metadata.getString(MediaMetadataCompat.METADATA_KEY_DURATION));
+ sb.append(
+ ", track_number="
+ + metadata.getLong(MediaMetadataCompat.METADATA_KEY_TRACK_NUMBER));
+ sb.append(
+ ", total_tracks="
+ + metadata.getLong(MediaMetadataCompat.METADATA_KEY_NUM_TRACKS));
sb.append(", genre=" + metadata.getString(MediaMetadataCompat.METADATA_KEY_GENRE));
- sb.append(", album_art="
- + metadata.getString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI));
+ sb.append(
+ ", album_art="
+ + metadata.getString(
+ MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI));
sb.append("}");
} else {
sb.append("\n track=" + metadata);
}
- sb.append("\n playbackState="
- + AvrcpControllerUtils.playbackStateCompatToString(playbackState));
+ sb.append(
+ "\n playbackState="
+ + AvrcpControllerUtils.playbackStateCompatToString(playbackState));
sb.append("\n queue=" + queue);
sb.append("\n internal_queue=" + sBluetoothMediaBrowserService.mMediaQueue);
sb.append("\n session active state=").append(isActive());
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java b/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
index 4d3973597bda6b63b74cd3c9b799de90a0e15e63..b8dab9f78fdb3b2a025d993266db71579e9baa2e 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/BrowseTree.java
@@ -38,18 +38,8 @@ import java.util.UUID;
/**
* An object that holds the browse tree of available media from a remote device.
*
- * Browsing hierarchy follows the AVRCP specification's description of various scopes and
- * looks like follows:
- * Root:
- * Player1:
- * Now_Playing:
- * MediaItem1
- * MediaItem2
- * Folder1
- * Folder2
- * ....
- * Player2
- * ....
+ * Browsing hierarchy follows the AVRCP specification's description of various scopes and looks
+ * like follows: Root: Player1: Now_Playing: MediaItem1 MediaItem2 Folder1 Folder2 .... Player2 ....
*/
public class BrowseTree {
private static final String TAG = BrowseTree.class.getSimpleName();
@@ -64,6 +54,7 @@ public class BrowseTree {
// Static instance of Folder ID <-> Folder Instance (for navigation purposes)
@VisibleForTesting
final HashMap mBrowseMap = new HashMap();
+
private BrowseNode mCurrentBrowseNode;
private BrowseNode mCurrentBrowsedPlayer;
private BrowseNode mCurrentAddressedPlayer;
@@ -78,13 +69,23 @@ public class BrowseTree {
BrowseTree(BluetoothDevice device) {
if (device == null) {
- mRootNode = new BrowseNode(new AvrcpItem.Builder()
- .setUuid(ROOT).setTitle(ROOT).setBrowsable(true).build());
+ mRootNode =
+ new BrowseNode(
+ new AvrcpItem.Builder()
+ .setUuid(ROOT)
+ .setTitle(ROOT)
+ .setBrowsable(true)
+ .build());
mRootNode.setCached(true);
} else if (!Flags.randomizeDeviceLevelMediaIds()) {
- mRootNode = new BrowseNode(new AvrcpItem.Builder().setDevice(device)
- .setUuid(ROOT + device.getAddress().toString())
- .setTitle(Utils.getName(device)).setBrowsable(true).build());
+ mRootNode =
+ new BrowseNode(
+ new AvrcpItem.Builder()
+ .setDevice(device)
+ .setUuid(ROOT + device.getAddress().toString())
+ .setTitle(Utils.getName(device))
+ .setBrowsable(true)
+ .build());
} else {
mRootNode =
new BrowseNode(
@@ -102,12 +103,21 @@ public class BrowseTree {
mRootNode.mBrowseScope = AvrcpControllerService.BROWSE_SCOPE_PLAYER_LIST;
mRootNode.setExpectedChildren(DEFAULT_FOLDER_SIZE);
- mNavigateUpNode = new BrowseNode(new AvrcpItem.Builder()
- .setUuid(UP).setTitle(UP).setBrowsable(true).build());
-
- mNowPlayingNode = new BrowseNode(new AvrcpItem.Builder()
- .setUuid(NOW_PLAYING_PREFIX).setTitle(NOW_PLAYING_PREFIX)
- .setBrowsable(true).build());
+ mNavigateUpNode =
+ new BrowseNode(
+ new AvrcpItem.Builder()
+ .setUuid(UP)
+ .setTitle(UP)
+ .setBrowsable(true)
+ .build());
+
+ mNowPlayingNode =
+ new BrowseNode(
+ new AvrcpItem.Builder()
+ .setUuid(NOW_PLAYING_PREFIX)
+ .setTitle(NOW_PLAYING_PREFIX)
+ .setBrowsable(true)
+ .build());
mNowPlayingNode.mBrowseScope = AvrcpControllerService.BROWSE_SCOPE_NOW_PLAYING;
mNowPlayingNode.setExpectedChildren(DEFAULT_FOLDER_SIZE);
mBrowseMap.put(mRootNode.getID(), mRootNode);
@@ -363,9 +373,13 @@ public class BrowseTree {
@Override
public synchronized String toString() {
- return "[Id: " + getID()
- + " Name: " + getMediaItem().getDescription().getTitle()
- + " Size: " + mChildren.size() + "]";
+ return "[Id: "
+ + getID()
+ + " Name: "
+ + getMediaItem().getDescription().getTitle()
+ + " Size: "
+ + mChildren.size()
+ + "]";
}
// Returns true if target is a descendant of this.
@@ -452,9 +466,7 @@ public class BrowseTree {
mCoverArtMap.get(handle).add(nodeId);
}
- /**
- * Indicate that a node in the tree no longer needs a specific piece of cover art.
- */
+ /** Indicate that a node in the tree no longer needs a specific piece of cover art. */
synchronized void indicateCoverArtUnused(String nodeId, String handle) {
if (mCoverArtMap.containsKey(handle) && mCoverArtMap.get(handle).contains(nodeId)) {
mCoverArtMap.get(handle).remove(nodeId);
@@ -483,8 +495,8 @@ public class BrowseTree {
/**
* Adds the Uri of a newly downloaded image to all tree nodes using that specific handle.
- * Returns the set of parent nodes that have children impacted by the new art so clients can
- * be notified of the change.
+ * Returns the set of parent nodes that have children impacted by the new art so clients can be
+ * notified of the change.
*/
synchronized Set notifyImageDownload(String uuid, Uri uri) {
Log.d(TAG, "Received downloaded image handle to cascade to BrowseNodes using it");
@@ -505,9 +517,7 @@ public class BrowseTree {
return parents;
}
- /**
- * Dump the state of the AVRCP browse tree
- */
+ /** Dump the state of the AVRCP browse tree */
public void dump(StringBuilder sb) {
mRootNode.toTreeString(0, sb);
sb.append("\n Image handles in use (" + mCoverArtMap.size() + "):");
@@ -556,8 +566,7 @@ public class BrowseTree {
static BrowseNode getEldestChild(BrowseNode ancestor, BrowseNode target) {
// ancestor is an ancestor of target
BrowseNode descendant = target;
- Log.d(TAG, "NAVIGATING ancestor" + ancestor.toString() + "Target"
- + target.toString());
+ Log.d(TAG, "NAVIGATING ancestor" + ancestor.toString() + "Target" + target.toString());
while (!ancestor.equals(descendant.mParent)) {
descendant = descendant.mParent;
if (descendant == null) {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java b/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java
index c4a5d643decc527f21ac83cce7ddcea89ee03c3f..f39f36d210ee7acf3734b88e5a749386a9b9b7fa 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/PlayerApplicationSettings.java
@@ -37,24 +37,16 @@ class PlayerApplicationSettings {
static final byte REPEAT_STATUS = 0x02;
static final byte SHUFFLE_STATUS = 0x03;
- @VisibleForTesting
- static final byte JNI_REPEAT_STATUS_OFF = 0x01;
- @VisibleForTesting
- static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02;
- @VisibleForTesting
- static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03;
- @VisibleForTesting
- static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04;
+ @VisibleForTesting static final byte JNI_REPEAT_STATUS_OFF = 0x01;
+ @VisibleForTesting static final byte JNI_REPEAT_STATUS_SINGLE_TRACK_REPEAT = 0x02;
+ @VisibleForTesting static final byte JNI_REPEAT_STATUS_ALL_TRACK_REPEAT = 0x03;
+ @VisibleForTesting static final byte JNI_REPEAT_STATUS_GROUP_REPEAT = 0x04;
- @VisibleForTesting
- static final byte JNI_SHUFFLE_STATUS_OFF = 0x01;
- @VisibleForTesting
- static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02;
- @VisibleForTesting
- static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03;
+ @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_OFF = 0x01;
+ @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_ALL_TRACK_SHUFFLE = 0x02;
+ @VisibleForTesting static final byte JNI_SHUFFLE_STATUS_GROUP_SHUFFLE = 0x03;
- @VisibleForTesting
- static final byte JNI_STATUS_INVALID = -1;
+ @VisibleForTesting static final byte JNI_STATUS_INVALID = -1;
/*
* Hash map of current settings.
@@ -96,7 +88,8 @@ class PlayerApplicationSettings {
for (int i = 0; i < btAvrcpAttributeList.length; ) {
byte attrId = btAvrcpAttributeList[i++];
- newObj.mSettings.put(attrId,
+ newObj.mSettings.put(
+ attrId,
mapAttribIdValtoAvrcpPlayerSetting(attrId, btAvrcpAttributeList[i++]));
}
} catch (ArrayIndexOutOfBoundsException exception) {
@@ -207,8 +200,10 @@ class PlayerApplicationSettings {
@Override
public String toString() {
return "";
}
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java b/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java
index 1f96bd29a96a30c94baa13f036cdaf745be93475..c303d529ff4aae8098d41a07ca7be58f62542aa5 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/StackEvent.java
@@ -42,8 +42,8 @@ final class StackEvent {
}
}
- static StackEvent connectionStateChanged(boolean remoteControlConnected,
- boolean browsingConnected) {
+ static StackEvent connectionStateChanged(
+ boolean remoteControlConnected, boolean browsingConnected) {
StackEvent event = new StackEvent(EVENT_TYPE_CONNECTION_STATE_CHANGED);
event.mRemoteControlConnected = remoteControlConnected;
event.mBrowsingConnected = browsingConnected;
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java
index 3760cb0f709d6ffe372e3357e63892665e212979..656e91f2567689e125caf3c86c233508a97c709e 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipAttachmentFormat.java
@@ -24,11 +24,10 @@ import java.util.Objects;
/**
* Represents BIP attachment metadata arriving from a GetImageProperties request.
*
- * Content type is the only spec-required field.
+ * Content type is the only spec-required field.
*
- * Examples:
- *
- *
+ *
Examples:
*/
public class BipAttachmentFormat {
private static final String TAG = "avrcpcontroller.BipAttachmentFormat";
@@ -36,39 +35,36 @@ public class BipAttachmentFormat {
/**
* MIME content type of the image attachment, i.e. "text/plain"
*
- * This is required by the specification
+ *
This is required by the specification
*/
private final String mContentType;
- /**
- * MIME character set of the image attachment, i.e. "ISO-8859-1"
- */
+ /** MIME character set of the image attachment, i.e. "ISO-8859-1" */
private final String mCharset;
/**
* File name of the image attachment
*
- * This is required by the specification
+ *
This is required by the specification
*/
private final String mName;
- /**
- * Size of the image attachment in bytes
- */
+ /** Size of the image attachment in bytes */
private final int mSize;
- /**
- * Date the image attachment was created
- */
+ /** Date the image attachment was created */
private final BipDateTime mCreated;
- /**
- * Date the image attachment was last modified
- */
+ /** Date the image attachment was last modified */
private final BipDateTime mModified;
- public BipAttachmentFormat(String contentType, String charset, String name, String size,
- String created, String modified) {
+ public BipAttachmentFormat(
+ String contentType,
+ String charset,
+ String name,
+ String size,
+ String created,
+ String modified) {
if (contentType == null) {
throw new ParseException("ContentType is required and must be valid");
}
@@ -98,8 +94,13 @@ public class BipAttachmentFormat {
mModified = bipModified;
}
- public BipAttachmentFormat(String contentType, String charset, String name, int size,
- Date created, Date modified) {
+ public BipAttachmentFormat(
+ String contentType,
+ String charset,
+ String name,
+ int size,
+ Date created,
+ Date modified) {
mContentType = Objects.requireNonNull(contentType, "Content-Type cannot be null");
mName = Objects.requireNonNull(name, "Name cannot be null");
mCharset = charset;
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
index bd648a4cf355e6f619d8cfcea9ac207c77f2acfe..cd7aa3fc62717af32a8cf3740d4fdf6f161e99f4 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipDateTime.java
@@ -27,18 +27,13 @@ import java.util.regex.Pattern;
/**
* An object representing a DateTime sent over the Basic Imaging Profile
*
- * Date-time format is as follows:
+ *
Date-time format is as follows:
*
- * YYYYMMDDTHHMMSSZ, where
- * Y/M/D/H/M/S - years, months, days, hours, minutes, seconds
- * T - A delimiter
- * Z - An optional, but recommended, character indicating the time is in UTC. If UTC
- * is not used then we're to assume "local timezone" instead.
+ *
YYYYMMDDTHHMMSSZ, where Y/M/D/H/M/S - years, months, days, hours, minutes, seconds T - A
+ * delimiter Z - An optional, but recommended, character indicating the time is in UTC. If UTC is
+ * not used then we're to assume "local timezone" instead.
*
- * Example date-time values:
- * 20000101T000000Z
- * 20000101T235959Z
- * 20000101T000000
+ *
Example date-time values: 20000101T000000Z 20000101T235959Z 20000101T000000
*/
public class BipDateTime {
private static final String TAG = "avrcpcontroller.BipDateTime";
@@ -49,12 +44,12 @@ public class BipDateTime {
public BipDateTime(String time) {
try {
/*
- * Match groups for the timestamp are numbered as follows:
- *
- * YYYY MM DD T HH MM SS Z
- * ^^^^ ^^ ^^ ^^ ^^ ^^ ^
- * 1 2 3 4 5 6 7
- */
+ * Match groups for the timestamp are numbered as follows:
+ *
+ * YYYY MM DD T HH MM SS Z
+ * ^^^^ ^^ ^^ ^^ ^^ ^^ ^
+ * 1 2 3 4 5 6 7
+ */
Pattern p = Pattern.compile("(\\d{4})(\\d{2})(\\d{2})T(\\d{2})(\\d{2})(\\d{2})([Z])?");
Matcher m = p.matcher(time);
@@ -66,15 +61,17 @@ public class BipDateTime {
builder.setLenient(false);
/* Note that Calendar months are zero-based in Java framework */
- builder.setDate(Integer.parseInt(m.group(1)), /* year */
- Integer.parseInt(m.group(2)) - 1, /* month */
- Integer.parseInt(m.group(3))); /* day of month */
+ builder.setDate(
+ Integer.parseInt(m.group(1)), /* year */
+ Integer.parseInt(m.group(2)) - 1, /* month */
+ Integer.parseInt(m.group(3))); /* day of month */
/* Note the timestamp doesn't have milliseconds and we're explicitly setting to 0 */
- builder.setTimeOfDay(Integer.parseInt(m.group(4)), /* hours */
- Integer.parseInt(m.group(5)), /* minutes */
- Integer.parseInt(m.group(6)), /* seconds */
- 0); /* milliseconds */
+ builder.setTimeOfDay(
+ Integer.parseInt(m.group(4)), /* hours */
+ Integer.parseInt(m.group(5)), /* minutes */
+ Integer.parseInt(m.group(6)), /* seconds */
+ 0); /* milliseconds */
/* If the 7th group is matched then we have UTC based timestamp */
if (m.group(7) != null) {
@@ -137,15 +134,25 @@ public class BipDateTime {
TimeZone utc = TimeZone.getTimeZone("UTC");
utc.setRawOffset(0);
cal.setTimeZone(utc);
- return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02dZ", cal.get(Calendar.YEAR),
- cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE),
- cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
+ return String.format(
+ Locale.US,
+ "%04d%02d%02dT%02d%02d%02dZ",
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH) + 1,
+ cal.get(Calendar.DATE),
+ cal.get(Calendar.HOUR_OF_DAY),
+ cal.get(Calendar.MINUTE),
cal.get(Calendar.SECOND));
} else {
cal.setTimeZone(TimeZone.getDefault());
- return String.format(Locale.US, "%04d%02d%02dT%02d%02d%02d", cal.get(Calendar.YEAR),
- cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE),
- cal.get(Calendar.HOUR_OF_DAY), cal.get(Calendar.MINUTE),
+ return String.format(
+ Locale.US,
+ "%04d%02d%02dT%02d%02d%02d",
+ cal.get(Calendar.YEAR),
+ cal.get(Calendar.MONTH) + 1,
+ cal.get(Calendar.DATE),
+ cal.get(Calendar.HOUR_OF_DAY),
+ cal.get(Calendar.MINUTE),
cal.get(Calendar.SECOND));
}
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java
index c4c401ebf79aefd857274e40e0c20699fe938d06..4de8caf7edb49001c35a05f999f65b5ba0ba8e86 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipEncoding.java
@@ -23,22 +23,17 @@ import java.util.HashMap;
/**
* Represents an encoding method in which a BIP image is available.
*
- * The encodings supported by this profile include:
- * - JPEG
- * - GIF
- * - WBMP
- * - PNG
- * - JPEG2000
- * - BMP
- * - USR-xxx
+ *
The encodings supported by this profile include: - JPEG - GIF - WBMP - PNG - JPEG2000 - BMP -
+ * USR-xxx
*
- * The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the string
- * “USR-” but the implementer assigns the characters of the second half of the string. This tag can
- * be used by a manufacturer to enable its devices to exchange images under a proprietary encoding.
+ *
The tag USR-xxx is used to represent proprietary encodings. The tag shall begin with the
+ * string “USR-” but the implementer assigns the characters of the second half of the string. This
+ * tag can be used by a manufacturer to enable its devices to exchange images under a proprietary
+ * encoding.
*
- * Example proprietary encoding:
+ *
Example proprietary encoding:
*
- * - USR-NOKIA-FORMAT1
+ *
- USR-NOKIA-FORMAT1
*/
public class BipEncoding {
public static final int JPEG = 0;
@@ -51,6 +46,7 @@ public class BipEncoding {
public static final int UNKNOWN = 7; // i.e 'not assigned' or 'not assigned anything valid'
private static final HashMap sEncodingNamesToIds = new HashMap();
+
static {
sEncodingNamesToIds.put("JPEG", JPEG);
sEncodingNamesToIds.put("GIF", GIF);
@@ -61,6 +57,7 @@ public class BipEncoding {
}
private static final SparseArray sIdsToEncodingNames = new SparseArray();
+
static {
sIdsToEncodingNames.put(JPEG, "JPEG");
sIdsToEncodingNames.put(GIF, "GIF");
@@ -71,14 +68,10 @@ public class BipEncoding {
sIdsToEncodingNames.put(UNKNOWN, "UNKNOWN");
}
- /**
- * The integer ID of the type that this encoding is
- */
+ /** The integer ID of the type that this encoding is */
private final int mType;
- /**
- * If an encoding is type USR_XXX then it has an extension that defines the encoding
- */
+ /** If an encoding is type USR_XXX then it has an extension that defines the encoding */
private final String mProprietaryEncodingId;
/**
@@ -110,7 +103,7 @@ public class BipEncoding {
*
* @param encoding A constant representing an available encoding
* @param proprietaryId A string representing the Id of a propreitary encoding. Only used if the
- * encoding type is BipEncoding.USR_XXX
+ * encoding type is BipEncoding.USR_XXX
*/
public BipEncoding(int encoding, String proprietaryId) {
if (encoding < 0 || encoding > USR_XXX) {
@@ -121,8 +114,8 @@ public class BipEncoding {
String proprietaryEncodingId = null;
if (mType == USR_XXX) {
if (proprietaryId == null) {
- throw new IllegalArgumentException("Received invalid user defined encoding id '"
- + proprietaryId + "'");
+ throw new IllegalArgumentException(
+ "Received invalid user defined encoding id '" + proprietaryId + "'");
}
proprietaryEncodingId = proprietaryId.toUpperCase();
}
@@ -154,18 +147,18 @@ public class BipEncoding {
/**
* Determines if an encoding is supported by Android's Graphics Framework
*
- * Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats.
+ * Android's Bitmap/BitmapFactory can handle BMP, GIF, JPEG, PNG, WebP, and HEIF formats.
*
* @return True if the encoding is supported, False otherwise.
*/
public boolean isAndroidSupported() {
- return mType == BipEncoding.JPEG || mType == BipEncoding.PNG || mType == BipEncoding.BMP
+ return mType == BipEncoding.JPEG
+ || mType == BipEncoding.PNG
+ || mType == BipEncoding.BMP
|| mType == BipEncoding.GIF;
}
- /**
- * Determine the encoding type based on an input string
- */
+ /** Determine the encoding type based on an input string */
private static int determineEncoding(String encoding) {
Integer type = (Integer) sEncodingNamesToIds.get(encoding);
if (type != null) return type.intValue();
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java
index cb31f43da5e0a64a6f6c1e61d1c6176e74b2448a..29936696ec192f3b7dc4628eba79e89eb19201aa 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImage.java
@@ -24,7 +24,7 @@ import java.io.InputStream;
/**
* An image object sent over BIP.
*
- * The image is sent as bytes in the payload of a GetImage request. The format of those bytes is
+ *
The image is sent as bytes in the payload of a GetImage request. The format of those bytes is
* determined by the BipImageDescriptor used when making the request.
*/
public class BipImage {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
index a2bee5f3fbd9a1244775dccf14639c335cc65f55..c38019b12849d9ae78f410d41c6049b8cac13bf8 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageDescriptor.java
@@ -33,31 +33,29 @@ import java.io.UnsupportedEncodingException;
* Contains the metadata that describes either (1) the desired size of a image to be downloaded or
* (2) the extact size of an image to be uploaded.
*
- * When using this to assert the size of an image to download/pull, it's best to derive this
+ *
When using this to assert the size of an image to download/pull, it's best to derive this
* specific descriptor from any of the available BipImageFormat options returned from a
* RequestGetImageProperties. Note that if a BipImageFormat is not of a fixed size type then you
* must arrive on a desired fixed size for this descriptor.
*
- * When using this to denote the size of an image when pushing an image for transfer this descriptor
- * must match the metadata of the image being sent.
+ *
When using this to denote the size of an image when pushing an image for transfer this
+ * descriptor must match the metadata of the image being sent.
*
- * Note, the encoding and pixel values are mandatory by specification. The version number is fixed.
- * All other values are optional. The transformation field is to have *one* selected option in it.
+ *
Note, the encoding and pixel values are mandatory by specification. The version number is
+ * fixed. All other values are optional. The transformation field is to have *one* selected option
+ * in it.
*
- * Example:
- * < image-descriptor version=“1.0” >
- * < image encoding=“JPEG” pixel=“1280*960” size=“500000”/>
- * < /image-descriptor >
+ *
Example: < image-descriptor version=“1.0” > < image encoding=“JPEG” pixel=“1280*960”
+ * size=“500000”/> < /image-descriptor >
*/
public class BipImageDescriptor {
private static final String TAG = "avrcpcontroller.BipImageDescriptor";
private static final String sVersion = "1.0";
- /**
- * A Builder for an ImageDescriptor object
- */
+ /** A Builder for an ImageDescriptor object */
public static class Builder {
private BipImageDescriptor mImageDescriptor = new BipImageDescriptor();
+
/**
* Set the encoding for the descriptor you're building using a BipEncoding object
*
@@ -147,14 +145,10 @@ public class BipImageDescriptor {
}
}
- /**
- * The encoding of the image, required by the specification
- */
+ /** The encoding of the image, required by the specification */
private BipEncoding mEncoding = null;
- /**
- * The width and height of the image, required by the specification
- */
+ /** The width and height of the image, required by the specification */
private BipPixel mPixel = null;
/**
@@ -163,15 +157,13 @@ public class BipImageDescriptor {
*/
private BipTransformation mTransformation = null;
- /**
- * The size in bytes of the image
- */
+ /** The size in bytes of the image */
private int mSize = -1;
/**
* The max size in bytes of the image.
*
- * Optional, used only when describing an image to pull
+ *
Optional, used only when describing an image to pull
*/
private int mMaxSize = -1;
@@ -195,8 +187,9 @@ public class BipImageDescriptor {
mPixel = new BipPixel(xpp.getAttributeValue(null, "pixel"));
mSize = parseInt(xpp.getAttributeValue(null, "size"));
mMaxSize = parseInt(xpp.getAttributeValue(null, "maxsize"));
- mTransformation = new BipTransformation(
- xpp.getAttributeValue(null, "transformation"));
+ mTransformation =
+ new BipTransformation(
+ xpp.getAttributeValue(null, "transformation"));
} else {
Log.w(TAG, "Unrecognized tag in x-bt/img-Description object: " + tag);
}
@@ -275,8 +268,10 @@ public class BipImageDescriptor {
@Override
public String toString() {
if (mEncoding == null || mPixel == null) {
- error("Missing required fields [ " + (mEncoding == null ? "encoding " : "")
- + (mPixel == null ? "pixel " : ""));
+ error(
+ "Missing required fields [ "
+ + (mEncoding == null ? "encoding " : "")
+ + (mPixel == null ? "pixel " : ""));
return null;
}
StringWriter writer = new StringWriter();
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
index 43cbef9dd780ecb2e0dff04f798f563fc1cb8d47..0572e814166be31110c8118d43b5c527be9bbab1 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageFormat.java
@@ -24,16 +24,15 @@ import java.util.Objects;
* Describes a single native or variant format available for an image, coming from a
* BipImageProperties object.
*
- * This is not an object by specification, per say. It abstracts all the various native and variant
- * formats available in a given set of image properties.
+ *
This is not an object by specification, per say. It abstracts all the various native and
+ * variant formats available in a given set of image properties.
*
- * This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an image
+ *
This BipImageFormat can be used to choose a specific BipImageDescriptor when downloading an
+ * image
*
- * Examples:
- *
- *
- *
- *
+ *
Examples:
*/
public class BipImageFormat {
private static final String TAG = "avrcpcontroller.BipImageFormat";
@@ -41,46 +40,34 @@ public class BipImageFormat {
public static final int FORMAT_NATIVE = 0;
public static final int FORMAT_VARIANT = 1;
- /**
- * Create a native BipImageFormat from the given string fields
- */
+ /** Create a native BipImageFormat from the given string fields */
public static BipImageFormat parseNative(String encoding, String pixel, String size) {
return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, null, null);
}
- /**
- * Create a variant BipImageFormat from the given string fields
- */
- public static BipImageFormat parseVariant(String encoding, String pixel, String maxSize,
- String transformation) {
- return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize,
- transformation);
+ /** Create a variant BipImageFormat from the given string fields */
+ public static BipImageFormat parseVariant(
+ String encoding, String pixel, String maxSize, String transformation) {
+ return new BipImageFormat(
+ BipImageFormat.FORMAT_VARIANT, encoding, pixel, null, maxSize, transformation);
}
- /**
- * Create a native BipImageFormat from the given parameters
- */
+ /** Create a native BipImageFormat from the given parameters */
public static BipImageFormat createNative(BipEncoding encoding, BipPixel pixel, int size) {
return new BipImageFormat(BipImageFormat.FORMAT_NATIVE, encoding, pixel, size, -1, null);
}
- /**
- * Create a variant BipImageFormat from the given parameters
- */
- public static BipImageFormat createVariant(BipEncoding encoding, BipPixel pixel, int maxSize,
- BipTransformation transformation) {
- return new BipImageFormat(BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize,
- transformation);
+ /** Create a variant BipImageFormat from the given parameters */
+ public static BipImageFormat createVariant(
+ BipEncoding encoding, BipPixel pixel, int maxSize, BipTransformation transformation) {
+ return new BipImageFormat(
+ BipImageFormat.FORMAT_VARIANT, encoding, pixel, -1, maxSize, transformation);
}
- /**
- * The 'flavor' of this image format, from the format constants above.
- */
+ /** The 'flavor' of this image format, from the format constants above. */
private final int mFormatType;
- /**
- * The encoding method in which this image is available, required by the specification
- */
+ /** The encoding method in which this image is available, required by the specification */
private final BipEncoding mEncoding;
/**
@@ -90,30 +77,35 @@ public class BipImageFormat {
private final BipPixel mPixel;
/**
- * The list of supported image transformation methods, any of:
- * - 'stretch' : Image server is capable of stretching the image to fit a space
- * - 'fill' : Image server is capable of filling the image padding data to fit a space
- * - 'crop' : Image server is capable of cropping the image down to fit a space
+ * The list of supported image transformation methods, any of: - 'stretch' : Image server is
+ * capable of stretching the image to fit a space - 'fill' : Image server is capable of filling
+ * the image padding data to fit a space - 'crop' : Image server is capable of cropping the
+ * image down to fit a space
*
- * Used by the variant type only
+ *
Used by the variant type only
*/
private final BipTransformation mTransformation;
/**
* Size in bytes of the image.
*
- * Used by the native type only
+ *
Used by the native type only
*/
private final int mSize;
/**
* The estimated maximum size of an image after a transformation is performed.
*
- * Used by the variant type only
+ *
Used by the variant type only
*/
private final int mMaxSize;
- private BipImageFormat(int type, BipEncoding encoding, BipPixel pixel, int size, int maxSize,
+ private BipImageFormat(
+ int type,
+ BipEncoding encoding,
+ BipPixel pixel,
+ int size,
+ int maxSize,
BipTransformation transformation) {
mFormatType = type;
mEncoding = Objects.requireNonNull(encoding, "Encoding cannot be null");
@@ -123,7 +115,12 @@ public class BipImageFormat {
mMaxSize = maxSize;
}
- private BipImageFormat(int type, String encoding, String pixel, String size, String maxSize,
+ private BipImageFormat(
+ int type,
+ String encoding,
+ String pixel,
+ String size,
+ String maxSize,
String transformation) {
mFormatType = type;
mEncoding = new BipEncoding(encoding);
@@ -183,10 +180,14 @@ public class BipImageFormat {
@Override
public String toString() {
- if (mEncoding == null || mEncoding.getType() == BipEncoding.UNKNOWN || mPixel == null
+ if (mEncoding == null
+ || mEncoding.getType() == BipEncoding.UNKNOWN
+ || mPixel == null
|| mPixel.getType() == BipPixel.TYPE_UNKNOWN) {
- error("Missing required fields [ " + (mEncoding == null ? "encoding " : "")
- + (mPixel == null ? "pixel " : ""));
+ error(
+ "Missing required fields [ "
+ + (mEncoding == null ? "encoding " : "")
+ + (mPixel == null ? "pixel " : ""));
return null;
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
index 94ae058d2e0e9e281f0723eaae3403d12714f2e5..e5b1e5b88385a5091557b621b633f69534bfd66f 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipImageProperties.java
@@ -35,39 +35,33 @@ import java.util.Objects;
* Represents the return value of a BIP GetImageProperties request, giving a detailed description of
* an image and its available descriptors before download.
*
- * Format is as described by version 1.2.1 of the Basic Image Profile Specification. The
+ *
Format is as described by version 1.2.1 of the Basic Image Profile Specification. The
* specification describes three types of metadata that can arrive with an image -- native, variant
- * and attachment. Native describes which native formats a particular image is available in.
- * Variant describes which other types of encodings/sizes can be created from the native image using
- * various transformations. Attachments describes other items that can be downloaded that are
- * associated with the image (text, sounds, etc.)
+ * and attachment. Native describes which native formats a particular image is available in. Variant
+ * describes which other types of encodings/sizes can be created from the native image using various
+ * transformations. Attachments describes other items that can be downloaded that are associated
+ * with the image (text, sounds, etc.)
*
- * The specification requires that
- * 1. The fixed version string of "1.0" is used
- * 2. There is an image handle
- * 3. The "imaging thumbnail format" is included. This is defined for BIP in section 4.4.3
- * (160x120 JPEG) and redefined for AVRCP in section 5.14.2.2.1 I (200x200 JPEG). It can be
- * either a native or variant format.
+ *
The specification requires that 1. The fixed version string of "1.0" is used 2. There is an
+ * image handle 3. The "imaging thumbnail format" is included. This is defined for BIP in section
+ * 4.4.3 (160x120 JPEG) and redefined for AVRCP in section 5.14.2.2.1 I (200x200 JPEG). It can be
+ * either a native or variant format.
*
- * Example:
- *
- *
- *
- *
- *
- *
- *
- *
+ *
Example:
+ *
*/
public class BipImageProperties {
private static final String TAG = "avrcpcontroller.BipImageProperties";
private static final String sVersion = "1.0";
- /**
- * A Builder for a BipImageProperties object
- */
+ /** A Builder for a BipImageProperties object */
public static class Builder {
private BipImageProperties mProperties = new BipImageProperties();
+
/**
* Set the image handle field for the object you're building
*
@@ -133,14 +127,10 @@ public class BipImageProperties {
}
}
- /**
- * The image handle associated with this set of properties.
- */
+ /** The image handle associated with this set of properties. */
private String mImageHandle = null;
- /**
- * The version of the properties object, used to encode and decode.
- */
+ /** The version of the properties object, used to encode and decode. */
private String mVersion = null;
/**
@@ -148,15 +138,12 @@ public class BipImageProperties {
*/
private String mFriendlyName = null;
- /**
- * Whether we have the required imaging thumbnail format
- */
+ /** Whether we have the required imaging thumbnail format */
private boolean mHasThumbnailFormat = false;
- /**
- * The various sets of available formats.
- */
+ /** The various sets of available formats. */
private ArrayList mNativeFormats;
+
private ArrayList mVariantFormats;
private ArrayList mAttachments;
@@ -207,8 +194,8 @@ public class BipImageProperties {
String created = xpp.getAttributeValue(null, "created");
String modified = xpp.getAttributeValue(null, "modified");
addAttachment(
- new BipAttachmentFormat(contentType, charset, name, size,
- created, modified));
+ new BipAttachmentFormat(
+ contentType, charset, name, size, created, modified));
} else {
warn("Unrecognized tag in x-bt/img-properties object: " + tag);
}
@@ -254,8 +241,12 @@ public class BipImageProperties {
private void addNativeFormat(BipImageFormat format) {
Objects.requireNonNull(format);
if (format.getType() != BipImageFormat.FORMAT_NATIVE) {
- throw new IllegalArgumentException("Format type '" + format.getType()
- + "' but expected '" + BipImageFormat.FORMAT_NATIVE + "'");
+ throw new IllegalArgumentException(
+ "Format type '"
+ + format.getType()
+ + "' but expected '"
+ + BipImageFormat.FORMAT_NATIVE
+ + "'");
}
mNativeFormats.add(format);
@@ -267,8 +258,12 @@ public class BipImageProperties {
private void addVariantFormat(BipImageFormat format) {
Objects.requireNonNull(format);
if (format.getType() != BipImageFormat.FORMAT_VARIANT) {
- throw new IllegalArgumentException("Format type '" + format.getType()
- + "' but expected '" + BipImageFormat.FORMAT_VARIANT + "'");
+ throw new IllegalArgumentException(
+ "Format type '"
+ + format.getType()
+ + "' but expected '"
+ + BipImageFormat.FORMAT_VARIANT
+ + "'");
}
mVariantFormats.add(format);
@@ -399,7 +394,7 @@ public class BipImageProperties {
/**
* Serialize this object into a byte array
*
- * Objects that are not valid will fail to serialize and return null.
+ * Objects that are not valid will fail to serialize and return null.
*
* @return Byte array representing this object, ready to send over OBEX, or null on error.
*/
@@ -415,10 +410,8 @@ public class BipImageProperties {
/**
* Determine if the contents of this BipImageProperties object are valid and meet the
- * specification requirements:
- * 1. Include the fixed 1.0 version
- * 2. Include an image handle
- * 3. Have the thumbnail format as either the native or variant
+ * specification requirements: 1. Include the fixed 1.0 version 2. Include an image handle 3.
+ * Have the thumbnail format as either the native or variant
*
* @return True if our contents are valid, false otherwise
*/
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
index bba0cefaeb58d1ae9dcab1f3fdb613405370b12c..f3be13363d85bef3b52560d398d2d005098a07af 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipPixel.java
@@ -22,27 +22,27 @@ import java.util.regex.Pattern;
/**
* The pixel size or range of pixel sizes in which the image is available
*
- * A FIXED size is represented as the following, where W is width and H is height. The domain
- * of values is [0, 65535]
+ *
A FIXED size is represented as the following, where W is width and H is height. The domain of
+ * values is [0, 65535]
*
- * W*H
+ *
W*H
*
- * A RESIZABLE size that allows a modified aspect ratio is represented as the following, where
- * W_1*H_1 is the minimum width and height pair and W2*H2 is the maximum width and height pair.
- * The domain of values is [0, 65535]
+ *
A RESIZABLE size that allows a modified aspect ratio is represented as the following, where
+ * W_1*H_1 is the minimum width and height pair and W2*H2 is the maximum width and height pair. The
+ * domain of values is [0, 65535]
*
- * W_1*H_1-W2*H2
+ *
W_1*H_1-W2*H2
*
- * A RESIZABLE size that allows a fixed aspect ratio is represented as the following, where
- * W_1 is the minimum width and W2*H2 is the maximum width and height pair.
- * The domain of values is [0, 65535]
+ *
A RESIZABLE size that allows a fixed aspect ratio is represented as the following, where W_1
+ * is the minimum width and W2*H2 is the maximum width and height pair. The domain of values is [0,
+ * 65535]
*
- * W_1**-W2*H2
+ *
W_1**-W2*H2
*
- * For each possible intermediate width value, the corresponding height is calculated using the
+ *
For each possible intermediate width value, the corresponding height is calculated using the
* formula
*
- * H=(W*H2)/W2
+ *
H=(W*H2)/W2
*/
public class BipPixel {
private static final String TAG = "avrcpcontroller.BipPixel";
@@ -64,37 +64,33 @@ public class BipPixel {
private final int mMaxWidth;
private final int mMaxHeight;
- /**
- * Create a fixed size BipPixel object
- */
+ /** Create a fixed size BipPixel object */
public static BipPixel createFixed(int width, int height) {
return new BipPixel(TYPE_FIXED, width, height, width, height);
}
- /**
- * Create a resizable modifiable aspect ratio BipPixel object
- */
- public static BipPixel createResizableModified(int minWidth, int minHeight, int maxWidth,
- int maxHeight) {
- return new BipPixel(TYPE_RESIZE_MODIFIED_ASPECT_RATIO, minWidth, minHeight, maxWidth,
- maxHeight);
+ /** Create a resizable modifiable aspect ratio BipPixel object */
+ public static BipPixel createResizableModified(
+ int minWidth, int minHeight, int maxWidth, int maxHeight) {
+ return new BipPixel(
+ TYPE_RESIZE_MODIFIED_ASPECT_RATIO, minWidth, minHeight, maxWidth, maxHeight);
}
- /**
- * Create a resizable fixed aspect ratio BipPixel object
- */
+ /** Create a resizable fixed aspect ratio BipPixel object */
public static BipPixel createResizableFixed(int minWidth, int maxWidth, int maxHeight) {
int minHeight = (minWidth * maxHeight) / maxWidth;
- return new BipPixel(TYPE_RESIZE_FIXED_ASPECT_RATIO, minWidth, minHeight,
- maxWidth, maxHeight);
+ return new BipPixel(
+ TYPE_RESIZE_FIXED_ASPECT_RATIO, minWidth, minHeight, maxWidth, maxHeight);
}
/**
* Directly create a BipPixel object knowing your exact type and dimensions. Internal use only
*/
private BipPixel(int type, int minWidth, int minHeight, int maxWidth, int maxHeight) {
- if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth)
- || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) {
+ if (isDimensionInvalid(minWidth)
+ || isDimensionInvalid(maxWidth)
+ || isDimensionInvalid(minHeight)
+ || isDimensionInvalid(maxHeight)) {
throw new IllegalArgumentException("Dimension's must be in [0, " + PIXEL_MAX + "]");
}
@@ -105,9 +101,7 @@ public class BipPixel {
mMaxHeight = maxHeight;
}
- /**
- * Create a BipPixel object from an Image Format pixel attribute string
- */
+ /** Create a BipPixel object from an Image Format pixel attribute string */
public BipPixel(String pixel) {
int type = TYPE_UNKNOWN;
int minWidth = -1;
@@ -129,8 +123,8 @@ public class BipPixel {
}
break;
case TYPE_RESIZE_MODIFIED_ASPECT_RATIO:
- Pattern modifiedRatio = Pattern.compile(
- "^(\\d{1,5})\\*(\\d{1,5})-(\\d{1,5})\\*(\\d{1,5})$");
+ Pattern modifiedRatio =
+ Pattern.compile("^(\\d{1,5})\\*(\\d{1,5})-(\\d{1,5})\\*(\\d{1,5})$");
Matcher m2 = modifiedRatio.matcher(pixel);
if (m2.matches()) {
type = TYPE_RESIZE_MODIFIED_ASPECT_RATIO;
@@ -157,8 +151,10 @@ public class BipPixel {
if (type == TYPE_UNKNOWN) {
throw new ParseException("Failed to determine type of '" + pixel + "'");
}
- if (isDimensionInvalid(minWidth) || isDimensionInvalid(maxWidth)
- || isDimensionInvalid(minHeight) || isDimensionInvalid(maxHeight)) {
+ if (isDimensionInvalid(minWidth)
+ || isDimensionInvalid(maxWidth)
+ || isDimensionInvalid(minHeight)
+ || isDimensionInvalid(maxHeight)) {
throw new ParseException("Parsed dimensions must be in [0, " + PIXEL_MAX + "]");
}
@@ -193,8 +189,8 @@ public class BipPixel {
* Determines the type of the pixel string by counting the number of '*' delimiters in the
* string.
*
- * Note that the overall maximum size of any pixel string is 23 characters in length due to the
- * max size of each dimension
+ *
Note that the overall maximum size of any pixel string is 23 characters in length due to
+ * the max size of each dimension
*
* @return The corresponding type we should assume the given pixel string is
*/
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java
index 82b9fe972933b92e1b8b57d4ea261a96845689cb..88fca6aa1a8c3d14e7f43308e6307cb2e946ac5f 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipRequest.java
@@ -27,9 +27,7 @@ import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
-/**
- * This is a base class for implementing AVRCP Controller Basic Image Profile (BIP) requests
- */
+/** This is a base class for implementing AVRCP Controller Basic Image Profile (BIP) requests */
abstract class BipRequest {
private static final String TAG = BipRequest.class.getSimpleName();
@@ -53,15 +51,15 @@ abstract class BipRequest {
/**
* A function that returns the type of the request.
*
- * Used to determine type instead of using 'instanceof'
+ *
Used to determine type instead of using 'instanceof'
*/
public abstract int getType();
/**
* A single point of entry for kicking off a AVRCP BIP request.
*
- * Child classes are expected to implement this interface, filling in the details of the request
- * (headers, operation type, error handling, etc).
+ *
Child classes are expected to implement this interface, filling in the details of the
+ * request (headers, operation type, error handling, etc).
*/
public abstract void execute(ClientSession session) throws IOException;
@@ -90,9 +88,7 @@ abstract class BipRequest {
debug("GET final response code is '" + mResponseCode + "'");
}
- /**
- * A generica PUT operation, providing overridable hooks to read response headers.
- */
+ /** A generica PUT operation, providing overridable hooks to read response headers. */
protected void executePut(ClientSession session, byte[] body) throws IOException {
debug("Exeucting PUT");
setOperation(null);
@@ -157,23 +153,17 @@ abstract class BipRequest {
return TAG + " (type: " + getType() + ", mResponseCode: " + mResponseCode + ")";
}
- /**
- * Print to debug if debug is enabled for this class
- */
+ /** Print to debug if debug is enabled for this class */
protected void debug(String msg) {
Log.d(TAG, msg);
}
- /**
- * Print to warn
- */
+ /** Print to warn */
protected void warn(String msg) {
Log.w(TAG, msg);
}
- /**
- * Print to error
- */
+ /** Print to error */
protected void error(String msg) {
Log.e(TAG, msg);
}
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
index 9922f61f6dfedc5b07eee792fa0fcca08fd77136..bb2e7ecb496b812d19bde8ec71adaf8939682b51 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/BipTransformation.java
@@ -24,20 +24,15 @@ import java.util.HashSet;
* Represents the set of possible transformations available for a variant of an image to get the
* image to a particular pixel size.
*
- * The transformations supported by BIP v1.2.1 include:
- * - Stretch
- * - Fill
- * - Crop
+ *
The transformations supported by BIP v1.2.1 include: - Stretch - Fill - Crop
*
- * Example in an image properties/format:
- *
- *
- *
+ *
Example in an image properties/format:
*
- * Example in an image descriptor:
- *
- *
- *
+ *
Example in an image descriptor:
*/
public class BipTransformation {
private static final String TAG = "avrcpcontroller.BipTransformation";
@@ -49,15 +44,10 @@ public class BipTransformation {
public final HashSet mSupportedTransformations = new HashSet(3);
- /**
- * Create an empty set of BIP Transformations
- */
- public BipTransformation() {
- }
+ /** Create an empty set of BIP Transformations */
+ public BipTransformation() {}
- /**
- * Create a set of BIP Transformations from an attribute value from an Image Format string
- */
+ /** Create a set of BIP Transformations from an attribute value from an Image Format string */
public BipTransformation(String transformations) {
if (transformations == null) return;
@@ -81,16 +71,12 @@ public class BipTransformation {
}
}
- /**
- * Create a set of BIP Transformations from a single supported transformation
- */
+ /** Create a set of BIP Transformations from a single supported transformation */
public BipTransformation(int transformation) {
addTransformation(transformation);
}
- /**
- * Create a set of BIP Transformations from a set of supported transformations
- */
+ /** Create a set of BIP Transformations from a set of supported transformations */
public BipTransformation(int[] transformations) {
for (int transformation : transformations) {
addTransformation(transformation);
@@ -104,8 +90,8 @@ public class BipTransformation {
*/
public void addTransformation(int transformation) {
if (!isValid(transformation)) {
- throw new IllegalArgumentException("Invalid transformation ID '" + transformation
- + "'");
+ throw new IllegalArgumentException(
+ "Invalid transformation ID '" + transformation + "'");
}
mSupportedTransformations.add(transformation);
}
@@ -117,8 +103,8 @@ public class BipTransformation {
*/
public void removeTransformation(int transformation) {
if (!isValid(transformation)) {
- throw new IllegalArgumentException("Invalid transformation ID '" + transformation
- + "'");
+ throw new IllegalArgumentException(
+ "Invalid transformation ID '" + transformation + "'");
}
mSupportedTransformations.remove(transformation);
}
@@ -127,7 +113,7 @@ public class BipTransformation {
* Determine if a given transformations is valid
*
* @param transformation The integer encoding ID of the transformation. Should be one of the
- * BipTransformation.* constants, but doesn't *have* to be
+ * BipTransformation.* constants, but doesn't *have* to be
* @return True if the transformation constant is valid, False otherwise
*/
private boolean isValid(int transformation) {
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
index 8dbb736e188522474b8176ab0f18f694433230fd..bd23be2972130b4605b3c02046f23b251a33945a 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/ParseException.java
@@ -16,9 +16,7 @@
package com.android.bluetooth.avrcpcontroller;
-/**
- * Thrown when has parsing.
- */
+/** Thrown when has parsing. */
public class ParseException extends RuntimeException {
public ParseException(String msg) {
super(msg);
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java
index fc5f49960b494d405d5ea3432ecafdfba814c711..79ad37c21d269044638dac962d1b89fc0a35a5be 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImage.java
@@ -30,8 +30,7 @@ import java.io.InputStream;
public class RequestGetImage extends BipRequest {
// Expected inputs
private final String mImageHandle;
- @VisibleForTesting
- final BipImageDescriptor mImageDescriptor;
+ @VisibleForTesting final BipImageDescriptor mImageDescriptor;
// Expected return type
private static final String TYPE = "x-bt/img-img";
diff --git a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java
index ad809e0997a1283523c9391a89be12cc28f7c146..1b6fa1836b9ecf16ef246b70269b1900d853907c 100644
--- a/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java
+++ b/android/app/src/com/android/bluetooth/avrcpcontroller/bip/RequestGetImageProperties.java
@@ -59,8 +59,11 @@ public class RequestGetImageProperties extends BipRequest {
protected void readResponse(InputStream stream) throws IOException {
try {
mImageProperties = new BipImageProperties(stream);
- debug("Response GetImageProperties - handle: " + mImageHandle + ", properties: "
- + mImageProperties.toString());
+ debug(
+ "Response GetImageProperties - handle: "
+ + mImageHandle
+ + ", properties: "
+ + mImageProperties.toString());
} catch (ParseException e) {
error("Failed to parse incoming properties object");
mImageProperties = null;
diff --git a/android/app/src/com/android/bluetooth/bas/BatteryService.java b/android/app/src/com/android/bluetooth/bas/BatteryService.java
index 94d505bee3805b7033e305c2e90f17f37a97971b..b062849a63ee845af310bf458901aa7116db2895 100644
--- a/android/app/src/com/android/bluetooth/bas/BatteryService.java
+++ b/android/app/src/com/android/bluetooth/bas/BatteryService.java
@@ -48,9 +48,7 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
-/**
- * A profile service that connects to the Battery service (BAS) of BLE devices
- */
+/** A profile service that connects to the Battery service (BAS) of BLE devices */
public class BatteryService extends ProfileService {
private static final String TAG = "BatteryService";
@@ -85,10 +83,14 @@ public class BatteryService extends ProfileService {
throw new IllegalStateException("start() called twice");
}
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when BatteryService starts");
- mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
- "DatabaseManager cannot be null when BatteryService starts");
+ mAdapterService =
+ Objects.requireNonNull(
+ AdapterService.getAdapterService(),
+ "AdapterService cannot be null when BatteryService starts");
+ mDatabaseManager =
+ Objects.requireNonNull(
+ mAdapterService.getDatabase(),
+ "DatabaseManager cannot be null when BatteryService starts");
mHandler = new Handler(Looper.getMainLooper());
mStateMachines.clear();
@@ -117,7 +119,6 @@ public class BatteryService extends ProfileService {
mStateMachines.clear();
}
-
if (mStateMachinesThread != null) {
try {
mStateMachinesThread.quitSafely();
@@ -142,9 +143,7 @@ public class BatteryService extends ProfileService {
Log.d(TAG, "cleanup()");
}
- /**
- * Gets the BatteryService instance
- */
+ /** Gets the BatteryService instance */
public static synchronized BatteryService getBatteryService() {
if (sBatteryService == null) {
Log.w(TAG, "getBatteryService(): service is NULL");
@@ -158,22 +157,18 @@ public class BatteryService extends ProfileService {
return sBatteryService;
}
- /**
- * Sets the battery service instance. It should be called only for testing purpose.
- */
+ /** Sets the battery service instance. It should be called only for testing purpose. */
@VisibleForTesting
public static synchronized void setBatteryService(BatteryService instance) {
Log.d(TAG, "setBatteryService(): set to: " + instance);
sBatteryService = instance;
}
- /**
- * Connects to the battery service of the given device.
- */
+ /** Connects to the battery service of the given device. */
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean connect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
Log.d(TAG, "connect(): " + device);
if (device == null) {
Log.w(TAG, "Ignore connecting to null device");
@@ -186,8 +181,7 @@ public class BatteryService extends ProfileService {
}
ParcelUuid[] featureUuids = mAdapterService.getRemoteUuids(device);
if (!Utils.arrayContains(featureUuids, BluetoothUuid.BATTERY)) {
- Log.e(TAG, "Cannot connect to " + device
- + " : Remote does not have Battery UUID");
+ Log.e(TAG, "Cannot connect to " + device + " : Remote does not have Battery UUID");
return false;
}
@@ -204,8 +198,8 @@ public class BatteryService extends ProfileService {
}
/**
- * Connects to the battery service of the given device if possible.
- * If it's impossible, it doesn't try without logging errors.
+ * Connects to the battery service of the given device if possible. If it's impossible, it
+ * doesn't try without logging errors.
*/
public boolean connectIfPossible(BluetoothDevice device) {
if (device == null
@@ -217,13 +211,11 @@ public class BatteryService extends ProfileService {
return connect(device);
}
- /**
- * Disconnects from the battery service of the given device.
- */
+ /** Disconnects from the battery service of the given device. */
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean disconnect(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
Log.d(TAG, "disconnect(): " + device);
if (device == null) {
Log.w(TAG, "Ignore disconnecting to null device");
@@ -241,12 +233,13 @@ public class BatteryService extends ProfileService {
/**
* Gets devices that battery service is connected.
+ *
* @return
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public List getConnectedDevices() {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
synchronized (mStateMachines) {
List devices = new ArrayList<>();
for (BatteryStateMachine sm : mStateMachines.values()) {
@@ -259,8 +252,8 @@ public class BatteryService extends ProfileService {
}
/**
- * Check whether it can connect to a peer device.
- * The check considers a number of factors during the evaluation.
+ * Check whether it can connect to a peer device. The check considers a number of factors during
+ * the evaluation.
*
* @param device the peer device to connect to
* @return true if connection is allowed, otherwise false
@@ -284,16 +277,19 @@ public class BatteryService extends ProfileService {
return true;
}
- /**
- * Called when the connection state of a state machine is changed
- */
+ /** Called when the connection state of a state machine is changed */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
- public void handleConnectionStateChanged(BatteryStateMachine sm,
- int fromState, int toState) {
+ public void handleConnectionStateChanged(BatteryStateMachine sm, int fromState, int toState) {
BluetoothDevice device = sm.getDevice();
if ((sm == null) || (fromState == toState)) {
- Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device
- + " fromState=" + fromState + " toState=" + toState);
+ Log.e(
+ TAG,
+ "connectionStateChanged: unexpected invocation. device="
+ + device
+ + " fromState="
+ + fromState
+ + " toState="
+ + toState);
return;
}
@@ -309,8 +305,8 @@ public class BatteryService extends ProfileService {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
List getDevicesMatchingConnectionStates(int[] states) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
ArrayList devices = new ArrayList<>();
if (states == null) {
return devices;
@@ -353,13 +349,10 @@ public class BatteryService extends ProfileService {
}
}
- /**
- * Gets the connection state of the given device's battery service
- */
+ /** Gets the connection state of the given device's battery service */
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_CONNECT,
- "Need BLUETOOTH_CONNECT permission");
+ enforceCallingOrSelfPermission(BLUETOOTH_CONNECT, "Need BLUETOOTH_CONNECT permission");
synchronized (mStateMachines) {
BatteryStateMachine sm = mStateMachines.get(device);
if (sm == null) {
@@ -370,15 +363,14 @@ public class BatteryService extends ProfileService {
}
/**
- * Set connection policy of the profile and connects it if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
+ * Set connection policy of the profile and connects it if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED} or disconnects if connectionPolicy is {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}
*
- * The device should already be paired.
- * Connection policy can be one of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The device should already be paired. Connection policy can be one of: {@link
+ * BluetoothProfile#CONNECTION_POLICY_ALLOWED}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device the remote device
* @param connectionPolicy is the connection policy to set to for this profile
@@ -386,11 +378,11 @@ public class BatteryService extends ProfileService {
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
- mDatabaseManager.setProfileConnectionPolicy(device, BluetoothProfile.BATTERY,
- connectionPolicy);
+ mDatabaseManager.setProfileConnectionPolicy(
+ device, BluetoothProfile.BATTERY, connectionPolicy);
if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
connect(device);
} else if (connectionPolicy == BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
@@ -399,21 +391,18 @@ public class BatteryService extends ProfileService {
return true;
}
- /**
- * Gets the connection policy for the battery service of the given device.
- */
+ /** Gets the connection policy for the battery service of the given device. */
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
public int getConnectionPolicy(BluetoothDevice device) {
- enforceCallingOrSelfPermission(BLUETOOTH_PRIVILEGED,
- "Need BLUETOOTH_PRIVILEGED permission");
+ enforceCallingOrSelfPermission(
+ BLUETOOTH_PRIVILEGED, "Need BLUETOOTH_PRIVILEGED permission");
return mDatabaseManager.getProfileConnectionPolicy(device, BluetoothProfile.BATTERY);
}
- /**
- * Called when the battery level of the device is notified.
- */
+
+ /** Called when the battery level of the device is notified. */
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public void handleBatteryChanged(BluetoothDevice device, int batteryLevel) {
- mAdapterService.setBatteryLevel(device, batteryLevel, /*isBas=*/ true);
+ mAdapterService.setBatteryLevel(device, batteryLevel, /* isBas= */ true);
}
private BatteryStateMachine getOrCreateStateMachine(BluetoothDevice device) {
@@ -428,8 +417,10 @@ public class BatteryService extends ProfileService {
}
// Limit the maximum number of state machines to avoid DoS attack
if (mStateMachines.size() >= MAX_BATTERY_STATE_MACHINES) {
- Log.e(TAG, "Maximum number of Battery state machines reached: "
- + MAX_BATTERY_STATE_MACHINES);
+ Log.e(
+ TAG,
+ "Maximum number of Battery state machines reached: "
+ + MAX_BATTERY_STATE_MACHINES);
return null;
}
Log.d(TAG, "Creating a new state machine for " + device);
@@ -480,8 +471,9 @@ public class BatteryService extends ProfileService {
synchronized (mStateMachines) {
BatteryStateMachine sm = mStateMachines.remove(device);
if (sm == null) {
- Log.w(TAG, "removeStateMachine: device " + device
- + " does not have a state machine");
+ Log.w(
+ TAG,
+ "removeStateMachine: device " + device + " does not have a state machine");
return;
}
Log.i(TAG, "removeGatt: removing bluetooth gatt for device: " + device);
@@ -490,9 +482,7 @@ public class BatteryService extends ProfileService {
}
}
- /**
- * Binder object: must be a static class or memory leak may occur
- */
+ /** Binder object: must be a static class or memory leak may occur */
@VisibleForTesting
static class BluetoothBatteryBinder extends IBluetoothBattery.Stub
implements IProfileServiceBinder {
diff --git a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
index 218cff125e14ed0d31b7d9a55765d030b4697231..cd0332f17368df6ab9e517d132ee6f1797de4c28 100644
--- a/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bas/BatteryStateMachine.java
@@ -44,9 +44,7 @@ import java.lang.ref.WeakReference;
import java.util.Scanner;
import java.util.UUID;
-/**
- * It manages Battery service of a BLE device
- */
+/** It manages Battery service of a BLE device */
public class BatteryStateMachine extends StateMachine {
private static final String TAG = "BatteryStateMachine";
@@ -63,8 +61,7 @@ public class BatteryStateMachine extends StateMachine {
private static final int CONNECT_TIMEOUT = 201;
// NOTE: the value is not "final" - it is modified in the unit tests
- @VisibleForTesting
- static int sConnectTimeoutMs = 30000; // 30s
+ @VisibleForTesting static int sConnectTimeoutMs = 30000; // 30s
private Disconnected mDisconnected;
private Connecting mConnecting;
@@ -103,17 +100,13 @@ public class BatteryStateMachine extends StateMachine {
return sm;
}
- /**
- * Quits the state machine
- */
+ /** Quits the state machine */
public void doQuit() {
log("doQuit for device " + mDevice);
quitNow();
}
- /**
- * Cleans up the resources the state machine held.
- */
+ /** Cleans up the resources the state machine held. */
public void cleanup() {
log("cleanup for device " + mDevice);
if (mBluetoothGatt != null) {
@@ -163,9 +156,7 @@ public class BatteryStateMachine extends StateMachine {
return Integer.toString(state);
}
- /**
- * Dumps battery state machine state.
- */
+ /** Dumps battery state machine state. */
public void dump(StringBuilder sb) {
ProfileService.println(sb, "mDevice: " + mDevice);
ProfileService.println(sb, " StateMachine: " + this);
@@ -173,7 +164,7 @@ public class BatteryStateMachine extends StateMachine {
// Dump the state machine logs
StringWriter stringWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(stringWriter);
- super.dump(new FileDescriptor(), printWriter, new String[]{});
+ super.dump(new FileDescriptor(), printWriter, new String[] {});
printWriter.flush();
stringWriter.flush();
ProfileService.println(sb, " StateMachineLog:");
@@ -204,8 +195,13 @@ public class BatteryStateMachine extends StateMachine {
}
void dispatchConnectionStateChanged(int fromState, int toState) {
- log("Connection state " + mDevice + ": " + profileStateToString(fromState)
- + "->" + profileStateToString(toState));
+ log(
+ "Connection state "
+ + mDevice
+ + ": "
+ + profileStateToString(fromState)
+ + "->"
+ + profileStateToString(toState));
BatteryService service = mServiceRef.get();
if (service != null) {
@@ -232,9 +228,15 @@ public class BatteryStateMachine extends StateMachine {
Log.w(TAG, "Trying connectGatt with existing BluetoothGatt instance.");
mBluetoothGatt.close();
}
- mBluetoothGatt = mDevice.connectGatt(service, /*autoConnect=*/false,
- mGattCallback, TRANSPORT_LE, /*opportunistic=*/true,
- PHY_LE_1M_MASK | PHY_LE_2M_MASK, getHandler());
+ mBluetoothGatt =
+ mDevice.connectGatt(
+ service,
+ /* autoConnect= */ false,
+ mGattCallback,
+ TRANSPORT_LE,
+ /* opportunistic= */ true,
+ PHY_LE_1M_MASK | PHY_LE_2M_MASK,
+ getHandler());
return mBluetoothGatt != null;
}
@@ -274,8 +276,7 @@ public class BatteryStateMachine extends StateMachine {
@Override
public void enter() {
- log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(
- getCurrentMessage().what));
+ log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
if (mBluetoothGatt != null) {
mBluetoothGatt.close();
@@ -284,22 +285,20 @@ public class BatteryStateMachine extends StateMachine {
if (mLastConnectionState != BluetoothProfile.STATE_DISCONNECTED) {
// Don't broadcast during startup
- dispatchConnectionStateChanged(mLastConnectionState,
- BluetoothProfile.STATE_DISCONNECTED);
+ dispatchConnectionStateChanged(
+ mLastConnectionState, BluetoothProfile.STATE_DISCONNECTED);
}
}
@Override
public void exit() {
- log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(
- getCurrentMessage().what));
+ log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED;
}
@Override
public boolean processMessage(Message message) {
- log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(
- message.what));
+ log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what));
BatteryService service = mServiceRef.get();
switch (message.what) {
@@ -309,13 +308,15 @@ public class BatteryStateMachine extends StateMachine {
if (connectGatt()) {
transitionTo(mConnecting);
} else {
- Log.w(TAG, "Battery connecting request rejected due to "
- + "GATT connection rejection: " + mDevice);
+ Log.w(
+ TAG,
+ "Battery connecting request rejected due to "
+ + "GATT connection rejection: "
+ + mDevice);
}
} else {
// Reject the request and stay in Disconnected state
- Log.w(TAG, "Battery connecting request rejected: "
- + mDevice);
+ Log.w(TAG, "Battery connecting request rejected: " + mDevice);
}
break;
case DISCONNECT:
@@ -346,24 +347,22 @@ public class BatteryStateMachine extends StateMachine {
@VisibleForTesting
class Connecting extends State {
private static final String TAG = "BASM_Connecting";
+
@Override
public void enter() {
- log(TAG, "Enter (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
dispatchConnectionStateChanged(mLastConnectionState, BluetoothProfile.STATE_CONNECTING);
}
@Override
public void exit() {
- log(TAG, "Exit (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_CONNECTING;
}
@Override
public boolean processMessage(Message message) {
- log(TAG, "process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(TAG, "process message(" + mDevice + "): " + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
@@ -409,31 +408,29 @@ public class BatteryStateMachine extends StateMachine {
@VisibleForTesting
class Disconnecting extends State {
private static final String TAG = "BASM_Disconnecting";
+
@Override
public void enter() {
- log(TAG, "Enter (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
sendMessageDelayed(CONNECT_TIMEOUT, sConnectTimeoutMs);
- dispatchConnectionStateChanged(mLastConnectionState,
- BluetoothProfile.STATE_DISCONNECTING);
+ dispatchConnectionStateChanged(
+ mLastConnectionState, BluetoothProfile.STATE_DISCONNECTING);
}
@Override
public void exit() {
- log(TAG, "Exit (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_DISCONNECTING;
removeMessages(CONNECT_TIMEOUT);
}
@Override
public boolean processMessage(Message message) {
- log(TAG, "Process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what));
switch (message.what) {
- //TODO: Check if connect while disconnecting is okay.
- // It is related to CONNECT_TIMEOUT as well.
+ // TODO: Check if connect while disconnecting is okay.
+ // It is related to CONNECT_TIMEOUT as well.
case CONNECT:
Log.w(TAG, "CONNECT ignored: " + mDevice);
break;
@@ -460,17 +457,17 @@ public class BatteryStateMachine extends StateMachine {
Log.i(TAG, "Disconnected: " + mDevice);
transitionTo(mDisconnected);
break;
- case BluetoothGatt.STATE_CONNECTED: {
- // Reject the connection and stay in Disconnecting state
- Log.w(TAG, "Incoming Battery connected request rejected: "
- + mDevice);
- if (mBluetoothGatt != null) {
- mBluetoothGatt.disconnect();
- } else {
- transitionTo(mDisconnected);
+ case BluetoothGatt.STATE_CONNECTED:
+ {
+ // Reject the connection and stay in Disconnecting state
+ Log.w(TAG, "Incoming Battery connected request rejected: " + mDevice);
+ if (mBluetoothGatt != null) {
+ mBluetoothGatt.disconnect();
+ } else {
+ transitionTo(mDisconnected);
+ }
+ break;
}
- break;
- }
default:
Log.e(TAG, "Incorrect state: " + state);
break;
@@ -481,10 +478,10 @@ public class BatteryStateMachine extends StateMachine {
@VisibleForTesting
class Connected extends State {
private static final String TAG = "BASM_Connected";
+
@Override
public void enter() {
- log(TAG, "Enter (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Enter (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
dispatchConnectionStateChanged(mLastConnectionState, BluetoothProfile.STATE_CONNECTED);
if (mBluetoothGatt != null) {
@@ -494,8 +491,7 @@ public class BatteryStateMachine extends StateMachine {
@Override
public void exit() {
- log(TAG, "Exit (" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(TAG, "Exit (" + mDevice + "): " + messageWhatToString(getCurrentMessage().what));
// Reset the battery level only after connected
resetBatteryLevel();
mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
@@ -503,8 +499,7 @@ public class BatteryStateMachine extends StateMachine {
@Override
public boolean processMessage(Message message) {
- log(TAG, "Process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(TAG, "Process message(" + mDevice + "): " + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
@@ -577,16 +572,19 @@ public class BatteryStateMachine extends StateMachine {
}
@Override
- public void onCharacteristicChanged(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, byte[] value) {
+ public void onCharacteristicChanged(
+ BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, byte[] value) {
if (GATT_BATTERY_LEVEL_CHARACTERISTIC_UUID.equals(characteristic.getUuid())) {
updateBatteryLevel(value);
}
}
@Override
- public void onCharacteristicRead(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, byte[] value, int status) {
+ public void onCharacteristicRead(
+ BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic,
+ byte[] value,
+ int status) {
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "Read characteristic failure on " + gatt + " " + characteristic);
return;
@@ -597,18 +595,19 @@ public class BatteryStateMachine extends StateMachine {
BluetoothGattDescriptor cccd =
characteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG_DESCRIPTOR_UUID);
if (cccd != null) {
- gatt.setCharacteristicNotification(characteristic, /*enable=*/true);
+ gatt.setCharacteristicNotification(characteristic, /* enable= */ true);
gatt.writeDescriptor(cccd, BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
} else {
- Log.w(TAG, "No CCCD for battery level characteristic, "
- + "it won't be notified");
+ Log.w(
+ TAG,
+ "No CCCD for battery level characteristic, " + "it won't be notified");
}
}
}
@Override
- public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
- int status) {
+ public void onDescriptorWrite(
+ BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
if (status != BluetoothGatt.GATT_SUCCESS) {
Log.w(TAG, "Failed to write descriptor " + descriptor.getUuid());
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BaseData.java b/android/app/src/com/android/bluetooth/bass_client/BaseData.java
index f98dda279c2d338d372e9f536d25d237a4f221c6..bd5a4dba5d3ea370e36f53b48b65ec4a133060de 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BaseData.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BaseData.java
@@ -30,9 +30,7 @@ import java.util.Map;
import java.util.MissingResourceException;
import java.util.Set;
-/**
- * Helper class to parse the Broadcast Announcement BASE data
- */
+/** Helper class to parse the Broadcast Announcement BASE data */
class BaseData {
private static final String TAG = "Bassclient-BaseData";
private static final byte UNKNOWN_CODEC = (byte) 0xFE;
@@ -143,8 +141,11 @@ class BaseData {
if (keyMetadataDiff != null) {
Iterator itr = keyMetadataDiff.iterator();
for (int k = 0; itr.hasNext(); k++) {
- log("keyMetadataDiff:[" + k + "]:"
- + Arrays.toString(itr.next().getBytes()));
+ log(
+ "keyMetadataDiff:["
+ + k
+ + "]:"
+ + Arrays.toString(itr.next().getBytes()));
}
}
log("END: Level2: Key Metadata differentiators");
@@ -152,8 +153,11 @@ class BaseData {
if (keyCodecCfgDiff != null) {
Iterator itr = keyCodecCfgDiff.iterator();
for (int k = 0; itr.hasNext(); k++) {
- log("LEVEL2: keyCodecCfgDiff:[" + k + "]:"
- + Arrays.toString(itr.next().getBytes()));
+ log(
+ "LEVEL2: keyCodecCfgDiff:["
+ + k
+ + "]:"
+ + Arrays.toString(itr.next().getBytes()));
}
}
log("END: Level2: Key CodecConfig differentiators");
@@ -164,8 +168,11 @@ class BaseData {
if (keyCodecCfgDiff != null) {
Iterator itr = keyCodecCfgDiff.iterator();
for (int k = 0; itr.hasNext(); k++) {
- log("LEVEL3: keyCodecCfgDiff:[" + k + "]:"
- + Arrays.toString(itr.next().getBytes()));
+ log(
+ "LEVEL3: keyCodecCfgDiff:["
+ + k
+ + "]:"
+ + Arrays.toString(itr.next().getBytes()));
}
}
log("END: Level3: Key CodecConfig differentiators");
@@ -176,8 +183,11 @@ class BaseData {
}
}
- BaseData(BaseInformation levelOne, ArrayList levelTwo,
- ArrayList levelThree, int numOfBISIndices) {
+ BaseData(
+ BaseInformation levelOne,
+ ArrayList levelTwo,
+ ArrayList levelThree,
+ int numOfBISIndices) {
mLevelOne = levelOne;
mLevelTwo = levelTwo;
mLevelThree = levelThree;
@@ -204,8 +214,7 @@ class BaseData {
levelOne.print();
log("levelOne subgroups" + levelOne.numSubGroups);
for (int i = 0; i < (int) levelOne.numSubGroups; i++) {
- Pair pair1 =
- parseLevelTwo(serviceData, i, offset);
+ Pair pair1 = parseLevelTwo(serviceData, i, offset);
BaseInformation node2 = pair1.first;
if (node2 == null) {
Log.e(TAG, "Error: parsing Level 2");
@@ -216,8 +225,7 @@ class BaseData {
node2.print();
offset = pair1.second;
for (int k = 0; k < node2.numSubGroups; k++) {
- Pair pair2 =
- parseLevelThree(serviceData, offset);
+ Pair pair2 = parseLevelThree(serviceData, offset);
BaseInformation node3 = pair2.first;
offset = pair2.second;
if (node3 == null) {
@@ -232,8 +240,8 @@ class BaseData {
return new BaseData(levelOne, levelTwo, levelThree, numOfBISIndices);
}
- private static Pair
- parseLevelTwo(byte[] serviceData, int groupIndex, int offset) {
+ private static Pair parseLevelTwo(
+ byte[] serviceData, int groupIndex, int offset) {
log("Parsing Level 2");
BaseInformation node = new BaseInformation();
node.level = METADATA_LEVEL2;
@@ -241,13 +249,16 @@ class BaseData {
node.numSubGroups = serviceData[offset++];
if (serviceData[offset] == (byte) UNKNOWN_CODEC) {
// Place It in the last byte of codecID
- System.arraycopy(serviceData, offset, node.codecId,
- METADATA_CODEC_LENGTH - 1, METADATA_UNKNOWN_CODEC_LENGTH);
+ System.arraycopy(
+ serviceData,
+ offset,
+ node.codecId,
+ METADATA_CODEC_LENGTH - 1,
+ METADATA_UNKNOWN_CODEC_LENGTH);
offset += METADATA_UNKNOWN_CODEC_LENGTH;
log("codecId is FE");
} else {
- System.arraycopy(serviceData, offset, node.codecId,
- 0, METADATA_CODEC_LENGTH);
+ System.arraycopy(serviceData, offset, node.codecId, 0, METADATA_CODEC_LENGTH);
offset += METADATA_CODEC_LENGTH;
}
node.codecConfigLength = serviceData[offset++] & 0xff;
@@ -265,8 +276,7 @@ class BaseData {
return new Pair(node, offset);
}
- private static Pair
- parseLevelThree(byte[] serviceData, int offset) {
+ private static Pair parseLevelThree(byte[] serviceData, int offset) {
log("Parsing Level 3");
BaseInformation node = new BaseInformation();
node.level = METADATA_LEVEL3;
@@ -280,15 +290,15 @@ class BaseData {
return new Pair(node, offset);
}
- static void consolidateBaseofLevelTwo(ArrayList levelTwo,
- ArrayList levelThree) {
+ static void consolidateBaseofLevelTwo(
+ ArrayList levelTwo, ArrayList levelThree) {
int startIdx = 0;
int children = 0;
for (int i = 0; i < levelTwo.size(); i++) {
startIdx = startIdx + children;
children = children + levelTwo.get(i).numSubGroups;
- consolidateBaseofLevelThree(levelTwo, levelThree,
- i, startIdx, levelTwo.get(i).numSubGroups);
+ consolidateBaseofLevelThree(
+ levelTwo, levelThree, i, startIdx, levelTwo.get(i).numSubGroups);
}
// Eliminate Duplicates at Level 3
for (int i = 0; i < levelThree.size(); i++) {
@@ -339,14 +349,21 @@ class BaseData {
}
}
- static void consolidateBaseofLevelThree(ArrayList levelTwo,
- ArrayList levelThree, int parentSubgroup, int startIdx, int numNodes) {
+ static void consolidateBaseofLevelThree(
+ ArrayList levelTwo,
+ ArrayList levelThree,
+ int parentSubgroup,
+ int startIdx,
+ int numNodes) {
for (int i = startIdx; i < startIdx + numNodes || i < levelThree.size(); i++) {
levelThree.get(i).subGroupId = levelTwo.get(parentSubgroup).subGroupId;
log("Copy Codec Id from Level2 Parent" + parentSubgroup);
System.arraycopy(
levelTwo.get(parentSubgroup).consolidatedCodecId,
- 0, levelThree.get(i).consolidatedCodecId, 0, 5);
+ 0,
+ levelThree.get(i).consolidatedCodecId,
+ 0,
+ 5);
// Metadata clone from Parent
levelThree.get(i).consolidatedMetadata =
new LinkedHashSet(levelTwo.get(parentSubgroup).consolidatedMetadata);
@@ -366,7 +383,7 @@ class BaseData {
return mNumBISIndices;
}
- public BaseInformation getLevelOne() {
+ public BaseInformation getLevelOne() {
return mLevelOne;
}
@@ -433,8 +450,7 @@ class BaseData {
case CODEC_AUDIO_LOCATION_FRONT_RIGHT:
ret = "RIGHT";
break;
- case CODEC_AUDIO_LOCATION_FRONT_LEFT
- | CODEC_AUDIO_LOCATION_FRONT_RIGHT:
+ case CODEC_AUDIO_LOCATION_FRONT_LEFT | CODEC_AUDIO_LOCATION_FRONT_RIGHT:
ret = "LR";
break;
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
index 460555aae4cf08c45acb0d6682df97142a0c99fb..c912a8d60816f4b641093e99e1ce1b72868d5f6a 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientService.java
@@ -94,9 +94,7 @@ import java.util.Optional;
import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;
-/**
- * Broacast Assistant Scan Service
- */
+/** Broacast Assistant Scan Service */
public class BassClientService extends ProfileService {
private static final String TAG = BassClientService.class.getSimpleName();
private static final int MAX_BASS_CLIENT_STATE_MACHINES = 10;
@@ -183,8 +181,7 @@ public class BassClientService extends ProfileService {
new BluetoothEventLogger(LOG_NB_EVENTS, TAG + " event log");
;
- @VisibleForTesting
- ServiceFactory mServiceFactory = new ServiceFactory();
+ @VisibleForTesting ServiceFactory mServiceFactory = new ServiceFactory();
private final Handler mHandler =
new Handler(Looper.getMainLooper()) {
@@ -297,8 +294,16 @@ public class BassClientService extends ProfileService {
if (paResMap == null
|| (bId != BassConstants.INVALID_BROADCAST_ID && !paResMap.containsKey(bId))) {
log("PAResmap: add >>>");
- PeriodicAdvertisementResult paRes = new PeriodicAdvertisementResult(device,
- addressType, syncHandle, advSid, advInterval, bId, pbData, broadcastName);
+ PeriodicAdvertisementResult paRes =
+ new PeriodicAdvertisementResult(
+ device,
+ addressType,
+ syncHandle,
+ advSid,
+ advInterval,
+ bId,
+ pbData,
+ broadcastName);
if (paRes != null) {
paRes.print();
mPeriodicAdvertisementResultMap.putIfAbsent(device, new HashMap<>());
@@ -415,8 +420,11 @@ public class BassClientService extends ProfileService {
return;
}
- log("removeActiveSyncedSource, scanDelegator: " + scanDelegator + ", syncHandle: "
- + syncHandle);
+ log(
+ "removeActiveSyncedSource, scanDelegator: "
+ + scanDelegator
+ + ", syncHandle: "
+ + syncHandle);
if (syncHandle == null) {
// remove all sources for this scanDelegator
mActiveSourceMap.remove(scanDelegator);
@@ -429,8 +437,12 @@ public class BassClientService extends ProfileService {
}
}
}
- sEventLogger.logd(TAG, "Broadcast Source Unsynced: scanDelegator= " + scanDelegator
- + ", syncHandle= " + syncHandle);
+ sEventLogger.logd(
+ TAG,
+ "Broadcast Source Unsynced: scanDelegator= "
+ + scanDelegator
+ + ", syncHandle= "
+ + syncHandle);
}
void addActiveSyncedSource(BluetoothDevice scanDelegator, Integer syncHandle) {
@@ -444,16 +456,23 @@ public class BassClientService extends ProfileService {
return;
}
- log("addActiveSyncedSource, scanDelegator: " + scanDelegator + ", syncHandle: "
- + syncHandle);
+ log(
+ "addActiveSyncedSource, scanDelegator: "
+ + scanDelegator
+ + ", syncHandle: "
+ + syncHandle);
if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) {
mActiveSourceMap.putIfAbsent(scanDelegator, new ArrayList<>());
if (!mActiveSourceMap.get(scanDelegator).contains(syncHandle)) {
mActiveSourceMap.get(scanDelegator).add(syncHandle);
}
}
- sEventLogger.logd(TAG, "Broadcast Source Synced: scanDelegator= " + scanDelegator
- + ", syncHandle= " + syncHandle);
+ sEventLogger.logd(
+ TAG,
+ "Broadcast Source Synced: scanDelegator= "
+ + scanDelegator
+ + ", syncHandle= "
+ + syncHandle);
}
List getActiveSyncedSources(BluetoothDevice scanDelegator) {
@@ -469,11 +488,16 @@ public class BassClientService extends ProfileService {
List currentSources = mActiveSourceMap.get(scanDelegator);
if (currentSources != null) {
- log("getActiveSyncedSources: scanDelegator: " + scanDelegator
- + ", sources num: " + currentSources.size());
+ log(
+ "getActiveSyncedSources: scanDelegator: "
+ + scanDelegator
+ + ", sources num: "
+ + currentSources.size());
} else {
- log("getActiveSyncedSources: scanDelegator: " + scanDelegator
- + ", currentSources is null");
+ log(
+ "getActiveSyncedSources: scanDelegator: "
+ + scanDelegator
+ + ", currentSources is null");
}
return currentSources;
}
@@ -523,10 +547,14 @@ public class BassClientService extends ProfileService {
if (sService != null) {
throw new IllegalStateException("start() called twice");
}
- mAdapterService = Objects.requireNonNull(AdapterService.getAdapterService(),
- "AdapterService cannot be null when BassClientService starts");
- mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
- "DatabaseManager cannot be null when BassClientService starts");
+ mAdapterService =
+ Objects.requireNonNull(
+ AdapterService.getAdapterService(),
+ "AdapterService cannot be null when BassClientService starts");
+ mDatabaseManager =
+ Objects.requireNonNull(
+ mAdapterService.getDatabase(),
+ "DatabaseManager cannot be null when BassClientService starts");
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mStateMachines.clear();
@@ -726,8 +754,9 @@ public class BassClientService extends ProfileService {
continue;
}
- boolean isAnyPendingAddSourceOperationForDevice = operations.stream()
- .anyMatch(e -> e.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE));
+ boolean isAnyPendingAddSourceOperationForDevice =
+ operations.stream()
+ .anyMatch(e -> e.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE));
if (isAnyPendingAddSourceOperationForDevice) {
return true;
@@ -737,10 +766,15 @@ public class BassClientService extends ProfileService {
return false;
}
- private void checkForPendingGroupOpRequest(BluetoothDevice sink, int reason, int reqMsg,
- Object obj) {
- log("checkForPendingGroupOpRequest device: " + sink + ", reason: " + reason
- + ", reqMsg: " + reqMsg);
+ private void checkForPendingGroupOpRequest(
+ BluetoothDevice sink, int reason, int reqMsg, Object obj) {
+ log(
+ "checkForPendingGroupOpRequest device: "
+ + sink
+ + ", reason: "
+ + reason
+ + ", reqMsg: "
+ + reqMsg);
List> operations = mPendingGroupOp.get(sink);
if (operations == null) {
@@ -756,22 +790,30 @@ public class BassClientService extends ProfileService {
if (isSuccess(reason)) {
BluetoothLeBroadcastReceiveState sourceState =
(BluetoothLeBroadcastReceiveState) obj;
- boolean removed = operations.removeIf(m ->
- (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE))
- && (sourceState.getBroadcastId()
- == ((BluetoothLeBroadcastMetadata) m.second).getBroadcastId()));
+ boolean removed =
+ operations.removeIf(
+ m ->
+ (m.first.equals(
+ BassClientStateMachine
+ .ADD_BCAST_SOURCE))
+ && (sourceState.getBroadcastId()
+ == ((BluetoothLeBroadcastMetadata)
+ m.second)
+ .getBroadcastId()));
if (removed) {
setSourceGroupManaged(sink, sourceState.getSourceId(), true);
-
}
} else {
BluetoothLeBroadcastMetadata metadata = (BluetoothLeBroadcastMetadata) obj;
- operations.removeIf(m ->
- (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE))
- && (metadata.getBroadcastId()
- == ((BluetoothLeBroadcastMetadata) m.second).getBroadcastId()));
-
- if (!isAnyPendingAddSourceOperation() && mIsAssistantActive
+ operations.removeIf(
+ m ->
+ (m.first.equals(BassClientStateMachine.ADD_BCAST_SOURCE))
+ && (metadata.getBroadcastId()
+ == ((BluetoothLeBroadcastMetadata) m.second)
+ .getBroadcastId()));
+
+ if (!isAnyPendingAddSourceOperation()
+ && mIsAssistantActive
&& mPausedBroadcastSinks.isEmpty()) {
LeAudioService leAudioService = mServiceFactory.getLeAudioService();
mIsAssistantActive = false;
@@ -786,9 +828,10 @@ public class BassClientService extends ProfileService {
case BassClientStateMachine.REMOVE_BCAST_SOURCE:
// Identify the operation by operation type and sourceId
Integer sourceId = (Integer) obj;
- operations.removeIf(m ->
- m.first.equals(BassClientStateMachine.REMOVE_BCAST_SOURCE)
- && (sourceId.equals((Integer) m.second)));
+ operations.removeIf(
+ m ->
+ m.first.equals(BassClientStateMachine.REMOVE_BCAST_SOURCE)
+ && (sourceId.equals((Integer) m.second)));
setSourceGroupManaged(sink, sourceId, false);
break;
default:
@@ -913,14 +956,15 @@ public class BassClientService extends ProfileService {
if (metadata != null) {
int broadcastId = metadata.getBroadcastId();
- for (BluetoothDevice device: getTargetDeviceList(sink, true)) {
+ for (BluetoothDevice device : getTargetDeviceList(sink, true)) {
List sources =
getOrCreateStateMachine(device).getAllSources();
// For each device, find the source ID having this broadcast ID
- Optional receiver = sources.stream()
- .filter(e -> e.getBroadcastId() == broadcastId)
- .findAny();
+ Optional receiver =
+ sources.stream()
+ .filter(e -> e.getBroadcastId() == broadcastId)
+ .findAny();
if (receiver.isPresent()) {
map.put(device, receiver.get().getSourceId());
} else {
@@ -928,11 +972,15 @@ public class BassClientService extends ProfileService {
map.put(device, BassConstants.INVALID_SOURCE_ID);
}
}
- return new Pair>(metadata, map);
+ return new Pair>(
+ metadata, map);
} else {
- Log.e(TAG, "Couldn't find broadcast metadata for device: "
- + sink.getAnonymizedAddress() + ", and sourceId:" + sourceId);
+ Log.e(
+ TAG,
+ "Couldn't find broadcast metadata for device: "
+ + sink.getAnonymizedAddress()
+ + ", and sourceId:"
+ + sourceId);
}
}
@@ -946,8 +994,8 @@ public class BassClientService extends ProfileService {
CsipSetCoordinatorService csipClient = mServiceFactory.getCsipSetCoordinatorService();
if (csipClient != null) {
// Check for coordinated set of devices in the context of CAP
- List csipDevices = csipClient.getGroupDevicesOrdered(device,
- BluetoothUuid.CAP);
+ List csipDevices =
+ csipClient.getGroupDevicesOrdered(device, BluetoothUuid.CAP);
if (!csipDevices.isEmpty()) {
return csipDevices;
} else {
@@ -974,8 +1022,12 @@ public class BassClientService extends ProfileService {
&& metaData.getSourceAdvertisingSid() == state.getSourceAdvertisingSid()
&& metaData.getBroadcastId() == state.getBroadcastId()) {
retval = false;
- Log.e(TAG, "isValidBroadcastSourceAddition: fail for " + device
- + " metaData: " + metaData);
+ Log.e(
+ TAG,
+ "isValidBroadcastSourceAddition: fail for "
+ + device
+ + " metaData: "
+ + metaData);
break;
}
}
@@ -993,7 +1045,7 @@ public class BassClientService extends ProfileService {
}
boolean isRoomAvailable = false;
String emptyBluetoothDevice = "00:00:00:00:00:00";
- for (BluetoothLeBroadcastReceiveState recvState: stateMachine.getAllSources()) {
+ for (BluetoothLeBroadcastReceiveState recvState : stateMachine.getAllSources()) {
if (recvState.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) {
isRoomAvailable = true;
break;
@@ -1050,8 +1102,10 @@ public class BassClientService extends ProfileService {
}
// Limit the maximum number of state machines to avoid DoS attack
if (mStateMachines.size() >= MAX_BASS_CLIENT_STATE_MACHINES) {
- Log.e(TAG, "Maximum number of Bassclient state machines reached: "
- + MAX_BASS_CLIENT_STATE_MACHINES);
+ Log.e(
+ TAG,
+ "Maximum number of Bassclient state machines reached: "
+ + MAX_BASS_CLIENT_STATE_MACHINES);
return null;
}
log("Creating a new state machine for " + device);
@@ -1123,8 +1177,9 @@ public class BassClientService extends ProfileService {
synchronized (mStateMachines) {
BassClientStateMachine sm = mStateMachines.get(device);
if (sm == null) {
- Log.w(TAG, "removeStateMachine: device " + device
- + " does not have a state machine");
+ Log.w(
+ TAG,
+ "removeStateMachine: device " + device + " does not have a state machine");
return;
}
log("removeStateMachine: removing state machine for device: " + device);
@@ -1167,8 +1222,11 @@ public class BassClientService extends ProfileService {
synchronized (mStateMachines) {
BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
if (stateMachine == null) {
- Log.w(TAG, "informConnectedDeviceAboutScanOffloadStop: Can't get state "
- + "machine for device: " + device);
+ Log.w(
+ TAG,
+ "informConnectedDeviceAboutScanOffloadStop: Can't get state "
+ + "machine for device: "
+ + device);
continue;
}
stateMachine.sendMessage(BassClientStateMachine.STOP_SCAN_OFFLOAD);
@@ -1224,16 +1282,21 @@ public class BassClientService extends ProfileService {
mHandler.post(() -> connectionStateChanged(device, fromState, toState));
}
- synchronized void connectionStateChanged(BluetoothDevice device, int fromState,
- int toState) {
+ synchronized void connectionStateChanged(BluetoothDevice device, int fromState, int toState) {
if (!isAvailable()) {
Log.w(TAG, "connectionStateChanged: service is not available");
return;
}
if ((device == null) || (fromState == toState)) {
- Log.e(TAG, "connectionStateChanged: unexpected invocation. device=" + device
- + " fromState=" + fromState + " toState=" + toState);
+ Log.e(
+ TAG,
+ "connectionStateChanged: unexpected invocation. device="
+ + device
+ + " fromState="
+ + fromState
+ + " toState="
+ + toState);
return;
}
@@ -1389,6 +1452,7 @@ public class BassClientService extends ProfileService {
/**
* Get a list of all LE Audio Broadcast Sinks with the specified connection states.
+ *
* @param states states array representing the connection states
* @return a list of devices that match the provided connection states
*/
@@ -1404,8 +1468,7 @@ public class BassClientService extends ProfileService {
synchronized (mStateMachines) {
for (BluetoothDevice device : bondedDevices) {
final ParcelUuid[] featureUuids = device.getUuids();
- if (!Utils.arrayContains(
- featureUuids, BluetoothUuid.BASS)) {
+ if (!Utils.arrayContains(featureUuids, BluetoothUuid.BASS)) {
continue;
}
int connectionState = BluetoothProfile.STATE_DISCONNECTED;
@@ -1426,6 +1489,7 @@ public class BassClientService extends ProfileService {
/**
* Get a list of all LE Audio Broadcast Sinks connected with the LE Audio Broadcast Assistant.
+ *
* @return list of connected devices
*/
public List getConnectedDevices() {
@@ -1444,10 +1508,9 @@ public class BassClientService extends ProfileService {
/**
* Set the connectionPolicy of the Broadcast Audio Scan Service profile.
*
- * The connection policy can be one of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The connection policy can be one of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
+ * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device paired bluetooth device
* @param connectionPolicy is the connection policy to set to for this profile
@@ -1456,8 +1519,8 @@ public class BassClientService extends ProfileService {
public boolean setConnectionPolicy(BluetoothDevice device, int connectionPolicy) {
Log.d(TAG, "Saved connectionPolicy " + device + " = " + connectionPolicy);
boolean setSuccessfully =
- mDatabaseManager.setProfileConnectionPolicy(device,
- BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, connectionPolicy);
+ mDatabaseManager.setProfileConnectionPolicy(
+ device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, connectionPolicy);
if (setSuccessfully && connectionPolicy == BluetoothProfile.CONNECTION_POLICY_ALLOWED) {
connect(device);
} else if (setSuccessfully
@@ -1470,17 +1533,16 @@ public class BassClientService extends ProfileService {
/**
* Get the connection policy of the profile.
*
- *
The connection policy can be any of:
- * {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
- * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN},
- * {@link BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
+ *
The connection policy can be any of: {@link BluetoothProfile#CONNECTION_POLICY_ALLOWED},
+ * {@link BluetoothProfile#CONNECTION_POLICY_FORBIDDEN}, {@link
+ * BluetoothProfile#CONNECTION_POLICY_UNKNOWN}
*
* @param device paired bluetooth device
* @return connection policy of the device
*/
public int getConnectionPolicy(BluetoothDevice device) {
- return mDatabaseManager
- .getProfileConnectionPolicy(device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
+ return mDatabaseManager.getProfileConnectionPolicy(
+ device, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
}
/**
@@ -1619,29 +1681,35 @@ public class BassClientService extends ProfileService {
if (mPeriodicAdvertisementResultMap != null) {
clearNotifiedFlags();
}
- ScanSettings settings = new ScanSettings.Builder().setCallbackType(
- ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
- .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
- .setLegacy(false)
- .build();
+ ScanSettings settings =
+ new ScanSettings.Builder()
+ .setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
+ .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+ .setLegacy(false)
+ .build();
if (filters == null) {
filters = new ArrayList();
}
if (!BassUtils.containUuid(filters, BassConstants.BAAS_UUID)) {
- byte[] serviceData = {0x00, 0x00 ,0x00}; // Broadcast_ID
+ byte[] serviceData = {0x00, 0x00, 0x00}; // Broadcast_ID
byte[] serviceDataMask = {0x00, 0x00, 0x00};
- filters.add(new ScanFilter.Builder()
- .setServiceData(BassConstants.BAAS_UUID,
- serviceData, serviceDataMask).build());
+ filters.add(
+ new ScanFilter.Builder()
+ .setServiceData(
+ BassConstants.BAAS_UUID, serviceData, serviceDataMask)
+ .build());
}
for (BluetoothDevice device : getConnectedDevices()) {
synchronized (mStateMachines) {
BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
if (stateMachine == null) {
- Log.w(TAG, "startSearchingForSources: Can't get state machine for "
- + "device: " + device);
+ Log.w(
+ TAG,
+ "startSearchingForSources: Can't get state machine for "
+ + "device: "
+ + device);
continue;
}
stateMachine.sendMessage(BassClientStateMachine.START_SCAN_OFFLOAD);
@@ -1654,9 +1722,7 @@ public class BassClientService extends ProfileService {
}
}
- /**
- * Stops an ongoing search for nearby Broadcast Sources
- */
+ /** Stops an ongoing search for nearby Broadcast Sources */
public void stopSearchingForSources() {
log("stopSearchingForSources");
if (mBluetoothAdapter == null) {
@@ -1718,6 +1784,7 @@ public class BassClientService extends ProfileService {
/**
* Return true if a search has been started by this application
+ *
* @return true if a search has been started by this application
*/
public boolean isSearchInProgress() {
@@ -2241,8 +2308,8 @@ public class BassClientService extends ProfileService {
Log.e(TAG, "Can't get state machine for device: " + sink);
return;
}
- Message message = stateMachine.obtainMessage(
- BassClientStateMachine.SELECT_BCAST_SOURCE);
+ Message message =
+ stateMachine.obtainMessage(BassClientStateMachine.SELECT_BCAST_SOURCE);
message.obj = result;
message.arg1 = autoTrigger ? BassConstants.AUTO : BassConstants.USER;
stateMachine.sendMessage(message);
@@ -2258,9 +2325,7 @@ public class BassClientService extends ProfileService {
* coordinated set members, False otherwise
*/
public void addSource(
- BluetoothDevice sink,
- BluetoothLeBroadcastMetadata sourceMetadata,
- boolean isGroupOp) {
+ BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata, boolean isGroupOp) {
log(
"addSource: "
+ ("device: " + sink)
@@ -2333,14 +2398,14 @@ public class BassClientService extends ProfileService {
BassClientStateMachine stateMachine = getOrCreateStateMachine(device);
if (stateMachine == null) {
log("addSource: Error bad parameter: no state machine for " + device);
- mCallbacks.notifySourceAddFailed(device, sourceMetadata,
- BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
+ mCallbacks.notifySourceAddFailed(
+ device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
continue;
}
if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
log("addSource: device is not connected");
- mCallbacks.notifySourceAddFailed(device, sourceMetadata,
- BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
+ mCallbacks.notifySourceAddFailed(
+ device, sourceMetadata, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
continue;
}
if (stateMachine.hasPendingSourceOperation()) {
@@ -2395,16 +2460,20 @@ public class BassClientService extends ProfileService {
}
if (!isValidBroadcastSourceAddition(device, sourceMetadata)) {
log("addSource: not a valid broadcast source addition");
- mCallbacks.notifySourceAddFailed(device, sourceMetadata,
+ mCallbacks.notifySourceAddFailed(
+ device,
+ sourceMetadata,
BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_DUPLICATE_ADDITION);
continue;
}
if ((code != null) && (code.length != 0)) {
if ((code.length > 16) || (code.length < 4)) {
- log("Invalid broadcast code length: " + code.length
- + ", should be between 4 and 16 octets");
- mCallbacks.notifySourceAddFailed(device, sourceMetadata,
- BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
+ log(
+ "Invalid broadcast code length: "
+ + code.length
+ + ", should be between 4 and 16 octets");
+ mCallbacks.notifySourceAddFailed(
+ device, sourceMetadata, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
continue;
}
}
@@ -2413,8 +2482,8 @@ public class BassClientService extends ProfileService {
mBroadcastMetadataMap.put(device, sourceMetadata);
if (isGroupOp) {
- enqueueSourceGroupOp(device, BassClientStateMachine.ADD_BCAST_SOURCE,
- sourceMetadata);
+ enqueueSourceGroupOp(
+ device, BassClientStateMachine.ADD_BCAST_SOURCE, sourceMetadata);
}
sEventLogger.logd(
@@ -2463,8 +2532,8 @@ public class BassClientService extends ProfileService {
if (updatedMetadata == null) {
log("modifySource: Error bad parameters: updatedMetadata cannot be null");
for (BluetoothDevice device : devices.keySet()) {
- mCallbacks.notifySourceModifyFailed(device, sourceId,
- BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
+ mCallbacks.notifySourceModifyFailed(
+ device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
}
return;
}
@@ -2520,8 +2589,7 @@ public class BassClientService extends ProfileService {
/**
* Removes the Broadcast Source from a Broadcast Sink
*
- * @param sink representing the Broadcast Sink from which a Broadcast
- * Source should be removed
+ * @param sink representing the Broadcast Sink from which a Broadcast Source should be removed
* @param sourceId source ID as delivered in onSourceAdded
*/
public void removeSource(BluetoothDevice sink, int sourceId) {
@@ -2540,20 +2608,22 @@ public class BassClientService extends ProfileService {
if (stateMachine == null) {
log("removeSource: Error bad parameters: device = " + device);
- mCallbacks.notifySourceRemoveFailed(device, sourceId,
- BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
+ mCallbacks.notifySourceRemoveFailed(
+ device, sourceId, BluetoothStatusCodes.ERROR_BAD_PARAMETERS);
continue;
}
if (deviceSourceId == BassConstants.INVALID_SOURCE_ID) {
log("removeSource: no such sourceId for device: " + device);
- mCallbacks.notifySourceRemoveFailed(device, sourceId,
+ mCallbacks.notifySourceRemoveFailed(
+ device,
+ sourceId,
BluetoothStatusCodes.ERROR_LE_BROADCAST_ASSISTANT_INVALID_SOURCE_ID);
continue;
}
if (getConnectionState(device) != BluetoothProfile.STATE_CONNECTED) {
log("removeSource: device is not connected");
- mCallbacks.notifySourceRemoveFailed(device, sourceId,
- BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
+ mCallbacks.notifySourceRemoveFailed(
+ device, sourceId, BluetoothStatusCodes.ERROR_REMOTE_LINK_ERROR);
continue;
}
@@ -2569,8 +2639,8 @@ public class BassClientService extends ProfileService {
+ (", broadcastName: " + metaData.getBroadcastName()));
log("Force source to lost PA sync");
- Message message = stateMachine.obtainMessage(
- BassClientStateMachine.UPDATE_BCAST_SOURCE);
+ Message message =
+ stateMachine.obtainMessage(BassClientStateMachine.UPDATE_BCAST_SOURCE);
message.arg1 = sourceId;
message.arg2 = BassConstants.PA_SYNC_DO_NOT_SYNC;
/* Pending remove set. Remove source once not synchronized to PA */
@@ -2581,8 +2651,7 @@ public class BassClientService extends ProfileService {
}
sEventLogger.logd(
- TAG,
- "Remove Broadcast Source: device: " + device + ", sourceId: " + sourceId);
+ TAG, "Remove Broadcast Source: device: " + device + ", sourceId: " + sourceId);
Message message =
stateMachine.obtainMessage(BassClientStateMachine.REMOVE_BCAST_SOURCE);
@@ -2593,7 +2662,9 @@ public class BassClientService extends ProfileService {
for (Map.Entry deviceSourceIdPair : devices.entrySet()) {
BluetoothDevice device = deviceSourceIdPair.getKey();
Integer deviceSourceId = deviceSourceIdPair.getValue();
- enqueueSourceGroupOp(device, BassClientStateMachine.REMOVE_BCAST_SOURCE,
+ enqueueSourceGroupOp(
+ device,
+ BassClientStateMachine.REMOVE_BCAST_SOURCE,
Integer.valueOf(deviceSourceId));
}
}
@@ -2614,7 +2685,7 @@ public class BassClientService extends ProfileService {
}
List recvStates =
new ArrayList();
- for (BluetoothLeBroadcastReceiveState rs: stateMachine.getAllSources()) {
+ for (BluetoothLeBroadcastReceiveState rs : stateMachine.getAllSources()) {
String emptyBluetoothDevice = "00:00:00:00:00:00";
if (!rs.getSourceDevice().getAddress().equals(emptyBluetoothDevice)) {
recvStates.add(rs);
@@ -2773,7 +2844,6 @@ public class BassClientService extends ProfileService {
if (leAudioService != null) {
leAudioService.activeBroadcastAssistantNotification(true);
}
-
}
return false;
@@ -3108,9 +3178,7 @@ public class BassClientService extends ProfileService {
}
}
- /**
- * Callback handler
- */
+ /** Callback handler */
static class Callbacks extends Handler {
private static final int MSG_SEARCH_STARTED = 1;
private static final int MSG_SEARCH_STARTED_FAILED = 2;
@@ -3126,8 +3194,8 @@ public class BassClientService extends ProfileService {
private static final int MSG_RECEIVESTATE_CHANGED = 12;
private static final int MSG_SOURCE_LOST = 13;
- private final RemoteCallbackList
- mCallbacks = new RemoteCallbackList<>();
+ private final RemoteCallbackList mCallbacks =
+ new RemoteCallbackList<>();
Callbacks(Looper looper) {
super(looper);
@@ -3155,14 +3223,17 @@ public class BassClientService extends ProfileService {
case MSG_SOURCE_ADDED_FAILED:
ObjParams param = (ObjParams) msg.obj;
sink = (BluetoothDevice) param.mObj1;
- sService.checkForPendingGroupOpRequest(sink, reason,
- BassClientStateMachine.ADD_BCAST_SOURCE, param.mObj2);
+ sService.checkForPendingGroupOpRequest(
+ sink, reason, BassClientStateMachine.ADD_BCAST_SOURCE, param.mObj2);
break;
case MSG_SOURCE_REMOVED:
case MSG_SOURCE_REMOVED_FAILED:
sink = (BluetoothDevice) msg.obj;
- sService.checkForPendingGroupOpRequest(sink, reason,
- BassClientStateMachine.REMOVE_BCAST_SOURCE, Integer.valueOf(msg.arg2));
+ sService.checkForPendingGroupOpRequest(
+ sink,
+ reason,
+ BassClientStateMachine.REMOVE_BCAST_SOURCE,
+ Integer.valueOf(msg.arg2));
break;
default:
break;
@@ -3188,14 +3259,15 @@ public class BassClientService extends ProfileService {
private class ObjParams {
Object mObj1;
Object mObj2;
+
ObjParams(Object o1, Object o2) {
mObj1 = o1;
mObj2 = o2;
}
}
- private void invokeCallback(IBluetoothLeBroadcastAssistantCallback callback,
- Message msg) throws RemoteException {
+ private void invokeCallback(IBluetoothLeBroadcastAssistantCallback callback, Message msg)
+ throws RemoteException {
final int reason = msg.arg1;
final int sourceId = msg.arg2;
ObjParams param;
@@ -3296,8 +3368,8 @@ public class BassClientService extends ProfileService {
obtainMessage(MSG_SOURCE_FOUND, 0, 0, source).sendToTarget();
}
- void notifySourceAdded(BluetoothDevice sink, BluetoothLeBroadcastReceiveState recvState,
- int reason) {
+ void notifySourceAdded(
+ BluetoothDevice sink, BluetoothLeBroadcastReceiveState recvState, int reason) {
sService.localNotifySourceAdded(sink, recvState);
sEventLogger.logd(
@@ -3314,8 +3386,8 @@ public class BassClientService extends ProfileService {
obtainMessage(MSG_SOURCE_ADDED, reason, recvState.getSourceId(), param).sendToTarget();
}
- void notifySourceAddFailed(BluetoothDevice sink, BluetoothLeBroadcastMetadata source,
- int reason) {
+ void notifySourceAddFailed(
+ BluetoothDevice sink, BluetoothLeBroadcastMetadata source, int reason) {
sEventLogger.loge(
TAG,
"notifySourceAddFailed: sink: "
@@ -3379,8 +3451,8 @@ public class BassClientService extends ProfileService {
obtainMessage(MSG_SOURCE_REMOVED_FAILED, reason, sourceId, sink).sendToTarget();
}
- void notifyReceiveStateChanged(BluetoothDevice sink, int sourceId,
- BluetoothLeBroadcastReceiveState state) {
+ void notifyReceiveStateChanged(
+ BluetoothDevice sink, int sourceId, BluetoothLeBroadcastReceiveState state) {
ObjParams param = new ObjParams(sink, state);
sService.localNotifyReceiveStateChanged(sink);
@@ -3632,7 +3704,8 @@ public class BassClientService extends ProfileService {
@Override
public void addSource(
- BluetoothDevice sink, BluetoothLeBroadcastMetadata sourceMetadata,
+ BluetoothDevice sink,
+ BluetoothLeBroadcastMetadata sourceMetadata,
boolean isGroupOp) {
try {
BassClientService service = getService();
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
index 546102bc74270b7c9a2c9b239b176dbe40c4f0a7..a93cb56893715f52c8d788eb3a5f3a92d12362f5 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassClientStateMachine.java
@@ -78,10 +78,8 @@ import java.util.stream.IntStream;
@VisibleForTesting
public class BassClientStateMachine extends StateMachine {
private static final String TAG = "BassClientStateMachine";
- @VisibleForTesting
- static final byte[] REMOTE_SCAN_STOP = {00};
- @VisibleForTesting
- static final byte[] REMOTE_SCAN_START = {01};
+ @VisibleForTesting static final byte[] REMOTE_SCAN_STOP = {00};
+ @VisibleForTesting static final byte[] REMOTE_SCAN_START = {01};
private static final byte OPCODE_ADD_SOURCE = 0x02;
private static final byte OPCODE_UPDATE_SOURCE = 0x03;
private static final byte OPCODE_SET_BCAST_PIN = 0x04;
@@ -108,8 +106,7 @@ public class BassClientStateMachine extends StateMachine {
static final int CANCEL_PENDING_SOURCE_OPERATION = 18;
// NOTE: the value is not "final" - it is modified in the unit tests
- @VisibleForTesting
- private int mConnectTimeoutMs;
+ @VisibleForTesting private int mConnectTimeoutMs;
// Type of argument for set broadcast code operation
static final int ARGTYPE_METADATA = 1;
@@ -122,7 +119,7 @@ public class BassClientStateMachine extends StateMachine {
/*key is combination of sourceId, Address and advSid for this hashmap*/
private final Map
mBluetoothLeBroadcastReceiveStates =
- new HashMap();
+ new HashMap();
private final Map mCurrentMetadata = new HashMap();
private final Disconnected mDisconnected = new Disconnected();
private final Connected mConnected = new Connected();
@@ -134,46 +131,33 @@ public class BassClientStateMachine extends StateMachine {
@VisibleForTesting
final List mBroadcastCharacteristics =
new ArrayList();
- @VisibleForTesting
- BluetoothDevice mDevice;
+
+ @VisibleForTesting BluetoothDevice mDevice;
private boolean mIsAllowedList = false;
private int mLastConnectionState = -1;
- @VisibleForTesting
- boolean mMTUChangeRequested = false;
- @VisibleForTesting
- boolean mDiscoveryInitiated = false;
- @VisibleForTesting
- BassClientService mService;
+ @VisibleForTesting boolean mMTUChangeRequested = false;
+ @VisibleForTesting boolean mDiscoveryInitiated = false;
+ @VisibleForTesting BassClientService mService;
AdapterService mAdapterService;
- @VisibleForTesting
- BluetoothGattCharacteristic mBroadcastScanControlPoint;
+ @VisibleForTesting BluetoothGattCharacteristic mBroadcastScanControlPoint;
private final Map mFirstTimeBisDiscoveryMap;
private int mPASyncRetryCounter = 0;
- @VisibleForTesting
- int mNumOfBroadcastReceiverStates = 0;
- @VisibleForTesting
- int mPendingOperation = -1;
- @VisibleForTesting
- byte mPendingSourceId = -1;
- @VisibleForTesting
- BluetoothLeBroadcastMetadata mPendingMetadata = null;
+ @VisibleForTesting int mNumOfBroadcastReceiverStates = 0;
+ @VisibleForTesting int mPendingOperation = -1;
+ @VisibleForTesting byte mPendingSourceId = -1;
+ @VisibleForTesting BluetoothLeBroadcastMetadata mPendingMetadata = null;
private BluetoothLeBroadcastMetadata mSetBroadcastPINMetadata = null;
- @VisibleForTesting
- boolean mSetBroadcastCodePending = false;
+ @VisibleForTesting boolean mSetBroadcastCodePending = false;
private final Map mPendingRemove = new HashMap();
- @VisibleForTesting
- boolean mAutoTriggered = false;
+ @VisibleForTesting boolean mAutoTriggered = false;
private boolean mDefNoPAS = false;
private boolean mForceSB = false;
- @VisibleForTesting
- BluetoothLeBroadcastMetadata mPendingSourceToAdd = null;
+ @VisibleForTesting BluetoothLeBroadcastMetadata mPendingSourceToAdd = null;
private int mBroadcastSourceIdLength = 3;
- @VisibleForTesting
- byte mNextSourceId = 0;
+ @VisibleForTesting byte mNextSourceId = 0;
private boolean mAllowReconnect = false;
- @VisibleForTesting
- BluetoothGattTestableWrapper mBluetoothGatt = null;
+ @VisibleForTesting BluetoothGattTestableWrapper mBluetoothGatt = null;
BluetoothGattCallback mGattCallback = null;
@VisibleForTesting PeriodicAdvertisingCallback mLocalPeriodicAdvCallback = new PACallback();
int mMaxSingleAttributeWriteValueLen = 0;
@@ -197,12 +181,19 @@ public class BassClientStateMachine extends StateMachine {
setInitialState(mDisconnected);
mFirstTimeBisDiscoveryMap = new HashMap();
long token = Binder.clearCallingIdentity();
- mIsAllowedList = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.wl", true);
- mDefNoPAS = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.defNoPAS", false);
- mForceSB = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_BLUETOOTH,
- "persist.vendor.service.bt.forceSB", false);
+ mIsAllowedList =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH, "persist.vendor.service.bt.wl", true);
+ mDefNoPAS =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "persist.vendor.service.bt.defNoPAS",
+ false);
+ mForceSB =
+ DeviceConfig.getBoolean(
+ DeviceConfig.NAMESPACE_BLUETOOTH,
+ "persist.vendor.service.bt.forceSB",
+ false);
Binder.restoreCallingIdentity(token);
}
@@ -282,8 +273,8 @@ public class BassClientStateMachine extends StateMachine {
return mCurrentMetadata.getOrDefault(sourceId, null);
}
- private void setCurrentBroadcastMetadata(Integer sourceId,
- BluetoothLeBroadcastMetadata metadata) {
+ private void setCurrentBroadcastMetadata(
+ Integer sourceId, BluetoothLeBroadcastMetadata metadata) {
if (metadata != null) {
mCurrentMetadata.put(sourceId, metadata);
} else {
@@ -311,9 +302,12 @@ public class BassClientStateMachine extends StateMachine {
BluetoothDevice device = currentSources.get(i).getSourceDevice();
if (device != null && device.equals(srcDevice)) {
state = currentSources.get(i);
- Log.e(TAG,
+ Log.e(
+ TAG,
"getBroadcastReceiveStateForSourceDevice: returns for: "
- + srcDevice + "&srcInfo" + state);
+ + srcDevice
+ + "&srcInfo"
+ + state);
return state;
}
}
@@ -388,8 +382,11 @@ public class BassClientStateMachine extends StateMachine {
Map bmsAdvDataMap = record.getServiceData();
if (bmsAdvDataMap != null) {
for (Map.Entry entry : bmsAdvDataMap.entrySet()) {
- log("ParcelUUid = " + entry.getKey() + ", Value = "
- + Arrays.toString(entry.getValue()));
+ log(
+ "ParcelUUid = "
+ + entry.getKey()
+ + ", Value = "
+ + Arrays.toString(entry.getValue()));
}
}
byte[] advData = record.getServiceData(BassConstants.BASIC_AUDIO_UUID);
@@ -459,8 +456,7 @@ public class BassClientStateMachine extends StateMachine {
broadcastId = BassUtils.parseBroadcastId(bId);
}
if (listOfUuids.containsKey(BassConstants.PUBLIC_BROADCAST_UUID)) {
- byte[] pbAnnouncement =
- listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID);
+ byte[] pbAnnouncement = listOfUuids.get(BassConstants.PUBLIC_BROADCAST_UUID);
pbData = PublicBroadcastData.parsePublicBroadcastData(pbAnnouncement);
}
}
@@ -599,15 +595,13 @@ public class BassClientStateMachine extends StateMachine {
"Should never be executed with"
+ " leaudioBroadcastExtractPeriodicScannerFromStateMachine flag");
}
- BluetoothLeBroadcastMetadata.Builder metaData =
- new BluetoothLeBroadcastMetadata.Builder();
+ BluetoothLeBroadcastMetadata.Builder metaData = new BluetoothLeBroadcastMetadata.Builder();
int index = 0;
for (BaseData.BaseInformation baseLevel2 : baseData.getLevelTwo()) {
BluetoothLeBroadcastSubgroup.Builder subGroup =
new BluetoothLeBroadcastSubgroup.Builder();
- for (int j = 0; j < baseLevel2.numSubGroups; j ++) {
- BaseData.BaseInformation baseLevel3 =
- baseData.getLevelThree().get(index++);
+ for (int j = 0; j < baseLevel2.numSubGroups; j++) {
+ BaseData.BaseInformation baseLevel3 = baseData.getLevelThree().get(index++);
BluetoothLeBroadcastChannel.Builder channel =
new BluetoothLeBroadcastChannel.Builder();
channel.setChannelIndex(baseLevel3.index);
@@ -624,11 +618,12 @@ public class BassClientStateMachine extends StateMachine {
subGroup.addChannel(channel.build());
}
byte[] arrayCodecId = baseLevel2.codecId;
- long codeId = ((long) (arrayCodecId[4] & 0xff)) << 32
- | (arrayCodecId[3] & 0xff) << 24
- | (arrayCodecId[2] & 0xff) << 16
- | (arrayCodecId[1] & 0xff) << 8
- | (arrayCodecId[0] & 0xff);
+ long codeId =
+ ((long) (arrayCodecId[4] & 0xff)) << 32
+ | (arrayCodecId[3] & 0xff) << 24
+ | (arrayCodecId[2] & 0xff) << 16
+ | (arrayCodecId[1] & 0xff) << 8
+ | (arrayCodecId[0] & 0xff);
subGroup.setCodecId(codeId);
try {
subGroup.setCodecSpecificConfig(
@@ -697,8 +692,7 @@ public class BassClientStateMachine extends StateMachine {
return metaData.build();
}
- private void broadcastReceiverState(
- BluetoothLeBroadcastReceiveState state, int sourceId) {
+ private void broadcastReceiverState(BluetoothLeBroadcastReceiveState state, int sourceId) {
log("broadcastReceiverState: " + mDevice);
mService.getCallbacks().notifyReceiveStateChanged(mDevice, sourceId, state);
}
@@ -726,14 +720,20 @@ public class BassClientStateMachine extends StateMachine {
if (syncHandle != BassConstants.INVALID_SYNC_HANDLE) {
serviceData = 0x000000FF & recvState.getSourceId();
serviceData = serviceData << 8;
- //advA matches EXT_ADV_ADDRESS
- //also matches source address (as we would have written)
- serviceData = serviceData
- & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
- serviceData = serviceData
- & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
- log("Initiate PAST for: " + mDevice + ", syncHandle: " + syncHandle
- + "serviceData" + serviceData);
+ // advA matches EXT_ADV_ADDRESS
+ // also matches source address (as we would have written)
+ serviceData =
+ serviceData & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_EXT_ADV_ADDRESS);
+ serviceData =
+ serviceData
+ & (~BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS);
+ log(
+ "Initiate PAST for: "
+ + mDevice
+ + ", syncHandle: "
+ + syncHandle
+ + "serviceData"
+ + serviceData);
BluetoothMethodProxy.getInstance()
.periodicAdvertisingManagerTransferSync(
BassClientPeriodicAdvertisingManager
@@ -750,11 +750,15 @@ public class BassClientStateMachine extends StateMachine {
serviceData = 0x000000FF & recvState.getSourceId();
serviceData = serviceData << 8;
// Address we set in the Source Address can differ from the address in the air
- serviceData = serviceData
- | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS;
- log("Initiate local broadcast PAST for: " + mDevice
- + ", advSID/Handle: " + advHandle
- + ", serviceData: " + serviceData);
+ serviceData =
+ serviceData | BassConstants.ADV_ADDRESS_DONT_MATCHES_SOURCE_ADV_ADDRESS;
+ log(
+ "Initiate local broadcast PAST for: "
+ + mDevice
+ + ", advSID/Handle: "
+ + advHandle
+ + ", serviceData: "
+ + serviceData);
BluetoothMethodProxy.getInstance()
.periodicAdvertisingManagerTransferSetInfo(
BassClientPeriodicAdvertisingManager
@@ -775,12 +779,11 @@ public class BassClientStateMachine extends StateMachine {
// non colocated case, Broadcast PIN should have been updated from lyaer
// If there is pending one process it Now
if (recvState.getBigEncryptionState()
- == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED
+ == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED
&& mSetBroadcastCodePending) {
log("Update the Broadcast now");
if (mSetBroadcastPINMetadata != null) {
- setCurrentBroadcastMetadata(recvState.getSourceId(),
- mSetBroadcastPINMetadata);
+ setCurrentBroadcastMetadata(recvState.getSourceId(), mSetBroadcastPINMetadata);
}
Message m = obtainMessage(BassClientStateMachine.SET_BCAST_CODE);
m.obj = recvState;
@@ -791,8 +794,7 @@ public class BassClientStateMachine extends StateMachine {
}
}
- private BluetoothLeBroadcastReceiveState parseBroadcastReceiverState(
- byte[] receiverState) {
+ private BluetoothLeBroadcastReceiveState parseBroadcastReceiverState(byte[] receiverState) {
byte sourceId = 0;
if (receiverState.length > 0) {
sourceId = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ID_IDX];
@@ -864,16 +866,20 @@ public class BassClientStateMachine extends StateMachine {
BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE);
badBroadcastCodeLen = BassConstants.BCAST_RCVR_STATE_BADCODE_SIZE;
}
- byte numSubGroups = receiverState[BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX
- + badBroadcastCodeLen];
- int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX
- + badBroadcastCodeLen + 1;
+ byte numSubGroups =
+ receiverState[
+ BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen];
+ int offset = BassConstants.BCAST_RCVR_STATE_BADCODE_START_IDX + badBroadcastCodeLen + 1;
ArrayList metadataList =
new ArrayList();
ArrayList bisSyncState = new ArrayList();
for (int i = 0; i < numSubGroups; i++) {
byte[] bisSyncIndex = new byte[BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE];
- System.arraycopy(receiverState, offset, bisSyncIndex, 0,
+ System.arraycopy(
+ receiverState,
+ offset,
+ bisSyncIndex,
+ 0,
BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE);
offset += BassConstants.BCAST_RCVR_STATE_BIS_SYNC_SIZE;
bisSyncState.add((long) Utils.byteArrayToInt(bisSyncIndex));
@@ -904,26 +910,27 @@ public class BassClientStateMachine extends StateMachine {
sourceAddress,
0,
BassConstants.BCAST_RCVR_STATE_SRC_ADDR_SIZE);
- byte sourceAddressType = receiverState[BassConstants
- .BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX];
+ byte sourceAddressType =
+ receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADDR_TYPE_IDX];
BassUtils.reverse(sourceAddress);
String address = Utils.getAddressStringFromByte(sourceAddress);
BluetoothDevice device =
BluetoothAdapter.getDefaultAdapter()
.getRemoteLeDevice(address, sourceAddressType);
byte sourceAdvSid = receiverState[BassConstants.BCAST_RCVR_STATE_SRC_ADV_SID_IDX];
- recvState = new BluetoothLeBroadcastReceiveState(
- sourceId,
- (int) sourceAddressType,
- device,
- sourceAdvSid,
- broadcastId,
- (int) paSyncState,
- (int) bigEncryptionStatus,
- badBroadcastCode,
- numSubGroups,
- bisSyncState,
- metadataList);
+ recvState =
+ new BluetoothLeBroadcastReceiveState(
+ sourceId,
+ (int) sourceAddressType,
+ device,
+ sourceAdvSid,
+ broadcastId,
+ (int) paSyncState,
+ (int) bigEncryptionStatus,
+ badBroadcastCode,
+ numSubGroups,
+ bisSyncState,
+ metadataList);
}
return recvState;
}
@@ -931,8 +938,7 @@ public class BassClientStateMachine extends StateMachine {
private void processBroadcastReceiverState(
byte[] receiverState, BluetoothGattCharacteristic characteristic) {
log("processBroadcastReceiverState: characteristic:" + characteristic);
- BluetoothLeBroadcastReceiveState recvState = parseBroadcastReceiverState(
- receiverState);
+ BluetoothLeBroadcastReceiveState recvState = parseBroadcastReceiverState(receiverState);
if (recvState == null) {
log("processBroadcastReceiverState: Null recvState");
return;
@@ -1004,8 +1010,11 @@ public class BassClientStateMachine extends StateMachine {
mPendingMetadata = null;
}
removeMessages(CANCEL_PENDING_SOURCE_OPERATION);
- mService.getCallbacks().notifySourceModified(mDevice,
- recvState.getSourceId(), BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
+ mService.getCallbacks()
+ .notifySourceModified(
+ mDevice,
+ recvState.getSourceId(),
+ BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
checkAndUpdateBroadcastCode(recvState);
processPASyncState(recvState);
@@ -1034,8 +1043,9 @@ public class BassClientStateMachine extends StateMachine {
if (mService.okToConnect(mDevice)) {
log("Bassclient Connected to: " + mDevice);
if (mBluetoothGatt != null) {
- log("Attempting to start service discovery:"
- + mBluetoothGatt.discoverServices());
+ log(
+ "Attempting to start service discovery:"
+ + mBluetoothGatt.discoverServices());
mDiscoveryInitiated = true;
}
} else if (mBluetoothGatt != null) {
@@ -1068,8 +1078,12 @@ public class BassClientStateMachine extends StateMachine {
mBluetoothGatt.requestMtu(BassConstants.BASS_MAX_BYTES);
mMTUChangeRequested = true;
} else {
- Log.w(TAG, "onServicesDiscovered received: "
- + status + "mBluetoothGatt" + mBluetoothGatt);
+ Log.w(
+ TAG,
+ "onServicesDiscovered received: "
+ + status
+ + "mBluetoothGatt"
+ + mBluetoothGatt);
}
} else {
log("remote initiated callback");
@@ -1078,23 +1092,24 @@ public class BassClientStateMachine extends StateMachine {
@Override
public void onCharacteristicRead(
- BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic,
- int status) {
- if (status == BluetoothGatt.GATT_SUCCESS && characteristic.getUuid()
- .equals(BassConstants.BASS_BCAST_RECEIVER_STATE)) {
+ BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
+ if (status == BluetoothGatt.GATT_SUCCESS
+ && characteristic.getUuid().equals(BassConstants.BASS_BCAST_RECEIVER_STATE)) {
log("onCharacteristicRead: BASS_BCAST_RECEIVER_STATE: status" + status);
if (characteristic.getValue() == null) {
Log.e(TAG, "Remote receiver state is NULL");
return;
}
- logByteArray("Received ", characteristic.getValue(), 0,
+ logByteArray(
+ "Received ",
+ characteristic.getValue(),
+ 0,
characteristic.getValue().length);
processBroadcastReceiverState(characteristic.getValue(), characteristic);
}
// switch to receiving notifications after initial characteristic read
- BluetoothGattDescriptor desc = characteristic
- .getDescriptor(BassConstants.CLIENT_CHARACTERISTIC_CONFIG);
+ BluetoothGattDescriptor desc =
+ characteristic.getDescriptor(BassConstants.CLIENT_CHARACTERISTIC_CONFIG);
if (mBluetoothGatt != null && desc != null) {
log("Setting the value for Desc");
mBluetoothGatt.setCharacteristicNotification(characteristic, true);
@@ -1124,8 +1139,7 @@ public class BassClientStateMachine extends StateMachine {
acquireAllBassChars();
mMTUChangeRequested = false;
} else {
- log("onMtuChanged is remote initiated trigger, mBluetoothGatt:"
- + mBluetoothGatt);
+ log("onMtuChanged is remote initiated trigger, mBluetoothGatt:" + mBluetoothGatt);
}
if (status == BluetoothGatt.GATT_SUCCESS) {
@@ -1147,8 +1161,8 @@ public class BassClientStateMachine extends StateMachine {
}
@Override
- public void onCharacteristicWrite(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, int status) {
+ public void onCharacteristicWrite(
+ BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Message m = obtainMessage(GATT_TXN_PROCESSED);
m.arg1 = status;
sendMessage(m);
@@ -1170,12 +1184,19 @@ public class BassClientStateMachine extends StateMachine {
"Should never be executed with"
+ " leaudioBroadcastExtractPeriodicScannerFromStateMachine flag");
}
- log("onSyncEstablished syncHandle: " + syncHandle
- + ", device: " + device
- + ", advertisingSid: " + advertisingSid
- + ", skip: " + skip
- + ", timeout: " + timeout
- + ", status: " + status);
+ log(
+ "onSyncEstablished syncHandle: "
+ + syncHandle
+ + ", device: "
+ + device
+ + ", advertisingSid: "
+ + advertisingSid
+ + ", skip: "
+ + skip
+ + ", timeout: "
+ + timeout
+ + ", status: "
+ + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
// updates syncHandle, advSid
// set other fields as invalid or null
@@ -1190,8 +1211,7 @@ public class BassClientStateMachine extends StateMachine {
null);
removeMessages(PSYNC_ACTIVE_TIMEOUT);
// Refresh sync timeout if another source synced
- sendMessageDelayed(
- PSYNC_ACTIVE_TIMEOUT, BassConstants.PSYNC_ACTIVE_TIMEOUT_MS);
+ sendMessageDelayed(PSYNC_ACTIVE_TIMEOUT, BassConstants.PSYNC_ACTIVE_TIMEOUT_MS);
mService.addActiveSyncedSource(mDevice, syncHandle);
// update valid sync handle in mPeriodicAdvCallbacksMap
@@ -1299,8 +1319,7 @@ public class BassClientStateMachine extends StateMachine {
@Override
public void onSyncTransferred(BluetoothDevice device, int status) {
- log("onSyncTransferred: device=" + device +
- " ,status =" + status);
+ log("onSyncTransferred: device=" + device + " ,status =" + status);
}
}
@@ -1315,11 +1334,16 @@ public class BassClientStateMachine extends StateMachine {
mGattCallback = new GattCallback();
}
- BluetoothGatt gatt = mDevice.connectGatt(mService, autoConnect,
- mGattCallback, BluetoothDevice.TRANSPORT_LE,
- (BluetoothDevice.PHY_LE_1M_MASK
- | BluetoothDevice.PHY_LE_2M_MASK
- | BluetoothDevice.PHY_LE_CODED_MASK), null);
+ BluetoothGatt gatt =
+ mDevice.connectGatt(
+ mService,
+ autoConnect,
+ mGattCallback,
+ BluetoothDevice.TRANSPORT_LE,
+ (BluetoothDevice.PHY_LE_1M_MASK
+ | BluetoothDevice.PHY_LE_2M_MASK
+ | BluetoothDevice.PHY_LE_CODED_MASK),
+ null);
if (gatt != null) {
mBluetoothGatt = new BluetoothGattTestableWrapper(gatt);
@@ -1328,9 +1352,7 @@ public class BassClientStateMachine extends StateMachine {
return mBluetoothGatt != null;
}
- /**
- * getAllSources
- */
+ /** getAllSources */
public List getAllSources() {
List list = new ArrayList(mBluetoothLeBroadcastReceiveStates.values());
return list;
@@ -1358,8 +1380,10 @@ public class BassClientStateMachine extends StateMachine {
if (((properties & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0)
|| ((properties & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0)) {
- Log.w(TAG, "Broadcast Audio Scan Control Point characteristic has invalid "
- + "properties!");
+ Log.w(
+ TAG,
+ "Broadcast Audio Scan Control Point characteristic has invalid "
+ + "properties!");
} else {
mBroadcastScanControlPoint = allChars.get(i);
log("Index of ScanCtrlPoint:" + i);
@@ -1395,8 +1419,11 @@ public class BassClientStateMachine extends StateMachine {
class Disconnected extends State {
@Override
public void enter() {
- log("Enter Disconnected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Enter Disconnected("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
clearCharsCache();
mNextSourceId = 0;
removeDeferredMessages(DISCONNECT);
@@ -1416,15 +1443,21 @@ public class BassClientStateMachine extends StateMachine {
@Override
public void exit() {
- log("Exit Disconnected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Exit Disconnected("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_DISCONNECTED;
}
@Override
public boolean processMessage(Message message) {
- log("Disconnected process message(" + mDevice
- + "): " + messageWhatToString(message.what));
+ log(
+ "Disconnected process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
log("Connecting to " + mDevice);
@@ -1478,8 +1511,11 @@ public class BassClientStateMachine extends StateMachine {
class Connecting extends State {
@Override
public void enter() {
- log("Enter Connecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Enter Connecting("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
sendMessageDelayed(CONNECT_TIMEOUT, mDevice, mConnectTimeoutMs);
broadcastConnectionState(
mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTING);
@@ -1487,16 +1523,22 @@ public class BassClientStateMachine extends StateMachine {
@Override
public void exit() {
- log("Exit Connecting(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Exit Connecting("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_CONNECTING;
removeMessages(CONNECT_TIMEOUT);
}
@Override
public boolean processMessage(Message message) {
- log("Connecting process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(
+ "Connecting process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
log("Already Connecting to " + mDevice);
@@ -1542,8 +1584,7 @@ public class BassClientStateMachine extends StateMachine {
}
}
- private static int getBisSyncFromChannelPreference(
- List channels) {
+ private static int getBisSyncFromChannelPreference(List channels) {
int bisSync = 0;
for (BluetoothLeBroadcastChannel channel : channels) {
if (channel.isSelected()) {
@@ -1622,8 +1663,8 @@ public class BassClientStateMachine extends StateMachine {
return res;
}
- private byte[] convertBroadcastMetadataToUpdateSourceByteArray(int sourceId,
- BluetoothLeBroadcastMetadata metaData, int paSync) {
+ private byte[] convertBroadcastMetadataToUpdateSourceByteArray(
+ int sourceId, BluetoothLeBroadcastMetadata metaData, int paSync) {
BluetoothLeBroadcastReceiveState existingState =
getBroadcastReceiveStateForSourceId(sourceId);
if (existingState == null) {
@@ -1690,13 +1731,13 @@ public class BassClientStateMachine extends StateMachine {
res[0] = OPCODE_SET_BCAST_PIN;
// Source_ID
res[1] = (byte) recvState.getSourceId();
- log("convertRecvStateToSetBroadcastCodeByteArray: Source device : "
- + recvState.getSourceDevice());
+ log(
+ "convertRecvStateToSetBroadcastCodeByteArray: Source device : "
+ + recvState.getSourceDevice());
BluetoothLeBroadcastMetadata metaData =
getCurrentBroadcastMetadata(recvState.getSourceId());
if (metaData == null) {
- Log.e(TAG, "Fail to find broadcast source, sourceId = "
- + recvState.getSourceId());
+ Log.e(TAG, "Fail to find broadcast source, sourceId = " + recvState.getSourceId());
return null;
}
// Broadcast Code
@@ -1732,8 +1773,10 @@ public class BassClientStateMachine extends StateMachine {
log("Source state is null");
continue;
}
- if (sourceId == state.getSourceId() && state.getBigEncryptionState()
- == BluetoothLeBroadcastReceiveState.BIG_ENCRYPTION_STATE_CODE_REQUIRED) {
+ if (sourceId == state.getSourceId()
+ && state.getBigEncryptionState()
+ == BluetoothLeBroadcastReceiveState
+ .BIG_ENCRYPTION_STATE_CODE_REQUIRED) {
retval = true;
break;
}
@@ -1746,19 +1789,25 @@ public class BassClientStateMachine extends StateMachine {
class Connected extends State {
@Override
public void enter() {
- log("Enter Connected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Enter Connected("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
removeDeferredMessages(CONNECT);
if (mLastConnectionState != BluetoothProfile.STATE_CONNECTED) {
- broadcastConnectionState(mDevice, mLastConnectionState,
- BluetoothProfile.STATE_CONNECTED);
+ broadcastConnectionState(
+ mDevice, mLastConnectionState, BluetoothProfile.STATE_CONNECTED);
}
}
@Override
public void exit() {
- log("Exit Connected(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Exit Connected("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
mLastConnectionState = BluetoothProfile.STATE_CONNECTED;
}
@@ -1950,8 +1999,9 @@ public class BassClientStateMachine extends StateMachine {
BassConstants.SOURCE_OPERATION_TIMEOUT_MS);
} else {
Log.e(TAG, "ADD_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal");
- mService.getCallbacks().notifySourceAddFailed(mDevice,
- metaData, BluetoothStatusCodes.ERROR_UNKNOWN);
+ mService.getCallbacks()
+ .notifySourceAddFailed(
+ mDevice, metaData, BluetoothStatusCodes.ERROR_UNKNOWN);
}
break;
case UPDATE_BCAST_SOURCE:
@@ -1959,8 +2009,9 @@ public class BassClientStateMachine extends StateMachine {
int sourceId = message.arg1;
int paSync = message.arg2;
log("Updating Broadcast source: " + metaData);
- byte[] updateSourceInfo = convertBroadcastMetadataToUpdateSourceByteArray(
- sourceId, metaData, paSync);
+ byte[] updateSourceInfo =
+ convertBroadcastMetadataToUpdateSourceByteArray(
+ sourceId, metaData, paSync);
if (updateSourceInfo == null) {
Log.e(TAG, "update source: source Info is NULL");
break;
@@ -1987,8 +2038,9 @@ public class BassClientStateMachine extends StateMachine {
BassConstants.SOURCE_OPERATION_TIMEOUT_MS);
} else {
Log.e(TAG, "UPDATE_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal");
- mService.getCallbacks().notifySourceModifyFailed(
- mDevice, sourceId, BluetoothStatusCodes.ERROR_UNKNOWN);
+ mService.getCallbacks()
+ .notifySourceModifyFailed(
+ mDevice, sourceId, BluetoothStatusCodes.ERROR_UNKNOWN);
}
break;
case SET_BCAST_CODE:
@@ -1996,13 +2048,11 @@ public class BassClientStateMachine extends StateMachine {
mSetBroadcastCodePending = false;
BluetoothLeBroadcastReceiveState recvState = null;
if (argType == ARGTYPE_METADATA) {
- mSetBroadcastPINMetadata =
- (BluetoothLeBroadcastMetadata) message.obj;
+ mSetBroadcastPINMetadata = (BluetoothLeBroadcastMetadata) message.obj;
mSetBroadcastCodePending = true;
} else {
recvState = (BluetoothLeBroadcastReceiveState) message.obj;
- if (!isItRightTimeToUpdateBroadcastPin(
- (byte) recvState.getSourceId())) {
+ if (!isItRightTimeToUpdateBroadcastPin((byte) recvState.getSourceId())) {
mSetBroadcastCodePending = true;
}
}
@@ -2048,8 +2098,9 @@ public class BassClientStateMachine extends StateMachine {
BassConstants.GATT_TXN_TIMEOUT_MS);
} else {
Log.e(TAG, "REMOVE_BCAST_SOURCE: no Bluetooth Gatt handle, Fatal");
- mService.getCallbacks().notifySourceRemoveFailed(mDevice,
- sid, BluetoothStatusCodes.ERROR_UNKNOWN);
+ mService.getCallbacks()
+ .notifySourceRemoveFailed(
+ mDevice, sid, BluetoothStatusCodes.ERROR_UNKNOWN);
if (mPendingSourceToSwitch != null) {
// Switching source failed
// Need to notify add source failure for service to cleanup
@@ -2123,8 +2174,8 @@ public class BassClientStateMachine extends StateMachine {
if (!mAutoTriggered
|| Flags.leaudioBroadcastExtractPeriodicScannerFromStateMachine()) {
if (!isSuccess(status)) {
- mService.getCallbacks().notifySourceModifyFailed(mDevice,
- mPendingSourceId, status);
+ mService.getCallbacks()
+ .notifySourceModifyFailed(mDevice, mPendingSourceId, status);
mPendingMetadata = null;
removeMessages(CANCEL_PENDING_SOURCE_OPERATION);
}
@@ -2134,8 +2185,8 @@ public class BassClientStateMachine extends StateMachine {
break;
case REMOVE_BCAST_SOURCE:
if (!isSuccess(status)) {
- mService.getCallbacks().notifySourceRemoveFailed(mDevice,
- mPendingSourceId, status);
+ mService.getCallbacks()
+ .notifySourceRemoveFailed(mDevice, mPendingSourceId, status);
if (mPendingSourceToSwitch != null) {
// Switching source failed
// Need to notify add source failure for service to cleanup
@@ -2159,23 +2210,34 @@ public class BassClientStateMachine extends StateMachine {
class ConnectedProcessing extends State {
@Override
public void enter() {
- log("Enter ConnectedProcessing(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Enter ConnectedProcessing("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
}
+
@Override
public void exit() {
/* Pending Metadata will be used to bond with source ID in receiver state notify */
if (mPendingOperation == REMOVE_BCAST_SOURCE) {
- mPendingMetadata = null;
+ mPendingMetadata = null;
}
- log("Exit ConnectedProcessing(" + mDevice + "): "
- + messageWhatToString(getCurrentMessage().what));
+ log(
+ "Exit ConnectedProcessing("
+ + mDevice
+ + "): "
+ + messageWhatToString(getCurrentMessage().what));
}
+
@Override
public boolean processMessage(Message message) {
- log("ConnectedProcessing process message(" + mDevice + "): "
- + messageWhatToString(message.what));
+ log(
+ "ConnectedProcessing process message("
+ + mDevice
+ + "): "
+ + messageWhatToString(message.what));
switch (message.what) {
case CONNECT:
Log.w(TAG, "CONNECT request is ignored" + mDevice);
@@ -2221,20 +2283,15 @@ public class BassClientStateMachine extends StateMachine {
log("GATT transaction processed for" + mDevice);
if (status == BluetoothGatt.GATT_SUCCESS) {
sendPendingCallbacks(
- mPendingOperation,
- BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
+ mPendingOperation, BluetoothStatusCodes.REASON_LOCAL_APP_REQUEST);
} else {
- sendPendingCallbacks(
- mPendingOperation,
- BluetoothStatusCodes.ERROR_UNKNOWN);
+ sendPendingCallbacks(mPendingOperation, BluetoothStatusCodes.ERROR_UNKNOWN);
}
transitionTo(mConnected);
break;
case GATT_TXN_TIMEOUT:
log("GATT transaction timeout for" + mDevice);
- sendPendingCallbacks(
- mPendingOperation,
- BluetoothStatusCodes.ERROR_UNKNOWN);
+ sendPendingCallbacks(mPendingOperation, BluetoothStatusCodes.ERROR_UNKNOWN);
mPendingOperation = -1;
mPendingSourceId = -1;
if ((message.arg1 == UPDATE_BCAST_SOURCE)
@@ -2252,9 +2309,10 @@ public class BassClientStateMachine extends StateMachine {
case REACHED_MAX_SOURCE_LIMIT:
case SWITCH_BCAST_SOURCE:
case PSYNC_ACTIVE_TIMEOUT:
- log("defer the message: "
- + messageWhatToString(message.what)
- + ", so that it will be processed later");
+ log(
+ "defer the message: "
+ + messageWhatToString(message.what)
+ + ", so that it will be processed later");
deferMessage(message);
break;
case CANCEL_PENDING_SOURCE_OPERATION:
@@ -2282,8 +2340,9 @@ public class BassClientStateMachine extends StateMachine {
intent.putExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, fromState);
intent.putExtra(BluetoothProfile.EXTRA_STATE, toState);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, mDevice);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
- | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ intent.addFlags(
+ Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
+ | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mService.sendBroadcast(
intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
}
@@ -2361,9 +2420,7 @@ public class BassClientStateMachine extends StateMachine {
return Integer.toString(what);
}
- /**
- * Dump info
- */
+ /** Dump info */
public void dump(StringBuilder sb) {
ProfileService.println(sb, "mDevice: " + mDevice);
ProfileService.println(sb, " StateMachine: " + this);
@@ -2428,17 +2485,14 @@ public class BassClientStateMachine extends StateMachine {
return mWrappedBluetoothGatt.discoverServices();
}
- /**
- * See {@link BluetoothGatt#readCharacteristic(
- * BluetoothGattCharacteristic)}.
- */
+ /** See {@link BluetoothGatt#readCharacteristic( BluetoothGattCharacteristic)}. */
public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
return mWrappedBluetoothGatt.readCharacteristic(characteristic);
}
/**
- * See {@link BluetoothGatt#writeCharacteristic(
- * BluetoothGattCharacteristic, byte[], int)} .
+ * See {@link BluetoothGatt#writeCharacteristic( BluetoothGattCharacteristic, byte[], int)}
+ * .
*/
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
return mWrappedBluetoothGatt.writeCharacteristic(characteristic);
@@ -2449,10 +2503,7 @@ public class BassClientStateMachine extends StateMachine {
return mWrappedBluetoothGatt.readDescriptor(descriptor);
}
- /**
- * See {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor,
- * byte[])}.
- */
+ /** See {@link BluetoothGatt#writeDescriptor(BluetoothGattDescriptor, byte[])}. */
public boolean writeDescriptor(BluetoothGattDescriptor descriptor) {
return mWrappedBluetoothGatt.writeDescriptor(descriptor);
}
@@ -2478,5 +2529,4 @@ public class BassClientStateMachine extends StateMachine {
mWrappedBluetoothGatt.close();
}
}
-
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
index c3399ae6360ab6dd0fdf104d0d73fec6f3f226b6..981f4b62874dea523f67d2ee4826980073912b06 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassConstants.java
@@ -20,14 +20,11 @@ import android.os.ParcelUuid;
import java.util.UUID;
-/**
- * Broadcast Audio Scan Service constants class
- */
+/** Broadcast Audio Scan Service constants class */
public class BassConstants {
public static final ParcelUuid BAAS_UUID =
ParcelUuid.fromString("00001852-0000-1000-8000-00805F9B34FB");
- public static final UUID BASS_UUID =
- UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB");
+ public static final UUID BASS_UUID = UUID.fromString("0000184F-0000-1000-8000-00805F9B34FB");
public static final UUID BASS_BCAST_AUDIO_SCAN_CTRL_POINT =
UUID.fromString("00002BC7-0000-1000-8000-00805F9B34FB");
public static final UUID BASS_BCAST_RECEIVER_STATE =
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java
index 1a4a40a2e872aa002371df6ea4abf114a32f2621..d65913d72296eb2b8f82e54344c11339f6c1416e 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassObjectsFactory.java
@@ -26,9 +26,7 @@ import com.android.bluetooth.Utils;
import com.android.bluetooth.btservice.AdapterService;
import com.android.internal.annotations.VisibleForTesting;
-/**
- * Factory class for object initialization to help with unit testing
- */
+/** Factory class for object initialization to help with unit testing */
public class BassObjectsFactory {
private static final String TAG = BassObjectsFactory.class.getSimpleName();
private static BassObjectsFactory sInstance;
diff --git a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
index 73dcbb92468c56b704ec909a5f8d082d34859960..239bcf3d825260d36fab6244003681376bb65f67 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BassUtils.java
@@ -23,14 +23,12 @@ import android.util.Log;
import java.util.Arrays;
import java.util.List;
-/**
- * Bass Utility functions
- */
+/** Bass Utility functions */
class BassUtils {
private static final String TAG = "BassUtils";
static boolean containUuid(List filters, ParcelUuid uuid) {
- for (ScanFilter filter: filters) {
+ for (ScanFilter filter : filters) {
if (filter.getServiceUuid().equals(uuid)) {
return true;
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java b/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java
index 7a33db94d0d8f174a1be905ea712ee12147bc02c..31cf2776060acdceced78adc27349d3d96da60af 100644
--- a/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java
+++ b/android/app/src/com/android/bluetooth/bass_client/BluetoothLeScannerWrapper.java
@@ -23,9 +23,7 @@ import android.bluetooth.le.ScanSettings;
import java.util.List;
-/**
- * Helper class to mock {@link BluetoothLeScanner} which is final.
- */
+/** Helper class to mock {@link BluetoothLeScanner} which is final. */
public class BluetoothLeScannerWrapper {
BluetoothLeScanner mBluetoothLeScanner;
@@ -34,17 +32,13 @@ public class BluetoothLeScannerWrapper {
mBluetoothLeScanner = scanner;
}
- /**
- * Starts Bluetooth LE scanning
- */
- public void startScan(List filters, ScanSettings settings,
- final ScanCallback callback) {
+ /** Starts Bluetooth LE scanning */
+ public void startScan(
+ List filters, ScanSettings settings, final ScanCallback callback) {
mBluetoothLeScanner.startScan(filters, settings, callback);
}
- /**
- * Stops Bluetooth LE scanning
- */
+ /** Stops Bluetooth LE scanning */
public void stopScan(ScanCallback callback) {
mBluetoothLeScanner.stopScan(callback);
}
diff --git a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
index 8f23446feaa93a13b752a40301b1fd2fe93b8944..6a985f6ac0b68ac121ba25f0b793b133c0162865 100644
--- a/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
+++ b/android/app/src/com/android/bluetooth/bass_client/PeriodicAdvertisementResult.java
@@ -19,9 +19,7 @@ package com.android.bluetooth.bass_client;
import android.bluetooth.BluetoothDevice;
import android.util.Log;
-/**
- * Periodic Advertisement Result
- */
+/** Periodic Advertisement Result */
public class PeriodicAdvertisementResult {
private static final String TAG = PeriodicAdvertisementResult.class.getSimpleName();
@@ -35,14 +33,15 @@ public class PeriodicAdvertisementResult {
private PublicBroadcastData mPbData;
private String mBroadcastName;
- PeriodicAdvertisementResult(BluetoothDevice device,
- int addressType,
- int syncHandle,
- int advSid,
- int paInterval,
- int broadcastId,
- PublicBroadcastData pbData,
- String broadcastName) {
+ PeriodicAdvertisementResult(
+ BluetoothDevice device,
+ int addressType,
+ int syncHandle,
+ int advSid,
+ int paInterval,
+ int broadcastId,
+ PublicBroadcastData pbData,
+ String broadcastName) {
mDevice = device;
mAddressType = addressType;
mAdvSid = advSid;
@@ -54,23 +53,17 @@ public class PeriodicAdvertisementResult {
mBroadcastName = broadcastName;
}
- /**
- * Update Sync handle
- */
+ /** Update Sync handle */
public void updateSyncHandle(int syncHandle) {
mSyncHandle = syncHandle;
}
- /**
- * Get Sync handle
- */
+ /** Get Sync handle */
public int getSyncHandle() {
return mSyncHandle;
}
- /**
- * Get mIsNotified flag
- */
+ /** Get mIsNotified flag */
public boolean isNotified() {
synchronized (this) {
return mIsNotified;
@@ -83,93 +76,67 @@ public class PeriodicAdvertisementResult {
}
}
- /**
- * Update Adv ID
- */
+ /** Update Adv ID */
public void updateAdvSid(int advSid) {
mAdvSid = advSid;
}
- /**
- * Get Adv ID
- */
+ /** Get Adv ID */
public int getAdvSid() {
return mAdvSid;
}
- /**
- * Update address type
- */
+ /** Update address type */
public void updateAddressType(int addressType) {
mAddressType = addressType;
}
- /**
- * Get address type
- */
+ /** Get address type */
public int getAddressType() {
return mAddressType;
}
- /**
- * Update Adv interval
- */
+ /** Update Adv interval */
public void updateAdvInterval(int advInterval) {
mPAInterval = advInterval;
}
- /**
- * Get Adv interval
- */
+ /** Get Adv interval */
public int getAdvInterval() {
return mPAInterval;
}
- /**
- * Update broadcast ID
- */
+ /** Update broadcast ID */
public void updateBroadcastId(int broadcastId) {
mBroadcastId = broadcastId;
}
- /**
- * Get broadcast ID
- */
+ /** Get broadcast ID */
public int getBroadcastId() {
return mBroadcastId;
}
- /**
- * Update public broadcast data
- */
+ /** Update public broadcast data */
public void updatePublicBroadcastData(PublicBroadcastData pbData) {
mPbData = pbData;
}
- /**
- * Get public broadcast data
- */
+ /** Get public broadcast data */
public PublicBroadcastData getPublicBroadcastData() {
return mPbData;
}
- /**
- * Update broadcast name
- */
+ /** Update broadcast name */
public void updateBroadcastName(String broadcastName) {
mBroadcastName = broadcastName;
}
- /**
- * Get broadcast name
- */
+ /** Get broadcast name */
public String getBroadcastName() {
return mBroadcastName;
}
- /**
- * print
- */
+ /** print */
public void print() {
log("-- PeriodicAdvertisementResult --");
log("mDevice:" + mDevice);
diff --git a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
index bff99cb25e7f2adef68ba50622ed373614f779e2..4601cafa6cc49caf8d8685a8da6e3224e7b2f292 100644
--- a/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
+++ b/android/app/src/com/android/bluetooth/bass_client/PublicBroadcastData.java
@@ -21,9 +21,7 @@ import android.util.Log;
import java.util.Arrays;
-/**
- * Helper class to parse the Public Broadcast Announcement data
- */
+/** Helper class to parse the Public Broadcast Announcement data */
class PublicBroadcastData {
private static final String TAG = "Bassclient.PublicBroadcastData";
private static final int FEATURES_ENCRYPTION_BIT = 0x01 << 0;
diff --git a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
index 0b416d1b70c4c0c32dc2d8d90c55202dd14fc0a1..266b115751f69e043a9ade1028d9078c5947c651 100644
--- a/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/ActiveDeviceManager.java
@@ -52,57 +52,44 @@ import java.util.Objects;
import java.util.Set;
/**
- * The active device manager is responsible for keeping track of the
- * connected A2DP/HFP/AVRCP/HearingAid/LE audio devices and select which device is
- * active (for each profile).
- * The active device manager selects a fallback device when the currently active device
- * is disconnected, and it selects BT devices that are lastly activated one.
+ * The active device manager is responsible for keeping track of the connected
+ * A2DP/HFP/AVRCP/HearingAid/LE audio devices and select which device is active (for each profile).
+ * The active device manager selects a fallback device when the currently active device is
+ * disconnected, and it selects BT devices that are lastly activated one.
*
- * Current policy (subject to change):
- * 1) If the maximum number of connected devices is one, the manager doesn't
- * do anything. Each profile is responsible for automatically selecting
- * the connected device as active. Only if the maximum number of connected
- * devices is more than one, the rules below will apply.
- * 2) The selected A2DP active device is the one used for AVRCP as well.
- * 3) The HFP active device might be different from the A2DP active device.
- * 4) The Active Device Manager always listens for the change of active devices.
- * When it changed (e.g., triggered indirectly by user action on the UI),
- * the new active device is marked as the current active device for that profile.
- * 5) If there is a HearingAid active device, then A2DP, HFP and LE audio active devices
- * must be set to null (i.e., A2DP, HFP and LE audio cannot have active devices).
- * The reason is that A2DP, HFP or LE audio cannot be used together with HearingAid.
- * 6) If there are no connected devices (e.g., during startup, or after all
- * devices have been disconnected, the active device per profile
- * (A2DP/HFP/HearingAid/LE audio) is selected as follows:
- * 6.1) The last connected HearingAid device is selected as active.
- * If there is an active A2DP, HFP or LE audio device, those must be set to null.
- * 6.2) The last connected A2DP, HFP or LE audio device is selected as active.
- * However, if there is an active HearingAid device, then the
- * A2DP, HFP, or LE audio active device is not set (must remain null).
- * 7) If the currently active device (per profile) is disconnected, the
- * Active Device Manager just marks that the profile has no active device,
- * and the lastly activated BT device that is still connected would be selected.
- * 8) If there is already an active device, however, if active device change notified
- * with a null device, the corresponding profile is marked as having no active device.
- * 9) If a wired audio device is connected, the audio output is switched
- * by the Audio Framework itself to that device. We detect this here,
- * and the active device for each profile (A2DP/HFP/HearingAid/LE audio) is set
- * to null to reflect the output device state change. However, if the
- * wired audio device is disconnected, we don't do anything explicit
- * and apply the default behavior instead:
- * 9.1) If the wired headset is still the selected output device (i.e. the
- * active device is set to null), the Phone itself will become the output
- * device (i.e., the active device will remain null). If music was
- * playing, it will stop.
- * 9.2) If one of the Bluetooth devices is the selected active device
- * (e.g., by the user in the UI), disconnecting the wired audio device
- * will have no impact. E.g., music will continue streaming over the
- * active Bluetooth device.
+ * Current policy (subject to change): 1) If the maximum number of connected devices is one, the
+ * manager doesn't do anything. Each profile is responsible for automatically selecting the
+ * connected device as active. Only if the maximum number of connected devices is more than one, the
+ * rules below will apply. 2) The selected A2DP active device is the one used for AVRCP as well. 3)
+ * The HFP active device might be different from the A2DP active device. 4) The Active Device
+ * Manager always listens for the change of active devices. When it changed (e.g., triggered
+ * indirectly by user action on the UI), the new active device is marked as the current active
+ * device for that profile. 5) If there is a HearingAid active device, then A2DP, HFP and LE audio
+ * active devices must be set to null (i.e., A2DP, HFP and LE audio cannot have active devices). The
+ * reason is that A2DP, HFP or LE audio cannot be used together with HearingAid. 6) If there are no
+ * connected devices (e.g., during startup, or after all devices have been disconnected, the active
+ * device per profile (A2DP/HFP/HearingAid/LE audio) is selected as follows: 6.1) The last connected
+ * HearingAid device is selected as active. If there is an active A2DP, HFP or LE audio device,
+ * those must be set to null. 6.2) The last connected A2DP, HFP or LE audio device is selected as
+ * active. However, if there is an active HearingAid device, then the A2DP, HFP, or LE audio active
+ * device is not set (must remain null). 7) If the currently active device (per profile) is
+ * disconnected, the Active Device Manager just marks that the profile has no active device, and the
+ * lastly activated BT device that is still connected would be selected. 8) If there is already an
+ * active device, however, if active device change notified with a null device, the corresponding
+ * profile is marked as having no active device. 9) If a wired audio device is connected, the audio
+ * output is switched by the Audio Framework itself to that device. We detect this here, and the
+ * active device for each profile (A2DP/HFP/HearingAid/LE audio) is set to null to reflect the
+ * output device state change. However, if the wired audio device is disconnected, we don't do
+ * anything explicit and apply the default behavior instead: 9.1) If the wired headset is still the
+ * selected output device (i.e. the active device is set to null), the Phone itself will become the
+ * output device (i.e., the active device will remain null). If music was playing, it will stop.
+ * 9.2) If one of the Bluetooth devices is the selected active device (e.g., by the user in the UI),
+ * disconnecting the wired audio device will have no impact. E.g., music will continue streaming
+ * over the active Bluetooth device.
*/
public class ActiveDeviceManager implements AdapterService.BluetoothStateCallback {
private static final String TAG = ActiveDeviceManager.class.getSimpleName();
- @VisibleForTesting
- static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS = 5_000;
+ @VisibleForTesting static final int A2DP_HFP_SYNC_CONNECTION_TIMEOUT_MS = 5_000;
private final AdapterService mAdapterService;
private DatabaseManager mDbManager;
@@ -113,28 +100,40 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private final AudioManagerAudioDeviceCallback mAudioManagerAudioDeviceCallback;
private final Object mLock = new Object();
+
@GuardedBy("mLock")
private final List mA2dpConnectedDevices = new ArrayList<>();
+
@GuardedBy("mLock")
private final List mHfpConnectedDevices = new ArrayList<>();
+
@GuardedBy("mLock")
private final List mHearingAidConnectedDevices = new ArrayList<>();
+
@GuardedBy("mLock")
private final List mLeAudioConnectedDevices = new ArrayList<>();
+
@GuardedBy("mLock")
private final List mLeHearingAidConnectedDevices = new ArrayList<>();
+
@GuardedBy("mLock")
private List mPendingLeHearingAidActiveDevice = new ArrayList<>();
+
@GuardedBy("mLock")
private BluetoothDevice mA2dpActiveDevice = null;
+
@GuardedBy("mLock")
private BluetoothDevice mHfpActiveDevice = null;
+
@GuardedBy("mLock")
private final Set mHearingAidActiveDevices = new ArraySet<>();
+
@GuardedBy("mLock")
private BluetoothDevice mLeAudioActiveDevice = null;
+
@GuardedBy("mLock")
private BluetoothDevice mLeHearingAidActiveDevice = null;
+
@GuardedBy("mLock")
private BluetoothDevice mPendingActiveDevice = null;
@@ -226,13 +225,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
}
/**
- * Handles the active device logic for when A2DP is connected. Does the following:
- * 1. Check if a hearing aid device is active. We will always prefer hearing aid devices, so if
- * one is active, we will not make this A2DP device active.
- * 2. If there is no hearing aid device active, we will make this A2DP device active.
- * 3. We will make this device active for HFP if it's already connected to HFP
- * 4. If dual mode is disabled, we clear the LE Audio active device to ensure mutual exclusion
- * between classic and LE audio.
+ * Handles the active device logic for when A2DP is connected. Does the following: 1. Check if a
+ * hearing aid device is active. We will always prefer hearing aid devices, so if one is active,
+ * we will not make this A2DP device active. 2. If there is no hearing aid device active, we
+ * will make this A2DP device active. 3. We will make this device active for HFP if it's already
+ * connected to HFP 4. If dual mode is disabled, we clear the LE Audio active device to ensure
+ * mutual exclusion between classic and LE audio.
*
* @param device is the device that was connected to A2DP
*/
@@ -275,8 +273,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setLeAudioActiveDevice(null, true);
}
} else {
- Log.d(TAG, "A2DP activation is suspended until HFP connected: "
- + device);
+ Log.d(TAG, "A2DP activation is suspended until HFP connected: " + device);
if (mPendingActiveDevice != null) {
mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
}
@@ -295,13 +292,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
}
/**
- * Handles the active device logic for when HFP is connected. Does the following:
- * 1. Check if a hearing aid device is active. We will always prefer hearing aid devices, so if
- * one is active, we will not make this HFP device active.
- * 2. If there is no hearing aid device active, we will make this HFP device active.
- * 3. We will make this device active for A2DP if it's already connected to A2DP
- * 4. If dual mode is disabled, we clear the LE Audio active device to ensure mutual exclusion
- * between classic and LE audio.
+ * Handles the active device logic for when HFP is connected. Does the following: 1. Check if a
+ * hearing aid device is active. We will always prefer hearing aid devices, so if one is active,
+ * we will not make this HFP device active. 2. If there is no hearing aid device active, we will
+ * make this HFP device active. 3. We will make this device active for A2DP if it's already
+ * connected to A2DP 4. If dual mode is disabled, we clear the LE Audio active device to ensure
+ * mutual exclusion between classic and LE audio.
*
* @param device is the device that was connected to A2DP
*/
@@ -354,8 +350,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setLeAudioActiveDevice(null, true);
}
} else {
- Log.d(TAG, "HFP activation is suspended until A2DP connected: "
- + device);
+ Log.d(TAG, "HFP activation is suspended until A2DP connected: " + device);
if (mPendingActiveDevice != null) {
mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
}
@@ -479,8 +474,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleA2dpDisconnected(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleA2dpDisconnected: " + device
- + ", mA2dpActiveDevice=" + mA2dpActiveDevice);
+ Log.d(
+ TAG,
+ "handleA2dpDisconnected: "
+ + device
+ + ", mA2dpActiveDevice="
+ + mA2dpActiveDevice);
mA2dpConnectedDevices.remove(device);
if (Objects.equals(mA2dpActiveDevice, device)) {
if (!setFallbackDeviceActiveLocked()) {
@@ -492,8 +491,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleHfpDisconnected(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleHfpDisconnected: " + device
- + ", mHfpActiveDevice=" + mHfpActiveDevice);
+ Log.d(
+ TAG,
+ "handleHfpDisconnected: " + device + ", mHfpActiveDevice=" + mHfpActiveDevice);
mHfpConnectedDevices.remove(device);
if (Objects.equals(mHfpActiveDevice, device)) {
if (mHfpConnectedDevices.isEmpty()) {
@@ -506,8 +506,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleHearingAidDisconnected(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleHearingAidDisconnected: " + device
- + ", mHearingAidActiveDevices=" + mHearingAidActiveDevices);
+ Log.d(
+ TAG,
+ "handleHearingAidDisconnected: "
+ + device
+ + ", mHearingAidActiveDevices="
+ + mHearingAidActiveDevices);
mHearingAidConnectedDevices.remove(device);
if (mHearingAidActiveDevices.remove(device) && mHearingAidActiveDevices.isEmpty()) {
if (!setFallbackDeviceActiveLocked()) {
@@ -519,8 +523,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleLeAudioDisconnected(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleLeAudioDisconnected: " + device
- + ", mLeAudioActiveDevice=" + mLeAudioActiveDevice);
+ Log.d(
+ TAG,
+ "handleLeAudioDisconnected: "
+ + device
+ + ", mLeAudioActiveDevice="
+ + mLeAudioActiveDevice);
final LeAudioService leAudioService = mFactory.getLeAudioService();
if (leAudioService == null || device == null) {
@@ -543,8 +551,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleHapDisconnected(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleHapDisconnected: " + device
- + ", mLeHearingAidActiveDevice=" + mLeHearingAidActiveDevice);
+ Log.d(
+ TAG,
+ "handleHapDisconnected: "
+ + device
+ + ", mLeHearingAidActiveDevice="
+ + mLeHearingAidActiveDevice);
mLeHearingAidConnectedDevices.remove(device);
mPendingLeHearingAidActiveDevice.remove(device);
if (Objects.equals(mLeHearingAidActiveDevice, device)) {
@@ -555,18 +567,21 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
/**
* Handles the active device logic for when the A2DP active device changes. Does the following:
- * 1. Clear the active hearing aid.
- * 2. If dual mode is enabled and all supported classic audio profiles are enabled, makes this
- * device active for LE Audio. If not, clear the LE Audio active device.
- * 3. Make HFP active for this device if it is already connected to HFP.
- * 4. Stores the new A2DP active device.
+ * 1. Clear the active hearing aid. 2. If dual mode is enabled and all supported classic audio
+ * profiles are enabled, makes this device active for LE Audio. If not, clear the LE Audio
+ * active device. 3. Make HFP active for this device if it is already connected to HFP. 4.
+ * Stores the new A2DP active device.
*
* @param device is the device that was connected to A2DP
*/
private void handleA2dpActiveDeviceChanged(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleA2dpActiveDeviceChanged: " + device
- + ", mA2dpActiveDevice=" + mA2dpActiveDevice);
+ Log.d(
+ TAG,
+ "handleA2dpActiveDeviceChanged: "
+ + device
+ + ", mA2dpActiveDevice="
+ + mA2dpActiveDevice);
if (!Objects.equals(mA2dpActiveDevice, device)) {
if (device != null) {
setHearingAidActiveDevice(null, true);
@@ -619,18 +634,21 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
/**
* Handles the active device logic for when the HFP active device changes. Does the following:
- * 1. Clear the active hearing aid.
- * 2. If dual mode is enabled and all supported classic audio profiles are enabled, makes this
- * device active for LE Audio. If not, clear the LE Audio active device.
- * 3. Make A2DP active for this device if it is already connected to A2DP.
- * 4. Stores the new HFP active device.
+ * 1. Clear the active hearing aid. 2. If dual mode is enabled and all supported classic audio
+ * profiles are enabled, makes this device active for LE Audio. If not, clear the LE Audio
+ * active device. 3. Make A2DP active for this device if it is already connected to A2DP. 4.
+ * Stores the new HFP active device.
*
* @param device is the device that was connected to A2DP
*/
private void handleHfpActiveDeviceChanged(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleHfpActiveDeviceChanged: " + device
- + ", mHfpActiveDevice=" + mHfpActiveDevice);
+ Log.d(
+ TAG,
+ "handleHfpActiveDeviceChanged: "
+ + device
+ + ", mHfpActiveDevice="
+ + mHfpActiveDevice);
if (!Objects.equals(mHfpActiveDevice, device)) {
if (device != null) {
setHearingAidActiveDevice(null, true);
@@ -690,8 +708,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleHearingAidActiveDeviceChanged(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleHearingAidActiveDeviceChanged: " + device
- + ", mHearingAidActiveDevices=" + mHearingAidActiveDevices);
+ Log.d(
+ TAG,
+ "handleHearingAidActiveDeviceChanged: "
+ + device
+ + ", mHearingAidActiveDevices="
+ + mHearingAidActiveDevices);
// Just assign locally the new value
final HearingAidService hearingAidService = mFactory.getHearingAidService();
if (hearingAidService != null) {
@@ -714,8 +736,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
private void handleLeAudioActiveDeviceChanged(BluetoothDevice device) {
synchronized (mLock) {
- Log.d(TAG, "handleLeAudioActiveDeviceChanged: " + device
- + ", mLeAudioActiveDevice=" + mLeAudioActiveDevice);
+ Log.d(
+ TAG,
+ "handleLeAudioActiveDeviceChanged: "
+ + device
+ + ", mLeAudioActiveDevice="
+ + mLeAudioActiveDevice);
if (device != null && !mLeAudioConnectedDevices.contains(device)) {
mLeAudioConnectedDevices.add(device);
}
@@ -756,8 +782,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
Log.d(TAG, "onAudioDevicesAdded");
boolean hasAddedWiredDevice = false;
for (AudioDeviceInfo deviceInfo : addedDevices) {
- Log.d(TAG, "Audio device added: " + deviceInfo.getProductName() + " type: "
- + deviceInfo.getType());
+ Log.d(
+ TAG,
+ "Audio device added: "
+ + deviceInfo.getProductName()
+ + " type: "
+ + deviceInfo.getType());
if (isWiredAudioHeadset(deviceInfo)) {
hasAddedWiredDevice = true;
break;
@@ -769,8 +799,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
}
@Override
- public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
- }
+ public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {}
}
ActiveDeviceManager(AdapterService service, ServiceFactory factory) {
@@ -806,8 +835,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
}
/**
- * Get the {@link Looper} for the handler thread. This is used in testing and helper
- * objects
+ * Get the {@link Looper} for the handler thread. This is used in testing and helper objects
*
* @return {@link Looper} for the handler thread
*/
@@ -823,10 +851,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
return setA2dpActiveDevice(device, false);
}
- private boolean setA2dpActiveDevice(@Nullable BluetoothDevice device,
- boolean hasFallbackDevice) {
- Log.d(TAG, "setA2dpActiveDevice(" + device + ")"
- + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
+ private boolean setA2dpActiveDevice(
+ @Nullable BluetoothDevice device, boolean hasFallbackDevice) {
+ Log.d(
+ TAG,
+ "setA2dpActiveDevice("
+ + device
+ + ")"
+ + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
synchronized (mLock) {
if (mPendingActiveDevice != null) {
mHandler.removeCallbacksAndMessages(mPendingActiveDevice);
@@ -869,8 +901,9 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
return false;
}
BluetoothSinkAudioPolicy audioPolicy = headsetService.getHfpCallAudioPolicy(device);
- if (audioPolicy != null && audioPolicy.getActiveDevicePolicyAfterConnection()
- == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) {
+ if (audioPolicy != null
+ && audioPolicy.getActiveDevicePolicyAfterConnection()
+ == BluetoothSinkAudioPolicy.POLICY_NOT_ALLOWED) {
return false;
}
if (!headsetService.setActiveDevice(device)) {
@@ -885,10 +918,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
return setHearingAidActiveDevice(device, false);
}
- private boolean setHearingAidActiveDevice(@Nullable BluetoothDevice device,
- boolean hasFallbackDevice) {
- Log.d(TAG, "setHearingAidActiveDevice(" + device + ")"
- + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
+ private boolean setHearingAidActiveDevice(
+ @Nullable BluetoothDevice device, boolean hasFallbackDevice) {
+ Log.d(
+ TAG,
+ "setHearingAidActiveDevice("
+ + device
+ + ")"
+ + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
final HearingAidService hearingAidService = mFactory.getHearingAidService();
if (hearingAidService == null) {
@@ -923,10 +960,14 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
return setLeAudioActiveDevice(device, false);
}
- private boolean setLeAudioActiveDevice(@Nullable BluetoothDevice device,
- boolean hasFallbackDevice) {
- Log.d(TAG, "setLeAudioActiveDevice(" + device + ")"
- + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
+ private boolean setLeAudioActiveDevice(
+ @Nullable BluetoothDevice device, boolean hasFallbackDevice) {
+ Log.d(
+ TAG,
+ "setLeAudioActiveDevice("
+ + device
+ + ")"
+ + (device == null ? " hasFallbackDevice=" + hasFallbackDevice : ""));
synchronized (mLock) {
final LeAudioService leAudioService = mFactory.getLeAudioService();
if (leAudioService == null) {
@@ -984,8 +1025,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
/**
* TODO: This method can return true when a fallback device for an unrelated profile is found.
- * Take disconnected profile as an argument, and find the exact fallback device.
- * Also, split this method to smaller methods for better readability.
+ * Take disconnected profile as an argument, and find the exact fallback device. Also, split
+ * this method to smaller methods for better readability.
*
* @return true when the fallback device is activated, false otherwise
*/
@@ -1063,7 +1104,7 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
setHfpActiveDevice(null);
}
/* If dual mode is enabled, LEA will be made active once all supported
- classic audio profiles are made active for the device. */
+ classic audio profiles are made active for the device. */
if (!Utils.isDualModeAudioEnabled()) {
setLeAudioActiveDevice(null, true);
}
@@ -1161,14 +1202,15 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
/**
* Checks CoD and metadata to determine if the device is a watch
+ *
* @param device the remote device
* @return {@code true} if it's a watch, {@code false} otherwise
*/
private boolean isWatch(BluetoothDevice device) {
// Check CoD
BluetoothClass deviceClass = device.getBluetoothClass();
- if (deviceClass != null && deviceClass.getDeviceClass()
- == BluetoothClass.Device.WEARABLE_WRIST_WATCH) {
+ if (deviceClass != null
+ && deviceClass.getDeviceClass() == BluetoothClass.Device.WEARABLE_WRIST_WATCH) {
return true;
}
@@ -1201,8 +1243,8 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
}
/**
- * Called when a wired audio device is connected.
- * It might be called multiple times each time a wired audio device is connected.
+ * Called when a wired audio device is connected. It might be called multiple times each time a
+ * wired audio device is connected.
*/
@VisibleForTesting
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterApp.java b/android/app/src/com/android/bluetooth/btservice/AdapterApp.java
index 08f69e161b7719c3c7945c219ca16a0e5d456165..6c245eb229daed95ac4c005be12bef0e0e37b00b 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterApp.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterApp.java
@@ -20,7 +20,7 @@ import android.util.Log;
public class AdapterApp extends Application {
private static final String TAG = "BluetoothAdapterApp";
- //For Debugging only
+ // For Debugging only
private static int sRefCount = 0;
public AdapterApp() {
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
index c4fce10d43286706dcd01e776464a0b898efb21e..ed783b993007be6419cb3c97519ccd370776d221 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterProperties.java
@@ -119,10 +119,10 @@ class AdapterProperties {
private AdapterService mService;
private boolean mDiscovering;
- private long mDiscoveryEndMs; //< Time (ms since epoch) that discovery ended or will end.
+ private long mDiscoveryEndMs; // < Time (ms since epoch) that discovery ended or will end.
private RemoteDevices mRemoteDevices;
private BluetoothAdapter mAdapter;
- //TODO - all hw capabilities to be exposed as a class
+ // TODO - all hw capabilities to be exposed as a class
private int mNumOfAdvertisementInstancesSupported;
private boolean mRpaOffloadSupported;
private int mNumOfOffloadedIrkSupported;
@@ -152,66 +152,67 @@ class AdapterProperties {
private boolean mReceiverRegistered;
private Handler mHandler;
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action == null) {
- Log.w(TAG, "Received intent with null action");
- return;
- }
- switch (action) {
- case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.HEADSET, intent);
- break;
- case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.A2DP, intent);
- break;
- case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent);
- break;
- case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent);
- break;
- case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent);
- break;
- case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent);
- break;
- case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.HID_HOST, intent);
- break;
- case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.AVRCP_CONTROLLER, intent);
- break;
- case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.PAN, intent);
- break;
- case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.MAP, intent);
- break;
- case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.MAP_CLIENT, intent);
- break;
- case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.SAP, intent);
- break;
- case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.PBAP_CLIENT, intent);
- break;
- case BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.PBAP, intent);
- break;
- case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
- logConnectionStateChanges(BluetoothProfile.LE_AUDIO, intent);
- break;
- default:
- Log.w(TAG, "Received unknown intent " + intent);
- break;
- }
- }
- };
+ private BroadcastReceiver mReceiver =
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action == null) {
+ Log.w(TAG, "Received intent with null action");
+ return;
+ }
+ switch (action) {
+ case BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.HEADSET, intent);
+ break;
+ case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.A2DP, intent);
+ break;
+ case BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.HEADSET_CLIENT, intent);
+ break;
+ case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.HEARING_AID, intent);
+ break;
+ case BluetoothA2dpSink.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.A2DP_SINK, intent);
+ break;
+ case BluetoothHidDevice.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.HID_DEVICE, intent);
+ break;
+ case BluetoothHidHost.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.HID_HOST, intent);
+ break;
+ case BluetoothAvrcpController.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.AVRCP_CONTROLLER, intent);
+ break;
+ case BluetoothPan.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.PAN, intent);
+ break;
+ case BluetoothMap.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.MAP, intent);
+ break;
+ case BluetoothMapClient.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.MAP_CLIENT, intent);
+ break;
+ case BluetoothSap.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.SAP, intent);
+ break;
+ case BluetoothPbapClient.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.PBAP_CLIENT, intent);
+ break;
+ case BluetoothPbap.ACTION_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.PBAP, intent);
+ break;
+ case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
+ logConnectionStateChanges(BluetoothProfile.LE_AUDIO, intent);
+ break;
+ default:
+ Log.w(TAG, "Received unknown intent " + intent);
+ break;
+ }
+ }
+ };
// Lock for all getters and setters.
// If finer grained locking is needer, more locks
@@ -230,23 +231,35 @@ class AdapterProperties {
mRemoteDevices = remoteDevices;
// Get default max connected audio devices from config.xml
- int configDefaultMaxConnectedAudioDevices = mService.getResources().getInteger(
- com.android.bluetooth.R.integer.config_bluetooth_max_connected_audio_devices);
+ int configDefaultMaxConnectedAudioDevices =
+ mService.getResources()
+ .getInteger(
+ com.android.bluetooth.R.integer
+ .config_bluetooth_max_connected_audio_devices);
// Override max connected audio devices if MAX_CONNECTED_AUDIO_DEVICES_PROPERTY is set
int propertyOverlayedMaxConnectedAudioDevices =
- SystemProperties.getInt(MAX_CONNECTED_AUDIO_DEVICES_PROPERTY,
+ SystemProperties.getInt(
+ MAX_CONNECTED_AUDIO_DEVICES_PROPERTY,
configDefaultMaxConnectedAudioDevices);
// Make sure the final value of max connected audio devices is within allowed range
- mMaxConnectedAudioDevices = Math.min(Math.max(propertyOverlayedMaxConnectedAudioDevices,
- MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOUND), MAX_CONNECTED_AUDIO_DEVICES_UPPER_BOUND);
- Log.i(TAG, "init(), maxConnectedAudioDevices, default="
- + configDefaultMaxConnectedAudioDevices + ", propertyOverlayed="
- + propertyOverlayedMaxConnectedAudioDevices + ", finalValue="
- + mMaxConnectedAudioDevices);
+ mMaxConnectedAudioDevices =
+ Math.min(
+ Math.max(
+ propertyOverlayedMaxConnectedAudioDevices,
+ MAX_CONNECTED_AUDIO_DEVICES_LOWER_BOUND),
+ MAX_CONNECTED_AUDIO_DEVICES_UPPER_BOUND);
+ Log.i(
+ TAG,
+ "init(), maxConnectedAudioDevices, default="
+ + configDefaultMaxConnectedAudioDevices
+ + ", propertyOverlayed="
+ + propertyOverlayedMaxConnectedAudioDevices
+ + ", finalValue="
+ + mMaxConnectedAudioDevices);
mA2dpOffloadEnabled =
SystemProperties.getBoolean(A2DP_OFFLOAD_SUPPORTED_PROPERTY, false)
- && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
+ && !SystemProperties.getBoolean(A2DP_OFFLOAD_DISABLED_PROPERTY, false);
mHandler = new Handler(Looper.getMainLooper());
@@ -294,19 +307,24 @@ class AdapterProperties {
private static void invalidateGetProfileConnectionStateCache() {
BluetoothAdapter.invalidateGetProfileConnectionStateCache();
}
+
private static void invalidateIsOffloadedFilteringSupportedCache() {
BluetoothAdapter.invalidateIsOffloadedFilteringSupportedCache();
}
+
private static void invalidateBluetoothGetConnectionStateCache() {
BluetoothMap.invalidateBluetoothGetConnectionStateCache();
BluetoothSap.invalidateBluetoothGetConnectionStateCache();
}
+
private static void invalidateGetConnectionStateCache() {
BluetoothAdapter.invalidateGetAdapterConnectionStateCache();
}
+
private static void invalidateGetBondStateCache() {
BluetoothDevice.invalidateBluetoothGetBondStateCache();
}
+
private static void invalidateBluetoothCaches() {
invalidateGetProfileConnectionStateCache();
invalidateIsOffloadedFilteringSupportedCache();
@@ -329,6 +347,7 @@ class AdapterProperties {
/**
* Set the local adapter property - name
+ *
* @param name the name to set
*/
boolean setName(String name) {
@@ -352,11 +371,9 @@ class AdapterProperties {
/**
* Set the local adapter property - scanMode
*
- * @param scanMode the ScanMode to set, valid values are: {
- * BluetoothAdapter.SCAN_MODE_NONE,
+ * @param scanMode the ScanMode to set, valid values are: { BluetoothAdapter.SCAN_MODE_NONE,
* BluetoothAdapter.SCAN_MODE_CONNECTABLE,
- * BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE,
- * }
+ * BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, }
*/
boolean setScanMode(int scanMode) {
addScanChangeLog(scanMode);
@@ -532,7 +549,6 @@ class AdapterProperties {
return mTotNumOfTrackableAdv;
}
-
/**
* @return the isOffloadedTransportDiscoveryDataScanSupported
*/
@@ -560,16 +576,14 @@ class AdapterProperties {
int getDynamicBufferSupport() {
if (!mA2dpOffloadEnabled) {
// TODO: Enable Dynamic Audio Buffer for A2DP software encoding when ready.
- mIsDynamicAudioBufferSizeSupported =
- BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
+ mIsDynamicAudioBufferSizeSupported = BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
} else {
if ((mDynamicAudioBufferSizeSupportedCodecsGroup1 != 0)
|| (mDynamicAudioBufferSizeSupportedCodecsGroup2 != 0)) {
mIsDynamicAudioBufferSizeSupported =
- BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD;
+ BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD;
} else {
- mIsDynamicAudioBufferSizeSupported =
- BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
+ mIsDynamicAudioBufferSizeSupported = BluetoothA2dp.DYNAMIC_BUFFER_SUPPORT_NONE;
}
}
return mIsDynamicAudioBufferSizeSupported;
@@ -741,8 +755,8 @@ class AdapterProperties {
int metricId = mService.getMetricId(device);
byte[] remoteDeviceInfoBytes = MetricsLogger.getInstance().getRemoteDeviceInfoProto(device);
if (state == BluetoothProfile.STATE_CONNECTING) {
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED,
- metricId, device.getName());
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED, metricId, device.getName());
BluetoothStatsLog.write(
BluetoothStatsLog.REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID,
metricId,
@@ -750,9 +764,15 @@ class AdapterProperties {
MetricsLogger.getInstance()
.logAllowlistedDeviceNameHash(metricId, device.getName(), true);
}
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED, state,
- 0 /* deprecated */, profile, mService.obfuscateAddress(device),
- metricId, 0, -1);
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED,
+ state,
+ 0 /* deprecated */,
+ profile,
+ mService.obfuscateAddress(device),
+ metricId,
+ 0,
+ -1);
}
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
@@ -763,13 +783,27 @@ class AdapterProperties {
@RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
void sendConnectionStateChange(BluetoothDevice device, int profile, int state, int prevState) {
- Log.d(TAG, "PROFILE_CONNECTION_STATE_CHANGE: profile="
- + BluetoothProfile.getProfileName(profile) + ", device=" + device + ", "
- + prevState + " -> " + state);
+ Log.d(
+ TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: profile="
+ + BluetoothProfile.getProfileName(profile)
+ + ", device="
+ + device
+ + ", "
+ + prevState
+ + " -> "
+ + state);
if (!isNormalStateTransition(prevState, state)) {
- Log.w(TAG, "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile="
- + BluetoothProfile.getProfileName(profile)
- + ", device=" + device + ", " + prevState + " -> " + state);
+ Log.w(
+ TAG,
+ "PROFILE_CONNECTION_STATE_CHANGE: unexpected transition for profile="
+ + BluetoothProfile.getProfileName(profile)
+ + ", device="
+ + device
+ + ", "
+ + prevState
+ + " -> "
+ + state);
}
BluetoothStatsLog.write(
BluetoothStatsLog.BLUETOOTH_CONNECTION_STATE_CHANGED,
@@ -785,8 +819,11 @@ class AdapterProperties {
// with the invalid state converted to -1 in the intent.
// Better to log an error and not send an intent with
// invalid contents or set mAdapterConnectionState to -1.
- errorLog("sendConnectionStateChange: invalid state transition " + prevState + " -> "
- + state);
+ errorLog(
+ "sendConnectionStateChange: invalid state transition "
+ + prevState
+ + " -> "
+ + state);
return;
}
@@ -803,12 +840,25 @@ class AdapterProperties {
intent.putExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, newAdapterState);
intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_CONNECTION_STATE, prevAdapterState);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
- Log.d(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: " + device + ": " + prevAdapterState
- + " -> " + newAdapterState);
+ Log.d(
+ TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: "
+ + device
+ + ": "
+ + prevAdapterState
+ + " -> "
+ + newAdapterState);
if (!isNormalStateTransition(prevState, state)) {
- Log.w(TAG, "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile="
- + BluetoothProfile.getProfileName(profile)
- + ", device=" + device + ", " + prevState + " -> " + state);
+ Log.w(
+ TAG,
+ "ADAPTER_CONNECTION_STATE_CHANGE: unexpected transition for profile="
+ + BluetoothProfile.getProfileName(profile)
+ + ", device="
+ + device
+ + ", "
+ + prevState
+ + " -> "
+ + state);
}
mService.sendBroadcastAsUser(
intent,
@@ -849,8 +899,8 @@ class AdapterProperties {
return nextState == BluetoothProfile.STATE_DISCONNECTING;
case BluetoothProfile.STATE_DISCONNECTING:
case BluetoothProfile.STATE_CONNECTING:
- return (nextState == BluetoothProfile.STATE_DISCONNECTED) || (nextState
- == BluetoothProfile.STATE_CONNECTED);
+ return (nextState == BluetoothProfile.STATE_DISCONNECTED)
+ || (nextState == BluetoothProfile.STATE_CONNECTED);
default:
return false;
}
@@ -937,8 +987,8 @@ class AdapterProperties {
if (newState == currHashState) {
numDev++;
- } else if (newState == BluetoothProfile.STATE_CONNECTED || (
- newState == BluetoothProfile.STATE_CONNECTING
+ } else if (newState == BluetoothProfile.STATE_CONNECTED
+ || (newState == BluetoothProfile.STATE_CONNECTING
&& currHashState != BluetoothProfile.STATE_CONNECTED)) {
numDev = 1;
} else if (numDev == 1 && oldState == currHashState) {
@@ -1026,8 +1076,9 @@ class AdapterProperties {
byte[] addrByte = new byte[BD_ADDR_LEN];
for (int j = 0; j < number; j++) {
System.arraycopy(val, j * BD_ADDR_LEN, addrByte, 0, BD_ADDR_LEN);
- onBondStateChanged(mAdapter.getRemoteDevice(
- Utils.getAddressStringFromByte(addrByte)),
+ onBondStateChanged(
+ mAdapter.getRemoteDevice(
+ Utils.getAddressStringFromByte(addrByte)),
BluetoothDevice.BOND_BONDED);
}
break;
@@ -1079,35 +1130,53 @@ class AdapterProperties {
mIsLePeriodicAdvertisingSyncTransferRecipientSupported = ((0xFF & ((int) val[27])) != 0);
mIsOffloadedTransportDiscoveryDataScanSupported = ((0x01 & ((int) val[28])) != 0);
- Log.d(TAG, "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller"
- + " mNumOfAdvertisementInstancesSupported = "
- + mNumOfAdvertisementInstancesSupported + " mRpaOffloadSupported = "
- + mRpaOffloadSupported + " mNumOfOffloadedIrkSupported = "
- + mNumOfOffloadedIrkSupported + " mNumOfOffloadedScanFilterSupported = "
- + mNumOfOffloadedScanFilterSupported + " mOffloadedScanResultStorageBytes= "
- + mOffloadedScanResultStorageBytes + " mIsActivityAndEnergyReporting = "
- + mIsActivityAndEnergyReporting + " mVersSupported = " + mVersSupported
- + " mTotNumOfTrackableAdv = " + mTotNumOfTrackableAdv
- + " mIsExtendedScanSupported = " + mIsExtendedScanSupported
- + " mIsDebugLogSupported = " + mIsDebugLogSupported + " mIsLe2MPhySupported = "
- + mIsLe2MPhySupported + " mIsLeCodedPhySupported = " + mIsLeCodedPhySupported
- + " mIsLeExtendedAdvertisingSupported = " + mIsLeExtendedAdvertisingSupported
- + " mIsLePeriodicAdvertisingSupported = " + mIsLePeriodicAdvertisingSupported
- + " mLeMaximumAdvertisingDataLength = " + mLeMaximumAdvertisingDataLength
- + " mDynamicAudioBufferSizeSupportedCodecsGroup1 = "
- + mDynamicAudioBufferSizeSupportedCodecsGroup1
- + " mDynamicAudioBufferSizeSupportedCodecsGroup2 = "
- + mDynamicAudioBufferSizeSupportedCodecsGroup2
- + " mIsLePeriodicAdvertisingSyncTransferSenderSupported = "
- + mIsLePeriodicAdvertisingSyncTransferSenderSupported
- + " mIsLeConnectedIsochronousStreamCentralSupported = "
- + mIsLeConnectedIsochronousStreamCentralSupported
- + " mIsLeIsochronousBroadcasterSupported = "
- + mIsLeIsochronousBroadcasterSupported
- + " mIsLePeriodicAdvertisingSyncTransferRecipientSupported = "
- + mIsLePeriodicAdvertisingSyncTransferRecipientSupported
- + " mIsOffloadedTransportDiscoveryDataScanSupported = "
- + mIsOffloadedTransportDiscoveryDataScanSupported);
+ Log.d(
+ TAG,
+ "BT_PROPERTY_LOCAL_LE_FEATURES: update from BT controller"
+ + " mNumOfAdvertisementInstancesSupported = "
+ + mNumOfAdvertisementInstancesSupported
+ + " mRpaOffloadSupported = "
+ + mRpaOffloadSupported
+ + " mNumOfOffloadedIrkSupported = "
+ + mNumOfOffloadedIrkSupported
+ + " mNumOfOffloadedScanFilterSupported = "
+ + mNumOfOffloadedScanFilterSupported
+ + " mOffloadedScanResultStorageBytes= "
+ + mOffloadedScanResultStorageBytes
+ + " mIsActivityAndEnergyReporting = "
+ + mIsActivityAndEnergyReporting
+ + " mVersSupported = "
+ + mVersSupported
+ + " mTotNumOfTrackableAdv = "
+ + mTotNumOfTrackableAdv
+ + " mIsExtendedScanSupported = "
+ + mIsExtendedScanSupported
+ + " mIsDebugLogSupported = "
+ + mIsDebugLogSupported
+ + " mIsLe2MPhySupported = "
+ + mIsLe2MPhySupported
+ + " mIsLeCodedPhySupported = "
+ + mIsLeCodedPhySupported
+ + " mIsLeExtendedAdvertisingSupported = "
+ + mIsLeExtendedAdvertisingSupported
+ + " mIsLePeriodicAdvertisingSupported = "
+ + mIsLePeriodicAdvertisingSupported
+ + " mLeMaximumAdvertisingDataLength = "
+ + mLeMaximumAdvertisingDataLength
+ + " mDynamicAudioBufferSizeSupportedCodecsGroup1 = "
+ + mDynamicAudioBufferSizeSupportedCodecsGroup1
+ + " mDynamicAudioBufferSizeSupportedCodecsGroup2 = "
+ + mDynamicAudioBufferSizeSupportedCodecsGroup2
+ + " mIsLePeriodicAdvertisingSyncTransferSenderSupported = "
+ + mIsLePeriodicAdvertisingSyncTransferSenderSupported
+ + " mIsLeConnectedIsochronousStreamCentralSupported = "
+ + mIsLeConnectedIsochronousStreamCentralSupported
+ + " mIsLeIsochronousBroadcasterSupported = "
+ + mIsLeIsochronousBroadcasterSupported
+ + " mIsLePeriodicAdvertisingSyncTransferRecipientSupported = "
+ + mIsLePeriodicAdvertisingSyncTransferRecipientSupported
+ + " mIsOffloadedTransportDiscoveryDataScanSupported = "
+ + mIsOffloadedTransportDiscoveryDataScanSupported);
invalidateIsOffloadedFilteringSupportedCache();
}
@@ -1125,12 +1194,12 @@ class AdapterProperties {
List bufferConstraintList = new ArrayList();
for (int i = 0; i < BufferConstraints.BUFFER_CODEC_MAX_NUM; i++) {
- int defaultBufferTime = ((0xFF & ((int) val[i * 6 + 1])) << 8)
- + (0xFF & ((int) val[i * 6]));
- int maximumBufferTime = ((0xFF & ((int) val[i * 6 + 3])) << 8)
- + (0xFF & ((int) val[i * 6 + 2]));
- int minimumBufferTime = ((0xFF & ((int) val[i * 6 + 5])) << 8)
- + (0xFF & ((int) val[i * 6 + 4]));
+ int defaultBufferTime =
+ ((0xFF & ((int) val[i * 6 + 1])) << 8) + (0xFF & ((int) val[i * 6]));
+ int maximumBufferTime =
+ ((0xFF & ((int) val[i * 6 + 3])) << 8) + (0xFF & ((int) val[i * 6 + 2]));
+ int minimumBufferTime =
+ ((0xFF & ((int) val[i * 6 + 5])) << 8) + (0xFF & ((int) val[i * 6 + 4]));
bufferConstraintList.add(
new BufferConstraint(defaultBufferTime, maximumBufferTime, minimumBufferTime));
}
@@ -1139,8 +1208,11 @@ class AdapterProperties {
}
void onBluetoothReady() {
- debugLog("onBluetoothReady, state=" + BluetoothAdapter.nameForState(getState())
- + ", ScanMode=" + mScanMode);
+ debugLog(
+ "onBluetoothReady, state="
+ + BluetoothAdapter.nameForState(getState())
+ + ", ScanMode="
+ + mScanMode);
synchronized (mObject) {
// Reset adapter and profile connection states
@@ -1251,7 +1323,6 @@ class AdapterProperties {
for (String log : mScanModeChanges) {
writer.println(" " + log);
}
-
}
private String dumpDeviceType(int deviceType) {
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterState.java b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
index 2e03054a05dced6556df0aa0ae1e87d3b48ee979..cd2182c1a7d34a88d8b79ed8e23dc3809b29446e 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterState.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterState.java
@@ -27,35 +27,17 @@ import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
/**
- * This state machine handles Bluetooth Adapter State.
- * Stable States:
- * {@link OffState}: Initial State
- * {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on
- * {@link OnState} : Bluetooth is on (All supported profiles)
+ * This state machine handles Bluetooth Adapter State. Stable States: {@link OffState}: Initial
+ * State {@link BleOnState} : Bluetooth Low Energy, Including GATT, is on {@link OnState} :
+ * Bluetooth is on (All supported profiles)
*
- * Transition States:
- * {@link TurningBleOnState} : OffState to BleOnState
- * {@link TurningBleOffState} : BleOnState to OffState
- * {@link TurningOnState} : BleOnState to OnState
- * {@link TurningOffState} : OnState to BleOnState
- *
- * +------ Off <-----+
- * | |
- * v |
- * TurningBleOn TO---> TurningBleOff
- * | ^ ^
- * | | |
- * +-----> ----+ |
- * BleOn |
- * +------ <---+ O
- * v | T
- * TurningOn TO----> TurningOff
- * | ^
- * | |
- * +-----> On ------+
+ * Transition States: {@link TurningBleOnState} : OffState to BleOnState {@link
+ * TurningBleOffState} : BleOnState to OffState {@link TurningOnState} : BleOnState to OnState
+ * {@link TurningOffState} : OnState to BleOnState
*
+ *
+------ Off <-----+ | | v | TurningBleOn TO---> TurningBleOff | ^ ^ | | | +-----> ----+ |
+ * BleOn | +------ <---+ O v | T TurningOn TO----> TurningOff | ^ | | +-----> On ------+
*/
-
final class AdapterState extends StateMachine {
private static final String TAG = AdapterState.class.getSimpleName();
@@ -72,19 +54,17 @@ final class AdapterState extends StateMachine {
static final int BLE_STOP_TIMEOUT = 11;
static final int BLE_START_TIMEOUT = 12;
- static final String BLE_START_TIMEOUT_DELAY_PROPERTY =
- "ro.bluetooth.ble_start_timeout_delay";
- static final String BLE_STOP_TIMEOUT_DELAY_PROPERTY =
- "ro.bluetooth.ble_stop_timeout_delay";
+ static final String BLE_START_TIMEOUT_DELAY_PROPERTY = "ro.bluetooth.ble_start_timeout_delay";
+ static final String BLE_STOP_TIMEOUT_DELAY_PROPERTY = "ro.bluetooth.ble_stop_timeout_delay";
static final int BLE_START_TIMEOUT_DELAY =
- 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
+ 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
static final int BLE_STOP_TIMEOUT_DELAY =
- 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
+ 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
static final int BREDR_START_TIMEOUT_DELAY =
- 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
+ 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
static final int BREDR_STOP_TIMEOUT_DELAY =
- 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
+ 4000 * SystemProperties.getInt("ro.hw_timeout_multiplier", 1);
private AdapterService mAdapterService;
private TurningOnState mTurningOnState = new TurningOnState();
@@ -113,19 +93,32 @@ final class AdapterState extends StateMachine {
private String messageString(int message) {
switch (message) {
- case BLE_TURN_ON: return "BLE_TURN_ON";
- case USER_TURN_ON: return "USER_TURN_ON";
- case BREDR_STARTED: return "BREDR_STARTED";
- case BLE_STARTED: return "BLE_STARTED";
- case USER_TURN_OFF: return "USER_TURN_OFF";
- case BLE_TURN_OFF: return "BLE_TURN_OFF";
- case BLE_STOPPED: return "BLE_STOPPED";
- case BREDR_STOPPED: return "BREDR_STOPPED";
- case BLE_START_TIMEOUT: return "BLE_START_TIMEOUT";
- case BLE_STOP_TIMEOUT: return "BLE_STOP_TIMEOUT";
- case BREDR_START_TIMEOUT: return "BREDR_START_TIMEOUT";
- case BREDR_STOP_TIMEOUT: return "BREDR_STOP_TIMEOUT";
- default: return "Unknown message (" + message + ")";
+ case BLE_TURN_ON:
+ return "BLE_TURN_ON";
+ case USER_TURN_ON:
+ return "USER_TURN_ON";
+ case BREDR_STARTED:
+ return "BREDR_STARTED";
+ case BLE_STARTED:
+ return "BLE_STARTED";
+ case USER_TURN_OFF:
+ return "USER_TURN_OFF";
+ case BLE_TURN_OFF:
+ return "BLE_TURN_OFF";
+ case BLE_STOPPED:
+ return "BLE_STOPPED";
+ case BREDR_STOPPED:
+ return "BREDR_STOPPED";
+ case BLE_START_TIMEOUT:
+ return "BLE_START_TIMEOUT";
+ case BLE_STOP_TIMEOUT:
+ return "BLE_STOP_TIMEOUT";
+ case BREDR_START_TIMEOUT:
+ return "BREDR_START_TIMEOUT";
+ case BREDR_STOP_TIMEOUT:
+ return "BREDR_STOP_TIMEOUT";
+ default:
+ return "Unknown message (" + message + ")";
}
}
@@ -263,8 +256,9 @@ final class AdapterState extends StateMachine {
@Override
public void enter() {
super.enter();
- final int timeoutDelay = SystemProperties.getInt(
- BLE_START_TIMEOUT_DELAY_PROPERTY, BLE_START_TIMEOUT_DELAY);
+ final int timeoutDelay =
+ SystemProperties.getInt(
+ BLE_START_TIMEOUT_DELAY_PROPERTY, BLE_START_TIMEOUT_DELAY);
Log.d(TAG, "Start Timeout Delay: " + timeoutDelay);
sendMessageDelayed(BLE_START_TIMEOUT, timeoutDelay);
mAdapterService.bringUpBle();
@@ -386,8 +380,9 @@ final class AdapterState extends StateMachine {
@Override
public void enter() {
super.enter();
- final int timeoutDelay = SystemProperties.getInt(
- BLE_STOP_TIMEOUT_DELAY_PROPERTY, BLE_STOP_TIMEOUT_DELAY);
+ final int timeoutDelay =
+ SystemProperties.getInt(
+ BLE_STOP_TIMEOUT_DELAY_PROPERTY, BLE_STOP_TIMEOUT_DELAY);
Log.d(TAG, "Stop Timeout Delay: " + timeoutDelay);
sendMessageDelayed(BLE_STOP_TIMEOUT, timeoutDelay);
mAdapterService.bringDownBle();
diff --git a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
index 8b1dc2e8b5fd5ceb4f2a7d82af09c9c823461a29..8f2ca9c35920e8b2c265423180be56ec7426ec63 100644
--- a/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/AudioRoutingManager.java
@@ -564,25 +564,26 @@ public class AudioRoutingManager extends ActiveDeviceManager {
+ ", "
+ device
+ ")");
- boolean activated = switch (profile) {
- case BluetoothProfile.A2DP -> {
- A2dpService service = mFactory.getA2dpService();
- yield service == null ? false : service.setActiveDevice(device);
- }
- case BluetoothProfile.HEADSET -> {
- HeadsetService service = mFactory.getHeadsetService();
- yield service == null ? false : service.setActiveDevice(device);
- }
- case BluetoothProfile.LE_AUDIO -> {
- LeAudioService service = mFactory.getLeAudioService();
- yield service == null ? false : service.setActiveDevice(device);
- }
- case BluetoothProfile.HEARING_AID -> {
- HearingAidService service = mFactory.getHearingAidService();
- yield service == null ? false : service.setActiveDevice(device);
- }
- default -> false;
- };
+ boolean activated =
+ switch (profile) {
+ case BluetoothProfile.A2DP -> {
+ A2dpService service = mFactory.getA2dpService();
+ yield service == null ? false : service.setActiveDevice(device);
+ }
+ case BluetoothProfile.HEADSET -> {
+ HeadsetService service = mFactory.getHeadsetService();
+ yield service == null ? false : service.setActiveDevice(device);
+ }
+ case BluetoothProfile.LE_AUDIO -> {
+ LeAudioService service = mFactory.getLeAudioService();
+ yield service == null ? false : service.setActiveDevice(device);
+ }
+ case BluetoothProfile.HEARING_AID -> {
+ HearingAidService service = mFactory.getHearingAidService();
+ yield service == null ? false : service.setActiveDevice(device);
+ }
+ default -> false;
+ };
if (activated) {
List activeDevices = mActiveDevices.get(profile);
if (activeDevices == null) {
@@ -756,19 +757,22 @@ public class AudioRoutingManager extends ActiveDeviceManager {
public boolean canActivateNow(int profile) {
if (!connectedProfiles.contains(profile)) return false;
return switch (profile) {
- case BluetoothProfile.HEADSET -> !supportedProfiles.contains(
- BluetoothProfile.A2DP)
- || connectedProfiles.contains(BluetoothProfile.A2DP);
- case BluetoothProfile.A2DP -> !supportedProfiles.contains(
- BluetoothProfile.HEADSET)
- || connectedProfiles.contains(BluetoothProfile.HEADSET);
- case BluetoothProfile.LE_AUDIO -> !Utils.isDualModeAudioEnabled()
- // Check all supported A2DP and HFP are connected if dual mode enabled
- || ((connectedProfiles.contains(BluetoothProfile.A2DP)
- || !supportedProfiles.contains(BluetoothProfile.A2DP))
- && (connectedProfiles.contains(BluetoothProfile.HEADSET)
- || !supportedProfiles.contains(
- BluetoothProfile.HEADSET)));
+ case BluetoothProfile.HEADSET ->
+ !supportedProfiles.contains(BluetoothProfile.A2DP)
+ || connectedProfiles.contains(BluetoothProfile.A2DP);
+ case BluetoothProfile.A2DP ->
+ !supportedProfiles.contains(BluetoothProfile.HEADSET)
+ || connectedProfiles.contains(BluetoothProfile.HEADSET);
+ case BluetoothProfile.LE_AUDIO ->
+ !Utils.isDualModeAudioEnabled()
+ // Check all supported A2DP and HFP are connected if dual mode
+ // enabled
+ || ((connectedProfiles.contains(BluetoothProfile.A2DP)
+ || !supportedProfiles.contains(
+ BluetoothProfile.A2DP))
+ && (connectedProfiles.contains(BluetoothProfile.HEADSET)
+ || !supportedProfiles.contains(
+ BluetoothProfile.HEADSET)));
default -> true;
};
}
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
index 4376097c22df20d333ac8bf5415389340c6a0ec9..aeb297dcb079ec03f29225c5b46cc2c1de002aaa 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothAdapterProxy.java
@@ -24,9 +24,9 @@ import com.android.internal.annotations.VisibleForTesting;
/**
* A proxy class that facilitates testing of the ScanManager.
*
- * This is necessary due to the "final" attribute of the BluetoothAdapter class. In order to
- * test the correct functioning of the ScanManager class, the final class must be put
- * into a container that can be mocked correctly.
+ * This is necessary due to the "final" attribute of the BluetoothAdapter class. In order to test
+ * the correct functioning of the ScanManager class, the final class must be put into a container
+ * that can be mocked correctly.
*/
public class BluetoothAdapterProxy {
private static final String TAG = BluetoothAdapterProxy.class.getSimpleName();
diff --git a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
index 3fa40e4b1824f9c7134409c666b8002180b6afec..279d625c8c8b3d89384a76c21b1f31737dcf206e 100644
--- a/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/BluetoothQualityReportNativeInterface.java
@@ -70,9 +70,7 @@ public class BluetoothQualityReportNativeInterface {
cleanupNative();
}
- /**
- * Callback from the native stack back into the Java framework.
- */
+ /** Callback from the native stack back into the Java framework. */
private void bqrDeliver(
byte[] remoteAddr, int lmpVer, int lmpSubVer, int manufacturerId, byte[] bqrRawData) {
BluetoothClass remoteBtClass = null;
@@ -91,8 +89,12 @@ public class BluetoothQualityReportNativeInterface {
remoteName = device.getName();
remoteBtClass = device.getBluetoothClass();
} else {
- Log.e(TAG, "bqrDeliver failed: "
- + (remoteAddress == null ? "remoteAddress is null" : "adapter is null"));
+ Log.e(
+ TAG,
+ "bqrDeliver failed: "
+ + (remoteAddress == null
+ ? "remoteAddress is null"
+ : "adapter is null"));
return;
}
diff --git a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
index 355a3ad5a9b2b4a643e6137d188eed83befaac50..10f3b195358d497f0e5652458c56840939693e4c 100644
--- a/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
+++ b/android/app/src/com/android/bluetooth/btservice/BondStateMachine.java
@@ -58,13 +58,10 @@ import java.util.Optional;
import java.util.Set;
/**
- * This state machine handles Bluetooth Adapter State.
- * States:
- * {@link StableState} : No device is in bonding / unbonding state.
- * {@link PendingCommandState} : Some device is in bonding / unbonding state.
- * TODO(BT) This class can be removed and this logic moved to the stack.
+ * This state machine handles Bluetooth Adapter State. States: {@link StableState} : No device is in
+ * bonding / unbonding state. {@link PendingCommandState} : Some device is in bonding / unbonding
+ * state. TODO(BT) This class can be removed and this logic moved to the stack.
*/
-
final class BondStateMachine extends StateMachine {
private static final String TAG = "BluetoothBondStateMachine";
@@ -99,8 +96,8 @@ final class BondStateMachine extends StateMachine {
@VisibleForTesting Set mPendingBondedDevices = new HashSet<>();
- private BondStateMachine(AdapterService service, AdapterProperties prop,
- RemoteDevices remoteDevices) {
+ private BondStateMachine(
+ AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) {
super("BondStateMachine:");
addState(mStableState);
addState(mPendingCommandState);
@@ -111,8 +108,8 @@ final class BondStateMachine extends StateMachine {
setInitialState(mStableState);
}
- public static BondStateMachine make(AdapterService service, AdapterProperties prop,
- RemoteDevices remoteDevices) {
+ public static BondStateMachine make(
+ AdapterService service, AdapterProperties prop, RemoteDevices remoteDevices) {
Log.d(TAG, "make");
BondStateMachine bsm = new BondStateMachine(service, prop, remoteDevices);
bsm.start();
@@ -146,7 +143,6 @@ final class BondStateMachine extends StateMachine {
BluetoothDevice dev = (BluetoothDevice) msg.obj;
switch (msg.what) {
-
case CREATE_BOND:
/* BOND_BONDED event is send after keys are exchanged, but BTIF layer would
still use bonding control blocks until service discovery is finished. If
@@ -183,10 +179,14 @@ final class BondStateMachine extends StateMachine {
}
}
- OobData p192Data = (msg.getData() != null)
- ? msg.getData().getParcelable(OOBDATAP192) : null;
- OobData p256Data = (msg.getData() != null)
- ? msg.getData().getParcelable(OOBDATAP256) : null;
+ OobData p192Data =
+ (msg.getData() != null)
+ ? msg.getData().getParcelable(OOBDATAP192)
+ : null;
+ OobData p256Data =
+ (msg.getData() != null)
+ ? msg.getData().getParcelable(OOBDATAP256)
+ : null;
createBond(dev, msg.arg1, p192Data, p256Data, true);
break;
case REMOVE_BOND:
@@ -194,16 +194,18 @@ final class BondStateMachine extends StateMachine {
break;
case BONDING_STATE_CHANGE:
int newState = msg.arg1;
- /* if incoming pairing, transition to pending state */
+ /* if incoming pairing, transition to pending state */
if (newState == BluetoothDevice.BOND_BONDING) {
deferMessage(msg);
transitionTo(mPendingCommandState);
} else if (newState == BluetoothDevice.BOND_NONE) {
- /* if the link key was deleted by the stack */
+ /* if the link key was deleted by the stack */
sendIntent(dev, newState, 0, false);
} else {
- Log.e(TAG, "In stable state, received invalid newState: "
- + state2str(newState));
+ Log.e(
+ TAG,
+ "In stable state, received invalid newState: "
+ + state2str(newState));
}
break;
case BONDED_INTENT_DELAY:
@@ -240,18 +242,24 @@ final class BondStateMachine extends StateMachine {
DeviceProperties devProp = mRemoteDevices.getDeviceProperties(dev);
boolean result = false;
if ((mDevices.contains(dev) || mPendingBondedDevices.contains(dev))
- && msg.what != CANCEL_BOND && msg.what != BONDING_STATE_CHANGE
- && msg.what != SSP_REQUEST && msg.what != PIN_REQUEST) {
+ && msg.what != CANCEL_BOND
+ && msg.what != BONDING_STATE_CHANGE
+ && msg.what != SSP_REQUEST
+ && msg.what != PIN_REQUEST) {
deferMessage(msg);
return true;
}
switch (msg.what) {
case CREATE_BOND:
- OobData p192Data = (msg.getData() != null)
- ? msg.getData().getParcelable(OOBDATAP192) : null;
- OobData p256Data = (msg.getData() != null)
- ? msg.getData().getParcelable(OOBDATAP256) : null;
+ OobData p192Data =
+ (msg.getData() != null)
+ ? msg.getData().getParcelable(OOBDATAP192)
+ : null;
+ OobData p256Data =
+ (msg.getData() != null)
+ ? msg.getData().getParcelable(OOBDATAP256)
+ : null;
result = createBond(dev, msg.arg1, p192Data, p256Data, false);
break;
case REMOVE_BOND:
@@ -278,12 +286,12 @@ final class BondStateMachine extends StateMachine {
transitionTo(mStableState);
}
if (newState == BluetoothDevice.BOND_NONE) {
- mAdapterService.setPhonebookAccessPermission(dev,
- BluetoothDevice.ACCESS_UNKNOWN);
- mAdapterService.setMessageAccessPermission(dev,
- BluetoothDevice.ACCESS_UNKNOWN);
- mAdapterService.setSimAccessPermission(dev,
- BluetoothDevice.ACCESS_UNKNOWN);
+ mAdapterService.setPhonebookAccessPermission(
+ dev, BluetoothDevice.ACCESS_UNKNOWN);
+ mAdapterService.setMessageAccessPermission(
+ dev, BluetoothDevice.ACCESS_UNKNOWN);
+ mAdapterService.setSimAccessPermission(
+ dev, BluetoothDevice.ACCESS_UNKNOWN);
// Set the profile Priorities to undefined
clearProfilePriority(dev);
}
@@ -323,7 +331,7 @@ final class BondStateMachine extends StateMachine {
// passkey and displaying it to the user. If the keyboard doesn't follow
// the spec recommendation, check if the keyboard has a fixed PIN zero
// and pair.
- //TODO: Maintain list of devices that have fixed pin
+ // TODO: Maintain list of devices that have fixed pin
// Generate a variable 6-digit PIN in range of 100000-999999
// This is not truly random but good enough.
int pin = 100000 + (int) Math.floor((Math.random() * (999999 - 100000)));
@@ -396,12 +404,17 @@ final class BondStateMachine extends StateMachine {
return false;
}
- @RequiresPermission(allOf = {
+ @RequiresPermission(
+ allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.INTERACT_ACROSS_USERS,
- })
- private boolean createBond(BluetoothDevice dev, int transport, OobData remoteP192Data,
- OobData remoteP256Data, boolean transition) {
+ })
+ private boolean createBond(
+ BluetoothDevice dev,
+ int transport,
+ OobData remoteP192Data,
+ OobData remoteP256Data,
+ boolean transition) {
if (dev.getBondState() == BluetoothDevice.BOND_NONE) {
infoLog("Bond address is:" + dev + ", transport is: " + transport);
byte[] addr = Utils.getBytesFromAddress(dev.getAddress());
@@ -409,28 +422,41 @@ final class BondStateMachine extends StateMachine {
boolean result;
// If we have some data
if (remoteP192Data != null || remoteP256Data != null) {
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
- BluetoothDevice.BOND_BONDING,
- BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING_OOB,
- BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, mAdapterService.getMetricId(dev));
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(dev),
+ transport,
+ dev.getType(),
+ BluetoothDevice.BOND_BONDING,
+ BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING_OOB,
+ BluetoothProtoEnums.UNBOND_REASON_UNKNOWN,
+ mAdapterService.getMetricId(dev));
result =
mAdapterService
.getNative()
.createBondOutOfBand(
addr, transport, remoteP192Data, remoteP256Data);
} else {
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
- BluetoothDevice.BOND_BONDING,
- BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING,
- BluetoothProtoEnums.UNBOND_REASON_UNKNOWN, mAdapterService.getMetricId(dev));
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(dev),
+ transport,
+ dev.getType(),
+ BluetoothDevice.BOND_BONDING,
+ BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_START_PAIRING,
+ BluetoothProtoEnums.UNBOND_REASON_UNKNOWN,
+ mAdapterService.getMetricId(dev));
result = mAdapterService.getNative().createBond(addr, addrType, transport);
}
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED,
- mAdapterService.getMetricId(dev), dev.getName());
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_DEVICE_NAME_REPORTED,
+ mAdapterService.getMetricId(dev),
+ dev.getName());
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(dev),
+ transport,
+ dev.getType(),
BluetoothDevice.BOND_BONDING,
remoteP192Data == null && remoteP256Data == null
? BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN
@@ -438,12 +464,19 @@ final class BondStateMachine extends StateMachine {
BluetoothProtoEnums.UNBOND_REASON_UNKNOWN);
if (!result) {
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(dev), transport, dev.getType(),
- BluetoothDevice.BOND_NONE, BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN,
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(dev),
+ transport,
+ dev.getType(),
+ BluetoothDevice.BOND_NONE,
+ BluetoothProtoEnums.BOND_SUB_STATE_UNKNOWN,
BluetoothDevice.UNBOND_REASON_REPEATED_ATTEMPTS);
// Using UNBOND_REASON_REMOVED for legacy reason
- sendIntent(dev, BluetoothDevice.BOND_NONE, BluetoothDevice.UNBOND_REASON_REMOVED,
+ sendIntent(
+ dev,
+ BluetoothDevice.BOND_NONE,
+ BluetoothDevice.UNBOND_REASON_REMOVED,
false);
return false;
} else if (transition) {
@@ -474,12 +507,13 @@ final class BondStateMachine extends StateMachine {
}
@VisibleForTesting
- @RequiresPermission(allOf = {
+ @RequiresPermission(
+ allOf = {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.INTERACT_ACROSS_USERS,
- })
- void sendIntent(BluetoothDevice device, int newState, int reason,
- boolean isTriggerFromDelayMessage) {
+ })
+ void sendIntent(
+ BluetoothDevice device, int newState, int reason, boolean isTriggerFromDelayMessage) {
DeviceProperties devProp = mRemoteDevices.getDeviceProperties(device);
int oldState = BluetoothDevice.BOND_NONE;
if (newState != BluetoothDevice.BOND_NONE
@@ -494,12 +528,17 @@ final class BondStateMachine extends StateMachine {
if (devProp != null) {
oldState = devProp.getBondState();
}
- if (isTriggerFromDelayMessage && (oldState != BluetoothDevice.BOND_BONDED
- || newState != BluetoothDevice.BOND_BONDED
- || !mPendingBondedDevices.contains(device))) {
- infoLog("Invalid state when doing delay send bonded intent, oldState: " + oldState
- + ", newState: " + newState + ", in PendingBondedDevices list? "
- + mPendingBondedDevices.contains(device));
+ if (isTriggerFromDelayMessage
+ && (oldState != BluetoothDevice.BOND_BONDED
+ || newState != BluetoothDevice.BOND_BONDED
+ || !mPendingBondedDevices.contains(device))) {
+ infoLog(
+ "Invalid state when doing delay send bonded intent, oldState: "
+ + oldState
+ + ", newState: "
+ + newState
+ + ", in PendingBondedDevices list? "
+ + mPendingBondedDevices.contains(device));
return;
}
if (mPendingBondedDevices.contains(device)) {
@@ -517,19 +556,28 @@ final class BondStateMachine extends StateMachine {
if (oldState == newState) {
return;
}
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(device), 0, device.getType(),
- newState, BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_BOND_STATE_INTENT_SENT, reason,
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(device),
+ 0,
+ device.getType(),
+ newState,
+ BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_BOND_STATE_INTENT_SENT,
+ reason,
mAdapterService.getMetricId(device));
BluetoothClass deviceClass = device.getBluetoothClass();
int classOfDevice = deviceClass == null ? 0 : deviceClass.getClassOfDevice();
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED,
- mAdapterService.obfuscateAddress(device), classOfDevice,
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED,
+ mAdapterService.obfuscateAddress(device),
+ classOfDevice,
mAdapterService.getMetricId(device));
mAdapterProperties.onBondStateChanged(device, newState);
- if (!isTriggerFromDelayMessage && newState == BluetoothDevice.BOND_BONDED
- && devProp != null && devProp.getUuids() == null) {
+ if (!isTriggerFromDelayMessage
+ && newState == BluetoothDevice.BOND_BONDED
+ && devProp != null
+ && devProp.getUuids() == null) {
infoLog(device + " is bonded, wait for SDP complete to broadcast bonded intent");
if (!mPendingBondedDevices.contains(device)) {
mPendingBondedDevices.add(device);
@@ -559,8 +607,13 @@ final class BondStateMachine extends StateMachine {
UserHandle.ALL,
BLUETOOTH_CONNECT,
Utils.getTempBroadcastOptions().toBundle());
- infoLog("Bond State Change Intent:" + device + " " + state2str(oldState) + " => "
- + state2str(newState));
+ infoLog(
+ "Bond State Change Intent:"
+ + device
+ + " "
+ + state2str(oldState)
+ + " => "
+ + state2str(newState));
}
void bondStateChangeCallback(int status, byte[] address, int newState, int hciReason) {
@@ -573,8 +626,15 @@ final class BondStateMachine extends StateMachine {
device = mAdapter.getRemoteDevice(Utils.getAddressStringFromByte(address));
}
- infoLog("bondStateChangeCallback: Status: " + status + " Address: " + device + " newState: "
- + newState + " hciReason: " + hciReason);
+ infoLog(
+ "bondStateChangeCallback: Status: "
+ + status
+ + " Address: "
+ + device
+ + " newState: "
+ + newState
+ + " hciReason: "
+ + hciReason);
Message msg = obtainMessage(BONDING_STATE_CHANGE);
msg.obj = device;
@@ -597,13 +657,16 @@ final class BondStateMachine extends StateMachine {
if (bdDevice == null) {
mRemoteDevices.addDeviceProperties(address);
}
- infoLog("sspRequestCallback: " + Utils.getRedactedAddressStringFromByte(address)
- + " pairingVariant " + pairingVariant
- + " passkey: " + (Build.isDebuggable() ? passkey : "******"));
+ infoLog(
+ "sspRequestCallback: "
+ + Utils.getRedactedAddressStringFromByte(address)
+ + " pairingVariant "
+ + pairingVariant
+ + " passkey: "
+ + (Build.isDebuggable() ? passkey : "******"));
int variant;
boolean displayPasskey = false;
switch (pairingVariant) {
-
case AbstractionLayer.BT_SSP_VARIANT_PASSKEY_CONFIRMATION:
variant = BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION;
displayPasskey = true;
@@ -633,10 +696,14 @@ final class BondStateMachine extends StateMachine {
device = Objects.requireNonNull(mRemoteDevices.getDevice(address));
}
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(device), 0, device.getType(),
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(device),
+ 0,
+ device.getType(),
BluetoothDevice.BOND_BONDING,
- BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REQUESTED, 0);
+ BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_SSP_REQUESTED,
+ 0);
Message msg = obtainMessage(SSP_REQUEST);
msg.obj = device;
@@ -652,7 +719,7 @@ final class BondStateMachine extends StateMachine {
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
void pinRequestCallback(byte[] address, byte[] name, int cod, boolean min16Digits) {
- //TODO(BT): Get wakelock and update name and cod
+ // TODO(BT): Get wakelock and update name and cod
BluetoothDevice bdDevice = mRemoteDevices.getDevice(address);
if (bdDevice == null) {
@@ -660,13 +727,22 @@ final class BondStateMachine extends StateMachine {
bdDevice = Objects.requireNonNull(mRemoteDevices.getDevice(address));
}
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
- mAdapterService.obfuscateAddress(bdDevice), 0, bdDevice.getType(),
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_BOND_STATE_CHANGED,
+ mAdapterService.obfuscateAddress(bdDevice),
+ 0,
+ bdDevice.getType(),
BluetoothDevice.BOND_BONDING,
- BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REQUESTED, 0);
+ BluetoothProtoEnums.BOND_SUB_STATE_LOCAL_PIN_REQUESTED,
+ 0);
- infoLog("pinRequestCallback: " + bdDevice
- + " name:" + Utils.getName(bdDevice) + " cod:" + new BluetoothClass(cod));
+ infoLog(
+ "pinRequestCallback: "
+ + bdDevice
+ + " name:"
+ + Utils.getName(bdDevice)
+ + " cod:"
+ + new BluetoothClass(cod));
Message msg = obtainMessage(PIN_REQUEST);
msg.obj = bdDevice;
@@ -691,10 +767,11 @@ final class BondStateMachine extends StateMachine {
removeMessages(what);
}
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- android.Manifest.permission.MODIFY_PHONE_STATE,
- })
+ @RequiresPermission(
+ allOf = {
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ })
private void clearProfilePriority(BluetoothDevice device) {
HidHostService hidService = HidHostService.getHidHostService();
A2dpService a2dpService = A2dpService.getA2dpService();
@@ -718,15 +795,15 @@ final class BondStateMachine extends StateMachine {
headsetService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
}
if (headsetClientService != null) {
- headsetClientService.setConnectionPolicy(device,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
+ headsetClientService.setConnectionPolicy(
+ device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
}
if (a2dpSinkService != null) {
a2dpSinkService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
}
if (pbapClientService != null) {
- pbapClientService.setConnectionPolicy(device,
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
+ pbapClientService.setConnectionPolicy(
+ device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
}
if (leAudioService != null) {
leAudioService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_UNKNOWN);
diff --git a/android/app/src/com/android/bluetooth/btservice/CompanionManager.java b/android/app/src/com/android/bluetooth/btservice/CompanionManager.java
index 16a6c556dc029465ccfda765c6b214b75cec3124..bd56a7dcc22a291368120e47f1ef5f525c6076e3 100644
--- a/android/app/src/com/android/bluetooth/btservice/CompanionManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/CompanionManager.java
@@ -32,16 +32,14 @@ import java.util.HashSet;
import java.util.Set;
/**
- A CompanionManager to specify parameters between companion devices and regular devices.
-
- 1. A paired device is recognized as a companion device if its METADATA_SOFTWARE_VERSION is
- set to BluetoothDevice.COMPANION_TYPE_PRIMARY or BluetoothDevice.COMPANION_TYPE_SECONDARY.
- 2. Only can have one companion device at a time.
- 3. Remove bond does not remove the companion device record.
- 4. Factory reset Bluetooth removes the companion device.
- 5. Companion device has individual GATT connection parameters.
-*/
-
+ * A CompanionManager to specify parameters between companion devices and regular devices.
+ *
+ * 1. A paired device is recognized as a companion device if its METADATA_SOFTWARE_VERSION is set
+ * to BluetoothDevice.COMPANION_TYPE_PRIMARY or BluetoothDevice.COMPANION_TYPE_SECONDARY. 2. Only
+ * can have one companion device at a time. 3. Remove bond does not remove the companion device
+ * record. 4. Factory reset Bluetooth removes the companion device. 5. Companion device has
+ * individual GATT connection parameters.
+ */
public class CompanionManager {
private static final String TAG = "BluetoothCompanionManager";
@@ -59,13 +57,13 @@ public class CompanionManager {
private final int[] mGattConnLowDefault;
private final int[] mGattConnDckDefault;
- @VisibleForTesting static final int COMPANION_TYPE_NONE = 0;
- @VisibleForTesting static final int COMPANION_TYPE_PRIMARY = 1;
+ @VisibleForTesting static final int COMPANION_TYPE_NONE = 0;
+ @VisibleForTesting static final int COMPANION_TYPE_PRIMARY = 1;
@VisibleForTesting static final int COMPANION_TYPE_SECONDARY = 2;
public static final int GATT_CONN_INTERVAL_MIN = 0;
public static final int GATT_CONN_INTERVAL_MAX = 1;
- public static final int GATT_CONN_LATENCY = 2;
+ public static final int GATT_CONN_LATENCY = 2;
@VisibleForTesting static final String COMPANION_INFO = "bluetooth_companion_info";
@VisibleForTesting static final String COMPANION_DEVICE_KEY = "companion_device";
@@ -95,72 +93,113 @@ public class CompanionManager {
public CompanionManager(AdapterService service, ServiceFactory factory) {
mAdapterService = service;
- mGattConnHighDefault = new int[] {
- getGattConfig(PROPERTY_HIGH_MIN_INTERVAL,
- R.integer.gatt_high_priority_min_interval),
- getGattConfig(PROPERTY_HIGH_MAX_INTERVAL,
- R.integer.gatt_high_priority_max_interval),
- getGattConfig(PROPERTY_HIGH_LATENCY,
- R.integer.gatt_high_priority_latency)};
- mGattConnBalanceDefault = new int[] {
- getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL,
- R.integer.gatt_balanced_priority_min_interval),
- getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL,
- R.integer.gatt_balanced_priority_max_interval),
- getGattConfig(PROPERTY_BALANCED_LATENCY,
- R.integer.gatt_balanced_priority_latency)};
- mGattConnLowDefault = new int[] {
- getGattConfig(PROPERTY_LOW_MIN_INTERVAL, R.integer.gatt_low_power_min_interval),
- getGattConfig(PROPERTY_LOW_MAX_INTERVAL, R.integer.gatt_low_power_max_interval),
- getGattConfig(PROPERTY_LOW_LATENCY, R.integer.gatt_low_power_latency)};
- mGattConnDckDefault = new int[] {
- getGattConfig(PROPERTY_DCK_MIN_INTERVAL, R.integer.gatt_dck_priority_min_interval),
- getGattConfig(PROPERTY_DCK_MAX_INTERVAL, R.integer.gatt_dck_priority_max_interval),
- getGattConfig(PROPERTY_DCK_LATENCY, R.integer.gatt_dck_priority_latency)};
-
- mGattConnHighPrimary = new int[] {
- getGattConfig(PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_high_priority_min_interval_primary),
- getGattConfig(PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_high_priority_max_interval_primary),
- getGattConfig(PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_high_priority_latency_primary)};
- mGattConnBalancePrimary = new int[] {
- getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_balanced_priority_min_interval_primary),
- getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_balanced_priority_max_interval_primary),
- getGattConfig(PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_balanced_priority_latency_primary)};
- mGattConnLowPrimary = new int[] {
- getGattConfig(PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_low_power_min_interval_primary),
- getGattConfig(PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_low_power_max_interval_primary),
- getGattConfig(PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_PRIMARY,
- R.integer.gatt_low_power_latency_primary)};
-
- mGattConnHighSecondary = new int[] {
- getGattConfig(PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_high_priority_min_interval_secondary),
- getGattConfig(PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_high_priority_max_interval_secondary),
- getGattConfig(PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_high_priority_latency_secondary)};
- mGattConnBalanceSecondary = new int[] {
- getGattConfig(PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_balanced_priority_min_interval_secondary),
- getGattConfig(PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_balanced_priority_max_interval_secondary),
- getGattConfig(PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_balanced_priority_latency_secondary)};
- mGattConnLowSecondary = new int[] {
- getGattConfig(PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_low_power_min_interval_secondary),
- getGattConfig(PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_low_power_max_interval_secondary),
- getGattConfig(PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_SECONDARY,
- R.integer.gatt_low_power_latency_secondary)};
+ mGattConnHighDefault =
+ new int[] {
+ getGattConfig(
+ PROPERTY_HIGH_MIN_INTERVAL, R.integer.gatt_high_priority_min_interval),
+ getGattConfig(
+ PROPERTY_HIGH_MAX_INTERVAL, R.integer.gatt_high_priority_max_interval),
+ getGattConfig(PROPERTY_HIGH_LATENCY, R.integer.gatt_high_priority_latency)
+ };
+ mGattConnBalanceDefault =
+ new int[] {
+ getGattConfig(
+ PROPERTY_BALANCED_MIN_INTERVAL,
+ R.integer.gatt_balanced_priority_min_interval),
+ getGattConfig(
+ PROPERTY_BALANCED_MAX_INTERVAL,
+ R.integer.gatt_balanced_priority_max_interval),
+ getGattConfig(
+ PROPERTY_BALANCED_LATENCY, R.integer.gatt_balanced_priority_latency)
+ };
+ mGattConnLowDefault =
+ new int[] {
+ getGattConfig(PROPERTY_LOW_MIN_INTERVAL, R.integer.gatt_low_power_min_interval),
+ getGattConfig(PROPERTY_LOW_MAX_INTERVAL, R.integer.gatt_low_power_max_interval),
+ getGattConfig(PROPERTY_LOW_LATENCY, R.integer.gatt_low_power_latency)
+ };
+ mGattConnDckDefault =
+ new int[] {
+ getGattConfig(
+ PROPERTY_DCK_MIN_INTERVAL, R.integer.gatt_dck_priority_min_interval),
+ getGattConfig(
+ PROPERTY_DCK_MAX_INTERVAL, R.integer.gatt_dck_priority_max_interval),
+ getGattConfig(PROPERTY_DCK_LATENCY, R.integer.gatt_dck_priority_latency)
+ };
+
+ mGattConnHighPrimary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_high_priority_min_interval_primary),
+ getGattConfig(
+ PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_high_priority_max_interval_primary),
+ getGattConfig(
+ PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_high_priority_latency_primary)
+ };
+ mGattConnBalancePrimary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_balanced_priority_min_interval_primary),
+ getGattConfig(
+ PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_balanced_priority_max_interval_primary),
+ getGattConfig(
+ PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_balanced_priority_latency_primary)
+ };
+ mGattConnLowPrimary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_low_power_min_interval_primary),
+ getGattConfig(
+ PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_low_power_max_interval_primary),
+ getGattConfig(
+ PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_PRIMARY,
+ R.integer.gatt_low_power_latency_primary)
+ };
+
+ mGattConnHighSecondary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_HIGH_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_high_priority_min_interval_secondary),
+ getGattConfig(
+ PROPERTY_HIGH_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_high_priority_max_interval_secondary),
+ getGattConfig(
+ PROPERTY_HIGH_LATENCY + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_high_priority_latency_secondary)
+ };
+ mGattConnBalanceSecondary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_BALANCED_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_balanced_priority_min_interval_secondary),
+ getGattConfig(
+ PROPERTY_BALANCED_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_balanced_priority_max_interval_secondary),
+ getGattConfig(
+ PROPERTY_BALANCED_LATENCY + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_balanced_priority_latency_secondary)
+ };
+ mGattConnLowSecondary =
+ new int[] {
+ getGattConfig(
+ PROPERTY_LOW_MIN_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_low_power_min_interval_secondary),
+ getGattConfig(
+ PROPERTY_LOW_MAX_INTERVAL + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_low_power_max_interval_secondary),
+ getGattConfig(
+ PROPERTY_LOW_LATENCY + PROPERTY_SUFFIX_SECONDARY,
+ R.integer.gatt_low_power_latency_secondary)
+ };
}
private int getGattConfig(String property, int resId) {
@@ -173,8 +212,8 @@ public class CompanionManager {
try {
mCompanionDevice = mAdapter.getRemoteDevice(address);
- mCompanionType = getCompanionPreferences().getInt(
- COMPANION_TYPE_KEY, COMPANION_TYPE_NONE);
+ mCompanionType =
+ getCompanionPreferences().getInt(COMPANION_TYPE_KEY, COMPANION_TYPE_NONE);
} catch (IllegalArgumentException e) {
mCompanionDevice = null;
mCompanionType = COMPANION_TYPE_NONE;
@@ -184,8 +223,9 @@ public class CompanionManager {
if (mCompanionDevice == null) {
// We don't have any companion phone registered, try look from the bonded devices
for (BluetoothDevice device : mAdapter.getBondedDevices()) {
- byte[] metadata = mAdapterService.getMetadata(device,
- BluetoothDevice.METADATA_SOFTWARE_VERSION);
+ byte[] metadata =
+ mAdapterService.getMetadata(
+ device, BluetoothDevice.METADATA_SOFTWARE_VERSION);
if (metadata == null) {
continue;
}
@@ -208,11 +248,14 @@ public class CompanionManager {
@Override
public void onMetadataChanged(BluetoothDevice device, int key, byte[] value) {
String valueStr = new String(value);
- Log.d(TAG, String.format("Metadata updated in Device %s: %d = %s.", device,
- key, value == null ? null : valueStr));
+ Log.d(
+ TAG,
+ String.format(
+ "Metadata updated in Device %s: %d = %s.",
+ device, key, value == null ? null : valueStr));
if (key == BluetoothDevice.METADATA_SOFTWARE_VERSION
&& (valueStr.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY)
- || valueStr.equals(BluetoothDevice.COMPANION_TYPE_SECONDARY))) {
+ || valueStr.equals(BluetoothDevice.COMPANION_TYPE_SECONDARY))) {
setCompanionDevice(device, valueStr);
}
}
@@ -222,16 +265,17 @@ public class CompanionManager {
synchronized (mMetadataListeningDevices) {
Log.i(TAG, "setCompanionDevice: " + companionDevice + ", type=" + type);
mCompanionDevice = companionDevice;
- mCompanionType = type.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY)
- ? COMPANION_TYPE_PRIMARY : COMPANION_TYPE_SECONDARY;
+ mCompanionType =
+ type.equals(BluetoothDevice.COMPANION_TYPE_PRIMARY)
+ ? COMPANION_TYPE_PRIMARY
+ : COMPANION_TYPE_SECONDARY;
// unregister all metadata listeners
for (BluetoothDevice device : mMetadataListeningDevices) {
try {
mAdapter.removeOnMetadataChangedListener(device, mMetadataListener);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "failed to unregister metadata listener for "
- + device + " " + e);
+ Log.e(TAG, "failed to unregister metadata listener for " + device + " " + e);
}
}
mMetadataListeningDevices.clear();
@@ -279,8 +323,7 @@ public class CompanionManager {
mAdapter.addOnMetadataChangedListener(
device, mAdapterService.getMainExecutor(), mMetadataListener);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "failed to register metadata listener for "
- + device + " " + e);
+ Log.e(TAG, "failed to register metadata listener for " + device + " " + e);
}
mMetadataListeningDevices.add(device);
}
@@ -294,14 +337,12 @@ public class CompanionManager {
try {
mAdapter.removeOnMetadataChangedListener(device, mMetadataListener);
} catch (IllegalArgumentException e) {
- Log.e(TAG, "failed to unregister metadata listener for "
- + device + " " + e);
+ Log.e(TAG, "failed to unregister metadata listener for " + device + " " + e);
}
mMetadataListeningDevices.remove(device);
}
}
-
/**
* Method to get the stored companion device
*
@@ -336,9 +377,7 @@ public class CompanionManager {
return device.equals(mCompanionDevice);
}
- /**
- * Method to reset the stored companion info
- */
+ /** Method to reset the stored companion info */
public void factoryReset() {
synchronized (mMetadataListeningDevices) {
mCompanionDevice = null;
@@ -355,11 +394,11 @@ public class CompanionManager {
* Gets the GATT connection parameters of the device
*
* @param address the address of the Bluetooth device
- * @param type type of the parameter, can be GATT_CONN_INTERVAL_MIN, GATT_CONN_INTERVAL_MAX
- * or GATT_CONN_LATENCY
+ * @param type type of the parameter, can be GATT_CONN_INTERVAL_MIN, GATT_CONN_INTERVAL_MAX or
+ * GATT_CONN_LATENCY
* @param priority the priority of the connection, can be
- * BluetoothGatt.CONNECTION_PRIORITY_HIGH, BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER or
- * BluetoothGatt.CONNECTION_PRIORITY_BALANCED
+ * BluetoothGatt.CONNECTION_PRIORITY_HIGH, BluetoothGatt.CONNECTION_PRIORITY_LOW_POWER or
+ * BluetoothGatt.CONNECTION_PRIORITY_BALANCED
* @return the connection parameter in integer
*/
public int getGattConnParameters(String address, int type, int priority) {
diff --git a/android/app/src/com/android/bluetooth/btservice/DataMigration.java b/android/app/src/com/android/bluetooth/btservice/DataMigration.java
index 7586658d3775d9f3c4a390b90cbfdabeb5db2322..3d4f964060760e70dd5367d139b0cc7f1f10f80b 100644
--- a/android/app/src/com/android/bluetooth/btservice/DataMigration.java
+++ b/android/app/src/com/android/bluetooth/btservice/DataMigration.java
@@ -32,21 +32,17 @@ import com.android.internal.annotations.VisibleForTesting;
import java.util.List;
final class DataMigration {
- private DataMigration(){}
+ private DataMigration() {}
+
private static final String TAG = "DataMigration";
- @VisibleForTesting
- static final String AUTHORITY = "bluetooth_legacy.provider";
+ @VisibleForTesting static final String AUTHORITY = "bluetooth_legacy.provider";
- @VisibleForTesting
- static final String START_MIGRATION_CALL = "start_legacy_migration";
- @VisibleForTesting
- static final String FINISH_MIGRATION_CALL = "finish_legacy_migration";
+ @VisibleForTesting static final String START_MIGRATION_CALL = "start_legacy_migration";
+ @VisibleForTesting static final String FINISH_MIGRATION_CALL = "finish_legacy_migration";
- @VisibleForTesting
- static final String BLUETOOTH_DATABASE = "bluetooth_db";
- @VisibleForTesting
- static final String OPP_DATABASE = "btopp.db";
+ @VisibleForTesting static final String BLUETOOTH_DATABASE = "bluetooth_db";
+ @VisibleForTesting static final String OPP_DATABASE = "btopp.db";
// AvrcpVolumeManager.VOLUME_MAP
private static final String VOLUME_MAP_PREFERENCE_FILE = "bluetooth_volume_map";
@@ -78,26 +74,18 @@ final class DataMigration {
};
// Main key use for storing all the key in the associate bundle
- @VisibleForTesting
- static final String KEY_LIST = "key_list";
+ @VisibleForTesting static final String KEY_LIST = "key_list";
- @VisibleForTesting
- static final String BLUETOOTH_CONFIG = "bluetooth_config";
+ @VisibleForTesting static final String BLUETOOTH_CONFIG = "bluetooth_config";
static final String MIGRATION_DONE_PROPERTY = "migration_done";
- @VisibleForTesting
- static final String MIGRATION_ATTEMPT_PROPERTY = "migration_attempt";
+ @VisibleForTesting static final String MIGRATION_ATTEMPT_PROPERTY = "migration_attempt";
- @VisibleForTesting
- public static final int MIGRATION_STATUS_TO_BE_DONE = 0;
- @VisibleForTesting
- public static final int MIGRATION_STATUS_COMPLETED = 1;
- @VisibleForTesting
- public static final int MIGRATION_STATUS_MISSING_APK = 2;
- @VisibleForTesting
- public static final int MIGRATION_STATUS_MAX_ATTEMPT = 3;
+ @VisibleForTesting public static final int MIGRATION_STATUS_TO_BE_DONE = 0;
+ @VisibleForTesting public static final int MIGRATION_STATUS_COMPLETED = 1;
+ @VisibleForTesting public static final int MIGRATION_STATUS_MISSING_APK = 2;
+ @VisibleForTesting public static final int MIGRATION_STATUS_MAX_ATTEMPT = 3;
- @VisibleForTesting
- static final int MAX_ATTEMPT = 3;
+ @VisibleForTesting static final int MAX_ATTEMPT = 3;
static int run(Context ctx) {
if (migrationStatus(ctx) == MIGRATION_STATUS_COMPLETED) {
@@ -115,7 +103,7 @@ final class DataMigration {
return MIGRATION_STATUS_MAX_ATTEMPT;
}
- for (String pref: sharedPreferencesKeys) {
+ for (String pref : sharedPreferencesKeys) {
sharedPreferencesMigration(pref, ctx);
}
// Migration for DefaultSharedPreferences used in PbapUtils. Contains Long
@@ -133,9 +121,13 @@ final class DataMigration {
static boolean bluetoothDatabaseMigration(Context ctx) {
final String logHeader = BLUETOOTH_DATABASE + ": ";
ContentResolver resolver = ctx.getContentResolver();
- Cursor cursor = resolver.query(
- Uri.parse("content://" + AUTHORITY + "/" + BLUETOOTH_DATABASE),
- null, null, null, null);
+ Cursor cursor =
+ resolver.query(
+ Uri.parse("content://" + AUTHORITY + "/" + BLUETOOTH_DATABASE),
+ null,
+ null,
+ null,
+ null);
if (cursor == null) {
Log.d(TAG, logHeader + "Nothing to migrate");
return true;
@@ -155,9 +147,13 @@ final class DataMigration {
static boolean oppDatabaseMigration(Context ctx) {
final String logHeader = OPP_DATABASE + ": ";
ContentResolver resolver = ctx.getContentResolver();
- Cursor cursor = resolver.query(
- Uri.parse("content://" + AUTHORITY + "/" + OPP_DATABASE),
- null, null, null, null);
+ Cursor cursor =
+ resolver.query(
+ Uri.parse("content://" + AUTHORITY + "/" + OPP_DATABASE),
+ null,
+ null,
+ null,
+ null);
if (cursor == null) {
Log.d(TAG, logHeader + "Nothing to migrate");
return true;
@@ -173,8 +169,8 @@ final class DataMigration {
return status;
}
- private static boolean writeObjectToEditor(SharedPreferences.Editor editor, Bundle b,
- String itemKey) {
+ private static boolean writeObjectToEditor(
+ SharedPreferences.Editor editor, Bundle b, String itemKey) {
Object value = b.get(itemKey);
if (value == null) {
Log.e(TAG, itemKey + ": No value associated with this itemKey");
@@ -189,8 +185,12 @@ final class DataMigration {
} else if (value instanceof String) {
editor.putString(itemKey, (String) value);
} else {
- Log.e(TAG, itemKey + ": Failed to migrate: "
- + value.getClass().getSimpleName() + ": Data type not handled");
+ Log.e(
+ TAG,
+ itemKey
+ + ": Failed to migrate: "
+ + value.getClass().getSimpleName()
+ + ": Data type not handled");
return false;
}
return true;
@@ -241,9 +241,7 @@ final class DataMigration {
static boolean incrementeMigrationAttempt(Context ctx) {
SharedPreferences pref = ctx.getSharedPreferences(BLUETOOTH_CONFIG, Context.MODE_PRIVATE);
int currentAttempt = Math.min(pref.getInt(MIGRATION_ATTEMPT_PROPERTY, 0), MAX_ATTEMPT);
- pref.edit()
- .putInt(MIGRATION_ATTEMPT_PROPERTY, currentAttempt + 1)
- .apply();
+ pref.edit().putInt(MIGRATION_ATTEMPT_PROPERTY, currentAttempt + 1).apply();
return currentAttempt < MAX_ATTEMPT;
}
@@ -261,8 +259,8 @@ final class DataMigration {
@VisibleForTesting
static void markMigrationStatus(Context ctx, int status) {
ctx.getSharedPreferences(BLUETOOTH_CONFIG, Context.MODE_PRIVATE)
- .edit()
- .putInt(MIGRATION_DONE_PROPERTY, status)
- .apply();
+ .edit()
+ .putInt(MIGRATION_DONE_PROPERTY, status)
+ .apply();
}
}
diff --git a/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java b/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java
index 02b2c4bef8ce902ea2eadfdc35fc04cef1d90f91..4e22c1ce4b48005d9800495db91790fc015170f8 100644
--- a/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java
+++ b/android/app/src/com/android/bluetooth/btservice/DeviceBloomfilterGenerator.java
@@ -19,9 +19,7 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-/**
- * Class to generate a default Device Bloomfilter
- */
+/** Class to generate a default Device Bloomfilter */
public class DeviceBloomfilterGenerator {
public static final String BLOOM_FILTER_DEFAULT =
@@ -373,8 +371,10 @@ public class DeviceBloomfilterGenerator {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
- data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
- + Character.digit(s.charAt(i + 1), 16));
+ data[i / 2] =
+ (byte)
+ ((Character.digit(s.charAt(i), 16) << 4)
+ + Character.digit(s.charAt(i + 1), 16));
}
return data;
}
diff --git a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
index 72bf389feb3516cbc10db5df7760da6ed18b840b..e2b729532289a4e41ed1627140cd85c457f9e007 100644
--- a/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
+++ b/android/app/src/com/android/bluetooth/btservice/DiscoveringPackage.java
@@ -24,7 +24,9 @@ final class DiscoveringPackage {
private @Nullable String mPermission;
private boolean mHasDisavowedLocation;
- DiscoveringPackage(@NonNull String packageName, @Nullable String permission,
+ DiscoveringPackage(
+ @NonNull String packageName,
+ @Nullable String permission,
boolean hasDisavowedLocation) {
mPackageName = packageName;
mPermission = permission;
diff --git a/android/app/src/com/android/bluetooth/btservice/InteropUtil.java b/android/app/src/com/android/bluetooth/btservice/InteropUtil.java
index 32e2476249de2aee120d5814fb06fa1d31f88b6e..93ab3ac4f2a6dad9887f6c8ad5c1cbc8751b27cf 100644
--- a/android/app/src/com/android/bluetooth/btservice/InteropUtil.java
+++ b/android/app/src/com/android/bluetooth/btservice/InteropUtil.java
@@ -20,18 +20,17 @@ package com.android.bluetooth.btservice;
import android.util.Log;
/**
- * APIs of interoperability workaround utilities.
- * These APIs will call stack layer's interop APIs of interop.cc to do matching
- * or entry adding/removing.
+ * APIs of interoperability workaround utilities. These APIs will call stack layer's interop APIs of
+ * interop.cc to do matching or entry adding/removing.
*/
public class InteropUtil {
private static final String TAG = "InteropUtil";
/**
- * Add interop feature from device/include/interop.h to below InteropFeature if
- * this feature needs to be matched at java layer. Feature's name will be passed to
- * stack layer to do matching, so make sure that the added feature's name is exactly
- * same as that in device/include/interop.h.
+ * Add interop feature from device/include/interop.h to below InteropFeature if this feature
+ * needs to be matched at java layer. Feature's name will be passed to stack layer to do
+ * matching, so make sure that the added feature's name is exactly same as that in
+ * device/include/interop.h.
*/
public enum InteropFeature {
INTEROP_NOT_UPDATE_AVRCP_PAUSED_TO_REMOTE,
@@ -45,8 +44,8 @@ public class InteropUtil {
}
/**
- * Check if a given address matches a known interoperability workaround
- * identified by the interop feature.
+ * Check if a given address matches a known interoperability workaround identified by the
+ * interop feature.
*
* @param feature a given interop feature defined in {@link InteropFeature}.
* @param address a given address to be matched.
@@ -55,8 +54,11 @@ public class InteropUtil {
public static boolean interopMatchAddr(InteropFeature feature, String address) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopMatchAddr: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopMatchAddr: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return false;
}
@@ -71,8 +73,8 @@ public class InteropUtil {
}
/**
- * Check if a given name matches a known interoperability workaround
- * identified by the interop feature.
+ * Check if a given name matches a known interoperability workaround identified by the interop
+ * feature.
*
* @param feature a given interop feature defined in {@link InteropFeature}.
* @param name a given name to be matched.
@@ -81,8 +83,11 @@ public class InteropUtil {
public static boolean interopMatchName(InteropFeature feature, String name) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopMatchName: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopMatchName: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return false;
}
@@ -98,8 +103,8 @@ public class InteropUtil {
/**
* Check if a given address or remote device name matches a known interoperability workaround
- * identified by the interop feature. remote device name will be fetched internally based on
- * the given address at stack layer.
+ * identified by the interop feature. remote device name will be fetched internally based on the
+ * given address at stack layer.
*
* @param feature a given interop feature defined in {@link InteropFeature}.
* @param address a given address to be matched.
@@ -108,8 +113,11 @@ public class InteropUtil {
public static boolean interopMatchAddrOrName(InteropFeature feature, String address) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopMatchAddrOrName: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopMatchAddrOrName: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return false;
}
@@ -124,25 +132,33 @@ public class InteropUtil {
}
/**
- * Add a dynamic address interop database entry identified by the interop feature
- * for a device matching the first length bytes of addr.
+ * Add a dynamic address interop database entry identified by the interop feature for a device
+ * matching the first length bytes of addr.
*
* @param feature a given interop feature defined in {@link InteropFeature}.
* @param address a given address to be added.
- * @param length the number of bytes of address to be stored,
- * length must be in [1,6], and usually it is 3.
+ * @param length the number of bytes of address to be stored, length must be in [1,6], and
+ * usually it is 3.
*/
- public static void interopDatabaseAddAddr(InteropFeature feature,
- String address, int length) {
+ public static void interopDatabaseAddAddr(InteropFeature feature, String address, int length) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopDatabaseAddAddr: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return;
}
- Log.d(TAG, "interopDatabaseAddAddr: feature=" + feature.name()
- + ", address=" + address + ", length=" + length);
+ Log.d(
+ TAG,
+ "interopDatabaseAddAddr: feature="
+ + feature.name()
+ + ", address="
+ + address
+ + ", length="
+ + length);
if (address == null || (length <= 0 || length > 6)) {
return;
}
@@ -151,8 +167,8 @@ public class InteropUtil {
}
/**
- * Remove a dynamic address interop database entry identified by the interop feature
- * for a device matching the addr.
+ * Remove a dynamic address interop database entry identified by the interop feature for a
+ * device matching the addr.
*
* @param feature a given interop feature defined in {@link InteropFeature}.
* @param address a given address to be removed.
@@ -160,8 +176,11 @@ public class InteropUtil {
public static void interopDatabaseRemoveAddr(InteropFeature feature, String address) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopDatabaseRemoveAddr: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopDatabaseRemoveAddr: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return;
}
@@ -182,8 +201,11 @@ public class InteropUtil {
public static void interopDatabaseAddName(InteropFeature feature, String name) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopDatabaseAddName: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopDatabaseAddName: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return;
}
@@ -204,8 +226,11 @@ public class InteropUtil {
public static void interopDatabaseRemoveName(InteropFeature feature, String name) {
AdapterService adapterService = AdapterService.getAdapterService();
if (adapterService == null) {
- Log.d(TAG, "interopDatabaseRemoveName: feature=" + feature.name()
- + ", adapterService is null or vendor intf is not enabled");
+ Log.d(
+ TAG,
+ "interopDatabaseRemoveName: feature="
+ + feature.name()
+ + ", adapterService is null or vendor intf is not enabled");
return;
}
diff --git a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
index f8904bd6d433ebc255b1428de3dc5a9beee07a20..2822345ed4c9f274ff18511176201ef80b0110f0 100644
--- a/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
+++ b/android/app/src/com/android/bluetooth/btservice/JniCallbacks.java
@@ -76,10 +76,15 @@ class JniCallbacks {
mRemoteDevices.leAddressAssociateCallback(mainAddress, secondaryAddress);
}
- void aclStateChangeCallback(int status, byte[] address, int newState,
- int transportLinkType, int hciReason, int handle) {
- mRemoteDevices.aclStateChangeCallback(status, address, newState,
- transportLinkType, hciReason, handle);
+ void aclStateChangeCallback(
+ int status,
+ byte[] address,
+ int newState,
+ int transportLinkType,
+ int hciReason,
+ int handle) {
+ mRemoteDevices.aclStateChangeCallback(
+ status, address, newState, transportLinkType, hciReason, handle);
}
void keyMissingCallback(byte[] address) {
@@ -111,8 +116,13 @@ class JniCallbacks {
int packets_not_receive_count,
int negative_acknowledgement_count) {
mAdapterService.linkQualityReportCallback(
- timestamp, report_id, rssi, snr, retransmission_count,
- packets_not_receive_count, negative_acknowledgement_count);
+ timestamp,
+ report_id,
+ rssi,
+ snr,
+ retransmission_count,
+ packets_not_receive_count,
+ negative_acknowledgement_count);
}
void switchBufferSizeCallback(boolean is_low_latency_buffer_size) {
diff --git a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
index 737abd3a56a2a8f0c58564770b1106fe2dee1740..7b490e2bbb28d06f80823e2eb85767500190352b 100644
--- a/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
+++ b/android/app/src/com/android/bluetooth/btservice/PhonePolicy.java
@@ -72,8 +72,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
// Message types for the handler (internal messages generated by intents or timeouts)
private static final int MESSAGE_CONNECT_OTHER_PROFILES = 3;
- @VisibleForTesting static final String AUTO_CONNECT_PROFILES_PROPERTY =
- "bluetooth.auto_connect_profiles.enabled";
+ @VisibleForTesting
+ static final String AUTO_CONNECT_PROFILES_PROPERTY = "bluetooth.auto_connect_profiles.enabled";
private static final String LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY =
"ro.bluetooth.leaudio.le_audio_connection_by_default";
@@ -144,18 +144,19 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MESSAGE_CONNECT_OTHER_PROFILES: {
- // Called when we try connect some profiles in processConnectOtherProfiles but
- // we send a delayed message to try connecting the remaining profiles
- BluetoothDevice device = (BluetoothDevice) msg.obj;
- processConnectOtherProfiles(device);
- mConnectOtherProfilesDeviceSet.remove(device);
- break;
- }
+ case MESSAGE_CONNECT_OTHER_PROFILES:
+ {
+ // Called when we try connect some profiles in processConnectOtherProfiles
+ // but
+ // we send a delayed message to try connecting the remaining profiles
+ BluetoothDevice device = (BluetoothDevice) msg.obj;
+ processConnectOtherProfiles(device);
+ mConnectOtherProfilesDeviceSet.remove(device);
+ break;
+ }
}
}
}
-
;
// Policy API functions for lifecycle management (protected)
@@ -174,8 +175,10 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
PhonePolicy(AdapterService service, ServiceFactory factory) {
mAdapterService = service;
- mDatabaseManager = Objects.requireNonNull(mAdapterService.getDatabase(),
- "DatabaseManager cannot be null when PhonePolicy starts");
+ mDatabaseManager =
+ Objects.requireNonNull(
+ mAdapterService.getDatabase(),
+ "DatabaseManager cannot be null when PhonePolicy starts");
mFactory = factory;
mHandler = new PhonePolicyHandler(service.getMainLooper());
mAutoConnectProfilesSupported =
@@ -293,9 +296,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
HearingAidService hearingAidService = mFactory.getHearingAidService();
LeAudioService leAudioService = mFactory.getLeAudioService();
CsipSetCoordinatorService csipSetCoordinatorService =
- mFactory.getCsipSetCoordinatorService();
- VolumeControlService volumeControlService =
- mFactory.getVolumeControlService();
+ mFactory.getCsipSetCoordinatorService();
+ VolumeControlService volumeControlService = mFactory.getVolumeControlService();
HapClientService hapClientService = mFactory.getHapClientService();
BassClientService bcService = mFactory.getBassClientService();
BatteryService batteryService = mFactory.getBatteryService();
@@ -341,8 +343,12 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
if (mAutoConnectProfilesSupported) {
hidService.setConnectionPolicy(device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
} else {
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HID_HOST, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ mAdapterService
+ .getDatabase()
+ .setProfileConnectionPolicy(
+ device,
+ BluetoothProfile.HID_HOST,
+ BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
MetricsLogger.getInstance()
.count(
@@ -359,17 +365,24 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
&& (headsetService.getConnectionPolicy(device)
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN))) {
if (!isDualModeAudioEnabled() && isLeAudioProfileAllowed) {
- debugLog("clear hfp profile priority for the le audio dual mode device "
- + device);
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
+ debugLog("clear hfp profile priority for the le audio dual mode device " + device);
+ mAdapterService
+ .getDatabase()
+ .setProfileConnectionPolicy(
+ device,
+ BluetoothProfile.HEADSET,
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
} else {
if (mAutoConnectProfilesSupported) {
headsetService.setConnectionPolicy(
device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
} else {
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HEADSET, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ mAdapterService
+ .getDatabase()
+ .setProfileConnectionPolicy(
+ device,
+ BluetoothProfile.HEADSET,
+ BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
}
}
@@ -381,12 +394,16 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
if (!isDualModeAudioEnabled() && isLeAudioProfileAllowed) {
debugLog("clear a2dp profile priority for the le audio dual mode device " + device);
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.A2DP, BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
+ mAdapterService
+ .getDatabase()
+ .setProfileConnectionPolicy(
+ device,
+ BluetoothProfile.A2DP,
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN);
} else {
if (mAutoConnectProfilesSupported) {
- a2dpService.setConnectionPolicy(device,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ a2dpService.setConnectionPolicy(
+ device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
} else {
mAdapterService
.getDatabase()
@@ -532,9 +549,12 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
hapClientService.setConnectionPolicy(
device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
} else {
- mAdapterService.getDatabase().setProfileConnectionPolicy(device,
- BluetoothProfile.HAP_CLIENT,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ mAdapterService
+ .getDatabase()
+ .setProfileConnectionPolicy(
+ device,
+ BluetoothProfile.HAP_CLIENT,
+ BluetoothProfile.CONNECTION_POLICY_ALLOWED);
}
} else {
mAdapterService
@@ -582,8 +602,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
== BluetoothProfile.CONNECTION_POLICY_UNKNOWN)) {
debugLog("setting battery profile priority for device " + device);
if (mAutoConnectProfilesSupported) {
- batteryService.setConnectionPolicy(device,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED);
+ batteryService.setConnectionPolicy(
+ device, BluetoothProfile.CONNECTION_POLICY_ALLOWED);
} else {
mAdapterService
.getDatabase()
@@ -655,8 +675,8 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
}
@RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
- private void processProfileStateChanged(BluetoothDevice device, int profileId, int nextState,
- int prevState) {
+ private void processProfileStateChanged(
+ BluetoothDevice device, int profileId, int nextState, int prevState) {
debugLog(
"processProfileStateChanged, device="
+ device
@@ -705,9 +725,13 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
* @param device is the device we just made the active device
*/
private void processActiveDeviceChanged(BluetoothDevice device, int profileId) {
- debugLog("processActiveDeviceChanged, device=" + device + ", profile="
- + BluetoothProfile.getProfileName(profileId) + " isDualModeAudioEnabled="
- + isDualModeAudioEnabled());
+ debugLog(
+ "processActiveDeviceChanged, device="
+ + device
+ + ", profile="
+ + BluetoothProfile.getProfileName(profileId)
+ + " isDualModeAudioEnabled="
+ + isDualModeAudioEnabled());
if (device == null) {
return;
@@ -771,7 +795,7 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
PanService panService = mFactory.getPanService();
LeAudioService leAudioService = mFactory.getLeAudioService();
CsipSetCoordinatorService csipSetCooridnatorService =
- mFactory.getCsipSetCoordinatorService();
+ mFactory.getCsipSetCoordinatorService();
if (hsService != null) {
List hsConnDevList = hsService.getConnectedDevices();
@@ -805,8 +829,9 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
mHeadsetRetrySet.remove(device);
mA2dpRetrySet.remove(device);
if (allProfilesEmpty) {
- debugLog("handleAllProfilesDisconnected: all profiles disconnected for all"
- + " devices");
+ debugLog(
+ "handleAllProfilesDisconnected: all profiles disconnected for all"
+ + " devices");
// reset retry status so that in the next round we can start retrying connections
resetStates();
}
@@ -886,8 +911,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
debugLog("autoConnectA2dp: connecting A2DP with " + device);
a2dpService.connect(device);
} else {
- debugLog("autoConnectA2dp: skipped auto-connect A2DP with device " + device
- + " connectionPolicy " + a2dpConnectionPolicy);
+ debugLog(
+ "autoConnectA2dp: skipped auto-connect A2DP with device "
+ + device
+ + " connectionPolicy "
+ + a2dpConnectionPolicy);
}
}
@@ -903,8 +931,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
debugLog("autoConnectHeadset: Connecting HFP with " + device);
hsService.connect(device);
} else {
- debugLog("autoConnectHeadset: skipped auto-connect HFP with device " + device
- + " connectionPolicy " + headsetConnectionPolicy);
+ debugLog(
+ "autoConnectHeadset: skipped auto-connect HFP with device "
+ + device
+ + " connectionPolicy "
+ + headsetConnectionPolicy);
}
}
@@ -920,8 +951,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
debugLog("autoConnectHidHost: Connecting HID with " + device);
hidHostService.connect(device);
} else {
- debugLog("autoConnectHidHost: skipped auto-connect HID with device " + device
- + " connectionPolicy " + hidHostConnectionPolicy);
+ debugLog(
+ "autoConnectHidHost: skipped auto-connect HID with device "
+ + device
+ + " connectionPolicy "
+ + hidHostConnectionPolicy);
}
}
@@ -944,10 +978,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
// profiles which are not already connected or in the process of connecting to attempt to
// connect to the device that initiated the connection. In the event that this function is
// invoked and there are no current bluetooth connections no new profiles will be connected.
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- android.Manifest.permission.MODIFY_PHONE_STATE,
- })
+ @RequiresPermission(
+ allOf = {
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ android.Manifest.permission.MODIFY_PHONE_STATE,
+ })
private void processConnectOtherProfiles(BluetoothDevice device) {
debugLog("processConnectOtherProfiles, device=" + device);
if (mAdapterService.getState() != BluetoothAdapter.STATE_ON) {
@@ -972,28 +1007,29 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
PanService panService = mFactory.getPanService();
LeAudioService leAudioService = mFactory.getLeAudioService();
CsipSetCoordinatorService csipSetCooridnatorService =
- mFactory.getCsipSetCoordinatorService();
- VolumeControlService volumeControlService =
- mFactory.getVolumeControlService();
+ mFactory.getCsipSetCoordinatorService();
+ VolumeControlService volumeControlService = mFactory.getVolumeControlService();
BatteryService batteryService = mFactory.getBatteryService();
HidHostService hidHostService = mFactory.getHidHostService();
BassClientService bcService = mFactory.getBassClientService();
if (hsService != null) {
- if (!mHeadsetRetrySet.contains(device) && (hsService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!mHeadsetRetrySet.contains(device)
+ && (hsService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (hsService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to Headset with device " + device);
mHeadsetRetrySet.add(device);
hsService.connect(device);
}
}
if (a2dpService != null) {
- if (!mA2dpRetrySet.contains(device) && (a2dpService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!mA2dpRetrySet.contains(device)
+ && (a2dpService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (a2dpService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to A2DP with device " + device);
mA2dpRetrySet.add(device);
a2dpService.connect(device);
@@ -1003,10 +1039,11 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
List panConnDevList = panService.getConnectedDevices();
// TODO: the panConnDevList.isEmpty() check below should be removed once
// Multi-PAN is supported.
- if (panConnDevList.isEmpty() && (panService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (panConnDevList.isEmpty()
+ && (panService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (panService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to PAN with device " + device);
panService.connect(device);
}
@@ -1024,49 +1061,53 @@ public class PhonePolicy implements AdapterService.BluetoothStateCallback {
}
if (csipSetCooridnatorService != null) {
List csipConnDevList = csipSetCooridnatorService.getConnectedDevices();
- if (!csipConnDevList.contains(device) && (csipSetCooridnatorService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!csipConnDevList.contains(device)
+ && (csipSetCooridnatorService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (csipSetCooridnatorService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to CSIP with device " + device);
csipSetCooridnatorService.connect(device);
}
}
if (volumeControlService != null) {
List vcConnDevList = volumeControlService.getConnectedDevices();
- if (!vcConnDevList.contains(device) && (volumeControlService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!vcConnDevList.contains(device)
+ && (volumeControlService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (volumeControlService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to VCP with device " + device);
volumeControlService.connect(device);
}
}
if (batteryService != null) {
List connectedDevices = batteryService.getConnectedDevices();
- if (!connectedDevices.contains(device) && (batteryService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!connectedDevices.contains(device)
+ && (batteryService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (batteryService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to BAS with device " + device);
batteryService.connect(device);
}
}
if (hidHostService != null) {
if ((hidHostService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (hidHostService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to HID with device " + device);
hidHostService.connect(device);
}
}
if (bcService != null) {
List connectedDevices = bcService.getConnectedDevices();
- if (!connectedDevices.contains(device) && (bcService.getConnectionPolicy(device)
- == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
+ if (!connectedDevices.contains(device)
+ && (bcService.getConnectionPolicy(device)
+ == BluetoothProfile.CONNECTION_POLICY_ALLOWED)
&& (bcService.getConnectionState(device)
- == BluetoothProfile.STATE_DISCONNECTED)) {
+ == BluetoothProfile.STATE_DISCONNECTED)) {
debugLog("Retrying connection to BASS with device " + device);
bcService.connect(device);
}
diff --git a/android/app/src/com/android/bluetooth/btservice/ProfileService.java b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
index e2e470401e4351a0d7802ed6a70bdbd0a53e343d..dc1646e4bd2ef3a55e93bb9b5e7d06ee6d19ecfe 100644
--- a/android/app/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/android/app/src/com/android/bluetooth/btservice/ProfileService.java
@@ -16,7 +16,6 @@
package com.android.bluetooth.btservice;
-
import static java.util.Objects.requireNonNull;
import android.annotation.RequiresPermission;
@@ -33,8 +32,7 @@ import com.android.bluetooth.BluetoothMetricsProto;
/** Base class for a background service that runs a Bluetooth profile */
public abstract class ProfileService extends ContextWrapper {
- public static final String BLUETOOTH_PERM =
- android.Manifest.permission.BLUETOOTH;
+ public static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
public static final String BLUETOOTH_PRIVILEGED =
android.Manifest.permission.BLUETOOTH_PRIVILEGED;
@@ -99,10 +97,10 @@ public abstract class ProfileService extends ContextWrapper {
}
/**
- * Set the availability of an owned/managed component (Service, Activity, Provider, etc.)
- * using a string class name assumed to be in the Bluetooth package.
+ * Set the availability of an owned/managed component (Service, Activity, Provider, etc.) using
+ * a string class name assumed to be in the Bluetooth package.
*
- * It's expected that profiles can have a set of components that they may use to provide
+ * It's expected that profiles can have a set of components that they may use to provide
* features or interact with other services/the user. Profiles are expected to enable those
* components when they start, and disable them when they stop.
*
@@ -111,8 +109,7 @@ public abstract class ProfileService extends ContextWrapper {
*/
@RequiresPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE)
protected void setComponentAvailable(String className, boolean enable) {
- Log.d(mName, "setComponentAvailable(className=" + className + ", enable=" + enable
- + ")");
+ Log.d(mName, "setComponentAvailable(className=" + className + ", enable=" + enable + ")");
if (className == null) {
return;
}
@@ -123,7 +120,7 @@ public abstract class ProfileService extends ContextWrapper {
/**
* Set the availability of an owned/managed component (Service, Activity, Provider, etc.)
*
- * It's expected that profiles can have a set of components that they may use to provide
+ *
It's expected that profiles can have a set of components that they may use to provide
* features or interact with other services/the user. Profiles are expected to enable those
* components when they start, and disable them when they stop.
*
@@ -132,16 +129,17 @@ public abstract class ProfileService extends ContextWrapper {
*/
@RequiresPermission(android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE)
protected void setComponentAvailable(ComponentName component, boolean enable) {
- Log.d(mName, "setComponentAvailable(component=" + component + ", enable=" + enable
- + ")");
+ Log.d(mName, "setComponentAvailable(component=" + component + ", enable=" + enable + ")");
if (component == null) {
return;
}
- getPackageManager().setComponentEnabledSetting(
- component,
- enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS);
+ getPackageManager()
+ .setComponentEnabledSetting(
+ component,
+ enable
+ ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP | PackageManager.SYNCHRONOUS);
}
/**
diff --git a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
index 661b7404d41725acf4fedbb7038bf56f31eccaef..8f7e769538ee3b0dcce18abbc4e1f7488950d6d8 100644
--- a/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
+++ b/android/app/src/com/android/bluetooth/btservice/RemoteDevices.java
@@ -82,17 +82,13 @@ public class RemoteDevices {
private final ArrayDeque mDeviceQueue;
/**
- * Bluetooth HFP v1.8 specifies the Battery Charge indicator of AG can take values from
- * {@code 0} to {@code 5}, but it does not specify how to map the values back to percentages.
- * The following mapping is used:
- * - Level 0: 0%
- * - Level 1: midpoint of 1-25%
- * - Level 2: midpoint of 26-50%
- * - Level 3: midpoint of 51-75%
- * - Level 4: midpoint of 76-99%
- * - Level 5: 100%
+ * Bluetooth HFP v1.8 specifies the Battery Charge indicator of AG can take values from {@code
+ * 0} to {@code 5}, but it does not specify how to map the values back to percentages. The
+ * following mapping is used: - Level 0: 0% - Level 1: midpoint of 1-25% - Level 2: midpoint of
+ * 26-50% - Level 3: midpoint of 51-75% - Level 4: midpoint of 76-99% - Level 5: 100%
*/
private static final int HFP_BATTERY_CHARGE_INDICATOR_0 = 0;
+
private static final int HFP_BATTERY_CHARGE_INDICATOR_1 = 13;
private static final int HFP_BATTERY_CHARGE_INDICATOR_2 = 38;
private static final int HFP_BATTERY_CHARGE_INDICATOR_3 = 63;
@@ -106,6 +102,7 @@ public class RemoteDevices {
/**
* Handler must be created from an explicit looper to avoid threading ambiguity
+ *
* @param looper The looper that this handler should be executed on
*/
RemoteDevicesHandler(Looper looper) {
@@ -119,14 +116,14 @@ public class RemoteDevices {
BluetoothDevice device = (BluetoothDevice) msg.obj;
if (device != null) {
// SDP Sending delayed SDP UUID intent
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_SENDING_DELAYED_UUID, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_SENDING_DELAYED_UUID, 1);
DeviceProperties prop = getDeviceProperties(device);
sendUuidIntent(device, prop);
} else {
// SDP Not sending delayed SDP UUID intent b/c device is not there
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_NOT_SENDING_DELAYED_UUID, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_NOT_SENDING_DELAYED_UUID, 1);
}
break;
}
@@ -134,22 +131,23 @@ public class RemoteDevices {
}
/**
- * Predicate that tests if the given {@link BluetoothDevice} is well-known
- * to be used for physical location.
+ * Predicate that tests if the given {@link BluetoothDevice} is well-known to be used for
+ * physical location.
*/
- private final Predicate mLocationDenylistPredicate = (device) -> {
- final MacAddress parsedAddress = MacAddress.fromString(device.getAddress());
- if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) {
- Log.v(TAG, "Skipping device matching denylist: " + device);
- return true;
- }
- final String name = Utils.getName(device);
- if (mAdapterService.getLocationDenylistName().test(name)) {
- Log.v(TAG, "Skipping name matching denylist: " + name);
- return true;
- }
- return false;
- };
+ private final Predicate mLocationDenylistPredicate =
+ (device) -> {
+ final MacAddress parsedAddress = MacAddress.fromString(device.getAddress());
+ if (mAdapterService.getLocationDenylistMac().test(parsedAddress.toByteArray())) {
+ Log.v(TAG, "Skipping device matching denylist: " + device);
+ return true;
+ }
+ final String name = Utils.getName(device);
+ if (mAdapterService.getLocationDenylistName().test(name)) {
+ Log.v(TAG, "Skipping name matching denylist: " + name);
+ return true;
+ }
+ return false;
+ };
RemoteDevices(AdapterService service, Looper looper) {
mAdapter = ((Context) service).getSystemService(BluetoothManager.class).getAdapter();
@@ -163,8 +161,8 @@ public class RemoteDevices {
}
/**
- * Reset should be called when the state of this object needs to be cleared
- * RemoteDevices is still usable after reset
+ * Reset should be called when the state of this object needs to be cleared RemoteDevices is
+ * still usable after reset
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
void reset() {
@@ -605,7 +603,7 @@ public class RemoteDevices {
/**
* @return the mIsCoordinatedSetMember
- */
+ */
boolean isCoordinatedSetMember() {
synchronized (mObject) {
return mIsCoordinatedSetMember;
@@ -614,7 +612,7 @@ public class RemoteDevices {
/**
* @param isCoordinatedSetMember the mIsCoordinatedSetMember to set
- */
+ */
void setIsCoordinatedSetMember(boolean isCoordinatedSetMember) {
if ((mAdapterService.getSupportedProfilesBitMask()
& (1 << BluetoothProfile.CSIP_SET_COORDINATOR))
@@ -669,9 +667,9 @@ public class RemoteDevices {
mModelName = modelName;
try {
mAdapterService.setMetadata(
- this.mDevice,
- BluetoothDevice.METADATA_MODEL_NAME,
- mModelName.getBytes("UTF-8"));
+ this.mDevice,
+ BluetoothDevice.METADATA_MODEL_NAME,
+ mModelName.getBytes("UTF-8"));
} catch (UnsupportedEncodingException uee) {
Log.e(TAG, "setModelName: UTF-8 not supported?!?"); // this should not happen
}
@@ -699,9 +697,8 @@ public class RemoteDevices {
intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
// SDP Sent UUID Intent here
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_SENT_UUID, 1);
- //Remove the outstanding UUID request
+ MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_SENT_UUID, 1);
+ // Remove the outstanding UUID request
mSdpTracker.remove(device);
}
@@ -921,7 +918,8 @@ public class RemoteDevices {
deviceProperties.setBluetoothClass(newBluetoothClass);
intent = new Intent(BluetoothDevice.ACTION_CLASS_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, bdDevice);
- intent.putExtra(BluetoothDevice.EXTRA_CLASS,
+ intent.putExtra(
+ BluetoothDevice.EXTRA_CLASS,
new BluetoothClass(deviceProperties.getBluetoothClass()));
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mAdapterService.sendBroadcast(
@@ -939,27 +937,29 @@ public class RemoteDevices {
if (areUuidsEqual(newUuids, deviceProperties.getUuids())) {
// SDP Skip adding UUIDs to property cache if equal
debugLog("Skip uuids update for " + bdDevice.getAddress());
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_UUIDS_EQUAL_SKIP, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_UUIDS_EQUAL_SKIP, 1);
break;
}
deviceProperties.setUuids(newUuids);
if (mAdapterService.getState() == BluetoothAdapter.STATE_ON) {
// SDP Adding UUIDs to property cache and sending intent
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_ADD_UUID_WITH_INTENT, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(
+ BluetoothProtoEnums.SDP_ADD_UUID_WITH_INTENT, 1);
mAdapterService.deviceUuidUpdated(bdDevice);
sendUuidIntent(bdDevice, deviceProperties);
} else if (mAdapterService.getState()
== BluetoothAdapter.STATE_BLE_ON) {
// SDP Adding UUIDs to property cache but with no intent
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_ADD_UUID_WITH_NO_INTENT, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(
+ BluetoothProtoEnums.SDP_ADD_UUID_WITH_NO_INTENT, 1);
mAdapterService.deviceUuidUpdated(bdDevice);
} else {
// SDP Silently dropping UUIDs and with no intent
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_DROP_UUID, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_DROP_UUID, 1);
}
break;
case AbstractionLayer.BT_PROPERTY_TYPE_OF_DEVICE:
@@ -990,9 +990,17 @@ public class RemoteDevices {
BluetoothStatsLog.write(
BluetoothStatsLog.BLUETOOTH_DEVICE_INFO_REPORTED,
mAdapterService.obfuscateAddress(bdDevice),
- BluetoothProtoEnums.DEVICE_INFO_INTERNAL, LOG_SOURCE_DIS, null,
- modelName, null, null, mAdapterService.getMetricId(bdDevice),
- bdDevice.getAddressType(), 0, 0, 0);
+ BluetoothProtoEnums.DEVICE_INFO_INTERNAL,
+ LOG_SOURCE_DIS,
+ null,
+ modelName,
+ null,
+ null,
+ mAdapterService.getMetricId(bdDevice),
+ bdDevice.getAddressType(),
+ 0,
+ 0,
+ 0);
break;
}
}
@@ -1019,11 +1027,12 @@ public class RemoteDevices {
Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothDevice.EXTRA_CLASS,
- new BluetoothClass(deviceProp.getBluetoothClass()));
+ intent.putExtra(
+ BluetoothDevice.EXTRA_CLASS, new BluetoothClass(deviceProp.getBluetoothClass()));
intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.getRssi());
intent.putExtra(BluetoothDevice.EXTRA_NAME, deviceProp.getName());
- intent.putExtra(BluetoothDevice.EXTRA_IS_COORDINATED_SET_MEMBER,
+ intent.putExtra(
+ BluetoothDevice.EXTRA_IS_COORDINATED_SET_MEMBER,
deviceProp.isCoordinatedSetMember());
final List packages = mAdapterService.getDiscoveringPackages();
@@ -1038,13 +1047,13 @@ public class RemoteDevices {
intent.setPackage(pkg.getPackageName());
if (pkg.getPermission() != null) {
- mAdapterService.sendBroadcastMultiplePermissions(intent,
- new String[] { BLUETOOTH_SCAN, pkg.getPermission() },
+ mAdapterService.sendBroadcastMultiplePermissions(
+ intent,
+ new String[] {BLUETOOTH_SCAN, pkg.getPermission()},
Utils.getTempBroadcastOptions());
} else {
- mAdapterService.sendBroadcastMultiplePermissions(intent,
- new String[] { BLUETOOTH_SCAN },
- Utils.getTempBroadcastOptions());
+ mAdapterService.sendBroadcastMultiplePermissions(
+ intent, new String[] {BLUETOOTH_SCAN}, Utils.getTempBroadcastOptions());
}
}
}
@@ -1053,20 +1062,26 @@ public class RemoteDevices {
void addressConsolidateCallback(byte[] mainAddress, byte[] secondaryAddress) {
BluetoothDevice device = getDevice(mainAddress);
if (device == null) {
- errorLog("addressConsolidateCallback: device is NULL, address="
- + Utils.getRedactedAddressStringFromByte(mainAddress)
- + ", secondaryAddress="
- + Utils.getRedactedAddressStringFromByte(secondaryAddress));
+ errorLog(
+ "addressConsolidateCallback: device is NULL, address="
+ + Utils.getRedactedAddressStringFromByte(mainAddress)
+ + ", secondaryAddress="
+ + Utils.getRedactedAddressStringFromByte(secondaryAddress));
return;
}
- Log.d(TAG, "addressConsolidateCallback device: " + device + ", secondaryAddress:"
- + Utils.getRedactedAddressStringFromByte(secondaryAddress));
+ Log.d(
+ TAG,
+ "addressConsolidateCallback device: "
+ + device
+ + ", secondaryAddress:"
+ + Utils.getRedactedAddressStringFromByte(secondaryAddress));
DeviceProperties deviceProperties = getDeviceProperties(device);
deviceProperties.setIsConsolidated(true);
deviceProperties.setDeviceType(BluetoothDevice.DEVICE_TYPE_DUAL);
deviceProperties.setIdentityAddress(Utils.getAddressStringFromByte(secondaryAddress));
- mDualDevicesMap.put(deviceProperties.getIdentityAddress(), Utils.getAddressStringFromByte(mainAddress));
+ mDualDevicesMap.put(
+ deviceProperties.getIdentityAddress(), Utils.getAddressStringFromByte(mainAddress));
}
/**
@@ -1078,25 +1093,36 @@ public class RemoteDevices {
void leAddressAssociateCallback(byte[] mainAddress, byte[] secondaryAddress) {
BluetoothDevice device = getDevice(mainAddress);
if (device == null) {
- errorLog("leAddressAssociateCallback: device is NULL, address="
- + Utils.getRedactedAddressStringFromByte(mainAddress)
- + ", secondaryAddress="
- + Utils.getRedactedAddressStringFromByte(secondaryAddress));
+ errorLog(
+ "leAddressAssociateCallback: device is NULL, address="
+ + Utils.getRedactedAddressStringFromByte(mainAddress)
+ + ", secondaryAddress="
+ + Utils.getRedactedAddressStringFromByte(secondaryAddress));
return;
}
- Log.d(TAG, "leAddressAssociateCallback device: " + device + ", secondaryAddress:"
- + Utils.getRedactedAddressStringFromByte(secondaryAddress));
+ Log.d(
+ TAG,
+ "leAddressAssociateCallback device: "
+ + device
+ + ", secondaryAddress:"
+ + Utils.getRedactedAddressStringFromByte(secondaryAddress));
DeviceProperties deviceProperties = getDeviceProperties(device);
deviceProperties.mIdentityAddress = Utils.getAddressStringFromByte(secondaryAddress);
}
- @RequiresPermission(allOf = {
- android.Manifest.permission.BLUETOOTH_CONNECT,
- android.Manifest.permission.BLUETOOTH_PRIVILEGED,
- })
- void aclStateChangeCallback(int status, byte[] address, int newState,
- int transportLinkType, int hciReason, int handle) {
+ @RequiresPermission(
+ allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ void aclStateChangeCallback(
+ int status,
+ byte[] address,
+ int newState,
+ int transportLinkType,
+ int hciReason,
+ int handle) {
if (status != AbstractionLayer.BT_STATUS_SUCCESS) {
debugLog("aclStateChangeCallback status is " + status + ", skipping");
return;
@@ -1105,9 +1131,11 @@ public class RemoteDevices {
BluetoothDevice device = getDevice(address);
if (device == null) {
- warnLog("aclStateChangeCallback: device is NULL, address="
- + Utils.getRedactedAddressStringFromByte(address)
- + ", newState=" + newState);
+ warnLog(
+ "aclStateChangeCallback: device is NULL, address="
+ + Utils.getRedactedAddressStringFromByte(address)
+ + ", newState="
+ + newState);
addDeviceProperties(address);
device = Objects.requireNonNull(getDevice(address));
}
@@ -1131,20 +1159,26 @@ public class RemoteDevices {
batteryService.connectIfPossible(device);
}
mAdapterService.updatePhonePolicyOnAclConnect(device);
- SecurityLog.writeEvent(SecurityLog.TAG_BLUETOOTH_CONNECTION,
- Utils.getLoggableAddress(device), /* success */ 1, /* reason */ "");
+ SecurityLog.writeEvent(
+ SecurityLog.TAG_BLUETOOTH_CONNECTION,
+ Utils.getLoggableAddress(device), /* success */
+ 1, /* reason */
+ "");
debugLog(
- "aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state)
- + " Connected: " + device);
+ "aclStateChangeCallback: Adapter State: "
+ + BluetoothAdapter.nameForState(state)
+ + " Connected: "
+ + device);
} else {
deviceProperties.setConnectionHandle(BluetoothDevice.ERROR, transportLinkType);
if (device.getBondState() == BluetoothDevice.BOND_BONDING) {
// Send PAIRING_CANCEL intent to dismiss any dialog requesting bonding.
intent = new Intent(BluetoothDevice.ACTION_PAIRING_CANCEL);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.setPackage(SystemProperties.get(
- Utils.PAIRING_UI_PROPERTY,
- mAdapterService.getString(R.string.pairing_ui_package)));
+ intent.setPackage(
+ SystemProperties.get(
+ Utils.PAIRING_UI_PROPERTY,
+ mAdapterService.getString(R.string.pairing_ui_package)));
mAdapterService.sendBroadcast(
intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
@@ -1168,7 +1202,7 @@ public class RemoteDevices {
&& transportLinkType == BluetoothDevice.TRANSPORT_LE) {
batteryService.disconnect(device);
}
- resetBatteryLevel(device, /*isBas=*/ true);
+ resetBatteryLevel(device, /* isBas= */ true);
}
if (mAdapterService.isAllProfilesUnknown(device)) {
@@ -1177,19 +1211,26 @@ public class RemoteDevices {
deviceProp.setBondingInitiatedLocally(false);
}
}
- SecurityLog.writeEvent(SecurityLog.TAG_BLUETOOTH_DISCONNECTION,
+ SecurityLog.writeEvent(
+ SecurityLog.TAG_BLUETOOTH_DISCONNECTION,
Utils.getLoggableAddress(device),
BluetoothAdapter.BluetoothConnectionCallback.disconnectReasonToString(
AdapterService.hciToAndroidDisconnectReason(hciReason)));
debugLog(
- "aclStateChangeCallback: Adapter State: " + BluetoothAdapter.nameForState(state)
- + " Disconnected: " + device
- + " transportLinkType: " + transportLinkType
- + " hciReason: " + hciReason);
+ "aclStateChangeCallback: Adapter State: "
+ + BluetoothAdapter.nameForState(state)
+ + " Disconnected: "
+ + device
+ + " transportLinkType: "
+ + transportLinkType
+ + " hciReason: "
+ + hciReason);
}
- int connectionState = newState == AbstractionLayer.BT_ACL_STATE_CONNECTED
- ? BluetoothAdapter.STATE_CONNECTED : BluetoothAdapter.STATE_DISCONNECTED;
+ int connectionState =
+ newState == AbstractionLayer.BT_ACL_STATE_CONNECTED
+ ? BluetoothAdapter.STATE_CONNECTED
+ : BluetoothAdapter.STATE_DISCONNECTED;
int metricId = mAdapterService.getMetricId(device);
BluetoothStatsLog.write(
BluetoothStatsLog.BLUETOOTH_ACL_CONNECTION_STATE_CHANGED,
@@ -1200,13 +1241,16 @@ public class RemoteDevices {
BluetoothClass deviceClass = device.getBluetoothClass();
int classOfDevice = deviceClass == null ? 0 : deviceClass.getClassOfDevice();
- BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED,
- mAdapterService.obfuscateAddress(device), classOfDevice, metricId);
+ BluetoothStatsLog.write(
+ BluetoothStatsLog.BLUETOOTH_CLASS_OF_DEVICE_REPORTED,
+ mAdapterService.obfuscateAddress(device),
+ classOfDevice,
+ metricId);
if (intent != null) {
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device)
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
- .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT)
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
mAdapterService.sendBroadcast(
intent, BLUETOOTH_CONNECT, Utils.getTempBroadcastOptions().toBundle());
@@ -1218,8 +1262,8 @@ public class RemoteDevices {
if (connectionState == BluetoothAdapter.STATE_CONNECTED) {
callback.onDeviceConnected(device);
} else {
- callback.onDeviceDisconnected(device,
- AdapterService.hciToAndroidDisconnectReason(hciReason));
+ callback.onDeviceDisconnected(
+ device, AdapterService.hciToAndroidDisconnectReason(hciReason));
}
} catch (RemoteException ex) {
Log.e(TAG, "RemoteException in calling IBluetoothConnectionCallback");
@@ -1227,8 +1271,10 @@ public class RemoteDevices {
}
}
} else {
- Log.e(TAG, "aclStateChangeCallback intent is null. deviceBondState: "
- + device.getBondState());
+ Log.e(
+ TAG,
+ "aclStateChangeCallback intent is null. deviceBondState: "
+ + device.getBondState());
}
}
@@ -1300,18 +1346,19 @@ public class RemoteDevices {
+ device
+ " transport:"
+ transport);
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_CACHED, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_CACHED, 1);
return;
}
// If no UUIDs are cached and the device is bonding, wait for SDP after the device is bonded
DeviceProperties deviceProperties = getDeviceProperties(device);
- if (deviceProperties != null && deviceProperties.isBonding()
+ if (deviceProperties != null
+ && deviceProperties.isBonding()
&& getDeviceProperties(device).getUuids() == null) {
debugLog("Skip fetch UUIDs due to bonding peer:" + device + " transport:" + transport);
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_BONDED, 1);
+ MetricsLogger.getInstance()
+ .cacheCount(BluetoothProtoEnums.SDP_FETCH_UUID_SKIP_ALREADY_BONDED, 1);
return;
}
@@ -1331,8 +1378,7 @@ public class RemoteDevices {
mAdapterService
.getNative()
.getRemoteServices(Utils.getBytesFromAddress(device.getAddress()), transport);
- MetricsLogger.getInstance().cacheCount(
- BluetoothProtoEnums.SDP_INVOKE_SDP_CYCLE, 1);
+ MetricsLogger.getInstance().cacheCount(BluetoothProtoEnums.SDP_INVOKE_SDP_CYCLE, 1);
}
}
@@ -1355,7 +1401,7 @@ public class RemoteDevices {
return;
}
if (toState == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) {
- resetBatteryLevel(device, /*isBas=*/ false);
+ resetBatteryLevel(device, /* isBas= */ false);
}
}
@@ -1372,7 +1418,7 @@ public class RemoteDevices {
return;
}
if (indicatorId == HeadsetHalConstants.HF_INDICATOR_BATTERY_LEVEL_STATUS) {
- updateBatteryLevel(device, indicatorValue, /*isBas=*/ false);
+ updateBatteryLevel(device, indicatorValue, /* isBas= */ false);
}
}
@@ -1421,19 +1467,23 @@ public class RemoteDevices {
break;
}
if (batteryPercent != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
- updateBatteryLevel(device, batteryPercent, /*isBas=*/ false);
- infoLog("Updated device " + device + " battery level to " + String.valueOf(
- batteryPercent) + "%");
+ updateBatteryLevel(device, batteryPercent, /* isBas= */ false);
+ infoLog(
+ "Updated device "
+ + device
+ + " battery level to "
+ + String.valueOf(batteryPercent)
+ + "%");
}
}
/**
- * Parse
- * AT+IPHONEACCEV=[NumberOfIndicators],[IndicatorType],[IndicatorValue]
- * vendor specific event
+ * Parse AT+IPHONEACCEV=[NumberOfIndicators],[IndicatorType],[IndicatorValue] vendor specific
+ * event
+ *
* @param args Array of arguments on the right side of assignment
* @return Battery level in percents, [0-100], {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
- * when there is an error parsing the arguments
+ * when there is an error parsing the arguments
*/
@VisibleForTesting
static int getBatteryLevelFromAppleBatteryVsc(Object[] args) {
@@ -1475,17 +1525,18 @@ public class RemoteDevices {
}
break;
}
- return (indicatorValue < 0 || indicatorValue > 9) ? BluetoothDevice.BATTERY_LEVEL_UNKNOWN
+ return (indicatorValue < 0 || indicatorValue > 9)
+ ? BluetoothDevice.BATTERY_LEVEL_UNKNOWN
: (indicatorValue + 1) * 10;
}
/**
- * Parse
- * AT+XEVENT=BATTERY,[Level],[NumberOfLevel],[MinutesOfTalk],[IsCharging]
- * vendor specific event
+ * Parse AT+XEVENT=BATTERY,[Level],[NumberOfLevel],[MinutesOfTalk],[IsCharging] vendor specific
+ * event
+ *
* @param args Array of arguments on the right side of SET command
* @return Battery level in percents, [0-100], {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
- * when there is an error parsing the arguments
+ * when there is an error parsing the arguments
*/
@VisibleForTesting
static int getBatteryLevelFromXEventVsc(Object[] args) {
@@ -1505,8 +1556,10 @@ public class RemoteDevices {
return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
}
if (args.length != 5) {
- Log.w(TAG, "getBatteryLevelFromXEventVsc() wrong battery level event length: "
- + String.valueOf(args.length));
+ Log.w(
+ TAG,
+ "getBatteryLevelFromXEventVsc() wrong battery level event length: "
+ + String.valueOf(args.length));
return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
}
if (!(args[1] instanceof Integer) || !(args[2] instanceof Integer)) {
@@ -1516,9 +1569,12 @@ public class RemoteDevices {
int batteryLevel = (Integer) args[1];
int numberOfLevels = (Integer) args[2];
if (batteryLevel < 0 || numberOfLevels <= 1 || batteryLevel > numberOfLevels) {
- Log.w(TAG, "getBatteryLevelFromXEventVsc() wrong event value, batteryLevel="
- + String.valueOf(batteryLevel) + ", numberOfLevels=" + String.valueOf(
- numberOfLevels));
+ Log.w(
+ TAG,
+ "getBatteryLevelFromXEventVsc() wrong event value, batteryLevel="
+ + String.valueOf(batteryLevel)
+ + ", numberOfLevels="
+ + String.valueOf(numberOfLevels));
return BluetoothDevice.BATTERY_LEVEL_UNKNOWN;
}
return batteryLevel * 100 / (numberOfLevels - 1);
@@ -1544,7 +1600,7 @@ public class RemoteDevices {
return;
}
if (toState == BluetoothProfile.STATE_DISCONNECTED && !hasBatteryService(device)) {
- resetBatteryLevel(device, /*isBas=*/ false);
+ resetBatteryLevel(device, /* isBas= */ false);
}
}
@@ -1560,7 +1616,7 @@ public class RemoteDevices {
return;
}
updateBatteryLevel(
- device, batteryChargeIndicatorToPercentge(batteryLevel), /*isBas=*/ false);
+ device, batteryChargeIndicatorToPercentge(batteryLevel), /* isBas= */ false);
}
private static void errorLog(String msg) {
@@ -1578,5 +1634,4 @@ public class RemoteDevices {
private static void warnLog(String msg) {
Log.w(TAG, msg);
}
-
}
diff --git a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
index 048dd3afc88e60dee8ef2dde97c9bdf2fa4b7041..3be3d98e91a0d6cca1dbed010f6c582f9c34dcae 100644
--- a/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/SilenceDeviceManager.java
@@ -43,16 +43,13 @@ import java.util.Map;
/**
* The silence device manager controls silence mode for A2DP, HFP, and AVRCP.
*
- * 1) If an active device (for A2DP or HFP) enters silence mode, the active device
- * for that profile will be set to null.
- * 2) If a device exits silence mode while the A2DP or HFP active device is null,
- * the device will be set as the active device for that profile.
- * 3) If a device is disconnected, it exits silence mode.
- * 4) If a device is set as the active device for A2DP or HFP, while silence mode
- * is enabled, then the device will exit silence mode.
- * 5) If a device is in silence mode, AVRCP position change event and HFP AG indicators
- * will be disabled.
- * 6) If a device is not connected with A2DP or HFP, it cannot enter silence mode.
+ * 1) If an active device (for A2DP or HFP) enters silence mode, the active device for that
+ * profile will be set to null. 2) If a device exits silence mode while the A2DP or HFP active
+ * device is null, the device will be set as the active device for that profile. 3) If a device is
+ * disconnected, it exits silence mode. 4) If a device is set as the active device for A2DP or HFP,
+ * while silence mode is enabled, then the device will exit silence mode. 5) If a device is in
+ * silence mode, AVRCP position change event and HFP AG indicators will be disabled. 6) If a device
+ * is not connected with A2DP or HFP, it cannot enter silence mode.
*/
public class SilenceDeviceManager {
private static final String TAG = SilenceDeviceManager.class.getSimpleName();
@@ -126,12 +123,13 @@ public class SilenceDeviceManager {
public void handleMessage(Message msg) {
Log.d(TAG, "handleMessage: " + msg.what);
switch (msg.what) {
- case MSG_SILENCE_DEVICE_STATE_CHANGED: {
- BluetoothDevice device = (BluetoothDevice) msg.obj;
- boolean state = (msg.arg1 == ENABLE_SILENCE);
- handleSilenceDeviceStateChanged(device, state);
- }
- break;
+ case MSG_SILENCE_DEVICE_STATE_CHANGED:
+ {
+ BluetoothDevice device = (BluetoothDevice) msg.obj;
+ boolean state = (msg.arg1 == ENABLE_SILENCE);
+ handleSilenceDeviceStateChanged(device, state);
+ }
+ break;
case MSG_A2DP_CONNECTION_STATE_CHANGED:
BluetoothDevice device = (BluetoothDevice) msg.obj;
@@ -221,8 +219,12 @@ public class SilenceDeviceManager {
return false;
}
Log.d(TAG, "setSilenceMode: " + device + ", " + silence);
- Message message = mHandler.obtainMessage(MSG_SILENCE_DEVICE_STATE_CHANGED,
- silence ? ENABLE_SILENCE : DISABLE_SILENCE, 0, device);
+ Message message =
+ mHandler.obtainMessage(
+ MSG_SILENCE_DEVICE_STATE_CHANGED,
+ silence ? ENABLE_SILENCE : DISABLE_SILENCE,
+ 0,
+ device);
mHandler.sendMessage(message);
return true;
}
@@ -252,8 +254,7 @@ public class SilenceDeviceManager {
if (headsetService != null) {
headsetService.setSilenceMode(device, state);
}
- Log.i(TAG, "Silence mode change " + device + ": " + oldState + " -> "
- + state);
+ Log.i(TAG, "Silence mode change " + device + ": " + oldState + " -> " + state);
broadcastSilenceStateChange(device, state);
}
@@ -277,8 +278,12 @@ public class SilenceDeviceManager {
}
void addConnectedDevice(BluetoothDevice device, int profile) {
- Log.d(TAG, "addConnectedDevice: " + device + ", profile:"
- + BluetoothProfile.getProfileName(profile));
+ Log.d(
+ TAG,
+ "addConnectedDevice: "
+ + device
+ + ", profile:"
+ + BluetoothProfile.getProfileName(profile));
switch (profile) {
case BluetoothProfile.A2DP:
if (!mA2dpConnectedDevices.contains(device)) {
@@ -294,8 +299,12 @@ public class SilenceDeviceManager {
}
void removeConnectedDevice(BluetoothDevice device, int profile) {
- Log.d(TAG, "removeConnectedDevice: " + device + ", profile:"
- + BluetoothProfile.getProfileName(profile));
+ Log.d(
+ TAG,
+ "removeConnectedDevice: "
+ + device
+ + ", profile:"
+ + BluetoothProfile.getProfileName(profile));
switch (profile) {
case BluetoothProfile.A2DP:
if (mA2dpConnectedDevices.contains(device)) {
@@ -318,7 +327,7 @@ public class SilenceDeviceManager {
writer.println("\nSilenceDeviceManager:");
writer.println(" Address | Is silenced?");
for (BluetoothDevice device : mSilenceDevices.keySet()) {
- writer.println(" " + device+ " | " + getSilenceMode(device));
+ writer.println(" " + device + " | " + getSilenceMode(device));
}
}
}
diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
index d87fca88298c43447a9ab63ab2f61a454ca214ce..073aa34302513564e0bb5cca546b3283cefd0fc6 100644
--- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
+++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreNativeInterface.java
@@ -65,9 +65,7 @@ public class BluetoothKeystoreNativeInterface {
initNative();
}
- /**
- * Cleanup the native interface.
- */
+ /** Cleanup the native interface. */
public void cleanup() {
cleanupNative();
mBluetoothKeystoreService = null;
@@ -112,5 +110,6 @@ public class BluetoothKeystoreNativeInterface {
// Native methods that call into the JNI interface
private native void initNative();
+
private native void cleanupNative();
}
diff --git a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
index d9b30db70b6d1a48a0a780957169216c76d66144..0c61375c9112fe3865973a996c244e842196b195 100644
--- a/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
+++ b/android/app/src/com/android/bluetooth/btservice/bluetoothKeystore/BluetoothKeystoreService.java
@@ -57,9 +57,7 @@ import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
-/**
- * Service used for handling encryption and decryption of the bt_config.conf
- */
+/** Service used for handling encryption and decryption of the bt_config.conf */
public class BluetoothKeystoreService {
private static final String TAG = BluetoothKeystoreService.class.getSimpleName();
@@ -103,8 +101,15 @@ public class BluetoothKeystoreService {
private Map mNameDecryptKey = new HashMap<>();
private BlockingQueue mPendingDecryptKey = new LinkedBlockingQueue<>();
private BlockingQueue mPendingEncryptKey = new LinkedBlockingQueue<>();
- private final List mEncryptKeyNameList = List.of("LinkKey", "LE_KEY_PENC", "LE_KEY_PID",
- "LE_KEY_LID", "LE_KEY_PCSRK", "LE_KEY_LENC", "LE_KEY_LCSRK");
+ private final List mEncryptKeyNameList =
+ List.of(
+ "LinkKey",
+ "LE_KEY_PENC",
+ "LE_KEY_PID",
+ "LE_KEY_LID",
+ "LE_KEY_PCSRK",
+ "LE_KEY_LENC",
+ "LE_KEY_LCSRK");
private Base64.Decoder mDecoder = Base64.getDecoder();
private Base64.Encoder mEncoder = Base64.getEncoder();
@@ -118,9 +123,7 @@ public class BluetoothKeystoreService {
startThread();
}
- /**
- * Start and initialize the BluetoothKeystoreService
- */
+ /** Start and initialize the BluetoothKeystoreService */
public void start() {
debugLog("start");
KeyStore keyStore;
@@ -152,9 +155,7 @@ public class BluetoothKeystoreService {
loadConfigData();
}
- /**
- * Factory reset the keystore service.
- */
+ /** Factory reset the keystore service. */
public void factoryReset() {
try {
cleanupAll();
@@ -163,9 +164,7 @@ public class BluetoothKeystoreService {
}
}
- /**
- * Cleans up the keystore service.
- */
+ /** Cleans up the keystore service. */
public void cleanup() {
debugLog("cleanup");
@@ -184,9 +183,7 @@ public class BluetoothKeystoreService {
}
}
- /**
- * Clean up if Common Criteria mode is enabled.
- */
+ /** Clean up if Common Criteria mode is enabled. */
@VisibleForTesting
public void cleanupForCommonCriteriaModeEnable() {
try {
@@ -202,18 +199,14 @@ public class BluetoothKeystoreService {
stopThread();
}
- /**
- * Clean up if Common Criteria mode is disabled.
- */
+ /** Clean up if Common Criteria mode is disabled. */
@VisibleForTesting
public void cleanupForCommonCriteriaModeDisable() {
mNameDecryptKey.clear();
mNameEncryptKey.clear();
}
- /**
- * Load decryption data from file.
- */
+ /** Load decryption data from file. */
@VisibleForTesting
public void loadConfigData() {
try {
@@ -270,9 +263,7 @@ public class BluetoothKeystoreService {
return SystemProperties.getBoolean("persist.bluetooth.factoryreset", false);
}
- /**
- * Init JNI
- */
+ /** Init JNI */
public void initJni() {
debugLog("initJni()");
// Need to make sure all keys are decrypted.
@@ -282,9 +273,7 @@ public class BluetoothKeystoreService {
mBluetoothKeystoreNativeInterface.init(this);
}
- /**
- * Gets result of the checksum comparison
- */
+ /** Gets result of the checksum comparison */
public int getCompareResult() {
debugLog("getCompareResult: " + mCompareResult);
return mCompareResult;
@@ -293,9 +282,9 @@ public class BluetoothKeystoreService {
/**
* Sets or removes the encryption key value.
*
- * If the value of decryptedString matches {@link #CONFIG_FILE_HASH} then
- * read the hash file and decrypt the keys and place them into {@link mPendingEncryptKey}
- * otherwise cleanup all data and remove the keys.
+ *
If the value of decryptedString matches {@link #CONFIG_FILE_HASH} then read the hash file
+ * and decrypt the keys and place them into {@link mPendingEncryptKey} otherwise cleanup all
+ * data and remove the keys.
*
* @param prefixString key to use
* @param decryptedString string to decrypt
@@ -329,9 +318,7 @@ public class BluetoothKeystoreService {
}
}
- /**
- * Clean up memory and all files.
- */
+ /** Clean up memory and all files. */
@VisibleForTesting
public void cleanupAll() throws IOException {
cleanupFile();
@@ -344,9 +331,7 @@ public class BluetoothKeystoreService {
Files.deleteIfExists(Paths.get(CONFIG_BACKUP_ENCRYPTION_PATH));
}
- /**
- * Clean up memory.
- */
+ /** Clean up memory. */
@VisibleForTesting
public void cleanupMemory() {
stopThread();
@@ -355,9 +340,7 @@ public class BluetoothKeystoreService {
startThread();
}
- /**
- * Stop encrypt/decrypt thread.
- */
+ /** Stop encrypt/decrypt thread. */
@VisibleForTesting
public void stopThread() {
try {
@@ -381,9 +364,7 @@ public class BluetoothKeystoreService {
mDecryptDataThread.start();
}
- /**
- * Get key value from the mNameDecryptKey.
- */
+ /** Get key value from the mNameDecryptKey. */
public String getKey(String prefixString) {
infoLog("getKey: prefix: " + prefixString);
if (!mNameDecryptKey.containsKey(prefixString)) {
@@ -393,9 +374,7 @@ public class BluetoothKeystoreService {
return mNameDecryptKey.get(prefixString);
}
- /**
- * Save encryption key into the encryption file.
- */
+ /** Save encryption key into the encryption file. */
@VisibleForTesting
public void saveEncryptedKey() {
stopThread();
@@ -450,9 +429,7 @@ public class BluetoothKeystoreService {
return (mCompareResult & item) == item;
}
- /**
- * Compare config file checksum.
- */
+ /** Compare config file checksum. */
@VisibleForTesting
public boolean compareFileHash(String hashFilePathString)
throws InterruptedException, IOException, NoSuchAlgorithmException {
@@ -475,8 +452,9 @@ public class BluetoothKeystoreService {
readHashFile(hashFilePathString, prefixString);
if (!mNameEncryptKey.containsKey(prefixString)) {
- errorLog("compareFileHash: NameEncryptKey doesn't contain the key, prefix:"
- + prefixString);
+ errorLog(
+ "compareFileHash: NameEncryptKey doesn't contain the key, prefix:"
+ + prefixString);
return false;
}
String encryptedData = mNameEncryptKey.get(prefixString);
@@ -492,7 +470,7 @@ public class BluetoothKeystoreService {
private void readHashFile(String filePathString, String prefixString)
throws InterruptedException, NoSuchAlgorithmException {
byte[] dataBuffer = new byte[BUFFER_SIZE];
- int bytesRead = 0;
+ int bytesRead = 0;
boolean successful = false;
int counter = 0;
while (!successful && counter < TRY_MAX) {
@@ -506,8 +484,9 @@ public class BluetoothKeystoreService {
byte[] messageDigestBytes = messageDigest.digest();
StringBuilder hashString = new StringBuilder();
for (int index = 0; index < messageDigestBytes.length; index++) {
- hashString.append(Integer.toString((
- messageDigestBytes[index] & 0xff) + 0x100, 16).substring(1));
+ hashString.append(
+ Integer.toString((messageDigestBytes[index] & 0xff) + 0x100, 16)
+ .substring(1));
}
mNameDecryptKey.put(prefixString, hashString.toString());
@@ -523,12 +502,9 @@ public class BluetoothKeystoreService {
}
}
- /**
- * Parses a file to search for the key and put it into the pending compute queue
- */
+ /** Parses a file to search for the key and put it into the pending compute queue */
@VisibleForTesting
- public void parseConfigFile(String filePathString)
- throws IOException, InterruptedException {
+ public void parseConfigFile(String filePathString) throws IOException, InterruptedException {
String prefixString = null;
String dataString = null;
String name = null;
@@ -570,9 +546,7 @@ public class BluetoothKeystoreService {
}
}
- /**
- * Load encryption file and push into mNameEncryptKey and pendingDecryptKey.
- */
+ /** Load encryption file and push into mNameEncryptKey and pendingDecryptKey. */
@VisibleForTesting
public void loadEncryptionFile(String filePathString, boolean doDecrypt)
throws InterruptedException {
@@ -640,9 +614,12 @@ public class BluetoothKeystoreService {
if (secretKeyReference != null) {
cipher.init(Cipher.ENCRYPT_MODE, secretKeyReference);
- protobuf = BluetoothKeystoreProto.EncryptedData.newBuilder()
- .setEncryptedData(ByteString.copyFrom(cipher.doFinal(data.getBytes())))
- .setInitVector(ByteString.copyFrom(cipher.getIV())).build();
+ protobuf =
+ BluetoothKeystoreProto.EncryptedData.newBuilder()
+ .setEncryptedData(
+ ByteString.copyFrom(cipher.doFinal(data.getBytes())))
+ .setInitVector(ByteString.copyFrom(cipher.getIV()))
+ .build();
outputBytes = protobuf.toByteArray();
if (outputBytes == null) {
@@ -701,8 +678,8 @@ public class BluetoothKeystoreService {
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
reportBluetoothKeystoreException(e, "decrypt: Failed to parse EncryptedData protobuf.");
} catch (NoSuchAlgorithmException e) {
- reportKeystoreException(e,
- "decrypt could not find cipher algorithm " + CIPHER_ALGORITHM);
+ reportKeystoreException(
+ e, "decrypt could not find cipher algorithm " + CIPHER_ALGORITHM);
} catch (NoSuchPaddingException e) {
reportKeystoreException(e, "decrypt could not find padding algorithm");
} catch (IllegalBlockSizeException e) {
@@ -725,7 +702,9 @@ public class BluetoothKeystoreService {
try {
keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
- } catch (KeyStoreException | CertificateException | NoSuchAlgorithmException
+ } catch (KeyStoreException
+ | CertificateException
+ | NoSuchAlgorithmException
| IOException e) {
reportKeystoreException(e, "cannot open keystore");
}
@@ -740,8 +719,8 @@ public class BluetoothKeystoreService {
try {
KeyStore keyStore = getKeyStore();
if (keyStore.containsAlias(KEYALIAS)) { // The key exists in key store. Get the key.
- KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore
- .getEntry(KEYALIAS, null);
+ KeyStore.SecretKeyEntry secretKeyEntry =
+ (KeyStore.SecretKeyEntry) keyStore.getEntry(KEYALIAS, null);
if (secretKeyEntry != null) {
secretKey = secretKeyEntry.getSecretKey();
@@ -750,15 +729,18 @@ public class BluetoothKeystoreService {
}
} else {
// The key does not exist in key store. Create the key and store it.
- KeyGenerator keyGenerator = KeyGenerator
- .getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE);
-
- KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(KEYALIAS,
- KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
- .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
- .setKeySize(KEY_LENGTH)
- .build();
+ KeyGenerator keyGenerator =
+ KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, KEY_STORE);
+
+ KeyGenParameterSpec keyGenParameterSpec =
+ new KeyGenParameterSpec.Builder(
+ KEYALIAS,
+ KeyProperties.PURPOSE_ENCRYPT
+ | KeyProperties.PURPOSE_DECRYPT)
+ .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setKeySize(KEY_LENGTH)
+ .build();
keyGenerator.init(keyGenParameterSpec);
secretKey = keyGenerator.generateKey();
@@ -772,8 +754,8 @@ public class BluetoothKeystoreService {
} catch (NoSuchProviderException e) {
reportKeystoreException(e, "getOrCreateSecretKey cannot find crypto provider");
} catch (UnrecoverableEntryException e) {
- reportKeystoreException(e,
- "getOrCreateSecretKey had an unrecoverable entry exception.");
+ reportKeystoreException(
+ e, "getOrCreateSecretKey had an unrecoverable entry exception.");
} catch (ProviderException e) {
reportKeystoreException(e, "getOrCreateSecretKey had a provider exception.");
}
@@ -800,9 +782,7 @@ public class BluetoothKeystoreService {
Log.e(TAG, msg);
}
- /**
- * A thread that decrypt data if the queue has new decrypt task.
- */
+ /** A thread that decrypt data if the queue has new decrypt task. */
private class ComputeDataThread extends Thread {
private Map mSourceDataMap;
private Map mTargetDataMap;
@@ -842,8 +822,11 @@ public class BluetoothKeystoreService {
if (targetData != null) {
mTargetDataMap.put(prefixString, targetData);
} else {
- errorLog("Computing of Data failed with prefixString: " + prefixString
- + ", doEncrypt: " + mDoEncrypt);
+ errorLog(
+ "Computing of Data failed with prefixString: "
+ + prefixString
+ + ", doEncrypt: "
+ + mDoEncrypt);
}
}
} catch (InterruptedException e) {
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
index 024fe1a5292fabe46d33886e6e5a13fc41695d67..b790e92c737e7d2c1a06e057d25e1aad2a7f85ee 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/AudioPolicyEntity.java
@@ -25,8 +25,10 @@ import androidx.room.Entity;
class AudioPolicyEntity {
@ColumnInfo(name = "call_establish_audio_policy")
public int callEstablishAudioPolicy;
+
@ColumnInfo(name = "connecting_time_audio_policy")
public int connectingTimeAudioPolicy;
+
@ColumnInfo(name = "in_band_ringtone_audio_policy")
public int inBandRingtoneAudioPolicy;
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
index 736a2e1caea3b84975c22bd468304545eecce19b..9743bba805f4b6a5dec20f3056f0828e3e50bdcc 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/BluetoothDatabaseMigration.java
@@ -29,11 +29,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-/**
- * Class for regrouping the migration that occur when going mainline
- */
+/** Class for regrouping the migration that occur when going mainline */
public final class BluetoothDatabaseMigration {
private static final String TAG = "BluetoothDatabaseMigration";
+
public static boolean run(Context ctx, Cursor cursor) {
boolean result = true;
MetadataDatabase database = MetadataDatabase.createDatabaseWithoutMigration(ctx);
@@ -67,82 +66,100 @@ public final class BluetoothDatabaseMigration {
private static final List> CONNECTION_POLICIES =
Arrays.asList(
- new Pair(BluetoothProfile.A2DP, "a2dp_connection_policy"),
- new Pair(BluetoothProfile.A2DP_SINK, "a2dp_sink_connection_policy"),
- new Pair(BluetoothProfile.HEADSET, "hfp_connection_policy"),
- new Pair(BluetoothProfile.HEADSET_CLIENT, "hfp_client_connection_policy"),
- new Pair(BluetoothProfile.HID_HOST, "hid_host_connection_policy"),
- new Pair(BluetoothProfile.PAN, "pan_connection_policy"),
- new Pair(BluetoothProfile.PBAP, "pbap_connection_policy"),
- new Pair(BluetoothProfile.PBAP_CLIENT, "pbap_client_connection_policy"),
- new Pair(BluetoothProfile.MAP, "map_connection_policy"),
- new Pair(BluetoothProfile.SAP, "sap_connection_policy"),
- new Pair(BluetoothProfile.HEARING_AID, "hearing_aid_connection_policy"),
- new Pair(BluetoothProfile.HAP_CLIENT, "hap_client_connection_policy"),
- new Pair(BluetoothProfile.MAP_CLIENT, "map_client_connection_policy"),
- new Pair(BluetoothProfile.LE_AUDIO, "le_audio_connection_policy"),
- new Pair(BluetoothProfile.VOLUME_CONTROL, "volume_control_connection_policy"),
- new Pair(BluetoothProfile.CSIP_SET_COORDINATOR,
- "csip_set_coordinator_connection_policy"),
- new Pair(BluetoothProfile.LE_CALL_CONTROL, "le_call_control_connection_policy"),
- new Pair(BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
- "bass_client_connection_policy"),
- new Pair(BluetoothProfile.BATTERY, "battery_connection_policy")
- );
+ new Pair(BluetoothProfile.A2DP, "a2dp_connection_policy"),
+ new Pair(BluetoothProfile.A2DP_SINK, "a2dp_sink_connection_policy"),
+ new Pair(BluetoothProfile.HEADSET, "hfp_connection_policy"),
+ new Pair(BluetoothProfile.HEADSET_CLIENT, "hfp_client_connection_policy"),
+ new Pair(BluetoothProfile.HID_HOST, "hid_host_connection_policy"),
+ new Pair(BluetoothProfile.PAN, "pan_connection_policy"),
+ new Pair(BluetoothProfile.PBAP, "pbap_connection_policy"),
+ new Pair(BluetoothProfile.PBAP_CLIENT, "pbap_client_connection_policy"),
+ new Pair(BluetoothProfile.MAP, "map_connection_policy"),
+ new Pair(BluetoothProfile.SAP, "sap_connection_policy"),
+ new Pair(BluetoothProfile.HEARING_AID, "hearing_aid_connection_policy"),
+ new Pair(BluetoothProfile.HAP_CLIENT, "hap_client_connection_policy"),
+ new Pair(BluetoothProfile.MAP_CLIENT, "map_client_connection_policy"),
+ new Pair(BluetoothProfile.LE_AUDIO, "le_audio_connection_policy"),
+ new Pair(BluetoothProfile.VOLUME_CONTROL, "volume_control_connection_policy"),
+ new Pair(
+ BluetoothProfile.CSIP_SET_COORDINATOR,
+ "csip_set_coordinator_connection_policy"),
+ new Pair(BluetoothProfile.LE_CALL_CONTROL, "le_call_control_connection_policy"),
+ new Pair(
+ BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT,
+ "bass_client_connection_policy"),
+ new Pair(BluetoothProfile.BATTERY, "battery_connection_policy"));
private static final List> CUSTOMIZED_META_KEYS =
Arrays.asList(
- new Pair(BluetoothDevice.METADATA_MANUFACTURER_NAME, "manufacturer_name"),
- new Pair(BluetoothDevice.METADATA_MODEL_NAME, "model_name"),
- new Pair(BluetoothDevice.METADATA_SOFTWARE_VERSION, "software_version"),
- new Pair(BluetoothDevice.METADATA_HARDWARE_VERSION, "hardware_version"),
- new Pair(BluetoothDevice.METADATA_COMPANION_APP, "companion_app"),
- new Pair(BluetoothDevice.METADATA_MAIN_ICON, "main_icon"),
- new Pair(BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET, "is_untethered_headset"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, "untethered_left_icon"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON, "untethered_right_icon"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, "untethered_case_icon"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
- "untethered_left_battery"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY,
- "untethered_right_battery"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY,
- "untethered_case_battery"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING,
- "untethered_left_charging"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING,
- "untethered_right_charging"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING,
- "untethered_case_charging"),
- new Pair(BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI,
- "enhanced_settings_ui_uri"),
- new Pair(BluetoothDevice.METADATA_DEVICE_TYPE, "device_type"),
- new Pair(BluetoothDevice.METADATA_MAIN_BATTERY, "main_battery"),
- new Pair(BluetoothDevice.METADATA_MAIN_CHARGING, "main_charging"),
- new Pair(BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD,
- "main_low_battery_threshold"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
- "untethered_left_low_battery_threshold"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
- "untethered_right_low_battery_threshold"),
- new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
- "untethered_case_low_battery_threshold"),
- new Pair(BluetoothDevice.METADATA_SPATIAL_AUDIO, "spatial_audio"),
- new Pair(BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS,
- "fastpair_customized")
- );
+ new Pair(BluetoothDevice.METADATA_MANUFACTURER_NAME, "manufacturer_name"),
+ new Pair(BluetoothDevice.METADATA_MODEL_NAME, "model_name"),
+ new Pair(BluetoothDevice.METADATA_SOFTWARE_VERSION, "software_version"),
+ new Pair(BluetoothDevice.METADATA_HARDWARE_VERSION, "hardware_version"),
+ new Pair(BluetoothDevice.METADATA_COMPANION_APP, "companion_app"),
+ new Pair(BluetoothDevice.METADATA_MAIN_ICON, "main_icon"),
+ new Pair(
+ BluetoothDevice.METADATA_IS_UNTETHERED_HEADSET,
+ "is_untethered_headset"),
+ new Pair(BluetoothDevice.METADATA_UNTETHERED_LEFT_ICON, "untethered_left_icon"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_ICON,
+ "untethered_right_icon"),
+ new Pair(BluetoothDevice.METADATA_UNTETHERED_CASE_ICON, "untethered_case_icon"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_BATTERY,
+ "untethered_left_battery"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_BATTERY,
+ "untethered_right_battery"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_CASE_BATTERY,
+ "untethered_case_battery"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_CHARGING,
+ "untethered_left_charging"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_CHARGING,
+ "untethered_right_charging"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_CASE_CHARGING,
+ "untethered_case_charging"),
+ new Pair(
+ BluetoothDevice.METADATA_ENHANCED_SETTINGS_UI_URI,
+ "enhanced_settings_ui_uri"),
+ new Pair(BluetoothDevice.METADATA_DEVICE_TYPE, "device_type"),
+ new Pair(BluetoothDevice.METADATA_MAIN_BATTERY, "main_battery"),
+ new Pair(BluetoothDevice.METADATA_MAIN_CHARGING, "main_charging"),
+ new Pair(
+ BluetoothDevice.METADATA_MAIN_LOW_BATTERY_THRESHOLD,
+ "main_low_battery_threshold"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_LEFT_LOW_BATTERY_THRESHOLD,
+ "untethered_left_low_battery_threshold"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_RIGHT_LOW_BATTERY_THRESHOLD,
+ "untethered_right_low_battery_threshold"),
+ new Pair(
+ BluetoothDevice.METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD,
+ "untethered_case_low_battery_threshold"),
+ new Pair(BluetoothDevice.METADATA_SPATIAL_AUDIO, "spatial_audio"),
+ new Pair(
+ BluetoothDevice.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS,
+ "fastpair_customized"));
private static int fetchInt(Cursor cursor, String key) {
return cursor.getInt(cursor.getColumnIndexOrThrow(key));
}
- private static void migrate_a2dpSupportsOptionalCodecs(Cursor cursor, String logKey,
- Metadata metadata) {
+ private static void migrate_a2dpSupportsOptionalCodecs(
+ Cursor cursor, String logKey, Metadata metadata) {
final String key = "a2dpSupportsOptionalCodecs";
- final List allowedValue = new ArrayList<>(Arrays.asList(
- BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN,
- BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED,
- BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED));
+ final List allowedValue =
+ new ArrayList<>(
+ Arrays.asList(
+ BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN,
+ BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED,
+ BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED));
final int value = fetchInt(cursor, key);
if (!allowedValue.contains(value)) {
throw new IllegalArgumentException(logKey + ": Bad value for [" + key + "]: " + value);
@@ -150,13 +167,15 @@ public final class BluetoothDatabaseMigration {
metadata.a2dpSupportsOptionalCodecs = value;
}
- private static void migrate_a2dpOptionalCodecsEnabled(Cursor cursor, String logKey,
- Metadata metadata) {
+ private static void migrate_a2dpOptionalCodecsEnabled(
+ Cursor cursor, String logKey, Metadata metadata) {
final String key = "a2dpOptionalCodecsEnabled";
- final List allowedValue = new ArrayList<>(Arrays.asList(
- BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
- BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
- BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED));
+ final List allowedValue =
+ new ArrayList<>(
+ Arrays.asList(
+ BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
+ BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
+ BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED));
final int value = fetchInt(cursor, key);
if (!allowedValue.contains(value)) {
throw new IllegalArgumentException(logKey + ": Bad value for [" + key + "]: " + value);
@@ -164,20 +183,24 @@ public final class BluetoothDatabaseMigration {
metadata.a2dpOptionalCodecsEnabled = value;
}
- private static void migrate_connectionPolicy(Cursor cursor, String logKey,
- Metadata metadata) {
- final List allowedValue = new ArrayList<>(Arrays.asList(
- BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
- BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
- BluetoothProfile.CONNECTION_POLICY_ALLOWED));
+ private static void migrate_connectionPolicy(Cursor cursor, String logKey, Metadata metadata) {
+ final List allowedValue =
+ new ArrayList<>(
+ Arrays.asList(
+ BluetoothProfile.CONNECTION_POLICY_UNKNOWN,
+ BluetoothProfile.CONNECTION_POLICY_FORBIDDEN,
+ BluetoothProfile.CONNECTION_POLICY_ALLOWED));
for (Pair p : CONNECTION_POLICIES) {
final int policy = cursor.getInt(cursor.getColumnIndexOrThrow(p.second));
if (allowedValue.contains(policy)) {
metadata.setProfileConnectionPolicy(p.first, policy);
} else {
- throw new IllegalArgumentException(logKey + ": Bad value for ["
- + BluetoothProfile.getProfileName(p.first)
- + "]: " + policy);
+ throw new IllegalArgumentException(
+ logKey
+ + ": Bad value for ["
+ + BluetoothProfile.getProfileName(p.first)
+ + "]: "
+ + policy);
}
}
}
@@ -189,5 +212,4 @@ public final class BluetoothDatabaseMigration {
metadata.setCustomizedMeta(p.first, blob);
}
}
-
}
diff --git a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
index dce3847dd5e6337c639a0677fd69edb54b7c507f..34ee90ee1cb144c0de1d4f85368ef8f8493565e4 100644
--- a/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
+++ b/android/app/src/com/android/bluetooth/btservice/storage/DatabaseManager.java
@@ -61,8 +61,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
- * The active device manager is responsible to handle a Room database
- * for Bluetooth persistent data.
+ * The active device manager is responsible to handle a Room database for Bluetooth persistent data.
*/
public class DatabaseManager {
private static final String TAG = "BluetoothDatabase";
@@ -74,8 +73,7 @@ public class DatabaseManager {
private @GuardedBy("mDatabaseLock") MetadataDatabase mDatabase = null;
private boolean mMigratedFromSettingsGlobal = false;
- @VisibleForTesting
- final Map mMetadataCache = new HashMap<>();
+ @VisibleForTesting final Map