1 /* 2 * Copyright (c) 2023-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef AUDIO_INTERRUPT_INFO_H 16 #define AUDIO_INTERRUPT_INFO_H 17 18 #include <parcel.h> 19 #include <audio_stream_info.h> 20 #include <audio_source_type.h> 21 #include <audio_session_info.h> 22 23 namespace OHOS { 24 namespace AudioStandard { 25 static constexpr int32_t AUDIO_INTERRUPT_INFO_SIZE_LIMIT = 65535; 26 27 enum ActionTarget { 28 CURRENT = 0, 29 INCOMING, 30 BOTH 31 }; 32 33 /** 34 * larger enumeration values has higher priority 35 */ 36 enum AudioFocuState { 37 ACTIVE = 0, 38 MUTED, 39 DUCK, 40 PAUSE, 41 STOP, 42 PLACEHOLDER, 43 PAUSEDBYREMOTE, 44 }; 45 46 enum InterruptMode { 47 SHARE_MODE = 0, 48 INDEPENDENT_MODE = 1 49 }; 50 51 /** 52 * Enumerates the audio interrupt request type. 53 */ 54 enum InterruptRequestType { 55 INTERRUPT_REQUEST_TYPE_DEFAULT = 0, 56 }; 57 58 /** 59 * Enumerates audio interrupt event. 60 */ 61 enum InterruptCallbackEvent { 62 NO_EVENT = 0, 63 FORCE_EVENT = 1, 64 FORCE_PAUSED_TO_RESUME_EVENT = 2 65 }; 66 67 /** 68 * Enumerates audio interrupt request result type. 69 */ 70 enum InterruptRequestResultType { 71 INTERRUPT_REQUEST_GRANT = 0, 72 INTERRUPT_REQUEST_REJECT = 1 73 }; 74 75 enum InterruptType { 76 INTERRUPT_TYPE_BEGIN = 1, 77 INTERRUPT_TYPE_END = 2, 78 }; 79 80 enum InterruptHint { 81 INTERRUPT_HINT_NONE = 0, 82 INTERRUPT_HINT_RESUME, 83 INTERRUPT_HINT_PAUSE, 84 INTERRUPT_HINT_STOP, 85 INTERRUPT_HINT_DUCK, 86 INTERRUPT_HINT_UNDUCK, 87 INTERRUPT_HINT_MUTE, 88 INTERRUPT_HINT_UNMUTE, 89 INTERRUPT_HINT_EXIT_STANDALONE 90 }; 91 92 enum InterruptForceType { 93 /** 94 * Force type, system change audio state. 95 */ 96 INTERRUPT_FORCE = 0, 97 /** 98 * Share type, application change audio state. 99 */ 100 INTERRUPT_SHARE 101 }; 102 103 struct InterruptEvent : public Parcelable { InterruptEventInterruptEvent104 InterruptEvent() {} 105 InterruptEvent(InterruptType eventTypeIn, InterruptForceType forceTypeIn, 106 InterruptHint hintType, bool callbackToAppIn = true) eventTypeInterruptEvent107 : eventType(eventTypeIn), forceType(forceTypeIn), hintType(hintType), callbackToApp(callbackToAppIn) {} MarshallingInterruptEvent108 bool Marshalling(Parcel &parcel) const override 109 { 110 parcel.WriteInt32(static_cast<int32_t>(eventType)); 111 parcel.WriteInt32(static_cast<int32_t>(forceType)); 112 parcel.WriteInt32(static_cast<int32_t>(hintType)); 113 parcel.WriteBool(callbackToApp); 114 return true; 115 } 116 UnmarshallingInterruptEvent117 static InterruptEvent *Unmarshalling(Parcel &parcel) 118 { 119 auto info = new(std::nothrow) InterruptEvent(); 120 if (info == nullptr) { 121 return nullptr; 122 } 123 info->eventType = static_cast<InterruptType>(parcel.ReadInt32()); 124 info->forceType = static_cast<InterruptForceType>(parcel.ReadInt32()); 125 info->hintType = static_cast<InterruptHint>(parcel.ReadInt32()); 126 info->callbackToApp = parcel.ReadBool(); 127 return info; 128 } 129 130 /** 131 * Interrupt event type, begin or end 132 */ 133 InterruptType eventType = INTERRUPT_TYPE_BEGIN; 134 /** 135 * Interrupt force type, force or share 136 */ 137 InterruptForceType forceType = INTERRUPT_FORCE; 138 /** 139 * Interrupt hint type. In force type, the audio state already changed, 140 * but in share mode, only provide a hint for application to decide. 141 */ 142 InterruptHint hintType = INTERRUPT_HINT_NONE; 143 /** 144 * Should callback to app. Default true; 145 * If false, interruptEvent should not callback to app. 146 */ 147 bool callbackToApp = true; 148 }; 149 150 // Used internally only by AudioFramework 151 struct InterruptEventInternal : public Parcelable { 152 InterruptType eventType = INTERRUPT_TYPE_BEGIN; 153 InterruptForceType forceType = INTERRUPT_FORCE; 154 InterruptHint hintType = INTERRUPT_HINT_NONE; 155 float duckVolume = 1.0f; 156 bool callbackToApp = true; 157 158 InterruptEventInternal() = default; 159 InterruptEventInternalInterruptEventInternal160 InterruptEventInternal(InterruptType eventtype, InterruptForceType forcetype, 161 InterruptHint hinttype, float duckvolume) 162 { 163 eventType = eventtype; 164 forceType = forcetype; 165 hintType = hinttype; 166 duckVolume = duckvolume; 167 } 168 MarshallingInterruptEventInternal169 bool Marshalling(Parcel &parcel) const override 170 { 171 return parcel.WriteInt32(static_cast<int32_t>(eventType)) 172 && parcel.WriteInt32(static_cast<int32_t>(forceType)) 173 && parcel.WriteInt32(static_cast<int32_t>(hintType)) 174 && parcel.WriteFloat(duckVolume) 175 && parcel.WriteBool(callbackToApp); 176 } 177 UnmarshallingInterruptEventInternal178 static InterruptEventInternal *Unmarshalling(Parcel &parcel) 179 { 180 auto interupt = new(std::nothrow) InterruptEventInternal(); 181 if (interupt == nullptr) { 182 return nullptr; 183 } 184 interupt->eventType = static_cast<InterruptType>(parcel.ReadInt32()); 185 interupt->forceType = static_cast<InterruptForceType>(parcel.ReadInt32()); 186 interupt->hintType = static_cast<InterruptHint>(parcel.ReadInt32()); 187 interupt->duckVolume = parcel.ReadFloat(); 188 interupt->callbackToApp = parcel.ReadBool(); 189 return interupt; 190 } 191 }; 192 193 enum AudioInterruptChangeType { 194 ACTIVATE_AUDIO_INTERRUPT = 0, 195 DEACTIVATE_AUDIO_INTERRUPT = 1, 196 }; 197 198 // Below APIs are added to handle compilation error in call manager 199 // Once call manager adapt to new interrupt APIs, this will be removed 200 enum InterruptActionType { 201 TYPE_ACTIVATED = 0, 202 TYPE_INTERRUPT = 1 203 }; 204 205 struct InterruptAction { 206 InterruptActionType actionType; 207 InterruptType interruptType; 208 InterruptHint interruptHint; 209 bool activated; 210 }; 211 212 struct AudioFocusEntry { 213 InterruptForceType forceType; 214 InterruptHint hintType; 215 ActionTarget actionOn; 216 bool isReject; 217 }; 218 219 struct AudioFocusConcurrency { 220 std::vector<SourceType> sourcesTypes; 221 }; 222 223 struct AudioFocusType { 224 AudioStreamType streamType = STREAM_DEFAULT; 225 SourceType sourceType = SOURCE_TYPE_INVALID; 226 bool isPlay = true; 227 bool operator==(const AudioFocusType &value) const 228 { 229 return streamType == value.streamType && sourceType == value.sourceType && isPlay == value.isPlay; 230 } 231 232 bool operator<(const AudioFocusType &value) const 233 { 234 return streamType < value.streamType || (streamType == value.streamType && sourceType < value.sourceType); 235 } 236 237 bool operator>(const AudioFocusType &value) const 238 { 239 return streamType > value.streamType || (streamType == value.streamType && sourceType > value.sourceType); 240 } 241 }; 242 243 enum InterruptStage { 244 INTERRUPT_STAGE_START = 0x10, 245 INTERRUPT_STAGE_RESTART = 0x11, 246 INTERRUPT_STAGE_STOP = 0x12, 247 INTERRUPT_STAGE_PAUSED = 0x20, 248 INTERRUPT_STAGE_RESUMED = 0x21, 249 INTERRUPT_STAGE_STOPPED = 0x30, 250 INTERRUPT_STAGE_DUCK_BEGIN = 0x40, 251 INTERRUPT_STAGE_DUCK_END = 0x41, 252 INTERRUPT_STAGE_TIMEOUT = 0x50 253 }; 254 255 enum InterruptSummary { 256 INTERRUPT_SUMMARY_INTERRUPT_OTHERS = 0, 257 INTERRUPT_SUMMARY_INTERRUPTED, 258 INTERRUPT_SUMMARY_INTERRUPT_BACKGROUND, 259 }; 260 261 enum InterruptRole { 262 INTERRUPT_ROLE_DEFAULT = 0, 263 INTERRUPT_ROLE_AUDIO_SESSION, 264 }; 265 266 enum InterruptStrategy { 267 DEFAULT = 0, 268 MUTE = 1, 269 }; 270 271 enum InterruptEventCallbackType { 272 /** 273 * Use OH_AudioRenderer_Callbacks.OH_AudioRenderer_OnInterruptEvent 274 */ 275 INTERRUPT_EVENT_CALLBACK_COMBINED = 0, 276 /** 277 * Use OH_AudioRenderer_OnInterruptEventCallback 278 */ 279 INTERRUPT_EVENT_CALLBACK_SEPERATED = 1, 280 /** 281 * Not use any OH_AudioRenderer InterruptEvent 282 */ 283 INTERRUPT_EVENT_CALLBACK_DEFAULT = 2 284 }; 285 286 class AudioInterrupt : public Parcelable { 287 public: 288 static constexpr int32_t MAX_SOURCE_TYPE_NUM = 20; 289 StreamUsage streamUsage = STREAM_USAGE_INVALID; 290 ContentType contentType = CONTENT_TYPE_UNKNOWN; 291 AudioFocusType audioFocusType; 292 uint32_t streamId = 0; 293 bool pauseWhenDucked = false; 294 int32_t pid { -1 }; 295 int32_t uid { -1 }; 296 std::string deviceTag; 297 InterruptMode mode { SHARE_MODE }; 298 bool isAudioSessionInterrupt {false}; 299 AudioFocusConcurrency currencySources; 300 AudioSessionStrategy sessionStrategy = { AudioConcurrencyMode::INVALID }; 301 int32_t api = 0; 302 int32_t state {-1}; 303 InterruptStrategy strategy { InterruptStrategy::DEFAULT }; 304 InterruptEventCallbackType callbackType {INTERRUPT_EVENT_CALLBACK_DEFAULT}; 305 306 AudioInterrupt() = default; AudioInterrupt(StreamUsage streamUsage_,ContentType contentType_,AudioFocusType audioFocusType_,uint32_t streamId_)307 AudioInterrupt(StreamUsage streamUsage_, ContentType contentType_, AudioFocusType audioFocusType_, 308 uint32_t streamId_) : streamUsage(streamUsage_), contentType(contentType_), audioFocusType(audioFocusType_), 309 streamId(streamId_) {} 310 ~AudioInterrupt() = default; 311 312 bool operator==(const AudioInterrupt &other) const 313 { 314 return streamId == other.streamId && 315 streamUsage == other.streamUsage && 316 audioFocusType == other.audioFocusType && 317 pid == other.pid && 318 uid == other.uid; 319 } 320 321 bool operator<(const AudioInterrupt &other) const 322 { 323 return streamId < other.streamId || pid < other.pid || uid < other.uid; 324 } 325 326 bool operator>(const AudioInterrupt &other) const 327 { 328 return streamId > other.streamId || pid > other.pid || uid > other.uid; 329 } 330 Marshalling(Parcel & parcel,const AudioInterrupt & interrupt)331 static bool Marshalling(Parcel &parcel, const AudioInterrupt &interrupt) 332 { 333 bool res = parcel.WriteInt32(static_cast<int32_t>(interrupt.streamUsage)); 334 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.contentType)); 335 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.audioFocusType.streamType)); 336 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.audioFocusType.sourceType)); 337 res = res && parcel.WriteBool(interrupt.audioFocusType.isPlay); 338 res = res && parcel.WriteUint32(interrupt.streamId); 339 res = res && parcel.WriteBool(interrupt.pauseWhenDucked); 340 res = res && parcel.WriteInt32(interrupt.pid); 341 res = res && parcel.WriteInt32(interrupt.uid); 342 res = res && parcel.WriteString(interrupt.deviceTag); 343 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.mode)); 344 res = res && parcel.WriteBool(interrupt.isAudioSessionInterrupt); 345 size_t vct = interrupt.currencySources.sourcesTypes.size(); 346 res = res && parcel.WriteInt32(static_cast<int32_t>(vct)); 347 for (size_t i = 0; i < vct; i++) { 348 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.currencySources.sourcesTypes[i])); 349 } 350 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.sessionStrategy.concurrencyMode)); 351 res = res && parcel.WriteInt32(interrupt.api); 352 res = res && parcel.WriteInt32(interrupt.state); 353 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.strategy)); 354 res = res && parcel.WriteInt32(static_cast<int32_t>(interrupt.callbackType)); 355 return res; 356 } Unmarshalling(Parcel & parcel,AudioInterrupt & interrupt)357 static void Unmarshalling(Parcel &parcel, AudioInterrupt &interrupt) 358 { 359 interrupt.streamUsage = static_cast<StreamUsage>(parcel.ReadInt32()); 360 interrupt.contentType = static_cast<ContentType>(parcel.ReadInt32()); 361 interrupt.audioFocusType.streamType = static_cast<AudioStreamType>(parcel.ReadInt32()); 362 interrupt.audioFocusType.sourceType = static_cast<SourceType>(parcel.ReadInt32()); 363 interrupt.audioFocusType.isPlay = parcel.ReadBool(); 364 interrupt.streamId = parcel.ReadUint32(); 365 interrupt.pauseWhenDucked = parcel.ReadBool(); 366 interrupt.pid = parcel.ReadInt32(); 367 interrupt.uid = parcel.ReadInt32(); 368 interrupt.deviceTag = parcel.ReadString(); 369 interrupt.mode = static_cast<InterruptMode>(parcel.ReadInt32()); 370 interrupt.isAudioSessionInterrupt = parcel.ReadBool(); 371 int32_t vct = parcel.ReadInt32(); 372 if (vct > MAX_SOURCE_TYPE_NUM) { 373 return; 374 } 375 376 for (int32_t i = 0; i < vct; i++) { 377 SourceType sourceType = static_cast<SourceType>(parcel.ReadInt32()); 378 interrupt.currencySources.sourcesTypes.push_back(sourceType); 379 } 380 interrupt.sessionStrategy.concurrencyMode = static_cast<AudioConcurrencyMode>(parcel.ReadInt32()); 381 interrupt.api = parcel.ReadInt32(); 382 interrupt.state = parcel.ReadInt32(); 383 interrupt.strategy = static_cast<InterruptStrategy>(parcel.ReadInt32()); 384 interrupt.callbackType = static_cast<InterruptEventCallbackType>(parcel.ReadInt32()); 385 } 386 Marshalling(Parcel & parcel)387 bool Marshalling(Parcel &parcel) const override 388 { 389 return Marshalling(parcel, *this); 390 } 391 Unmarshalling(Parcel & parcel)392 static AudioInterrupt *Unmarshalling(Parcel &parcel) 393 { 394 auto interrupt = new(std::nothrow) AudioInterrupt(); 395 if (interrupt == nullptr) { 396 return nullptr; 397 } 398 Unmarshalling(parcel, *interrupt); 399 return interrupt; 400 } 401 }; 402 } // namespace AudioStandard 403 } // namespace OHOS 404 #endif // AUDIO_INTERRUPT_INFO_H