From 93c9c83ac593ed1cf0c4671d88370b4d0a48a261 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 19 Mar 2019 10:45:36 -0700 Subject: [PATCH] Haptic feedback when remote enables video --- Signal/src/UserInterface/HapticFeedback.swift | 59 +++++++++++++++++++ .../Call/CallViewController.swift | 35 +++++++++-- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/Signal/src/UserInterface/HapticFeedback.swift b/Signal/src/UserInterface/HapticFeedback.swift index 672e33803..2db0b0975 100644 --- a/Signal/src/UserInterface/HapticFeedback.swift +++ b/Signal/src/UserInterface/HapticFeedback.swift @@ -46,3 +46,62 @@ class ModernSelectionHapticFeedbackAdapter: NSObject, SelectionHapticFeedbackAda selectionFeedbackGenerator.prepare() } } + +enum NotificationHapticFeedbackType { + case error, success, warning +} + +extension NotificationHapticFeedbackType { + var uiNotificationFeedbackType: UINotificationFeedbackType { + switch self { + case .error: return .error + case .success: return .success + case .warning: return .warning + } + } +} + +protocol NotificationHapticFeedbackAdapter { + func notificationOccurred(_ notificationType: NotificationHapticFeedbackType) +} + +class NotificationHapticFeedback: NotificationHapticFeedbackAdapter { + + let adapter: NotificationHapticFeedbackAdapter + + init() { + if #available(iOS 10, *) { + adapter = ModernNotificationHapticFeedbackAdapter() + } else { + adapter = LegacyNotificationHapticFeedbackAdapter() + } + } + + func notificationOccurred(_ notificationType: NotificationHapticFeedbackType) { + adapter.notificationOccurred(notificationType) + } +} + +@available(iOS 10.0, *) +class ModernNotificationHapticFeedbackAdapter: NotificationHapticFeedbackAdapter { + let feedbackGenerator = UINotificationFeedbackGenerator() + + init() { + feedbackGenerator.prepare() + } + + func notificationOccurred(_ notificationType: NotificationHapticFeedbackType) { + feedbackGenerator.notificationOccurred(notificationType.uiNotificationFeedbackType) + feedbackGenerator.prepare() + } +} + +class LegacyNotificationHapticFeedbackAdapter: NotificationHapticFeedbackAdapter { + func notificationOccurred(_ notificationType: NotificationHapticFeedbackType) { + vibrate() + } + + private func vibrate() { + AudioServicesPlaySystemSound(kSystemSoundID_Vibrate) + } +} diff --git a/Signal/src/ViewControllers/Call/CallViewController.swift b/Signal/src/ViewControllers/Call/CallViewController.swift index 758914d33..f56a6936b 100644 --- a/Signal/src/ViewControllers/Call/CallViewController.swift +++ b/Signal/src/ViewControllers/Call/CallViewController.swift @@ -88,10 +88,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } } - override var preferredStatusBarStyle: UIStatusBarStyle { - return .lightContent - } - // MARK: - Settings Nag Views var isShowingSettingsNag = false { @@ -230,6 +226,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, return .portrait } + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + // MARK: - Create Views func createViews() { @@ -1035,6 +1035,11 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, AssertIsOnMainThread() + guard localVideoView.captureSession != captureSession else { + Logger.debug("ignoring redundant update") + return + } + localVideoView.captureSession = captureSession let isHidden = captureSession == nil @@ -1058,7 +1063,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, internal func updateRemoteVideoTrack(remoteVideoTrack: RTCVideoTrack?) { AssertIsOnMainThread() + guard self.remoteVideoTrack != remoteVideoTrack else { + Logger.debug("ignoring redundant update") return } @@ -1070,9 +1077,29 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, shouldRemoteVideoControlsBeHidden = false + if remoteVideoTrack != nil { + playRemoteEnabledVideoHapticFeedback() + } + updateRemoteVideoLayout() } + // MARK: Video Haptics + + let feedbackGenerator = NotificationHapticFeedback() + var lastHapticTime: TimeInterval = CACurrentMediaTime() + func playRemoteEnabledVideoHapticFeedback() { + let currentTime = CACurrentMediaTime() + guard currentTime - lastHapticTime > 5 else { + Logger.debug("ignoring haptic feedback since it's too soon") + return + } + feedbackGenerator.notificationOccurred(.success) + lastHapticTime = currentTime + } + + // MARK: - Dismiss + internal func dismissIfPossible(shouldDelay: Bool, ignoreNag ignoreNagParam: Bool = false, completion: (() -> Void)? = nil) { callUIAdapter.audioService.delegate = nil