Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AudioSession을 설정할 수 없는 경우 retry하도록 수정 #1109

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions NuguClientKit/Sources/Client/NuguClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -548,16 +553,30 @@ extension NuguClient: FocusDelegate {
focusManager.delegate = self
}

public func focusShouldAcquire() -> Bool {
public func focusShouldAcquire(completion: @escaping (Result<Bool, Error>) -> 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: Const.retryTimeInterval)
}

isFocusAcquired = audioSessionManager.updateAudioSession(requestingFocus: true)
retryCount += 1
} while retryCount < Const.maxRetryCount && isFocusAcquired == false

completion(.success(isFocusAcquired))
}
}

public func focusShouldRelease() {
Expand Down
2 changes: 1 addition & 1 deletion NuguCore/Sources/Focus/FocusDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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<Bool, Error>) -> Void)

/// Determines whether the `AVAudioSession` should be deactivates.
func focusShouldRelease()
Expand Down
66 changes: 35 additions & 31 deletions NuguCore/Sources/Focus/FocusManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)

}
}
}
}
Expand Down