refactoring on showing call ip exposure

This commit is contained in:
ryanzhao 2021-11-11 12:12:12 +11:00
parent da14539639
commit 336c694b52
13 changed files with 94 additions and 79 deletions

View File

@ -21,12 +21,15 @@ extension SessionCallManager: CXProviderDelegate {
if let _ = CurrentAppContext().frontmostViewController() as? CallVC {
call.answerSessionCall()
} else {
let userDefaults = UserDefaults.standard
if userDefaults[.hasSeenCallIPExposureWarning] {
showCallVC()
} else {
showCallModal()
guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() } // TODO: Handle more gracefully
let callVC = CallVC(for: self.currentCall!)
callVC.shouldAnswer = true
if let conversationVC = presentingVC as? ConversationVC {
callVC.conversationVC = conversationVC
conversationVC.inputAccessoryView?.isHidden = true
conversationVC.inputAccessoryView?.alpha = 0
}
presentingVC.present(callVC, animated: true, completion: nil)
}
action.fulfill()
} else {

View File

@ -123,7 +123,7 @@ public final class SessionCallManager: NSObject {
callUpdate.supportsDTMF = false
}
public func handleIncomingCallOfferInBusyState(offerMessage: CallMessage, using transaction: YapDatabaseReadWriteTransaction) {
public func handleIncomingCallOfferInBusyOrUnenabledState(offerMessage: CallMessage, using transaction: YapDatabaseReadWriteTransaction) {
guard let caller = offerMessage.sender, let thread = TSContactThread.fetch(for: caller, using: transaction) else { return }
let message = CallMessage()
message.uuid = offerMessage.uuid
@ -134,27 +134,5 @@ public final class SessionCallManager: NSObject {
tsMessage.updateCall(withNewBody: NSLocalizedString("call_missing", comment: ""), transaction: transaction)
}
}
internal func showCallModal() {
let callModal = CallModal() { [weak self] in
self?.showCallVC()
}
callModal.modalPresentationStyle = .overFullScreen
callModal.modalTransitionStyle = .crossDissolve
guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() } // TODO: Handle more gracefully
presentingVC.present(callModal, animated: true, completion: nil)
}
internal func showCallVC() {
guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() } // TODO: Handle more gracefully
let callVC = CallVC(for: self.currentCall!)
callVC.shouldAnswer = true
if let conversationVC = presentingVC as? ConversationVC {
callVC.conversationVC = conversationVC
conversationVC.inputAccessoryView?.isHidden = true
conversationVC.inputAccessoryView?.alpha = 0
}
presentingVC.present(callVC, animated: true, completion: nil)
}
}

View File

