1 /* 2 * Copyright 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <set> 20 #include <string> 21 22 #include <base/callback_forward.h> 23 24 #include "avrcp_common.h" 25 #include "raw_address.h" 26 27 namespace bluetooth { 28 namespace avrcp { 29 30 struct SongInfo { 31 std::string media_id; // This gets converted to a UID in the native service 32 std::set<AttributeEntry> attributes; 33 }; 34 35 enum PlayState : uint8_t { 36 STOPPED = 0x00, 37 PLAYING, 38 PAUSED, 39 FWD_SEEK, 40 REV_SEEK, 41 ERROR = 0xFF, 42 }; 43 44 struct PlayStatus { 45 uint32_t position; 46 uint32_t duration; 47 PlayState state; 48 }; 49 50 struct MediaPlayerInfo { 51 uint16_t id; 52 std::string name; 53 bool browsing_supported; 54 }; 55 56 struct FolderInfo { 57 std::string media_id; 58 bool is_playable; 59 std::string name; 60 }; 61 62 // TODO (apanicke): Convert this to a union 63 struct ListItem { 64 enum : uint8_t { 65 FOLDER, 66 SONG, 67 } type; 68 69 FolderInfo folder; 70 SongInfo song; 71 }; 72 73 class MediaCallbacks { 74 public: 75 virtual void SendMediaUpdate(bool track_changed, bool play_state, 76 bool queue) = 0; 77 virtual void SendFolderUpdate(bool available_players, bool addressed_players, 78 bool uids_changed) = 0; 79 virtual void SendActiveDeviceChanged(const RawAddress& address) = 0; 80 virtual ~MediaCallbacks() = default; 81 }; 82 83 // The classes below are used by the JNI and are loaded dynamically with the 84 // Bluetooth library. All classes must be pure virtual otherwise a compiler 85 // error occurs when trying to link the function implementation. 86 87 // MediaInterface defines the class that the AVRCP Service uses in order 88 // communicate with the media layer. The media layer will define its own 89 // implementation of this object and register it with the service using 90 // Avrcp::ServiceInterface::Init(). At this point the AVRCP Service will 91 // call RegisterUpdateCallbacks() to provide an handle to use to send 92 // notifications about changes in the Media Interface. 93 // 94 // NOTES: The current implementation has the native service handle all the 95 // thread switching. It will call the interface functions on the btif/jni 96 // thread and the callback will post its results to the bta thread. 97 // In the future the interface the JNI registered with the 98 // service should post all its tasks to the JNI thread itself so that the native 99 // service isn't aware of the thread the interface functions need to be called 100 // on. It can then supply callbacks that post results to the correct thread 101 // allowing the threading model to be totally encapsulated and allow correct 102 // behavior in case the threading model changes on either side. 103 class MediaInterface { 104 public: 105 virtual void SendKeyEvent(uint8_t key, KeyState state) = 0; 106 107 using SongInfoCallback = base::Callback<void(SongInfo)>; 108 virtual void GetSongInfo(SongInfoCallback info_cb) = 0; 109 110 using PlayStatusCallback = base::Callback<void(PlayStatus)>; 111 virtual void GetPlayStatus(PlayStatusCallback status_cb) = 0; 112 113 // Contains the current queue and the media ID of the currently playing item 114 // in the queue 115 using NowPlayingCallback = 116 base::Callback<void(std::string, std::vector<SongInfo>)>; 117 virtual void GetNowPlayingList(NowPlayingCallback now_playing_cb) = 0; 118 119 // TODO (apanicke): Use a map with the ID as the key instead of vector 120 // in follow up cleanup patches. This allows simplification of the 121 // MediaPlayerInfo object 122 using MediaListCallback = 123 base::Callback<void(uint16_t curr_player, std::vector<MediaPlayerInfo>)>; 124 virtual void GetMediaPlayerList(MediaListCallback list_cb) = 0; 125 126 using FolderItemsCallback = base::Callback<void(std::vector<ListItem>)>; 127 virtual void GetFolderItems(uint16_t player_id, std::string media_id, 128 FolderItemsCallback folder_cb) = 0; 129 130 using SetBrowsedPlayerCallback = base::Callback<void( 131 bool success, std::string root_id, uint32_t num_items)>; 132 virtual void SetBrowsedPlayer(uint16_t player_id, 133 SetBrowsedPlayerCallback browse_cb) = 0; 134 135 virtual void PlayItem(uint16_t player_id, bool now_playing, 136 std::string media_id) = 0; 137 138 virtual void SetActiveDevice(const RawAddress& address) = 0; 139 140 virtual void RegisterUpdateCallback(MediaCallbacks* callback) = 0; 141 142 virtual void UnregisterUpdateCallback(MediaCallbacks* callback) = 0; 143 144 MediaInterface() = default; 145 virtual ~MediaInterface() = default; 146 }; 147 148 class VolumeInterface { 149 public: 150 // TODO (apanicke): Investigate the best value type for volume. Right now it 151 // is a value from 0-127 because thats what AVRCP uses. 152 using VolumeChangedCb = base::Callback<void(int8_t volume)>; 153 154 // Indicate that a device has been connected that does not support absolute 155 // volume. 156 virtual void DeviceConnected(const RawAddress& bdaddr) = 0; 157 158 // Indicate that a device has been connected that does support absolute 159 // volume. The callback will be immediately called with the current volume 160 // which will be sent to the device. 161 virtual void DeviceConnected(const RawAddress& bdaddr, 162 VolumeChangedCb cb) = 0; 163 164 // Indicate that a device has been disconnected from AVRCP. Will unregister 165 // any callbacks if absolute volume is supported. 166 virtual void DeviceDisconnected(const RawAddress& bdaddr) = 0; 167 168 virtual void SetVolume(int8_t volume) = 0; 169 170 virtual ~VolumeInterface() = default; 171 }; 172 173 class ServiceInterface { 174 public: 175 // mediaInterface can not be null. If volumeInterface is null then Absolute 176 // Volume is disabled. 177 virtual void Init(MediaInterface* mediaInterface, 178 VolumeInterface* volumeInterface) = 0; 179 virtual bool ConnectDevice(const RawAddress& bdaddr) = 0; 180 virtual bool DisconnectDevice(const RawAddress& bdaddr) = 0; 181 virtual bool Cleanup() = 0; 182 183 protected: 184 virtual ~ServiceInterface() = default; 185 }; 186 187 } // namespace avrcp 188 } // namespace bluetooth