• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/bind.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, bool queue);
76   virtual void SendFolderUpdate(bool available_players, bool addressed_players,
77                                 bool uids_changed);
78   virtual void SendActiveDeviceChanged(const RawAddress& address);
79   virtual ~MediaCallbacks() = default;
80 };
81 
82 // The classes below are used by the JNI and are loaded dynamically with the
83 // Bluetooth library. All classes must be pure virtual otherwise a compiler
84 // error occurs when trying to link the function implementation.
85 
86 // MediaInterface defines the class that the AVRCP Service uses in order
87 // communicate with the media layer. The media layer will define its own
88 // implementation of this object and register it with the service using
89 // Avrcp::ServiceInterface::Init(). At this point the AVRCP Service will
90 // call RegisterUpdateCallbacks() to provide an handle to use to send
91 // notifications about changes in the Media Interface.
92 //
93 // NOTES: The current implementation has the native service handle all the
94 // thread switching. It will call the interface functions on the btif/jni
95 // thread and the callback will post its results to the bta thread.
96 // In the future the interface the JNI registered with the
97 // service should post all its tasks to the JNI thread itself so that the native
98 // service isn't aware of the thread the interface functions need to be called
99 // on. It can then supply callbacks that post results to the correct thread
100 // allowing the threading model to be totally encapsulated and allow correct
101 // behavior in case the threading model changes on either side.
102 class MediaInterface {
103  public:
104   virtual void SendKeyEvent(uint8_t key, KeyState state) = 0;
105 
106   using SongInfoCallback = base::Callback<void(SongInfo)>;
107   virtual void GetSongInfo(SongInfoCallback info_cb) = 0;
108 
109   using PlayStatusCallback = base::Callback<void(PlayStatus)>;
110   virtual void GetPlayStatus(PlayStatusCallback status_cb) = 0;
111 
112   // Contains the current queue and the media ID of the currently playing item
113   // in the queue
114   using NowPlayingCallback =
115       base::Callback<void(std::string, std::vector<SongInfo>)>;
116   virtual void GetNowPlayingList(NowPlayingCallback now_playing_cb) = 0;
117 
118   // TODO (apanicke): Use a map with the ID as the key instead of vector
119   // in follow up cleanup patches. This allows simplification of the
120   // MediaPlayerInfo object
121   using MediaListCallback =
122       base::Callback<void(uint16_t curr_player, std::vector<MediaPlayerInfo>)>;
123   virtual void GetMediaPlayerList(MediaListCallback list_cb) = 0;
124 
125   using FolderItemsCallback = base::Callback<void(std::vector<ListItem>)>;
126   virtual void GetFolderItems(uint16_t player_id, std::string media_id,
127                               FolderItemsCallback folder_cb) = 0;
128 
129   using SetBrowsedPlayerCallback = base::Callback<void(
130       bool success, std::string root_id, uint32_t num_items)>;
131   virtual void SetBrowsedPlayer(uint16_t player_id,
132                                 SetBrowsedPlayerCallback browse_cb) = 0;
133 
134   virtual void PlayItem(uint16_t player_id, bool now_playing,
135                         std::string media_id) = 0;
136 
137   virtual void SetActiveDevice(const RawAddress& address) = 0;
138 
139   virtual void RegisterUpdateCallback(MediaCallbacks* callback) = 0;
140 
141   virtual void UnregisterUpdateCallback(MediaCallbacks* callback) = 0;
142 
143   MediaInterface() = default;
144   virtual ~MediaInterface() = default;
145 };
146 
147 class VolumeInterface {
148  public:
149   // TODO (apanicke): Investigate the best value type for volume. Right now it
150   // is a value from 0-127 because thats what AVRCP uses.
151   using VolumeChangedCb = base::Callback<void(int8_t volume)>;
152 
153   // Indicate that a device has been connected that does not support absolute
154   // volume.
155   virtual void DeviceConnected(const RawAddress& bdaddr) = 0;
156 
157   // Indicate that a device has been connected that does support absolute
158   // volume. The callback will be immediately called with the current volume
159   // which will be sent to the device.
160   virtual void DeviceConnected(const RawAddress& bdaddr,
161                                VolumeChangedCb cb) = 0;
162 
163   // Indicate that a device has been disconnected from AVRCP. Will unregister
164   // any callbacks if absolute volume is supported.
165   virtual void DeviceDisconnected(const RawAddress& bdaddr) = 0;
166 
167   virtual void SetVolume(int8_t volume) = 0;
168 
169   virtual ~VolumeInterface() = default;
170 };
171 
172 class ServiceInterface {
173  public:
174   // mediaInterface can not be null. If volumeInterface is null then Absolute
175   // Volume is disabled.
176   virtual void Init(MediaInterface* mediaInterface,
177                     VolumeInterface* volumeInterface) = 0;
178   virtual bool ConnectDevice(const RawAddress& bdaddr) = 0;
179   virtual bool DisconnectDevice(const RawAddress& bdaddr) = 0;
180   virtual bool Cleanup() = 0;
181 
182  protected:
183   virtual ~ServiceInterface() = default;
184 };
185 
186 }  // namespace avrcp
187 }  // namespace bluetooth