@ -314,29 +314,14 @@ final class CallVC : UIViewController, VideoPreviewDelegate {
}
}
internal func showCallModal() {
let callModal = CallModal() { [weak self] in
self?.answerCall()
}
callModal.modalPresentationStyle = .overFullScreen
callModal.modalTransitionStyle = .crossDissolve
present(callModal, animated: true, completion: nil)
}
@objc private func answerCall() {
let userDefaults = UserDefaults.standard
if userDefaults[.hasSeenCallIPExposureWarning] {
AppEnvironment.shared.callManager.answerCall(call) { error in
DispatchQueue.main.async {
if let _ = error {
self.callInfoLabel.text = "Can't answer the call."
self.endCall()
}
AppEnvironment.shared.callManager.answerCall(call) { error in
DispatchQueue.main.async {
if let _ = error {
self.callInfoLabel.text = "Can't answer the call."
self.endCall()
}
}
} else {
userDefaults[.hasSeenCallIPExposureWarning] = true
showCallModal()
}
}

View File

@ -136,22 +136,7 @@ final class IncomingCallBanner: UIView, UIGestureRecognizerDelegate {
}
@objc private func answerCall() {
let userDefaults = UserDefaults.standard
if userDefaults[.hasSeenCallIPExposureWarning] {
showCallVC(answer: true)
} else {
showCallModal()
}
}
internal func showCallModal() {
let callModal = CallModal() { [weak self] in
self?.showCallVC(answer: true)
}
callModal.modalPresentationStyle = .overFullScreen
callModal.modalTransitionStyle = .crossDissolve
guard let presentingVC = CurrentAppContext().frontmostViewController() else { preconditionFailure() } // TODO: Handle more gracefully
presentingVC.present(callModal, animated: true, completion: nil)
showCallVC(answer: true)
}
@objc private func endCall() {

View File

@ -29,7 +29,10 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
// MARK: Call
@objc func startCall(_ sender: Any?) {
let userDefaults = UserDefaults.standard
if userDefaults[.hasSeenCallIPExposureWarning] {
if !SSKPreferences.areCallsEnabled && !userDefaults[.hasSeenCallIPExposureWarning] {
userDefaults[.hasSeenCallIPExposureWarning] = true
showCallModal()
} else if SSKPreferences.areCallsEnabled {
guard let contactSessionID = (thread as? TSContactThread)?.contactSessionID() else { return }
guard AppEnvironment.shared.callManager.currentCall == nil else { return }
let call = SessionCall(for: contactSessionID, uuid: UUID().uuidString, mode: .offer, outgoing: true)
@ -38,9 +41,6 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
self.inputAccessoryView?.isHidden = true
self.inputAccessoryView?.alpha = 0
present(callVC, animated: true, completion: nil)
} else {
userDefaults[.hasSeenCallIPExposureWarning] = true
showCallModal()
}
}
@ -48,8 +48,6 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
let callModal = CallModal() { [weak self] in
self?.startCall(nil)
}
callModal.modalPresentationStyle = .overFullScreen
callModal.modalTransitionStyle = .crossDissolve
present(callModal, animated: true, completion: nil)
}

View File

@ -309,8 +309,10 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
settingsButton.accessibilityLabel = "Settings button"
settingsButton.isAccessibilityElement = true
rightBarButtonItems.append(settingsButton)
let callButton = UIBarButtonItem(image: UIImage(named: "Phone")!, style: .plain, target: self, action: #selector(startCall))
rightBarButtonItems.append(callButton)
if SSKPreferences.areCallsEnabled || !UserDefaults.standard[.hasSeenCallIPExposureWarning] {
let callButton = UIBarButtonItem(image: UIImage(named: "Phone")!, style: .plain, target: self, action: #selector(startCall))
rightBarButtonItems.append(callButton)
}
} else {
let settingsButton = UIBarButtonItem(image: UIImage(named: "Gear"), style: .plain, target: self, action: #selector(openSettings))
settingsButton.accessibilityLabel = "Settings button"

View File

@ -1,11 +1,15 @@
@objc
final class CallModal : Modal {
private let onCallEnabled: () -> Void
// MARK: Lifecycle
@objc
init(onCallEnabled: @escaping () -> Void) {
self.onCallEnabled = onCallEnabled
super.init(nibName: nil, bundle: nil)
self.modalPresentationStyle = .overFullScreen
self.modalTransitionStyle = .crossDissolve
}
required init?(coder: NSCoder) {
@ -59,6 +63,7 @@ final class CallModal : Modal {
// MARK: Interaction
@objc private func enable() {
SSKPreferences.areCallsEnabled = true
presentingViewController?.dismiss(animated: true, completion: nil)
onCallEnabled()
}

View File

@ -25,8 +25,8 @@ extension AppDelegate {
MessageReceiver.handlePreOfferCallMessage = { (message, transaction) in
guard CurrentAppContext().isMainApp else { return }
let callManager = AppEnvironment.shared.callManager
guard callManager.currentCall == nil else {
callManager.handleIncomingCallOfferInBusyState(offerMessage: message, using: transaction)
guard callManager.currentCall == nil || !SSKPreferences.areCallsEnabled else {
callManager.handleIncomingCallOfferInBusyOrUnenabledState(offerMessage: message, using: transaction)
return
}
DispatchQueue.main.async {

View File

@ -350,6 +350,12 @@
"SETTINGS_LINK_PREVIEWS_FOOTER" = "Previews are supported for most urls.";
/* Header for setting for enabling & disabling link previews. */
"SETTINGS_LINK_PREVIEWS_HEADER" = "Link Previews";
/* Setting for enabling & disabling voice & video calls. */
"SETTINGS_CALLS" = "Voice and video calls";
/* Footer for setting for enabling & disabling voice & video calls. */
"SETTINGS_CALLS_FOOTER" = "Allow access to accept voice and video calls from other users.";
/* Header for setting for enabling & disabling voice & video calls. */
"SETTINGS_CALLS_HEADER" = "Calls";
/* table section header */
"SETTINGS_NOTIFICATION_CONTENT_TITLE" = "Notification Content";
/* Label for the 'read receipts' setting. */

View File

@ -197,6 +197,25 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
linkPreviewsSection.footerTitle = NSLocalizedString(
@"SETTINGS_LINK_PREVIEWS_FOOTER", @"Footer for setting for enabling & disabling link previews.");
[contents addSection:linkPreviewsSection];
OWSTableSection *callsSection = [OWSTableSection new];
[callsSection
addItem:[OWSTableItem switchItemWithText:NSLocalizedString(@"SETTINGS_CALLS",
@"Setting for enabling & disabling voice & video calls.")
accessibilityIdentifier:[NSString stringWithFormat:@"settings.privacy.%@", @"calls"]
isOnBlock:^{
return [SSKPreferences areCallsEnabled];
}
isEnabledBlock:^{
return YES;
}
target:weakSelf
selector:@selector(didToggleCallsEnabled:)]];
callsSection.headerTitle = NSLocalizedString(
@"SETTINGS_CALLS_HEADER", @"Header for setting for enabling & disabling voice & video calls.");
callsSection.footerTitle = NSLocalizedString(
@"SETTINGS_CALLS_FOOTER", @"Footer for setting for enabling & disabling voice & video calls.");
[contents addSection:callsSection];
self.contents = contents;
}
@ -260,6 +279,22 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
SSKPreferences.areLinkPreviewsEnabled = enabled;
}
- (void)didToggleCallsEnabled:(UISwitch *)sender
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
BOOL enabled = sender.isOn;
if (enabled && ![userDefaults boolForKey:@"hasSeenCallIPExposureWarning"]) {
[userDefaults setBool:YES forKey:@"hasSeenCallIPExposureWarning"];
CallModal *modal = [[CallModal alloc] initOnCallEnabled:^{
OWSLogInfo(@"toggled to: %@", (enabled ? @"ON" : @"OFF"));
}];
[self presentViewController:modal animated:YES completion:nil];
} else {
OWSLogInfo(@"toggled to: %@", (enabled ? @"ON" : @"OFF"));
SSKPreferences.areCallsEnabled = enabled;
}
}
- (void)isScreenLockEnabledDidChange:(UISwitch *)sender
{
BOOL shouldBeEnabled = sender.isOn;

View File

@ -24,6 +24,19 @@ public class SSKPreferences: NSObject {
setBool(newValue, key: areLinkPreviewsEnabledKey)
}
}
// MARK: -
private static let areCallsEnabledKey = "areCallsEnabled"
@objc
public static var areCallsEnabled: Bool {
get {
return getBool(key: areCallsEnabledKey, defaultValue: false)
}
set {
setBool(newValue, key: areCallsEnabledKey)
}
}
// MARK: -

View File

@ -267,12 +267,14 @@ extension MessageReceiver {
switch message.kind! {
case .preOffer:
print("[Calls] Received pre-offer message.")
let storage = SNMessagingKitConfiguration.shared.storage
let transaction = transaction as! YapDatabaseReadWriteTransaction
if let threadID = storage.getOrCreateThread(for: message.sender!, groupPublicKey: message.groupPublicKey, openGroupID: nil, using: transaction),
let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) {
let tsMessage = TSIncomingMessage.from(message, associatedWith: thread)
tsMessage.save(with: transaction)
if SSKPreferences.areCallsEnabled {
let storage = SNMessagingKitConfiguration.shared.storage
if let threadID = storage.getOrCreateThread(for: message.sender!, groupPublicKey: message.groupPublicKey, openGroupID: nil, using: transaction),
let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) {
let tsMessage = TSIncomingMessage.from(message, associatedWith: thread)
tsMessage.save(with: transaction)
}
}
handlePreOfferCallMessage?(message, transaction)
case .offer:

View File

@ -92,6 +92,9 @@ public final class NotificationServiceExtension : UNNotificationServiceExtension
}
case let callMessage as CallMessage:
MessageReceiver.handleCallMessage(callMessage, using: transaction)
if !SSKPreferences.areCallsEnabled {
return self.completeSilenty()
}
notificationContent.userInfo = userInfo
notificationContent.badge = 1
notificationContent.title = "Session"