Instrument CallService.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 90945609e5
commit 958a8b4c80

@ -46,6 +46,7 @@
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/NSTimer+OWS.h>
#import <SignalServiceKit/OWSAcknowledgeMessageDeliveryRequest.h>
#import <SignalServiceKit/OWSAnalytics.h>
#import <SignalServiceKit/OWSAttachmentsProcessor.h>
#import <SignalServiceKit/OWSCallAnswerMessage.h>
#import <SignalServiceKit/OWSCallBusyMessage.h>

@ -81,6 +81,18 @@ enum CallError: Error {
// Should be roughly synced with Android client for consistency
fileprivate let connectingTimeoutSeconds = 120
// Example: OWSProdError("blah", #file, #function, #line)
func OWSProdError(_ __eventName: String, file __file: String, function __function: String, line __line: Int32) {
let location = "\((__file as NSString).lastPathComponent):\(__function)"
OWSAnalytics
.logEvent(__eventName, severity: .error, parameters: nil, location: (location as NSString).utf8String!, line:__line)
}
func OWSProdCallAssertionError(description: String) -> CallError {
OWSProdError(description, file:#file, function:#function, line:#line)
return .assertionError(description: description)
}
// All Observer methods will be invoked from the main thread.
protocol CallServiceObserver: class {
/**
@ -273,7 +285,7 @@ protocol CallServiceObserver: class {
let errorDescription = "\(TAG) call was unexpectedly already set."
Logger.error(errorDescription)
call.state = .localFailure
return Promise(error: CallError.assertionError(description: errorDescription))
return Promise(error: OWSProdCallAssertionError(description: errorDescription))
}
self.call = call
@ -295,7 +307,7 @@ protocol CallServiceObserver: class {
guard self.peerConnectionClient == nil else {
let errorDescription = "\(self.TAG) peerconnection was unexpectedly already set."
Logger.error(errorDescription)
throw CallError.assertionError(description: errorDescription)
throw OWSProdCallAssertionError(description: errorDescription)
}
let useTurnOnly = Environment.getCurrent().preferences.doCallsHideIPAddress()
@ -371,7 +383,7 @@ protocol CallServiceObserver: class {
}
guard let fulfillReadyToSendIceUpdatesPromise = self.fulfillReadyToSendIceUpdatesPromise else {
self.handleFailedCall(failedCall: call, error: .assertionError(description: "failed to create fulfillReadyToSendIceUpdatesPromise"))
self.handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description: "failed to create fulfillReadyToSendIceUpdatesPromise"))
return
}
@ -409,7 +421,7 @@ protocol CallServiceObserver: class {
}
guard let peerConnectionClient = self.peerConnectionClient else {
handleFailedCall(failedCall: call, error: CallError.assertionError(description: "peerConnectionClient was unexpectedly nil in \(#function)"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description: "peerConnectionClient was unexpectedly nil in \(#function)"))
return
}
@ -697,7 +709,7 @@ protocol CallServiceObserver: class {
AssertIsOnMainThread()
guard let call = self.call else {
self.handleFailedCurrentCall(error: .assertionError(description: "ignoring local ice candidate, since there is no current call."))
self.handleFailedCurrentCall(error: OWSProdCallAssertionError(description: "ignoring local ice candidate, since there is no current call."))
return
}
@ -712,7 +724,7 @@ protocol CallServiceObserver: class {
guard call.state != .idle else {
// This will only be called for the current peerConnectionClient, so
// fail the current call.
self.handleFailedCurrentCall(error: .assertionError(description: "ignoring local ice candidate, since call is now idle."))
self.handleFailedCurrentCall(error: OWSProdCallAssertionError(description: "ignoring local ice candidate, since call is now idle."))
return
}
@ -748,7 +760,7 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This will only be called for the current peerConnectionClient, so
// fail the current call.
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) ignoring \(#function) since there is no current call."))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) ignoring \(#function) since there is no current call."))
return
}
@ -817,14 +829,14 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This should never happen; return to a known good state.
owsFail("\(TAG) call was unexpectedly nil in \(#function)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) call was unexpectedly nil in \(#function)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) call was unexpectedly nil in \(#function)"))
return
}
guard call.localId == localId else {
// This should never happen; return to a known good state.
owsFail("\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)"))
return
}
@ -840,7 +852,7 @@ protocol CallServiceObserver: class {
Logger.debug("\(TAG) in \(#function)")
guard let currentCall = self.call else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) ignoring \(#function) since there is no current call"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) ignoring \(#function) since there is no current call"))
return
}
@ -852,7 +864,7 @@ protocol CallServiceObserver: class {
}
guard let peerConnectionClient = self.peerConnectionClient else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) missing peerconnection client in \(#function)"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) missing peerconnection client in \(#function)"))
return
}
@ -877,7 +889,7 @@ protocol CallServiceObserver: class {
AssertIsOnMainThread()
guard let peerConnectionClient = self.peerConnectionClient else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) peerConnectionClient unexpectedly nil in \(#function)"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) peerConnectionClient unexpectedly nil in \(#function)"))
return
}
@ -907,14 +919,14 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This should never happen; return to a known good state.
owsFail("\(TAG) call was unexpectedly nil in \(#function)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) call was unexpectedly nil in \(#function)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) call was unexpectedly nil in \(#function)"))
return
}
guard call.localId == localId else {
// This should never happen; return to a known good state.
owsFail("\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) callLocalId:\(localId) doesn't match current calls: \(call.localId)"))
return
}
@ -953,17 +965,17 @@ protocol CallServiceObserver: class {
AssertIsOnMainThread()
guard let currentCall = self.call else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) ignoring \(#function) since there is no current call"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) ignoring \(#function) since there is no current call"))
return
}
guard call == currentCall else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) ignoring \(#function) for call other than current call"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) ignoring \(#function) for call other than current call"))
return
}
guard let peerConnectionClient = self.peerConnectionClient else {
handleFailedCall(failedCall: call, error: .assertionError(description:"\(TAG) missing peerconnection client in \(#function)"))
handleFailedCall(failedCall: call, error: OWSProdCallAssertionError(description:"\(TAG) missing peerconnection client in \(#function)"))
return
}
@ -1003,7 +1015,7 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This should never happen; return to a known good state.
owsFail("\(TAG) call was unexpectedly nil in \(#function)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) call unexpectedly nil in \(#function)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) call unexpectedly nil in \(#function)"))
return
}
@ -1057,7 +1069,7 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This should never happen; return to a known good state.
owsFail("\(TAG) call was unexpectedly nil in \(#function)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) call unexpectedly nil in \(#function)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) call unexpectedly nil in \(#function)"))
return
}
@ -1095,7 +1107,7 @@ protocol CallServiceObserver: class {
guard let call = self.call else {
// This should never happen; return to a known good state.
owsFail("\(TAG) received data message, but there is no current call. Ignoring.")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) received data message, but there is no current call. Ignoring."))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) received data message, but there is no current call. Ignoring."))
return
}
@ -1107,7 +1119,7 @@ protocol CallServiceObserver: class {
guard connected.id == call.signalingId else {
// This should never happen; return to a known good state.
owsFail("\(TAG) received connected message for call with id:\(connected.id) but current call has id:\(call.signalingId)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) received connected message for call with id:\(connected.id) but current call has id:\(call.signalingId)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) received connected message for call with id:\(connected.id) but current call has id:\(call.signalingId)"))
return
}
@ -1122,7 +1134,7 @@ protocol CallServiceObserver: class {
guard hangup.id == call.signalingId else {
// This should never happen; return to a known good state.
owsFail("\(TAG) received hangup message for call with id:\(hangup.id) but current call has id:\(call.signalingId)")
handleFailedCurrentCall(error: .assertionError(description:"\(TAG) received hangup message for call with id:\(hangup.id) but current call has id:\(call.signalingId)"))
handleFailedCurrentCall(error: OWSProdCallAssertionError(description:"\(TAG) received hangup message for call with id:\(hangup.id) but current call has id:\(call.signalingId)"))
return
}
@ -1229,7 +1241,7 @@ protocol CallServiceObserver: class {
}
guard let readyToSendIceUpdatesPromise = self.readyToSendIceUpdatesPromise else {
return Promise(error: CallError.assertionError(description: "failed to create readyToSendIceUpdatesPromise"))
return Promise(error: OWSProdCallAssertionError(description: "failed to create readyToSendIceUpdatesPromise"))
}
return readyToSendIceUpdatesPromise
@ -1272,7 +1284,7 @@ protocol CallServiceObserver: class {
}
guard let peerConnectionClientPromise = self.peerConnectionClientPromise else {
return Promise(error: CallError.assertionError(description: "failed to create peerConnectionClientPromise"))
return Promise(error: OWSProdCallAssertionError(description: "failed to create peerConnectionClientPromise"))
}
return peerConnectionClientPromise

@ -83,12 +83,12 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
// parametersBlock is of type OWSProdAssertParametersBlock.
// The "C" variants (e.g. OWSProdAssert() vs. OWSProdCAssert() should be used in free functions,
// where there is no self. They can also be used in blocks to avoid capturing a reference to self.
#define OWSProdAssertWParamsTemplate(__value, __analyticsEventName, __parametersBlock, __assertMacro) \
#define OWSProdAssertWParamsTemplate(__value, __eventName, __parametersBlock, __assertMacro) \
{ \
if (!(BOOL)(__value)) { \
NSDictionary<NSString *, id> *__eventParameters = (__parametersBlock ? __parametersBlock() : nil); \
[DDLog flushLog]; \
[OWSAnalytics logEvent:__analyticsEventName \
[OWSAnalytics logEvent:__eventName \
severity:OWSAnalyticsSeverityError \
parameters:__eventParameters \
location:__PRETTY_FUNCTION__ \
@ -98,64 +98,64 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
return (BOOL)(__value); \
}
#define OWSProdAssertWParams(__value, __analyticsEventName, __parametersBlock) \
OWSProdAssertWParamsTemplate(__value, __analyticsEventName, __parametersBlock, OWSAssert)
#define OWSProdAssertWParams(__value, __eventName, __parametersBlock) \
OWSProdAssertWParamsTemplate(__value, __eventName, __parametersBlock, OWSAssert)
#define OWSProdCAssertWParams(__value, __analyticsEventName, __parametersBlock) \
OWSProdAssertWParamsTemplate(__value, __analyticsEventName, __parametersBlock, OWSCAssert)
#define OWSProdCAssertWParams(__value, __eventName, __parametersBlock) \
OWSProdAssertWParamsTemplate(__value, __eventName, __parametersBlock, OWSCAssert)
#define OWSProdAssert(__value, __analyticsEventName) OWSProdAssertWParams(__value, __analyticsEventName, nil)
#define OWSProdAssert(__value, __eventName) OWSProdAssertWParams(__value, __eventName, nil)
#define OWSProdCAssert(__value, __analyticsEventName) OWSProdCAssertWParams(__value, __analyticsEventName, nil)
#define OWSProdCAssert(__value, __eventName) OWSProdCAssertWParams(__value, __eventName, nil)
#define OWSProdFailWParamsTemplate(__analyticsEventName, __parametersBlock, __failMacro) \
#define OWSProdFailWParamsTemplate(__eventName, __parametersBlock, __failMacro) \
{ \
NSDictionary<NSString *, id> *__eventParameters \
= (__parametersBlock ? ((OWSProdAssertParametersBlock)__parametersBlock)() : nil); \
[OWSAnalytics logEvent:__analyticsEventName \
[OWSAnalytics logEvent:__eventName \
severity:OWSAnalyticsSeverityCritical \
parameters:__eventParameters \
location:__PRETTY_FUNCTION__ \
line:__LINE__]; \
__failMacro(__analyticsEventName); \
__failMacro(__eventName); \
}
#define OWSProdFailWParams(__analyticsEventName, __parametersBlock) \
OWSProdFailWParamsTemplate(__analyticsEventName, __parametersBlock, OWSFail)
#define OWSProdCFailWParams(__analyticsEventName, __parametersBlock) \
OWSProdFailWParamsTemplate(__analyticsEventName, __parametersBlock, OWSCFail)
#define OWSProdFailWParams(__eventName, __parametersBlock) \
OWSProdFailWParamsTemplate(__eventName, __parametersBlock, OWSFail)
#define OWSProdCFailWParams(__eventName, __parametersBlock) \
OWSProdFailWParamsTemplate(__eventName, __parametersBlock, OWSCFail)
#define OWSProdFail(__analyticsEventName) OWSProdFailWParams(__analyticsEventName, nil)
#define OWSProdFail(__eventName) OWSProdFailWParams(__eventName, nil)
#define OWSProdCFail(__analyticsEventName) OWSProdCFailWParams(__analyticsEventName, nil)
#define OWSProdCFail(__eventName) OWSProdCFailWParams(__eventName, nil)
// The debug logs can be more verbose than the analytics events.
//
// In this case `debugDescription` is valuable enough to
// log but too dangerous to include in the analytics event.
#define OWSProdFailWNSError(__analyticsEventName, __nserror) \
#define OWSProdFailWNSError(__eventName, __nserror) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __nserror.debugDescription); \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __nserror.debugDescription); \
OWSProdFailWParams(__eventName, AnalyticsParametersFromNSError(__nserror)) \
}
// The debug logs can be more verbose than the analytics events.
//
// In this case `exception` is valuable enough to
// log but too dangerous to include in the analytics event.
#define OWSProdFailWNSException(__analyticsEventName, __exception) \
#define OWSProdFailWNSException(__eventName, __exception) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __exception); \
OWSProdFailWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __exception); \
OWSProdFailWParams(__eventName, AnalyticsParametersFromNSException(__exception)) \
}
#define OWSProdCFail(__analyticsEventName) OWSProdCFailWParams(__analyticsEventName, nil)
#define OWSProdCFail(__eventName) OWSProdCFailWParams(__eventName, nil)
#define OWSProdEventWParams(__severityLevel, __analyticsEventName, __parametersBlock) \
#define OWSProdEventWParams(__severityLevel, __eventName, __parametersBlock) \
{ \
NSDictionary<NSString *, id> *__eventParameters \
= (__parametersBlock ? ((OWSProdAssertParametersBlock)__parametersBlock)() : nil); \
[OWSAnalytics logEvent:__analyticsEventName \
[OWSAnalytics logEvent:__eventName \
severity:__severityLevel \
parameters:__eventParameters \
location:__PRETTY_FUNCTION__ \
@ -164,60 +164,59 @@ typedef NSDictionary<NSString *, id> *_Nonnull (^OWSProdAssertParametersBlock)()
#pragma mark - Info Events
#define OWSProdInfoWParams(__analyticsEventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityInfo, __analyticsEventName, __parametersBlock)
#define OWSProdInfoWParams(__eventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityInfo, __eventName, __parametersBlock)
#define OWSProdInfo(__analyticsEventName) OWSProdEventWParams(OWSAnalyticsSeverityInfo, __analyticsEventName, nil)
#define OWSProdInfo(__eventName) OWSProdEventWParams(OWSAnalyticsSeverityInfo, __eventName, nil)
#pragma mark - Error Events
#define OWSProdErrorWParams(__analyticsEventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityError, __analyticsEventName, __parametersBlock)
#define OWSProdErrorWParams(__eventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityError, __eventName, __parametersBlock)
#define OWSProdError(__analyticsEventName) OWSProdEventWParams(OWSAnalyticsSeverityError, __analyticsEventName, nil)
#define OWSProdError(__eventName) OWSProdEventWParams(OWSAnalyticsSeverityError, __eventName, nil)
// The debug logs can be more verbose than the analytics events.
//
// In this case `debugDescription` is valuable enough to
// log but too dangerous to include in the analytics event.
#define OWSProdErrorWNSError(__analyticsEventName, __nserror) \
#define OWSProdErrorWNSError(__eventName, __nserror) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __nserror.debugDescription); \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __nserror.debugDescription); \
OWSProdErrorWParams(__eventName, AnalyticsParametersFromNSError(__nserror)) \
}
// The debug logs can be more verbose than the analytics events.
//
// In this case `exception` is valuable enough to
// log but too dangerous to include in the analytics event.
#define OWSProdErrorWNSException(__analyticsEventName, __exception) \
#define OWSProdErrorWNSException(__eventName, __exception) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __exception); \
OWSProdErrorWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __exception); \
OWSProdErrorWParams(__eventName, AnalyticsParametersFromNSException(__exception)) \
}
#pragma mark - Critical Events
#define OWSProdCriticalWParams(__analyticsEventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityCritical, __analyticsEventName, __parametersBlock)
#define OWSProdCriticalWParams(__eventName, __parametersBlock) \
OWSProdEventWParams(OWSAnalyticsSeverityCritical, __eventName, __parametersBlock)
#define OWSProdCritical(__analyticsEventName) \
OWSProdEventWParams(OWSAnalyticsSeverityCritical, __analyticsEventName, nil)
#define OWSProdCritical(__eventName) OWSProdEventWParams(OWSAnalyticsSeverityCritical, __eventName, nil)
#define OWSProdCriticalWNSError(__analyticsEventName, __nserror) \
#define OWSProdCriticalWNSError(__eventName, __nserror) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __nserror.debugDescription); \
OWSProdCriticalWParams(__analyticsEventName, AnalyticsParametersFromNSError(__nserror)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __nserror.debugDescription); \
OWSProdCriticalWParams(__eventName, AnalyticsParametersFromNSError(__nserror)) \
}
// The debug logs can be more verbose than the analytics events.
//
// In this case `exception` is valuable enough to
// log but too dangerous to include in the analytics event.
#define OWSProdCriticalWNSException(__analyticsEventName, __exception) \
#define OWSProdCriticalWNSException(__eventName, __exception) \
{ \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __analyticsEventName, __exception); \
OWSProdCriticalWParams(__analyticsEventName, AnalyticsParametersFromNSException(__exception)) \
DDLogError(@"%s:%d %@: %@", __PRETTY_FUNCTION__, __LINE__, __eventName, __exception); \
OWSProdCriticalWParams(__eventName, AnalyticsParametersFromNSException(__exception)) \
}
NS_ASSUME_NONNULL_END

Loading…
Cancel
Save