From ce197b0ada5600ba4d06e011ad18cf2da3a59a7f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 11:40:42 -0400 Subject: [PATCH 1/7] Remove usage of ! in call view. --- .../ViewControllers/CallViewController.swift | 257 +++++++++++------- 1 file changed, 159 insertions(+), 98 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index 106c7ecac..f25187afe 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -30,27 +30,27 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Views var hasConstraints = false - var blurView: UIVisualEffectView! + var blurView: UIVisualEffectView? var dateFormatter: DateFormatter? // MARK: Contact Views - var contactNameLabel: MarqueeLabel! - var contactAvatarView: AvatarImageView! - var contactAvatarContainerView: UIView! - var callStatusLabel: UILabel! + let contactNameLabel = MarqueeLabel() + let contactAvatarView = AvatarImageView() + let contactAvatarContainerView = UIView.container() + let callStatusLabel = UILabel() var callDurationTimer: Timer? // MARK: Ongoing Call Controls - var ongoingCallView: UIView! + var ongoingCallView: UIView? - var hangUpButton: UIButton! - var audioSourceButton: UIButton! - var audioModeMuteButton: UIButton! - var audioModeVideoButton: UIButton! - var videoModeMuteButton: UIButton! - var videoModeVideoButton: UIButton! + var hangUpButton: UIButton? + var audioSourceButton: UIButton? + var audioModeMuteButton: UIButton? + var audioModeVideoButton: UIButton? + var videoModeMuteButton: UIButton? + var videoModeVideoButton: UIButton? // TODO: Later, we'll re-enable the text message button // so users can send and read messages during a // call. @@ -58,15 +58,15 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Incoming Call Controls - var incomingCallView: UIView! + var incomingCallView: UIView? - var acceptIncomingButton: UIButton! - var declineIncomingButton: UIButton! + var acceptIncomingButton: UIButton? + var declineIncomingButton: UIButton? // MARK: Video Views - var remoteVideoView: RemoteVideoView! - var localVideoView: RTCCameraPreviewView! + var remoteVideoView: RemoteVideoView? + var localVideoView: RTCCameraPreviewView? weak var localVideoTrack: RTCVideoTrack? weak var remoteVideoTrack: RTCVideoTrack? var localVideoConstraints: [NSLayoutConstraint] = [] @@ -90,8 +90,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } } } - var settingsNagView: UIView! - var settingsNagDescriptionLabel: UILabel! + let settingsNagView = UIView() + let settingsNagDescriptionLabel = UILabel() // MARK: Audio Source @@ -219,7 +219,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // Dark blurred background. let blurEffect = UIBlurEffect(style: .dark) - blurView = UIVisualEffectView(effect: blurEffect) + let blurView = UIVisualEffectView(effect: blurEffect) + self.blurView = blurView blurView.isUserInteractionEnabled = false self.view.addSubview(blurView) @@ -234,15 +235,22 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } func didTouchRootView(sender: UIGestureRecognizer) { + guard let remoteVideoView = remoteVideoView else { + owsFail("\(TAG) missing remoteVideoView.") + return + } if !remoteVideoView.isHidden { shouldRemoteVideoControlsBeHidden = !shouldRemoteVideoControlsBeHidden } } func createVideoViews() { - remoteVideoView = RemoteVideoView() + let remoteVideoView = RemoteVideoView() + self.remoteVideoView = remoteVideoView remoteVideoView.isUserInteractionEnabled = false - localVideoView = RTCCameraPreviewView() + + let localVideoView = RTCCameraPreviewView() + self.localVideoView = localVideoView remoteVideoView.isHidden = true localVideoView.isHidden = true @@ -251,8 +259,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } func createContactViews() { - contactNameLabel = MarqueeLabel() - // marquee config contactNameLabel.type = .continuous // This feels pretty slow when you're initially waiting for it, but when you're overlaying video calls, anything faster is distracting. @@ -272,7 +278,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, self.view.addSubview(contactNameLabel) - callStatusLabel = UILabel() callStatusLabel.font = UIFont.ows_regularFont(withSize: ScaleFromIPhone5To7Plus(19, 25)) callStatusLabel.textColor = UIColor.white callStatusLabel.layer.shadowOffset = CGSize.zero @@ -280,14 +285,11 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, callStatusLabel.layer.shadowRadius = 4 self.view.addSubview(callStatusLabel) - contactAvatarContainerView = UIView.container() self.view.addSubview(contactAvatarContainerView) - contactAvatarView = AvatarImageView() contactAvatarContainerView.addSubview(contactAvatarView) } func createSettingsNagViews() { - settingsNagView = UIView() settingsNagView.isHidden = true self.view.addSubview(settingsNagView) @@ -296,7 +298,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, viewStack.autoPinWidthToSuperview() viewStack.autoVCenterInSuperview() - settingsNagDescriptionLabel = UILabel() settingsNagDescriptionLabel.text = NSLocalizedString("CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL", comment: "Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy.") settingsNagDescriptionLabel.font = UIFont.ows_regularFont(withSize: ScaleFromIPhone5To7Plus(16, 18)) @@ -348,32 +349,38 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // textMessageButton = createButton(imageName:"message-active-wide", // action:#selector(didPressTextMessage)) - audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", - action: #selector(didPressAudioSource)) - audioSourceButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", - comment: "Accessibility label for selection the audio source") - - hangUpButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressHangup)) - hangUpButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_HANGUP_LABEL", - comment: "Accessibility label for hang up call") - - audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", - action: #selector(didPressMute)) - audioModeMuteButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_MUTE_LABEL", - comment: "Accessibility label for muting the microphone") - - videoModeMuteButton = createButton(imageName: "video-mute-unselected", - action: #selector(didPressMute)) - videoModeMuteButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone") - - audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", - action: #selector(didPressVideo)) - audioModeVideoButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call") - - videoModeVideoButton = createButton(imageName: "video-video-unselected", - action: #selector(didPressVideo)) - videoModeVideoButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only") + let audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", + action: #selector(didPressAudioSource), + accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", + comment: "Accessibility label for selection the audio source")) + self.audioSourceButton = audioSourceButton + + let hangUpButton = createButton(imageName: "hangup-active-wide", + action: #selector(didPressHangup), + accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", + comment: "Accessibility label for hang up call")) + self.hangUpButton = hangUpButton + + let audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", + comment: "Accessibility label for muting the microphone")) + self.audioModeMuteButton = audioModeMuteButton + + let videoModeMuteButton = createButton(imageName: "video-mute-unselected", + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) + self.videoModeMuteButton = videoModeMuteButton + + let audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) + self.audioModeMuteButton = audioModeVideoButton + + let videoModeVideoButton = createButton(imageName: "video-video-unselected", + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) + self.videoModeVideoButton = videoModeVideoButton setButtonSelectedImage(button: audioModeMuteButton, imageName: "audio-call-mute-active") setButtonSelectedImage(button: videoModeMuteButton, imageName: "video-mute-selected") @@ -425,14 +432,16 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createIncomingCallControls() { - acceptIncomingButton = createButton(imageName: "call-active-wide", - action: #selector(didPressAnswerCall)) - acceptIncomingButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", - comment: "Accessibility label for accepting incoming calls") - declineIncomingButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressDeclineCall)) - declineIncomingButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", - comment: "Accessibility label for declining incoming calls") + let acceptIncomingButton = createButton(imageName: "call-active-wide", + action: #selector(didPressAnswerCall), + accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", + comment: "Accessibility label for accepting incoming calls")) + self.acceptIncomingButton = acceptIncomingButton + let declineIncomingButton = createButton(imageName: "hangup-active-wide", + action: #selector(didPressDeclineCall), +accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", + comment: "Accessibility label for declining incoming calls")) + self.declineIncomingButton = declineIncomingButton incomingCallView = createContainerForCallControls(controlGroups: [ [acceptIncomingButton, declineIncomingButton ] @@ -451,19 +460,19 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, for row in rows { containerView.addSubview(row) row.autoHCenterInSuperview() - if prevRow != nil { - row.autoPinEdge(.top, to: .bottom, of: prevRow!, withOffset: rowspacing) + if let prevRow = prevRow { + row.autoPinEdge(.top, to: .bottom, of: prevRow, withOffset: rowspacing) } prevRow = row } containerView.setContentHuggingVerticalHigh() - rows.first!.autoPinEdge(toSuperviewEdge: .top) - rows.last!.autoPinEdge(toSuperviewEdge: .bottom) + rows.first?.autoPinEdge(toSuperviewEdge: .top) + rows.last?.autoPinEdge(toSuperviewEdge: .bottom) return containerView } - func createButton(imageName: String, action: Selector) -> UIButton { + func createButton(imageName: String, action: Selector, accessibilityLabel: String) -> UIButton { let image = UIImage(named: imageName) assert(image != nil) let button = UIButton() @@ -475,6 +484,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, button.addTarget(self, action: action, for: .touchUpInside) button.autoSetDimension(.width, toSize: buttonSize()) button.autoSetDimension(.height, toSize: buttonSize()) + button.accessibilityLabel = accessibilityLabel return button } @@ -493,11 +503,11 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, subview.setContentHuggingHorizontalHigh() subview.autoVCenterInSuperview() - if lastSubview != nil { + if let lastSubview = lastSubview { let spacer = UIView() spacer.isHidden = true row.addSubview(spacer) - spacer.autoPinEdge(.left, to: .right, of: lastSubview!) + spacer.autoPinEdge(.left, to: .right, of: lastSubview) spacer.autoPinEdge(.right, to: .left, of: subview) spacer.setContentHuggingHorizontalLow() spacer.autoVCenterInSuperview() @@ -512,8 +522,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, lastSubview = subview } - subviews.first!.autoPinEdge(toSuperviewEdge: .left) - subviews.last!.autoPinEdge(toSuperviewEdge: .right) + subviews.first?.autoPinEdge(toSuperviewEdge: .left) + subviews.last?.autoPinEdge(toSuperviewEdge: .right) } else if subviews.count == 1 { // If there's only one subview in this row, center it. let subview = subviews.first! @@ -528,6 +538,27 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: - Layout override func updateViewConstraints() { + guard let blurView = blurView else { + owsFail("\(TAG) missing blurView.") + return + } + guard let localVideoView = localVideoView else { + owsFail("\(TAG) missing localVideoView.") + return + } + guard let remoteVideoView = remoteVideoView else { + owsFail("\(TAG) missing remoteVideoView.") + return + } + guard let ongoingCallView = ongoingCallView else { + owsFail("\(TAG) missing ongoingCallView.") + return + } + guard let incomingCallView = incomingCallView else { + owsFail("\(TAG) missing incomingCallView.") + return + } + if !hasConstraints { // We only want to create our constraints once. // @@ -613,11 +644,19 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } internal func updateRemoteVideoLayout() { + guard let remoteVideoView = remoteVideoView else { + owsFail("\(TAG) missing remoteVideoView.") + return + } remoteVideoView.isHidden = !self.hasRemoteVideoTrack updateCallUI(callState: call.state) } internal func updateLocalVideoLayout() { + guard let localVideoView = localVideoView else { + owsFail("\(TAG) missing localVideoView.") + return + } NSLayoutConstraint.deactivate(self.localVideoConstraints) @@ -662,9 +701,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, let callDuration = call.connectionDuration() let callDurationDate = Date(timeIntervalSinceReferenceDate: callDuration) if dateFormatter == nil { - dateFormatter = DateFormatter() - dateFormatter!.dateFormat = "HH:mm:ss" - dateFormatter!.timeZone = TimeZone(identifier: "UTC")! + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "HH:mm:ss" + dateFormatter.timeZone = TimeZone(identifier: "UTC")! + self.dateFormatter = dateFormatter } var formattedDate = dateFormatter!.string(from: callDurationDate) if formattedDate.hasPrefix("00:") { @@ -707,29 +747,39 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func updateCallUI(callState: CallState) { assert(Thread.isMainThread) + + guard let remoteVideoView = remoteVideoView else { + owsFail("\(TAG) missing remoteVideoView.") + return + } + guard let localVideoView = localVideoView else { + owsFail("\(TAG) missing localVideoView.") + return + } + updateCallStatusLabel(callState: callState) if isShowingSettingsNag { settingsNagView.isHidden = false contactAvatarView.isHidden = true - ongoingCallView.isHidden = true + ongoingCallView?.isHidden = true return } // Marquee scrolling is distracting during a video call, disable it. contactNameLabel.labelize = call.hasLocalVideo - audioModeMuteButton.isSelected = call.isMuted - videoModeMuteButton.isSelected = call.isMuted - audioModeVideoButton.isSelected = call.hasLocalVideo - videoModeVideoButton.isSelected = call.hasLocalVideo + audioModeMuteButton?.isSelected = call.isMuted + videoModeMuteButton?.isSelected = call.isMuted + audioModeVideoButton?.isSelected = call.hasLocalVideo + videoModeVideoButton?.isSelected = call.hasLocalVideo // Show Incoming vs. Ongoing call controls let isRinging = callState == .localRinging - incomingCallView.isHidden = !isRinging - incomingCallView.isUserInteractionEnabled = isRinging - ongoingCallView.isHidden = isRinging - ongoingCallView.isUserInteractionEnabled = !isRinging + incomingCallView?.isHidden = !isRinging + incomingCallView?.isUserInteractionEnabled = isRinging + ongoingCallView?.isHidden = isRinging + ongoingCallView?.isUserInteractionEnabled = !isRinging // Rework control state if remote video is available. let hasRemoteVideo = !remoteVideoView.isHidden @@ -749,7 +799,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, if shouldRemoteVideoControlsBeHidden && !remoteVideoView.isHidden { contactNameLabel.isHidden = true callStatusLabel.isHidden = true - ongoingCallView.isHidden = true + ongoingCallView?.isHidden = true } else { contactNameLabel.isHidden = false callStatusLabel.isHidden = false @@ -759,24 +809,24 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, if self.hasAlternateAudioSources { // With bluetooth, button does not stay selected. Pressing it pops an actionsheet // and the button should immediately "unselect". - audioSourceButton.isSelected = false + audioSourceButton?.isSelected = false if hasLocalVideo { - audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .normal) - audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .selected) + audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .normal) + audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .selected) } else { - audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .normal) - audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .selected) + audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .normal) + audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .selected) } - audioSourceButton.isHidden = false + audioSourceButton?.isHidden = false } else { // No bluetooth audio detected - audioSourceButton.setImage(#imageLiteral(resourceName: "audio-call-speaker-inactive"), for: .normal) - audioSourceButton.setImage(#imageLiteral(resourceName: "audio-call-speaker-active"), for: .selected) + audioSourceButton?.setImage(#imageLiteral(resourceName: "audio-call-speaker-inactive"), for: .normal) + audioSourceButton?.setImage(#imageLiteral(resourceName: "audio-call-speaker-active"), for: .selected) // If there's no bluetooth, we always use speakerphone, so no need for // a button, giving more screen back for the video. - audioSourceButton.isHidden = hasLocalVideo + audioSourceButton?.isHidden = hasLocalVideo } // Dismiss Handling @@ -819,18 +869,18 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // before the operation completes. func updateAudioSourceButtonIsSelected() { guard callUIAdapter.audioService.isSpeakerphoneEnabled else { - self.audioSourceButton.isSelected = false + self.audioSourceButton?.isSelected = false return } // VideoChat mode enables the output speaker, but we don't // want to highlight the speaker button in that case. guard !call.hasLocalVideo else { - self.audioSourceButton.isSelected = false + self.audioSourceButton?.isSelected = false return } - self.audioSourceButton.isSelected = true + self.audioSourceButton?.isSelected = true } // MARK: - Actions @@ -936,7 +986,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, private func markSettingsNagAsComplete() { Logger.info("\(TAG) called \(#function)") - let preferences = Environment.current().preferences! + guard let preferences = Environment.current().preferences else { + owsFail("\(TAG) missing preferences.") + return + } preferences.setIsCallKitEnabled(preferences.isCallKitEnabled()) preferences.setIsCallKitPrivacyEnabled(preferences.isCallKitPrivacyEnabled()) @@ -1000,6 +1053,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, guard self.localVideoTrack != localVideoTrack else { return } + guard let localVideoView = localVideoView else { + owsFail("\(TAG) missing localVideoView.") + return + } self.localVideoTrack = localVideoTrack @@ -1023,6 +1080,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, guard self.remoteVideoTrack != remoteVideoTrack else { return } + guard let remoteVideoView = remoteVideoView else { + owsFail("\(TAG) missing remoteVideoView.") + return + } self.remoteVideoTrack?.remove(remoteVideoView) self.remoteVideoTrack = nil From 699bf0a8293bb1beb85926ec25d75d8ce886a688 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 13:28:33 -0400 Subject: [PATCH 2/7] Remove usage of ! in call view. --- .../ViewControllers/CallViewController.swift | 44 +++++++------------ 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index f25187afe..239824054 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -30,7 +30,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Views var hasConstraints = false - var blurView: UIVisualEffectView? + let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) var dateFormatter: DateFormatter? // MARK: Contact Views @@ -43,7 +43,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Ongoing Call Controls - var ongoingCallView: UIView? + let ongoingCallView = UIView() var hangUpButton: UIButton? var audioSourceButton: UIButton? @@ -58,7 +58,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Incoming Call Controls - var incomingCallView: UIView? + let incomingCallView = UIView() var acceptIncomingButton: UIButton? var declineIncomingButton: UIButton? @@ -218,9 +218,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, action: #selector(didTouchRootView))) // Dark blurred background. - let blurEffect = UIBlurEffect(style: .dark) - let blurView = UIVisualEffectView(effect: blurEffect) - self.blurView = blurView blurView.isUserInteractionEnabled = false self.view.addSubview(blurView) @@ -387,7 +384,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, setButtonSelectedImage(button: audioModeVideoButton, imageName: "audio-call-video-active") setButtonSelectedImage(button: videoModeVideoButton, imageName: "video-video-selected") - ongoingCallView = createContainerForCallControls(controlGroups: [ + createContainerForCallControls(containerView: ongoingCallView, + controlGroups: [ [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], [videoModeMuteButton, hangUpButton, videoModeVideoButton ] ]) @@ -443,13 +441,14 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", comment: "Accessibility label for declining incoming calls")) self.declineIncomingButton = declineIncomingButton - incomingCallView = createContainerForCallControls(controlGroups: [ + createContainerForCallControls(containerView: incomingCallView, + controlGroups: [ [acceptIncomingButton, declineIncomingButton ] ]) } - func createContainerForCallControls(controlGroups: [[UIView]]) -> UIView { - let containerView = UIView() + func createContainerForCallControls(containerView: UIView, + controlGroups: [[UIView]]) { self.view.addSubview(containerView) var rows: [UIView] = [] for controlGroup in controlGroups { @@ -469,7 +468,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", containerView.setContentHuggingVerticalHigh() rows.first?.autoPinEdge(toSuperviewEdge: .top) rows.last?.autoPinEdge(toSuperviewEdge: .bottom) - return containerView } func createButton(imageName: String, action: Selector, accessibilityLabel: String) -> UIButton { @@ -538,10 +536,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // MARK: - Layout override func updateViewConstraints() { - guard let blurView = blurView else { - owsFail("\(TAG) missing blurView.") - return - } guard let localVideoView = localVideoView else { owsFail("\(TAG) missing localVideoView.") return @@ -550,14 +544,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", owsFail("\(TAG) missing remoteVideoView.") return } - guard let ongoingCallView = ongoingCallView else { - owsFail("\(TAG) missing ongoingCallView.") - return - } - guard let incomingCallView = incomingCallView else { - owsFail("\(TAG) missing incomingCallView.") - return - } if !hasConstraints { // We only want to create our constraints once. @@ -762,7 +748,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if isShowingSettingsNag { settingsNagView.isHidden = false contactAvatarView.isHidden = true - ongoingCallView?.isHidden = true + ongoingCallView.isHidden = true return } @@ -776,10 +762,10 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // Show Incoming vs. Ongoing call controls let isRinging = callState == .localRinging - incomingCallView?.isHidden = !isRinging - incomingCallView?.isUserInteractionEnabled = isRinging - ongoingCallView?.isHidden = isRinging - ongoingCallView?.isUserInteractionEnabled = !isRinging + incomingCallView.isHidden = !isRinging + incomingCallView.isUserInteractionEnabled = isRinging + ongoingCallView.isHidden = isRinging + ongoingCallView.isUserInteractionEnabled = !isRinging // Rework control state if remote video is available. let hasRemoteVideo = !remoteVideoView.isHidden @@ -799,7 +785,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if shouldRemoteVideoControlsBeHidden && !remoteVideoView.isHidden { contactNameLabel.isHidden = true callStatusLabel.isHidden = true - ongoingCallView?.isHidden = true + ongoingCallView.isHidden = true } else { contactNameLabel.isHidden = false callStatusLabel.isHidden = false From 3cbd49627aedaa42974b2568f0fd8f9791ea7194 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 13:58:43 -0400 Subject: [PATCH 3/7] Remove usage of ! in call view. --- .../ViewControllers/CallViewController.swift | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index 239824054..7d9c7b750 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -52,9 +52,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, var videoModeMuteButton: UIButton? var videoModeVideoButton: UIButton? // TODO: Later, we'll re-enable the text message button - // so users can send and read messages during a + // so users can send and read messages during a // call. -// var textMessageButton: UIButton! + // var textMessageButton: UIButton! // MARK: Incoming Call Controls @@ -309,7 +309,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, let descriptionVSpacingHeight = ScaleFromIPhone5To7Plus(30, 60) let callSettingsButton = OWSFlatButton.button(title: NSLocalizedString("CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS", - comment: "Label for button that shows the privacy settings."), + comment: "Label for button that shows the privacy settings."), font: OWSFlatButton.fontForHeight(buttonHeight), titleColor: UIColor.white, backgroundColor: UIColor.ows_signalBrandBlue, @@ -321,7 +321,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, callSettingsButton.autoPinEdge(.top, to: .bottom, of: settingsNagDescriptionLabel, withOffset: descriptionVSpacingHeight) let notNowButton = OWSFlatButton.button(title: NSLocalizedString("CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON", - comment: "Label for button that dismiss the call view's settings nag."), + comment: "Label for button that dismiss the call view's settings nag."), font: OWSFlatButton.fontForHeight(buttonHeight), titleColor: UIColor.white, backgroundColor: UIColor.ows_signalBrandBlue, @@ -344,39 +344,39 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createOngoingCallControls() { -// textMessageButton = createButton(imageName:"message-active-wide", -// action:#selector(didPressTextMessage)) + // textMessageButton = createButton(imageName:"message-active-wide", + // action:#selector(didPressTextMessage)) let audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", - action: #selector(didPressAudioSource), - accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", - comment: "Accessibility label for selection the audio source")) + action: #selector(didPressAudioSource), + accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", + comment: "Accessibility label for selection the audio source")) self.audioSourceButton = audioSourceButton let hangUpButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressHangup), - accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", - comment: "Accessibility label for hang up call")) + action: #selector(didPressHangup), + accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", + comment: "Accessibility label for hang up call")) self.hangUpButton = hangUpButton let audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", - comment: "Accessibility label for muting the microphone")) + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", + comment: "Accessibility label for muting the microphone")) self.audioModeMuteButton = audioModeMuteButton let videoModeMuteButton = createButton(imageName: "video-mute-unselected", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) self.videoModeMuteButton = videoModeMuteButton let audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) self.audioModeMuteButton = audioModeVideoButton let videoModeVideoButton = createButton(imageName: "video-video-unselected", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) self.videoModeVideoButton = videoModeVideoButton setButtonSelectedImage(button: audioModeMuteButton, imageName: "audio-call-mute-active") @@ -386,9 +386,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, createContainerForCallControls(containerView: ongoingCallView, controlGroups: [ - [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], - [videoModeMuteButton, hangUpButton, videoModeVideoButton ] - ]) + [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], + [videoModeMuteButton, hangUpButton, videoModeVideoButton ] + ]) } func presentAudioSourcePicker() { @@ -431,19 +431,19 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createIncomingCallControls() { let acceptIncomingButton = createButton(imageName: "call-active-wide", - action: #selector(didPressAnswerCall), - accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", - comment: "Accessibility label for accepting incoming calls")) + action: #selector(didPressAnswerCall), + accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", + comment: "Accessibility label for accepting incoming calls")) self.acceptIncomingButton = acceptIncomingButton let declineIncomingButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressDeclineCall), -accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", - comment: "Accessibility label for declining incoming calls")) + action: #selector(didPressDeclineCall), + accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", + comment: "Accessibility label for declining incoming calls")) self.declineIncomingButton = declineIncomingButton createContainerForCallControls(containerView: incomingCallView, controlGroups: [ - [acceptIncomingButton, declineIncomingButton ] + [acceptIncomingButton, declineIncomingButton ] ]) } @@ -565,7 +565,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // The buttons have built-in 10% margins, so to appear centered // the avatar's bottom spacing should be a bit less. let avatarBottomSpacing = ScaleFromIPhone5To7Plus(18, 41) - // Layout of the local video view is a bit unusual because + // Layout of the local video view is a bit unusual because // although the view is square, it will be used let videoPreviewHMargin = CGFloat(0) @@ -830,10 +830,10 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if callDurationTimer == nil { let kDurationUpdateFrequencySeconds = 1 / 20.0 callDurationTimer = WeakTimer.scheduledTimer(timeInterval: TimeInterval(kDurationUpdateFrequencySeconds), - target: self, - userInfo: nil, - repeats: true) {[weak self] _ in - self?.updateCallDuration() + target: self, + userInfo: nil, + repeats: true) {[weak self] _ in + self?.updateCallDuration() } } } else { @@ -965,8 +965,8 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // We only show the "blocking" settings nag until the user has chosen // to view the privacy settings _or_ dismissed the nag at least once. - // - // In either case, we set the "CallKit enabled" and "CallKit privacy enabled" + // + // In either case, we set the "CallKit enabled" and "CallKit privacy enabled" // settings to their default values to indicate that the user has reviewed // them. private func markSettingsNagAsComplete() { From 594ddfaec3bef360541322ada7c5bf741abc9923 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 14:39:37 -0400 Subject: [PATCH 4/7] Revert "Remove usage of ! in call view." This reverts commit 3cbd49627aedaa42974b2568f0fd8f9791ea7194. --- .../ViewControllers/CallViewController.swift | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index 7d9c7b750..239824054 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -52,9 +52,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, var videoModeMuteButton: UIButton? var videoModeVideoButton: UIButton? // TODO: Later, we'll re-enable the text message button - // so users can send and read messages during a + // so users can send and read messages during a // call. - // var textMessageButton: UIButton! +// var textMessageButton: UIButton! // MARK: Incoming Call Controls @@ -309,7 +309,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, let descriptionVSpacingHeight = ScaleFromIPhone5To7Plus(30, 60) let callSettingsButton = OWSFlatButton.button(title: NSLocalizedString("CALL_VIEW_SETTINGS_NAG_SHOW_CALL_SETTINGS", - comment: "Label for button that shows the privacy settings."), + comment: "Label for button that shows the privacy settings."), font: OWSFlatButton.fontForHeight(buttonHeight), titleColor: UIColor.white, backgroundColor: UIColor.ows_signalBrandBlue, @@ -321,7 +321,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, callSettingsButton.autoPinEdge(.top, to: .bottom, of: settingsNagDescriptionLabel, withOffset: descriptionVSpacingHeight) let notNowButton = OWSFlatButton.button(title: NSLocalizedString("CALL_VIEW_SETTINGS_NAG_NOT_NOW_BUTTON", - comment: "Label for button that dismiss the call view's settings nag."), + comment: "Label for button that dismiss the call view's settings nag."), font: OWSFlatButton.fontForHeight(buttonHeight), titleColor: UIColor.white, backgroundColor: UIColor.ows_signalBrandBlue, @@ -344,39 +344,39 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createOngoingCallControls() { - // textMessageButton = createButton(imageName:"message-active-wide", - // action:#selector(didPressTextMessage)) +// textMessageButton = createButton(imageName:"message-active-wide", +// action:#selector(didPressTextMessage)) let audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", - action: #selector(didPressAudioSource), - accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", - comment: "Accessibility label for selection the audio source")) + action: #selector(didPressAudioSource), + accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", + comment: "Accessibility label for selection the audio source")) self.audioSourceButton = audioSourceButton let hangUpButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressHangup), - accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", - comment: "Accessibility label for hang up call")) + action: #selector(didPressHangup), + accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", + comment: "Accessibility label for hang up call")) self.hangUpButton = hangUpButton let audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", - comment: "Accessibility label for muting the microphone")) + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", + comment: "Accessibility label for muting the microphone")) self.audioModeMuteButton = audioModeMuteButton let videoModeMuteButton = createButton(imageName: "video-mute-unselected", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) + action: #selector(didPressMute), + accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) self.videoModeMuteButton = videoModeMuteButton let audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) self.audioModeMuteButton = audioModeVideoButton let videoModeVideoButton = createButton(imageName: "video-video-unselected", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) + action: #selector(didPressVideo), + accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) self.videoModeVideoButton = videoModeVideoButton setButtonSelectedImage(button: audioModeMuteButton, imageName: "audio-call-mute-active") @@ -386,9 +386,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, createContainerForCallControls(containerView: ongoingCallView, controlGroups: [ - [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], - [videoModeMuteButton, hangUpButton, videoModeVideoButton ] - ]) + [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], + [videoModeMuteButton, hangUpButton, videoModeVideoButton ] + ]) } func presentAudioSourcePicker() { @@ -431,19 +431,19 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createIncomingCallControls() { let acceptIncomingButton = createButton(imageName: "call-active-wide", - action: #selector(didPressAnswerCall), - accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", - comment: "Accessibility label for accepting incoming calls")) + action: #selector(didPressAnswerCall), + accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", + comment: "Accessibility label for accepting incoming calls")) self.acceptIncomingButton = acceptIncomingButton let declineIncomingButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressDeclineCall), - accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", - comment: "Accessibility label for declining incoming calls")) + action: #selector(didPressDeclineCall), +accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", + comment: "Accessibility label for declining incoming calls")) self.declineIncomingButton = declineIncomingButton createContainerForCallControls(containerView: incomingCallView, controlGroups: [ - [acceptIncomingButton, declineIncomingButton ] + [acceptIncomingButton, declineIncomingButton ] ]) } @@ -565,7 +565,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // The buttons have built-in 10% margins, so to appear centered // the avatar's bottom spacing should be a bit less. let avatarBottomSpacing = ScaleFromIPhone5To7Plus(18, 41) - // Layout of the local video view is a bit unusual because + // Layout of the local video view is a bit unusual because // although the view is square, it will be used let videoPreviewHMargin = CGFloat(0) @@ -830,10 +830,10 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, if callDurationTimer == nil { let kDurationUpdateFrequencySeconds = 1 / 20.0 callDurationTimer = WeakTimer.scheduledTimer(timeInterval: TimeInterval(kDurationUpdateFrequencySeconds), - target: self, - userInfo: nil, - repeats: true) {[weak self] _ in - self?.updateCallDuration() + target: self, + userInfo: nil, + repeats: true) {[weak self] _ in + self?.updateCallDuration() } } } else { @@ -965,8 +965,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // We only show the "blocking" settings nag until the user has chosen // to view the privacy settings _or_ dismissed the nag at least once. - // - // In either case, we set the "CallKit enabled" and "CallKit privacy enabled" + // + // In either case, we set the "CallKit enabled" and "CallKit privacy enabled" // settings to their default values to indicate that the user has reviewed // them. private func markSettingsNagAsComplete() { From 943b3f031c43bc4b838a0187712791f4eedd61a8 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 14:39:50 -0400 Subject: [PATCH 5/7] Revert "Remove usage of ! in call view." This reverts commit 699bf0a8293bb1beb85926ec25d75d8ce886a688. --- .../ViewControllers/CallViewController.swift | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index 239824054..f25187afe 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -30,7 +30,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Views var hasConstraints = false - let blurView = UIVisualEffectView(effect: UIBlurEffect(style: .dark)) + var blurView: UIVisualEffectView? var dateFormatter: DateFormatter? // MARK: Contact Views @@ -43,7 +43,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Ongoing Call Controls - let ongoingCallView = UIView() + var ongoingCallView: UIView? var hangUpButton: UIButton? var audioSourceButton: UIButton? @@ -58,7 +58,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Incoming Call Controls - let incomingCallView = UIView() + var incomingCallView: UIView? var acceptIncomingButton: UIButton? var declineIncomingButton: UIButton? @@ -218,6 +218,9 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, action: #selector(didTouchRootView))) // Dark blurred background. + let blurEffect = UIBlurEffect(style: .dark) + let blurView = UIVisualEffectView(effect: blurEffect) + self.blurView = blurView blurView.isUserInteractionEnabled = false self.view.addSubview(blurView) @@ -384,8 +387,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, setButtonSelectedImage(button: audioModeVideoButton, imageName: "audio-call-video-active") setButtonSelectedImage(button: videoModeVideoButton, imageName: "video-video-selected") - createContainerForCallControls(containerView: ongoingCallView, - controlGroups: [ + ongoingCallView = createContainerForCallControls(controlGroups: [ [audioModeMuteButton, audioSourceButton, audioModeVideoButton ], [videoModeMuteButton, hangUpButton, videoModeVideoButton ] ]) @@ -441,14 +443,13 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", comment: "Accessibility label for declining incoming calls")) self.declineIncomingButton = declineIncomingButton - createContainerForCallControls(containerView: incomingCallView, - controlGroups: [ + incomingCallView = createContainerForCallControls(controlGroups: [ [acceptIncomingButton, declineIncomingButton ] ]) } - func createContainerForCallControls(containerView: UIView, - controlGroups: [[UIView]]) { + func createContainerForCallControls(controlGroups: [[UIView]]) -> UIView { + let containerView = UIView() self.view.addSubview(containerView) var rows: [UIView] = [] for controlGroup in controlGroups { @@ -468,6 +469,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", containerView.setContentHuggingVerticalHigh() rows.first?.autoPinEdge(toSuperviewEdge: .top) rows.last?.autoPinEdge(toSuperviewEdge: .bottom) + return containerView } func createButton(imageName: String, action: Selector, accessibilityLabel: String) -> UIButton { @@ -536,6 +538,10 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // MARK: - Layout override func updateViewConstraints() { + guard let blurView = blurView else { + owsFail("\(TAG) missing blurView.") + return + } guard let localVideoView = localVideoView else { owsFail("\(TAG) missing localVideoView.") return @@ -544,6 +550,14 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", owsFail("\(TAG) missing remoteVideoView.") return } + guard let ongoingCallView = ongoingCallView else { + owsFail("\(TAG) missing ongoingCallView.") + return + } + guard let incomingCallView = incomingCallView else { + owsFail("\(TAG) missing incomingCallView.") + return + } if !hasConstraints { // We only want to create our constraints once. @@ -748,7 +762,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if isShowingSettingsNag { settingsNagView.isHidden = false contactAvatarView.isHidden = true - ongoingCallView.isHidden = true + ongoingCallView?.isHidden = true return } @@ -762,10 +776,10 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // Show Incoming vs. Ongoing call controls let isRinging = callState == .localRinging - incomingCallView.isHidden = !isRinging - incomingCallView.isUserInteractionEnabled = isRinging - ongoingCallView.isHidden = isRinging - ongoingCallView.isUserInteractionEnabled = !isRinging + incomingCallView?.isHidden = !isRinging + incomingCallView?.isUserInteractionEnabled = isRinging + ongoingCallView?.isHidden = isRinging + ongoingCallView?.isUserInteractionEnabled = !isRinging // Rework control state if remote video is available. let hasRemoteVideo = !remoteVideoView.isHidden @@ -785,7 +799,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if shouldRemoteVideoControlsBeHidden && !remoteVideoView.isHidden { contactNameLabel.isHidden = true callStatusLabel.isHidden = true - ongoingCallView.isHidden = true + ongoingCallView?.isHidden = true } else { contactNameLabel.isHidden = false callStatusLabel.isHidden = false From 621d54db1762e9c565251b5850483ab1ba472c45 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 14:39:59 -0400 Subject: [PATCH 6/7] Revert "Remove usage of ! in call view." This reverts commit ce197b0ada5600ba4d06e011ad18cf2da3a59a7f. --- .../ViewControllers/CallViewController.swift | 257 +++++++----------- 1 file changed, 98 insertions(+), 159 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index f25187afe..106c7ecac 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -30,27 +30,27 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Views var hasConstraints = false - var blurView: UIVisualEffectView? + var blurView: UIVisualEffectView! var dateFormatter: DateFormatter? // MARK: Contact Views - let contactNameLabel = MarqueeLabel() - let contactAvatarView = AvatarImageView() - let contactAvatarContainerView = UIView.container() - let callStatusLabel = UILabel() + var contactNameLabel: MarqueeLabel! + var contactAvatarView: AvatarImageView! + var contactAvatarContainerView: UIView! + var callStatusLabel: UILabel! var callDurationTimer: Timer? // MARK: Ongoing Call Controls - var ongoingCallView: UIView? + var ongoingCallView: UIView! - var hangUpButton: UIButton? - var audioSourceButton: UIButton? - var audioModeMuteButton: UIButton? - var audioModeVideoButton: UIButton? - var videoModeMuteButton: UIButton? - var videoModeVideoButton: UIButton? + var hangUpButton: UIButton! + var audioSourceButton: UIButton! + var audioModeMuteButton: UIButton! + var audioModeVideoButton: UIButton! + var videoModeMuteButton: UIButton! + var videoModeVideoButton: UIButton! // TODO: Later, we'll re-enable the text message button // so users can send and read messages during a // call. @@ -58,15 +58,15 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // MARK: Incoming Call Controls - var incomingCallView: UIView? + var incomingCallView: UIView! - var acceptIncomingButton: UIButton? - var declineIncomingButton: UIButton? + var acceptIncomingButton: UIButton! + var declineIncomingButton: UIButton! // MARK: Video Views - var remoteVideoView: RemoteVideoView? - var localVideoView: RTCCameraPreviewView? + var remoteVideoView: RemoteVideoView! + var localVideoView: RTCCameraPreviewView! weak var localVideoTrack: RTCVideoTrack? weak var remoteVideoTrack: RTCVideoTrack? var localVideoConstraints: [NSLayoutConstraint] = [] @@ -90,8 +90,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } } } - let settingsNagView = UIView() - let settingsNagDescriptionLabel = UILabel() + var settingsNagView: UIView! + var settingsNagDescriptionLabel: UILabel! // MARK: Audio Source @@ -219,8 +219,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // Dark blurred background. let blurEffect = UIBlurEffect(style: .dark) - let blurView = UIVisualEffectView(effect: blurEffect) - self.blurView = blurView + blurView = UIVisualEffectView(effect: blurEffect) blurView.isUserInteractionEnabled = false self.view.addSubview(blurView) @@ -235,22 +234,15 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } func didTouchRootView(sender: UIGestureRecognizer) { - guard let remoteVideoView = remoteVideoView else { - owsFail("\(TAG) missing remoteVideoView.") - return - } if !remoteVideoView.isHidden { shouldRemoteVideoControlsBeHidden = !shouldRemoteVideoControlsBeHidden } } func createVideoViews() { - let remoteVideoView = RemoteVideoView() - self.remoteVideoView = remoteVideoView + remoteVideoView = RemoteVideoView() remoteVideoView.isUserInteractionEnabled = false - - let localVideoView = RTCCameraPreviewView() - self.localVideoView = localVideoView + localVideoView = RTCCameraPreviewView() remoteVideoView.isHidden = true localVideoView.isHidden = true @@ -259,6 +251,8 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, } func createContactViews() { + contactNameLabel = MarqueeLabel() + // marquee config contactNameLabel.type = .continuous // This feels pretty slow when you're initially waiting for it, but when you're overlaying video calls, anything faster is distracting. @@ -278,6 +272,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, self.view.addSubview(contactNameLabel) + callStatusLabel = UILabel() callStatusLabel.font = UIFont.ows_regularFont(withSize: ScaleFromIPhone5To7Plus(19, 25)) callStatusLabel.textColor = UIColor.white callStatusLabel.layer.shadowOffset = CGSize.zero @@ -285,11 +280,14 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, callStatusLabel.layer.shadowRadius = 4 self.view.addSubview(callStatusLabel) + contactAvatarContainerView = UIView.container() self.view.addSubview(contactAvatarContainerView) + contactAvatarView = AvatarImageView() contactAvatarContainerView.addSubview(contactAvatarView) } func createSettingsNagViews() { + settingsNagView = UIView() settingsNagView.isHidden = true self.view.addSubview(settingsNagView) @@ -298,6 +296,7 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, viewStack.autoPinWidthToSuperview() viewStack.autoVCenterInSuperview() + settingsNagDescriptionLabel = UILabel() settingsNagDescriptionLabel.text = NSLocalizedString("CALL_VIEW_SETTINGS_NAG_DESCRIPTION_ALL", comment: "Reminder to the user of the benefits of enabling CallKit and disabling CallKit privacy.") settingsNagDescriptionLabel.font = UIFont.ows_regularFont(withSize: ScaleFromIPhone5To7Plus(16, 18)) @@ -349,38 +348,32 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, // textMessageButton = createButton(imageName:"message-active-wide", // action:#selector(didPressTextMessage)) - let audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", - action: #selector(didPressAudioSource), - accessibilityLabel: NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", - comment: "Accessibility label for selection the audio source")) - self.audioSourceButton = audioSourceButton - - let hangUpButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressHangup), - accessibilityLabel: NSLocalizedString("CALL_VIEW_HANGUP_LABEL", - comment: "Accessibility label for hang up call")) - self.hangUpButton = hangUpButton - - let audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", - comment: "Accessibility label for muting the microphone")) - self.audioModeMuteButton = audioModeMuteButton - - let videoModeMuteButton = createButton(imageName: "video-mute-unselected", - action: #selector(didPressMute), - accessibilityLabel: NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone")) - self.videoModeMuteButton = videoModeMuteButton - - let audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call")) - self.audioModeMuteButton = audioModeVideoButton - - let videoModeVideoButton = createButton(imageName: "video-video-unselected", - action: #selector(didPressVideo), - accessibilityLabel: NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only")) - self.videoModeVideoButton = videoModeVideoButton + audioSourceButton = createButton(imageName: "audio-call-speaker-inactive", + action: #selector(didPressAudioSource)) + audioSourceButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_AUDIO_SOURCE_LABEL", + comment: "Accessibility label for selection the audio source") + + hangUpButton = createButton(imageName: "hangup-active-wide", + action: #selector(didPressHangup)) + hangUpButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_HANGUP_LABEL", + comment: "Accessibility label for hang up call") + + audioModeMuteButton = createButton(imageName: "audio-call-mute-inactive", + action: #selector(didPressMute)) + audioModeMuteButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_MUTE_LABEL", + comment: "Accessibility label for muting the microphone") + + videoModeMuteButton = createButton(imageName: "video-mute-unselected", + action: #selector(didPressMute)) + videoModeMuteButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_MUTE_LABEL", comment: "Accessibility label for muting the microphone") + + audioModeVideoButton = createButton(imageName: "audio-call-video-inactive", + action: #selector(didPressVideo)) + audioModeVideoButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_SWITCH_TO_VIDEO_LABEL", comment: "Accessibility label to switch to video call") + + videoModeVideoButton = createButton(imageName: "video-video-unselected", + action: #selector(didPressVideo)) + videoModeVideoButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_SWITCH_TO_AUDIO_LABEL", comment: "Accessibility label to switch to audio only") setButtonSelectedImage(button: audioModeMuteButton, imageName: "audio-call-mute-active") setButtonSelectedImage(button: videoModeMuteButton, imageName: "video-mute-selected") @@ -432,16 +425,14 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, func createIncomingCallControls() { - let acceptIncomingButton = createButton(imageName: "call-active-wide", - action: #selector(didPressAnswerCall), - accessibilityLabel: NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", - comment: "Accessibility label for accepting incoming calls")) - self.acceptIncomingButton = acceptIncomingButton - let declineIncomingButton = createButton(imageName: "hangup-active-wide", - action: #selector(didPressDeclineCall), -accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", - comment: "Accessibility label for declining incoming calls")) - self.declineIncomingButton = declineIncomingButton + acceptIncomingButton = createButton(imageName: "call-active-wide", + action: #selector(didPressAnswerCall)) + acceptIncomingButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_ACCEPT_INCOMING_CALL_LABEL", + comment: "Accessibility label for accepting incoming calls") + declineIncomingButton = createButton(imageName: "hangup-active-wide", + action: #selector(didPressDeclineCall)) + declineIncomingButton.accessibilityLabel = NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", + comment: "Accessibility label for declining incoming calls") incomingCallView = createContainerForCallControls(controlGroups: [ [acceptIncomingButton, declineIncomingButton ] @@ -460,19 +451,19 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", for row in rows { containerView.addSubview(row) row.autoHCenterInSuperview() - if let prevRow = prevRow { - row.autoPinEdge(.top, to: .bottom, of: prevRow, withOffset: rowspacing) + if prevRow != nil { + row.autoPinEdge(.top, to: .bottom, of: prevRow!, withOffset: rowspacing) } prevRow = row } containerView.setContentHuggingVerticalHigh() - rows.first?.autoPinEdge(toSuperviewEdge: .top) - rows.last?.autoPinEdge(toSuperviewEdge: .bottom) + rows.first!.autoPinEdge(toSuperviewEdge: .top) + rows.last!.autoPinEdge(toSuperviewEdge: .bottom) return containerView } - func createButton(imageName: String, action: Selector, accessibilityLabel: String) -> UIButton { + func createButton(imageName: String, action: Selector) -> UIButton { let image = UIImage(named: imageName) assert(image != nil) let button = UIButton() @@ -484,7 +475,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", button.addTarget(self, action: action, for: .touchUpInside) button.autoSetDimension(.width, toSize: buttonSize()) button.autoSetDimension(.height, toSize: buttonSize()) - button.accessibilityLabel = accessibilityLabel return button } @@ -503,11 +493,11 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", subview.setContentHuggingHorizontalHigh() subview.autoVCenterInSuperview() - if let lastSubview = lastSubview { + if lastSubview != nil { let spacer = UIView() spacer.isHidden = true row.addSubview(spacer) - spacer.autoPinEdge(.left, to: .right, of: lastSubview) + spacer.autoPinEdge(.left, to: .right, of: lastSubview!) spacer.autoPinEdge(.right, to: .left, of: subview) spacer.setContentHuggingHorizontalLow() spacer.autoVCenterInSuperview() @@ -522,8 +512,8 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", lastSubview = subview } - subviews.first?.autoPinEdge(toSuperviewEdge: .left) - subviews.last?.autoPinEdge(toSuperviewEdge: .right) + subviews.first!.autoPinEdge(toSuperviewEdge: .left) + subviews.last!.autoPinEdge(toSuperviewEdge: .right) } else if subviews.count == 1 { // If there's only one subview in this row, center it. let subview = subviews.first! @@ -538,27 +528,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // MARK: - Layout override func updateViewConstraints() { - guard let blurView = blurView else { - owsFail("\(TAG) missing blurView.") - return - } - guard let localVideoView = localVideoView else { - owsFail("\(TAG) missing localVideoView.") - return - } - guard let remoteVideoView = remoteVideoView else { - owsFail("\(TAG) missing remoteVideoView.") - return - } - guard let ongoingCallView = ongoingCallView else { - owsFail("\(TAG) missing ongoingCallView.") - return - } - guard let incomingCallView = incomingCallView else { - owsFail("\(TAG) missing incomingCallView.") - return - } - if !hasConstraints { // We only want to create our constraints once. // @@ -644,19 +613,11 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", } internal func updateRemoteVideoLayout() { - guard let remoteVideoView = remoteVideoView else { - owsFail("\(TAG) missing remoteVideoView.") - return - } remoteVideoView.isHidden = !self.hasRemoteVideoTrack updateCallUI(callState: call.state) } internal func updateLocalVideoLayout() { - guard let localVideoView = localVideoView else { - owsFail("\(TAG) missing localVideoView.") - return - } NSLayoutConstraint.deactivate(self.localVideoConstraints) @@ -701,10 +662,9 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", let callDuration = call.connectionDuration() let callDurationDate = Date(timeIntervalSinceReferenceDate: callDuration) if dateFormatter == nil { - let dateFormatter = DateFormatter() - dateFormatter.dateFormat = "HH:mm:ss" - dateFormatter.timeZone = TimeZone(identifier: "UTC")! - self.dateFormatter = dateFormatter + dateFormatter = DateFormatter() + dateFormatter!.dateFormat = "HH:mm:ss" + dateFormatter!.timeZone = TimeZone(identifier: "UTC")! } var formattedDate = dateFormatter!.string(from: callDurationDate) if formattedDate.hasPrefix("00:") { @@ -747,39 +707,29 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", func updateCallUI(callState: CallState) { assert(Thread.isMainThread) - - guard let remoteVideoView = remoteVideoView else { - owsFail("\(TAG) missing remoteVideoView.") - return - } - guard let localVideoView = localVideoView else { - owsFail("\(TAG) missing localVideoView.") - return - } - updateCallStatusLabel(callState: callState) if isShowingSettingsNag { settingsNagView.isHidden = false contactAvatarView.isHidden = true - ongoingCallView?.isHidden = true + ongoingCallView.isHidden = true return } // Marquee scrolling is distracting during a video call, disable it. contactNameLabel.labelize = call.hasLocalVideo - audioModeMuteButton?.isSelected = call.isMuted - videoModeMuteButton?.isSelected = call.isMuted - audioModeVideoButton?.isSelected = call.hasLocalVideo - videoModeVideoButton?.isSelected = call.hasLocalVideo + audioModeMuteButton.isSelected = call.isMuted + videoModeMuteButton.isSelected = call.isMuted + audioModeVideoButton.isSelected = call.hasLocalVideo + videoModeVideoButton.isSelected = call.hasLocalVideo // Show Incoming vs. Ongoing call controls let isRinging = callState == .localRinging - incomingCallView?.isHidden = !isRinging - incomingCallView?.isUserInteractionEnabled = isRinging - ongoingCallView?.isHidden = isRinging - ongoingCallView?.isUserInteractionEnabled = !isRinging + incomingCallView.isHidden = !isRinging + incomingCallView.isUserInteractionEnabled = isRinging + ongoingCallView.isHidden = isRinging + ongoingCallView.isUserInteractionEnabled = !isRinging // Rework control state if remote video is available. let hasRemoteVideo = !remoteVideoView.isHidden @@ -799,7 +749,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if shouldRemoteVideoControlsBeHidden && !remoteVideoView.isHidden { contactNameLabel.isHidden = true callStatusLabel.isHidden = true - ongoingCallView?.isHidden = true + ongoingCallView.isHidden = true } else { contactNameLabel.isHidden = false callStatusLabel.isHidden = false @@ -809,24 +759,24 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", if self.hasAlternateAudioSources { // With bluetooth, button does not stay selected. Pressing it pops an actionsheet // and the button should immediately "unselect". - audioSourceButton?.isSelected = false + audioSourceButton.isSelected = false if hasLocalVideo { - audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .normal) - audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .selected) + audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .normal) + audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_video_mode"), for: .selected) } else { - audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .normal) - audioSourceButton?.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .selected) + audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .normal) + audioSourceButton.setImage(#imageLiteral(resourceName: "ic_speaker_bluetooth_inactive_audio_mode"), for: .selected) } - audioSourceButton?.isHidden = false + audioSourceButton.isHidden = false } else { // No bluetooth audio detected - audioSourceButton?.setImage(#imageLiteral(resourceName: "audio-call-speaker-inactive"), for: .normal) - audioSourceButton?.setImage(#imageLiteral(resourceName: "audio-call-speaker-active"), for: .selected) + audioSourceButton.setImage(#imageLiteral(resourceName: "audio-call-speaker-inactive"), for: .normal) + audioSourceButton.setImage(#imageLiteral(resourceName: "audio-call-speaker-active"), for: .selected) // If there's no bluetooth, we always use speakerphone, so no need for // a button, giving more screen back for the video. - audioSourceButton?.isHidden = hasLocalVideo + audioSourceButton.isHidden = hasLocalVideo } // Dismiss Handling @@ -869,18 +819,18 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", // before the operation completes. func updateAudioSourceButtonIsSelected() { guard callUIAdapter.audioService.isSpeakerphoneEnabled else { - self.audioSourceButton?.isSelected = false + self.audioSourceButton.isSelected = false return } // VideoChat mode enables the output speaker, but we don't // want to highlight the speaker button in that case. guard !call.hasLocalVideo else { - self.audioSourceButton?.isSelected = false + self.audioSourceButton.isSelected = false return } - self.audioSourceButton?.isSelected = true + self.audioSourceButton.isSelected = true } // MARK: - Actions @@ -986,10 +936,7 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", private func markSettingsNagAsComplete() { Logger.info("\(TAG) called \(#function)") - guard let preferences = Environment.current().preferences else { - owsFail("\(TAG) missing preferences.") - return - } + let preferences = Environment.current().preferences! preferences.setIsCallKitEnabled(preferences.isCallKitEnabled()) preferences.setIsCallKitPrivacyEnabled(preferences.isCallKitPrivacyEnabled()) @@ -1053,10 +1000,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", guard self.localVideoTrack != localVideoTrack else { return } - guard let localVideoView = localVideoView else { - owsFail("\(TAG) missing localVideoView.") - return - } self.localVideoTrack = localVideoTrack @@ -1080,10 +1023,6 @@ accessibilityLabel: NSLocalizedString("CALL_VIEW_DECLINE_INCOMING_CALL_LABEL", guard self.remoteVideoTrack != remoteVideoTrack else { return } - guard let remoteVideoView = remoteVideoView else { - owsFail("\(TAG) missing remoteVideoView.") - return - } self.remoteVideoTrack?.remove(remoteVideoView) self.remoteVideoTrack = nil From cc42e85bd6afd0fe350d6af68f2f3b3c153c0f98 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Wed, 18 Apr 2018 15:39:35 -0400 Subject: [PATCH 7/7] Avoid race condition in call view controller. --- .../ViewControllers/CallViewController.swift | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/Signal/src/ViewControllers/CallViewController.swift b/Signal/src/ViewControllers/CallViewController.swift index 106c7ecac..d9ed3dd01 100644 --- a/Signal/src/ViewControllers/CallViewController.swift +++ b/Signal/src/ViewControllers/CallViewController.swift @@ -140,17 +140,6 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, super.init(nibName: nil, bundle: nil) allAudioSources = Set(callUIAdapter.audioService.availableInputs) - - assert(callUIAdapter.audioService.delegate == nil) - callUIAdapter.audioService.delegate = self - observeNotifications() - } - - func observeNotifications() { - NotificationCenter.default.addObserver(self, - selector: #selector(didBecomeActive), - name: NSNotification.Name.OWSApplicationDidBecomeActive, - object: nil) } deinit { @@ -208,6 +197,14 @@ class CallViewController: OWSViewController, CallObserver, CallServiceObserver, call.addObserverAndSyncState(observer: self) SignalApp.shared().callService.addObserverAndSyncState(observer: self) + + assert(callUIAdapter.audioService.delegate == nil) + callUIAdapter.audioService.delegate = self + + NotificationCenter.default.addObserver(self, + selector: #selector(didBecomeActive), + name: NSNotification.Name.OWSApplicationDidBecomeActive, + object: nil) } // MARK: - Create Views