From d244e1c8a64fa2dd6f67a276efe1bae53a216ee6 Mon Sep 17 00:00:00 2001 From: childc Date: Fri, 24 Nov 2023 16:23:28 +0900 Subject: [PATCH 1/2] =?UTF-8?q?AudioSession=EC=9D=84=20=EC=84=A4=EC=A0=95?= =?UTF-8?q?=ED=95=A0=20=EC=88=98=20=EC=97=86=EB=8A=94=20=EA=B2=BD=EC=9A=B0?= =?UTF-8?q?=20retry=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NuguClientKit/Sources/Client/NuguClient.swift | 20 +++++- NuguCore/Sources/Focus/FocusDelegate.swift | 2 +- NuguCore/Sources/Focus/FocusManager.swift | 66 ++++++++++--------- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/NuguClientKit/Sources/Client/NuguClient.swift b/NuguClientKit/Sources/Client/NuguClient.swift index d566abbe7..cbb394de5 100644 --- a/NuguClientKit/Sources/Client/NuguClient.swift +++ b/NuguClientKit/Sources/Client/NuguClient.swift @@ -548,16 +548,30 @@ extension NuguClient: FocusDelegate { focusManager.delegate = self } - public func focusShouldAcquire() -> Bool { + public func focusShouldAcquire(completion: @escaping (Result) -> Void) { guard let audioSessionManager = audioSessionManager else { - return delegate?.nuguClientShouldUpdateAudioSessionForFocusAquire() == true + completion(.success(delegate?.nuguClientShouldUpdateAudioSessionForFocusAquire() == true)) + return } if let audioDeactivateWorkItem = audioDeactivateWorkItem { audioDeactivateWorkItem.cancel() } - return audioSessionManager.updateAudioSession(requestingFocus: true) == true + DispatchQueue.global().async { + var isFocusAcquired = false + var retryCount: Int = .zero + repeat { + if .zero < retryCount { + Thread.sleep(forTimeInterval: 1) + } + + isFocusAcquired = audioSessionManager.updateAudioSession(requestingFocus: true) + retryCount += 1 + } while retryCount < 3 || isFocusAcquired == false + + completion(.success(isFocusAcquired)) + } } public func focusShouldRelease() { diff --git a/NuguCore/Sources/Focus/FocusDelegate.swift b/NuguCore/Sources/Focus/FocusDelegate.swift index ba8550e69..f2caaecc7 100644 --- a/NuguCore/Sources/Focus/FocusDelegate.swift +++ b/NuguCore/Sources/Focus/FocusDelegate.swift @@ -25,7 +25,7 @@ public protocol FocusDelegate: AnyObject { /// Determines whether the `AVAudioSession` should be activates. /// /// This mehthod called When the `FocusManager` receives a `requestFocus:channelDelegate:` - func focusShouldAcquire() -> Bool + func focusShouldAcquire(completion: @escaping (Result) -> Void) /// Determines whether the `AVAudioSession` should be deactivates. func focusShouldRelease() diff --git a/NuguCore/Sources/Focus/FocusManager.swift b/NuguCore/Sources/Focus/FocusManager.swift index a6ae081d3..faf8d090c 100644 --- a/NuguCore/Sources/Focus/FocusManager.swift +++ b/NuguCore/Sources/Focus/FocusManager.swift @@ -73,42 +73,46 @@ public extension FocusManager { func requestFocus(channelDelegate: FocusChannelDelegate) { focusDispatchQueue.sync { [weak self] in - guard let self = self else { return } - guard self.channelInfos.object(forDelegate: channelDelegate) != nil else { + guard let self else { return } + guard channelInfos.object(forDelegate: channelDelegate) != nil else { log.warning("\(channelDelegate): Channel not registered") return } - guard self.delegate?.focusShouldAcquire() == true else { - log.warning("Focus should not acquire. \(channelDelegate.focusChannelPriority())") - self.update(channelDelegate: channelDelegate, focusState: .nothing) - return - } - guard self.foregroundChannelDelegate !== channelDelegate else { - self.update(channelDelegate: channelDelegate, focusState: .foreground) - return - } - - // Move current foreground channel to background If Its priority is lower than requested. - if let foregroundChannelDelegate = self.foregroundChannelDelegate, - channelDelegate.focusChannelPriority().requestPriority >= foregroundChannelDelegate.focusChannelPriority().maintainPriority { - self.update(channelDelegate: foregroundChannelDelegate, focusState: .background) - } + delegate?.focusShouldAcquire { [weak self] result in + guard let self else { return } + if case .success(let success) = result, success { + guard foregroundChannelDelegate !== channelDelegate else { + update(channelDelegate: channelDelegate, focusState: .foreground) + return + } + + // Move current foreground channel to background If Its priority is lower than requested. + if let foregroundChannelDelegate = foregroundChannelDelegate, + channelDelegate.focusChannelPriority().requestPriority >= foregroundChannelDelegate.focusChannelPriority().maintainPriority { + update(channelDelegate: foregroundChannelDelegate, focusState: .background) + } - if let prepareChannelDelegate = self.prepareChannelDelegate, - prepareChannelDelegate !== channelDelegate, - channelDelegate.focusChannelPriority().requestPriority < prepareChannelDelegate.focusChannelPriority().requestPriority { - // Prepare channel will request focus in the future. - self.update(channelDelegate: channelDelegate, focusState: .background) - } else if let backgroundChannelDelegate = self.backgroundChannelDelegate, - backgroundChannelDelegate !== channelDelegate, - channelDelegate.focusChannelPriority().requestPriority < backgroundChannelDelegate.focusChannelPriority().maintainPriority { - // Assign a higher background channel to the foreground in the future. - self.update(channelDelegate: channelDelegate, focusState: .background) - } else if self.foregroundChannelDelegate == nil { - self.update(channelDelegate: channelDelegate, focusState: .foreground) - } else { - self.update(channelDelegate: channelDelegate, focusState: .background) + if let prepareChannelDelegate = prepareChannelDelegate, + prepareChannelDelegate !== channelDelegate, + channelDelegate.focusChannelPriority().requestPriority < prepareChannelDelegate.focusChannelPriority().requestPriority { + // Prepare channel will request focus in the future. + update(channelDelegate: channelDelegate, focusState: .background) + } else if let backgroundChannelDelegate = backgroundChannelDelegate, + backgroundChannelDelegate !== channelDelegate, + channelDelegate.focusChannelPriority().requestPriority < backgroundChannelDelegate.focusChannelPriority().maintainPriority { + // Assign a higher background channel to the foreground in the future. + update(channelDelegate: channelDelegate, focusState: .background) + } else if foregroundChannelDelegate == nil { + update(channelDelegate: channelDelegate, focusState: .foreground) + } else { + update(channelDelegate: channelDelegate, focusState: .background) + } + } else { + log.warning("Focus should not acquire. \(channelDelegate.focusChannelPriority())") + update(channelDelegate: channelDelegate, focusState: .nothing) + + } } } } From bc2a354d2e6df86c079c5d29373f1809ab477ff1 Mon Sep 17 00:00:00 2001 From: childc Date: Fri, 24 Nov 2023 16:42:02 +0900 Subject: [PATCH 2/2] =?UTF-8?q?=EC=83=81=EC=88=98=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NuguClientKit/Sources/Client/NuguClient.swift | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/NuguClientKit/Sources/Client/NuguClient.swift b/NuguClientKit/Sources/Client/NuguClient.swift index cbb394de5..53b9eb594 100644 --- a/NuguClientKit/Sources/Client/NuguClient.swift +++ b/NuguClientKit/Sources/Client/NuguClient.swift @@ -24,6 +24,11 @@ import AVFoundation import NuguCore import NuguAgents +private enum Const { + static let maxRetryCount = 3 + static let retryTimeInterval: TimeInterval = 1 +} + /// <#Description#> public class NuguClient { public weak var delegate: NuguClientDelegate? @@ -563,12 +568,12 @@ extension NuguClient: FocusDelegate { var retryCount: Int = .zero repeat { if .zero < retryCount { - Thread.sleep(forTimeInterval: 1) + Thread.sleep(forTimeInterval: Const.retryTimeInterval) } isFocusAcquired = audioSessionManager.updateAudioSession(requestingFocus: true) retryCount += 1 - } while retryCount < 3 || isFocusAcquired == false + } while retryCount < Const.maxRetryCount && isFocusAcquired == false completion(.success(isFocusAcquired)) }