193 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			193 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			C++
		
	
	
	
/*
 | 
						|
 * 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 <set>
 | 
						|
#include <string>
 | 
						|
#include <vector>
 | 
						|
 | 
						|
#include <base/callback_forward.h>
 | 
						|
 | 
						|
#include "avrcp_common.h"
 | 
						|
#include "raw_address.h"
 | 
						|
 | 
						|
namespace bluetooth {
 | 
						|
namespace avrcp {
 | 
						|
 | 
						|
struct SongInfo {
 | 
						|
  std::string media_id;  // This gets converted to a UID in the native service
 | 
						|
  std::set<AttributeEntry> 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) = 0;
 | 
						|
  virtual void SendActiveDeviceChanged(const RawAddress& address) = 0;
 | 
						|
  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<void(SongInfo)>;
 | 
						|
  virtual void GetSongInfo(SongInfoCallback info_cb) = 0;
 | 
						|
 | 
						|
  using PlayStatusCallback = base::Callback<void(PlayStatus)>;
 | 
						|
  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<void(std::string, std::vector<SongInfo>)>;
 | 
						|
  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<void(uint16_t curr_player, std::vector<MediaPlayerInfo>)>;
 | 
						|
  virtual void GetMediaPlayerList(MediaListCallback list_cb) = 0;
 | 
						|
 | 
						|
  using FolderItemsCallback = base::Callback<void(std::vector<ListItem>)>;
 | 
						|
  virtual void GetFolderItems(uint16_t player_id, std::string media_id,
 | 
						|
                              FolderItemsCallback folder_cb) = 0;
 | 
						|
 | 
						|
  using SetBrowsedPlayerCallback = base::Callback<void(
 | 
						|
      bool success, std::string root_id, uint32_t num_items)>;
 | 
						|
  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;
 | 
						|
 | 
						|
  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<void(int8_t volume)>;
 | 
						|
 | 
						|
  // 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
 |