/* * Copyright 2018 The Android Open Source Project * * 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. */ #pragma once #include #include #include #include #include "avrcp_common.h" #include "raw_address.h" namespace bluetooth { namespace avrcp { #if defined(MTK_AVRCP_APP_SETTINGS) && (MTK_AVRCP_APP_SETTINGS == TRUE) constexpr uint32_t BTRC_MAX_ATTR_STR_LEN = (1u << 16); constexpr uint8_t BTRC_MAX_APP_SETTINGS = 8; constexpr uint8_t BTRC_MAX_APP_ATTR_SIZE = 16; enum BtrcStatus : uint8_t { BTRC_STS_BAD_CMD = 0x00, /* Invalid command */ BTRC_STS_BAD_PARAM = 0x01, /* Invalid parameter */ BTRC_STS_NOT_FOUND = 0x02, /* Specified parameter is wrong or not found */ BTRC_STS_INTERNAL_ERR = 0x03, /* Internal Error */ BTRC_STS_NO_ERROR = 0x04, /* Operation Success */ BTRC_STS_UID_CHANGED = 0x05, /* UIDs changed */ BTRC_STS_RESERVED = 0x06, /* Reserved */ BTRC_STS_INV_DIRN = 0x07, /* Invalid direction */ BTRC_STS_INV_DIRECTORY = 0x08, /* Invalid directory */ BTRC_STS_INV_ITEM = 0x09, /* Invalid Item */ BTRC_STS_INV_SCOPE = 0x0a, /* Invalid scope */ BTRC_STS_INV_RANGE = 0x0b, /* Invalid range */ BTRC_STS_DIRECTORY = 0x0c, /* UID is a directory */ BTRC_STS_MEDIA_IN_USE = 0x0d, /* Media in use */ BTRC_STS_PLAY_LIST_FULL = 0x0e, /* Playing list full */ BTRC_STS_SRCH_NOT_SPRTD = 0x0f, /* Search not supported */ BTRC_STS_SRCH_IN_PROG = 0x10, /* Search in progress */ BTRC_STS_INV_PLAYER = 0x11, /* Invalid player */ BTRC_STS_PLAY_NOT_BROW = 0x12, /* Player not browsable */ BTRC_STS_PLAY_NOT_ADDR = 0x13, /* Player not addressed */ BTRC_STS_INV_RESULTS = 0x14, /* Invalid results */ BTRC_STS_NO_AVBL_PLAY = 0x15, /* No available players */ BTRC_STS_ADDR_PLAY_CHGD = 0x16, /* Addressed player changed */ }; enum BtrcPlayerAttr : uint8_t { BTRC_PLAYER_ATTR_EQUALIZER = 0x01, BTRC_PLAYER_ATTR_REPEAT = 0x02, BTRC_PLAYER_ATTR_SHUFFLE = 0x03, BTRC_PLAYER_ATTR_SCAN = 0x04, }; struct BtrcPlayerSettings { uint8_t num_attr; uint8_t attr_ids[BTRC_MAX_APP_SETTINGS]; uint8_t attr_values[BTRC_MAX_APP_SETTINGS]; }; struct BtrcPlayerSettingText { uint8_t id; /* can be attr_id or value_id */ uint8_t text[BTRC_MAX_ATTR_STR_LEN]; }; #endif struct SongInfo { std::string media_id; // This gets converted to a UID in the native service std::set attributes; }; enum PlayState : uint8_t { STOPPED = 0x00, PLAYING, PAUSED, FWD_SEEK, REV_SEEK, ERROR = 0xFF, }; struct PlayStatus { uint32_t position; uint32_t duration; PlayState state; }; struct MediaPlayerInfo { uint16_t id; std::string name; bool browsing_supported; }; struct FolderInfo { std::string media_id; bool is_playable; std::string name; }; // TODO (apanicke): Convert this to a union struct ListItem { enum : uint8_t { FOLDER, SONG, } type; FolderInfo folder; SongInfo song; }; class MediaCallbacks { public: virtual void SendMediaUpdate(bool track_changed, bool play_state, bool queue) = 0; virtual void SendFolderUpdate(bool available_players, bool addressed_players, bool uids_changed); virtual void SendActiveDeviceChanged(const RawAddress& address); #if defined(MTK_AVRCP_APP_SETTINGS) && (MTK_AVRCP_APP_SETTINGS == TRUE) virtual void SendAppSettingUpdate(bool setting_changed); #endif virtual ~MediaCallbacks() = default; }; // The classes below are used by the JNI and are loaded dynamically with the // Bluetooth library. All classes must be pure virtual otherwise a compiler // error occurs when trying to link the function implementation. // MediaInterface defines the class that the AVRCP Service uses in order // communicate with the media layer. The media layer will define its own // implementation of this object and register it with the service using // Avrcp::ServiceInterface::Init(). At this point the AVRCP Service will // call RegisterUpdateCallbacks() to provide an handle to use to send // notifications about changes in the Media Interface. // // NOTES: The current implementation has the native service handle all the // thread switching. It will call the interface functions on the btif/jni // thread and the callback will post its results to the bta thread. // In the future the interface the JNI registered with the // service should post all its tasks to the JNI thread itself so that the native // service isn't aware of the thread the interface functions need to be called // on. It can then supply callbacks that post results to the correct thread // allowing the threading model to be totally encapsulated and allow correct // behavior in case the threading model changes on either side. class MediaInterface { public: virtual void SendKeyEvent(uint8_t key, KeyState state) = 0; using SongInfoCallback = base::Callback; virtual void GetSongInfo(SongInfoCallback info_cb) = 0; using PlayStatusCallback = base::Callback; virtual void GetPlayStatus(PlayStatusCallback status_cb) = 0; // Contains the current queue and the media ID of the currently playing item // in the queue using NowPlayingCallback = base::Callback)>; virtual void GetNowPlayingList(NowPlayingCallback now_playing_cb) = 0; // TODO (apanicke): Use a map with the ID as the key instead of vector // in follow up cleanup patches. This allows simplification of the // MediaPlayerInfo object using MediaListCallback = base::Callback)>; virtual void GetMediaPlayerList(MediaListCallback list_cb) = 0; using FolderItemsCallback = base::Callback)>; virtual void GetFolderItems(uint16_t player_id, std::string media_id, FolderItemsCallback folder_cb) = 0; using SetBrowsedPlayerCallback = base::Callback; virtual void SetBrowsedPlayer(uint16_t player_id, SetBrowsedPlayerCallback browse_cb) = 0; virtual void PlayItem(uint16_t player_id, bool now_playing, std::string media_id) = 0; virtual void SetActiveDevice(const RawAddress& address) = 0; virtual void RegisterUpdateCallback(MediaCallbacks* callback) = 0; virtual void UnregisterUpdateCallback(MediaCallbacks* callback) = 0; #if defined(MTK_AVRCP_APP_SETTINGS) && (MTK_AVRCP_APP_SETTINGS == TRUE) using GetSettingChangeCallback = base::Callback; virtual void GetAppSettingChange(GetSettingChangeCallback get_values_cb) = 0; using ListAttributesCallback = base::Callback)>; virtual void ListAppSettingAttrs( ListAttributesCallback list_attributes_cb) = 0; using ListValuesCallback = base::Callback)>; virtual void ListAppSettingValues(uint8_t attr_id, ListValuesCallback list_values_cb) = 0; using GetValuesCallback = base::Callback; virtual void GetAppSettingValues(std::vector, GetValuesCallback get_values_cb) = 0; using SetValuesCallback = base::Callback; virtual void SetAppSettingValues(BtrcPlayerSettings p_vals, SetValuesCallback set_values_cb) = 0; using GetAttrsTxtCallback = base::Callback)>; virtual void GetAppSettingAttrsText(std::vector, GetAttrsTxtCallback get_attrs_txt_cb) = 0; using GetValuesTxtCallback = base::Callback)>; virtual void GetAppSettingValuesText(uint8_t attr_id, std::vector, GetValuesTxtCallback get_vals_txt_cb) = 0; #endif MediaInterface() = default; virtual ~MediaInterface() = default; }; class VolumeInterface { public: // TODO (apanicke): Investigate the best value type for volume. Right now it // is a value from 0-127 because thats what AVRCP uses. using VolumeChangedCb = base::Callback; // Indicate that a device has been connected that does not support absolute // volume. virtual void DeviceConnected(const RawAddress& bdaddr) = 0; // Indicate that a device has been connected that does support absolute // volume. The callback will be immediately called with the current volume // which will be sent to the device. virtual void DeviceConnected(const RawAddress& bdaddr, VolumeChangedCb cb) = 0; // Indicate that a device has been disconnected from AVRCP. Will unregister // any callbacks if absolute volume is supported. virtual void DeviceDisconnected(const RawAddress& bdaddr) = 0; virtual void SetVolume(int8_t volume) = 0; virtual ~VolumeInterface() = default; }; class ServiceInterface { public: // mediaInterface can not be null. If volumeInterface is null then Absolute // Volume is disabled. virtual void Init(MediaInterface* mediaInterface, VolumeInterface* volumeInterface) = 0; virtual void RegisterBipServer(int psm) = 0; virtual void UnregisterBipServer() = 0; virtual bool ConnectDevice(const RawAddress& bdaddr) = 0; virtual bool DisconnectDevice(const RawAddress& bdaddr) = 0; virtual void SetBipClientStatus(const RawAddress& bdaddr, bool connected) = 0; virtual bool Cleanup() = 0; protected: virtual ~ServiceInterface() = default; }; } // namespace avrcp } // namespace bluetooth