1 /* 2 * Copyright 2024 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 <atomic> 20 #include <cstdint> 21 #include <map> 22 #include <string> 23 24 namespace bluetooth::avrcp { 25 constexpr uint32_t RECORD_NOT_ASSIGNED = -1u; 26 constexpr uint16_t UNASSIGNED_REQUEST_ID = -1; 27 28 /** 29 * Struct containing all the required data to add the AVRC SDP records. 30 */ 31 struct AvrcpSdpRecord { 32 /** 33 * Service uuid for the SDP record. 34 */ 35 uint16_t service_uuid; 36 37 /** 38 * Service name for the record. 39 */ 40 std::string service_name; 41 42 /** 43 * Provider name for the record. 44 */ 45 std::string provider_name; 46 47 /** 48 * Categories of features that are supported. 49 * Each bit represents the feature that is supported. 50 */ 51 uint16_t categories; 52 53 /** 54 * Is browse supported by the service. 55 */ 56 bool browse_supported; 57 58 /** 59 * Profile version for the service. 60 */ 61 uint16_t profile_version; 62 63 /** 64 * Cover art psm for the service. 65 */ 66 uint16_t cover_art_psm; 67 68 /*** 69 * 70 * Sets the category bit to the existing categories. 71 * @param category category bit that needs to be added. 72 */ AddToExistingCategoriesAvrcpSdpRecord73 void AddToExistingCategories(uint16_t category) { categories |= category; } 74 75 /** 76 * Remove the category bit from the existing set of categories. 77 * @param category category bit that needs to be removed. 78 */ RemoveCategoryAvrcpSdpRecord79 void RemoveCategory(uint16_t category) { categories &= ~category; } 80 }; 81 82 /** 83 * Abstract class to add, remove AVRC SDP records. 84 */ 85 class AvrcSdpRecordHelper { 86 public: 87 /** 88 * Default constructor. 89 */ AvrcSdpRecordHelper()90 AvrcSdpRecordHelper() : request_id_counter_(0) {} 91 92 /** 93 * Default virtual destructor. 94 */ 95 virtual ~AvrcSdpRecordHelper() = default; 96 97 /** 98 * Adds the records if none exists. If records already exists, then it only 99 * updates the categories that can be supported. 100 * @param request_id unique request id that needs to be assigned. It generate unique id only if 101 * the previous request doesn't exist. 102 * @param add_record_request record request that needs 103 * @return the request id. 104 */ 105 virtual uint16_t AddRecord(const AvrcpSdpRecord& add_record_request, uint16_t& request_id, 106 bool add_sys_uid = true); 107 108 /** 109 * Removes the SDP records. If there were multiple SDP record request, it would remove the 110 * corresponding request and use the rest of the records to identify the SDP record that needs 111 * to be created. 112 * @param request_id id of the previous request for which the record needs to be removed. 113 * @return AVRC_SUCCESS if successful. 114 * AVRC_FAIL otherwise 115 */ 116 uint16_t RemoveRecord(uint16_t request_id); 117 118 /** 119 * Abstract method for child class to implement. 120 * @param cover_art_psm cover art protocol service multiplexor. 121 * @param request_id id of the previous request for which cover art needs to be enabled. 122 * @return AVRC_SUCCESS if successful. 123 * AVRC_FAIL otherwise 124 */ 125 virtual uint16_t EnableCovertArt(uint16_t cover_art_psm, uint16_t request_id) = 0; 126 127 /** 128 * Abstract method for child class to implement. 129 * @param request_id id of the previous request for which cover art needs to be disabled. 130 * @return AVRC_SUCCESS if successful. 131 * AVRC_FAIL otherwise 132 */ 133 virtual uint16_t DisableCovertArt(uint16_t request_id) = 0; 134 135 protected: 136 /** 137 * Record handle for the SDP records. 138 */ 139 uint32_t sdp_record_handle_ = -1; 140 141 /** 142 * Update the SDP record with the new set of categories. 143 * @param updated_categories new categories bits that needs to be added. 144 * @return AVRC_SUCCESS if successful. 145 * AVRC_FAIL otherwise 146 */ 147 virtual uint16_t UpdateRecord(uint16_t updated_categories); 148 149 /** 150 * Merges all the cached requests submitted to the service. 151 * @param add_sdp_record_request reference of sdp record that needs to be merged. 152 * @return 153 */ 154 virtual bool MergeSdpRecords(AvrcpSdpRecord& add_sdp_record_request); 155 156 /** 157 * Map of request id v/s individual sdp record requested by individual clients. 158 */ 159 std::map<uint16_t, AvrcpSdpRecord> sdp_record_request_map_; 160 161 private: 162 std::atomic<uint16_t> request_id_counter_; 163 }; 164 165 /** 166 * Helper class to add Control AVRC SDP records. 167 */ 168 class ControlAvrcSdpRecordHelper : public AvrcSdpRecordHelper { 169 public: 170 /** 171 * Default constructor. 172 */ 173 ControlAvrcSdpRecordHelper() = default; 174 175 /** 176 * Unsupported method for control SDP records. 177 * @param cover_art_psm no-op. 178 * @param request_id no-op 179 * @return AVRC_FAIL as it's unsupported. 180 */ 181 uint16_t EnableCovertArt(uint16_t cover_art_psm, uint16_t request_id) override; 182 183 /** 184 * Unsupported method for control SDP records. 185 * @param request_id no-op 186 * @return AVRC_FAIL as it's unsupported. 187 */ 188 uint16_t DisableCovertArt(uint16_t request_id) override; 189 190 protected: 191 /** 192 * Invokes the base class's UpdateRecord. Also updates the class attributes based on the 193 * profile version. 194 * @param updated_categories new categories that needs to be updated. 195 * @return AVRC_SUCCESS if successful. 196 * AVRC_FAIL otherwise 197 */ 198 uint16_t UpdateRecord(uint16_t updated_categories) override; 199 }; 200 201 /** 202 * Helper class to add Target AVRC SDP records. 203 */ 204 class TargetAvrcSdpRecordHelper : public AvrcSdpRecordHelper { 205 public: 206 /** 207 * Default constructor. 208 */ 209 TargetAvrcSdpRecordHelper() = default; 210 211 /** 212 * Enables cover art support. It removes the existing SDP records, updates the 213 * cached SDP record request with cover art attributes (categories & cover art 214 * psm), creates new AVRC SDP records. 215 * @param cover_art_psm cover art protocol service multiplexor. 216 * @return AVRC_SUCCESS if successful. 217 * AVRC_FAIL otherwise 218 */ 219 uint16_t EnableCovertArt(uint16_t cover_art_psm, uint16_t request_id) override; 220 221 /** 222 * Disables cover art support. It removes the existing SDP records, removes 223 * the cached SDP record request with cover art attributes (categories & cover 224 * art psm), creates new AVRC SDP records w/o cover art support. 225 * @param cover_art_psm cover art protocol service multiplexor 226 * @return AVRC_SUCCESS if successful. 227 * AVRC_FAIL otherwise 228 */ 229 uint16_t DisableCovertArt(uint16_t request_id) override; 230 }; 231 } // namespace bluetooth::avrcp 232