From 1fb808169f035f4e822d794b189f4c8657e07f89 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 09:53:57 -0500 Subject: [PATCH 001/152] video streaming manager stop method fixed --- SmartDeviceLink/SDLLifecycleManager.m | 1 + .../SDLStreamingVideoLifecycleManager.m | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 53f2059ac..46e813212 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -269,6 +269,7 @@ - (void)sdl_stopManager:(BOOL)shouldRestart { [self.lockScreenManager stop]; [self.screenManager stop]; [self.encryptionLifecycleManager stop]; + [self.streamManager stop]; if (self.secondaryTransportManager != nil) { [self.secondaryTransportManager stop]; } else { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 92801dc8e..1c5a3df3f 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -191,8 +191,7 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { } - (void)stop { - SDLLogD(@"Stopping manager"); - [self sdl_stopVideoSession]; + SDLLogD(@"Stopping video streaming lifecycle manager"); _protocol = nil; _backgroundingPixelBuffer = NULL; @@ -204,7 +203,10 @@ - (void)stop { _lastPresentationTimestamp = kCMTimeInvalid; [self.videoScaleManager stop]; - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; + + if (!self.isVideoStopped) { + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; + } } - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { @@ -253,6 +255,10 @@ - (BOOL)isVideoStreamingPaused { return !(self.isVideoConnected && self.isHmiStateVideoStreamCapable && self.isAppStateVideoStreamCapable); } +- (BOOL)isVideoStopped { + return [self.videoStreamStateMachine isCurrentState:SDLVideoStreamManagerStateStopped]; +} + - (CVPixelBufferPoolRef __nullable)pixelBufferPool { return self.videoEncoder.pixelBufferPool; } @@ -610,6 +616,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { if (hmiStatus.windowID != nil && hmiStatus.windowID.integerValue != SDLPredefinedWindowsDefaultWindow) { return; } + self.hmiLevel = hmiStatus.hmiLevel; SDLVideoStreamingState newState = hmiStatus.videoStreamingState ?: SDLVideoStreamingStateStreamable; @@ -676,12 +683,14 @@ - (void)sdl_startVideoSession { - (void)sdl_stopVideoSession { SDLLogV(@"Attempting to stop video session"); if (!self.isStreamingSupported) { + SDLLogV(@"Head unit does not support video streaming. Will not send an end video service request"); return; } - if (self.isVideoConnected || self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; + } else { + SDLLogV(@"No video currently streaming. Will not send an end video service request"); } } From 2fabda5aab94973d0018e6dfe2329d66c3796d0e Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 12:29:27 -0500 Subject: [PATCH 002/152] Added logs --- .../SDLStreamingVideoLifecycleManager.m | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 1c5a3df3f..f536ce9b9 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -292,7 +292,10 @@ - (void)sdl_appStateDidUpdate:(NSNotification*)notification { - (void)didEnterStateAppInactive { SDLLogD(@"App became inactive"); - if (!self.protocol) { return; } + if (!self.protocol) { + SDLLogV(@"No session established with head unit. Ignoring app backgrounded notification"); + return; + } if (_showVideoBackgroundDisplay) { [self sdl_sendBackgroundFrames]; @@ -310,7 +313,10 @@ - (void)didEnterStateAppInactive { // We should be waiting to start any OpenGL drawing until UIApplicationDidBecomeActive is called. - (void)didEnterStateAppActive { SDLLogD(@"App became active"); - if (!self.protocol) { return; } + if (!self.protocol) { + SDLLogV(@"No session established with head unit. Ignoring app foregounded notification"); + return; + } if (self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateReady]; @@ -656,7 +662,7 @@ - (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)en - (void)sdl_startVideoSession { SDLLogV(@"Attempting to start video session"); if (!self.protocol) { - SDLLogV(@"Video manager is not yet started"); + SDLLogV(@"No session established with head unit. Video start service request will not be sent."); return; } @@ -712,6 +718,11 @@ - (void)sdl_displayLinkFired:(CADisplayLink *)displayLink { SDLLogV(@"DisplayLink frame fired, duration: %f, last frame timestamp: %f, target timestamp: (not available)", displayLink.duration, displayLink.timestamp); } + if (![self.hmiLevel isEqualToEnum:SDLHMILevelFull]) { + SDLLogD(@"hmiLevel is not FULL. Not sending video data: %@", self.hmiLevel); + return; + } + [self.touchManager syncFrame]; [self.carWindow syncFrame]; } From 21c3fb65d53436d2efebcba0756db7be72c08a31 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 12:29:58 -0500 Subject: [PATCH 003/152] Fixed nil pixel buffer pool --- SmartDeviceLink/SDLH264VideoEncoder.m | 34 ++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 933a4f48a..b739fceb3 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -26,6 +26,9 @@ @interface SDLH264VideoEncoder () @property (assign, nonatomic) NSUInteger currentFrameNumber; @property (assign, nonatomic) double timestampOffset; +@property (assign, nonatomic, nullable) CVPixelBufferPoolRef pool; +@property (assign, nonatomic) CGSize imageDimensions; + @end @@ -54,6 +57,7 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: _compressionSession = NULL; _currentFrameNumber = 0; _videoEncoderSettings = properties; + _imageDimensions = dimensions; _delegate = delegate; @@ -134,6 +138,8 @@ - (void)stop { CFRelease(self.compressionSession); self.compressionSession = NULL; } + + self.pool = nil; } - (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer { @@ -176,7 +182,18 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { } - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { - return VTCompressionSessionGetPixelBufferPool(self.compressionSession); + // HAX: When the app is backgrounded, some of the time the compression session gets invalidated. This causes the pool to fail when the app is foregrounded and video frames are sent again. + if (self.pool == nil) { + NSError* error = nil; + [self sdl_resetCompressionSessionWithError:&error]; + if (error != nil) { + return nil; + } + + self.pool = VTCompressionSessionGetPixelBufferPool(self.compressionSession); + } + + return self.pool; } #pragma mark - Private @@ -312,6 +329,21 @@ + (NSArray *)sdl_extractNalUnitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer return nalUnits; } +/// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoded was created. +/// @param error The error that occured when creating the VTCompressionSession, if any occured +- (void)sdl_resetCompressionSessionWithError:(NSError **)error { + OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.imageDimensions.width, (int32_t)self.imageDimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); + + if (status == noErr) { + return; + } + + if (!*error) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status) }]; + SDLLogE(@"Error attempting to create video compression session: %@", *error); + } +} + @end NS_ASSUME_NONNULL_END From e4d0a25f07a84fdcc833d48971fe3d2ead2ce65c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 13:36:50 -0500 Subject: [PATCH 004/152] Added log to car window --- SmartDeviceLink/SDLCarWindow.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m index d6048739e..0e55b6dd6 100644 --- a/SmartDeviceLink/SDLCarWindow.m +++ b/SmartDeviceLink/SDLCarWindow.m @@ -94,6 +94,8 @@ - (void)syncFrame { if (pixelBuffer != nil) { [self.streamManager sendVideoData:pixelBuffer]; CVPixelBufferRelease(pixelBuffer); + } else { + SDLLogE(@"Video frame will not be sent because the pixel buffer is nil"); } } From 0e1cd3fa654e86d7aec9d4a5555d94226428efd6 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 13:38:04 -0500 Subject: [PATCH 005/152] Removed hmilevel check --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index f536ce9b9..6eb3db397 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -718,10 +718,10 @@ - (void)sdl_displayLinkFired:(CADisplayLink *)displayLink { SDLLogV(@"DisplayLink frame fired, duration: %f, last frame timestamp: %f, target timestamp: (not available)", displayLink.duration, displayLink.timestamp); } - if (![self.hmiLevel isEqualToEnum:SDLHMILevelFull]) { - SDLLogD(@"hmiLevel is not FULL. Not sending video data: %@", self.hmiLevel); - return; - } +// if (![self.hmiLevel isEqualToEnum:SDLHMILevelFull]) { +// SDLLogD(@"hmiLevel is not FULL. Not sending video data: %@", self.hmiLevel); +// return; +// } [self.touchManager syncFrame]; [self.carWindow syncFrame]; From 630517c6158f42c6529fedef7c95911e6fef04d7 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 13:38:20 -0500 Subject: [PATCH 006/152] Fixed documentation --- SmartDeviceLink/SDLH264VideoEncoder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index b739fceb3..28dbac8d8 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -182,7 +182,7 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { } - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { - // HAX: When the app is backgrounded, some of the time the compression session gets invalidated. This causes the pool to fail when the app is foregrounded and video frames are sent again. + // HAX: When the app is backgrounded, sometimes the compression session gets invalidated. This causes the pool to fail when the app is foregrounded and video frames are sent again. if (self.pool == nil) { NSError* error = nil; [self sdl_resetCompressionSessionWithError:&error]; From cbf99f7b36b313bb784ed5d4a15125b07832ce11 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 13:38:32 -0500 Subject: [PATCH 007/152] Removed hmi level check --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 5 ----- 1 file changed, 5 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 6eb3db397..4e4fb87f0 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -718,11 +718,6 @@ - (void)sdl_displayLinkFired:(CADisplayLink *)displayLink { SDLLogV(@"DisplayLink frame fired, duration: %f, last frame timestamp: %f, target timestamp: (not available)", displayLink.duration, displayLink.timestamp); } -// if (![self.hmiLevel isEqualToEnum:SDLHMILevelFull]) { -// SDLLogD(@"hmiLevel is not FULL. Not sending video data: %@", self.hmiLevel); -// return; -// } - [self.touchManager syncFrame]; [self.carWindow syncFrame]; } From 92fd023137d65c95067666311d6a41711c823512 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 13:55:36 -0500 Subject: [PATCH 008/152] Fixed pragma markers --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 6 +++--- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 7f1fa6ba6..6e5b0a67e 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -170,7 +170,7 @@ - (void)didEnterStateAudioStreamShuttingDown { } #pragma mark - SDLProtocolListener -#pragma mark Video / Audio Start Service ACK +#pragma mark Start Service ACK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { switch (startServiceACK.header.serviceType) { @@ -195,7 +195,7 @@ - (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAc [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateReady]; } -#pragma mark Video / Audio Start Service NAK +#pragma mark Start Service NAK - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { switch (startServiceNAK.header.serviceType) { @@ -211,7 +211,7 @@ - (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNa [self sdl_transitionToStoppedState:SDLServiceTypeAudio]; } -#pragma mark Video / Audio End Service +#pragma mark End Service - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { SDLLogD(@"%@ service ended", (endServiceACK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 4e4fb87f0..202530c3f 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -483,7 +483,7 @@ - (void)didEnterStateVideoStreamShuttingDown { } #pragma mark - SDLProtocolListener -#pragma mark Video / Audio Start Service ACK +#pragma mark Start Service ACK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { switch (startServiceACK.header.serviceType) { @@ -526,7 +526,7 @@ - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAc [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateReady]; } -#pragma mark Video / Audio Start Service NAK +#pragma mark Start Service NAK - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { switch (startServiceNAK.header.serviceType) { @@ -562,7 +562,7 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa [self sdl_sendVideoStartService]; } -#pragma mark Video / Audio End Service +#pragma mark End Service - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { SDLLogD(@"%@ service ended", (endServiceACK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); From 6919c06a049763a0acd4ca25d29dfeb098119cba Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 15:44:36 -0500 Subject: [PATCH 009/152] Remove setting pool to nil --- SmartDeviceLink/SDLH264VideoEncoder.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 28dbac8d8..f0865759d 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -138,8 +138,6 @@ - (void)stop { CFRelease(self.compressionSession); self.compressionSession = NULL; } - - self.pool = nil; } - (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer { From 21745377e3521e5085e42a73d5861c16c00bc80c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 30 Jan 2020 15:45:45 -0500 Subject: [PATCH 010/152] fixed video state for starting video when app is in bg --- .../SDLStreamingVideoLifecycleManager.m | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 202530c3f..34da2b8fa 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -416,10 +416,10 @@ - (void)didEnterStateVideoStreamStarting { - (void)didEnterStateVideoStreamReady { SDLLogD(@"Video stream ready"); - if (self.videoEncoder != nil) { - [self.videoEncoder stop]; - self.videoEncoder = nil; - } +// if (self.videoEncoder != nil) { +// [self.videoEncoder stop]; +// self.videoEncoder = nil; +// } [self disposeDisplayLink]; @@ -451,9 +451,14 @@ - (void)didEnterStateVideoStreamReady { [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil]; + if (!self.isAppStateVideoStreamCapable) { + SDLLogV(@"App is in the background and can not stream video. Video will resume when app is foregrounded"); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateSuspended]; + return; + } + if (self.useDisplayLink) { dispatch_async(dispatch_get_main_queue(), ^{ - // And start up the displayLink NSInteger targetFramerate = ((NSNumber *)self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate]).integerValue; SDLLogD(@"Initializing CADisplayLink with framerate: %ld", (long)targetFramerate); self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(sdl_displayLinkFired:)]; @@ -623,7 +628,9 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { return; } + SDLHMILevel oldHMILevel = self.hmiLevel; self.hmiLevel = hmiStatus.hmiLevel; + SDLLogV(@"hmi level changed from %@ to $%@", oldHMILevel, self.hmiLevel); SDLVideoStreamingState newState = hmiStatus.videoStreamingState ?: SDLVideoStreamingStateStreamable; if (![self.videoStreamingState isEqualToEnum:newState]) { From 902e556a07a22f44ebd28d5c84ee153353bc83b1 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 31 Jan 2020 15:54:45 -0500 Subject: [PATCH 011/152] Added error handling to CarWindow --- SmartDeviceLink/SDLCarWindow.m | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m index 0e55b6dd6..9e21ad483 100644 --- a/SmartDeviceLink/SDLCarWindow.m +++ b/SmartDeviceLink/SDLCarWindow.m @@ -92,7 +92,11 @@ - (void)syncFrame { CGImageRef imageRef = screenshot.CGImage; CVPixelBufferRef pixelBuffer = [self.class sdl_pixelBufferForImageRef:imageRef usingPool:self.streamManager.pixelBufferPool]; if (pixelBuffer != nil) { - [self.streamManager sendVideoData:pixelBuffer]; + BOOL success = [self.streamManager sendVideoData:pixelBuffer]; + if (!success) { + SDLLogE(@"Video frame will not be sent because the video frame encoding failed"); + return; + } CVPixelBufferRelease(pixelBuffer); } else { SDLLogE(@"Video frame will not be sent because the pixel buffer is nil"); @@ -193,6 +197,11 @@ - (void)sdl_applyDisplayDimensionsToRootViewController:(UIViewController *)rootV return; } + if (CGRectEqualToRect(rootViewController.view.frame, self.streamManager.videoScaleManager.appViewportFrame)) { + SDLLogV(@"The CarWindow frame is already the correct size"); + return; + } + rootViewController.view.frame = self.streamManager.videoScaleManager.appViewportFrame; rootViewController.view.bounds = rootViewController.view.frame; From ba7627a4e0e95e8a4e1b8e5c27f6341ab7578ff0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 31 Jan 2020 15:55:13 -0500 Subject: [PATCH 012/152] Added more detail to error messages --- SmartDeviceLink/SDLH264VideoEncoder.m | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index f0865759d..d7907d812 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -68,8 +68,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: if (status != noErr) { if (!*error) { - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status) }]; - SDLLogE(@"Error attempting to create video compression session: %@", *error); + NSString *description = @"Compression session could not be created"; + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status), NSLocalizedDescriptionKey: description }]; } return nil; @@ -83,7 +83,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: status = VTSessionCopySupportedPropertyDictionary(self.compressionSession, &supportedProperties); if (status != noErr) { if (!*error) { - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }]; + NSString *description = [NSString stringWithFormat:@"\"%@\" are not supported properties.", supportedProperties]; + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status), NSLocalizedDescriptionKey: description }]; } return nil; @@ -133,6 +134,10 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: } - (void)stop { + _currentFrameNumber = 0; + _imageDimensions = CGSizeZero; + _timestampOffset = 0.0; + if (self.compressionSession != NULL) { VTCompressionSessionInvalidate(self.compressionSession); CFRelease(self.compressionSession); @@ -180,12 +185,12 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { } - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { - // HAX: When the app is backgrounded, sometimes the compression session gets invalidated. This causes the pool to fail when the app is foregrounded and video frames are sent again. - if (self.pool == nil) { - NSError* error = nil; + // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool to fail when the app is foregrounded and video frames are sent again. + if (self.pool == NULL) { + NSError* error = NULL; [self sdl_resetCompressionSessionWithError:&error]; - if (error != nil) { - return nil; + if (error != NULL) { + return NULL; } self.pool = VTCompressionSessionGetPixelBufferPool(self.compressionSession); From 25ee7561fdcd4d3548736d55e889c053fd37019c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 31 Jan 2020 15:55:40 -0500 Subject: [PATCH 013/152] Cleaned up serviceType check --- .../SDLStreamingVideoLifecycleManager.m | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 34da2b8fa..1e8a9ddf7 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -416,10 +416,10 @@ - (void)didEnterStateVideoStreamStarting { - (void)didEnterStateVideoStreamReady { SDLLogD(@"Video stream ready"); -// if (self.videoEncoder != nil) { -// [self.videoEncoder stop]; -// self.videoEncoder = nil; -// } + if (self.videoEncoder != nil) { + [self.videoEncoder stop]; + self.videoEncoder = nil; + } [self disposeDisplayLink]; @@ -478,7 +478,7 @@ - (void)didEnterStateVideoStreamSuspended { SDLLogD(@"Video stream suspended"); [self disposeDisplayLink]; - + [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamSuspendedNotification object:nil]; } @@ -491,12 +491,8 @@ - (void)didEnterStateVideoStreamShuttingDown { #pragma mark Start Service ACK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { - switch (startServiceACK.header.serviceType) { - case SDLServiceTypeVideo: { - [self sdl_handleVideoStartServiceAck:startServiceACK]; - } break; - default: break; - } + if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } + [self sdl_handleVideoStartServiceAck:startServiceACK]; } - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAck { @@ -534,12 +530,8 @@ - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAc #pragma mark Start Service NAK - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { - switch (startServiceNAK.header.serviceType) { - case SDLServiceTypeVideo: { - [self sdl_handleVideoStartServiceNak:startServiceNAK]; - } - default: break; - } + if (startServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } + [self sdl_handleVideoStartServiceNak:startServiceNAK]; } - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNak { @@ -551,6 +543,8 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa if (nakPayload.rejectedParams.count == 0) { [self sdl_transitionToStoppedState:SDLServiceTypeVideo]; return; + } else { + SDLLogV(@"video nak payload: %@)", nakPayload.rejectedParams.description); } // If height and/or width was rejected, and we have another resolution to try, advance our counter to try another resolution @@ -570,12 +564,22 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa #pragma mark End Service - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - SDLLogD(@"%@ service ended", (endServiceACK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); + if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } + SDLLogD(@"Video service ended successfully"); + [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { - SDLLogW(@"%@ service ended with end service NAK", (endServiceNAK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); + if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } + + if (endServiceNAK.payload != nil) { + SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; + SDLLogW(@"Video service ended with end service NAK. Rejected parameters: %@", nakPayload.description); + } else { + SDLLogW(@"Video service ended with end service NAK. Rejected parameters not returned."); + } + [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } @@ -630,7 +634,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { SDLHMILevel oldHMILevel = self.hmiLevel; self.hmiLevel = hmiStatus.hmiLevel; - SDLLogV(@"hmi level changed from %@ to $%@", oldHMILevel, self.hmiLevel); + SDLLogV(@"video hmi level changed from %@ to $%@", oldHMILevel, self.hmiLevel); SDLVideoStreamingState newState = hmiStatus.videoStreamingState ?: SDLVideoStreamingStateStreamable; if (![self.videoStreamingState isEqualToEnum:newState]) { @@ -641,7 +645,9 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { // if startWithProtocol has not been called yet, abort here if (!self.protocol) { return; } - if (self.isHmiStateVideoStreamCapable) { + if (![self.hmiLevel isEqualToEnum:SDLHMILevelNone] && self.isVideoConnected) { + [self resetVideo]; + } else if (self.isHmiStateVideoStreamCapable) { [self sdl_startVideoSession]; } else { [self sdl_stopVideoSession]; @@ -708,13 +714,8 @@ - (void)sdl_stopVideoSession { } - (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { - switch (serviceType) { - case SDLServiceTypeVideo: - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; - break; - default: - break; - } + if (serviceType != SDLServiceTypeVideo) { return; } + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } - (void)sdl_displayLinkFired:(CADisplayLink *)displayLink { From cf15791d263bdd84373555a39fc4bc3cbcca4e3e Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 3 Feb 2020 08:47:39 -0500 Subject: [PATCH 014/152] Removed reset --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 1e8a9ddf7..006ad9115 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -646,7 +646,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { if (!self.protocol) { return; } if (![self.hmiLevel isEqualToEnum:SDLHMILevelNone] && self.isVideoConnected) { - [self resetVideo]; + //do nothing } else if (self.isHmiStateVideoStreamCapable) { [self sdl_startVideoSession]; } else { From 53121aeea572ee7e692752f19371059880da5639 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:00:46 -0500 Subject: [PATCH 015/152] Fixed SDL log messages --- SmartDeviceLink/SDLCarWindow.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m index 9e21ad483..12f2e83b7 100644 --- a/SmartDeviceLink/SDLCarWindow.m +++ b/SmartDeviceLink/SDLCarWindow.m @@ -99,7 +99,7 @@ - (void)syncFrame { } CVPixelBufferRelease(pixelBuffer); } else { - SDLLogE(@"Video frame will not be sent because the pixel buffer is nil"); + SDLLogE(@"Video frame will not be sent because the pixelBuffer is nil"); } } @@ -198,7 +198,7 @@ - (void)sdl_applyDisplayDimensionsToRootViewController:(UIViewController *)rootV } if (CGRectEqualToRect(rootViewController.view.frame, self.streamManager.videoScaleManager.appViewportFrame)) { - SDLLogV(@"The CarWindow frame is already the correct size"); + SDLLogV(@"The rootViewController frame is already the correct size: %@", NSStringFromCGRect(rootViewController.view.frame)); return; } From 13562fbba529151ae159343ddbd981f976d508f0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:08:37 -0500 Subject: [PATCH 016/152] Refactored compression session resetting --- SmartDeviceLink/SDLH264VideoEncoder.m | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index d7907d812..306b59fe1 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -185,11 +185,10 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { } - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { - // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool to fail when the app is foregrounded and video frames are sent again. + // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. if (self.pool == NULL) { - NSError* error = NULL; - [self sdl_resetCompressionSessionWithError:&error]; - if (error != NULL) { + BOOL success = [self sdl_resetCompressionSession]; + if (success == NO) { return NULL; } @@ -332,19 +331,15 @@ + (NSArray *)sdl_extractNalUnitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer return nalUnits; } -/// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoded was created. -/// @param error The error that occured when creating the VTCompressionSession, if any occured -- (void)sdl_resetCompressionSessionWithError:(NSError **)error { +/// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoder was created and returns whether or not creating the new compression session was created successfully. +- (BOOL)sdl_resetCompressionSession { OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.imageDimensions.width, (int32_t)self.imageDimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); if (status == noErr) { - return; + return NO; } - if (!*error) { - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status) }]; - SDLLogE(@"Error attempting to create video compression session: %@", *error); - } + return YES; } @end From 66138ddd63aabc91caa77fab5c192179cdebe592 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:17:54 -0500 Subject: [PATCH 017/152] Cleaned up documentation --- SmartDeviceLink/SDLH264VideoEncoder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 306b59fe1..fbe8b270e 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -185,7 +185,7 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { } - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { - // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. + // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool and/or the compression session to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. if (self.pool == NULL) { BOOL success = [self sdl_resetCompressionSession]; if (success == NO) { From 0780c1e1978d1f6d0e5897ac1a4ce3eb157738c2 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:18:12 -0500 Subject: [PATCH 018/152] Refactoring the video lifecycle manager --- .../SDLStreamingVideoLifecycleManager.m | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 006ad9115..c12e6ee93 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -543,8 +543,6 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa if (nakPayload.rejectedParams.count == 0) { [self sdl_transitionToStoppedState:SDLServiceTypeVideo]; return; - } else { - SDLLogV(@"video nak payload: %@)", nakPayload.rejectedParams.description); } // If height and/or width was rejected, and we have another resolution to try, advance our counter to try another resolution @@ -573,13 +571,6 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - if (endServiceNAK.payload != nil) { - SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; - SDLLogW(@"Video service ended with end service NAK. Rejected parameters: %@", nakPayload.description); - } else { - SDLLogW(@"Video service ended with end service NAK. Rejected parameters not returned."); - } - [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } @@ -634,7 +625,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { SDLHMILevel oldHMILevel = self.hmiLevel; self.hmiLevel = hmiStatus.hmiLevel; - SDLLogV(@"video hmi level changed from %@ to $%@", oldHMILevel, self.hmiLevel); + SDLLogV(@"HMI level changed from %@ to $%@", oldHMILevel, self.hmiLevel); SDLVideoStreamingState newState = hmiStatus.videoStreamingState ?: SDLVideoStreamingStateStreamable; if (![self.videoStreamingState isEqualToEnum:newState]) { @@ -643,11 +634,12 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { } // if startWithProtocol has not been called yet, abort here - if (!self.protocol) { return; } + if (!self.protocol) { + SDLLogV(@"No session established with head unit. HMI status is not relevant."); + return; + } - if (![self.hmiLevel isEqualToEnum:SDLHMILevelNone] && self.isVideoConnected) { - //do nothing - } else if (self.isHmiStateVideoStreamCapable) { + if (self.isHmiStateVideoStreamCapable) { [self sdl_startVideoSession]; } else { [self sdl_stopVideoSession]; From 7ee19e29d6891bf26e9fbbf9d184869eb262f6a3 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:29:07 -0500 Subject: [PATCH 019/152] Fixed returned value --- SmartDeviceLink/SDLH264VideoEncoder.m | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index fbe8b270e..15648aa1e 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -334,12 +334,7 @@ + (NSArray *)sdl_extractNalUnitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer /// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoder was created and returns whether or not creating the new compression session was created successfully. - (BOOL)sdl_resetCompressionSession { OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.imageDimensions.width, (int32_t)self.imageDimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); - - if (status == noErr) { - return NO; - } - - return YES; + return (status == noErr) ? YES : NO; } @end From 28a06ec11a51fd8bae135fa7e2d6c95f3933da0b Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:41:52 -0500 Subject: [PATCH 020/152] Fixing audio state stop method --- .../SDLStreamingAudioLifecycleManager.m | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 6e5b0a67e..1a74fa642 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -56,9 +56,7 @@ - (instancetype)initWithConnectionManager:(id)connecti SDLLogV(@"Creating AudioStreamingLifecycleManager"); _connectionManager = connectionManager; - _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self]; - _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; NSMutableArray *tempMakeArray = [NSMutableArray array]; @@ -96,12 +94,12 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { } - (void)stop { - SDLLogD(@"Stopping manager"); - [self sdl_stopAudioSession]; - - self.hmiLevel = SDLHMILevelNone; + SDLLogD(@"Stopping audio streaming lifecycle manager"); + _hmiLevel = SDLHMILevelNone; - [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; + if (!self.isAudioStopped) { + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; + } } - (BOOL)sendAudioData:(NSData*)audioData { @@ -315,6 +313,10 @@ - (BOOL)isHmiStateAudioStreamCapable { return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull]; } +- (BOOL)isAudioStopped { + return [self.audioStreamStateMachine isCurrentState:SDLAudioStreamManagerStateStopped]; +} + @end NS_ASSUME_NONNULL_END From df13cf61eda6d0463de7bc5fe72738707f2b81e4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:41:59 -0500 Subject: [PATCH 021/152] Added error message --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index c12e6ee93..f52fe9e63 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -570,6 +570,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } + SDLLogE(@"Video service did not end successfully"); [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } From 56e793a505c2329eb2c03c9839e9f107c365e013 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:46:39 -0500 Subject: [PATCH 022/152] Cleaned up audio stream manager --- .../SDLStreamingAudioLifecycleManager.m | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 1a74fa642..b8e409add 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -171,12 +171,8 @@ - (void)didEnterStateAudioStreamShuttingDown { #pragma mark Start Service ACK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { - switch (startServiceACK.header.serviceType) { - case SDLServiceTypeAudio: { - [self sdl_handleAudioStartServiceAck:startServiceACK]; - } break; - default: break; - } + if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } + [self sdl_handleAudioStartServiceAck:startServiceACK]; } - (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAck { @@ -196,12 +192,8 @@ - (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAc #pragma mark Start Service NAK - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { - switch (startServiceNAK.header.serviceType) { - case SDLServiceTypeAudio: { - [self sdl_handleAudioStartServiceNak:startServiceNAK]; - } break; - default: break; - } + if (startServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } + [self sdl_handleAudioStartServiceNak:startServiceNAK]; } - (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNak { @@ -212,12 +204,16 @@ - (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNa #pragma mark End Service - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - SDLLogD(@"%@ service ended", (endServiceACK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); + if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } + SDLLogD(@"Audio service ended successfully"); + [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { - SDLLogW(@"%@ service ended with end service NAK", (endServiceNAK.header.serviceType == SDLServiceTypeVideo ? @"Video" : @"Audio")); + if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } + SDLLogE(@"Audio service did not end successfully"); + [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } From 618464d68c51ab505466c5c59dd8db78a8b5bf44 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 08:46:49 -0500 Subject: [PATCH 023/152] Removed newlines --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index f52fe9e63..9853fe832 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -476,9 +476,7 @@ - (void)didEnterStateVideoStreamReady { - (void)didEnterStateVideoStreamSuspended { SDLLogD(@"Video stream suspended"); - [self disposeDisplayLink]; - [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamSuspendedNotification object:nil]; } From 8c272fa0b1d8033c2933e065118cdaf17fa67db0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 09:33:51 -0500 Subject: [PATCH 024/152] Added test cases for audio manager --- .../SDLStreamingAudioLifecycleManagerSpec.m | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index cfcb62aea..6f3312dd8 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -402,6 +402,38 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); }); + + describe(@"when stopped", ^{ + context(@"if audio not stopped", ^{ + beforeEach(^{ + [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager stop]; + }); + + it(@"should transition to the stopped state", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); + }); + + it(@"should reset the hmiLevel", ^{ + expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + }); + }); + + context(@"if audio is already stopped", ^{ + beforeEach(^{ + [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateStopped fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager stop]; + }); + + it(@"should stay in the stopped state", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); + }); + + it(@"should reset the hmiLevel", ^{ + expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + }); + }); + }); }); QuickSpecEnd From 106c0cddff57ba6dc6b5e6526843ff535483de3a Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 10:20:28 -0500 Subject: [PATCH 025/152] Added test cases for stopping streaming --- .../SDLStreamingAudioLifecycleManager.m | 14 +++--- .../SDLStreamingVideoLifecycleManager.m | 9 +--- .../SDLStreamingAudioLifecycleManagerSpec.m | 14 +++++- .../SDLStreamingVideoLifecycleManagerSpec.m | 44 +++++++++++++++++++ 4 files changed, 62 insertions(+), 19 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index b8e409add..2d32bcfc4 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -41,7 +41,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (weak, nonatomic) SDLProtocol *protocol; @property (copy, nonatomic) NSArray *secureMakes; -@property (copy, nonatomic) NSString *connectedVehicleMake; +@property (copy, nonatomic, nullable) NSString *connectedVehicleMake; @end @@ -58,6 +58,7 @@ - (instancetype)initWithConnectionManager:(id)connecti _connectionManager = connectionManager; _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; + _connectedVehicleMake = nil; NSMutableArray *tempMakeArray = [NSMutableArray array]; #pragma clang diagnostic push @@ -95,11 +96,10 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { - (void)stop { SDLLogD(@"Stopping audio streaming lifecycle manager"); + _protocol = nil; _hmiLevel = SDLHMILevelNone; - - if (!self.isAudioStopped) { - [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; - } + _connectedVehicleMake = nil; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } - (BOOL)sendAudioData:(NSData*)audioData { @@ -309,10 +309,6 @@ - (BOOL)isHmiStateAudioStreamCapable { return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull]; } -- (BOOL)isAudioStopped { - return [self.audioStreamStateMachine isCurrentState:SDLAudioStreamManagerStateStopped]; -} - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 9853fe832..542c9591e 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -203,10 +203,7 @@ - (void)stop { _lastPresentationTimestamp = kCMTimeInvalid; [self.videoScaleManager stop]; - - if (!self.isVideoStopped) { - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; - } + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { @@ -255,10 +252,6 @@ - (BOOL)isVideoStreamingPaused { return !(self.isVideoConnected && self.isHmiStateVideoStreamCapable && self.isAppStateVideoStreamCapable); } -- (BOOL)isVideoStopped { - return [self.videoStreamStateMachine isCurrentState:SDLVideoStreamManagerStateStopped]; -} - - (CVPixelBufferPoolRef __nullable)pixelBufferPool { return self.videoEncoder.pixelBufferPool; } diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 6f3312dd8..d3963ce23 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -20,6 +20,12 @@ #import "SDLV2ProtocolMessage.h" #import "TestConnectionManager.h" + +@interface SDLStreamingAudioLifecycleManager() +@property (weak, nonatomic) SDLProtocol *protocol; +@property (copy, nonatomic, nullable) NSString *connectedVehicleMake; +@end + QuickSpecBegin(SDLStreamingAudioLifecycleManagerSpec) describe(@"the streaming audio manager", ^{ @@ -414,8 +420,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); }); - it(@"should reset the hmiLevel", ^{ + it(@"should reset the saved properties", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); }); }); @@ -429,8 +437,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); }); - it(@"should reset the hmiLevel", ^{ + it(@"should reset the saved properties", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); }); }); }); diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 31b87c9c9..58a429f26 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -42,6 +42,8 @@ #import "SDLHMICapabilities.h" @interface SDLStreamingVideoLifecycleManager () +@property (weak, nonatomic) SDLProtocol *protocol; +@property (copy, nonatomic) NSString *connectedVehicleMake; @property (copy, nonatomic, readonly) NSString *appName; @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; @end @@ -713,6 +715,48 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); + describe(@"when stopped", ^{ + context(@"if video is not stopped", ^{ + beforeEach(^{ + [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager stop]; + }); + + it(@"should transition to the stopped state", ^{ + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped)); + }); + + it(@"should reset the saved properties", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); + expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); + expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + expect(streamingLifecycleManager.videoStreamingState).to(equal(SDLVideoStreamingStateNotStreamable)); + expect(streamingLifecycleManager.preferredFormatIndex).to(equal(0)); + expect(streamingLifecycleManager.preferredResolutionIndex).to(equal(0)); + }); + }); + + context(@"if video is already stopped", ^{ + beforeEach(^{ + [streamingLifecycleManager.videoStreamStateMachine setToState:SDLAudioStreamManagerStateStopped fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager stop]; + }); + + it(@"should stay in the stopped state", ^{ + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped)); + }); + + it(@"should reset the saved properties", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); + expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); + expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); + expect(streamingLifecycleManager.videoStreamingState).to(equal(SDLVideoStreamingStateNotStreamable)); + expect(streamingLifecycleManager.preferredFormatIndex).to(equal(0)); + expect(streamingLifecycleManager.preferredResolutionIndex).to(equal(0)); + }); + }); + }); + describe(@"Creating a background video stream string", ^{ __block NSString *expectedVideoStreamBackgroundString = [NSString stringWithFormat:@"When it is safe to do so, open %@ on your phone", testAppName]; From 484f19313ea907936c0cc83abbd0ec160d260ba5 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 10:47:54 -0500 Subject: [PATCH 026/152] Fixed resetting the pixelBufferPool --- SmartDeviceLink/SDLH264VideoEncoder.m | 9 ++++----- SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m | 14 +++++++++++--- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 15648aa1e..5df3d33fa 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -26,7 +26,7 @@ @interface SDLH264VideoEncoder () @property (assign, nonatomic) NSUInteger currentFrameNumber; @property (assign, nonatomic) double timestampOffset; -@property (assign, nonatomic, nullable) CVPixelBufferPoolRef pool; +@property (assign, nonatomic, readwrite) CVPixelBufferPoolRef CV_NULLABLE pixelBufferPool; @property (assign, nonatomic) CGSize imageDimensions; @end @@ -135,7 +135,6 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: - (void)stop { _currentFrameNumber = 0; - _imageDimensions = CGSizeZero; _timestampOffset = 0.0; if (self.compressionSession != NULL) { @@ -186,16 +185,16 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool and/or the compression session to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. - if (self.pool == NULL) { + if (!_pixelBufferPool) { BOOL success = [self sdl_resetCompressionSession]; if (success == NO) { return NULL; } - self.pool = VTCompressionSessionGetPixelBufferPool(self.compressionSession); + _pixelBufferPool = VTCompressionSessionGetPixelBufferPool(self.compressionSession); } - return self.pool; + return _pixelBufferPool; } #pragma mark - Private diff --git a/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m b/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m index f79085706..cc662f47c 100644 --- a/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m +++ b/SmartDeviceLinkTests/SDLH264VideoEncoderSpec.m @@ -18,6 +18,12 @@ #import "SDLRTPH264Packetizer.h" #import "SDLVideoStreamingProtocol.h" +@interface SDLH264VideoEncoder () +@property (assign, nonatomic) NSUInteger currentFrameNumber; +@property (assign, nonatomic) double timestampOffset; +@property (assign, nonatomic, nullable) VTCompressionSessionRef compressionSession; +@end + QuickSpecBegin(SDLH264VideoEncoderSpec) describe(@"a video encoder", ^{ @@ -55,9 +61,11 @@ beforeEach(^{ [testVideoEncoder stop]; }); - - it(@"should have a nil pixel buffer pool", ^{ - expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@YES)); + + it(@"should reset the saved properties", ^{ + expect(testVideoEncoder.currentFrameNumber).to(equal(0)); + expect(testVideoEncoder.timestampOffset).to(equal(0.0)); + expect((id)testVideoEncoder.compressionSession).to(beNil()); }); }); }); From e5b1543fec593f30b4c30fb8316fc578d55280a7 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 4 Feb 2020 12:17:24 -0500 Subject: [PATCH 027/152] connectedVehicleMake now reset on disconnect --- .../SDLStreamingVideoLifecycleManager.m | 4 ++- .../SDLStreamingVideoLifecycleManagerSpec.m | 33 ++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 542c9591e..4ba4d3712 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -71,7 +71,7 @@ @interface SDLStreamingVideoLifecycleManager() @property (strong, nonatomic) NSMutableDictionary *videoEncoderSettings; @property (copy, nonatomic) NSDictionary *customEncoderSettings; @property (copy, nonatomic) NSArray *secureMakes; -@property (copy, nonatomic) NSString *connectedVehicleMake; +@property (copy, nonatomic, nullable) NSString *connectedVehicleMake; @property (copy, nonatomic, readonly) NSString *appName; @property (assign, nonatomic) CV_NULLABLE CVPixelBufferRef backgroundingPixelBuffer; @@ -127,6 +127,7 @@ - (instancetype)initWithConnectionManager:(id)connecti _touchManager = [[SDLTouchManager alloc] initWithHitTester:(id)_focusableItemManager videoScaleManager:_videoScaleManager]; _requestedEncryptionType = configuration.streamingMediaConfig.maximumDesiredEncryption; + _connectedVehicleMake = nil; _dataSource = configuration.streamingMediaConfig.dataSource; _useDisplayLink = configuration.streamingMediaConfig.enableForcedFramerateSync; _backgroundingPixelBuffer = NULL; @@ -201,6 +202,7 @@ - (void)stop { _hmiLevel = SDLHMILevelNone; _videoStreamingState = SDLVideoStreamingStateNotStreamable; _lastPresentationTimestamp = kCMTimeInvalid; + _connectedVehicleMake = nil; [self.videoScaleManager stop]; [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 58a429f26..152db9339 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -17,6 +17,7 @@ #import "SDLGetSystemCapabilityResponse.h" #import "SDLGenericResponse.h" #import "SDLGlobals.h" +#import "SDLHMICapabilities.h" #import "SDLHMILevel.h" #import "SDLImageResolution.h" #import "SDLLifecycleConfiguration.h" @@ -35,11 +36,12 @@ #import "SDLSystemCapability.h" #import "SDLV2ProtocolHeader.h" #import "SDLV2ProtocolMessage.h" +#import "SDLVehicleType.h" #import "SDLVideoStreamingCapability.h" #import "SDLVideoStreamingState.h" #import "TestConnectionManager.h" #import "SDLVersion.h" -#import "SDLHMICapabilities.h" + @interface SDLStreamingVideoLifecycleManager () @property (weak, nonatomic) SDLProtocol *protocol; @@ -139,6 +141,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream __block SDLScreenParams *someScreenParams = nil; __block SDLImageResolution *someImageResolution = nil; __block SDLHMICapabilities *someHMICapabilities = nil; + __block SDLVehicleType *testVehicleType = nil; beforeEach(^{ someImageResolution = [[SDLImageResolution alloc] init]; @@ -147,6 +150,12 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream someScreenParams = [[SDLScreenParams alloc] init]; someScreenParams.resolution = someImageResolution; + + testVehicleType = [[SDLVehicleType alloc] init]; + testVehicleType.make = @"OEM_make"; + testVehicleType.model = @"OEM_model"; + testVehicleType.modelYear = @"OEM_year"; + testVehicleType.trim = @"OEM_trim"; }); context(@"that does not support video streaming", ^{ @@ -160,6 +169,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream someRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init]; someRegisterAppInterfaceResponse.hmiCapabilities = someHMICapabilities; + someRegisterAppInterfaceResponse.vehicleType = testVehicleType; SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:someRegisterAppInterfaceResponse]; @@ -170,6 +180,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream it(@"should not support streaming", ^{ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO)); }); + + it(@"should not save the vehicle make", ^{ + expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); + }); }); context(@"that supports video streaming", ^{ @@ -191,6 +205,8 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream someRegisterAppInterfaceResponse.displayCapabilities = someDisplayCapabilities; #pragma clang diagnostic pop + someRegisterAppInterfaceResponse.vehicleType = testVehicleType; + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:someRegisterAppInterfaceResponse]; [[NSNotificationCenter defaultCenter] postNotification:notification]; @@ -201,6 +217,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@YES)); expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeMake(600, 100)))).to(equal(@YES)); }); + + it(@"should save the vehicle make", ^{ + expect(streamingLifecycleManager.connectedVehicleMake).to(equal(testVehicleType.make)); + }); }); context(@"version is less then 4.5.0", ^{ @@ -217,6 +237,9 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream #pragma clang diagnostic ignored "-Wdeprecated" someRegisterAppInterfaceResponse.displayCapabilities = someDisplayCapabilities; #pragma clang diagnostic pop + + someRegisterAppInterfaceResponse.vehicleType = testVehicleType; + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:someRegisterAppInterfaceResponse]; [[NSNotificationCenter defaultCenter] postNotification:notification]; @@ -227,6 +250,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@YES)); expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeMake(600, 100)))).to(equal(@YES)); }); + + it(@"should save the vehicle make", ^{ + expect(streamingLifecycleManager.connectedVehicleMake).to(equal(testVehicleType.make)); + }); }); }); @@ -716,6 +743,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); describe(@"when stopped", ^{ + beforeEach(^{ + streamingLifecycleManager.connectedVehicleMake = @"OEM_make"; + }); + context(@"if video is not stopped", ^{ beforeEach(^{ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; From 74954457539d0693c812758aa5d91fd105e2b7b6 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 17 Feb 2020 13:52:17 -0500 Subject: [PATCH 028/152] Fix backgrounding breaking the compression session --- SmartDeviceLink/SDLH264VideoEncoder.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 5df3d33fa..3888a412c 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -332,6 +332,13 @@ + (NSArray *)sdl_extractNalUnitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer /// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoder was created and returns whether or not creating the new compression session was created successfully. - (BOOL)sdl_resetCompressionSession { + // Destroy the compression session before attempting to create a new one. Otherwise the attempt to create a new compression session sometimes fails. + if (self.compressionSession != NULL) { + VTCompressionSessionInvalidate(self.compressionSession); + CFRelease(self.compressionSession); + self.compressionSession = NULL; + } + OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.imageDimensions.width, (int32_t)self.imageDimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); return (status == noErr) ? YES : NO; } From af768ef3f67f28d84053d93f5337ef2b6c45b397 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 18 Feb 2020 09:40:39 -0500 Subject: [PATCH 029/152] TCP transport only stopped after video stops --- SmartDeviceLink/SDLLifecycleManager.m | 5 +- .../SDLSecondaryTransportManager.h | 2 + .../SDLSecondaryTransportManager.m | 10 ++-- SmartDeviceLink/SDLStreamingMediaManager.h | 2 + SmartDeviceLink/SDLStreamingMediaManager.m | 10 ++++ .../SDLStreamingVideoLifecycleManager.h | 3 ++ .../SDLStreamingVideoLifecycleManager.m | 47 ++++++++++++++++++- SmartDeviceLink/SDLTCPTransport.m | 4 +- 8 files changed, 77 insertions(+), 6 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 46e813212..0bbc5dfc6 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -887,8 +887,11 @@ - (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)old } if (oldProtocol != nil) { - [self.streamManager stopVideo]; + [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { + [self.secondaryTransportManager disconnectSecondaryTransport]; + }]; } + if (newProtocol != nil) { [self.streamManager startVideoWithProtocol:newProtocol]; } diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 0af612d7e..8e9f2e3ca 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -61,6 +61,8 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; */ - (void)stop; +- (BOOL)disconnectSecondaryTransport; + /** * Call this method when Start Service ACK control frame is received on primary transport. diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 860abcbaf..65e1f9f53 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -266,14 +266,14 @@ - (void)willTransitionFromStateRegisteredToStateConfigured { SDLLogD(@"Stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; - [self sdl_disconnectSecondaryTransport]; + // [self sdl_disconnectSecondaryTransport]; } - (void)willTransitionFromStateRegisteredToStateReconnecting { SDLLogD(@"Stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; - [self sdl_disconnectSecondaryTransport]; + //[self sdl_disconnectSecondaryTransport]; } - (void)willTransitionFromStateRegisteredToStateStopped { @@ -300,7 +300,7 @@ - (void)sdl_startManager { } - (void)sdl_stopManager { - SDLLogD(@"SDLSecondaryTransportManager stop"); + SDLLogD(@"SDLSecondaryTransportManager in state stopped"); [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; @@ -485,6 +485,10 @@ - (BOOL)sdl_connectSecondaryTransport { } } +- (BOOL)disconnectSecondaryTransport { + return [self sdl_disconnectSecondaryTransport]; +} + - (BOOL)sdl_disconnectSecondaryTransport { if (self.secondaryTransport == nil) { SDLLogW(@"Attempted to disconnect secondary transport, but it's already stopped."); diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 0998868a6..6289734c8 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -157,6 +157,8 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopVideo; +- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; + /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index a1c81facc..c0b2302c1 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -81,6 +81,16 @@ - (void)stopVideo { self.videoStarted = NO; } +- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + __weak typeof(self) weakSelf = self; + [self.videoLifecycleManager stopWithCompletionHandler:^(BOOL success) { + weakSelf.videoStarted = NO; + + if (completionHandler == nil) { return; } + return completionHandler(success); + }]; +} + - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self.videoLifecycleManager sendVideoData:imageBuffer]; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 9a74f977a..020902a39 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -158,6 +158,9 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stop; + +- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; + /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 4ba4d3712..879a3ab7d 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -92,6 +92,10 @@ @interface SDLStreamingVideoLifecycleManager() @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; +@property (nonatomic, copy, nullable) void (^videoEndServiceReceivedHandler)(BOOL success); + +@property (nonatomic, copy, nullable) void (^audioDataReceivedHandler)(NSData *__nullable audioData); + @end @implementation SDLStreamingVideoLifecycleManager @@ -175,6 +179,8 @@ - (instancetype)initWithConnectionManager:(id)connecti _ssrc = arc4random_uniform(UINT32_MAX); _lastPresentationTimestamp = kCMTimeInvalid; + _videoEndServiceReceivedHandler = nil; + return self; } @@ -208,6 +214,30 @@ - (void)stop { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } +- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + self.videoEndServiceReceivedHandler = completionHandler; + + // Can't sent procol to `nil` else we will not get a response to the end service frame + + _backgroundingPixelBuffer = NULL; + _preferredFormatIndex = 0; + _preferredResolutionIndex = 0; + + _hmiLevel = SDLHMILevelNone; + _videoStreamingState = SDLVideoStreamingStateNotStreamable; + _lastPresentationTimestamp = kCMTimeInvalid; + _connectedVehicleMake = nil; + + [self.videoScaleManager stop]; + + if (self.isVideoConnected || self.isVideoSuspended) { + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; + } else { + SDLLogV(@"No video currently streaming. No need to send an end video service request"); + return completionHandler(NO); + } +} + - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self sendVideoData:imageBuffer presentationTimestamp:kCMTimeInvalid]; } @@ -485,6 +515,7 @@ - (void)didEnterStateVideoStreamShuttingDown { - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } + [self sdl_handleVideoStartServiceAck:startServiceACK]; } @@ -558,13 +589,20 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogD(@"Video service ended successfully"); - [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; + if (self.videoEndServiceReceivedHandler != nil) { + [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; + self.videoEndServiceReceivedHandler(YES); + } } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogE(@"Video service did not end successfully"); + if (self.videoEndServiceReceivedHandler != nil) { + self.videoEndServiceReceivedHandler(NO); + } + [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } @@ -606,6 +644,12 @@ - (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification * SDLLogD(@"Determined base screen size on display capabilities: %@", NSStringFromCGSize(self.videoScaleManager.displayViewportResolution)); } +/// Parses out the `hmiLevel` and `videoStreamingState` from an `OnHMIStatus` notification from Core. Since Core only allows video streaming when the `hmiLevel` is `FULL` or `LIMITED`, sending video data when the `hmiLevel` is not `FULL` or `LIMITED` will result in Core forcing an unregistration with a reason of `PROTOCOL_VIOLATION`. +/// 2. The `hmiLevel` will go to `FULL` when the user opens the SDL app by tapping on the SDL app icon on the HMI or uses a voice command to launch the SDL app. +/// 3. The `hmiLevel` will go to `LIMITED` when the user backgrounds the SDL app by opening another app or by going back to the home screen. +/// 4. The `hmiLevel` will go to `NONE` when the user "exits" the app (either through gesture or voice commands). It will also go to `NONE` if video fails to stream and the user presses "cancel" on the HMI popup. In these cases the transport between the phone and accessory will still be open. It will also go to `NONE` when the user disconnects the transport between the phone and accessory. In this case no notification will be recieved since the transport was disconnected. +/// +/// @param notification The `OnHMIStatus` notification - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { NSAssert([notification.notification isKindOfClass:[SDLOnHMIStatus class]], @"A notification was sent with an unanticipated object"); if (![notification.notification isKindOfClass:[SDLOnHMIStatus class]]) { @@ -701,6 +745,7 @@ - (void)sdl_stopVideoSession { - (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { if (serviceType != SDLServiceTypeVideo) { return; } + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index f56641fe7..e84f72bd0 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -348,7 +348,9 @@ - (void)sdl_onStreamEnd:(NSStream *)stream { } } -- (void)sdl_doNothing {} +- (void)sdl_doNothing { + SDLLogV(@"Doing nothing to trigger cancel"); +} @end From d62883c3a7d7f10cf626548f3b7fbd7c0ba76a1a Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 19 Feb 2020 13:12:07 -0500 Subject: [PATCH 030/152] Added background task and fixes --- SmartDeviceLink/SDLLifecycleManager.m | 113 +++++++++++++----- .../SDLSecondaryTransportManager.m | 52 ++++++-- .../SDLStreamingAudioLifecycleManager.h | 4 + .../SDLStreamingAudioLifecycleManager.m | 52 ++++++-- SmartDeviceLink/SDLStreamingMediaManager.h | 5 + SmartDeviceLink/SDLStreamingMediaManager.m | 18 +++ .../SDLStreamingProtocolDelegate.h | 7 +- .../SDLStreamingVideoLifecycleManager.h | 3 +- .../SDLStreamingVideoLifecycleManager.m | 40 +++++-- SmartDeviceLink/SDLTCPTransport.m | 24 ++-- 10 files changed, 242 insertions(+), 76 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 0bbc5dfc6..6ac6de6b4 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -273,8 +273,10 @@ - (void)sdl_stopManager:(BOOL)shouldRestart { if (self.secondaryTransportManager != nil) { [self.secondaryTransportManager stop]; } else { - [self audioServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; - [self videoServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; + [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:self.proxy.protocol toNewVideoProtocol:nil fromOldAudioProtocol:self.proxy.protocol + toNewAudioProtocol:nil]; +// [self audioServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; +// [self videoServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; } [self.systemCapabilityManager stop]; [self.responseDispatcher clear]; @@ -453,8 +455,9 @@ - (void)didEnterStateSettingUpManagers { // if secondary transport manager is used, streaming media manager will be started through onAudioServiceProtocolUpdated and onVideoServiceProtocolUpdated if (self.secondaryTransportManager == nil && self.streamManager != nil) { - [self audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; - [self videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; + [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:self.proxy.protocol fromOldAudioProtocol:nil toNewAudioProtocol:self.proxy.protocol]; +// [self audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; +// [self videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; } dispatch_group_enter(managerGroup); @@ -868,34 +871,86 @@ - (void)sdl_remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notifi #pragma mark Streaming protocol listener -- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { - if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { - return; - } - - if (oldProtocol != nil) { - [self.streamManager stopAudio]; - } - if (newProtocol != nil) { - [self.streamManager startAudioWithProtocol:newProtocol]; +- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { + + BOOL videoProtocolUpdated = ((oldVideoProtocol == nil && newVideoProtocol == nil) || (oldVideoProtocol == newVideoProtocol)) ? NO : YES; + BOOL audioProtocolUpdated = ((oldAudioProtocol == nil && newAudioProtocol == nil) || (oldAudioProtocol == newAudioProtocol)) ? NO : YES; + + if (videoProtocolUpdated && audioProtocolUpdated) { + // Stop both audio and video session before destroying the transport + if (oldVideoProtocol != nil && oldAudioProtocol != nil) { + [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { + [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { + [self.secondaryTransportManager disconnectSecondaryTransport]; + [self.streamManager destroyAudioProtocol]; + [self.streamManager destroyVideoProtocol]; + + if (newAudioProtocol != nil) { + [self.streamManager startAudioWithProtocol:newAudioProtocol]; + } + if (newVideoProtocol != nil) { + [self.streamManager startVideoWithProtocol:newVideoProtocol]; + } + }]; + }]; + } else if (oldVideoProtocol != nil) { + [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { + [self.secondaryTransportManager disconnectSecondaryTransport]; + + if (newVideoProtocol != nil) { + [self.streamManager startVideoWithProtocol:newVideoProtocol]; + } + }]; + } else if (oldAudioProtocol != nil) { + [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { + [self.secondaryTransportManager disconnectSecondaryTransport]; + + if (newAudioProtocol != nil) { + [self.streamManager startAudioWithProtocol:newAudioProtocol]; + } + }]; + } else { + // Both old audio and video protocols are nil + if (newAudioProtocol != nil) { + [self.streamManager startAudioWithProtocol:newAudioProtocol]; + } + if (newVideoProtocol != nil) { + [self.streamManager startVideoWithProtocol:newVideoProtocol]; + } + } } } -- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { - if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { - return; - } - - if (oldProtocol != nil) { - [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { - [self.secondaryTransportManager disconnectSecondaryTransport]; - }]; - } - - if (newProtocol != nil) { - [self.streamManager startVideoWithProtocol:newProtocol]; - } -} +//- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { +// if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { +// return; +// } +// +// if (oldProtocol != nil) { +// [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { +// [self.secondaryTransportManager disconnectSecondaryTransport]; +// }]; +// } +// if (newProtocol != nil) { +// [self.streamManager startAudioWithProtocol:newProtocol]; +// } +//} +// +//- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { +// if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { +// return; +// } +// +// if (oldProtocol != nil) { +// [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { +// [self.secondaryTransportManager disconnectSecondaryTransport]; +// }]; +// } +// +// if (newProtocol != nil) { +// [self.streamManager startVideoWithProtocol:newProtocol]; +// } +//} @end diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 65e1f9f53..a94f2c1f2 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -11,6 +11,7 @@ #import "SDLSecondaryTransportManager.h" +#import "SDLBackgroundTaskManager.h" #import "SDLControlFramePayloadConstants.h" #import "SDLControlFramePayloadRPCStartServiceAck.h" #import "SDLControlFramePayloadTransportEventUpdate.h" @@ -98,10 +99,14 @@ @interface SDLSecondaryTransportManager () // App is ready to set security manager to secondary protocol @property (assign, nonatomic, getter=isAppReady) BOOL appReady; +@property (copy, nonatomic) SDLBackgroundTaskManager *backgroundTaskManager; + @end @implementation SDLSecondaryTransportManager +NSString *const BackgroundTaskSecondaryTransportName = @"com.sdl.transport.secondaryTransportBackgroundTask"; + #pragma mark - Public - (instancetype)initWithStreamingProtocolDelegate:(id)streamingProtocolDelegate @@ -122,6 +127,8 @@ - (instancetype)initWithStreamingProtocolDelegate:(id *secureMakes; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; +@property (nonatomic, copy, nullable) void (^audioEndServiceReceivedHandler)(BOOL success); + @end @implementation SDLStreamingAudioLifecycleManager @@ -102,6 +104,26 @@ - (void)stop { [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } +- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + self.audioEndServiceReceivedHandler = completionHandler; + + // Can't sent procol to `nil` else we will not get a response to the end audio service control frame + + // _hmiLevel = SDLHMILevelNone; + _connectedVehicleMake = nil; + + if (self.isAudioConnected) { + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateShuttingDown]; + } else { + SDLLogV(@"No audio currently streaming. No need to send an end audio service request"); + return completionHandler(NO); + } +} + +- (void)closeProtocol { + self.protocol = nil; +} + - (BOOL)sendAudioData:(NSData*)audioData { if (!self.isAudioConnected) { return NO; @@ -176,11 +198,12 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA } - (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAck { - SDLLogD(@"Audio service started"); + SDLLogW(@"Audio start ACKed"); + //SDLLogD(@"Audio service started"); _audioEncrypted = audioStartServiceAck.header.encrypted; SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:audioStartServiceAck.payload]; - SDLLogV(@"ACK: %@", audioAckPayload); + //SDLLogV(@"ACK: %@", audioAckPayload); if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio]; @@ -197,7 +220,8 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN } - (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNak { - SDLLogW(@"Audio service failed to start due to NAK"); + SDLLogW(@"Audio start NAKed"); + //SDLLogW(@"Audio service failed to start due to NAK"); [self sdl_transitionToStoppedState:SDLServiceTypeAudio]; } @@ -205,14 +229,24 @@ - (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNa - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogD(@"Audio service ended successfully"); + SDLLogW(@"Audio end ACKed"); + //SDLLogD(@"Audio service ended successfully"); + + if (self.audioEndServiceReceivedHandler != nil) { + self.audioEndServiceReceivedHandler(YES); + } [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogE(@"Audio service did not end successfully"); + SDLLogW(@"Audio end NAKed"); + //SDLLogE(@"Audio service did not end successfully"); + + if (self.audioEndServiceReceivedHandler != nil) { + self.audioEndServiceReceivedHandler(NO); + } [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; } @@ -295,12 +329,8 @@ - (void)sdl_stopAudioSession { } - (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { - switch (serviceType) { - case SDLServiceTypeAudio: - [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; - break; - default: break; - } + if (serviceType != SDLServiceTypeAudio) { return; } + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } #pragma mark Setters / Getters diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 6289734c8..f1c478351 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -152,6 +152,10 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopAudio; +- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; + +- (void)destroyAudioProtocol; + /** * Stop the video feature of the manager. This method is used internally. */ @@ -159,6 +163,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +- (void)destroyVideoProtocol; /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index c0b2302c1..41f8b0c10 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -76,6 +76,16 @@ - (void)stopAudio { self.audioStarted = NO; } +- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + __weak typeof(self) weakSelf = self; + [self.audioLifecycleManager stopWithCompletionHandler:^(BOOL success) { + weakSelf.audioStarted = NO; + + if (completionHandler == nil) { return; } + return completionHandler(success); + }]; +} + - (void)stopVideo { [self.videoLifecycleManager stop]; self.videoStarted = NO; @@ -91,6 +101,14 @@ - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completio }]; } +- (void)destroyVideoProtocol { + [self.videoLifecycleManager closeProtocol]; +} + +- (void)destroyAudioProtocol { + [self.audioLifecycleManager closeProtocol]; +} + - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self.videoLifecycleManager sendVideoData:imageBuffer]; } diff --git a/SmartDeviceLink/SDLStreamingProtocolDelegate.h b/SmartDeviceLink/SDLStreamingProtocolDelegate.h index b3ec8f78a..550705797 100644 --- a/SmartDeviceLink/SDLStreamingProtocolDelegate.h +++ b/SmartDeviceLink/SDLStreamingProtocolDelegate.h @@ -23,7 +23,7 @@ NS_ASSUME_NONNULL_BEGIN * @param oldProtocol protocol instance that has been used for audio streaming. * @param newProtocol protocol instance that will be used for audio streaming. */ -- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; +//- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; /** * Called when protocol instance for video service has been updated. @@ -34,7 +34,10 @@ NS_ASSUME_NONNULL_BEGIN * @param oldProtocol protocol instance that has been used for video streaming. * @param newProtocol protocol instance that will be used for video streaming. */ -- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; +//- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; + +- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; + @end diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 020902a39..1a8a8f467 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -158,9 +158,10 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stop; - - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +- (void)closeProtocol; + /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 879a3ab7d..2449d1921 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -217,14 +217,14 @@ - (void)stop { - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { self.videoEndServiceReceivedHandler = completionHandler; - // Can't sent procol to `nil` else we will not get a response to the end service frame + // Can't sent procol to `nil` else we will not get a response to the end video service control frame _backgroundingPixelBuffer = NULL; _preferredFormatIndex = 0; _preferredResolutionIndex = 0; - _hmiLevel = SDLHMILevelNone; - _videoStreamingState = SDLVideoStreamingStateNotStreamable; +// _hmiLevel = SDLHMILevelNone; +// _videoStreamingState = SDLVideoStreamingStateNotStreamable; _lastPresentationTimestamp = kCMTimeInvalid; _connectedVehicleMake = nil; @@ -238,6 +238,10 @@ - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHand } } +- (void)closeProtocol { + self.protocol = nil; +} + - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self sendVideoData:imageBuffer presentationTimestamp:kCMTimeInvalid]; } @@ -378,6 +382,11 @@ - (void)didEnterStateVideoStreamStopped { _videoEncoder = nil; } + _backgroundingPixelBuffer = NULL; + _preferredFormatIndex = 0; + _preferredResolutionIndex = 0; + _lastPresentationTimestamp = kCMTimeInvalid; + [self disposeDisplayLink]; [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStopNotification object:nil]; @@ -515,16 +524,16 @@ - (void)didEnterStateVideoStreamShuttingDown { - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - [self sdl_handleVideoStartServiceAck:startServiceACK]; } - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAck { - SDLLogD(@"Video service started"); + SDLLogW(@"Video Start ACKed"); + //SDLLogD(@"Video service started"); _videoEncrypted = videoStartServiceAck.header.encrypted; SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:videoStartServiceAck.payload]; - SDLLogV(@"ACK: %@", videoAckPayload); + //SDLLogV(@"ACK payload: %@", videoAckPayload); if (videoAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)videoAckPayload.mtu forServiceType:SDLServiceTypeVideo]; @@ -559,9 +568,11 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN } - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNak { - SDLLogW(@"Video service failed to start due to NAK"); + SDLLogW(@"Video Start NAKed"); + + //SDLLogW(@"Video service failed to start due to NAK"); SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:videoStartServiceNak.payload]; - SDLLogD(@"NAK: %@", videoStartServiceNak); + //SDLLogD(@"NAK parameters: %@", nakPayload); // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { @@ -587,17 +598,20 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogD(@"Video service ended successfully"); + SDLLogW(@"Video End ACKed"); + //SDLLogD(@"Video service ended successfully"); if (self.videoEndServiceReceivedHandler != nil) { - [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; self.videoEndServiceReceivedHandler(YES); } + + [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogE(@"Video service did not end successfully"); + SDLLogW(@"Video End NAKed"); + //SDLLogE(@"Video service did not end successfully"); if (self.videoEndServiceReceivedHandler != nil) { self.videoEndServiceReceivedHandler(NO); @@ -739,13 +753,13 @@ - (void)sdl_stopVideoSession { if (self.isVideoConnected || self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; } else { - SDLLogV(@"No video currently streaming. Will not send an end video service request"); + SDLLogV(@"no video streaming but we are going to send an end service anyways"); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; } } - (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { if (serviceType != SDLServiceTypeVideo) { return; } - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index e84f72bd0..ada9a5366 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -15,14 +15,13 @@ NS_ASSUME_NONNULL_BEGIN NSString *const TCPIOThreadName = @"com.smartdevicelink.tcpiothread"; -NSTimeInterval const IOThreadWaitSecs = 1.0; NSUInteger const DefaultReceiveBufferSize = 16 * 1024; NSTimeInterval ConnectionTimeoutSecs = 30.0; @interface SDLTCPTransport () @property (nullable, nonatomic, strong) NSThread *ioThread; -@property (nonatomic, strong) dispatch_semaphore_t ioThreadStoppedSemaphore; +//@property (nonatomic, strong) dispatch_semaphore_t ioThreadStoppedSemaphore; @property (nonatomic, assign) NSUInteger receiveBufferSize; @property (nonatomic, strong) SDLMutableDataQueue *sendDataQueue; @property (nullable, nonatomic, strong) NSInputStream *inputStream; @@ -78,7 +77,7 @@ - (void)connect { self.ioThread = [[NSThread alloc] initWithTarget:self selector:@selector(sdl_tcpTransportEventLoop) object:nil]; self.ioThread.name = TCPIOThreadName; - self.ioThreadStoppedSemaphore = dispatch_semaphore_create(0); + // self.ioThreadStoppedSemaphore = dispatch_semaphore_create(0); CFReadStreamRef readStream = NULL; CFWriteStreamRef writeStream = NULL; @@ -106,12 +105,14 @@ - (void)disconnect { [self sdl_cancelIOThread]; - long ret = dispatch_semaphore_wait(self.ioThreadStoppedSemaphore, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(IOThreadWaitSecs * NSEC_PER_SEC))); - if (ret == 0) { - SDLLogD(@"TCP transport thread stopped"); - } else { - SDLLogE(@"Failed to stop TCP transport thread"); + // Calling `dispatch_semaphore_wait` freezes the thread so shutdown never occurs `cancel` never gets called + if (self.ioThread != nil) { + [self sdl_teardownStream:self.inputStream]; + [self sdl_teardownStream:self.outputStream]; + + [self.connectionTimer invalidate]; } + self.ioThread = nil; self.inputStream = nil; @@ -145,7 +146,7 @@ - (void)sdl_tcpTransportEventLoop { [self.inputStream open]; [self.outputStream open]; - while (![self.ioThread isCancelled]) { + while (self.ioThread != nil && ![self.ioThread isCancelled]) { BOOL ret = [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; if (!ret) { SDLLogW(@"Failed to start TCP transport run loop"); @@ -158,8 +159,6 @@ - (void)sdl_tcpTransportEventLoop { [self sdl_teardownStream:self.outputStream]; [self.connectionTimer invalidate]; - - dispatch_semaphore_signal(self.ioThreadStoppedSemaphore); } } @@ -179,7 +178,8 @@ - (void)sdl_teardownStream:(NSStream *)stream { - (void)sdl_cancelIOThread { [self.ioThread cancel]; - // wake up the run loop in case we don't have any I/O event + + // Wake up the run loop in case we don't have any I/O event [self performSelector:@selector(sdl_doNothing) onThread:self.ioThread withObject:nil waitUntilDone:NO]; } From d3d6d7fbe0035aed4be250f8810fefcba4cbea15 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 19 Feb 2020 15:08:54 -0500 Subject: [PATCH 031/152] Fixed log message --- SmartDeviceLink/SDLProtocol.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m index f71da8354..0d07071e7 100644 --- a/SmartDeviceLink/SDLProtocol.m +++ b/SmartDeviceLink/SDLProtocol.m @@ -688,7 +688,7 @@ - (void)sdl_logControlNAKPayload:(SDLProtocolMessage *)nakMessage { SDLControlFramePayloadNak *endServiceNakPayload = [[SDLControlFramePayloadNak alloc] initWithData:nakMessage.payload]; NSArray *rejectedParams = endServiceNakPayload.rejectedParams; if (rejectedParams.count > 0) { - SDLLogE(@"Start Service NAK'd, service type: %@, rejectedParams: %@", @(nakMessage.header.serviceType), rejectedParams); + SDLLogE(@"%@ Service NAK'd, service type: %@, rejectedParams: %@", (nakMessage.header.frameData == SDLFrameInfoStartServiceACK) ? @"Start" : @"End", @(nakMessage.header.serviceType), rejectedParams); } } } break; From 0e49c5aed6f7d4de426a14cbc7672b5d38cf7958 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 19 Feb 2020 15:09:01 -0500 Subject: [PATCH 032/152] reset handler --- .../SDLStreamingAudioLifecycleManager.m | 15 +++++++++------ .../SDLStreamingVideoLifecycleManager.m | 19 +++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index af6bfab2f..77cb94240 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -112,12 +112,13 @@ - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHand // _hmiLevel = SDLHMILevelNone; _connectedVehicleMake = nil; - if (self.isAudioConnected) { - [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateShuttingDown]; - } else { - SDLLogV(@"No audio currently streaming. No need to send an end audio service request"); - return completionHandler(NO); - } + [self.protocol endServiceWithType:SDLServiceTypeAudio]; +// if (self.isAudioConnected) { +// [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateShuttingDown]; +// } else { +// SDLLogV(@"No audio currently streaming. No need to send an end audio service request"); +// return completionHandler(NO); +// } } - (void)closeProtocol { @@ -234,6 +235,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (self.audioEndServiceReceivedHandler != nil) { self.audioEndServiceReceivedHandler(YES); + self.audioEndServiceReceivedHandler = nil; } [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; @@ -246,6 +248,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (self.audioEndServiceReceivedHandler != nil) { self.audioEndServiceReceivedHandler(NO); + self.audioEndServiceReceivedHandler = nil; } [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 2449d1921..0f911af44 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -94,8 +94,6 @@ @interface SDLStreamingVideoLifecycleManager() @property (nonatomic, copy, nullable) void (^videoEndServiceReceivedHandler)(BOOL success); -@property (nonatomic, copy, nullable) void (^audioDataReceivedHandler)(NSData *__nullable audioData); - @end @implementation SDLStreamingVideoLifecycleManager @@ -230,12 +228,15 @@ - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHand [self.videoScaleManager stop]; - if (self.isVideoConnected || self.isVideoSuspended) { - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; - } else { - SDLLogV(@"No video currently streaming. No need to send an end video service request"); - return completionHandler(NO); - } + // Always send an end service, regardless of whether video is streaming or not + + [self.protocol endServiceWithType:SDLServiceTypeVideo]; +// if (![self.currentVideoStreamState isEqualToEnum:SDLVideoStreamManagerStateStopped]) { +// [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; +// } else { +// SDLLogV(@"No video currently streaming. No need to send an end video service request"); +// return completionHandler(NO); +// } } - (void)closeProtocol { @@ -603,6 +604,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (self.videoEndServiceReceivedHandler != nil) { self.videoEndServiceReceivedHandler(YES); + self.videoEndServiceReceivedHandler = nil; } [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; @@ -615,6 +617,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (self.videoEndServiceReceivedHandler != nil) { self.videoEndServiceReceivedHandler(NO); + self.videoEndServiceReceivedHandler = nil; } [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; From 1f975198a6b64b1e0b1022e33e3cb236ad0d881d Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 19 Feb 2020 17:03:01 -0500 Subject: [PATCH 033/152] Added logs --- SmartDeviceLink/SDLH264VideoEncoder.m | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 3888a412c..eb1bf96b8 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -64,6 +64,7 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: OSStatus status; // Create a compression session + SDLLogW(@"compression session width %f x height %f", dimensions.width, dimensions.height); status = VTCompressionSessionCreate(NULL, (int32_t)dimensions.width, (int32_t)dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); if (status != noErr) { @@ -199,6 +200,14 @@ - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { #pragma mark - Private #pragma mark Callback + + +/// Callback function that VideoToolbox calls when encoding is complete. +/// @param outputCallbackRefCon The callback's reference value +/// @param sourceFrameRefCon The frame's reference value +/// @param status Returns `noErr` if compression was successful;error if not successful +/// @param infoFlags Information about the encode operation (frame dropped or if encode ran asynchronously) +/// @param sampleBuffer Contains the compressed frame if compression was successful and the frame was not dropped; null otherwise void sdl_videoEncoderOutputCallback(void * CM_NULLABLE outputCallbackRefCon, void * CM_NULLABLE sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CM_NULLABLE CMSampleBufferRef sampleBuffer) { // If there was an error in the encoding, drop the frame if (status != noErr) { From f7e810736e4ba73c5a8279128ce868e83ba968ba Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 19 Feb 2020 17:03:26 -0500 Subject: [PATCH 034/152] Fix for video ack screen size being 0 --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 0f911af44..51cc8d969 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -226,7 +226,8 @@ - (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHand _lastPresentationTimestamp = kCMTimeInvalid; _connectedVehicleMake = nil; - [self.videoScaleManager stop]; + // Don't reset the dimensions - seems to be a video start service bug + //[self.videoScaleManager stop]; // Always send an end service, regardless of whether video is streaming or not @@ -409,6 +410,8 @@ - (void)didEnterStateVideoStreamStarting { weakSelf.videoEncoderSettings[(__bridge NSString *) kVTCompressionPropertyKey_AverageBitRate] = [[NSNumber alloc] initWithUnsignedLongLong:(capability.maxBitrate.unsignedLongLongValue * 1000)]; } + weakSelf.videoScaleManager.displayViewportResolution = CGSizeMake(capability.preferredResolution.resolutionWidth.floatValue, capability.preferredResolution.resolutionHeight.floatValue); + if (weakSelf.dataSource != nil) { SDLLogV(@"Calling data source for modified preferred formats"); weakSelf.preferredFormats = [weakSelf.dataSource preferredVideoFormatOrderFromHeadUnitPreferredOrder:weakSelf.preferredFormats]; @@ -541,8 +544,8 @@ - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAc } // This is the definitive screen size that will be used - if (videoAckPayload.height != SDLControlFrameInt32NotFound && videoAckPayload.width != SDLControlFrameInt32NotFound) { - self.videoScaleManager.displayViewportResolution = CGSizeMake(videoAckPayload.width, videoAckPayload.height); + if ((videoAckPayload.height != SDLControlFrameInt32NotFound || videoAckPayload.height != 0) && (videoAckPayload.width != SDLControlFrameInt32NotFound && videoAckPayload.width != 0)) { + self.videoScaleManager.displayViewportResolution = CGSizeMake(videoAckPayload.width, videoAckPayload.height); } else if (self.preferredResolutions.count > 0) { // If a preferred resolution was set, use the first option to set the screen size SDLImageResolution *preferredResolution = self.preferredResolutions.firstObject; From eabd306d65eb631f51eafa0d5dd864dc224a5452 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 20 Feb 2020 09:14:51 -0500 Subject: [PATCH 035/152] Removed duplicate saving video resolution --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 51cc8d969..c0ea933b3 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -410,8 +410,6 @@ - (void)didEnterStateVideoStreamStarting { weakSelf.videoEncoderSettings[(__bridge NSString *) kVTCompressionPropertyKey_AverageBitRate] = [[NSNumber alloc] initWithUnsignedLongLong:(capability.maxBitrate.unsignedLongLongValue * 1000)]; } - weakSelf.videoScaleManager.displayViewportResolution = CGSizeMake(capability.preferredResolution.resolutionWidth.floatValue, capability.preferredResolution.resolutionHeight.floatValue); - if (weakSelf.dataSource != nil) { SDLLogV(@"Calling data source for modified preferred formats"); weakSelf.preferredFormats = [weakSelf.dataSource preferredVideoFormatOrderFromHeadUnitPreferredOrder:weakSelf.preferredFormats]; From 979e54a1e42a4e9d12e6120a7a9d51022e99e3bc Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 11:14:10 -0500 Subject: [PATCH 036/152] Added documentation --- SmartDeviceLink/SDLLifecycleManager.m | 45 ++++++++-------- SmartDeviceLink/SDLStreamingMediaManager.m | 4 +- .../SDLStreamingVideoLifecycleManager.h | 14 +++-- .../SDLStreamingVideoLifecycleManager.m | 52 +++++++++---------- 4 files changed, 61 insertions(+), 54 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 6ac6de6b4..3316aabf8 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -877,50 +877,49 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto BOOL audioProtocolUpdated = ((oldAudioProtocol == nil && newAudioProtocol == nil) || (oldAudioProtocol == newAudioProtocol)) ? NO : YES; if (videoProtocolUpdated && audioProtocolUpdated) { - // Stop both audio and video session before destroying the transport if (oldVideoProtocol != nil && oldAudioProtocol != nil) { + // Both an audio and video service are currently running. Make sure both audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; [self.streamManager destroyAudioProtocol]; [self.streamManager destroyVideoProtocol]; - - if (newAudioProtocol != nil) { - [self.streamManager startAudioWithProtocol:newAudioProtocol]; - } - if (newVideoProtocol != nil) { - [self.streamManager startVideoWithProtocol:newVideoProtocol]; - } + [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; }]; }]; } else if (oldVideoProtocol != nil) { + // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; - - if (newVideoProtocol != nil) { - [self.streamManager startVideoWithProtocol:newVideoProtocol]; - } + [self.streamManager destroyVideoProtocol]; + [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; }]; } else if (oldAudioProtocol != nil) { + // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; - - if (newAudioProtocol != nil) { - [self.streamManager startAudioWithProtocol:newAudioProtocol]; - } + [self.streamManager destroyAudioProtocol]; + [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; }]; } else { - // Both old audio and video protocols are nil - if (newAudioProtocol != nil) { - [self.streamManager startAudioWithProtocol:newAudioProtocol]; - } - if (newVideoProtocol != nil) { - [self.streamManager startVideoWithProtocol:newVideoProtocol]; - } + // No audio and/or video service currently running. Just start the new audio and/or video service. + [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; } } } +/// Starts the audio and/or video services using the new protocol. +/// @param newAudioProtocol The new audio protocol +/// @param newVideoProtocol The new video protocol +- (void)sdl_startNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol startNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol { + if (newAudioProtocol != nil) { + [self.streamManager startAudioWithProtocol:newAudioProtocol]; + } + if (newVideoProtocol != nil) { + [self.streamManager startVideoWithProtocol:newVideoProtocol]; + } +} + //- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { // if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { // return; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 41f8b0c10..225acb4a1 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -93,7 +93,7 @@ - (void)stopVideo { - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; - [self.videoLifecycleManager stopWithCompletionHandler:^(BOOL success) { + [self.videoLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { weakSelf.videoStarted = NO; if (completionHandler == nil) { return; } @@ -102,7 +102,7 @@ - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completio } - (void)destroyVideoProtocol { - [self.videoLifecycleManager closeProtocol]; + [self.videoLifecycleManager destroyProtocol]; } - (void)destroyAudioProtocol { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 1a8a8f467..b911459f5 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -154,13 +154,21 @@ NS_ASSUME_NONNULL_BEGIN - (void)startWithProtocol:(SDLProtocol *)protocol; /** - * Stop the manager. This method is used internally. + * This method is used internally to stop the manager when the device disconnects from the module. */ - (void)stop; -- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +/** + * This method is used internally to end a video service on the secondary transport. The primary transport is still open. + * + * @param completionHandler Called when the module ACKs or NAKs to the request to end the video service. + */ +- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; -- (void)closeProtocol; +/** + * This method is used internally to destroy the protocol after the secondary transport is shut down. + */ +- (void)destroyProtocol; /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index c0ea933b3..9902bf6fa 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -195,53 +195,53 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { [self sdl_startVideoSession]; } + +/// Stops the manager when the device disconnects from the module. - (void)stop { SDLLogD(@"Stopping video streaming lifecycle manager"); - _protocol = nil; + // Reset the video streaming parameters as video is not streaming. _backgroundingPixelBuffer = NULL; _preferredFormatIndex = 0; _preferredResolutionIndex = 0; + _lastPresentationTimestamp = kCMTimeInvalid; + // Reset the `hmiLevel` and `videoStreamingState`. This is done because we will not get a notification with the updated hmi status due to the transport being destroyed. _hmiLevel = SDLHMILevelNone; _videoStreamingState = SDLVideoStreamingStateNotStreamable; - _lastPresentationTimestamp = kCMTimeInvalid; - _connectedVehicleMake = nil; + // Since the transport layer has been destroyed, destroy the protocol as it is not usable. + _protocol = nil; + + // Reset the video scale manager because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. [self.videoScaleManager stop]; + + // Reset the `connectedVehicleMake` because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. It is possible that the user could connect to different module during the same app session. + _connectedVehicleMake = nil; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } -- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +// Stops the manager when video needs to be stopped on the secondary transport. The primary transport is still open. +// 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` since we can still get notifications from the module with the updated hmi status on the primary transport. +// 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. +// 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). +- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { self.videoEndServiceReceivedHandler = completionHandler; - // Can't sent procol to `nil` else we will not get a response to the end video service control frame + // Always send an end video service control frame, regardless of whether video is streaming or not. + [self.protocol endServiceWithType:SDLServiceTypeVideo]; +} +/// Used internally to destroy the protocol after the secondary transport is shut down. +- (void)destroyProtocol { + self.protocol = nil; + + // Reset the video streaming parameters as video is not streaming. _backgroundingPixelBuffer = NULL; _preferredFormatIndex = 0; _preferredResolutionIndex = 0; - -// _hmiLevel = SDLHMILevelNone; -// _videoStreamingState = SDLVideoStreamingStateNotStreamable; _lastPresentationTimestamp = kCMTimeInvalid; - _connectedVehicleMake = nil; - - // Don't reset the dimensions - seems to be a video start service bug - //[self.videoScaleManager stop]; - - // Always send an end service, regardless of whether video is streaming or not - - [self.protocol endServiceWithType:SDLServiceTypeVideo]; -// if (![self.currentVideoStreamState isEqualToEnum:SDLVideoStreamManagerStateStopped]) { -// [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; -// } else { -// SDLLogV(@"No video currently streaming. No need to send an end video service request"); -// return completionHandler(NO); -// } -} - -- (void)closeProtocol { - self.protocol = nil; } - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { From 977a27e8541a67de65d449254e16793dcc307102 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 11:36:18 -0500 Subject: [PATCH 037/152] Refactored audioSLM method names --- .../SDLStreamingAudioLifecycleManager.h | 14 ++++- .../SDLStreamingAudioLifecycleManager.m | 56 ++++++++----------- SmartDeviceLink/SDLStreamingMediaManager.m | 4 +- .../SDLStreamingVideoLifecycleManager.m | 35 +++--------- 4 files changed, 46 insertions(+), 63 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index cc81887bf..54e094c54 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -77,13 +77,21 @@ NS_ASSUME_NONNULL_BEGIN - (void)startWithProtocol:(SDLProtocol *)protocol; /** - * Stop the manager. This method is used internally. + * This method is used internally to stop the manager when the device disconnects from the module. */ - (void)stop; -- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +/** + * This method is used internally to end an audio service on the secondary transport. The primary transport is still open. + * + * @param completionHandler Called when the module ACKs or NAKs to the request to end the audio service. +*/ +- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; -- (void)closeProtocol; +/** + * This method is used internally to destroy the protocol after the secondary transport is shut down. + */ +- (void)destroyProtocol; /** * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 77cb94240..e56556e6f 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -96,32 +96,35 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { [self sdl_startAudioSession]; } +/// Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. - (void)stop { SDLLogD(@"Stopping audio streaming lifecycle manager"); + + // Since the transport layer has been destroyed, destroy the protocol as it is not usable. _protocol = nil; + + // Reset the `hmiLevel`. This is done because we will not get a notification with the updated hmi status due to the transport being destroyed. _hmiLevel = SDLHMILevelNone; + + // Reset the `connectedVehicleMake` because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. It is possible that the user could connect to different module during the same app session. _connectedVehicleMake = nil; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } -- (void)stopWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +// Stops the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. +// 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. +// 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. +- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + SDLLogD(@"Stopping audio streaming"); self.audioEndServiceReceivedHandler = completionHandler; - // Can't sent procol to `nil` else we will not get a response to the end audio service control frame - - // _hmiLevel = SDLHMILevelNone; - _connectedVehicleMake = nil; - + // Always send an end audio service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeAudio]; -// if (self.isAudioConnected) { -// [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateShuttingDown]; -// } else { -// SDLLogV(@"No audio currently streaming. No need to send an end audio service request"); -// return completionHandler(NO); -// } } -- (void)closeProtocol { +/// Used internally to destroy the protocol after the secondary transport is shut down. +- (void)destroyProtocol { self.protocol = nil; } @@ -191,19 +194,16 @@ - (void)didEnterStateAudioStreamShuttingDown { } #pragma mark - SDLProtocolListener -#pragma mark Start Service ACK +#pragma mark Start Service ACK/NAK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - [self sdl_handleAudioStartServiceAck:startServiceACK]; -} -- (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAck { - SDLLogW(@"Audio start ACKed"); + SDLLogW(@"Request to start audio service ACKed"); //SDLLogD(@"Audio service started"); - _audioEncrypted = audioStartServiceAck.header.encrypted; + _audioEncrypted = startServiceACK.header.encrypted; - SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:audioStartServiceAck.payload]; + SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:startServiceACK.payload]; //SDLLogV(@"ACK: %@", audioAckPayload); if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) { @@ -213,26 +213,19 @@ - (void)sdl_handleAudioStartServiceAck:(SDLProtocolMessage *)audioStartServiceAc [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateReady]; } -#pragma mark Start Service NAK - - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { if (startServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - [self sdl_handleAudioStartServiceNak:startServiceNAK]; -} + SDLLogW(@"Request to start audio service NAKed"); -- (void)sdl_handleAudioStartServiceNak:(SDLProtocolMessage *)audioStartServiceNak { - SDLLogW(@"Audio start NAKed"); - //SDLLogW(@"Audio service failed to start due to NAK"); [self sdl_transitionToStoppedState:SDLServiceTypeAudio]; } -#pragma mark End Service +#pragma mark End Service ACK/NAK - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Audio end ACKed"); - //SDLLogD(@"Audio service ended successfully"); + SDLLogW(@"Request to end audio service ACKed"); if (self.audioEndServiceReceivedHandler != nil) { self.audioEndServiceReceivedHandler(YES); self.audioEndServiceReceivedHandler = nil; @@ -243,9 +236,8 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Audio end NAKed"); - //SDLLogE(@"Audio service did not end successfully"); + SDLLogW(@"Request to end audio service ACKed"); if (self.audioEndServiceReceivedHandler != nil) { self.audioEndServiceReceivedHandler(NO); self.audioEndServiceReceivedHandler = nil; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 225acb4a1..ac59a0a75 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -78,7 +78,7 @@ - (void)stopAudio { - (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager stopWithCompletionHandler:^(BOOL success) { + [self.audioLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { weakSelf.audioStarted = NO; if (completionHandler == nil) { return; } @@ -106,7 +106,7 @@ - (void)destroyVideoProtocol { } - (void)destroyAudioProtocol { - [self.audioLifecycleManager closeProtocol]; + [self.audioLifecycleManager destroyProtocol]; } - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 9902bf6fa..28e3d0c75 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -196,7 +196,7 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { } -/// Stops the manager when the device disconnects from the module. +/// Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end video service control frame as the module will never receive the request. - (void)stop { SDLLogD(@"Stopping video streaming lifecycle manager"); @@ -522,20 +522,15 @@ - (void)didEnterStateVideoStreamShuttingDown { } #pragma mark - SDLProtocolListener -#pragma mark Start Service ACK +#pragma mark Start Service ACK/NAK - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - [self sdl_handleVideoStartServiceAck:startServiceACK]; -} -- (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAck { - SDLLogW(@"Video Start ACKed"); - //SDLLogD(@"Video service started"); - _videoEncrypted = videoStartServiceAck.header.encrypted; + SDLLogD(@"Request to start video service ACKed"); + _videoEncrypted = startServiceACK.header.encrypted; - SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:videoStartServiceAck.payload]; - //SDLLogV(@"ACK payload: %@", videoAckPayload); + SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:startServiceACK.payload]; if (videoAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)videoAckPayload.mtu forServiceType:SDLServiceTypeVideo]; @@ -558,23 +553,13 @@ - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAc self.videoFormat = [[SDLVideoStreamingFormat alloc] init]; self.videoFormat.codec = videoAckPayload.videoCodec ?: SDLVideoStreamingCodecH264; self.videoFormat.protocol = videoAckPayload.videoProtocol ?: SDLVideoStreamingProtocolRAW; - - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateReady]; } -#pragma mark Start Service NAK - - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { if (startServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - [self sdl_handleVideoStartServiceNak:startServiceNAK]; -} - -- (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNak { - SDLLogW(@"Video Start NAKed"); - //SDLLogW(@"Video service failed to start due to NAK"); - SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:videoStartServiceNak.payload]; - //SDLLogD(@"NAK parameters: %@", nakPayload); + SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:startServiceNAK.payload]; + SDLLogE(@"Request to start video service NAKed with reason: %@", nakPayload.description); // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { @@ -600,9 +585,8 @@ - (void)sdl_handleVideoStartServiceNak:(SDLProtocolMessage *)videoStartServiceNa - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogW(@"Video End ACKed"); - //SDLLogD(@"Video service ended successfully"); + SDLLogD(@"Request to end video service ACKed"); if (self.videoEndServiceReceivedHandler != nil) { self.videoEndServiceReceivedHandler(YES); self.videoEndServiceReceivedHandler = nil; @@ -613,9 +597,8 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogW(@"Video End NAKed"); - //SDLLogE(@"Video service did not end successfully"); + SDLLogE(@"Request to end video service NAKed"); if (self.videoEndServiceReceivedHandler != nil) { self.videoEndServiceReceivedHandler(NO); self.videoEndServiceReceivedHandler = nil; From 0ff5a353cd6e59b2fc73cb7406698a53ac5f5fed Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 11:58:08 -0500 Subject: [PATCH 038/152] Renamed vars & added documentation --- SmartDeviceLink/SDLLifecycleManager.m | 35 ++----------------- .../SDLStreamingAudioLifecycleManager.h | 5 ++- .../SDLStreamingAudioLifecycleManager.m | 18 +++++----- SmartDeviceLink/SDLStreamingMediaManager.m | 2 ++ .../SDLStreamingVideoLifecycleManager.h | 6 ++-- .../SDLStreamingVideoLifecycleManager.m | 20 +++++------ 6 files changed, 31 insertions(+), 55 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 3316aabf8..befd567d1 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -878,7 +878,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto if (videoProtocolUpdated && audioProtocolUpdated) { if (oldVideoProtocol != nil && oldAudioProtocol != nil) { - // Both an audio and video service are currently running. Make sure both audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. + // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; @@ -902,7 +902,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; }]; } else { - // No audio and/or video service currently running. Just start the new audio and/or video service. + // No audio and/or video service currently running. Just start the new audio and/or video services. [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; } } @@ -920,37 +920,6 @@ - (void)sdl_startNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol start } } -//- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { -// if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { -// return; -// } -// -// if (oldProtocol != nil) { -// [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { -// [self.secondaryTransportManager disconnectSecondaryTransport]; -// }]; -// } -// if (newProtocol != nil) { -// [self.streamManager startAudioWithProtocol:newProtocol]; -// } -//} -// -//- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol { -// if ((oldProtocol == nil && newProtocol == nil) || (oldProtocol == newProtocol)) { -// return; -// } -// -// if (oldProtocol != nil) { -// [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { -// [self.secondaryTransportManager disconnectSecondaryTransport]; -// }]; -// } -// -// if (newProtocol != nil) { -// [self.streamManager startVideoWithProtocol:newProtocol]; -// } -//} - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 54e094c54..b657ef8dd 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -21,6 +21,9 @@ @protocol SDLConnectionManagerType; +/// Called when an end audio service ACK or NAK has been received. +/// @param success True if the end service ACKed; False if NAKed. +typedef void (^SDLAudioEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -86,7 +89,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param completionHandler Called when the module ACKs or NAKs to the request to end the audio service. */ -- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +- (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler)audioEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index e56556e6f..0dc3138d7 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -43,7 +43,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (copy, nonatomic) NSArray *secureMakes; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; -@property (nonatomic, copy, nullable) void (^audioEndServiceReceivedHandler)(BOOL success); +@property (nonatomic, copy, nullable) SDLAudioEndedCompletionHandler audioEndedCompletionHandler; @end @@ -115,9 +115,9 @@ - (void)stop { // Stops the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. // 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. -- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +- (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler)completionHandler { SDLLogD(@"Stopping audio streaming"); - self.audioEndServiceReceivedHandler = completionHandler; + self.audioEndedCompletionHandler = completionHandler; // Always send an end audio service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeAudio]; @@ -226,9 +226,9 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogW(@"Request to end audio service ACKed"); - if (self.audioEndServiceReceivedHandler != nil) { - self.audioEndServiceReceivedHandler(YES); - self.audioEndServiceReceivedHandler = nil; + if (self.audioEndedCompletionHandler != nil) { + self.audioEndedCompletionHandler(YES); + self.audioEndedCompletionHandler = nil; } [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; @@ -238,9 +238,9 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogW(@"Request to end audio service ACKed"); - if (self.audioEndServiceReceivedHandler != nil) { - self.audioEndServiceReceivedHandler(NO); - self.audioEndServiceReceivedHandler = nil; + if (self.audioEndedCompletionHandler != nil) { + self.audioEndedCompletionHandler(NO); + self.audioEndedCompletionHandler = nil; } [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index ac59a0a75..a3f1d361c 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -19,6 +19,8 @@ NS_ASSUME_NONNULL_BEGIN + + @interface SDLStreamingMediaManager () @property (strong, nonatomic) SDLStreamingAudioLifecycleManager *audioLifecycleManager; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index b911459f5..c2fd64ecc 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -28,7 +28,9 @@ @protocol SDLFocusableItemLocatorType; @protocol SDLStreamingMediaManagerDataSource; - +/// Called when an end video service ACK or NAK has been received. +/// @param success True if the end service ACKed; False if NAKed. +typedef void (^SDLVideoEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -163,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param completionHandler Called when the module ACKs or NAKs to the request to end the video service. */ -- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +- (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler)videoEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 28e3d0c75..746519ffc 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -92,7 +92,7 @@ @interface SDLStreamingVideoLifecycleManager() @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; -@property (nonatomic, copy, nullable) void (^videoEndServiceReceivedHandler)(BOOL success); +@property (nonatomic, copy, nullable) SDLVideoEndedCompletionHandler videoEndedCompletionHandler; @end @@ -177,7 +177,7 @@ - (instancetype)initWithConnectionManager:(id)connecti _ssrc = arc4random_uniform(UINT32_MAX); _lastPresentationTimestamp = kCMTimeInvalid; - _videoEndServiceReceivedHandler = nil; + _videoEndedCompletionHandler = nil; return self; } @@ -226,8 +226,8 @@ - (void)stop { // 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. // 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). -- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { - self.videoEndServiceReceivedHandler = completionHandler; +- (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler)completionHandler { + self.videoEndedCompletionHandler = completionHandler; // Always send an end video service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeVideo]; @@ -587,9 +587,9 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogD(@"Request to end video service ACKed"); - if (self.videoEndServiceReceivedHandler != nil) { - self.videoEndServiceReceivedHandler(YES); - self.videoEndServiceReceivedHandler = nil; + if (self.videoEndedCompletionHandler != nil) { + self.videoEndedCompletionHandler(YES); + self.videoEndedCompletionHandler = nil; } [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; @@ -599,9 +599,9 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogE(@"Request to end video service NAKed"); - if (self.videoEndServiceReceivedHandler != nil) { - self.videoEndServiceReceivedHandler(NO); - self.videoEndServiceReceivedHandler = nil; + if (self.videoEndedCompletionHandler != nil) { + self.videoEndedCompletionHandler(NO); + self.videoEndedCompletionHandler = nil; } [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; From 9254ee684ac5f66cf6df1439f138c69a82ca5a83 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 13:50:33 -0500 Subject: [PATCH 039/152] Removed commented out code --- SmartDeviceLink/SDLLifecycleManager.m | 4 ---- 1 file changed, 4 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 515078957..bc0a60b84 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -281,8 +281,6 @@ - (void)sdl_stopManager:(BOOL)shouldRestart { } else { [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:self.proxy.protocol toNewVideoProtocol:nil fromOldAudioProtocol:self.proxy.protocol toNewAudioProtocol:nil]; -// [self audioServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; -// [self videoServiceProtocolDidUpdateFromOldProtocol:self.proxy.protocol toNewProtocol:nil]; } [self.systemCapabilityManager stop]; [self.responseDispatcher clear]; @@ -463,8 +461,6 @@ - (void)didEnterStateSettingUpManagers { // if secondary transport manager is used, streaming media manager will be started through onAudioServiceProtocolUpdated and onVideoServiceProtocolUpdated if (self.secondaryTransportManager == nil && self.streamManager != nil) { [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:self.proxy.protocol fromOldAudioProtocol:nil toNewAudioProtocol:self.proxy.protocol]; -// [self audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; -// [self videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:self.proxy.protocol]; } dispatch_group_enter(managerGroup); From 372c11e6b0675b67dec753b3233477e3f148225c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 13:54:19 -0500 Subject: [PATCH 040/152] Added documentation for new method --- SmartDeviceLink/SDLSecondaryTransportManager.h | 13 ++++++++----- SmartDeviceLink/SDLSecondaryTransportManager.m | 4 ---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 8e9f2e3ca..2855d21de 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -36,7 +36,7 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; */ @interface SDLSecondaryTransportManager : NSObject -/** state of this manager */ +// State of this manager @property (strong, nonatomic, readonly) SDLStateMachine *stateMachine; /** @@ -50,28 +50,31 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; serialQueue:(dispatch_queue_t)queue; /** - * Start the manager. + Start the manager. @param primaryProtocol protocol that runs on the main (primary) transport */ - (void)startWithPrimaryProtocol:(SDLProtocol *)primaryProtocol; /** - * Stop the manager. + Stop the manager. */ - (void)stop; +/** + Destroys the secondary transport. + */ - (BOOL)disconnectSecondaryTransport; /** - * Call this method when Start Service ACK control frame is received on primary transport. + Call this method when Start Service ACK control frame is received on primary transport. @param payload payload of Start Service ACK frame received on the primary transport */ - (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload; /** - * Call this method when Transport Event Update control frame is received on primary transport. + Call this method when Transport Event Update control frame is received on primary transport. @param payload payload of Transport Event Update frame received on the primary transport */ diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 2ab680bc7..b99609c06 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -308,15 +308,11 @@ - (void)willTransitionFromStateRegisteredToStateConfigured { // before disconnecting Secondary Transport, stop running services SDLLogD(@"Stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; - - // [self sdl_disconnectSecondaryTransport]; } - (void)willTransitionFromStateRegisteredToStateReconnecting { SDLLogD(@"Stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; - - //[self sdl_disconnectSecondaryTransport]; } - (void)willTransitionFromStateRegisteredToStateStopped { From f436c9ef9cba3609e6c1ef1eac49eb66a0fa1887 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 13:58:45 -0500 Subject: [PATCH 041/152] Removed commented out logs --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 0dc3138d7..f10433e44 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -200,11 +200,9 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogW(@"Request to start audio service ACKed"); - //SDLLogD(@"Audio service started"); _audioEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:startServiceACK.payload]; - //SDLLogV(@"ACK: %@", audioAckPayload); if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio]; From f655a4b84b6fdc40dcb57a268dd1764a13120051 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 14:01:47 -0500 Subject: [PATCH 042/152] Added documentation to methods --- SmartDeviceLink/SDLStreamingMediaManager.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index f1c478351..bb8a24701 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -152,8 +152,14 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopAudio; +/** +* Stops the audio feature of the manager on the secondary transport. This method is used internally. +*/ - (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +/** + * Destroys the audio transport protocol after the secondary transport has been shut down. This method is used internally. + */ - (void)destroyAudioProtocol; /** @@ -161,9 +167,16 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopVideo; +/** + * Stops the video feature of the manager on the secondary transport. This method is used internally. + */ - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; +/** + * Destroys the video service protocol after the secondary transport has been shut down. This method is used internally. + */ - (void)destroyVideoProtocol; + /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * From 8617155b2f2e2db4148b685c01a0100c3668fbbd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 14:06:58 -0500 Subject: [PATCH 043/152] Refactored the streaming media manager --- SmartDeviceLink/SDLStreamingMediaManager.m | 47 +++++++++++----------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index a3f1d361c..1c592d6f4 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -19,8 +19,6 @@ NS_ASSUME_NONNULL_BEGIN - - @interface SDLStreamingMediaManager () @property (strong, nonatomic) SDLStreamingAudioLifecycleManager *audioLifecycleManager; @@ -33,8 +31,7 @@ @interface SDLStreamingMediaManager () @implementation SDLStreamingMediaManager -#pragma mark - Public -#pragma mark Lifecycle +#pragma mark - Lifecycle - (instancetype)initWithConnectionManager:(id)connectionManager configuration:(SDLConfiguration *)configuration { self = [super init]; @@ -58,21 +55,18 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { [self startVideoWithProtocol:protocol]; } -- (void)startAudioWithProtocol:(SDLProtocol *)protocol { - [self.audioLifecycleManager startWithProtocol:protocol]; - self.audioStarted = YES; -} - -- (void)startVideoWithProtocol:(SDLProtocol *)protocol { - [self.videoLifecycleManager startWithProtocol:protocol]; - self.videoStarted = YES; -} - - (void)stop { [self stopAudio]; [self stopVideo]; } +#pragma mark - Audio + +- (void)startAudioWithProtocol:(SDLProtocol *)protocol { + [self.audioLifecycleManager startWithProtocol:protocol]; + self.audioStarted = YES; +} + - (void)stopAudio { [self.audioLifecycleManager stop]; self.audioStarted = NO; @@ -88,6 +82,21 @@ - (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completio }]; } +- (void)destroyAudioProtocol { + [self.audioLifecycleManager destroyProtocol]; +} + +- (BOOL)sendAudioData:(NSData*)audioData { + return [self.audioLifecycleManager sendAudioData:audioData]; +} + +#pragma mark - Video + +- (void)startVideoWithProtocol:(SDLProtocol *)protocol { + [self.videoLifecycleManager startWithProtocol:protocol]; + self.videoStarted = YES; +} + - (void)stopVideo { [self.videoLifecycleManager stop]; self.videoStarted = NO; @@ -107,10 +116,6 @@ - (void)destroyVideoProtocol { [self.videoLifecycleManager destroyProtocol]; } -- (void)destroyAudioProtocol { - [self.audioLifecycleManager destroyProtocol]; -} - - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self.videoLifecycleManager sendVideoData:imageBuffer]; } @@ -119,11 +124,6 @@ - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTim return [self.videoLifecycleManager sendVideoData:imageBuffer presentationTimestamp:presentationTimestamp]; } -- (BOOL)sendAudioData:(NSData*)audioData { - return [self.audioLifecycleManager sendAudioData:audioData]; -} - - #pragma mark - Getters - (SDLTouchManager *)touchManager { @@ -200,6 +200,7 @@ - (BOOL)showVideoBackgroundDisplay { } #pragma mark - Setters + - (void)setRootViewController:(nullable UIViewController *)rootViewController { self.videoLifecycleManager.rootViewController = rootViewController; } From 0aeca6c09a8b6ca4d38bf5f23ac7846c12ebdda8 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 21 Feb 2020 14:12:28 -0500 Subject: [PATCH 044/152] Cleaned up TCP transport classes and docs --- .../SDLStreamingProtocolDelegate.h | 30 +++++-------------- SmartDeviceLink/SDLTCPTransport.m | 7 +---- 2 files changed, 9 insertions(+), 28 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingProtocolDelegate.h b/SmartDeviceLink/SDLStreamingProtocolDelegate.h index 550705797..ff5a718af 100644 --- a/SmartDeviceLink/SDLStreamingProtocolDelegate.h +++ b/SmartDeviceLink/SDLStreamingProtocolDelegate.h @@ -14,28 +14,14 @@ NS_ASSUME_NONNULL_BEGIN @protocol SDLStreamingProtocolDelegate -/** - * Called when protocol instance for audio service has been updated. - * - * If `newProtocol` is nil, it indicates that underlying transport - * becomes unavailable. - * - * @param oldProtocol protocol instance that has been used for audio streaming. - * @param newProtocol protocol instance that will be used for audio streaming. - */ -//- (void)audioServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; - -/** - * Called when protocol instance for video service has been updated. - * - * If `newProtocol` is nil, it indicates that underlying transport - * becomes unavailable. - * - * @param oldProtocol protocol instance that has been used for video streaming. - * @param newProtocol protocol instance that will be used for video streaming. - */ -//- (void)videoServiceProtocolDidUpdateFromOldProtocol:(nullable SDLProtocol *)oldProtocol toNewProtocol:(nullable SDLProtocol *)newProtocol; - +/// Called when protocol instance for audio and/or video service has been updated. +/// +/// If `newVideoProtocol` or `newAudioProtocol` is nil, it indicates that underlying transport has become unavailable. +/// +/// @param oldVideoProtocol protocol instance that was being used for video streaming +/// @param newVideoProtocol protocol instance that will be used for video streaming +/// @param oldAudioProtocol protocol instance that was being used for audio streaming +/// @param newAudioProtocol protocol instance that will be used for audio streaming - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index 7c79aca48..3c94eddd4 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -21,7 +21,6 @@ @interface SDLTCPTransport () @property (nullable, nonatomic, strong) NSThread *ioThread; -//@property (nonatomic, strong) dispatch_semaphore_t ioThreadStoppedSemaphore; @property (nonatomic, assign) NSUInteger receiveBufferSize; @property (nonatomic, strong) SDLMutableDataQueue *sendDataQueue; @property (nullable, nonatomic, strong) NSInputStream *inputStream; @@ -77,7 +76,6 @@ - (void)connect { self.ioThread = [[NSThread alloc] initWithTarget:self selector:@selector(sdl_tcpTransportEventLoop) object:nil]; self.ioThread.name = TCPIOThreadName; - // self.ioThreadStoppedSemaphore = dispatch_semaphore_create(0); CFReadStreamRef readStream = NULL; CFWriteStreamRef writeStream = NULL; @@ -105,7 +103,6 @@ - (void)disconnect { [self sdl_cancelIOThread]; - // Calling `dispatch_semaphore_wait` freezes the thread so shutdown never occurs `cancel` never gets called if (self.ioThread != nil) { [self sdl_teardownStream:self.inputStream]; [self sdl_teardownStream:self.outputStream]; @@ -348,9 +345,7 @@ - (void)sdl_onStreamEnd:(NSStream *)stream { } } -- (void)sdl_doNothing { - SDLLogV(@"Doing nothing to trigger cancel"); -} +- (void)sdl_doNothing {} @end From c690aab7f62a810fa1cadf40b5630ffa83714a71 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 11:28:49 -0500 Subject: [PATCH 045/152] Refactored the transport updated code --- .../SDLSecondaryTransportManager.m | 43 ++++++++----------- 1 file changed, 17 insertions(+), 26 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index b99609c06..761c3bba0 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -62,6 +62,10 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { // Indicates that a TCP port is not specified (unconfigured). static const int TCPPortUnspecified = -1; +struct TransportUpdated { + SDLProtocol * _Nullable oldProtocol; + SDLProtocol * _Nullable newProtocol; +} transportUpdated; @interface SDLSecondaryTransportManager () @@ -335,35 +339,18 @@ - (void)didEnterStateReconnecting { #pragma mark - Starting / Stopping / Restarting services - (void)sdl_handleTransportUpdateWithPrimaryAvailable:(BOOL)primaryAvailable secondaryAvailable:(BOOL)secondaryAvailable { - __weak typeof(self) weakSelf = self; - [self updateAudioServiceWithPrimaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable transportUpdatedBlock:^(SDLProtocol * _Nullable oldAudioProtocol, SDLProtocol * _Nullable newAudioProtocol) { - [weakSelf updateVideoServiceWithPrimaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable transportUpdatedBlock:^(SDLProtocol * _Nullable oldVideoProtocol, SDLProtocol * _Nullable newVideoProtocol) { - [weakSelf.streamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:oldVideoProtocol toNewVideoProtocol:newVideoProtocol fromOldAudioProtocol:oldAudioProtocol toNewAudioProtocol:newAudioProtocol]; - }]; - }]; -} + struct TransportUpdated audioTransportUpdated = [self sdl_updateService:SDLServiceTypeAudio allowedTransports:self.transportsForAudioService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; + struct TransportUpdated videoTransportUpdated = [self sdl_updateService:SDLServiceTypeVideo allowedTransports:self.transportsForVideoService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; -- (void)updateAudioServiceWithPrimaryAvailable:(BOOL)primaryAvailable secondaryAvailable:(BOOL)secondaryAvailable transportUpdatedBlock:(void (^)(SDLProtocol * _Nullable oldAudioProtocol, SDLProtocol * _Nullable newAudioProtocol))transportUpdatedBlock { - [self sdl_updateService:SDLServiceTypeAudio - allowedTransports:self.transportsForAudioService - primaryAvailable:primaryAvailable - secondaryAvailable:secondaryAvailable - transportUpdatedBlock:transportUpdatedBlock]; -} + if (audioTransportUpdated.newProtocol == audioTransportUpdated.oldProtocol && videoTransportUpdated.newProtocol == videoTransportUpdated.oldProtocol) { return; } -- (void)updateVideoServiceWithPrimaryAvailable:(BOOL)primaryAvailable secondaryAvailable:(BOOL)secondaryAvailable transportUpdatedBlock:(void (^)(SDLProtocol * _Nullable oldVideoProtocol, SDLProtocol * _Nullable newVideoProtocol))transportUpdatedBlock { - [self sdl_updateService:SDLServiceTypeVideo - allowedTransports:self.transportsForVideoService - primaryAvailable:primaryAvailable - secondaryAvailable:secondaryAvailable - transportUpdatedBlock:transportUpdatedBlock]; + [self.streamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:videoTransportUpdated.oldProtocol toNewVideoProtocol:videoTransportUpdated.newProtocol fromOldAudioProtocol:audioTransportUpdated.oldProtocol toNewAudioProtocol:audioTransportUpdated.newProtocol]; } -- (void)sdl_updateService:(UInt8)service +- (struct TransportUpdated)sdl_updateService:(UInt8)service allowedTransports:(nonnull NSArray *)transportList primaryAvailable:(BOOL)primaryTransportAvailable - secondaryAvailable:(BOOL)secondaryTransportAvailable - transportUpdatedBlock:(void (^)(SDLProtocol * _Nullable oldProtocol, SDLProtocol * _Nullable newProtocol))transportUpdatedBlock { + secondaryAvailable:(BOOL)secondaryTransportAvailable { SDLTransportClass newTransport = SDLTransportClassInvalid; // the list is in preferred order, so take a look from the beginning for (SDLTransportClassBox *transport in transportList) { @@ -389,10 +376,14 @@ - (void)sdl_updateService:(UInt8)service } else if (newTransport != SDLTransportClassInvalid) { SDLLogD(@"Starting service 0x%X on %@ transport", service, [self sdl_getTransportClassName:newTransport]); } - - transportUpdatedBlock([self sdl_getProtocolFromTransportClass:oldTransport], - [self sdl_getProtocolFromTransportClass:newTransport]); + } else { + SDLLogV(@"Transport was not updated"); } + + struct TransportUpdated transportUpdated; + transportUpdated.oldProtocol = [self sdl_getProtocolFromTransportClass:oldTransport]; + transportUpdated.newProtocol = [self sdl_getProtocolFromTransportClass:newTransport]; + return transportUpdated; } - (nullable SDLProtocol *)sdl_getProtocolFromTransportClass:(SDLTransportClass)transportClass { From 2ed7147512bc81f923ef04910dd2ec3c152c547b Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 11:29:01 -0500 Subject: [PATCH 046/152] Updated docs --- SmartDeviceLink/SDLStreamingProtocolDelegate.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingProtocolDelegate.h b/SmartDeviceLink/SDLStreamingProtocolDelegate.h index ff5a718af..214ca99ae 100644 --- a/SmartDeviceLink/SDLStreamingProtocolDelegate.h +++ b/SmartDeviceLink/SDLStreamingProtocolDelegate.h @@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN /// Called when protocol instance for audio and/or video service has been updated. /// -/// If `newVideoProtocol` or `newAudioProtocol` is nil, it indicates that underlying transport has become unavailable. +/// If `newVideoProtocol` or `newAudioProtocol` is nil it indicates that underlying transport has become unavailable. /// /// @param oldVideoProtocol protocol instance that was being used for video streaming /// @param newVideoProtocol protocol instance that will be used for video streaming @@ -24,7 +24,6 @@ NS_ASSUME_NONNULL_BEGIN /// @param newAudioProtocol protocol instance that will be used for audio streaming - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; - @end NS_ASSUME_NONNULL_END From 3ebedfe1dd39d088b9c0419ad0d3624c497d9855 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 11:35:12 -0500 Subject: [PATCH 047/152] Fixed test cases --- .../SDLStreamingVideoLifecycleManager.m | 7 ++- .../SDLStreamingVideoLifecycleManagerSpec.m | 59 ++++++++++++++++++- .../SDLSecondaryTransportManagerSpec.m | 32 ++++------ 3 files changed, 72 insertions(+), 26 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 746519ffc..2a5949511 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -553,6 +553,8 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA self.videoFormat = [[SDLVideoStreamingFormat alloc] init]; self.videoFormat.codec = videoAckPayload.videoCodec ?: SDLVideoStreamingCodecH264; self.videoFormat.protocol = videoAckPayload.videoProtocol ?: SDLVideoStreamingProtocolRAW; + + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateReady]; } - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { @@ -581,7 +583,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN [self sdl_sendVideoStartService]; } -#pragma mark End Service +#pragma mark End Service ACK/NAK - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } @@ -740,8 +742,7 @@ - (void)sdl_stopVideoSession { if (self.isVideoConnected || self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; } else { - SDLLogV(@"no video streaming but we are going to send an end service anyways"); - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; + SDLLogV(@"No video streaming. Will not send an end video service request."); } } diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 152db9339..bba73510a 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -659,6 +659,8 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream __block SDLProtocolHeader *testVideoHeader = nil; __block SDLProtocolMessage *testVideoMessage = nil; __block SDLControlFramePayloadNak *testVideoStartNakPayload = nil; + __block NSArray *testPreferredFormats = nil; + __block NSArray *testPreferredResolutions = nil; beforeEach(^{ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamManagerStateStarting fromOldState:nil callEnterTransition:NO]; @@ -670,8 +672,18 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream testVideoHeader.serviceType = SDLServiceTypeVideo; }); - context(@"with data", ^{ + context(@"with rejected parameters for resolution and codec and there is more than one supported resolution and video codec", ^{ beforeEach(^{ + SDLVideoStreamingFormat *testVideoFormat = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecTheora protocol:SDLVideoStreamingProtocolWebM]; + SDLVideoStreamingFormat *testVideoFormat2 = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]; + testPreferredFormats = @[testVideoFormat, testVideoFormat2]; + streamingLifecycleManager.preferredFormats = testPreferredFormats; + + SDLImageResolution *testImageResolution = [[SDLImageResolution alloc] initWithWidth:400 height:200]; + SDLImageResolution *testImageResolution2 = [[SDLImageResolution alloc] initWithWidth:500 height:800]; + testPreferredResolutions = @[testImageResolution, testImageResolution2]; + streamingLifecycleManager.preferredResolutions = testPreferredResolutions; + testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameHeightKey], [NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; @@ -683,8 +695,53 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); + context(@"with rejected parameters for codec and there is more than one supported video codec", ^{ + beforeEach(^{ + SDLVideoStreamingFormat *testVideoFormat = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecTheora protocol:SDLVideoStreamingProtocolWebM]; + SDLVideoStreamingFormat *testVideoFormat2 = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]; + testPreferredFormats = @[testVideoFormat, testVideoFormat2]; + streamingLifecycleManager.preferredFormats = testPreferredFormats; + + SDLImageResolution *testImageResolution = [[SDLImageResolution alloc] initWithWidth:400 height:200]; + testPreferredResolutions = @[testImageResolution]; + streamingLifecycleManager.preferredResolutions = testPreferredResolutions; + + testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; + testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; + [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + }); + + it(@"should have retried with new properties", ^{ + expect(streamingLifecycleManager.preferredResolutionIndex).to(equal(0)); + expect(streamingLifecycleManager.preferredFormatIndex).to(equal(1)); + }); + }); + + context(@"with rejected parameters for codec and there are no more supported video codecs", ^{ + beforeEach(^{ + SDLVideoStreamingFormat *testVideoFormat = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]; + testPreferredFormats = @[testVideoFormat]; + streamingLifecycleManager.preferredFormats = testPreferredFormats; + + SDLImageResolution *testImageResolution = [[SDLImageResolution alloc] initWithWidth:400 height:200]; + testPreferredResolutions = @[testImageResolution]; + streamingLifecycleManager.preferredResolutions = testPreferredResolutions; + + testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:@[[NSString stringWithUTF8String:SDLControlFrameVideoCodecKey]]]; + testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; + [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; + }); + + it(@"should end the service", ^{ + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped)); + }); + }); + context(@"with missing data", ^{ beforeEach(^{ + streamingLifecycleManager.preferredFormats = testPreferredFormats; + streamingLifecycleManager.preferredResolutions = testPreferredResolutions; + testVideoStartNakPayload = [[SDLControlFramePayloadNak alloc] initWithRejectedParams:nil]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartNakPayload.data]; [streamingLifecycleManager handleProtocolStartServiceNAKMessage:testVideoMessage]; diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index 2c4abf093..0ba6eecf1 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -164,8 +164,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve afterEach(^{ // it is possible that manager calls methods of SDLStreamingProtocolDelegate while stopping, so accept them // (Don't put OCMVerifyAll() after calling stop.) - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:OCMOCK_ANY toNewProtocol:nil]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:OCMOCK_ANY toNewProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:OCMOCK_ANY toNewVideoProtocol:nil fromOldAudioProtocol:OCMOCK_ANY toNewAudioProtocol:nil]); dispatch_sync(testStateMachineQueue, ^{ [manager stop]; @@ -190,7 +189,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve expect(manager.tcpPort).to(equal(TCPPortUnspecified)); }); - describe(@"when started", ^{ beforeEach(^{ testPrimaryProtocol = [[SDLProtocol alloc] init]; @@ -206,7 +204,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - describe(@"In Started state", ^{ beforeEach(^{ // In the tests, we assume primary transport is iAP @@ -249,12 +246,11 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve testStartServiceACKPayload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithHashId:testHashId mtu:testMtu authToken:nil protocolVersion:testProtocolVersion secondaryTransports:testSecondaryTransports audioServiceTransports:testAudioServiceTransports videoServiceTransports:testVideoServiceTransports]; testStartServiceACKMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testStartServiceACKHeader andPayload:testStartServiceACKPayload.data]; - }); it(@"should configure its properties and transition to Configured state", ^{ // in this configuration, only audio service is allowed on primary transport - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -282,8 +278,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should configure its properties and transition to Configured state", ^{ // in this case, audio and video services start on primary transport (for compatibility) - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -311,8 +306,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should transition to Configured state with transport type disabled", ^{ // Since primary transport is iAP, we cannot use iAP for secondary transport. // So both services run on primary transport. - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -336,8 +330,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should transition to Configured state with transport type disabled", ^{ // both services run on primary transport - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -696,8 +689,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Registered state", ^{ - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:secondaryProtocol]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:nil toNewProtocol:secondaryProtocol]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:secondaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:secondaryProtocol]); [testSecondaryProtocolMock handleBytesFromTransport:testRegisterSecondaryTransportAckMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -907,8 +899,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Configured state, then transition to Connecting state again", ^{ - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -928,8 +919,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Configured state", ^{ - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -950,8 +940,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Reconnecting state", ^{ - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testSecondaryProtocolMock onProtocolClosed]; [NSThread sleepForTimeInterval:0.1]; @@ -971,8 +960,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Stopped state", ^{ - OCMExpect([testStreamingProtocolDelegate audioServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); - OCMExpect([testStreamingProtocolDelegate videoServiceProtocolDidUpdateFromOldProtocol:secondaryProtocol toNewProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); dispatch_sync(testStateMachineQueue, ^{ [manager stop]; From cba57a9a612e81621cf0c7a590832b003bfd30f4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 13:41:20 -0500 Subject: [PATCH 048/152] Fixed log level --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 4 ++-- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index f10433e44..abb411695 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -199,7 +199,7 @@ - (void)didEnterStateAudioStreamShuttingDown { - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Request to start audio service ACKed"); + SDLLogD(@"Request to start audio service ACKed"); _audioEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:startServiceACK.payload]; @@ -223,7 +223,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Request to end audio service ACKed"); + SDLLogD(@"Request to end audio service ACKed"); if (self.audioEndedCompletionHandler != nil) { self.audioEndedCompletionHandler(YES); self.audioEndedCompletionHandler = nil; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 2a5949511..2d061d089 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -561,7 +561,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN if (startServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:startServiceNAK.payload]; - SDLLogE(@"Request to start video service NAKed with reason: %@", nakPayload.description); + SDLLogW(@"Request to start video service NAKed with reason: %@", nakPayload.description); // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { @@ -600,7 +600,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogE(@"Request to end video service NAKed"); + SDLLogW(@"Request to end video service NAKed"); if (self.videoEndedCompletionHandler != nil) { self.videoEndedCompletionHandler(NO); self.videoEndedCompletionHandler = nil; From 7d50b5382e18ff759b4d7571f94517bebd2068cf Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 13:59:12 -0500 Subject: [PATCH 049/152] Fixed audio manager not getting reset --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index abb411695..97e040ded 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -109,6 +109,9 @@ - (void)stop { // Reset the `connectedVehicleMake` because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. It is possible that the user could connect to different module during the same app session. _connectedVehicleMake = nil; + // Stop the audio manager + [_audioManager stop]; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } @@ -119,6 +122,9 @@ - (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler) SDLLogD(@"Stopping audio streaming"); self.audioEndedCompletionHandler = completionHandler; + // Stop the audio manager from sending any more data + [_audioManager stop]; + // Always send an end audio service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeAudio]; } From f3bda0ddc1a63dabc6e29bf382c1baf474a11a41 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 15:49:07 -0500 Subject: [PATCH 050/152] Refactored streaming managers --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 6 ++++-- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 6 +++++- SmartDeviceLink/SDLStreamingVideoLifecycleManager.h | 2 +- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 6 ------ 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index b657ef8dd..720e60176 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -64,6 +64,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration audioManager:(nullable SDLAudioStreamManager *)audioManager NS_DESIGNATED_INITIALIZER; + /** Create a new streaming media manager for navigation and VPM apps with a specified configuration @@ -72,7 +74,7 @@ NS_ASSUME_NONNULL_BEGIN @param encryptionConfiguration The encryption configuration with security managers @return A new streaming manager */ -- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration; /** * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. @@ -87,7 +89,7 @@ NS_ASSUME_NONNULL_BEGIN /** * This method is used internally to end an audio service on the secondary transport. The primary transport is still open. * - * @param completionHandler Called when the module ACKs or NAKs to the request to end the audio service. + * @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. */ - (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler)audioEndedCompletionHandler; diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 97e040ded..5dadf6f3f 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -50,6 +50,10 @@ @interface SDLStreamingAudioLifecycleManager() @implementation SDLStreamingAudioLifecycleManager - (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration { + return [self initWithConnectionManager:connectionManager streamingConfiguration:streamingConfiguration encryptionConfiguration:encryptionConfiguration audioManager:nil]; +} + +- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration audioManager:(nullable SDLAudioStreamManager *)audioManager { self = [super init]; if (!self) { return nil; @@ -58,7 +62,7 @@ - (instancetype)initWithConnectionManager:(id)connecti SDLLogV(@"Creating AudioStreamingLifecycleManager"); _connectionManager = connectionManager; - _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self]; + _audioManager = audioManager != nil ? audioManager : [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; _connectedVehicleMake = nil; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index c2fd64ecc..0752817a3 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -163,7 +163,7 @@ NS_ASSUME_NONNULL_BEGIN /** * This method is used internally to end a video service on the secondary transport. The primary transport is still open. * - * @param completionHandler Called when the module ACKs or NAKs to the request to end the video service. + * @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. */ - (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler)videoEndedCompletionHandler; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 2d061d089..5742cf535 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -236,12 +236,6 @@ - (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler) /// Used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol { self.protocol = nil; - - // Reset the video streaming parameters as video is not streaming. - _backgroundingPixelBuffer = NULL; - _preferredFormatIndex = 0; - _preferredResolutionIndex = 0; - _lastPresentationTimestamp = kCMTimeInvalid; } - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { From d1e83749c24155c02be6ab53579dac20f2a0c998 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 15:49:25 -0500 Subject: [PATCH 051/152] Added test cases for streaming managers --- .../SDLStreamingAudioLifecycleManagerSpec.m | 97 ++++++++++++++++++- .../SDLStreamingVideoLifecycleManagerSpec.m | 90 ++++++++++++++++- 2 files changed, 181 insertions(+), 6 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index d3963ce23..e448f023e 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -2,6 +2,7 @@ #import #import +#import "SDLAudioStreamManager.h" #import "SDLControlFramePayloadAudioStartServiceAck.h" #import "SDLDisplayCapabilities.h" #import "SDLGlobals.h" @@ -33,6 +34,7 @@ @interface SDLStreamingAudioLifecycleManager() __block SDLStreamingMediaConfiguration *testConfiguration = [SDLStreamingMediaConfiguration insecureConfiguration]; __block SDLEncryptionConfiguration *encryptionConfiguration = [SDLEncryptionConfiguration defaultConfiguration]; __block TestConnectionManager *testConnectionManager = nil; + __block id mockAudioStreamManager = nil; __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILevel hmiLevel) { SDLOnHMIStatus *hmiStatus = [[SDLOnHMIStatus alloc] init]; @@ -44,8 +46,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }; beforeEach(^{ + mockAudioStreamManager = OCMClassMock([SDLAudioStreamManager class]); + testConnectionManager = [[TestConnectionManager alloc] init]; - streamingLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:testConnectionManager streamingConfiguration:testConfiguration encryptionConfiguration:encryptionConfiguration]; + streamingLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:testConnectionManager streamingConfiguration:testConfiguration encryptionConfiguration:encryptionConfiguration audioManager:mockAudioStreamManager]; }); it(@"should initialize properties", ^{ @@ -409,7 +413,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - describe(@"when stopped", ^{ + describe(@"when the manager is stopped", ^{ context(@"if audio not stopped", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; @@ -424,6 +428,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); + OCMVerify([mockAudioStreamManager stop]); }); }); @@ -441,9 +446,97 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); + OCMVerify([mockAudioStreamManager stop]); }); }); }); + + describe(@"when audio is stopped", ^{ + __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); + __block BOOL handlerCalled = nil; + __block BOOL audioServiceEnded = nil; + + beforeEach(^{ + handlerCalled = NO; + audioServiceEnded = NO; + [streamingLifecycleManager startWithProtocol:protocolMock]; + }); + + context(@"if stopping audio on secondary transport", ^{ + beforeEach(^{ + [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { + handlerCalled = YES; + audioServiceEnded = success; + }]; + }); + + it(@"should reset the audio stream manger", ^{ + OCMVerify([mockAudioStreamManager stop]); + }); + + it(@"should send an end audio service control frame", ^{ + OCMVerify([protocolMock endServiceWithType:SDLServiceTypeAudio]); + }); + + context(@"If the end audio service ACKs", ^{ + __block SDLProtocolHeader *testAudioHeader = nil; + __block SDLProtocolMessage *testAudioMessage = nil; + + beforeEach(^{ + testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5]; + testAudioHeader.frameType = SDLFrameTypeSingle; + testAudioHeader.frameData = SDLFrameInfoEndServiceACK; + testAudioHeader.encrypted = NO; + testAudioHeader.serviceType = SDLServiceTypeAudio; + testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; + + [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage]; + }); + + it(@"should call the handler with a success result", ^{ + expect(handlerCalled).to(beTrue()); + expect(audioServiceEnded).to(beTrue()); + }); + }); + + context(@"If the end audio service NAKs", ^{ + __block SDLProtocolHeader *testAudioHeader = nil; + __block SDLProtocolMessage *testAudioMessage = nil; + + beforeEach(^{ + testAudioHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5]; + testAudioHeader.frameType = SDLFrameTypeSingle; + testAudioHeader.frameData = SDLFrameInfoEndServiceNACK; + testAudioHeader.encrypted = NO; + testAudioHeader.serviceType = SDLServiceTypeAudio; + testAudioMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testAudioHeader andPayload:nil]; + + [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testAudioMessage]; + }); + + it(@"should call the handler with an unsuccessful result", ^{ + expect(handlerCalled).to(beTrue()); + expect(audioServiceEnded).to(beFalse()); + }); + }); + }); + }); + + describe(@"when the protocol is destroyed", ^{ + __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); + + beforeEach(^{ + [streamingLifecycleManager startWithProtocol:protocolMock]; + expect(streamingLifecycleManager.protocol).toNot(beNil()); + + [streamingLifecycleManager destroyProtocol]; + }); + + it(@"should destroy the protocol", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); + }); + }); }); QuickSpecEnd diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index bba73510a..01c8da970 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -619,7 +619,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream context(@"with missing screen height and screen width values", ^{ beforeEach(^{ streamingLifecycleManager.preferredResolutions = @[]; - + testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:SDLControlFrameInt32NotFound width:SDLControlFrameInt32NotFound protocol:nil codec:nil]; testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data]; expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeZero))).to(equal(@YES)); @@ -637,13 +637,13 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream context(@"If the preferred resolution was set in the data source", ^{ __block SDLImageResolution *preferredResolutionLow = nil; __block SDLImageResolution *preferredResolutionHigh = nil; - + beforeEach(^{ preferredResolutionLow = [[SDLImageResolution alloc] initWithWidth:10 height:10]; preferredResolutionHigh = [[SDLImageResolution alloc] initWithWidth:100 height:100]; streamingLifecycleManager.dataSource = testDataSource; streamingLifecycleManager.preferredResolutions = @[preferredResolutionLow, preferredResolutionHigh]; - + [streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage]; }); it(@"should set the screen size using the first provided preferred resolution", ^{ @@ -799,7 +799,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - describe(@"when stopped", ^{ + describe(@"when the manager is stopped", ^{ beforeEach(^{ streamingLifecycleManager.connectedVehicleMake = @"OEM_make"; }); @@ -845,6 +845,88 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); + describe(@"when video is stopped", ^{ + __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); + __block BOOL handlerCalled = nil; + __block BOOL videoServiceEnded = nil; + + beforeEach(^{ + handlerCalled = NO; + videoServiceEnded = NO; + [streamingLifecycleManager startWithProtocol:protocolMock]; + }); + + context(@"if stopping video on secondary transport", ^{ + beforeEach(^{ + [streamingLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { + handlerCalled = YES; + videoServiceEnded = success; + }]; + }); + + it(@"should send an end video service control frame", ^{ + OCMVerify([protocolMock endServiceWithType:SDLServiceTypeVideo]); + }); + + context(@"If the end video service ACKs", ^{ + __block SDLProtocolHeader *testVideoHeader = nil; + __block SDLProtocolMessage *testVideoMessage = nil; + + beforeEach(^{ + testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5]; + testVideoHeader.frameType = SDLFrameTypeSingle; + testVideoHeader.frameData = SDLFrameInfoEndServiceACK; + testVideoHeader.encrypted = NO; + testVideoHeader.serviceType = SDLServiceTypeVideo; + testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; + + [streamingLifecycleManager handleProtocolEndServiceACKMessage:testVideoMessage]; + }); + + it(@"should call the handler with a success result", ^{ + expect(handlerCalled).to(beTrue()); + expect(videoServiceEnded).to(beTrue()); + }); + }); + + context(@"If the end audio service NAKs", ^{ + __block SDLProtocolHeader *testVideoHeader = nil; + __block SDLProtocolMessage *testVideoMessage = nil; + + beforeEach(^{ + testVideoHeader = [[SDLV2ProtocolHeader alloc] initWithVersion:5]; + testVideoHeader.frameType = SDLFrameTypeSingle; + testVideoHeader.frameData = SDLFrameInfoEndServiceNACK; + testVideoHeader.encrypted = NO; + testVideoHeader.serviceType = SDLServiceTypeVideo; + testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:nil]; + + [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testVideoMessage]; + }); + + it(@"should call the handler with an unsuccessful result", ^{ + expect(handlerCalled).to(beTrue()); + expect(videoServiceEnded).to(beFalse()); + }); + }); + }); + }); + + describe(@"when the protocol is destroyed", ^{ + __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); + + beforeEach(^{ + [streamingLifecycleManager startWithProtocol:protocolMock]; + expect(streamingLifecycleManager.protocol).toNot(beNil()); + + [streamingLifecycleManager destroyProtocol]; + }); + + it(@"should destroy the protocol", ^{ + expect(streamingLifecycleManager.protocol).to(beNil()); + }); + }); + describe(@"Creating a background video stream string", ^{ __block NSString *expectedVideoStreamBackgroundString = [NSString stringWithFormat:@"When it is safe to do so, open %@ on your phone", testAppName]; From 14e050a8a79bf1ae8ffdb43c5aaffb470c2d73f5 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 15:56:10 -0500 Subject: [PATCH 052/152] Cleaning up docs in H264VideoEncoder class --- SmartDeviceLink/SDLH264VideoEncoder.h | 2 +- SmartDeviceLink/SDLH264VideoEncoder.m | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.h b/SmartDeviceLink/SDLH264VideoEncoder.h index 29f15515e..58bde0508 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.h +++ b/SmartDeviceLink/SDLH264VideoEncoder.h @@ -51,7 +51,7 @@ extern NSString *const SDLErrorDomainVideoEncoder; /** * The pixel buffer pool reference returned back from an active VTCompressionSessionRef encoder. * - * @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started). + * @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started). * @discussion Clients may call this once and retain the resulting pool, this call is cheap enough that it's OK to call it once per frame. */ @property (assign, nonatomic, readonly) CVPixelBufferPoolRef CV_NULLABLE pixelBufferPool; diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index eb1bf96b8..3e118818a 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -27,7 +27,9 @@ @interface SDLH264VideoEncoder () @property (assign, nonatomic) double timestampOffset; @property (assign, nonatomic, readwrite) CVPixelBufferPoolRef CV_NULLABLE pixelBufferPool; -@property (assign, nonatomic) CGSize imageDimensions; + +/// Width and height of the video frame. +@property (assign, nonatomic) CGSize dimensions; @end @@ -57,14 +59,13 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: _compressionSession = NULL; _currentFrameNumber = 0; _videoEncoderSettings = properties; - _imageDimensions = dimensions; + _dimensions = dimensions; _delegate = delegate; OSStatus status; // Create a compression session - SDLLogW(@"compression session width %f x height %f", dimensions.width, dimensions.height); status = VTCompressionSessionCreate(NULL, (int32_t)dimensions.width, (int32_t)dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); if (status != noErr) { @@ -339,16 +340,16 @@ + (NSArray *)sdl_extractNalUnitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer return nalUnits; } -/// Attempts to create a new VTCompressionSession using the image dimensions passed when the video encoder was created and returns whether or not creating the new compression session was created successfully. +/// Attempts to create a new VTCompressionSession using the dimensions passed when the video encoder was created and returns whether or not creating the new compression session was created successfully. - (BOOL)sdl_resetCompressionSession { - // Destroy the compression session before attempting to create a new one. Otherwise the attempt to create a new compression session sometimes fails. + // Destroy the current compression session before attempting to create a new one. Otherwise the attempt to create a new compression session sometimes fails. if (self.compressionSession != NULL) { VTCompressionSessionInvalidate(self.compressionSession); CFRelease(self.compressionSession); self.compressionSession = NULL; } - OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.imageDimensions.width, (int32_t)self.imageDimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); + OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.dimensions.width, (int32_t)self.dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); return (status == noErr) ? YES : NO; } From 6e1d5d708ac4cd0a6c445ea239b6f29f00e153fd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 24 Feb 2020 16:08:44 -0500 Subject: [PATCH 053/152] Fixed formatting and logs --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 5742cf535..de1ea8733 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -532,7 +532,7 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA // This is the definitive screen size that will be used if ((videoAckPayload.height != SDLControlFrameInt32NotFound || videoAckPayload.height != 0) && (videoAckPayload.width != SDLControlFrameInt32NotFound && videoAckPayload.width != 0)) { - self.videoScaleManager.displayViewportResolution = CGSizeMake(videoAckPayload.width, videoAckPayload.height); + self.videoScaleManager.displayViewportResolution = CGSizeMake(videoAckPayload.width, videoAckPayload.height); } else if (self.preferredResolutions.count > 0) { // If a preferred resolution was set, use the first option to set the screen size SDLImageResolution *preferredResolution = self.preferredResolutions.firstObject; @@ -658,9 +658,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { return; } - SDLHMILevel oldHMILevel = self.hmiLevel; self.hmiLevel = hmiStatus.hmiLevel; - SDLLogV(@"HMI level changed from %@ to $%@", oldHMILevel, self.hmiLevel); SDLVideoStreamingState newState = hmiStatus.videoStreamingState ?: SDLVideoStreamingStateStreamable; if (![self.videoStreamingState isEqualToEnum:newState]) { From 9ef00f17b961cdd282fe238f03ef6205bce4b983 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 25 Feb 2020 16:19:20 -0500 Subject: [PATCH 054/152] Fixed log --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 5dadf6f3f..bb8325152 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -245,7 +245,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Request to end audio service ACKed"); + SDLLogW(@"Request to end audio service NAKed"); if (self.audioEndedCompletionHandler != nil) { self.audioEndedCompletionHandler(NO); self.audioEndedCompletionHandler = nil; From d78d99ec7446a3e1f5cd8ff67acdac095a349ace Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 25 Feb 2020 16:27:07 -0500 Subject: [PATCH 055/152] Attempting broken Travis test cases --- .../Notifications/SDLResponseDispatcherSpec.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m index abf70ac38..579bb74fe 100644 --- a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m @@ -457,9 +457,9 @@ it(@"should have removed all the handlers", ^{ // There should still be the add command request & handler in the dictionaries since we never responded - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); + expect(testDispatcher.commandHandlerMap).toEventually(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).toEventually(haveCount(@1)); + expect(testDispatcher.rpcResponseHandlerMap).toEventually(haveCount(@1)); }); }); }); From 86a411a65b411efcf84575be3f02f278b7ce3fd8 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 26 Feb 2020 08:44:49 -0500 Subject: [PATCH 056/152] Attempting to fix Response Dispatcher tests --- .../Notifications/SDLResponseDispatcherSpec.m | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m index 579bb74fe..d7b4b8c09 100644 --- a/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m +++ b/SmartDeviceLinkTests/Notifications/SDLResponseDispatcherSpec.m @@ -44,7 +44,7 @@ expect(testDispatcher.commandHandlerMap).toNot(beNil()); expect(testDispatcher.buttonHandlerMap).toNot(beNil()); expect(testDispatcher.customButtonHandlerMap).toNot(beNil()); -// expect(testDispatcher.audioPassThruHandler).to(beNil()); + expect((id)testDispatcher.audioPassThruHandler).to(beNil()); expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); @@ -66,11 +66,11 @@ it(@"should not store the request", ^{ [testDispatcher storeRequest:testRPC handler:nil]; - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.rpcResponseHandlerMap).toEventually(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).toEventually(haveCount(@1)); + expect(testDispatcher.commandHandlerMap).toEventually(haveCount(@0)); + expect(testDispatcher.buttonHandlerMap).toEventually(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); @@ -109,9 +109,9 @@ }); it(@"should run the handler", ^{ - expect(@(handlerCalled)).to(beTruthy()); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@0)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@0)); + expect(@(handlerCalled)).toEventually(beTruthy()); + expect(testDispatcher.rpcRequestDictionary).toEventually(haveCount(@0)); + expect(testDispatcher.rpcResponseHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -165,7 +165,7 @@ }); it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@2)); }); }); @@ -185,7 +185,7 @@ }); it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); }); @@ -197,7 +197,7 @@ }); it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); @@ -213,7 +213,7 @@ #pragma clang diagnostic pop testShow.softButtons = [@[testSoftButton1] mutableCopy]; - expectAction(^{ [testDispatcher storeRequest:testShow handler:nil]; }).to(raiseException().named(@"MissingIdException")); + expectAction(^{ [testDispatcher storeRequest:testShow handler:nil]; }).toEventually(raiseException().named(@"MissingIdException")); }); }); @@ -221,7 +221,7 @@ it(@"should not store the request", ^{ [testDispatcher storeRequest:testShow handler:nil]; - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -259,7 +259,7 @@ testAddCommand.cmdID = nil; #pragma clang diagnostic pop - expectAction(^{ [testDispatcher storeRequest:testAddCommand handler:nil]; }).to(raiseException().named(@"MissingIdException")); + expectAction(^{ [testDispatcher storeRequest:testAddCommand handler:nil]; }).toEventually(raiseException().named(@"MissingIdException")); }); describe(@"when button press and button event notifications arrive", ^{ @@ -281,7 +281,7 @@ }); it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@1)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@1)); }); }); @@ -296,7 +296,7 @@ }); it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); }); @@ -328,9 +328,9 @@ it(@"should have removed all the handlers", ^{ // There should still be the add command request & handler in the dictionaries since we never responded - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); - expect(testDispatcher.rpcRequestDictionary).to(haveCount(@1)); - expect(testDispatcher.rpcResponseHandlerMap).to(haveCount(@1)); + expect(testDispatcher.commandHandlerMap).toEventually(haveCount(@0)); + expect(testDispatcher.rpcRequestDictionary).toEventually(haveCount(@1)); + expect(testDispatcher.rpcResponseHandlerMap).toEventually(haveCount(@1)); }); }); }); @@ -341,7 +341,7 @@ }); it(@"should not add the command", ^{ - expect(testDispatcher.commandHandlerMap).to(haveCount(@0)); + expect(testDispatcher.commandHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -379,7 +379,7 @@ testSubscribeButton.buttonName = nil; #pragma clang diagnostic pop - expectAction(^{ [testDispatcher storeRequest:testSubscribeButton handler:nil]; }).to(raiseException().named(@"MissingIdException")); + expectAction(^{ [testDispatcher storeRequest:testSubscribeButton handler:nil]; }).toEventually(raiseException().named(@"MissingIdException")); }); describe(@"when button press and button event notifications arrive", ^{ @@ -406,7 +406,7 @@ }); it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@2)); }); }); @@ -426,7 +426,7 @@ }); it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); }); @@ -470,7 +470,7 @@ }); it(@"should not add the subscription", ^{ - expect(testDispatcher.buttonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.buttonHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -525,7 +525,7 @@ }); it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@2)); }); }); @@ -545,7 +545,7 @@ }); it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); }); @@ -557,7 +557,7 @@ }); it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); @@ -573,7 +573,7 @@ #pragma clang diagnostic pop testAlert.softButtons = [@[testSoftButton1] mutableCopy]; - expectAction(^{ [testDispatcher storeRequest:testAlert handler:nil]; }).to(raiseException().named(@"MissingIdException")); + expectAction(^{ [testDispatcher storeRequest:testAlert handler:nil]; }).toEventually(raiseException().named(@"MissingIdException")); }); }); @@ -581,7 +581,7 @@ it(@"should not store the request", ^{ [testDispatcher storeRequest:testAlert handler:nil]; - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -636,7 +636,7 @@ }); it(@"should run the handler for each", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@2)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@2)); }); }); @@ -656,7 +656,7 @@ }); it(@"should not run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); }); @@ -668,7 +668,7 @@ }); it(@"should not add the soft button", ^{ - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); @@ -684,7 +684,7 @@ #pragma clang diagnostic pop testScrollableMessage.softButtons = [@[testSoftButton1] mutableCopy]; - expectAction(^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; }).to(raiseException().named(@"MissingIdException")); + expectAction(^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; }).toEventually(raiseException().named(@"MissingIdException")); }); }); @@ -692,7 +692,7 @@ it(@"should not store the request", ^{ [testDispatcher storeRequest:testScrollableMessage handler:nil]; - expect(testDispatcher.customButtonHandlerMap).to(haveCount(@0)); + expect(testDispatcher.customButtonHandlerMap).toEventually(haveCount(@0)); }); }); }); @@ -712,8 +712,8 @@ }); it(@"should store the handler" ,^{ -// expect(testDispatcher.audioPassThruHandler).toNot(beNil()); -// expect(testDispatcher.audioPassThruHandler).to(equal(testPerformAudioPassThru.audioDataHandler)); + expect((id)testDispatcher.audioPassThruHandler).toEventuallyNot(beNil()); + expect((id)testDispatcher.audioPassThruHandler).toEventually(equal((id)testPerformAudioPassThru.audioDataHandler)); }); describe(@"when an on audio data notification arrives", ^{ @@ -725,7 +725,7 @@ }); it(@"should run the handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@1)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@1)); }); }); @@ -739,7 +739,7 @@ }); it(@"should clear the handler", ^{ -// expect(testDispatcher.audioPassThruHandler).to(beNil()); + expect((id)testDispatcher.audioPassThruHandler).toEventually(beNil()); }); }); }); @@ -763,7 +763,7 @@ }); it(@"should not run a handler", ^{ - expect(@(numTimesHandlerCalled)).to(equal(@0)); + expect(@(numTimesHandlerCalled)).toEventually(equal(@0)); }); }); @@ -777,7 +777,7 @@ }); it(@"should clear the handler", ^{ -// expect(testDispatcher.audioPassThruHandler).to(beNil()); + expect((id)testDispatcher.audioPassThruHandler).toEventually(beNil()); }); }); From 630b78c52ce5a5e1963b143fd5545310a3a572b7 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 28 Feb 2020 16:05:50 -0500 Subject: [PATCH 057/152] Apply suggestions from code review Committed video encoder suggestions Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLH264VideoEncoder.m | 5 ++--- SmartDeviceLink/SDLSecondaryTransportManager.h | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 3e118818a..565f311d7 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -189,7 +189,7 @@ - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool and/or the compression session to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. if (!_pixelBufferPool) { BOOL success = [self sdl_resetCompressionSession]; - if (success == NO) { + if (!success) { return NULL; } @@ -202,11 +202,10 @@ - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { #pragma mark - Private #pragma mark Callback - /// Callback function that VideoToolbox calls when encoding is complete. /// @param outputCallbackRefCon The callback's reference value /// @param sourceFrameRefCon The frame's reference value -/// @param status Returns `noErr` if compression was successful;error if not successful +/// @param status Returns `noErr` if compression was successful, or an error if not successful /// @param infoFlags Information about the encode operation (frame dropped or if encode ran asynchronously) /// @param sampleBuffer Contains the compressed frame if compression was successful and the frame was not dropped; null otherwise void sdl_videoEncoderOutputCallback(void * CM_NULLABLE outputCallbackRefCon, void * CM_NULLABLE sourceFrameRefCon, OSStatus status, VTEncodeInfoFlags infoFlags, CM_NULLABLE CMSampleBufferRef sampleBuffer) { diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 2855d21de..80ced3445 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -36,7 +36,7 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; */ @interface SDLSecondaryTransportManager : NSObject -// State of this manager +/// State of this manager @property (strong, nonatomic, readonly) SDLStateMachine *stateMachine; /** From 1afc4a509978bd8a8dbb78b74872bb113023a4f4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 28 Feb 2020 16:15:45 -0500 Subject: [PATCH 058/152] Refactored error description in video encoder --- SmartDeviceLink/SDLH264VideoEncoder.m | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 565f311d7..29b15bde2 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -69,9 +69,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: status = VTCompressionSessionCreate(NULL, (int32_t)dimensions.width, (int32_t)dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); if (status != noErr) { - if (!*error) { - NSString *description = @"Compression session could not be created"; - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status), NSLocalizedDescriptionKey: description }]; + if (error != NULL) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{@"OSStatus":@(status), NSLocalizedDescriptionKey:@"Compression session could not be created"}]; } return nil; @@ -84,9 +83,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: CFDictionaryRef supportedProperties; status = VTSessionCopySupportedPropertyDictionary(self.compressionSession, &supportedProperties); if (status != noErr) { - if (!*error) { - NSString *description = [NSString stringWithFormat:@"\"%@\" are not supported properties.", supportedProperties]; - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status), NSLocalizedDescriptionKey: description }]; + if (error != NULL) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{@"OSStatus":@(status), NSLocalizedDescriptionKey:[NSString stringWithFormat:@"\"%@\" are not supported properties.", supportedProperties]}]; } return nil; @@ -95,9 +93,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: NSArray* videoEncoderKeys = self.videoEncoderSettings.allKeys; for (NSString *key in videoEncoderKeys) { if (CFDictionaryContainsKey(supportedProperties, (__bridge CFStringRef)key) == false) { - if (!*error) { - NSString *description = [NSString stringWithFormat:@"\"%@\" is not a supported key.", key]; - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{NSLocalizedDescriptionKey: description}]; + if (error != NULL) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:@"\"%@\" is not a supported key.", key]}]; } CFRelease(supportedProperties); return nil; @@ -111,9 +108,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: status = VTSessionSetProperty(self.compressionSession, (__bridge CFStringRef)key, (__bridge CFTypeRef)value); if (status != noErr) { - if (!*error) { - NSString *description = [NSString stringWithFormat:@"Setting key failed \"%@\"", key]; - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{NSLocalizedDescriptionKey: description, @"OSStatus": @(status)}]; + if (error != NULL) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{@"OSStatus": @(status), NSLocalizedDescriptionKey:[NSString stringWithFormat:@"Setting key failed \"%@\"", key]}]; } return nil; } @@ -124,8 +120,8 @@ - (instancetype)initWithProtocol:(SDLVideoStreamingProtocol)protocol dimensions: } else if ([protocol isEqualToEnum:SDLVideoStreamingProtocolRTP]) { _packetizer = [[SDLRTPH264Packetizer alloc] initWithSSRC:ssrc]; } else { - if (!*error) { - *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorProtocolUnknown userInfo:@{ @"encoder": protocol}]; + if (error != NULL) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorProtocolUnknown userInfo:@{@"encoder": protocol}]; } return nil; } From 9fdd0586ef84fd47276648fc0ca400c5ece5d275 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 08:34:46 -0500 Subject: [PATCH 059/152] Relocated func to streaming media manager --- SmartDeviceLink/SDLLifecycleManager.m | 20 ++------ SmartDeviceLink/SDLStreamingMediaManager.h | 7 +++ SmartDeviceLink/SDLStreamingMediaManager.m | 55 ++++++++++++++-------- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 54f6bd978..26cd4e84f 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -903,7 +903,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto [self.secondaryTransportManager disconnectSecondaryTransport]; [self.streamManager destroyAudioProtocol]; [self.streamManager destroyVideoProtocol]; - [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; + [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; }]; } else if (oldVideoProtocol != nil) { @@ -911,34 +911,22 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; [self.streamManager destroyVideoProtocol]; - [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; + [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else if (oldAudioProtocol != nil) { // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { [self.secondaryTransportManager disconnectSecondaryTransport]; [self.streamManager destroyAudioProtocol]; - [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; + [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else { // No audio and/or video service currently running. Just start the new audio and/or video services. - [self sdl_startNewAudioProtocol:newAudioProtocol startNewVideoProtocol:newVideoProtocol]; + [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; } } } -/// Starts the audio and/or video services using the new protocol. -/// @param newAudioProtocol The new audio protocol -/// @param newVideoProtocol The new video protocol -- (void)sdl_startNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol startNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol { - if (newAudioProtocol != nil) { - [self.streamManager startAudioWithProtocol:newAudioProtocol]; - } - if (newVideoProtocol != nil) { - [self.streamManager startVideoWithProtocol:newVideoProtocol]; - } -} - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index bb8a24701..6b1aa7321 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -177,6 +177,13 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)destroyVideoProtocol; +/** + * Starts the audio and/or video services using the new protocol. + * @param newAudioProtocol The new audio protocol + * @param newVideoProtocol The new video protocol + */ +- (void)startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol; + /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 1c592d6f4..8b9111281 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -60,7 +60,7 @@ - (void)stop { [self stopVideo]; } -#pragma mark - Audio +#pragma mark Audio - (void)startAudioWithProtocol:(SDLProtocol *)protocol { [self.audioLifecycleManager startWithProtocol:protocol]; @@ -72,25 +72,11 @@ - (void)stopAudio { self.audioStarted = NO; } -- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { - __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { - weakSelf.audioStarted = NO; - - if (completionHandler == nil) { return; } - return completionHandler(success); - }]; -} - -- (void)destroyAudioProtocol { - [self.audioLifecycleManager destroyProtocol]; -} - - (BOOL)sendAudioData:(NSData*)audioData { return [self.audioLifecycleManager sendAudioData:audioData]; } -#pragma mark - Video +#pragma mark Video - (void)startVideoWithProtocol:(SDLProtocol *)protocol { [self.videoLifecycleManager startWithProtocol:protocol]; @@ -102,6 +88,27 @@ - (void)stopVideo { self.videoStarted = NO; } +- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { + return [self.videoLifecycleManager sendVideoData:imageBuffer]; +} + +- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTime)presentationTimestamp { + return [self.videoLifecycleManager sendVideoData:imageBuffer presentationTimestamp:presentationTimestamp]; +} + +#pragma mark - Secondary Transport + +- (void)startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol { + if (newAudioProtocol != nil) { + [self startAudioWithProtocol:newAudioProtocol]; + } + if (newVideoProtocol != nil) { + [self startVideoWithProtocol:newVideoProtocol]; + } +} + +#pragma mark Video + - (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; [self.videoLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { @@ -116,12 +123,20 @@ - (void)destroyVideoProtocol { [self.videoLifecycleManager destroyProtocol]; } -- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { - return [self.videoLifecycleManager sendVideoData:imageBuffer]; +#pragma mark Audio + +- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { + __weak typeof(self) weakSelf = self; + [self.audioLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { + weakSelf.audioStarted = NO; + + if (completionHandler == nil) { return; } + return completionHandler(success); + }]; } -- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTime)presentationTimestamp { - return [self.videoLifecycleManager sendVideoData:imageBuffer presentationTimestamp:presentationTimestamp]; +- (void)destroyAudioProtocol { + [self.audioLifecycleManager destroyProtocol]; } #pragma mark - Getters From 8cfa80fb8ba6fca900c22185281275dab670ec8f Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 09:01:11 -0500 Subject: [PATCH 060/152] Added weak/strong to blocks --- SmartDeviceLink/SDLLifecycleManager.m | 66 +++++++++++++++------------ 1 file changed, 38 insertions(+), 28 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 26cd4e84f..205000f69 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -895,35 +895,45 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto BOOL videoProtocolUpdated = ((oldVideoProtocol == nil && newVideoProtocol == nil) || (oldVideoProtocol == newVideoProtocol)) ? NO : YES; BOOL audioProtocolUpdated = ((oldAudioProtocol == nil && newAudioProtocol == nil) || (oldAudioProtocol == newAudioProtocol)) ? NO : YES; - if (videoProtocolUpdated && audioProtocolUpdated) { - if (oldVideoProtocol != nil && oldAudioProtocol != nil) { - // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. - [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { - [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { - [self.secondaryTransportManager disconnectSecondaryTransport]; - [self.streamManager destroyAudioProtocol]; - [self.streamManager destroyVideoProtocol]; - [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - }]; - } else if (oldVideoProtocol != nil) { - // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { - [self.secondaryTransportManager disconnectSecondaryTransport]; - [self.streamManager destroyVideoProtocol]; - [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - } else if (oldAudioProtocol != nil) { - // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { - [self.secondaryTransportManager disconnectSecondaryTransport]; - [self.streamManager destroyAudioProtocol]; - [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + if (!videoProtocolUpdated && !audioProtocolUpdated) { + SDLLogV(@"The video and audio protocols did not update. Nothing will update."); + return; + } + + if (oldVideoProtocol != nil && oldAudioProtocol != nil) { + // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + [strongSelf.streamManager stopVideoWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; + [strongSelf.streamManager destroyAudioProtocol]; + [strongSelf.streamManager destroyVideoProtocol]; + [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; - } else { - // No audio and/or video service currently running. Just start the new audio and/or video services. - [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - } + }]; + } else if (oldVideoProtocol != nil) { + // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; + [strongSelf.streamManager destroyVideoProtocol]; + [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }]; + } else if (oldAudioProtocol != nil) { + // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; + [strongSelf.streamManager destroyAudioProtocol]; + [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }]; + } else { + // No audio and/or video service currently running. Just start the new audio and/or video services. + [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; } } From 75512762013675665c8f1cd40a14ebe65c71f8fa Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:07:18 -0500 Subject: [PATCH 061/152] Moved some video/audio to streaming media manager Moved video/audio state from lifecycle manager to the streaming media manager --- SmartDeviceLink/SDLLifecycleManager.m | 66 ++------------ SmartDeviceLink/SDLStreamingMediaManager.h | 63 +++++-------- SmartDeviceLink/SDLStreamingMediaManager.m | 88 ++++++++++++++++--- .../DevAPISpecs/SDLLifecycleManagerSpec.m | 4 +- 4 files changed, 106 insertions(+), 115 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 205000f69..4caa006f5 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -54,7 +54,6 @@ #import "SDLStateMachine.h" #import "SDLStreamingMediaConfiguration.h" #import "SDLStreamingMediaManager.h" -#import "SDLStreamingProtocolDelegate.h" #import "SDLSystemCapabilityManager.h" #import "SDLUnregisterAppInterface.h" #import "SDLVersion.h" @@ -78,7 +77,7 @@ #pragma mark - SDLManager Private Interface -@interface SDLLifecycleManager () +@interface SDLLifecycleManager () // Readonly public properties @property (copy, nonatomic, readwrite) SDLConfiguration *configuration; @@ -249,7 +248,8 @@ - (void)didEnterStateStarted { [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { // We reuse our queue to run secondary transport manager's state machine - self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:self serialQueue:self.lifecycleQueue]; + self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:self.streamManager serialQueue:self.lifecycleQueue]; + self.streamManager.secondaryTransportDelegate = self; } self.proxy = [SDLProxy iapProxyWithListener:self.notificationDispatcher secondaryTransportManager:self.secondaryTransportManager encryptionLifecycleManager:self.encryptionLifecycleManager]; @@ -276,12 +276,7 @@ - (void)sdl_stopManager:(BOOL)shouldRestart { [self.screenManager stop]; [self.encryptionLifecycleManager stop]; [self.streamManager stop]; - if (self.secondaryTransportManager != nil) { - [self.secondaryTransportManager stop]; - } else { - [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:self.proxy.protocol toNewVideoProtocol:nil fromOldAudioProtocol:self.proxy.protocol - toNewAudioProtocol:nil]; - } + [self.secondaryTransportManager stop]; [self.systemCapabilityManager stop]; [self.responseDispatcher clear]; @@ -458,9 +453,9 @@ - (void)didEnterStateSettingUpManagers { [self.encryptionLifecycleManager startWithProtocol:self.proxy.protocol]; } - // if secondary transport manager is used, streaming media manager will be started through onAudioServiceProtocolUpdated and onVideoServiceProtocolUpdated + // If the secondary transport manager is used, the streaming media manager will be started through `onAudioServiceProtocolUpdated` and `onVideoServiceProtocolUpdated` if (self.secondaryTransportManager == nil && self.streamManager != nil) { - [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:self.proxy.protocol fromOldAudioProtocol:nil toNewAudioProtocol:self.proxy.protocol]; + [self.streamManager startSecondaryTransportOnProtocol:self.proxy.protocol]; } dispatch_group_enter(managerGroup); @@ -888,53 +883,10 @@ - (void)sdl_remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notifi } } -#pragma mark Streaming protocol listener - -- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { - - BOOL videoProtocolUpdated = ((oldVideoProtocol == nil && newVideoProtocol == nil) || (oldVideoProtocol == newVideoProtocol)) ? NO : YES; - BOOL audioProtocolUpdated = ((oldAudioProtocol == nil && newAudioProtocol == nil) || (oldAudioProtocol == newAudioProtocol)) ? NO : YES; - - if (!videoProtocolUpdated && !audioProtocolUpdated) { - SDLLogV(@"The video and audio protocols did not update. Nothing will update."); - return; - } +#pragma mark - SDLSecondaryTransportDelegate - if (oldVideoProtocol != nil && oldAudioProtocol != nil) { - // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf.streamManager stopVideoWithCompletionHandler:^(BOOL success) { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; - [strongSelf.streamManager destroyAudioProtocol]; - [strongSelf.streamManager destroyVideoProtocol]; - [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - }]; - } else if (oldVideoProtocol != nil) { - // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self.streamManager stopVideoWithCompletionHandler:^(BOOL success) { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; - [strongSelf.streamManager destroyVideoProtocol]; - [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - } else if (oldAudioProtocol != nil) { - // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self.streamManager stopAudioWithCompletionHandler:^(BOOL success) { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf.secondaryTransportManager disconnectSecondaryTransport]; - [strongSelf.streamManager destroyAudioProtocol]; - [strongSelf.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - } else { - // No audio and/or video service currently running. Just start the new audio and/or video services. - [self.streamManager startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - } +- (void)destroySecondaryTransport { + [self.secondaryTransportManager disconnectSecondaryTransport]; } @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 6b1aa7321..706a23dfa 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -23,9 +23,17 @@ NS_ASSUME_NONNULL_BEGIN +@protocol SDLSecondaryTransportDelegate + +- (void)destroySecondaryTransport; + +@end + #pragma mark - Interface -/// Manager to help control streaming media services. +/** + * Manager to help control streaming video and audio media services. + */ @interface SDLStreamingMediaManager : NSObject /** @@ -86,7 +94,7 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic, readonly) CGSize screenSize; /** - This is the agreed upon format of video encoder that is in use, or nil if not currently connected. + * This is the agreed upon format of video encoder that is in use, or nil if not currently connected. */ @property (strong, nonatomic, readonly, nullable) SDLVideoStreamingFormat *videoFormat; @@ -98,7 +106,7 @@ NS_ASSUME_NONNULL_BEGIN /** * The pixel buffer pool reference returned back from an active VTCompressionSessionRef encoder. * - * @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started). + * @warning This will only return a valid pixel buffer pool after the encoder has been initialized (when the video session has started). * @discussion Clients may call this once and retain the resulting pool, this call is cheap enough that it's OK to call it once per frame. */ @property (assign, nonatomic, readonly, nullable) CVPixelBufferPoolRef pixelBufferPool; @@ -111,10 +119,15 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType; /** - When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES. + * When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES. */ @property (assign, nonatomic) BOOL showVideoBackgroundDisplay; +/** + * A delegate callback that notifies when the secondary transport state can change. + */ +@property (weak, nonatomic, nullable) id secondaryTransportDelegate; + /// Initializer unavailable - (instancetype)init NS_UNAVAILABLE; @@ -127,21 +140,6 @@ NS_ASSUME_NONNULL_BEGIN */ - (instancetype)initWithConnectionManager:(id)connectionManager configuration:(SDLConfiguration *)configuration NS_DESIGNATED_INITIALIZER; -/** - * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. - */ -- (void)startWithProtocol:(SDLProtocol *)protocol; - -/** - * Start the audio feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. - */ -- (void)startAudioWithProtocol:(SDLProtocol *)protocol; - -/** - * Start the video feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. - */ -- (void)startVideoWithProtocol:(SDLProtocol *)protocol; - /** * Stop the manager. This method is used internally. */ @@ -152,37 +150,16 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopAudio; -/** -* Stops the audio feature of the manager on the secondary transport. This method is used internally. -*/ -- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; - -/** - * Destroys the audio transport protocol after the secondary transport has been shut down. This method is used internally. - */ -- (void)destroyAudioProtocol; - /** * Stop the video feature of the manager. This method is used internally. */ - (void)stopVideo; /** - * Stops the video feature of the manager on the secondary transport. This method is used internally. - */ -- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler; - -/** - * Destroys the video service protocol after the secondary transport has been shut down. This method is used internally. - */ -- (void)destroyVideoProtocol; - -/** - * Starts the audio and/or video services using the new protocol. - * @param newAudioProtocol The new audio protocol - * @param newVideoProtocol The new video protocol + * Starts the video/audio services on the passed protocol. This method is used internally. + * @param protocol The protocol to use for the audio/video services */ -- (void)startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol; +- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 8b9111281..ba431f6be 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -11,15 +11,18 @@ #import "SDLAudioStreamManager.h" #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" +#import "SDLLogMacros.h" #import "SDLStreamingAudioLifecycleManager.h" +#import "SDLStreamingProtocolDelegate.h" #import "SDLStreamingVideoLifecycleManager.h" #import "SDLStreamingVideoScaleManager.h" #import "SDLTouchManager.h" + NS_ASSUME_NONNULL_BEGIN -@interface SDLStreamingMediaManager () +@interface SDLStreamingMediaManager () @property (strong, nonatomic) SDLStreamingAudioLifecycleManager *audioLifecycleManager; @property (strong, nonatomic) SDLStreamingVideoLifecycleManager *videoLifecycleManager; @@ -50,11 +53,6 @@ - (void)dealloc { [_videoLifecycleManager stop]; } -- (void)startWithProtocol:(SDLProtocol *)protocol { - [self startAudioWithProtocol:protocol]; - [self startVideoWithProtocol:protocol]; -} - - (void)stop { [self stopAudio]; [self stopVideo]; @@ -62,7 +60,7 @@ - (void)stop { #pragma mark Audio -- (void)startAudioWithProtocol:(SDLProtocol *)protocol { +- (void)sdl_startAudioWithProtocol:(SDLProtocol *)protocol { [self.audioLifecycleManager startWithProtocol:protocol]; self.audioStarted = YES; } @@ -78,7 +76,7 @@ - (BOOL)sendAudioData:(NSData*)audioData { #pragma mark Video -- (void)startVideoWithProtocol:(SDLProtocol *)protocol { +- (void)sdl_startVideoWithProtocol:(SDLProtocol *)protocol { [self.videoLifecycleManager startWithProtocol:protocol]; self.videoStarted = YES; } @@ -98,18 +96,80 @@ - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTim #pragma mark - Secondary Transport -- (void)startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol { +- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol { + [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; +} + +- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { + + BOOL videoProtocolUpdated = oldVideoProtocol != newVideoProtocol; + BOOL audioProtocolUpdated = oldAudioProtocol != newAudioProtocol; + + if (!videoProtocolUpdated && !audioProtocolUpdated) { + SDLLogV(@"The video and audio protocols did not update. Nothing will update."); + return; + } + + if (oldVideoProtocol != nil && oldAudioProtocol != nil) { + // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self sdl_stopAudioWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + [strongSelf sdl_stopVideoWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (strongSelf.secondaryTransportDelegate != nil) { + [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; + } + [strongSelf destroyAudioProtocol]; + [strongSelf destroyVideoProtocol]; + [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }]; + }]; + } else if (oldVideoProtocol != nil) { + // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self sdl_stopVideoWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (strongSelf.secondaryTransportDelegate != nil) { + [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; + } + [strongSelf destroyVideoProtocol]; + [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }]; + } else if (oldAudioProtocol != nil) { + // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. + __weak typeof(self) weakSelf = self; + [self sdl_stopAudioWithCompletionHandler:^(BOOL success) { + __strong typeof(weakSelf) strongSelf = weakSelf; + if (strongSelf.secondaryTransportDelegate != nil) { + [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; + } + [strongSelf destroyAudioProtocol]; + [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }]; + } else { + // No audio and/or video service currently running. Just start the new audio and/or video services. + [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + } +} + +/// Starts the audio and/or video services using the new protocol. +/// @param newAudioProtocol The new audio protocol +/// @param newVideoProtocol The new video protocol +- (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol { if (newAudioProtocol != nil) { - [self startAudioWithProtocol:newAudioProtocol]; + [self sdl_startAudioWithProtocol:newAudioProtocol]; } if (newVideoProtocol != nil) { - [self startVideoWithProtocol:newVideoProtocol]; + [self sdl_startVideoWithProtocol:newVideoProtocol]; } } #pragma mark Video -- (void)stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +/// Stops the video feature of the manager on the secondary transport. +/// @param completionHandler Called when video has stopped. +- (void)sdl_stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; [self.videoLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { weakSelf.videoStarted = NO; @@ -125,7 +185,9 @@ - (void)destroyVideoProtocol { #pragma mark Audio -- (void)stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +/// Stops the audio feature of the manager on the secondary transport. +/// @param completionHandler Called when audio has stopped. +- (void)sdl_stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; [self.audioLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { weakSelf.audioStarted = NO; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index 4e136dfa0..d987785b8 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -291,7 +291,7 @@ @interface SDLLifecycleManager () OCMStub([fileManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), fileManagerStartError, nil])]); OCMStub([permissionManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), permissionManagerStartError, nil])]); if (testConfig.lifecycleConfig.tcpDebugMode) { - OCMStub([streamingManagerMock startWithProtocol:protocolMock]); + OCMStub([streamingManagerMock startSecondaryTransportOnProtocol:proxyMock]); } // Send an RAI response & make sure we have an HMI status to move the lifecycle forward @@ -306,7 +306,7 @@ @interface SDLLifecycleManager () OCMVerify([fileManagerMock startWithCompletionHandler:[OCMArg any]]); OCMVerify([permissionManagerMock startWithCompletionHandler:[OCMArg any]]); if (testManager.configuration.lifecycleConfig.tcpDebugMode) { - OCMVerify([streamingManagerMock startWithProtocol:[OCMArg any]]); + OCMStub([streamingManagerMock startSecondaryTransportOnProtocol:[OCMArg any]]); } }); From d4d64cd13a745aa6d2b52b52e8e5bdf67ab6970d Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:15:41 -0500 Subject: [PATCH 062/152] Fixed error log for NAK --- SmartDeviceLink/SDLProtocol.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m index 3ef3541e0..f841e849b 100644 --- a/SmartDeviceLink/SDLProtocol.m +++ b/SmartDeviceLink/SDLProtocol.m @@ -684,7 +684,7 @@ - (void)sdl_logControlNAKPayload:(SDLProtocolMessage *)nakMessage { SDLControlFramePayloadNak *endServiceNakPayload = [[SDLControlFramePayloadNak alloc] initWithData:nakMessage.payload]; NSArray *rejectedParams = endServiceNakPayload.rejectedParams; if (rejectedParams.count > 0) { - SDLLogE(@"%@ Service NAK'd, service type: %@, rejectedParams: %@", (nakMessage.header.frameData == SDLFrameInfoStartServiceACK) ? @"Start" : @"End", @(nakMessage.header.serviceType), rejectedParams); + SDLLogE(@"%@ service NAK'd, service type: %@, rejectedParams: %@", (nakMessage.header.frameData == SDLFrameInfoStartServiceNACK) ? @"Start" : @"End", @(nakMessage.header.serviceType), rejectedParams); } } } break; From ec454dee7f7fc48f024d3fbe00f6ac4a638f09ca Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:16:45 -0500 Subject: [PATCH 063/152] Fixed documentation formatting --- SmartDeviceLink/SDLSecondaryTransportManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 761c3bba0..691fd5e9b 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -69,7 +69,7 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { @interface SDLSecondaryTransportManager () -// State of this manager. +/// State of this manager. @property (strong, nonatomic, readwrite) SDLStateMachine *stateMachine; // Dedicated queue that the state machine will run on. @property (copy, nonatomic) dispatch_queue_t stateMachineQueue; From 1d86ebdb64a4b98de38dff2f9a03fd692e25192e Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:28:07 -0500 Subject: [PATCH 064/152] Refactored the secondary transport manager --- .../SDLSecondaryTransportManager.m | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 691fd5e9b..63aeeb515 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -53,6 +53,9 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { SDLSecondaryTransportState *const SDLSecondaryTransportStateRegistered = @"Registered"; SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting = @"Reconnecting"; +/// Name for the background task started when the device app is backgrounded. +NSString *const BackgroundTaskSecondaryTransportName = @"com.sdl.transport.secondaryTransportBackgroundTask"; + // Timeout for receiving Register Secondary Transport ACK frame static const float RegisterTransportTime = 10.0; @@ -62,7 +65,8 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { // Indicates that a TCP port is not specified (unconfigured). static const int TCPPortUnspecified = -1; -struct TransportUpdated { +/// The old and new protocols being used when the transport switches. If the old protocol is `nil`, the transport is not yet started; newProtocol is `nil` the transport will be stopped. +struct TransportProtocolUpdated { SDLProtocol * _Nullable oldProtocol; SDLProtocol * _Nullable newProtocol; } transportUpdated; @@ -111,8 +115,6 @@ @interface SDLSecondaryTransportManager () @implementation SDLSecondaryTransportManager -NSString *const BackgroundTaskSecondaryTransportName = @"com.sdl.transport.secondaryTransportBackgroundTask"; - #pragma mark - Public - (instancetype)initWithStreamingProtocolDelegate:(id)streamingProtocolDelegate @@ -339,18 +341,15 @@ - (void)didEnterStateReconnecting { #pragma mark - Starting / Stopping / Restarting services - (void)sdl_handleTransportUpdateWithPrimaryAvailable:(BOOL)primaryAvailable secondaryAvailable:(BOOL)secondaryAvailable { - struct TransportUpdated audioTransportUpdated = [self sdl_updateService:SDLServiceTypeAudio allowedTransports:self.transportsForAudioService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; - struct TransportUpdated videoTransportUpdated = [self sdl_updateService:SDLServiceTypeVideo allowedTransports:self.transportsForVideoService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; + struct TransportProtocolUpdated audioTransportUpdated = [self sdl_updateService:SDLServiceTypeAudio allowedTransports:self.transportsForAudioService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; + struct TransportProtocolUpdated videoTransportUpdated = [self sdl_updateService:SDLServiceTypeVideo allowedTransports:self.transportsForVideoService primaryAvailable:primaryAvailable secondaryAvailable:secondaryAvailable]; if (audioTransportUpdated.newProtocol == audioTransportUpdated.oldProtocol && videoTransportUpdated.newProtocol == videoTransportUpdated.oldProtocol) { return; } [self.streamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:videoTransportUpdated.oldProtocol toNewVideoProtocol:videoTransportUpdated.newProtocol fromOldAudioProtocol:audioTransportUpdated.oldProtocol toNewAudioProtocol:audioTransportUpdated.newProtocol]; } -- (struct TransportUpdated)sdl_updateService:(UInt8)service - allowedTransports:(nonnull NSArray *)transportList - primaryAvailable:(BOOL)primaryTransportAvailable - secondaryAvailable:(BOOL)secondaryTransportAvailable { +- (struct TransportProtocolUpdated)sdl_updateService:(UInt8)service allowedTransports:(nonnull NSArray *)transportList primaryAvailable:(BOOL)primaryTransportAvailable secondaryAvailable:(BOOL)secondaryTransportAvailable { SDLTransportClass newTransport = SDLTransportClassInvalid; // the list is in preferred order, so take a look from the beginning for (SDLTransportClassBox *transport in transportList) { @@ -380,7 +379,7 @@ - (struct TransportUpdated)sdl_updateService:(UInt8)service SDLLogV(@"Transport was not updated"); } - struct TransportUpdated transportUpdated; + struct TransportProtocolUpdated transportUpdated; transportUpdated.oldProtocol = [self sdl_getProtocolFromTransportClass:oldTransport]; transportUpdated.newProtocol = [self sdl_getProtocolFromTransportClass:newTransport]; return transportUpdated; From 87977bc2d3cd57b0b9809ac0c1fc2f4b1a2cc9f0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:41:17 -0500 Subject: [PATCH 065/152] Renamed handlers --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 4 ++-- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 4 ++-- SmartDeviceLink/SDLStreamingVideoLifecycleManager.h | 4 ++-- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 720e60176..3a5dec670 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -23,7 +23,7 @@ /// Called when an end audio service ACK or NAK has been received. /// @param success True if the end service ACKed; False if NAKed. -typedef void (^SDLAudioEndedCompletionHandler)(BOOL success); +typedef void (^SDLAudioServiceEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -91,7 +91,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. */ -- (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler)audioEndedCompletionHandler; +- (void)stopAudioWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index bb8325152..ba90a9a67 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -43,7 +43,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (copy, nonatomic) NSArray *secureMakes; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; -@property (nonatomic, copy, nullable) SDLAudioEndedCompletionHandler audioEndedCompletionHandler; +@property (nonatomic, copy, nullable) SDLAudioServiceEndedCompletionHandler audioEndedCompletionHandler; @end @@ -122,7 +122,7 @@ - (void)stop { // Stops the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. // 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. -- (void)stopAudioWithCompletionHandler:(nullable SDLAudioEndedCompletionHandler)completionHandler { +- (void)stopAudioWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { SDLLogD(@"Stopping audio streaming"); self.audioEndedCompletionHandler = completionHandler; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 0752817a3..2333a72aa 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -30,7 +30,7 @@ /// Called when an end video service ACK or NAK has been received. /// @param success True if the end service ACKed; False if NAKed. -typedef void (^SDLVideoEndedCompletionHandler)(BOOL success); +typedef void (^SDLVideoServiceEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -165,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. */ -- (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler)videoEndedCompletionHandler; +- (void)stopVideoWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index de1ea8733..4399c58f1 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -92,7 +92,7 @@ @interface SDLStreamingVideoLifecycleManager() @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; -@property (nonatomic, copy, nullable) SDLVideoEndedCompletionHandler videoEndedCompletionHandler; +@property (nonatomic, copy, nullable) SDLVideoServiceEndedCompletionHandler videoEndedCompletionHandler; @end @@ -226,7 +226,7 @@ - (void)stop { // 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. // 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). -- (void)stopVideoWithCompletionHandler:(nullable SDLVideoEndedCompletionHandler)completionHandler { +- (void)stopVideoWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { self.videoEndedCompletionHandler = completionHandler; // Always send an end video service control frame, regardless of whether video is streaming or not. From 0fdf860519ef90f27a089f579bafbd9d99c67baa Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 14:57:43 -0500 Subject: [PATCH 066/152] Renamed video/audio completion handlers --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 11 ++++++++++- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 2 +- SmartDeviceLink/SDLStreamingMediaManager.m | 4 ++-- SmartDeviceLink/SDLStreamingVideoLifecycleManager.h | 2 +- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 +- .../SDLStreamingAudioLifecycleManagerSpec.m | 2 +- .../SDLStreamingVideoLifecycleManagerSpec.m | 2 +- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 3a5dec670..861f0e911 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -64,6 +64,15 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; +/** +Create a new streaming media manager for navigation and VPM apps with a specified configuration. Used for testing. + +@param connectionManager The pass-through for RPCs +@param streamingConfiguration The configuration of this streaming media session +@param encryptionConfiguration The encryption configuration with security managers +@param audioManager The audio manager. +@return A new streaming manager +*/ - (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration audioManager:(nullable SDLAudioStreamManager *)audioManager NS_DESIGNATED_INITIALIZER; /** @@ -91,7 +100,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. */ -- (void)stopAudioWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; +- (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index ba90a9a67..1a2fbfccf 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -122,7 +122,7 @@ - (void)stop { // Stops the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. // 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. -- (void)stopAudioWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { +- (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { SDLLogD(@"Stopping audio streaming"); self.audioEndedCompletionHandler = completionHandler; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index ba431f6be..2e35452c3 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -171,7 +171,7 @@ - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol fo /// @param completionHandler Called when video has stopped. - (void)sdl_stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; - [self.videoLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { + [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^(BOOL success) { weakSelf.videoStarted = NO; if (completionHandler == nil) { return; } @@ -189,7 +189,7 @@ - (void)destroyVideoProtocol { /// @param completionHandler Called when audio has stopped. - (void)sdl_stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { + [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^(BOOL success) { weakSelf.audioStarted = NO; if (completionHandler == nil) { return; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 2333a72aa..1e1cebfa6 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -165,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN * * @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. */ -- (void)stopVideoWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; +- (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; /** * This method is used internally to destroy the protocol after the secondary transport is shut down. diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 4399c58f1..f5b7db1f0 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -226,7 +226,7 @@ - (void)stop { // 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. // 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). -- (void)stopVideoWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { +- (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { self.videoEndedCompletionHandler = completionHandler; // Always send an end video service control frame, regardless of whether video is streaming or not. diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index e448f023e..cf6b519e3 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -465,7 +465,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve context(@"if stopping audio on secondary transport", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; - [streamingLifecycleManager stopAudioWithCompletionHandler:^(BOOL success) { + [streamingLifecycleManager endAudioServiceWithCompletionHandler:^(BOOL success) { handlerCalled = YES; audioServiceEnded = success; }]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 01c8da970..ede58e04c 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -858,7 +858,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream context(@"if stopping video on secondary transport", ^{ beforeEach(^{ - [streamingLifecycleManager stopVideoWithCompletionHandler:^(BOOL success) { + [streamingLifecycleManager endVideoServiceWithCompletionHandler:^(BOOL success) { handlerCalled = YES; videoServiceEnded = success; }]; From f3a3fd65832cdec2b8aaecb09d4eb60011c5ad82 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 15:02:52 -0500 Subject: [PATCH 067/152] Removed redundant setting to `nil` --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 3 +-- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 1a2fbfccf..6899cf6a1 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -64,7 +64,6 @@ - (instancetype)initWithConnectionManager:(id)connecti _connectionManager = connectionManager; _audioManager = audioManager != nil ? audioManager : [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; - _connectedVehicleMake = nil; NSMutableArray *tempMakeArray = [NSMutableArray array]; #pragma clang diagnostic push @@ -100,8 +99,8 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { [self sdl_startAudioSession]; } -/// Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. - (void)stop { + // Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. SDLLogD(@"Stopping audio streaming lifecycle manager"); // Since the transport layer has been destroyed, destroy the protocol as it is not usable. diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index f5b7db1f0..6bc2965ad 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -129,7 +129,6 @@ - (instancetype)initWithConnectionManager:(id)connecti _touchManager = [[SDLTouchManager alloc] initWithHitTester:(id)_focusableItemManager videoScaleManager:_videoScaleManager]; _requestedEncryptionType = configuration.streamingMediaConfig.maximumDesiredEncryption; - _connectedVehicleMake = nil; _dataSource = configuration.streamingMediaConfig.dataSource; _useDisplayLink = configuration.streamingMediaConfig.enableForcedFramerateSync; _backgroundingPixelBuffer = NULL; @@ -177,8 +176,6 @@ - (instancetype)initWithConnectionManager:(id)connecti _ssrc = arc4random_uniform(UINT32_MAX); _lastPresentationTimestamp = kCMTimeInvalid; - _videoEndedCompletionHandler = nil; - return self; } From dc566e6b9862c0423c2a415adc8581f1c0a98b3c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 15:25:22 -0500 Subject: [PATCH 068/152] Cleaned up streaming log modules & logs --- SmartDeviceLink/SDLLogFileModuleMap.m | 23 +++++++++++++++---- .../SDLStreamingAudioLifecycleManager.m | 10 ++++---- .../SDLStreamingVideoLifecycleManager.m | 9 ++++---- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index 9195840e0..f290c28a3 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -27,7 +27,10 @@ @implementation SDLLogFileModuleMap [self sdl_systemCapabilityModule], [self sdl_lockscreenManagerModule], [self sdl_streamingMediaManagerModule], - [self sdl_streamingMediaAudioTranscoderModule], + [self sdl_videoStreamingMediaManagerModule], + [self sdl_videoStreamingMediaTranscoderModule], + [self sdl_audioStreamingMediaManagerModule], + [self sdl_audioStreamingMediaTranscoderModule], [self sdl_screenManagerModule], [self sdl_screenManagerTextAndGraphicModule], [self sdl_screenManagerSoftButtonModule], @@ -95,11 +98,23 @@ + (SDLLogFileModule *)sdl_lockscreenManagerModule { } + (SDLLogFileModule *)sdl_streamingMediaManagerModule { - return [SDLLogFileModule moduleWithName:@"Streaming" files:[NSSet setWithArray:@[@"SDLH264VideoEncoder", @"SDLRAWH264Packetizer", @"SDLRTPH264Packetizer", @"SDLStreamingMediaManager", @"SDLStreamingAudioLifecycleManager", @"SDLStreamingVideoLifecycleManager", @"SDLTouchManager", @"SDLCarWindow"]]]; + return [SDLLogFileModule moduleWithName:@"Audio and Video Streaming" files:[NSSet setWithArray:@[@"SDLStreamingMediaManager"]]]; } -+ (SDLLogFileModule *)sdl_streamingMediaAudioTranscoderModule { - return [SDLLogFileModule moduleWithName:@"Streaming/Audio Transcode" files:[NSSet setWithArray:@[@"SDLAudioStreamManager", @"SDLPCMAudioConverter"]]]; ++ (SDLLogFileModule *)sdl_videoStreamingMediaManagerModule { + return [SDLLogFileModule moduleWithName:@"Video Streaming" files:[NSSet setWithArray:@[@"SDLStreamingVideoLifecycleManager", @"SDLTouchManager", @"SDLCarWindow"]]]; +} + ++ (SDLLogFileModule *)sdl_videoStreamingMediaTranscoderModule { + return [SDLLogFileModule moduleWithName:@"Video Streaming/Video Transcoding" files:[NSSet setWithArray:@[@"SDLH264VideoEncoder", @"SDLRAWH264Packetizer", @"SDLRTPH264Packetizer"]]]; +} + ++ (SDLLogFileModule *)sdl_audioStreamingMediaManagerModule { + return [SDLLogFileModule moduleWithName:@"Audio Streaming" files:[NSSet setWithArray:@[@"SDLStreamingAudioLifecycleManager"]]]; +} + ++ (SDLLogFileModule *)sdl_audioStreamingMediaTranscoderModule { + return [SDLLogFileModule moduleWithName:@"Audio Streaming/Audio Transcoding" files:[NSSet setWithArray:@[@"SDLAudioStreamManager", @"SDLPCMAudioConverter"]]]; } + (SDLLogFileModule *)sdl_screenManagerModule { diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 6899cf6a1..d60f8b26a 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -59,8 +59,6 @@ - (instancetype)initWithConnectionManager:(id)connecti return nil; } - SDLLogV(@"Creating AudioStreamingLifecycleManager"); - _connectionManager = connectionManager; _audioManager = audioManager != nil ? audioManager : [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; @@ -87,6 +85,7 @@ - (instancetype)initWithConnectionManager:(id)connecti } - (void)startWithProtocol:(SDLProtocol *)protocol { + SDLLogD(@"Starting with protocol: %@", self.protocol); _protocol = protocol; @synchronized(self.protocol.protocolDelegateTable) { @@ -101,7 +100,7 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { - (void)stop { // Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. - SDLLogD(@"Stopping audio streaming lifecycle manager"); + SDLLogD(@"Stopping manager"); // Since the transport layer has been destroyed, destroy the protocol as it is not usable. _protocol = nil; @@ -122,7 +121,7 @@ - (void)stop { // 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. // 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { - SDLLogD(@"Stopping audio streaming"); + SDLLogD(@"Ending audio service"); self.audioEndedCompletionHandler = completionHandler; // Stop the audio manager from sending any more data @@ -134,6 +133,7 @@ - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompl /// Used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol { + SDLLogD(@"Destroying protocol: %@", self.protocol); self.protocol = nil; } @@ -261,7 +261,7 @@ - (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification * return; } - SDLLogD(@"Received Register App Interface"); + SDLLogV(@"Received Register App Interface"); SDLRegisterAppInterfaceResponse* registerResponse = (SDLRegisterAppInterfaceResponse*)notification.response; #pragma clang diagnostic push diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 6bc2965ad..8da615bf0 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -104,8 +104,6 @@ - (instancetype)initWithConnectionManager:(id)connecti return nil; } - SDLLogV(@"Creating StreamingLifecycleManager"); - _appName = configuration.lifecycleConfig.appName; _connectionManager = connectionManager; _videoEncoderSettings = [NSMutableDictionary dictionary]; @@ -180,6 +178,7 @@ - (instancetype)initWithConnectionManager:(id)connecti } - (void)startWithProtocol:(SDLProtocol *)protocol { + SDLLogD(@"Starting with protocol: %@", self.protocol); _protocol = protocol; @synchronized(self.protocol.protocolDelegateTable) { @@ -195,7 +194,7 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { /// Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end video service control frame as the module will never receive the request. - (void)stop { - SDLLogD(@"Stopping video streaming lifecycle manager"); + SDLLogD(@"Stopping manager"); // Reset the video streaming parameters as video is not streaming. _backgroundingPixelBuffer = NULL; @@ -224,6 +223,7 @@ - (void)stop { // 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. // 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { + SDLLogD(@"Ending video service"); self.videoEndedCompletionHandler = completionHandler; // Always send an end video service control frame, regardless of whether video is streaming or not. @@ -232,6 +232,7 @@ - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompl /// Used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol { + SDLLogD(@"Destroying protocol: %@", self.protocol); self.protocol = nil; } @@ -730,8 +731,6 @@ - (void)sdl_stopVideoSession { if (self.isVideoConnected || self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; - } else { - SDLLogV(@"No video streaming. Will not send an end video service request."); } } From 019bd972de09953e3e16b17ab4305210bfb8d495 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 15:52:21 -0500 Subject: [PATCH 069/152] Removed unnecessary methods --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 11 +++-------- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 13 ++++--------- 2 files changed, 7 insertions(+), 17 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index d60f8b26a..0abbba41d 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -224,7 +224,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN if (startServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogW(@"Request to start audio service NAKed"); - [self sdl_transitionToStoppedState:SDLServiceTypeAudio]; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } #pragma mark End Service ACK/NAK @@ -238,7 +238,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { self.audioEndedCompletionHandler = nil; } - [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { @@ -250,7 +250,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { self.audioEndedCompletionHandler = nil; } - [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; + [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } #pragma mark - SDL RPC Notification callbacks @@ -330,11 +330,6 @@ - (void)sdl_stopAudioSession { } } -- (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { - if (serviceType != SDLServiceTypeAudio) { return; } - [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; -} - #pragma mark Setters / Getters - (BOOL)isHmiStateAudioStreamCapable { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 8da615bf0..ecff0f2e9 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -557,7 +557,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { - [self sdl_transitionToStoppedState:SDLServiceTypeVideo]; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; return; } @@ -586,7 +586,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { self.videoEndedCompletionHandler = nil; } - [self sdl_transitionToStoppedState:endServiceACK.header.serviceType]; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { @@ -598,7 +598,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { self.videoEndedCompletionHandler = nil; } - [self sdl_transitionToStoppedState:endServiceNAK.header.serviceType]; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } #pragma mark - SDL RPC Notification callbacks @@ -734,11 +734,6 @@ - (void)sdl_stopVideoSession { } } -- (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { - if (serviceType != SDLServiceTypeVideo) { return; } - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; -} - - (void)sdl_displayLinkFired:(CADisplayLink *)displayLink { NSAssert([NSThread isMainThread], @"Display link should always fire on the main thread"); if (@available(iOS 10.0, *)) { @@ -812,7 +807,7 @@ - (void)sdl_sendVideoStartService { if (self.preferredFormatIndex >= self.preferredFormats.count || self.preferredResolutionIndex >= self.preferredResolutions.count) { SDLLogE(@"No preferred format or no preferred resolution found that works: format index %lu, resolution index %lu", (unsigned long)self.preferredFormatIndex, (unsigned long)self.preferredResolutionIndex); - [self sdl_transitionToStoppedState:SDLServiceTypeVideo]; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; return; } From 284ebf6027899fff469d8ed793e2f02f140be737 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 15:56:00 -0500 Subject: [PATCH 070/152] Fixed check for nil --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index ecff0f2e9..93bc0d222 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -315,7 +315,7 @@ - (void)sdl_appStateDidUpdate:(NSNotification*)notification { - (void)didEnterStateAppInactive { SDLLogD(@"App became inactive"); - if (!self.protocol) { + if (self.protocol == nil) { SDLLogV(@"No session established with head unit. Ignoring app backgrounded notification"); return; } @@ -336,7 +336,7 @@ - (void)didEnterStateAppInactive { // We should be waiting to start any OpenGL drawing until UIApplicationDidBecomeActive is called. - (void)didEnterStateAppActive { SDLLogD(@"App became active"); - if (!self.protocol) { + if (self.protocol == nil) { SDLLogV(@"No session established with head unit. Ignoring app foregounded notification"); return; } @@ -665,7 +665,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { } // if startWithProtocol has not been called yet, abort here - if (!self.protocol) { + if (self.protocol == nil) { SDLLogV(@"No session established with head unit. HMI status is not relevant."); return; } @@ -697,7 +697,7 @@ - (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)en - (void)sdl_startVideoSession { SDLLogV(@"Attempting to start video session"); - if (!self.protocol) { + if (self.protocol == nil) { SDLLogV(@"No session established with head unit. Video start service request will not be sent."); return; } @@ -731,6 +731,8 @@ - (void)sdl_stopVideoSession { if (self.isVideoConnected || self.isVideoSuspended) { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateShuttingDown]; + } else { + SDLLogW(@"No video is currently streaming. Will not send an end video service request."); } } From 25718bafae1fac3e9ec6cff4df9572dfcf85faa0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 15:58:36 -0500 Subject: [PATCH 071/152] Fixed documentation for hmiLevel --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 93bc0d222..5dc5024b5 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -640,9 +640,10 @@ - (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification * } /// Parses out the `hmiLevel` and `videoStreamingState` from an `OnHMIStatus` notification from Core. Since Core only allows video streaming when the `hmiLevel` is `FULL` or `LIMITED`, sending video data when the `hmiLevel` is not `FULL` or `LIMITED` will result in Core forcing an unregistration with a reason of `PROTOCOL_VIOLATION`. -/// 2. The `hmiLevel` will go to `FULL` when the user opens the SDL app by tapping on the SDL app icon on the HMI or uses a voice command to launch the SDL app. -/// 3. The `hmiLevel` will go to `LIMITED` when the user backgrounds the SDL app by opening another app or by going back to the home screen. -/// 4. The `hmiLevel` will go to `NONE` when the user "exits" the app (either through gesture or voice commands). It will also go to `NONE` if video fails to stream and the user presses "cancel" on the HMI popup. In these cases the transport between the phone and accessory will still be open. It will also go to `NONE` when the user disconnects the transport between the phone and accessory. In this case no notification will be recieved since the transport was disconnected. +/// 1. The `hmiLevel` will go to `FULL` when the user opens the SDL app by tapping on the SDL app icon on the HMI or uses a voice command to launch the SDL app. +/// 2. The `hmiLevel` will go to `LIMITED` when the user backgrounds the SDL app by opening another app or by going back to the home screen. +/// 3. The `hmiLevel` will go to `NONE` when the user "exits" the app (either through gesture or voice commands). It will also go to `NONE` if video fails to stream and the user presses "cancel" on the HMI popup. In these cases the transport between the phone and accessory will still be open. It will also go to `NONE` when the user disconnects the transport between the phone and accessory. In this case no notification will be recieved since the transport was disconnected. +/// 4. The `hmiLevel` will go to `BACKGROUND` if the app is in `LIMITED` and another app takes over video streaming capability (i.e. another navigation app's `hmiLevel` changes to `FULL`). /// /// @param notification The `OnHMIStatus` notification - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { From 0a91598cae7aa5d044bebf11a047821db5f66413 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 16:19:36 -0500 Subject: [PATCH 072/152] Refactored logs and docs --- .../SDLStreamingAudioLifecycleManager.h | 13 +++++-------- .../SDLStreamingAudioLifecycleManager.m | 13 +++++-------- .../SDLStreamingVideoLifecycleManager.h | 14 ++++++-------- .../SDLStreamingVideoLifecycleManager.m | 19 ++++++++----------- 4 files changed, 24 insertions(+), 35 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 861f0e911..090740323 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -90,16 +90,13 @@ Create a new streaming media manager for navigation and VPM apps with a specifie */ - (void)startWithProtocol:(SDLProtocol *)protocol; -/** - * This method is used internally to stop the manager when the device disconnects from the module. - */ +/// This method is used internally to stop the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. - (void)stop; -/** - * This method is used internally to end an audio service on the secondary transport. The primary transport is still open. - * - * @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. -*/ +/// This method is used internally to stop the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. +/// 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. +/// 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. +/// @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; /** diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 0abbba41d..7de0e697a 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -42,6 +42,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (copy, nonatomic) NSArray *secureMakes; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; +@property (assign, nonatomic, readwrite, getter=isAudioEncrypted) BOOL audioEncrypted; @property (nonatomic, copy, nullable) SDLAudioServiceEndedCompletionHandler audioEndedCompletionHandler; @@ -99,7 +100,6 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { } - (void)stop { - // Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end audio service control frame as the module will never receive the request. SDLLogD(@"Stopping manager"); // Since the transport layer has been destroyed, destroy the protocol as it is not usable. @@ -117,9 +117,6 @@ - (void)stop { [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } -// Stops the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. -// 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. -// 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { SDLLogD(@"Ending audio service"); self.audioEndedCompletionHandler = completionHandler; @@ -208,10 +205,10 @@ - (void)didEnterStateAudioStreamShuttingDown { - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogD(@"Request to start audio service ACKed"); - _audioEncrypted = startServiceACK.header.encrypted; + self.audioEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadAudioStartServiceAck *audioAckPayload = [[SDLControlFramePayloadAudioStartServiceAck alloc] initWithData:startServiceACK.payload]; + SDLLogD(@"Request to start audio service ACKed with payload: %@", audioAckPayload); if (audioAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)audioAckPayload.mtu forServiceType:SDLServiceTypeAudio]; @@ -222,7 +219,7 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceNAK { if (startServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Request to start audio service NAKed"); + SDLLogE(@"Request to start audio service NAKed"); [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } @@ -244,7 +241,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogW(@"Request to end audio service NAKed"); + SDLLogE(@"Request to end audio service NAKed"); if (self.audioEndedCompletionHandler != nil) { self.audioEndedCompletionHandler(NO); self.audioEndedCompletionHandler = nil; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 1e1cebfa6..d9925d287 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -155,16 +155,14 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)startWithProtocol:(SDLProtocol *)protocol; -/** - * This method is used internally to stop the manager when the device disconnects from the module. - */ +/// This method is used internally to stop the manager when the device disconnects from the module. - (void)stop; -/** - * This method is used internally to end a video service on the secondary transport. The primary transport is still open. - * - * @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. - */ +/// This method is used internally to stop the manager when video needs to be stopped on the secondary transport. The primary transport is still open. +/// 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` because we can still get notifications from the module with the updated hmi status on the primary transport. +/// 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. +/// 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). +/// @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; /** diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 5dc5024b5..8a26f1cb3 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -79,6 +79,8 @@ @interface SDLStreamingVideoLifecycleManager() @property (strong, nonatomic, nullable) CADisplayLink *displayLink; @property (assign, nonatomic) BOOL useDisplayLink; +@property (assign, nonatomic, readwrite, getter=isVideoEncrypted) BOOL videoEncrypted; + /** * SSRC of RTP header field. * @@ -191,8 +193,6 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { [self sdl_startVideoSession]; } - -/// Stops the manager when the device disconnects from the module. Since there is no connection between the device and the module there is no point in sending an end video service control frame as the module will never receive the request. - (void)stop { SDLLogD(@"Stopping manager"); @@ -218,10 +218,6 @@ - (void)stop { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } -// Stops the manager when video needs to be stopped on the secondary transport. The primary transport is still open. -// 1. Since the primary transport is still open, do will not reset the `hmiLevel` and `videoStreamingState` since we can still get notifications from the module with the updated hmi status on the primary transport. -// 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. -// 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { SDLLogD(@"Ending video service"); self.videoEndedCompletionHandler = completionHandler; @@ -480,7 +476,7 @@ - (void)didEnterStateVideoStreamReady { [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil]; if (!self.isAppStateVideoStreamCapable) { - SDLLogV(@"App is in the background and can not stream video. Video will resume when app is foregrounded"); + SDLLogD(@"App is in the background and can not stream video. Video will resume when app is foregrounded"); [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateSuspended]; return; } @@ -519,10 +515,11 @@ - (void)didEnterStateVideoStreamShuttingDown { - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { if (startServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogD(@"Request to start video service ACKed"); - _videoEncrypted = startServiceACK.header.encrypted; + self.videoEncrypted = startServiceACK.header.encrypted; SDLControlFramePayloadVideoStartServiceAck *videoAckPayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithData:startServiceACK.payload]; + SDLLogD(@"Request to start video service ACKed with payload: %@", videoAckPayload); + if (videoAckPayload.mtu != SDLControlFrameInt64NotFound) { [[SDLGlobals sharedGlobals] setDynamicMTUSize:(NSUInteger)videoAckPayload.mtu forServiceType:SDLServiceTypeVideo]; @@ -553,7 +550,7 @@ - (void)handleProtocolStartServiceNAKMessage:(SDLProtocolMessage *)startServiceN if (startServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:startServiceNAK.payload]; - SDLLogW(@"Request to start video service NAKed with reason: %@", nakPayload.description); + SDLLogE(@"Request to start video service NAKed with reason: %@", nakPayload.description); // If we have no payload rejected params, we don't know what to do to retry, so we'll just stop and maybe cry if (nakPayload.rejectedParams.count == 0) { @@ -592,7 +589,7 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogW(@"Request to end video service NAKed"); + SDLLogE(@"Request to end video service NAKed"); if (self.videoEndedCompletionHandler != nil) { self.videoEndedCompletionHandler(NO); self.videoEndedCompletionHandler = nil; From 0fe779090e6c193c81a07b9a2ec44dc440350dc3 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 3 Mar 2020 16:30:52 -0500 Subject: [PATCH 073/152] Removed unnecessary methods --- SmartDeviceLink/SDLStreamingMediaManager.m | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 2e35452c3..98b94b6a6 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -60,11 +60,6 @@ - (void)stop { #pragma mark Audio -- (void)sdl_startAudioWithProtocol:(SDLProtocol *)protocol { - [self.audioLifecycleManager startWithProtocol:protocol]; - self.audioStarted = YES; -} - - (void)stopAudio { [self.audioLifecycleManager stop]; self.audioStarted = NO; @@ -76,11 +71,6 @@ - (BOOL)sendAudioData:(NSData*)audioData { #pragma mark Video -- (void)sdl_startVideoWithProtocol:(SDLProtocol *)protocol { - [self.videoLifecycleManager startWithProtocol:protocol]; - self.videoStarted = YES; -} - - (void)stopVideo { [self.videoLifecycleManager stop]; self.videoStarted = NO; @@ -158,10 +148,12 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto /// @param newVideoProtocol The new video protocol - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol { if (newAudioProtocol != nil) { - [self sdl_startAudioWithProtocol:newAudioProtocol]; + [self.audioLifecycleManager startWithProtocol:newAudioProtocol]; + self.audioStarted = YES; } if (newVideoProtocol != nil) { - [self sdl_startVideoWithProtocol:newVideoProtocol]; + [self.videoLifecycleManager startWithProtocol:newVideoProtocol]; + self.videoStarted = YES; } } From 472924f62eda19206c5678c1fe3f85a3032ec137 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 4 Mar 2020 11:19:25 -0500 Subject: [PATCH 074/152] Fixed documentation formatting --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 4 +--- SmartDeviceLink/SDLStreamingVideoLifecycleManager.h | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 090740323..283666a30 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -99,9 +99,7 @@ Create a new streaming media manager for navigation and VPM apps with a specifie /// @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; -/** - * This method is used internally to destroy the protocol after the secondary transport is shut down. - */ +/// This method is used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol; /** diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index d9925d287..5737ef825 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -165,9 +165,7 @@ NS_ASSUME_NONNULL_BEGIN /// @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; -/** - * This method is used internally to destroy the protocol after the secondary transport is shut down. - */ +/// This method is used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol; /** From 780115b123cc870c3b01d004d09249466a435152 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 4 Mar 2020 11:24:18 -0500 Subject: [PATCH 075/152] Fixed documentation --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 11 ----------- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 11 ----------- 2 files changed, 22 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 7de0e697a..1ea764204 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -101,17 +101,9 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { - (void)stop { SDLLogD(@"Stopping manager"); - - // Since the transport layer has been destroyed, destroy the protocol as it is not usable. _protocol = nil; - - // Reset the `hmiLevel`. This is done because we will not get a notification with the updated hmi status due to the transport being destroyed. _hmiLevel = SDLHMILevelNone; - - // Reset the `connectedVehicleMake` because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. It is possible that the user could connect to different module during the same app session. _connectedVehicleMake = nil; - - // Stop the audio manager [_audioManager stop]; [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; @@ -121,10 +113,7 @@ - (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompl SDLLogD(@"Ending audio service"); self.audioEndedCompletionHandler = completionHandler; - // Stop the audio manager from sending any more data [_audioManager stop]; - - // Always send an end audio service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeAudio]; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 8a26f1cb3..efffba38e 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -196,23 +196,14 @@ - (void)startWithProtocol:(SDLProtocol *)protocol { - (void)stop { SDLLogD(@"Stopping manager"); - // Reset the video streaming parameters as video is not streaming. _backgroundingPixelBuffer = NULL; _preferredFormatIndex = 0; _preferredResolutionIndex = 0; _lastPresentationTimestamp = kCMTimeInvalid; - - // Reset the `hmiLevel` and `videoStreamingState`. This is done because we will not get a notification with the updated hmi status due to the transport being destroyed. _hmiLevel = SDLHMILevelNone; _videoStreamingState = SDLVideoStreamingStateNotStreamable; - - // Since the transport layer has been destroyed, destroy the protocol as it is not usable. _protocol = nil; - - // Reset the video scale manager because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. [self.videoScaleManager stop]; - - // Reset the `connectedVehicleMake` because we will get a `RegisterAppInterfaceResponse` when a new session is established between the device and a module. It is possible that the user could connect to different module during the same app session. _connectedVehicleMake = nil; [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; @@ -221,8 +212,6 @@ - (void)stop { - (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { SDLLogD(@"Ending video service"); self.videoEndedCompletionHandler = completionHandler; - - // Always send an end video service control frame, regardless of whether video is streaming or not. [self.protocol endServiceWithType:SDLServiceTypeVideo]; } From 4ce0ef8d17cdae628c28bd63065589e258c697eb Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 4 Mar 2020 13:13:58 -0500 Subject: [PATCH 076/152] Removed typedef for completion handler --- .../SDLStreamingAudioLifecycleManager.h | 5 +--- .../SDLStreamingAudioLifecycleManager.m | 19 ++++++------ SmartDeviceLink/SDLStreamingMediaManager.h | 16 ++++++---- SmartDeviceLink/SDLStreamingMediaManager.m | 30 +++++++++---------- .../SDLStreamingVideoLifecycleManager.h | 5 +--- .../SDLStreamingVideoLifecycleManager.m | 19 ++++++------ .../SDLStreamingAudioLifecycleManagerSpec.m | 7 +---- .../SDLStreamingVideoLifecycleManagerSpec.m | 7 +---- 8 files changed, 47 insertions(+), 61 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 283666a30..70eeccbca 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -21,9 +21,6 @@ @protocol SDLConnectionManagerType; -/// Called when an end audio service ACK or NAK has been received. -/// @param success True if the end service ACKed; False if NAKed. -typedef void (^SDLAudioServiceEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -97,7 +94,7 @@ Create a new streaming media manager for navigation and VPM apps with a specifie /// 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. /// 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. /// @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. -- (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)audioEndedCompletionHandler; +- (void)endAudioServiceWithCompletionHandler:(void (^)(void))audioEndedCompletionHandler; /// This method is used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol; diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 1ea764204..8420aeb36 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -44,8 +44,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; @property (assign, nonatomic, readwrite, getter=isAudioEncrypted) BOOL audioEncrypted; -@property (nonatomic, copy, nullable) SDLAudioServiceEndedCompletionHandler audioEndedCompletionHandler; - +@property (nonatomic, copy, nullable) void (^audioServiceEndedCompletionHandler)(void); @end @implementation SDLStreamingAudioLifecycleManager @@ -109,9 +108,9 @@ - (void)stop { [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } -- (void)endAudioServiceWithCompletionHandler:(nullable SDLAudioServiceEndedCompletionHandler)completionHandler { +- (void)endAudioServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending audio service"); - self.audioEndedCompletionHandler = completionHandler; + self.audioServiceEndedCompletionHandler = completionHandler; [_audioManager stop]; [self.protocol endServiceWithType:SDLServiceTypeAudio]; @@ -219,9 +218,9 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogD(@"Request to end audio service ACKed"); - if (self.audioEndedCompletionHandler != nil) { - self.audioEndedCompletionHandler(YES); - self.audioEndedCompletionHandler = nil; + if (self.audioServiceEndedCompletionHandler != nil) { + self.audioServiceEndedCompletionHandler(); + self.audioServiceEndedCompletionHandler = nil; } [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; @@ -231,9 +230,9 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } SDLLogE(@"Request to end audio service NAKed"); - if (self.audioEndedCompletionHandler != nil) { - self.audioEndedCompletionHandler(NO); - self.audioEndedCompletionHandler = nil; + if (self.audioServiceEndedCompletionHandler != nil) { + self.audioServiceEndedCompletionHandler(); + self.audioServiceEndedCompletionHandler = nil; } [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 706a23dfa..be7a9d521 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -128,6 +128,8 @@ NS_ASSUME_NONNULL_BEGIN */ @property (weak, nonatomic, nullable) id secondaryTransportDelegate; +#pragma mark - Lifecycle + /// Initializer unavailable - (instancetype)init NS_UNAVAILABLE; @@ -155,11 +157,7 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)stopVideo; -/** - * Starts the video/audio services on the passed protocol. This method is used internally. - * @param protocol The protocol to use for the audio/video services - */ -- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; +#pragma mark - Data Transfer /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. @@ -191,6 +189,14 @@ NS_ASSUME_NONNULL_BEGIN */ - (BOOL)sendAudioData:(NSData *)audioData; +#pragma mark - Secondary Transport Specific + +/** + * Starts the video/audio services on the passed protocol. This method is used internally. + * @param protocol The protocol to use for the audio/video services + */ +- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; + @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 98b94b6a6..db2f3f9d3 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -103,9 +103,9 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto if (oldVideoProtocol != nil && oldAudioProtocol != nil) { // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. __weak typeof(self) weakSelf = self; - [self sdl_stopAudioWithCompletionHandler:^(BOOL success) { + [self sdl_stopAudioWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf sdl_stopVideoWithCompletionHandler:^(BOOL success) { + [strongSelf sdl_stopVideoWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; @@ -118,7 +118,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto } else if (oldVideoProtocol != nil) { // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. __weak typeof(self) weakSelf = self; - [self sdl_stopVideoWithCompletionHandler:^(BOOL success) { + [self sdl_stopVideoWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; @@ -129,7 +129,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto } else if (oldAudioProtocol != nil) { // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. __weak typeof(self) weakSelf = self; - [self sdl_stopAudioWithCompletionHandler:^(BOOL success) { + [self sdl_stopAudioWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; @@ -161,13 +161,12 @@ - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol fo /// Stops the video feature of the manager on the secondary transport. /// @param completionHandler Called when video has stopped. -- (void)sdl_stopVideoWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +- (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { __weak typeof(self) weakSelf = self; - [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^(BOOL success) { - weakSelf.videoStarted = NO; - - if (completionHandler == nil) { return; } - return completionHandler(success); + [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^() { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.videoStarted = NO; + return completionHandler(); }]; } @@ -179,13 +178,12 @@ - (void)destroyVideoProtocol { /// Stops the audio feature of the manager on the secondary transport. /// @param completionHandler Called when audio has stopped. -- (void)sdl_stopAudioWithCompletionHandler:(nullable void(^)(BOOL success))completionHandler { +- (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^(BOOL success) { - weakSelf.audioStarted = NO; - - if (completionHandler == nil) { return; } - return completionHandler(success); + [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.audioStarted = NO; + return completionHandler(); }]; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index 5737ef825..e8ee9b66f 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -28,9 +28,6 @@ @protocol SDLFocusableItemLocatorType; @protocol SDLStreamingMediaManagerDataSource; -/// Called when an end video service ACK or NAK has been received. -/// @param success True if the end service ACKed; False if NAKed. -typedef void (^SDLVideoServiceEndedCompletionHandler)(BOOL success); NS_ASSUME_NONNULL_BEGIN @@ -163,7 +160,7 @@ NS_ASSUME_NONNULL_BEGIN /// 2. We need to send an end video service control frame to the module to ensure that the video session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end video service request. /// 3. Since the primary transport is still open, the video scale manager should not be reset because the default video dimensions are retrieved from the `RegisterAppInterfaceResponse`. Due to a bug with the video start service ACK sometimes returning a screen resolution of {0, 0} on subsequent request to start a video service, we need to keep the screen resolution from the very first start video service ACK. (This is not an issue if the head unit supports the `VideoStreamingCapability`). /// @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. -- (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)videoEndedCompletionHandler; +- (void)endVideoServiceWithCompletionHandler:(void (^)(void))videoEndedCompletionHandler; /// This method is used internally to destroy the protocol after the secondary transport is shut down. - (void)destroyProtocol; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index efffba38e..725e6d6a2 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -93,8 +93,7 @@ @interface SDLStreamingVideoLifecycleManager() @property (assign, nonatomic) CMTime lastPresentationTimestamp; @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; - -@property (nonatomic, copy, nullable) SDLVideoServiceEndedCompletionHandler videoEndedCompletionHandler; +@property (nonatomic, copy, nullable) void (^videoServiceEndedCompletionHandler)(void); @end @@ -209,9 +208,9 @@ - (void)stop { [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } -- (void)endVideoServiceWithCompletionHandler:(nullable SDLVideoServiceEndedCompletionHandler)completionHandler { +- (void)endVideoServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending video service"); - self.videoEndedCompletionHandler = completionHandler; + self.videoServiceEndedCompletionHandler = completionHandler; [self.protocol endServiceWithType:SDLServiceTypeVideo]; } @@ -567,9 +566,9 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { if (endServiceACK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogD(@"Request to end video service ACKed"); - if (self.videoEndedCompletionHandler != nil) { - self.videoEndedCompletionHandler(YES); - self.videoEndedCompletionHandler = nil; + if (self.videoServiceEndedCompletionHandler != nil) { + self.videoServiceEndedCompletionHandler(); + self.videoServiceEndedCompletionHandler = nil; } [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; @@ -579,9 +578,9 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } SDLLogE(@"Request to end video service NAKed"); - if (self.videoEndedCompletionHandler != nil) { - self.videoEndedCompletionHandler(NO); - self.videoEndedCompletionHandler = nil; + if (self.videoServiceEndedCompletionHandler != nil) { + self.videoServiceEndedCompletionHandler(); + self.videoServiceEndedCompletionHandler = nil; } [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index cf6b519e3..fc13de62a 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -454,20 +454,17 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve describe(@"when audio is stopped", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); __block BOOL handlerCalled = nil; - __block BOOL audioServiceEnded = nil; beforeEach(^{ handlerCalled = NO; - audioServiceEnded = NO; [streamingLifecycleManager startWithProtocol:protocolMock]; }); context(@"if stopping audio on secondary transport", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; - [streamingLifecycleManager endAudioServiceWithCompletionHandler:^(BOOL success) { + [streamingLifecycleManager endAudioServiceWithCompletionHandler:^ { handlerCalled = YES; - audioServiceEnded = success; }]; }); @@ -496,7 +493,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should call the handler with a success result", ^{ expect(handlerCalled).to(beTrue()); - expect(audioServiceEnded).to(beTrue()); }); }); @@ -517,7 +513,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should call the handler with an unsuccessful result", ^{ expect(handlerCalled).to(beTrue()); - expect(audioServiceEnded).to(beFalse()); }); }); }); diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index ede58e04c..d11f18012 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -848,19 +848,16 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream describe(@"when video is stopped", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); __block BOOL handlerCalled = nil; - __block BOOL videoServiceEnded = nil; beforeEach(^{ handlerCalled = NO; - videoServiceEnded = NO; [streamingLifecycleManager startWithProtocol:protocolMock]; }); context(@"if stopping video on secondary transport", ^{ beforeEach(^{ - [streamingLifecycleManager endVideoServiceWithCompletionHandler:^(BOOL success) { + [streamingLifecycleManager endVideoServiceWithCompletionHandler:^ { handlerCalled = YES; - videoServiceEnded = success; }]; }); @@ -885,7 +882,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream it(@"should call the handler with a success result", ^{ expect(handlerCalled).to(beTrue()); - expect(videoServiceEnded).to(beTrue()); }); }); @@ -906,7 +902,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream it(@"should call the handler with an unsuccessful result", ^{ expect(handlerCalled).to(beTrue()); - expect(videoServiceEnded).to(beFalse()); }); }); }); From a7e811b0e96bc87f7ec4faf7d00170c7c3f494d9 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 5 Mar 2020 10:25:38 -0500 Subject: [PATCH 077/152] Added more logs to module map --- SmartDeviceLink/SDLLogFileModuleMap.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index f290c28a3..00a9ec38a 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -64,7 +64,7 @@ + (SDLLogFileModule *)sdl_proxyModule { } + (SDLLogFileModule *)sdl_protocolModule { - return [SDLLogFileModule moduleWithName:@"Protocol" files:[NSSet setWithArray:@[@"SDLProtocol", @"SDLProtocolMessageAssembler", @"SDLProtocolMessageDisassembler", @"SDLProtocolReceivedMessageRouter", @"SDLV1ProtocolMessage", @"SDLV2ProtocolMessage", @"SDLV1ProtocolHeader", @"SDLV2ProtocolHeader"]]]; + return [SDLLogFileModule moduleWithName:@"Protocol" files:[NSSet setWithArray:@[@"SDLProtocol", @"SDLProtocolMessageAssembler", @"SDLProtocolMessageDisassembler", @"SDLProtocolReceivedMessageRouter", @"SDLV1ProtocolMessage", @"SDLV2ProtocolMessage", @"SDLV1ProtocolHeader", @"SDLV2ProtocolHeader", @"SDLGlobals"]]]; } + (SDLLogFileModule *)sdl_rpcModule { @@ -102,7 +102,7 @@ + (SDLLogFileModule *)sdl_streamingMediaManagerModule { } + (SDLLogFileModule *)sdl_videoStreamingMediaManagerModule { - return [SDLLogFileModule moduleWithName:@"Video Streaming" files:[NSSet setWithArray:@[@"SDLStreamingVideoLifecycleManager", @"SDLTouchManager", @"SDLCarWindow"]]]; + return [SDLLogFileModule moduleWithName:@"Video Streaming" files:[NSSet setWithArray:@[@"SDLStreamingVideoLifecycleManager", @"SDLTouchManager", @"SDLCarWindow", @"SDLFocusableItemLocator"]]]; } + (SDLLogFileModule *)sdl_videoStreamingMediaTranscoderModule { From ceae12ea28d305e481a58e4c713f4343c671f7fe Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 09:23:21 -0500 Subject: [PATCH 078/152] Display link now stopped before end service sent --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 725e6d6a2..90387a483 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -210,6 +210,7 @@ - (void)stop { - (void)endVideoServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending video service"); + [self disposeDisplayLink]; self.videoServiceEndedCompletionHandler = completionHandler; [self.protocol endServiceWithType:SDLServiceTypeVideo]; } @@ -344,10 +345,9 @@ - (void)didEnterStateAppActive { } - (void)disposeDisplayLink { - if (self.displayLink != nil) { - [self.displayLink invalidate]; - self.displayLink = nil; - } + if (self.displayLink == nil) { return; } + [self.displayLink invalidate]; + self.displayLink = nil; } - (void)didEnterStateVideoStreamStopped { From 32dd840666516edb92510b4b0e29548269bee030 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 10:56:41 -0500 Subject: [PATCH 079/152] Fixed audio test cases --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 13 +------------ SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 7 ++----- .../SDLStreamingAudioLifecycleManagerSpec.m | 7 ++++--- 3 files changed, 7 insertions(+), 20 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 70eeccbca..89bf15833 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -61,17 +61,6 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -/** -Create a new streaming media manager for navigation and VPM apps with a specified configuration. Used for testing. - -@param connectionManager The pass-through for RPCs -@param streamingConfiguration The configuration of this streaming media session -@param encryptionConfiguration The encryption configuration with security managers -@param audioManager The audio manager. -@return A new streaming manager -*/ -- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration audioManager:(nullable SDLAudioStreamManager *)audioManager NS_DESIGNATED_INITIALIZER; - /** Create a new streaming media manager for navigation and VPM apps with a specified configuration @@ -80,7 +69,7 @@ Create a new streaming media manager for navigation and VPM apps with a specifie @param encryptionConfiguration The encryption configuration with security managers @return A new streaming manager */ -- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration; +- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration NS_DESIGNATED_INITIALIZER; /** * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 8420aeb36..dbd3c9cb8 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -34,6 +34,7 @@ @interface SDLStreamingAudioLifecycleManager() +@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioManager; @property (strong, nonatomic, readwrite) SDLStateMachine *audioStreamStateMachine; @property (assign, nonatomic, readonly, getter=isHmiStateAudioStreamCapable) BOOL hmiStateAudioStreamCapable; @@ -50,17 +51,13 @@ @interface SDLStreamingAudioLifecycleManager() @implementation SDLStreamingAudioLifecycleManager - (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration { - return [self initWithConnectionManager:connectionManager streamingConfiguration:streamingConfiguration encryptionConfiguration:encryptionConfiguration audioManager:nil]; -} - -- (instancetype)initWithConnectionManager:(id)connectionManager streamingConfiguration:(SDLStreamingMediaConfiguration *)streamingConfiguration encryptionConfiguration:(SDLEncryptionConfiguration *)encryptionConfiguration audioManager:(nullable SDLAudioStreamManager *)audioManager { self = [super init]; if (!self) { return nil; } _connectionManager = connectionManager; - _audioManager = audioManager != nil ? audioManager : [[SDLAudioStreamManager alloc] initWithManager:self]; + _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; NSMutableArray *tempMakeArray = [NSMutableArray array]; diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index fc13de62a..8104ce81d 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -25,6 +25,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (weak, nonatomic) SDLProtocol *protocol; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; +@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioManager; @end QuickSpecBegin(SDLStreamingAudioLifecycleManagerSpec) @@ -46,10 +47,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }; beforeEach(^{ - mockAudioStreamManager = OCMClassMock([SDLAudioStreamManager class]); - testConnectionManager = [[TestConnectionManager alloc] init]; - streamingLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:testConnectionManager streamingConfiguration:testConfiguration encryptionConfiguration:encryptionConfiguration audioManager:mockAudioStreamManager]; + streamingLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:testConnectionManager streamingConfiguration:testConfiguration encryptionConfiguration:encryptionConfiguration]; + mockAudioStreamManager = OCMClassMock([SDLAudioStreamManager class]); + streamingLifecycleManager.audioManager = mockAudioStreamManager; }); it(@"should initialize properties", ^{ From bad3301e506ebe780c42f5d94182b9db2e375f84 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 13:25:10 -0500 Subject: [PATCH 080/152] Fixed warning --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 4caa006f5..91653a0f9 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -248,7 +248,7 @@ - (void)didEnterStateStarted { [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { // We reuse our queue to run secondary transport manager's state machine - self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:self.streamManager serialQueue:self.lifecycleQueue]; + self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; self.streamManager.secondaryTransportDelegate = self; } From f8ff3dcc41ccc293f6141b42f4548969038b3c43 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 15:42:02 -0500 Subject: [PATCH 081/152] removed dealloc --- SmartDeviceLink/SDLStreamingMediaManager.m | 75 +++++++++++----------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index db2f3f9d3..a927c26cc 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -48,11 +48,6 @@ - (instancetype)initWithConnectionManager:(id)connecti return self; } -- (void)dealloc { - [_audioLifecycleManager stop]; - [_videoLifecycleManager stop]; -} - - (void)stop { [self stopAudio]; [self stopVideo]; @@ -90,6 +85,42 @@ - (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol { [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; } +#pragma mark Video + +/// Stops the video feature of the manager on the secondary transport. +/// @param completionHandler Called when video has stopped. +- (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { + __weak typeof(self) weakSelf = self; + [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^() { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.videoStarted = NO; + return completionHandler(); + }]; +} + +- (void)destroyVideoProtocol { + [self.videoLifecycleManager destroyProtocol]; +} + +#pragma mark Audio + +/// Stops the audio feature of the manager on the secondary transport. +/// @param completionHandler Called when audio has stopped. +- (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { + __weak typeof(self) weakSelf = self; + [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.audioStarted = NO; + return completionHandler(); + }]; +} + +- (void)destroyAudioProtocol { + [self.audioLifecycleManager destroyProtocol]; +} + +# pragma mark SDLStreamingProtocolDelegate + - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { BOOL videoProtocolUpdated = oldVideoProtocol != newVideoProtocol; @@ -157,40 +188,6 @@ - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol fo } } -#pragma mark Video - -/// Stops the video feature of the manager on the secondary transport. -/// @param completionHandler Called when video has stopped. -- (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { - __weak typeof(self) weakSelf = self; - [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^() { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.videoStarted = NO; - return completionHandler(); - }]; -} - -- (void)destroyVideoProtocol { - [self.videoLifecycleManager destroyProtocol]; -} - -#pragma mark Audio - -/// Stops the audio feature of the manager on the secondary transport. -/// @param completionHandler Called when audio has stopped. -- (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { - __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.audioStarted = NO; - return completionHandler(); - }]; -} - -- (void)destroyAudioProtocol { - [self.audioLifecycleManager destroyProtocol]; -} - #pragma mark - Getters - (SDLTouchManager *)touchManager { From 7a1c0f566959de501792b23e3c6f0fb546077c18 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 15:42:19 -0500 Subject: [PATCH 082/152] Added streaming media manager tests --- SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 2 + .../SDLStreamingAudioLifecycleManager.m | 4 +- .../SDLStreamingMediaManagerSpec.m | 304 ++++++++++++++++++ 3 files changed, 308 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 80cdf1dba..ec2b56392 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1395,6 +1395,7 @@ 888DBAF022D528DE002A0AE2 /* SDLCloseApplicationResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 888DBAEE22D528DE002A0AE2 /* SDLCloseApplicationResponse.m */; }; 888F86FE221DEE200052FE4C /* SDLAsynchronousRPCOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FD221DEE1F0052FE4C /* SDLAsynchronousRPCOperation.m */; }; 888F8700221DF4880052FE4C /* SDLAsynchronousRPCOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 888F86FF221DF4880052FE4C /* SDLAsynchronousRPCOperationSpec.m */; }; + 88A118272412ACAD00B45FB5 /* SDLStreamingMediaManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA661E2B1E553E7E001C1345 /* SDLStreamingMediaManagerSpec.m */; }; 88A1CF1E21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A1CF1D21669AC7001ACC75 /* SDLLifecycleConfigurationUpdateSpec.m */; }; 88A4A0FA22242AB400C6F01D /* SDLNavigationServiceDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A4A0F922242AB400C6F01D /* SDLNavigationServiceDataSpec.m */; }; 88A5E7F4220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 88A5E7F3220B57F900495E8A /* SDLOnSystemCapabilityUpdatedSpec.m */; }; @@ -8104,6 +8105,7 @@ 162E83371A9BDE8B00906325 /* SDLResetGlobalPropertiesSpec.m in Sources */, 162E82DF1A9BDE8B00906325 /* SDLGlobalProperySpec.m in Sources */, 88DF998F22035D1700477AC1 /* SDLIAPSessionSpec.m in Sources */, + 88A118272412ACAD00B45FB5 /* SDLStreamingMediaManagerSpec.m in Sources */, 5DD8406520FCE21A0082CE04 /* SDLElectronicParkBrakeStatusSpec.m in Sources */, 162E82F61A9BDE8B00906325 /* SDLRequestTypeSpec.m in Sources */, 5DE35E4520CAFC5D0034BE5A /* SDLChoiceCellSpec.m in Sources */, diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index dbd3c9cb8..6c0ff2543 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -100,7 +100,7 @@ - (void)stop { _protocol = nil; _hmiLevel = SDLHMILevelNone; _connectedVehicleMake = nil; - [_audioManager stop]; + [self.audioManager stop]; [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } @@ -109,7 +109,7 @@ - (void)endAudioServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending audio service"); self.audioServiceEndedCompletionHandler = completionHandler; - [_audioManager stop]; + [self.audioManager stop]; [self.protocol endServiceWithType:SDLServiceTypeAudio]; } diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 404fa1f05..cf82556f5 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -4,13 +4,317 @@ // #import #import +#import +#import "SDLConfiguration.h" +#import "SDLProtocol.h" +#import "SDLStreamingAudioLifecycleManager.h" #import "SDLStreamingMediaManager.h" +#import "SDLStreamingProtocolDelegate.h" +#import "SDLStreamingVideoLifecycleManager.h" +#import "TestConnectionManager.h" + +@interface SDLStreamingMediaManager() + +@property (strong, nonatomic) SDLStreamingAudioLifecycleManager *audioLifecycleManager; +@property (strong, nonatomic) SDLStreamingVideoLifecycleManager *videoLifecycleManager; +@property (assign, nonatomic) BOOL audioStarted; +@property (assign, nonatomic) BOOL videoStarted; + +- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; + +@end QuickSpecBegin(SDLStreamingMediaManagerSpec) describe(@"the streaming media manager", ^{ + __block SDLStreamingMediaManager *testStreamingMediaManager = nil; + __block TestConnectionManager *testConnectionManager = nil; + __block SDLConfiguration *testConfiguration = nil; + __block id mockVideoLifecycleManager = nil; + __block id mockAudioLifecycleManager = nil; + __block id mockSecondaryTransportDelegate = nil; + + beforeEach(^{ + testConnectionManager = [[TestConnectionManager alloc] init]; + testStreamingMediaManager = [[SDLStreamingMediaManager alloc] initWithConnectionManager:testConnectionManager configuration:testConfiguration]; + mockVideoLifecycleManager = OCMClassMock([SDLStreamingVideoLifecycleManager class]); + mockAudioLifecycleManager = OCMClassMock([SDLStreamingAudioLifecycleManager class]); + mockSecondaryTransportDelegate = OCMProtocolMock(@protocol(SDLSecondaryTransportDelegate)); + testStreamingMediaManager.audioLifecycleManager = mockAudioLifecycleManager; + testStreamingMediaManager.videoLifecycleManager = mockVideoLifecycleManager; + testStreamingMediaManager.secondaryTransportDelegate = mockSecondaryTransportDelegate; + }); + + context(@"when stop is called", ^{ + it(@"should stop both the audio and video stream managers", ^{ + [testStreamingMediaManager stop]; + OCMVerify([mockAudioLifecycleManager stop]); + OCMVerify([mockVideoLifecycleManager stop]); + expect(testStreamingMediaManager.audioStarted).to(beFalse()); + expect(testStreamingMediaManager.videoStarted).to(beFalse()); + }); + }); + + fcontext(@"when stop video is called", ^{ + beforeEach(^{ + testStreamingMediaManager.audioStarted = YES; + testStreamingMediaManager.videoStarted = YES; + }); + + it(@"should stop the video stream manager", ^{ + [testStreamingMediaManager stopVideo]; + OCMVerify([mockVideoLifecycleManager stop]); + expect(testStreamingMediaManager.videoStarted).to(beFalse()); + + OCMReject([mockAudioLifecycleManager stop]); + expect(testStreamingMediaManager.audioStarted).to(beTrue()); + }); + }); + + fcontext(@"when stop audio is called", ^{ + beforeEach(^{ + testStreamingMediaManager.audioStarted = YES; + testStreamingMediaManager.videoStarted = YES; + }); + + it(@"should stop the audio stream manager", ^{ + [testStreamingMediaManager stopAudio]; + OCMVerify([mockAudioLifecycleManager stop]); + expect(testStreamingMediaManager.audioStarted).to(beFalse()); + + OCMReject([mockVideoLifecycleManager stop]); + expect(testStreamingMediaManager.videoStarted).to(beTrue()); + }); + }); + + context(@"streaming media manager getters", ^{ + it(@"should return true if only video is streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if only audio is streaming", ^{ + testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if both video and audio are streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return false if neither video or audio is streaming", ^{ testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beFalse()); + }); + }); + + context(@"secondary transport", ^{ + __block SDLProtocol *mockProtocol = nil; + + beforeEach(^{ + mockProtocol = OCMClassMock([SDLProtocol class]); + }); + + describe(@"starting a service on a transport when none is running", ^{ + beforeEach(^{ + [testStreamingMediaManager startSecondaryTransportOnProtocol:mockProtocol]; + }); + + it(@"should start both the audio and video stream managers with the protocol", ^{ + OCMVerify([mockAudioLifecycleManager startWithProtocol:mockProtocol]); + OCMVerify([mockVideoLifecycleManager startWithProtocol:mockProtocol]); + expect(testStreamingMediaManager.audioStarted).to(beTrue()); + expect(testStreamingMediaManager.videoStarted).to(beTrue()); + }); + + it(@"should should not attempt to stop a current video or audio session", ^{ + OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); + OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); + }); + }); + + describe(@"stopping a running service on a transport", ^{ + beforeEach(^{ + OCMStub([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + OCMStub([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:[OCMArg any] toNewVideoProtocol:nil fromOldAudioProtocol:[OCMArg any] toNewAudioProtocol:nil]; + }); + + it(@"should stop both the audio and video stream managers", ^{ + OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); + OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); + expect(testStreamingMediaManager.audioStarted).to(beFalse()); + expect(testStreamingMediaManager.videoStarted).to(beFalse()); + }); + + it(@"should tell the audio and video stream managers to destroy the protocol", ^{ + OCMVerify([mockAudioLifecycleManager destroyProtocol]); + OCMVerify([mockVideoLifecycleManager destroyProtocol]); + }); + + it(@"should not attempt to start a new audio and video session", ^{ + OCMReject([mockAudioLifecycleManager startWithProtocol:[OCMArg any]]); + OCMReject([mockVideoLifecycleManager startWithProtocol:[OCMArg any]]); + }); + + it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ + OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); + }); + }); + + describe(@"switching a service to a different transport", ^{ + __block SDLProtocol *mockOldProtocol = nil; + __block SDLProtocol *mockNewProtocol = nil; + + beforeEach(^{ + mockOldProtocol = OCMClassMock([SDLProtocol class]); + mockNewProtocol = OCMClassMock([SDLProtocol class]); + + OCMStub([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + OCMStub([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; + }); + + it(@"should stop both the audio and video stream managers", ^{ + OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); + OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); + }); + + it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ + OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); + }); + + it(@"should tell the audio and video stream managers to destroy the protocol", ^{ + OCMVerify([mockAudioLifecycleManager destroyProtocol]); + OCMVerify([mockVideoLifecycleManager destroyProtocol]); + }); + + it(@"should try to start a new audio and video session with the new protocol", ^{ + OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); + OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); + + expect(testStreamingMediaManager.audioStarted).to(beTrue()); + expect(testStreamingMediaManager.videoStarted).to(beTrue()); + }); + }); + + describe(@"switching only the video service to a different transport", ^{ + __block SDLProtocol *mockOldProtocol = nil; + __block SDLProtocol *mockNewProtocol = nil; + + beforeEach(^{ + mockOldProtocol = OCMClassMock([SDLProtocol class]); + mockNewProtocol = OCMClassMock([SDLProtocol class]); + + OCMStub([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:nil toNewAudioProtocol:nil]; + }); + + it(@"should stop the video stream manager but not the audio stream manager", ^{ + OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); + OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); + }); + + it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ + OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); + }); + + it(@"should tell the video stream manager to destroy the protocol but not the audio stream manager", ^{ + OCMVerify([mockVideoLifecycleManager destroyProtocol]); + OCMReject([mockAudioLifecycleManager destroyProtocol]); + }); + + it(@"should try to start a new audio session with the new protocol, but not a video session ", ^{ + OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); + expect(testStreamingMediaManager.videoStarted).to(beTrue()); + + OCMReject([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); + expect(testStreamingMediaManager.audioStarted).to(beFalse()); + }); + }); + + describe(@"switching only the audio service to a different transport", ^{ + __block SDLProtocol *mockOldProtocol = nil; + __block SDLProtocol *mockNewProtocol = nil; + + beforeEach(^{ + mockOldProtocol = OCMClassMock([SDLProtocol class]); + mockNewProtocol = OCMClassMock([SDLProtocol class]); + + OCMStub([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { + void (^handler)(void); + [invocation getArgument:&handler atIndex:2]; + handler(); + }); + + [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; + }); + + it(@"should stop the audio stream manager but not the video stream manager", ^{ + OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); + OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); + }); + + it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ + OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); + }); + + it(@"should tell the audio stream manager to destroy the protocol but not the video stream manager", ^{ + OCMVerify([mockAudioLifecycleManager destroyProtocol]); + OCMReject([mockVideoLifecycleManager destroyProtocol]); + }); + + it(@"should try to start a new audio session with the new protocol, but not a video session ", ^{ + OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); + expect(testStreamingMediaManager.audioStarted).to(beTrue()); + OCMReject([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); + expect(testStreamingMediaManager.videoStarted).to(beFalse()); + }); + }); + }); }); QuickSpecEnd From a8e27812d096a9565f503c37532a1fb5ffc53a13 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 15:50:50 -0500 Subject: [PATCH 083/152] removed focus from tests --- SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index cf82556f5..9a828f430 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -56,7 +56,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - fcontext(@"when stop video is called", ^{ + context(@"when stop video is called", ^{ beforeEach(^{ testStreamingMediaManager.audioStarted = YES; testStreamingMediaManager.videoStarted = YES; @@ -72,7 +72,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - fcontext(@"when stop audio is called", ^{ + context(@"when stop audio is called", ^{ beforeEach(^{ testStreamingMediaManager.audioStarted = YES; testStreamingMediaManager.videoStarted = YES; From 619103b707f7d50c06d5f526fac7cef3625c2f60 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 6 Mar 2020 16:10:07 -0500 Subject: [PATCH 084/152] Renamed private methods --- SmartDeviceLink/SDLStreamingMediaManager.m | 12 ++++++------ SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m | 11 +++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index a927c26cc..7f0876c76 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -98,7 +98,7 @@ - (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { }]; } -- (void)destroyVideoProtocol { +- (void)sdl_destroyVideoProtocol { [self.videoLifecycleManager destroyProtocol]; } @@ -115,7 +115,7 @@ - (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { }]; } -- (void)destroyAudioProtocol { +- (void)sdl_destroyAudioProtocol { [self.audioLifecycleManager destroyProtocol]; } @@ -141,8 +141,8 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; } - [strongSelf destroyAudioProtocol]; - [strongSelf destroyVideoProtocol]; + [strongSelf sdl_destroyAudioProtocol]; + [strongSelf sdl_destroyVideoProtocol]; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; }]; @@ -154,7 +154,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; } - [strongSelf destroyVideoProtocol]; + [strongSelf sdl_destroyVideoProtocol]; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else if (oldAudioProtocol != nil) { @@ -165,7 +165,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto if (strongSelf.secondaryTransportDelegate != nil) { [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; } - [strongSelf destroyAudioProtocol]; + [strongSelf sdl_destroyAudioProtocol]; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else { diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 9a828f430..aa92eba6d 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -88,6 +88,17 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); + context(@"when setting the encryption flag for audio and video managers", ^{ + __block SDLStreamingEncryptionFlag testEncryptionFlag = SDLStreamingEncryptionFlagNone; + + it(@"should set the flag on both the audio and video managers", ^{ + [testStreamingMediaManager setRequestedEncryptionType:testEncryptionFlag]; + + OCMVerify([mockAudioLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); + OCMVerify([mockVideoLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); + }); + }); + context(@"streaming media manager getters", ^{ it(@"should return true if only video is streaming", ^{ testStreamingMediaManager.videoStarted = YES; From d5582b42fd1c0358b8e4c1aa6a4b805cb51409b2 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 08:50:38 -0400 Subject: [PATCH 085/152] Moved secondary trans. delegate to separate file --- SmartDeviceLink-iOS.podspec | 1 + SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 4 ++++ SmartDeviceLink.podspec | 3 ++- .../SDLSecondaryTransportDelegate.h | 20 +++++++++++++++++++ SmartDeviceLink/SDLStreamingMediaManager.h | 9 +-------- SmartDeviceLink/SmartDeviceLink.h | 3 +++ 6 files changed, 31 insertions(+), 9 deletions(-) create mode 100644 SmartDeviceLink/SDLSecondaryTransportDelegate.h diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec index 294917248..da401e318 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -326,6 +326,7 @@ ss.public_header_files = [ 'SmartDeviceLink/SDLSeatMemoryAction.h', 'SmartDeviceLink/SDLSeatMemoryActionType.h', 'SmartDeviceLink/SDLSupportedSeat.h', +'SmartDeviceLink/SDLSecondaryTransportDelegate.h', 'SmartDeviceLink/SDLSecurityType.h', 'SmartDeviceLink/SDLSendHapticData.h', 'SmartDeviceLink/SDLSendHapticDataResponse.h', diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index ec2b56392..5ea50d73b 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1284,6 +1284,7 @@ 880245A520F79C3400ED195B /* SDLFileManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */; }; 8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */; }; 8803DCF022C2B84B00FBB7CE /* SDLBackgroundTaskManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */; }; + 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; 880723EB23A2CFB4003D0489 /* SDLLockScreenRootViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 880723E923A2CFB4003D0489 /* SDLLockScreenRootViewController.h */; }; 880723EC23A2CFB4003D0489 /* SDLLockScreenRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 880723EA23A2CFB4003D0489 /* SDLLockScreenRootViewController.m */; }; 880D267A220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */; }; @@ -3034,6 +3035,7 @@ 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfiguration.m; sourceTree = ""; }; 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLBackgroundTaskManager.h; sourceTree = ""; }; 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLBackgroundTaskManager.m; sourceTree = ""; }; + 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLSecondaryTransportDelegate.h; sourceTree = ""; }; 880723E923A2CFB4003D0489 /* SDLLockScreenRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLockScreenRootViewController.h; sourceTree = ""; }; 880723EA23A2CFB4003D0489 /* SDLLockScreenRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLockScreenRootViewController.m; sourceTree = ""; }; 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherServiceDataSpec.m; sourceTree = ""; }; @@ -6516,6 +6518,7 @@ EE798CA520561217008EDE8E /* SDLSecondaryTransportManager.m */, EE38C0C1211C43E100E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.h */, EE38C0C2211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m */, + 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */, ); name = "Secondary Transport"; sourceTree = ""; @@ -7060,6 +7063,7 @@ 888DBAEF22D528DE002A0AE2 /* SDLCloseApplicationResponse.h in Headers */, DAC5726C1D11B4840004288B /* SDLTouchManagerDelegate.h in Headers */, 5D61FD3F1A84238C00846EE7 /* SDLPrioritizedObjectCollection.h in Headers */, + 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */, 5D9FC29E1FD8813900ACA5C2 /* SDLAudioStreamManager.h in Headers */, 5DD67CB01E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.h in Headers */, 5D61FCBF1A84238C00846EE7 /* SDLHexUtility.h in Headers */, diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec index 5aaf3d39e..fae6fd418 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -326,7 +326,7 @@ sdefault.public_header_files = [ 'SmartDeviceLink/SDLSeatLocationCapability.h', 'SmartDeviceLink/SDLSeatMemoryAction.h', 'SmartDeviceLink/SDLSeatMemoryActionType.h', -'SmartDeviceLink/SDLSupportedSeat.h', +'SmartDeviceLink/SDLSecondaryTransportDelegate.h', 'SmartDeviceLink/SDLSecurityType.h', 'SmartDeviceLink/SDLSendHapticData.h', 'SmartDeviceLink/SDLSendHapticDataResponse.h', @@ -378,6 +378,7 @@ sdefault.public_header_files = [ 'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h', 'SmartDeviceLink/SDLSubscribeWaypoints.h', 'SmartDeviceLink/SDLSubscribeWaypointsResponse.h', +'SmartDeviceLink/SDLSupportedSeat.h', 'SmartDeviceLink/SDLSyncMsgVersion.h', 'SmartDeviceLink/SDLMsgVersion.h', 'SmartDeviceLink/SDLSyncPData.h', diff --git a/SmartDeviceLink/SDLSecondaryTransportDelegate.h b/SmartDeviceLink/SDLSecondaryTransportDelegate.h new file mode 100644 index 000000000..e331cea22 --- /dev/null +++ b/SmartDeviceLink/SDLSecondaryTransportDelegate.h @@ -0,0 +1,20 @@ +// +// SDLSecondaryTransportDelegate.h +// SmartDeviceLink +// +// Created by Nicole on 3/9/20. +// Copyright © 2020 smartdevicelink. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol SDLSecondaryTransportDelegate + +/// Called when the secondary transport should be destroyed. +- (void)destroySecondaryTransport; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index be7a9d521..121ea7c24 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -9,6 +9,7 @@ #import #import +#import "SDLSecondaryTransportDelegate.h" #import "SDLStreamingAudioManagerType.h" #import "SDLStreamingMediaManagerConstants.h" @@ -23,14 +24,6 @@ NS_ASSUME_NONNULL_BEGIN -@protocol SDLSecondaryTransportDelegate - -- (void)destroySecondaryTransport; - -@end - -#pragma mark - Interface - /** * Manager to help control streaming video and audio media services. */ diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h index 542c2a208..3a1a0151d 100644 --- a/SmartDeviceLink/SmartDeviceLink.h +++ b/SmartDeviceLink/SmartDeviceLink.h @@ -417,6 +417,9 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLStreamingMediaManagerDataSource.h" #import "SDLStreamingVideoScaleManager.h" +// Streaming - Secondary Transport +#import "SDLSecondaryTransportDelegate.h" + // Files #import "SDLArtwork.h" #import "SDLFile.h" From 682b18cb1bbb80e63e0c6ece0df8b6b3aa45aef2 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 10:35:21 -0400 Subject: [PATCH 086/152] Fixed documentation --- SmartDeviceLink/SDLStreamingMediaManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 121ea7c24..e0176f054 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic) BOOL showVideoBackgroundDisplay; /** - * A delegate callback that notifies when the secondary transport state can change. + * A delegate callback that notifies when the secondary transport state should change. */ @property (weak, nonatomic, nullable) id secondaryTransportDelegate; From 1fe5dbd15e152e17ae87dd27349a873d2adc9bd6 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 10:35:34 -0400 Subject: [PATCH 087/152] Removed unneeded documentation --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 7f0876c76..112aca8e5 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -19,7 +19,6 @@ #import "SDLTouchManager.h" - NS_ASSUME_NONNULL_BEGIN @interface SDLStreamingMediaManager () @@ -259,7 +258,6 @@ - (SDLStreamingEncryptionFlag)requestedEncryptionType { } - (BOOL)showVideoBackgroundDisplay { - // both audio and video managers should have same type return self.videoLifecycleManager.showVideoBackgroundDisplay; } From f4599fca485e20b3bb5374503e08e7b5d29792d3 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 10:35:44 -0400 Subject: [PATCH 088/152] Added test cases --- .../SDLStreamingMediaManagerSpec.m | 200 +++++++++++++++--- 1 file changed, 167 insertions(+), 33 deletions(-) diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index aa92eba6d..8ca48d8b1 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -12,6 +12,7 @@ #import "SDLStreamingMediaManager.h" #import "SDLStreamingProtocolDelegate.h" #import "SDLStreamingVideoLifecycleManager.h" +#import "SDLStreamingVideoScaleManager.h" #import "TestConnectionManager.h" @interface SDLStreamingMediaManager() @@ -31,8 +32,8 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __block SDLStreamingMediaManager *testStreamingMediaManager = nil; __block TestConnectionManager *testConnectionManager = nil; __block SDLConfiguration *testConfiguration = nil; - __block id mockVideoLifecycleManager = nil; - __block id mockAudioLifecycleManager = nil; + __block SDLStreamingVideoLifecycleManager *mockVideoLifecycleManager = nil; + __block SDLStreamingAudioLifecycleManager *mockAudioLifecycleManager = nil; __block id mockSecondaryTransportDelegate = nil; beforeEach(^{ @@ -76,10 +77,11 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto beforeEach(^{ testStreamingMediaManager.audioStarted = YES; testStreamingMediaManager.videoStarted = YES; + + [testStreamingMediaManager stopAudio]; }); it(@"should stop the audio stream manager", ^{ - [testStreamingMediaManager stopAudio]; OCMVerify([mockAudioLifecycleManager stop]); expect(testStreamingMediaManager.audioStarted).to(beFalse()); @@ -88,51 +90,183 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"when setting the encryption flag for audio and video managers", ^{ - __block SDLStreamingEncryptionFlag testEncryptionFlag = SDLStreamingEncryptionFlagNone; + context(@"when sending audio data", ^{ + __block NSData *testAudioData = nil; - it(@"should set the flag on both the audio and video managers", ^{ - [testStreamingMediaManager setRequestedEncryptionType:testEncryptionFlag]; + beforeEach(^{ + testAudioData = [[NSData alloc] initWithBase64EncodedString:@"test data" options:kNilOptions]; + [testStreamingMediaManager sendAudioData:testAudioData]; + }); - OCMVerify([mockAudioLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); - OCMVerify([mockVideoLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); + it(@"should pass the audio data to the audio streaming manager", ^{ + OCMVerify([mockAudioLifecycleManager sendAudioData:testAudioData]); }); }); - context(@"streaming media manager getters", ^{ - it(@"should return true if only video is streaming", ^{ - testStreamingMediaManager.videoStarted = YES; - testStreamingMediaManager.audioStarted = NO; + context(@"when sending video data", ^{ + __block CVPixelBufferRef testPixelBuffer = nil; - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + beforeEach(^{ + CVPixelBufferCreate(kCFAllocatorDefault, 100, 50, kCVPixelFormatType_14Bayer_GRBG, nil, &testPixelBuffer); }); - it(@"should return true if only audio is streaming", ^{ - testStreamingMediaManager.videoStarted = NO; - testStreamingMediaManager.audioStarted = YES; + describe(@"without a timestamp", ^{ + beforeEach(^{ + [testStreamingMediaManager sendVideoData:testPixelBuffer]; + }); - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + it(@"should pass the video data to the video streaming manager", ^{ + OCMVerify([mockVideoLifecycleManager sendVideoData:testPixelBuffer]); + }); }); - it(@"should return true if both video and audio are streaming", ^{ - testStreamingMediaManager.videoStarted = YES; - testStreamingMediaManager.audioStarted = YES; + describe(@"with a timestamp", ^{ + __block CMTime testTimestamp = CMTimeMake(1, NSEC_PER_SEC); + + beforeEach(^{ + [testStreamingMediaManager sendVideoData:testPixelBuffer presentationTimestamp:testTimestamp]; + }); + + it(@"should pass the video data to the video streaming manager", ^{ + OCMVerify([mockVideoLifecycleManager sendVideoData:testPixelBuffer presentationTimestamp:testTimestamp]); + }); + }); + }); + + describe(@"getters", ^{ + it(@"should return the video lifecycle manager's touch manager for touchManager", ^{ + [testStreamingMediaManager touchManager]; + OCMVerify([mockVideoLifecycleManager touchManager]); + }); + + it(@"should return the audio lifecycle manager's audio manager for audioManager", ^{ + [testStreamingMediaManager audioManager]; + OCMVerify([mockAudioLifecycleManager audioManager]); + }); + + it(@"should return the video lifecycle manager's rootViewController for rootViewController", ^{ + [testStreamingMediaManager rootViewController]; + OCMVerify([mockVideoLifecycleManager rootViewController]); + }); - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + it(@"should return the video lifecycle manager's focusableItemManager for focusableItemManager", ^{ + [testStreamingMediaManager focusableItemManager]; + OCMVerify([mockVideoLifecycleManager focusableItemManager]); }); - it(@"should return false if neither video or audio is streaming", ^{ testStreamingMediaManager.videoStarted = NO; - testStreamingMediaManager.audioStarted = NO; + context(@"isStreamingSupported", ^{ + it(@"should return true if only video is streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if only audio is streaming", ^{ + testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if both video and audio are streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return false if neither video or audio is streaming", ^{ + testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beFalse()); + }); + }); + + it(@"should return the audio lifecycle manager's isAudioConnected for isAudioConnected", ^{ + [testStreamingMediaManager isAudioConnected]; + OCMVerify([mockAudioLifecycleManager isAudioConnected]); + }); + + it(@"should return the video lifecycle manager's isVideoConnected for isVideoConnected", ^{ + [testStreamingMediaManager isVideoConnected]; + OCMVerify([mockVideoLifecycleManager isVideoConnected]); + }); + + it(@"should return the audio lifecycle manager's isAudioEncrypted for isAudioEncrypted", ^{ + [testStreamingMediaManager isAudioEncrypted]; + OCMVerify([mockAudioLifecycleManager isAudioEncrypted]); + }); + + it(@"should return the video lifecycle manager's isVideoEncrypted for isVideoEncrypted", ^{ + [testStreamingMediaManager isVideoEncrypted]; + OCMVerify([mockVideoLifecycleManager isVideoEncrypted]); + }); + + it(@"should return the video lifecycle manager's isVideoStreamingPaused for isVideoStreamingPaused", ^{ + [testStreamingMediaManager isVideoStreamingPaused]; + OCMVerify([mockVideoLifecycleManager isVideoStreamingPaused]); + }); + + it(@"should return the video lifecycle manager's screenSize for screenSize", ^{ + [testStreamingMediaManager screenSize]; + OCMVerify([mockVideoLifecycleManager.videoScaleManager displayViewportResolution]); + }); + + it(@"should return the video lifecycle manager's videoFormat for videoFormat", ^{ + [testStreamingMediaManager videoFormat]; + OCMVerify([mockVideoLifecycleManager videoFormat]); + }); + + it(@"should return the video lifecycle manager's supportedFormats for supportedFormats", ^{ + [testStreamingMediaManager supportedFormats]; + OCMVerify([mockVideoLifecycleManager supportedFormats]); + }); + + it(@"should return the video lifecycle manager's pixelBufferPool for pixelBufferPool", ^{ + [testStreamingMediaManager pixelBufferPool]; + OCMVerify([mockVideoLifecycleManager pixelBufferPool]); + }); + + it(@"should return the video lifecycle manager's requestedEncryptionType for requestedEncryptionType", ^{ + [testStreamingMediaManager requestedEncryptionType]; + OCMVerify([mockVideoLifecycleManager requestedEncryptionType]); + }); + + it(@"should return the video lifecycle manager's showVideoBackgroundDisplay for showVideoBackgroundDisplay", ^{ + [testStreamingMediaManager showVideoBackgroundDisplay]; + OCMVerify([mockVideoLifecycleManager showVideoBackgroundDisplay]); + }); + }); + + describe(@"setters", ^{ + it(@"should set the encryption flag on both the audio and video managers", ^{ + SDLStreamingEncryptionFlag testEncryptionFlag = SDLStreamingEncryptionFlagNone; + [testStreamingMediaManager setRequestedEncryptionType:testEncryptionFlag]; + + OCMVerify([mockAudioLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); + OCMVerify([mockVideoLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); + }); + + it(@"should set the rootViewController on the video manager", ^{ + UIViewController *testViewController = [[UIViewController alloc] init]; + [testStreamingMediaManager setRootViewController:testViewController]; + + OCMVerify([mockVideoLifecycleManager setRootViewController:testViewController]); + }); - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); - expect(testStreamingMediaManager.isStreamingSupported).to(beFalse()); + it(@"should set showVideoBackgroundDisplay on the video manager", ^{ + [testStreamingMediaManager setShowVideoBackgroundDisplay:NO]; + OCMVerify([mockVideoLifecycleManager setShowVideoBackgroundDisplay:NO]); }); }); From 47478ee6dc5e2c5ee8907e6bbaceb2272aabbe74 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 12:04:02 -0400 Subject: [PATCH 089/152] Added secondary transport tests to lifecycle mgr --- .../DevAPISpecs/SDLLifecycleManagerSpec.m | 85 ++++++++++++++++--- 1 file changed, 73 insertions(+), 12 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index d987785b8..c8a0fac82 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -29,6 +29,8 @@ #import "SDLRegisterAppInterfaceResponse.h" #import "SDLResult.h" #import "SDLRPCNotificationNotification.h" +#import "SDLSecondaryTransportDelegate.h" +#import "SDLSecondaryTransportManager.h" #import "SDLShow.h" #import "SDLStateMachine.h" #import "SDLStreamingMediaConfiguration.h" @@ -698,26 +700,85 @@ @interface SDLLifecycleManager () }); }); }); -}); -describe(@"configuring the lifecycle manager", ^{ - __block SDLLifecycleConfiguration *lifecycleConfig = nil; - __block SDLLifecycleManager *testManager = nil; + describe(@"configuring the lifecycle manager", ^{ + __block SDLLifecycleConfiguration *lifecycleConfig = nil; + __block SDLLifecycleManager *testManager = nil; - beforeEach(^{ - lifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:@"Test app" fullAppId:@"Test ID"]; + beforeEach(^{ + lifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:@"Test app" fullAppId:@"Test ID"]; + }); + + context(@"if secondary transport is not allowed", ^{ + beforeEach(^{ + lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsNone; + SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil fileManager:nil]; + testManager = [[SDLLifecycleManager alloc] initWithConfiguration:config delegate:nil]; + [testManager.lifecycleStateMachine setToState:SDLLifecycleStateStarted fromOldState:nil callEnterTransition:YES]; + }); + + it(@"should not create a secondary transport manager", ^{ + expect(testManager.secondaryTransportManager).to(beNil()); + }); + }); + + context(@"if a secondary transport is allowed but app is NOT a navigation or projection app", ^{ + beforeEach(^{ + lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsTCP; + lifecycleConfig.appType = SDLAppHMITypeSocial; + SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil fileManager:nil]; + testManager = [[SDLLifecycleManager alloc] initWithConfiguration:config delegate:nil]; + [testManager.lifecycleStateMachine setToState:SDLLifecycleStateStarted fromOldState:nil callEnterTransition:YES]; + }); + + it(@"should not create a secondary transport manager", ^{ + expect(testManager.secondaryTransportManager).to(beNil()); + }); + }); + + context(@"if a secondary transport is allowed and app is a navigation or projection app", ^{ + beforeEach(^{ + lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsTCP; + lifecycleConfig.appType = SDLAppHMITypeProjection; + SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil streamingMedia:SDLStreamingMediaConfiguration.insecureConfiguration fileManager:nil]; + testManager = [[SDLLifecycleManager alloc] initWithConfiguration:config delegate:nil]; + + [testManager.lifecycleStateMachine setToState:SDLLifecycleStateStarted fromOldState:nil callEnterTransition:YES]; + }); + + it(@"should create a secondary transport manager", ^{ + expect(testManager.secondaryTransportManager).toNot(beNil()); + expect(testManager.streamManager.secondaryTransportDelegate).toNot(beNil()); + }); + }); }); - context(@"if no secondary transport is allowed", ^{ - beforeEach(^{ - lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsNone; + describe(@"shutting down the secondary transport", ^{ + __block SDLLifecycleConfiguration *lifecycleConfig = nil; + __block SDLLifecycleManager *testManager = nil; + __block SDLSecondaryTransportManager *mockSecondaryTransportManager = nil; + __block SDLStreamingMediaManager *mockStreamingMediaManager = nil; - SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil fileManager:nil]; + beforeEach(^{ + lifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:@"Test app" fullAppId:@"Test ID"]; + lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsTCP; + lifecycleConfig.appType = SDLAppHMITypeProjection; + SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil streamingMedia:SDLStreamingMediaConfiguration.insecureConfiguration fileManager:nil]; testManager = [[SDLLifecycleManager alloc] initWithConfiguration:config delegate:nil]; + + mockSecondaryTransportManager = OCMClassMock([SDLSecondaryTransportManager class]); + testManager.secondaryTransportManager = mockSecondaryTransportManager; + + mockStreamingMediaManager = OCMClassMock([SDLStreamingMediaManager class]); + testManager.streamManager = mockStreamingMediaManager; + + OCMStub([testManager.streamManager secondaryTransportDelegate]).andReturn(testManager); }); - it(@"should not create a secondary transport manager", ^{ - expect(testManager.secondaryTransportManager).to(beNil()); + it(@"it should shutdown the secondary transport when the delegate object is called", ^{ + [[testManager.streamManager secondaryTransportDelegate] destroySecondaryTransport]; + + OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); }); }); }); From 8314002dc98a2d11123da7f7a1d93d4f0bf33e15 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 13:14:10 -0400 Subject: [PATCH 090/152] Fixed documentation --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 91653a0f9..a7fc47bce 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -453,7 +453,7 @@ - (void)didEnterStateSettingUpManagers { [self.encryptionLifecycleManager startWithProtocol:self.proxy.protocol]; } - // If the secondary transport manager is used, the streaming media manager will be started through `onAudioServiceProtocolUpdated` and `onVideoServiceProtocolUpdated` + // If the secondary transport manager is used, the streaming media manager will be started through `streamingServiceProtocolDidUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` if (self.secondaryTransportManager == nil && self.streamManager != nil) { [self.streamManager startSecondaryTransportOnProtocol:self.proxy.protocol]; } From 160602d198750ab736921295134f56ce3c88a844 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 13:31:37 -0400 Subject: [PATCH 091/152] Fixed doc formatting --- .../SDLSecondaryTransportManager.h | 39 ++++++------------- 1 file changed, 11 insertions(+), 28 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 80ced3445..46f4ba336 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -39,45 +39,28 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; /// State of this manager @property (strong, nonatomic, readonly) SDLStateMachine *stateMachine; -/** - Create a new secondary transport manager. - - @param streamingProtocolDelegate a delegate to handle updates on protocol instances - @param queue a serial dispatch queue that the internal state machine runs on - @return A new secondary transport manager - */ +/// Create a new secondary transport manager. +/// @param streamingProtocolDelegate a delegate to handle updates on protocol instances +/// @param queue a serial dispatch queue that the internal state machine runs on - (instancetype)initWithStreamingProtocolDelegate:(id)streamingProtocolDelegate serialQueue:(dispatch_queue_t)queue; -/** - Start the manager. - - @param primaryProtocol protocol that runs on the main (primary) transport - */ +/// Start the manager. +/// @param primaryProtocol The protocol that runs on the main (primary) transport - (void)startWithPrimaryProtocol:(SDLProtocol *)primaryProtocol; -/** - Stop the manager. - */ +/// Stop the manager. - (void)stop; -/** - Destroys the secondary transport. - */ +/// Destroys the secondary transport. - (BOOL)disconnectSecondaryTransport; -/** - Call this method when Start Service ACK control frame is received on primary transport. - - @param payload payload of Start Service ACK frame received on the primary transport - */ +/// Call this method when Start Service ACK control frame is received on primary transport. +/// @param payload The payload of Start Service ACK frame received on the primary transport. - (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload; -/** - Call this method when Transport Event Update control frame is received on primary transport. - - @param payload payload of Transport Event Update frame received on the primary transport - */ +/// Call this method when Transport Event Update control frame is received on primary transport. +/// @param payload the payload of Transport Event Update frame received on the primary transport. - (void)onTransportEventUpdateReceived:(SDLControlFramePayloadTransportEventUpdate *)payload; @end From 834797c4e63be37ff4d2fc8a9ec0e24413d29ee1 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 13:37:57 -0400 Subject: [PATCH 092/152] Added more documentation --- SmartDeviceLink/SDLSecondaryTransportManager.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 63aeeb515..248252908 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -107,8 +107,10 @@ @interface SDLSecondaryTransportManager () // TCP port number of SDL Core. If the information isn't available then TCPPortUnspecified is stored. @property (assign, nonatomic) int tcpPort; +/// The current hmi level of the SDL app. @property (strong, nonatomic, nullable) SDLHMILevel currentHMILevel; +/// A background task used to close the secondary transport before the app is suspended. @property (copy, nonatomic) SDLBackgroundTaskManager *backgroundTaskManager; @end From 791273cae7565268d214204efaec336d0d311400 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 14:03:10 -0400 Subject: [PATCH 093/152] Undo removal of methods from public header --- SmartDeviceLink/SDLStreamingMediaManager.h | 28 +++++++++++++++------- SmartDeviceLink/SDLStreamingMediaManager.m | 15 ++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index e0176f054..50464bec5 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -24,9 +24,8 @@ NS_ASSUME_NONNULL_BEGIN -/** - * Manager to help control streaming video and audio media services. - */ + +/// Manager to help control streaming video and audio media services. @interface SDLStreamingMediaManager : NSObject /** @@ -87,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic, readonly) CGSize screenSize; /** - * This is the agreed upon format of video encoder that is in use, or nil if not currently connected. + This is the agreed upon format of video encoder that is in use, or nil if not currently connected. */ @property (strong, nonatomic, readonly, nullable) SDLVideoStreamingFormat *videoFormat; @@ -112,13 +111,11 @@ NS_ASSUME_NONNULL_BEGIN @property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType; /** - * When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES. + When YES, the StreamingMediaManager will send a black screen with "Video Backgrounded String". Defaults to YES. */ @property (assign, nonatomic) BOOL showVideoBackgroundDisplay; -/** - * A delegate callback that notifies when the secondary transport state should change. - */ +/// A delegate callback that notifies when the secondary transport state should change. @property (weak, nonatomic, nullable) id secondaryTransportDelegate; #pragma mark - Lifecycle @@ -190,6 +187,21 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; +/** + * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. + */ +- (void)startWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); + + /** + * Start the audio feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. + */ +- (void)startAudioWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); + + /** + * Start the video feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. + */ +- (void)startVideoWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); + @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 112aca8e5..e234f3b8d 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -187,6 +187,21 @@ - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol fo } } +- (void)startWithProtocol:(SDLProtocol *)protocol { + [self startAudioWithProtocol:protocol]; + [self startVideoWithProtocol:protocol]; +} + + - (void)startAudioWithProtocol:(SDLProtocol *)protocol { + [self.audioLifecycleManager startWithProtocol:protocol]; + self.audioStarted = YES; +} + + - (void)startVideoWithProtocol:(SDLProtocol *)protocol { + [self.videoLifecycleManager startWithProtocol:protocol]; + self.videoStarted = YES; +} + #pragma mark - Getters - (SDLTouchManager *)touchManager { From 7e413595726fdbae18b58b27c1264ea4303db8b4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 14:29:03 -0400 Subject: [PATCH 094/152] Fixed docs --- SmartDeviceLink/SDLStreamingMediaManager.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 50464bec5..f7d89976b 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -188,19 +188,19 @@ NS_ASSUME_NONNULL_BEGIN - (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; /** - * Start the manager with a completion block that will be called when startup completes. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. + * Start the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); +- (void)startWithProtocol:(SDLProtocol *)protocol; /** * Start the audio feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startAudioWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); +- (void)startAudioWithProtocol:(SDLProtocol *)protocol; /** * Start the video feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startVideoWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportOnProtocol: instead"); +- (void)startVideoWithProtocol:(SDLProtocol *)protocol; @end From e7be40af6b2f72f3768e2a0fd6393f83f32f89bd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 9 Mar 2020 14:36:42 -0400 Subject: [PATCH 095/152] Renamed method --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- SmartDeviceLink/SDLStreamingMediaManager.h | 6 +++--- SmartDeviceLink/SDLStreamingMediaManager.m | 2 +- SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m | 4 ++-- SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index a7fc47bce..4a41d3158 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -455,7 +455,7 @@ - (void)didEnterStateSettingUpManagers { // If the secondary transport manager is used, the streaming media manager will be started through `streamingServiceProtocolDidUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` if (self.secondaryTransportManager == nil && self.streamManager != nil) { - [self.streamManager startSecondaryTransportOnProtocol:self.proxy.protocol]; + [self.streamManager startSecondaryTransportWithProtocol:self.proxy.protocol]; } dispatch_group_enter(managerGroup); diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index f7d89976b..f0c71fd36 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -185,7 +185,7 @@ NS_ASSUME_NONNULL_BEGIN * Starts the video/audio services on the passed protocol. This method is used internally. * @param protocol The protocol to use for the audio/video services */ -- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol; +- (void)startSecondaryTransportWithProtocol:(SDLProtocol *)protocol; /** * Start the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. @@ -195,12 +195,12 @@ NS_ASSUME_NONNULL_BEGIN /** * Start the audio feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startAudioWithProtocol:(SDLProtocol *)protocol; +- (void)startAudioWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportWithProtocol: instead"); /** * Start the video feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startVideoWithProtocol:(SDLProtocol *)protocol; +- (void)startVideoWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportWithProtocol: instead"); @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index e234f3b8d..9cbc16d17 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -80,7 +80,7 @@ - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTim #pragma mark - Secondary Transport -- (void)startSecondaryTransportOnProtocol:(SDLProtocol *)protocol { +- (void)startSecondaryTransportWithProtocol:(SDLProtocol *)protocol { [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; } diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index c8a0fac82..ac250d659 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -293,7 +293,7 @@ @interface SDLLifecycleManager () OCMStub([fileManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), fileManagerStartError, nil])]); OCMStub([permissionManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), permissionManagerStartError, nil])]); if (testConfig.lifecycleConfig.tcpDebugMode) { - OCMStub([streamingManagerMock startSecondaryTransportOnProtocol:proxyMock]); + OCMStub([streamingManagerMock startSecondaryTransportWithProtocol:proxyMock]); } // Send an RAI response & make sure we have an HMI status to move the lifecycle forward @@ -308,7 +308,7 @@ @interface SDLLifecycleManager () OCMVerify([fileManagerMock startWithCompletionHandler:[OCMArg any]]); OCMVerify([permissionManagerMock startWithCompletionHandler:[OCMArg any]]); if (testManager.configuration.lifecycleConfig.tcpDebugMode) { - OCMStub([streamingManagerMock startSecondaryTransportOnProtocol:[OCMArg any]]); + OCMStub([streamingManagerMock startSecondaryTransportWithProtocol:[OCMArg any]]); } }); diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 8ca48d8b1..6c7187baf 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -279,7 +279,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto describe(@"starting a service on a transport when none is running", ^{ beforeEach(^{ - [testStreamingMediaManager startSecondaryTransportOnProtocol:mockProtocol]; + [testStreamingMediaManager startSecondaryTransportWithProtocol:mockProtocol]; }); it(@"should start both the audio and video stream managers with the protocol", ^{ From b282a6f8b1b253352524fc241a93c51688c6b4f7 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:57:18 -0400 Subject: [PATCH 096/152] Update SmartDeviceLink/SDLH264VideoEncoder.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLH264VideoEncoder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 29b15bde2..21a6eb6d7 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -183,7 +183,7 @@ - (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { - (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { // HAX: When the app is backgrounded, sometimes the compression session gets invalidated (this can happen the first time the app is backgrounded or the tenth). This causes the pool and/or the compression session to fail when the app is foregrounded and video frames are sent again. Attempt to fix this by recreating the compression session. - if (!_pixelBufferPool) { + if (_pixelBufferPool == NULL) { BOOL success = [self sdl_resetCompressionSession]; if (!success) { return NULL; From be041d6af65802208ddda70cc494d2a5a2ca051f Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:57:39 -0400 Subject: [PATCH 097/152] Update SmartDeviceLink/SDLH264VideoEncoder.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLH264VideoEncoder.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLH264VideoEncoder.m b/SmartDeviceLink/SDLH264VideoEncoder.m index 21a6eb6d7..7ce981f5e 100644 --- a/SmartDeviceLink/SDLH264VideoEncoder.m +++ b/SmartDeviceLink/SDLH264VideoEncoder.m @@ -345,7 +345,7 @@ - (BOOL)sdl_resetCompressionSession { } OSStatus status = VTCompressionSessionCreate(NULL, (int32_t)self.dimensions.width, (int32_t)self.dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); - return (status == noErr) ? YES : NO; + return (status == noErr); } @end From 3b939c0c3f98e624e7f11eab6004dffeb846079f Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:58:02 -0400 Subject: [PATCH 098/152] Update SmartDeviceLink/SDLLifecycleManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 4a41d3158..6d0859369 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -248,7 +248,7 @@ - (void)didEnterStateStarted { [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { // We reuse our queue to run secondary transport manager's state machine - self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; + self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; self.streamManager.secondaryTransportDelegate = self; } From 4de2746a90f965fd19ac9c1bec682f990c47be85 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:58:26 -0400 Subject: [PATCH 099/152] Update SmartDeviceLink/SDLLogFileModuleMap.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLLogFileModuleMap.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index 00a9ec38a..804242272 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -106,7 +106,7 @@ + (SDLLogFileModule *)sdl_videoStreamingMediaManagerModule { } + (SDLLogFileModule *)sdl_videoStreamingMediaTranscoderModule { - return [SDLLogFileModule moduleWithName:@"Video Streaming/Video Transcoding" files:[NSSet setWithArray:@[@"SDLH264VideoEncoder", @"SDLRAWH264Packetizer", @"SDLRTPH264Packetizer"]]]; + return [SDLLogFileModule moduleWithName:@"Video Streaming/Transcoding" files:[NSSet setWithArray:@[@"SDLH264VideoEncoder", @"SDLRAWH264Packetizer", @"SDLRTPH264Packetizer"]]]; } + (SDLLogFileModule *)sdl_audioStreamingMediaManagerModule { From c60f574de731439e2cadb8c044281ac29fec6269 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:58:45 -0400 Subject: [PATCH 100/152] Update SmartDeviceLink/SDLLogFileModuleMap.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLLogFileModuleMap.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index 804242272..1d8b7ce51 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -114,7 +114,7 @@ + (SDLLogFileModule *)sdl_audioStreamingMediaManagerModule { } + (SDLLogFileModule *)sdl_audioStreamingMediaTranscoderModule { - return [SDLLogFileModule moduleWithName:@"Audio Streaming/Audio Transcoding" files:[NSSet setWithArray:@[@"SDLAudioStreamManager", @"SDLPCMAudioConverter"]]]; + return [SDLLogFileModule moduleWithName:@"Audio Streaming/Transcoding" files:[NSSet setWithArray:@[@"SDLAudioStreamManager", @"SDLPCMAudioConverter"]]]; } + (SDLLogFileModule *)sdl_screenManagerModule { From 7982163415b5fbe7787b49025cfca043204a6d5f Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:59:09 -0400 Subject: [PATCH 101/152] Update SmartDeviceLink/SDLSecondaryTransportManager.h Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLSecondaryTransportManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 46f4ba336..9c56e950c 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -55,7 +55,7 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; /// Destroys the secondary transport. - (BOOL)disconnectSecondaryTransport; -/// Call this method when Start Service ACK control frame is received on primary transport. +/// Call this method when a Start Service ACK control frame is received on primary transport. /// @param payload The payload of Start Service ACK frame received on the primary transport. - (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload; From bc011ba4c0fb3becb69a5ea8774a51793706a2b8 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 14:59:45 -0400 Subject: [PATCH 102/152] Update SmartDeviceLink/SDLStreamingMediaManager.h Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index f0c71fd36..b59cd5aee 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN -/// Manager to help control streaming video and audio media services. +/// Manager to help control streaming (video and audio) media services. @interface SDLStreamingMediaManager : NSObject /** From dd498542604c1b8c5419e2e763bda650a8af032f Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:00:38 -0400 Subject: [PATCH 103/152] Update SmartDeviceLink/SDLStreamingAudioLifecycleManager.h Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 89bf15833..46523602c 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -80,7 +80,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)stop; /// This method is used internally to stop the manager when audio needs to be stopped on the secondary transport. The primary transport is still open. -/// 1. Since the primary transport is still open, do will not reset the `hmiLevel` since we can still get notifications from the module with the updated hmi status on the primary transport. +/// 1. Since the primary transport is still open, we will not reset the `hmiLevel` since we can still get notifications from the module with the updated HMI status on the primary transport. /// 2. We need to send an end audio service control frame to the module to ensure that the audio session is shut down correctly. In order to do this the protocol must be kept open and only destroyed after the module ACKs or NAKs our end audio service request. /// @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. - (void)endAudioServiceWithCompletionHandler:(void (^)(void))audioEndedCompletionHandler; From 7b14aff68971455ab2339829f7af0b7418f41e31 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:01:25 -0400 Subject: [PATCH 104/152] Update SmartDeviceLink/SDLSecondaryTransportManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLSecondaryTransportManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 248252908..dc0f85a15 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -137,7 +137,7 @@ - (instancetype)initWithStreamingProtocolDelegate:(id Date: Tue, 10 Mar 2020 15:02:56 -0400 Subject: [PATCH 105/152] Update SmartDeviceLink/SDLStreamingMediaManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.m | 1 - 1 file changed, 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 9cbc16d17..feb4a63f4 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -121,7 +121,6 @@ - (void)sdl_destroyAudioProtocol { # pragma mark SDLStreamingProtocolDelegate - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { - BOOL videoProtocolUpdated = oldVideoProtocol != newVideoProtocol; BOOL audioProtocolUpdated = oldAudioProtocol != newAudioProtocol; From dd7f118df08ba3037140047f19700f81dab300ac Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:03:46 -0400 Subject: [PATCH 106/152] Update SmartDeviceLink/SDLStreamingMediaManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index feb4a63f4..80e1ef5c3 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -121,7 +121,7 @@ - (void)sdl_destroyAudioProtocol { # pragma mark SDLStreamingProtocolDelegate - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { - BOOL videoProtocolUpdated = oldVideoProtocol != newVideoProtocol; + BOOL videoProtocolUpdated = (oldVideoProtocol != newVideoProtocol); BOOL audioProtocolUpdated = oldAudioProtocol != newAudioProtocol; if (!videoProtocolUpdated && !audioProtocolUpdated) { From c0a9112114a4609231ea18e8ca9ee709fed7c278 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:04:34 -0400 Subject: [PATCH 107/152] Update SmartDeviceLink/SDLStreamingMediaManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 80e1ef5c3..dffc48abe 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -122,7 +122,7 @@ - (void)sdl_destroyAudioProtocol { - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { BOOL videoProtocolUpdated = (oldVideoProtocol != newVideoProtocol); - BOOL audioProtocolUpdated = oldAudioProtocol != newAudioProtocol; + BOOL audioProtocolUpdated = (oldAudioProtocol != newAudioProtocol); if (!videoProtocolUpdated && !audioProtocolUpdated) { SDLLogV(@"The video and audio protocols did not update. Nothing will update."); From 26f2251b29e7fb1ad6baaa13d864e3a283d4e177 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:06:26 -0400 Subject: [PATCH 108/152] Update SmartDeviceLink/SDLStreamingMediaManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index dffc48abe..9aca362a8 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -275,6 +275,7 @@ - (BOOL)showVideoBackgroundDisplay { return self.videoLifecycleManager.showVideoBackgroundDisplay; } + #pragma mark - Setters - (void)setRootViewController:(nullable UIViewController *)rootViewController { From db393f797705b948a1a8ace917a7142919c26433 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:07:33 -0400 Subject: [PATCH 109/152] Update SmartDeviceLink/SDLStreamingMediaManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingMediaManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 9aca362a8..cf0dcc325 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -201,6 +201,7 @@ - (void)startVideoWithProtocol:(SDLProtocol *)protocol { self.videoStarted = YES; } + #pragma mark - Getters - (SDLTouchManager *)touchManager { From 4781c9d2ee53833ecc0358cec866b27f76dd4e5a Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:08:51 -0400 Subject: [PATCH 110/152] Update SmartDeviceLink/SDLStreamingVideoLifecycleManager.m Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 90387a483..e225deab4 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -346,6 +346,7 @@ - (void)didEnterStateAppActive { - (void)disposeDisplayLink { if (self.displayLink == nil) { return; } + SDLLogD(@"Destroying display link"); [self.displayLink invalidate]; self.displayLink = nil; } From a93921bd474f2ce87f2084a1680c297b4d7d64fd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:26:44 -0400 Subject: [PATCH 111/152] Apply suggestions from code review Review comments Co-Authored-By: Joel Fischer --- .../SDLStreamingAudioLifecycleManagerSpec.m | 16 +++++++-------- .../SDLStreamingVideoLifecycleManagerSpec.m | 16 +++++++-------- .../SDLStreamingMediaManagerSpec.m | 20 +++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 8104ce81d..ae14292cb 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -414,8 +414,8 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - describe(@"when the manager is stopped", ^{ - context(@"if audio not stopped", ^{ + describe(@"attempting to stop the manager", ^{ + context(@"when the manager is READY", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; [streamingLifecycleManager stop]; @@ -433,7 +433,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - context(@"if audio is already stopped", ^{ + context(@"when the manager is STOPPED", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateStopped fromOldState:nil callEnterTransition:NO]; [streamingLifecycleManager stop]; @@ -452,7 +452,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - describe(@"when audio is stopped", ^{ + describe(@"starting the manager when it's STOPPED", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); __block BOOL handlerCalled = nil; @@ -461,7 +461,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve [streamingLifecycleManager startWithProtocol:protocolMock]; }); - context(@"if stopping audio on secondary transport", ^{ + context(@"when stopping the audio service due to a secondary transport shutdown", ^{ beforeEach(^{ [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; [streamingLifecycleManager endAudioServiceWithCompletionHandler:^ { @@ -477,7 +477,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve OCMVerify([protocolMock endServiceWithType:SDLServiceTypeAudio]); }); - context(@"If the end audio service ACKs", ^{ + context(@"when the end audio service ACKs", ^{ __block SDLProtocolHeader *testAudioHeader = nil; __block SDLProtocolMessage *testAudioMessage = nil; @@ -497,7 +497,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - context(@"If the end audio service NAKs", ^{ + context(@"when the end audio service NAKs", ^{ __block SDLProtocolHeader *testAudioHeader = nil; __block SDLProtocolMessage *testAudioMessage = nil; @@ -519,7 +519,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); - describe(@"when the protocol is destroyed", ^{ + describe(@"destroying the protocol", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); beforeEach(^{ diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index d11f18012..8805de191 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -799,12 +799,12 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - describe(@"when the manager is stopped", ^{ + describe(@"stopping the manager", ^{ beforeEach(^{ streamingLifecycleManager.connectedVehicleMake = @"OEM_make"; }); - context(@"if video is not stopped", ^{ + context(@"when the manager is not stopped", ^{ beforeEach(^{ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamManagerStateReady fromOldState:nil callEnterTransition:NO]; [streamingLifecycleManager stop]; @@ -824,7 +824,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - context(@"if video is already stopped", ^{ + context(@"when the manager is already stopped", ^{ beforeEach(^{ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLAudioStreamManagerStateStopped fromOldState:nil callEnterTransition:NO]; [streamingLifecycleManager stop]; @@ -845,7 +845,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - describe(@"when video is stopped", ^{ + describe(@"starting the manager", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); __block BOOL handlerCalled = nil; @@ -854,7 +854,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [streamingLifecycleManager startWithProtocol:protocolMock]; }); - context(@"if stopping video on secondary transport", ^{ + describe(@"then ending the video service through the secondary transport", ^{ beforeEach(^{ [streamingLifecycleManager endVideoServiceWithCompletionHandler:^ { handlerCalled = YES; @@ -865,7 +865,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream OCMVerify([protocolMock endServiceWithType:SDLServiceTypeVideo]); }); - context(@"If the end video service ACKs", ^{ + context(@"when the end video service ACKs", ^{ __block SDLProtocolHeader *testVideoHeader = nil; __block SDLProtocolMessage *testVideoMessage = nil; @@ -885,7 +885,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - context(@"If the end audio service NAKs", ^{ + context(@"when the end audio service NAKs", ^{ __block SDLProtocolHeader *testVideoHeader = nil; __block SDLProtocolMessage *testVideoMessage = nil; @@ -907,7 +907,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - describe(@"when the protocol is destroyed", ^{ + describe(@"destroying the protocol", ^{ __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); beforeEach(^{ diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 6c7187baf..67c7f3d60 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -57,13 +57,13 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"when stop video is called", ^{ + describe(@"when stop video is called", ^{ beforeEach(^{ testStreamingMediaManager.audioStarted = YES; testStreamingMediaManager.videoStarted = YES; }); - it(@"should stop the video stream manager", ^{ + it(@"should only stop the video stream manager", ^{ [testStreamingMediaManager stopVideo]; OCMVerify([mockVideoLifecycleManager stop]); expect(testStreamingMediaManager.videoStarted).to(beFalse()); @@ -73,7 +73,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"when stop audio is called", ^{ + describe(@"when stop audio is called", ^{ beforeEach(^{ testStreamingMediaManager.audioStarted = YES; testStreamingMediaManager.videoStarted = YES; @@ -81,7 +81,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto [testStreamingMediaManager stopAudio]; }); - it(@"should stop the audio stream manager", ^{ + it(@"should only stop the audio stream manager", ^{ OCMVerify([mockAudioLifecycleManager stop]); expect(testStreamingMediaManager.audioStarted).to(beFalse()); @@ -90,7 +90,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"when sending audio data", ^{ + describe(@"when sending audio data", ^{ __block NSData *testAudioData = nil; beforeEach(^{ @@ -103,14 +103,14 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"when sending video data", ^{ + describe(@"when sending video data", ^{ __block CVPixelBufferRef testPixelBuffer = nil; beforeEach(^{ CVPixelBufferCreate(kCFAllocatorDefault, 100, 50, kCVPixelFormatType_14Bayer_GRBG, nil, &testPixelBuffer); }); - describe(@"without a timestamp", ^{ + context(@"without a timestamp", ^{ beforeEach(^{ [testStreamingMediaManager sendVideoData:testPixelBuffer]; }); @@ -120,7 +120,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - describe(@"with a timestamp", ^{ + context(@"with a timestamp", ^{ __block CMTime testTimestamp = CMTimeMake(1, NSEC_PER_SEC); beforeEach(^{ @@ -154,7 +154,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto OCMVerify([mockVideoLifecycleManager focusableItemManager]); }); - context(@"isStreamingSupported", ^{ + describe(@"when calling isStreamingSupported", ^{ it(@"should return true if only video is streaming", ^{ testStreamingMediaManager.videoStarted = YES; testStreamingMediaManager.audioStarted = NO; @@ -270,7 +270,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto }); }); - context(@"secondary transport", ^{ + describe(@"when using the secondary transport", ^{ __block SDLProtocol *mockProtocol = nil; beforeEach(^{ From c4a0fd26ecf1864dc67ac6929c2c35c9dc14bb14 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:37:33 -0400 Subject: [PATCH 112/152] Combined test cases --- .../SDLStreamingMediaManagerSpec.m | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 67c7f3d60..320b426db 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -287,9 +287,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto OCMVerify([mockVideoLifecycleManager startWithProtocol:mockProtocol]); expect(testStreamingMediaManager.audioStarted).to(beTrue()); expect(testStreamingMediaManager.videoStarted).to(beTrue()); - }); - it(@"should should not attempt to stop a current video or audio session", ^{ OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); }); @@ -317,19 +315,13 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); expect(testStreamingMediaManager.audioStarted).to(beFalse()); expect(testStreamingMediaManager.videoStarted).to(beFalse()); - }); - it(@"should tell the audio and video stream managers to destroy the protocol", ^{ OCMVerify([mockAudioLifecycleManager destroyProtocol]); OCMVerify([mockVideoLifecycleManager destroyProtocol]); - }); - it(@"should not attempt to start a new audio and video session", ^{ OCMReject([mockAudioLifecycleManager startWithProtocol:[OCMArg any]]); OCMReject([mockVideoLifecycleManager startWithProtocol:[OCMArg any]]); - }); - it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); }); }); @@ -357,21 +349,15 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; }); - it(@"should stop both the audio and video stream managers", ^{ + it(@"should stop both the audio and video stream managers and call the delegate then start a new session", ^{ OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); - }); - it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - }); - it(@"should tell the audio and video stream managers to destroy the protocol", ^{ OCMVerify([mockAudioLifecycleManager destroyProtocol]); OCMVerify([mockVideoLifecycleManager destroyProtocol]); - }); - it(@"should try to start a new audio and video session with the new protocol", ^{ OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); @@ -400,18 +386,12 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto it(@"should stop the video stream manager but not the audio stream manager", ^{ OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); - }); - it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - }); - it(@"should tell the video stream manager to destroy the protocol but not the audio stream manager", ^{ OCMVerify([mockVideoLifecycleManager destroyProtocol]); OCMReject([mockAudioLifecycleManager destroyProtocol]); - }); - it(@"should try to start a new audio session with the new protocol, but not a video session ", ^{ OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.videoStarted).to(beTrue()); @@ -440,18 +420,12 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto it(@"should stop the audio stream manager but not the video stream manager", ^{ OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); - }); - it(@"should notify the delegate object that the secondary transport can be destroyed", ^{ OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - }); - it(@"should tell the audio stream manager to destroy the protocol but not the video stream manager", ^{ OCMVerify([mockAudioLifecycleManager destroyProtocol]); OCMReject([mockVideoLifecycleManager destroyProtocol]); - }); - it(@"should try to start a new audio session with the new protocol, but not a video session ", ^{ OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.audioStarted).to(beTrue()); From 7fe7d15fc2135c59d1329fee6f649d569423412c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:43:31 -0400 Subject: [PATCH 113/152] combining test cases --- .../DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 8805de191..77b21824b 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -801,7 +801,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream describe(@"stopping the manager", ^{ beforeEach(^{ - streamingLifecycleManager.connectedVehicleMake = @"OEM_make"; + streamingLifecycleManager.connectedVehicleMake = @"OEM_make_2"; }); context(@"when the manager is not stopped", ^{ @@ -812,9 +812,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream it(@"should transition to the stopped state", ^{ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped)); - }); - - it(@"should reset the saved properties", ^{ expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); @@ -832,9 +829,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream it(@"should stay in the stopped state", ^{ expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamManagerStateStopped)); - }); - - it(@"should reset the saved properties", ^{ expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); From 09bd41a8de51da72b64acb50caeeabed3273a86c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:52:07 -0400 Subject: [PATCH 114/152] Fixed test description --- .../SDLStreamingAudioLifecycleManagerSpec.m | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index ae14292cb..4c27826c3 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -35,7 +35,7 @@ @interface SDLStreamingAudioLifecycleManager() __block SDLStreamingMediaConfiguration *testConfiguration = [SDLStreamingMediaConfiguration insecureConfiguration]; __block SDLEncryptionConfiguration *encryptionConfiguration = [SDLEncryptionConfiguration defaultConfiguration]; __block TestConnectionManager *testConnectionManager = nil; - __block id mockAudioStreamManager = nil; + __block SDLAudioStreamManager *mockAudioStreamManager = nil; __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILevel hmiLevel) { SDLOnHMIStatus *hmiStatus = [[SDLOnHMIStatus alloc] init]; @@ -421,15 +421,14 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve [streamingLifecycleManager stop]; }); - it(@"should transition to the stopped state", ^{ + it(@"should transition to the stopped state and reset the saved properties", ^{ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); - }); - it(@"should reset the saved properties", ^{ expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); OCMVerify([mockAudioStreamManager stop]); + }); }); @@ -439,11 +438,9 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve [streamingLifecycleManager stop]; }); - it(@"should stay in the stopped state", ^{ + it(@"should stay in the stopped state and reset the saved properties", ^{ expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamManagerStateStopped)); - }); - it(@"should reset the saved properties", ^{ expect(streamingLifecycleManager.protocol).to(beNil()); expect(streamingLifecycleManager.hmiLevel).to(equal(SDLHMILevelNone)); expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); @@ -469,12 +466,10 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }]; }); - it(@"should reset the audio stream manger", ^{ + it(@"should reset the audio stream manger and send an end audio service control frame", ^{ OCMVerify([mockAudioStreamManager stop]); - }); - - it(@"should send an end audio service control frame", ^{ OCMVerify([protocolMock endServiceWithType:SDLServiceTypeAudio]); + }); context(@"when the end audio service ACKs", ^{ @@ -492,7 +487,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve [streamingLifecycleManager handleProtocolEndServiceACKMessage:testAudioMessage]; }); - it(@"should call the handler with a success result", ^{ + it(@"should call the handler", ^{ expect(handlerCalled).to(beTrue()); }); }); @@ -512,7 +507,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testAudioMessage]; }); - it(@"should call the handler with an unsuccessful result", ^{ + it(@"should call the handler", ^{ expect(handlerCalled).to(beTrue()); }); }); From 7d692d3bb3dc991b1199cecc8a5b2b6f86f43922 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:55:10 -0400 Subject: [PATCH 115/152] Fixed test cases --- .../SDLStreamingVideoLifecycleManagerSpec.m | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 77b21824b..e5bd4c5f6 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -39,8 +39,8 @@ #import "SDLVehicleType.h" #import "SDLVideoStreamingCapability.h" #import "SDLVideoStreamingState.h" -#import "TestConnectionManager.h" #import "SDLVersion.h" +#import "TestConnectionManager.h" @interface SDLStreamingVideoLifecycleManager () @@ -177,11 +177,8 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [NSThread sleepForTimeInterval:0.1]; }); - it(@"should not support streaming", ^{ + it(@"should not support streaming or save the vehicle make", ^{ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO)); - }); - - it(@"should not save the vehicle make", ^{ expect(streamingLifecycleManager.connectedVehicleMake).to(beNil()); }); }); @@ -213,12 +210,9 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [NSThread sleepForTimeInterval:0.1]; }); - it(@"should support streaming", ^{ + it(@"should support streaming and save the vehicle make", ^{ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@YES)); expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeMake(600, 100)))).to(equal(@YES)); - }); - - it(@"should save the vehicle make", ^{ expect(streamingLifecycleManager.connectedVehicleMake).to(equal(testVehicleType.make)); }); }); @@ -246,12 +240,9 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [NSThread sleepForTimeInterval:0.1]; }); - it(@"should support streaming even though hmiCapabilities.videoStreaming is nil", ^{ + it(@"should support streaming even though hmiCapabilities.videoStreaming is nil and it should save the vehicle make", ^{ expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@YES)); expect(@(CGSizeEqualToSize(streamingLifecycleManager.videoScaleManager.displayViewportResolution, CGSizeMake(600, 100)))).to(equal(@YES)); - }); - - it(@"should save the vehicle make", ^{ expect(streamingLifecycleManager.connectedVehicleMake).to(equal(testVehicleType.make)); }); }); From c36db6210c2fd94d67017a79cc6afb8045c0cecf Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 15:56:26 -0400 Subject: [PATCH 116/152] Fixed test description --- .../DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index e5bd4c5f6..006be9494 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -865,7 +865,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [streamingLifecycleManager handleProtocolEndServiceACKMessage:testVideoMessage]; }); - it(@"should call the handler with a success result", ^{ + it(@"should call the handler", ^{ expect(handlerCalled).to(beTrue()); }); }); @@ -885,7 +885,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream [streamingLifecycleManager handleProtocolEndServiceNAKMessage:testVideoMessage]; }); - it(@"should call the handler with an unsuccessful result", ^{ + it(@"should call the handler", ^{ expect(handlerCalled).to(beTrue()); }); }); From 87e9c618fad6c0f6ad3d58c386e76eaa28b51cd9 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 16:03:42 -0400 Subject: [PATCH 117/152] renamed method and added logs --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 3 ++- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 6c0ff2543..be5d23171 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -226,7 +226,8 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeAudio) { return; } - SDLLogE(@"Request to end audio service NAKed"); + SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; + SDLLogE(@"Request to end audio service NAKed with playlod: %@", nakPayload); if (self.audioServiceEndedCompletionHandler != nil) { self.audioServiceEndedCompletionHandler(); self.audioServiceEndedCompletionHandler = nil; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index e225deab4..33ec12341 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -210,7 +210,7 @@ - (void)stop { - (void)endVideoServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending video service"); - [self disposeDisplayLink]; + [self sdl_disposeDisplayLink]; self.videoServiceEndedCompletionHandler = completionHandler; [self.protocol endServiceWithType:SDLServiceTypeVideo]; } @@ -344,7 +344,7 @@ - (void)didEnterStateAppActive { }; } -- (void)disposeDisplayLink { +- (void)sdl_disposeDisplayLink { if (self.displayLink == nil) { return; } SDLLogD(@"Destroying display link"); [self.displayLink invalidate]; @@ -366,7 +366,7 @@ - (void)didEnterStateVideoStreamStopped { _preferredResolutionIndex = 0; _lastPresentationTimestamp = kCMTimeInvalid; - [self disposeDisplayLink]; + [self sdl_disposeDisplayLink]; [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStopNotification object:nil]; } @@ -434,7 +434,7 @@ - (void)didEnterStateVideoStreamReady { self.videoEncoder = nil; } - [self disposeDisplayLink]; + [self sdl_disposeDisplayLink]; if (self.videoEncoder == nil) { NSError* error = nil; @@ -489,7 +489,7 @@ - (void)didEnterStateVideoStreamReady { - (void)didEnterStateVideoStreamSuspended { SDLLogD(@"Video stream suspended"); - [self disposeDisplayLink]; + [self sdl_disposeDisplayLink]; [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamSuspendedNotification object:nil]; } @@ -578,7 +578,8 @@ - (void)handleProtocolEndServiceACKMessage:(SDLProtocolMessage *)endServiceACK { - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { if (endServiceNAK.header.serviceType != SDLServiceTypeVideo) { return; } - SDLLogE(@"Request to end video service NAKed"); + SDLControlFramePayloadNak *nakPayload = [[SDLControlFramePayloadNak alloc] initWithData:endServiceNAK.payload]; + SDLLogE(@"Request to end video service NAKed with payload: %@", nakPayload); if (self.videoServiceEndedCompletionHandler != nil) { self.videoServiceEndedCompletionHandler(); self.videoServiceEndedCompletionHandler = nil; From 9887ea58e7b26c13268c74fa768a0fc5d6bb681e Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 10 Mar 2020 16:05:12 -0400 Subject: [PATCH 118/152] Apply suggestions from code review Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 33ec12341..8b278ad2c 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -686,7 +686,7 @@ - (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)en - (void)sdl_startVideoSession { SDLLogV(@"Attempting to start video session"); if (self.protocol == nil) { - SDLLogV(@"No session established with head unit. Video start service request will not be sent."); + SDLLogV(@"No transport established with head unit. Video start service request will not be sent."); return; } From 6fd66a785f2fd3f1ff5fb6949f2bd12587fb79ed Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 11:57:09 -0400 Subject: [PATCH 119/152] Moved secondary transport logic to stream mgr --- SmartDeviceLink-iOS.podspec | 1 - SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 2 +- SmartDeviceLink.podspec | 1 - SmartDeviceLink/SDLLifecycleManager.m | 10 +-- .../SDLStreamingAudioLifecycleManager.h | 3 - .../SDLStreamingAudioLifecycleManager.m | 6 -- SmartDeviceLink/SDLStreamingMediaManager.h | 9 +-- SmartDeviceLink/SDLStreamingMediaManager.m | 51 ++++++++------ .../SDLStreamingVideoLifecycleManager.h | 3 - .../SDLStreamingVideoLifecycleManager.m | 6 -- SmartDeviceLink/SmartDeviceLink.h | 3 - .../DevAPISpecs/SDLLifecycleManagerSpec.m | 32 +-------- .../SDLStreamingAudioLifecycleManagerSpec.m | 15 ---- .../SDLStreamingVideoLifecycleManagerSpec.m | 15 ---- .../SDLStreamingMediaManagerSpec.m | 69 +++++++++++-------- 15 files changed, 78 insertions(+), 148 deletions(-) diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec index da401e318..294917248 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -326,7 +326,6 @@ ss.public_header_files = [ 'SmartDeviceLink/SDLSeatMemoryAction.h', 'SmartDeviceLink/SDLSeatMemoryActionType.h', 'SmartDeviceLink/SDLSupportedSeat.h', -'SmartDeviceLink/SDLSecondaryTransportDelegate.h', 'SmartDeviceLink/SDLSecurityType.h', 'SmartDeviceLink/SDLSendHapticData.h', 'SmartDeviceLink/SDLSendHapticDataResponse.h', diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 5ea50d73b..75c9fbf88 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1284,7 +1284,7 @@ 880245A520F79C3400ED195B /* SDLFileManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */; }; 8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */; }; 8803DCF022C2B84B00FBB7CE /* SDLBackgroundTaskManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */; }; - 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */; }; 880723EB23A2CFB4003D0489 /* SDLLockScreenRootViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 880723E923A2CFB4003D0489 /* SDLLockScreenRootViewController.h */; }; 880723EC23A2CFB4003D0489 /* SDLLockScreenRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 880723EA23A2CFB4003D0489 /* SDLLockScreenRootViewController.m */; }; 880D267A220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */; }; diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec index fae6fd418..315e1693d 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -326,7 +326,6 @@ sdefault.public_header_files = [ 'SmartDeviceLink/SDLSeatLocationCapability.h', 'SmartDeviceLink/SDLSeatMemoryAction.h', 'SmartDeviceLink/SDLSeatMemoryActionType.h', -'SmartDeviceLink/SDLSecondaryTransportDelegate.h', 'SmartDeviceLink/SDLSecurityType.h', 'SmartDeviceLink/SDLSendHapticData.h', 'SmartDeviceLink/SDLSendHapticDataResponse.h', diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 6d0859369..31638fd01 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -77,7 +77,7 @@ #pragma mark - SDLManager Private Interface -@interface SDLLifecycleManager () +@interface SDLLifecycleManager () // Readonly public properties @property (copy, nonatomic, readwrite) SDLConfiguration *configuration; @@ -249,7 +249,7 @@ - (void)didEnterStateStarted { [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { // We reuse our queue to run secondary transport manager's state machine self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; - self.streamManager.secondaryTransportDelegate = self; + self.streamManager.secondaryTransportManager = self.secondaryTransportManager; } self.proxy = [SDLProxy iapProxyWithListener:self.notificationDispatcher secondaryTransportManager:self.secondaryTransportManager encryptionLifecycleManager:self.encryptionLifecycleManager]; @@ -883,12 +883,6 @@ - (void)sdl_remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notifi } } -#pragma mark - SDLSecondaryTransportDelegate - -- (void)destroySecondaryTransport { - [self.secondaryTransportManager disconnectSecondaryTransport]; -} - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 46523602c..230264cfb 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -85,9 +85,6 @@ NS_ASSUME_NONNULL_BEGIN /// @param audioEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the audio service. - (void)endAudioServiceWithCompletionHandler:(void (^)(void))audioEndedCompletionHandler; -/// This method is used internally to destroy the protocol after the secondary transport is shut down. -- (void)destroyProtocol; - /** * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback * diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index be5d23171..76d95803c 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -113,12 +113,6 @@ - (void)endAudioServiceWithCompletionHandler:(void (^)(void))completionHandler { [self.protocol endServiceWithType:SDLServiceTypeAudio]; } -/// Used internally to destroy the protocol after the secondary transport is shut down. -- (void)destroyProtocol { - SDLLogD(@"Destroying protocol: %@", self.protocol); - self.protocol = nil; -} - - (BOOL)sendAudioData:(NSData*)audioData { if (!self.isAudioConnected) { return NO; diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index b59cd5aee..5e4613f90 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -9,19 +9,20 @@ #import #import -#import "SDLSecondaryTransportDelegate.h" #import "SDLStreamingAudioManagerType.h" #import "SDLStreamingMediaManagerConstants.h" @class SDLAudioStreamManager; @class SDLConfiguration; @class SDLProtocol; +@class SDLSecondaryTransportManager; @class SDLTouchManager; @class SDLVideoStreamingFormat; @protocol SDLFocusableItemLocatorType; @protocol SDLConnectionManagerType; + NS_ASSUME_NONNULL_BEGIN @@ -115,8 +116,8 @@ NS_ASSUME_NONNULL_BEGIN */ @property (assign, nonatomic) BOOL showVideoBackgroundDisplay; -/// A delegate callback that notifies when the secondary transport state should change. -@property (weak, nonatomic, nullable) id secondaryTransportDelegate; +/// The manager for handling streaming over a secondary transport +@property (strong, nonatomic, nullable) SDLSecondaryTransportManager *secondaryTransportManager; #pragma mark - Lifecycle @@ -190,7 +191,7 @@ NS_ASSUME_NONNULL_BEGIN /** * Start the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. */ -- (void)startWithProtocol:(SDLProtocol *)protocol; +- (void)startWithProtocol:(SDLProtocol *)protocol __deprecated_msg("Use startSecondaryTransportWithProtocol: instead"); /** * Start the audio feature of the manager. This is used internally. To use an SDLStreamingMediaManager, you should use the manager found on `SDLManager`. diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index cf0dcc325..8fbfd92fe 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -12,6 +12,7 @@ #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" #import "SDLLogMacros.h" +#import "SDLSecondaryTransportManager.h" #import "SDLStreamingAudioLifecycleManager.h" #import "SDLStreamingProtocolDelegate.h" #import "SDLStreamingVideoLifecycleManager.h" @@ -27,7 +28,8 @@ @interface SDLStreamingMediaManager () @property (strong, nonatomic) SDLStreamingVideoLifecycleManager *videoLifecycleManager; @property (assign, nonatomic) BOOL audioStarted; @property (assign, nonatomic) BOOL videoStarted; - +@property (strong, nonatomic, nullable) SDLProtocol *audioProtocol; +@property (strong, nonatomic, nullable) SDLProtocol *videoProtocol; @end @@ -52,6 +54,7 @@ - (void)stop { [self stopVideo]; } + #pragma mark Audio - (void)stopAudio { @@ -84,6 +87,15 @@ - (void)startSecondaryTransportWithProtocol:(SDLProtocol *)protocol { [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; } +- (void)sdl_disconnectSecondaryTransport { + if (self.secondaryTransportManager == nil) { + SDLLogV(@"Attempting to disconnect a non-existent secondary transport. Returning."); + return; + } + + [self.secondaryTransportManager disconnectSecondaryTransport]; +} + #pragma mark Video /// Stops the video feature of the manager on the secondary transport. @@ -97,10 +109,6 @@ - (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { }]; } -- (void)sdl_destroyVideoProtocol { - [self.videoLifecycleManager destroyProtocol]; -} - #pragma mark Audio /// Stops the audio feature of the manager on the secondary transport. @@ -114,10 +122,6 @@ - (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { }]; } -- (void)sdl_destroyAudioProtocol { - [self.audioLifecycleManager destroyProtocol]; -} - # pragma mark SDLStreamingProtocolDelegate - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { @@ -136,11 +140,10 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __strong typeof(weakSelf) strongSelf = weakSelf; [strongSelf sdl_stopVideoWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; - if (strongSelf.secondaryTransportDelegate != nil) { - [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; - } - [strongSelf sdl_destroyAudioProtocol]; - [strongSelf sdl_destroyVideoProtocol]; + [strongSelf sdl_disconnectSecondaryTransport]; + SDLLogV(@"Destroying the video and audio protocols"); + self.videoProtocol = nil; + self.audioProtocol = nil; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; }]; @@ -149,10 +152,9 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __weak typeof(self) weakSelf = self; [self sdl_stopVideoWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; - if (strongSelf.secondaryTransportDelegate != nil) { - [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; - } - [strongSelf sdl_destroyVideoProtocol]; + [strongSelf sdl_disconnectSecondaryTransport]; + SDLLogV(@"Destroying the video protocol"); + self.videoProtocol = nil; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else if (oldAudioProtocol != nil) { @@ -160,10 +162,9 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __weak typeof(self) weakSelf = self; [self sdl_stopAudioWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; - if (strongSelf.secondaryTransportDelegate != nil) { - [strongSelf.secondaryTransportDelegate destroySecondaryTransport]; - } - [strongSelf sdl_destroyAudioProtocol]; + [strongSelf sdl_disconnectSecondaryTransport]; + SDLLogV(@"Destroying the audio protocol"); + self.audioProtocol = nil; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else { @@ -177,26 +178,32 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto /// @param newVideoProtocol The new video protocol - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol forVideo:(nullable SDLProtocol *)newVideoProtocol { if (newAudioProtocol != nil) { + self.audioProtocol = newAudioProtocol; [self.audioLifecycleManager startWithProtocol:newAudioProtocol]; self.audioStarted = YES; } if (newVideoProtocol != nil) { + self.videoProtocol = newVideoProtocol; [self.videoLifecycleManager startWithProtocol:newVideoProtocol]; self.videoStarted = YES; } } - (void)startWithProtocol:(SDLProtocol *)protocol { + self.audioProtocol = protocol; + self.videoProtocol = protocol; [self startAudioWithProtocol:protocol]; [self startVideoWithProtocol:protocol]; } - (void)startAudioWithProtocol:(SDLProtocol *)protocol { + self.audioProtocol = protocol; [self.audioLifecycleManager startWithProtocol:protocol]; self.audioStarted = YES; } - (void)startVideoWithProtocol:(SDLProtocol *)protocol { + self.videoProtocol = protocol; [self.videoLifecycleManager startWithProtocol:protocol]; self.videoStarted = YES; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index e8ee9b66f..68ba3db0d 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -162,9 +162,6 @@ NS_ASSUME_NONNULL_BEGIN /// @param videoEndedCompletionHandler Called when the module ACKs or NAKs to the request to end the video service. - (void)endVideoServiceWithCompletionHandler:(void (^)(void))videoEndedCompletionHandler; -/// This method is used internally to destroy the protocol after the secondary transport is shut down. -- (void)destroyProtocol; - /** * This method receives raw image data and will run iOS8+'s hardware video encoder to turn the data into a video stream, which will then be passed to the connected head unit. * diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 8b278ad2c..dddb9fa49 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -215,12 +215,6 @@ - (void)endVideoServiceWithCompletionHandler:(void (^)(void))completionHandler { [self.protocol endServiceWithType:SDLServiceTypeVideo]; } -/// Used internally to destroy the protocol after the secondary transport is shut down. -- (void)destroyProtocol { - SDLLogD(@"Destroying protocol: %@", self.protocol); - self.protocol = nil; -} - - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { return [self sendVideoData:imageBuffer presentationTimestamp:kCMTimeInvalid]; } diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h index 3a1a0151d..542c2a208 100644 --- a/SmartDeviceLink/SmartDeviceLink.h +++ b/SmartDeviceLink/SmartDeviceLink.h @@ -417,9 +417,6 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLStreamingMediaManagerDataSource.h" #import "SDLStreamingVideoScaleManager.h" -// Streaming - Secondary Transport -#import "SDLSecondaryTransportDelegate.h" - // Files #import "SDLArtwork.h" #import "SDLFile.h" diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index ac250d659..9e5bac3cb 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -29,7 +29,6 @@ #import "SDLRegisterAppInterfaceResponse.h" #import "SDLResult.h" #import "SDLRPCNotificationNotification.h" -#import "SDLSecondaryTransportDelegate.h" #import "SDLSecondaryTransportManager.h" #import "SDLShow.h" #import "SDLStateMachine.h" @@ -747,40 +746,11 @@ @interface SDLLifecycleManager () }); it(@"should create a secondary transport manager", ^{ + expect(testManager.streamManager).toNot(beNil()); expect(testManager.secondaryTransportManager).toNot(beNil()); - expect(testManager.streamManager.secondaryTransportDelegate).toNot(beNil()); }); }); }); - - describe(@"shutting down the secondary transport", ^{ - __block SDLLifecycleConfiguration *lifecycleConfig = nil; - __block SDLLifecycleManager *testManager = nil; - __block SDLSecondaryTransportManager *mockSecondaryTransportManager = nil; - __block SDLStreamingMediaManager *mockStreamingMediaManager = nil; - - beforeEach(^{ - lifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:@"Test app" fullAppId:@"Test ID"]; - lifecycleConfig.allowedSecondaryTransports = SDLSecondaryTransportsTCP; - lifecycleConfig.appType = SDLAppHMITypeProjection; - SDLConfiguration *config = [[SDLConfiguration alloc] initWithLifecycle:lifecycleConfig lockScreen:nil logging:nil streamingMedia:SDLStreamingMediaConfiguration.insecureConfiguration fileManager:nil]; - testManager = [[SDLLifecycleManager alloc] initWithConfiguration:config delegate:nil]; - - mockSecondaryTransportManager = OCMClassMock([SDLSecondaryTransportManager class]); - testManager.secondaryTransportManager = mockSecondaryTransportManager; - - mockStreamingMediaManager = OCMClassMock([SDLStreamingMediaManager class]); - testManager.streamManager = mockStreamingMediaManager; - - OCMStub([testManager.streamManager secondaryTransportDelegate]).andReturn(testManager); - }); - - it(@"it should shutdown the secondary transport when the delegate object is called", ^{ - [[testManager.streamManager secondaryTransportDelegate] destroySecondaryTransport]; - - OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); - }); - }); }); QuickSpecEnd diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 4c27826c3..24d6cd72a 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -513,21 +513,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); }); }); - - describe(@"destroying the protocol", ^{ - __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); - - beforeEach(^{ - [streamingLifecycleManager startWithProtocol:protocolMock]; - expect(streamingLifecycleManager.protocol).toNot(beNil()); - - [streamingLifecycleManager destroyProtocol]; - }); - - it(@"should destroy the protocol", ^{ - expect(streamingLifecycleManager.protocol).to(beNil()); - }); - }); }); QuickSpecEnd diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 006be9494..66caf8458 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -892,21 +892,6 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); }); - describe(@"destroying the protocol", ^{ - __block SDLProtocol *protocolMock = OCMClassMock([SDLProtocol class]); - - beforeEach(^{ - [streamingLifecycleManager startWithProtocol:protocolMock]; - expect(streamingLifecycleManager.protocol).toNot(beNil()); - - [streamingLifecycleManager destroyProtocol]; - }); - - it(@"should destroy the protocol", ^{ - expect(streamingLifecycleManager.protocol).to(beNil()); - }); - }); - describe(@"Creating a background video stream string", ^{ __block NSString *expectedVideoStreamBackgroundString = [NSString stringWithFormat:@"When it is safe to do so, open %@ on your phone", testAppName]; diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 320b426db..c6b0ce674 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -8,9 +8,9 @@ #import "SDLConfiguration.h" #import "SDLProtocol.h" +#import "SDLSecondaryTransportManager.h" #import "SDLStreamingAudioLifecycleManager.h" #import "SDLStreamingMediaManager.h" -#import "SDLStreamingProtocolDelegate.h" #import "SDLStreamingVideoLifecycleManager.h" #import "SDLStreamingVideoScaleManager.h" #import "TestConnectionManager.h" @@ -21,6 +21,8 @@ @interface SDLStreamingMediaManager() @property (strong, nonatomic) SDLStreamingVideoLifecycleManager *videoLifecycleManager; @property (assign, nonatomic) BOOL audioStarted; @property (assign, nonatomic) BOOL videoStarted; +@property (strong, nonatomic, nullable) SDLProtocol *audioProtocol; +@property (strong, nonatomic, nullable) SDLProtocol *videoProtocol; - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; @@ -32,19 +34,22 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __block SDLStreamingMediaManager *testStreamingMediaManager = nil; __block TestConnectionManager *testConnectionManager = nil; __block SDLConfiguration *testConfiguration = nil; + __block SDLSecondaryTransportManager *mockSecondaryTransportManager = nil; __block SDLStreamingVideoLifecycleManager *mockVideoLifecycleManager = nil; __block SDLStreamingAudioLifecycleManager *mockAudioLifecycleManager = nil; - __block id mockSecondaryTransportDelegate = nil; beforeEach(^{ testConnectionManager = [[TestConnectionManager alloc] init]; testStreamingMediaManager = [[SDLStreamingMediaManager alloc] initWithConnectionManager:testConnectionManager configuration:testConfiguration]; + mockVideoLifecycleManager = OCMClassMock([SDLStreamingVideoLifecycleManager class]); + testStreamingMediaManager.videoLifecycleManager = mockVideoLifecycleManager; + mockAudioLifecycleManager = OCMClassMock([SDLStreamingAudioLifecycleManager class]); - mockSecondaryTransportDelegate = OCMProtocolMock(@protocol(SDLSecondaryTransportDelegate)); testStreamingMediaManager.audioLifecycleManager = mockAudioLifecycleManager; - testStreamingMediaManager.videoLifecycleManager = mockVideoLifecycleManager; - testStreamingMediaManager.secondaryTransportDelegate = mockSecondaryTransportDelegate; + + mockSecondaryTransportManager = OCMClassMock([SDLSecondaryTransportManager class]); + testStreamingMediaManager.secondaryTransportManager = mockSecondaryTransportManager; }); context(@"when stop is called", ^{ @@ -285,6 +290,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto it(@"should start both the audio and video stream managers with the protocol", ^{ OCMVerify([mockAudioLifecycleManager startWithProtocol:mockProtocol]); OCMVerify([mockVideoLifecycleManager startWithProtocol:mockProtocol]); + expect(testStreamingMediaManager.audioStarted).to(beTrue()); expect(testStreamingMediaManager.videoStarted).to(beTrue()); @@ -316,23 +322,28 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto expect(testStreamingMediaManager.audioStarted).to(beFalse()); expect(testStreamingMediaManager.videoStarted).to(beFalse()); - OCMVerify([mockAudioLifecycleManager destroyProtocol]); - OCMVerify([mockVideoLifecycleManager destroyProtocol]); - OCMReject([mockAudioLifecycleManager startWithProtocol:[OCMArg any]]); OCMReject([mockVideoLifecycleManager startWithProtocol:[OCMArg any]]); - OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); + OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); + + expect(testStreamingMediaManager.audioProtocol).to(beNil()); + expect(testStreamingMediaManager.videoProtocol).to(beNil()); }); }); - describe(@"switching a service to a different transport", ^{ - __block SDLProtocol *mockOldProtocol = nil; - __block SDLProtocol *mockNewProtocol = nil; + describe(@"switching both the video and audio services to a different transport", ^{ + __block SDLProtocol *mockOldVideoProtocol = nil; + __block SDLProtocol *mockNewVideoProtocol = nil; + __block SDLProtocol *mockOldAudioProtocol = nil; + __block SDLProtocol *mockNewAudioProtocol = nil; beforeEach(^{ - mockOldProtocol = OCMClassMock([SDLProtocol class]); - mockNewProtocol = OCMClassMock([SDLProtocol class]); + mockOldVideoProtocol = OCMClassMock([SDLProtocol class]); + mockNewVideoProtocol = OCMClassMock([SDLProtocol class]); + mockOldAudioProtocol = OCMClassMock([SDLProtocol class]); + mockNewAudioProtocol = OCMClassMock([SDLProtocol class]); + OCMStub([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]).andDo(^(NSInvocation *invocation) { void (^handler)(void); @@ -346,23 +357,23 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto handler(); }); - [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; + [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldVideoProtocol toNewVideoProtocol:mockNewVideoProtocol fromOldAudioProtocol:mockOldAudioProtocol toNewAudioProtocol:mockNewAudioProtocol]; }); it(@"should stop both the audio and video stream managers and call the delegate then start a new session", ^{ OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); - OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - - OCMVerify([mockAudioLifecycleManager destroyProtocol]); - OCMVerify([mockVideoLifecycleManager destroyProtocol]); + OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); - OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); - OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); + OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewAudioProtocol]); + OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewVideoProtocol]); expect(testStreamingMediaManager.audioStarted).to(beTrue()); expect(testStreamingMediaManager.videoStarted).to(beTrue()); + + expect(testStreamingMediaManager.audioProtocol).to(equal(mockNewAudioProtocol)); + expect(testStreamingMediaManager.videoProtocol).to(equal(mockNewVideoProtocol)); }); }); @@ -387,16 +398,16 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto OCMVerify([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); - OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - - OCMVerify([mockVideoLifecycleManager destroyProtocol]); - OCMReject([mockAudioLifecycleManager destroyProtocol]); + OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); OCMVerify([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.videoStarted).to(beTrue()); OCMReject([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.audioStarted).to(beFalse()); + + expect(testStreamingMediaManager.audioProtocol).to(beNil()); + expect(testStreamingMediaManager.videoProtocol).to(equal(mockNewProtocol)); }); }); @@ -421,16 +432,16 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto OCMVerify([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); - OCMVerify([mockSecondaryTransportDelegate destroySecondaryTransport]); - - OCMVerify([mockAudioLifecycleManager destroyProtocol]); - OCMReject([mockVideoLifecycleManager destroyProtocol]); + OCMVerify([mockSecondaryTransportManager disconnectSecondaryTransport]); OCMVerify([mockAudioLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.audioStarted).to(beTrue()); OCMReject([mockVideoLifecycleManager startWithProtocol:mockNewProtocol]); expect(testStreamingMediaManager.videoStarted).to(beFalse()); + + expect(testStreamingMediaManager.audioProtocol).to(equal(mockNewProtocol)); + expect(testStreamingMediaManager.videoProtocol).to(beNil()); }); }); }); From 6f3a17567fb8c04f468b01d4935d7324e6d7c5fa Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 12:54:57 -0400 Subject: [PATCH 120/152] Refactored nested blocks to use dispatch group --- SmartDeviceLink/SDLStreamingMediaManager.m | 40 ++++++++++++++-------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 8fbfd92fe..aa702c767 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -11,6 +11,7 @@ #import "SDLAudioStreamManager.h" #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" +#import "SDLGlobals.h" #import "SDLLogMacros.h" #import "SDLSecondaryTransportManager.h" #import "SDLStreamingAudioLifecycleManager.h" @@ -30,6 +31,7 @@ @interface SDLStreamingMediaManager () @property (assign, nonatomic) BOOL videoStarted; @property (strong, nonatomic, nullable) SDLProtocol *audioProtocol; @property (strong, nonatomic, nullable) SDLProtocol *videoProtocol; + @end @@ -129,24 +131,31 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto BOOL audioProtocolUpdated = (oldAudioProtocol != newAudioProtocol); if (!videoProtocolUpdated && !audioProtocolUpdated) { - SDLLogV(@"The video and audio protocols did not update. Nothing will update."); + SDLLogV(@"The video and audio transports will not be updated since neither changed."); return; } if (oldVideoProtocol != nil && oldAudioProtocol != nil) { // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self sdl_stopAudioWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf sdl_stopVideoWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - [strongSelf sdl_disconnectSecondaryTransport]; - SDLLogV(@"Destroying the video and audio protocols"); - self.videoProtocol = nil; - self.audioProtocol = nil; - [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }]; - }]; + dispatch_group_t closeServicesTask = dispatch_group_create(); + dispatch_group_enter(closeServicesTask); + dispatch_group_enter(closeServicesTask); + [self sdl_stopAudioWithCompletionHandler:^{ + dispatch_group_leave(closeServicesTask); + }]; + dispatch_group_enter(closeServicesTask); + [self sdl_stopVideoWithCompletionHandler:^{ + dispatch_group_leave(closeServicesTask); + }]; + dispatch_group_leave(closeServicesTask); + + dispatch_group_notify(closeServicesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ + [self sdl_disconnectSecondaryTransport]; + SDLLogV(@"Destroying the video and audio protocols"); + self.videoProtocol = nil; + self.audioProtocol = nil; + [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }); } else if (oldVideoProtocol != nil) { // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. __weak typeof(self) weakSelf = self; @@ -154,7 +163,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __strong typeof(weakSelf) strongSelf = weakSelf; [strongSelf sdl_disconnectSecondaryTransport]; SDLLogV(@"Destroying the video protocol"); - self.videoProtocol = nil; + strongSelf.videoProtocol = nil; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else if (oldAudioProtocol != nil) { @@ -164,7 +173,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto __strong typeof(weakSelf) strongSelf = weakSelf; [strongSelf sdl_disconnectSecondaryTransport]; SDLLogV(@"Destroying the audio protocol"); - self.audioProtocol = nil; + strongSelf.audioProtocol = nil; [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; }]; } else { @@ -173,6 +182,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto } } + /// Starts the audio and/or video services using the new protocol. /// @param newAudioProtocol The new audio protocol /// @param newVideoProtocol The new video protocol From 215bd7efb11ce2300919a2961087766f7401b656 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 13:11:43 -0400 Subject: [PATCH 121/152] Refactored check for streaming app --- SmartDeviceLink/SDLLifecycleManager.m | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index 31638fd01..eaa75be48 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -144,10 +144,7 @@ - (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate _systemCapabilityManager = [[SDLSystemCapabilityManager alloc] initWithConnectionManager:self]; _screenManager = [[SDLScreenManager alloc] initWithConnectionManager:self fileManager:_fileManager systemCapabilityManager:_systemCapabilityManager]; - if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || - [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] || - [configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || - [configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { + if ([self.class isStreamingConfiguration:self.configuration]) { _streamManager = [[SDLStreamingMediaManager alloc] initWithConnectionManager:self configuration:configuration]; } else { SDLLogV(@"Skipping StreamingMediaManager setup due to app type"); @@ -243,11 +240,8 @@ - (void)didEnterStateStarted { } else if (self.configuration.lifecycleConfig.allowedSecondaryTransports == SDLSecondaryTransportsNone) { self.proxy = [SDLProxy iapProxyWithListener:self.notificationDispatcher secondaryTransportManager:nil encryptionLifecycleManager:self.encryptionLifecycleManager]; } else { - if([self.configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || - [self.configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] || - [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || - [self.configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { - // We reuse our queue to run secondary transport manager's state machine + if ([self.class isStreamingConfiguration:self.configuration]) { + // Reuse the queue to run the secondary transport manager's state machine self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; self.streamManager.secondaryTransportManager = self.secondaryTransportManager; } @@ -715,6 +709,18 @@ - (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(n } #pragma mark Helper Methods + ++ (BOOL)isStreamingConfiguration:(SDLConfiguration *)configuration { + if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || + [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] || + [configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || + [configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeProjection]) { + return YES; + } + + return NO; +} + - (NSNumber *)sdl_getNextCorrelationId { if (self.lastCorrelationId == INT32_MAX) { self.lastCorrelationId = 0; From d3e463e5bcd8a6dfda18f1fa228dd0e9cc81de60 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 13:20:18 -0400 Subject: [PATCH 122/152] Removed one-line method --- SmartDeviceLink/SDLSecondaryTransportManager.m | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index dc0f85a15..6b4f4d16b 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -296,15 +296,15 @@ - (void)willLeaveStateConnecting { } - (void)willTransitionFromStateConnectingToStateConfigured { - [self sdl_disconnectSecondaryTransport]; + [self disconnectSecondaryTransport]; } - (void)willTransitionFromStateConnectingToStateReconnecting { - [self sdl_disconnectSecondaryTransport]; + [self disconnectSecondaryTransport]; } - (void)willTransitionFromStateConnectingToStateStopped { - [self sdl_disconnectSecondaryTransport]; + [self disconnectSecondaryTransport]; } - (void)didEnterStateRegistered { @@ -325,7 +325,7 @@ - (void)willTransitionFromStateRegisteredToStateReconnecting { - (void)willTransitionFromStateRegisteredToStateStopped { // sdl_handleTransportUpdateWithPrimaryAvailable is called in stop method - [self sdl_disconnectSecondaryTransport]; + [self disconnectSecondaryTransport]; } - (void)didEnterStateReconnecting { @@ -425,10 +425,6 @@ - (BOOL)sdl_connectSecondaryTransport { } - (BOOL)disconnectSecondaryTransport { - return [self sdl_disconnectSecondaryTransport]; -} - -- (BOOL)sdl_disconnectSecondaryTransport { if (self.secondaryTransport == nil) { SDLLogW(@"Attempted to disconnect secondary transport, but it's already stopped."); return NO; From 60bab5c11bf21c0673072af653fad6b766fe81bd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 14:45:45 -0400 Subject: [PATCH 123/152] Removed SecondaryTransportPrimaryProtocolHandler --- SmartDeviceLink-iOS.xcodeproj/project.pbxproj | 10 --- SmartDeviceLink/SDLLogFileModuleMap.m | 2 +- .../SDLSecondaryTransportDelegate.h | 20 ----- .../SDLSecondaryTransportManager.m | 67 +++++++++++----- ...SecondaryTransportPrimaryProtocolHandler.h | 46 ----------- ...SecondaryTransportPrimaryProtocolHandler.m | 76 ------------------- 6 files changed, 50 insertions(+), 171 deletions(-) delete mode 100644 SmartDeviceLink/SDLSecondaryTransportDelegate.h delete mode 100644 SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.h delete mode 100644 SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.m diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 75c9fbf88..3d2a13fa8 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -1284,7 +1284,6 @@ 880245A520F79C3400ED195B /* SDLFileManagerConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */; }; 8803DCEF22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */; }; 8803DCF022C2B84B00FBB7CE /* SDLBackgroundTaskManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */; }; - 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */; }; 880723EB23A2CFB4003D0489 /* SDLLockScreenRootViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 880723E923A2CFB4003D0489 /* SDLLockScreenRootViewController.h */; }; 880723EC23A2CFB4003D0489 /* SDLLockScreenRootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 880723EA23A2CFB4003D0489 /* SDLLockScreenRootViewController.m */; }; 880D267A220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */; }; @@ -1608,7 +1607,6 @@ E9C32B9E1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h in Headers */ = {isa = PBXBuildFile; fileRef = E9C32B9A1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h */; }; E9C32B9F1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m in Sources */ = {isa = PBXBuildFile; fileRef = E9C32B9B1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m */; }; EE28F9E3209802A500B1B61D /* SDLStreamingProtocolDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = EE6CBF872064CAEE00EEE0CA /* SDLStreamingProtocolDelegate.h */; }; - EE38C0C3211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = EE38C0C2211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m */; }; EE460E082066B5F20006EDD3 /* SDLControlFramePayloadTransportEventUpdateSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EE460E072066B5F20006EDD3 /* SDLControlFramePayloadTransportEventUpdateSpec.m */; }; EE460E0A2066B6E40006EDD3 /* SDLControlFramePayloadRegisterSecondaryTransportNakSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EE460E092066B6E40006EDD3 /* SDLControlFramePayloadRegisterSecondaryTransportNakSpec.m */; }; EE5D1B33208EBCA900D17216 /* SDLTCPTransportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = EE5D1B32208EBCA900D17216 /* SDLTCPTransportSpec.m */; }; @@ -3035,7 +3033,6 @@ 880245A320F79C3400ED195B /* SDLFileManagerConfiguration.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLFileManagerConfiguration.m; sourceTree = ""; }; 8803DCED22C2B84B00FBB7CE /* SDLBackgroundTaskManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLBackgroundTaskManager.h; sourceTree = ""; }; 8803DCEE22C2B84B00FBB7CE /* SDLBackgroundTaskManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLBackgroundTaskManager.m; sourceTree = ""; }; - 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLSecondaryTransportDelegate.h; sourceTree = ""; }; 880723E923A2CFB4003D0489 /* SDLLockScreenRootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLockScreenRootViewController.h; sourceTree = ""; }; 880723EA23A2CFB4003D0489 /* SDLLockScreenRootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLockScreenRootViewController.m; sourceTree = ""; }; 880D2679220DDD1000B3F496 /* SDLWeatherServiceDataSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLWeatherServiceDataSpec.m; sourceTree = ""; }; @@ -3355,8 +3352,6 @@ E9C32B991AB20C5900F283AF /* EAAccessory+SDLProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EAAccessory+SDLProtocols.m"; sourceTree = ""; }; E9C32B9A1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "EAAccessoryManager+SDLProtocols.h"; sourceTree = ""; }; E9C32B9B1AB20C5900F283AF /* EAAccessoryManager+SDLProtocols.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "EAAccessoryManager+SDLProtocols.m"; sourceTree = ""; }; - EE38C0C1211C43E100E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDLSecondaryTransportPrimaryProtocolHandler.h; sourceTree = ""; }; - EE38C0C2211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLSecondaryTransportPrimaryProtocolHandler.m; sourceTree = ""; }; EE460E072066B5F20006EDD3 /* SDLControlFramePayloadTransportEventUpdateSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFramePayloadTransportEventUpdateSpec.m; path = ControlFramePayloadSpecs/SDLControlFramePayloadTransportEventUpdateSpec.m; sourceTree = ""; }; EE460E092066B6E40006EDD3 /* SDLControlFramePayloadRegisterSecondaryTransportNakSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = SDLControlFramePayloadRegisterSecondaryTransportNakSpec.m; path = ControlFramePayloadSpecs/SDLControlFramePayloadRegisterSecondaryTransportNakSpec.m; sourceTree = ""; }; EE5D1B32208EBCA900D17216 /* SDLTCPTransportSpec.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDLTCPTransportSpec.m; sourceTree = ""; }; @@ -6516,9 +6511,6 @@ children = ( EE798CA32056120F008EDE8E /* SDLSecondaryTransportManager.h */, EE798CA520561217008EDE8E /* SDLSecondaryTransportManager.m */, - EE38C0C1211C43E100E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.h */, - EE38C0C2211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m */, - 8805CDBB24166F1A00D645BF /* SDLSecondaryTransportDelegate.h */, ); name = "Secondary Transport"; sourceTree = ""; @@ -7063,7 +7055,6 @@ 888DBAEF22D528DE002A0AE2 /* SDLCloseApplicationResponse.h in Headers */, DAC5726C1D11B4840004288B /* SDLTouchManagerDelegate.h in Headers */, 5D61FD3F1A84238C00846EE7 /* SDLPrioritizedObjectCollection.h in Headers */, - 8805CDBD24166F1A00D645BF /* SDLSecondaryTransportDelegate.h in Headers */, 5D9FC29E1FD8813900ACA5C2 /* SDLAudioStreamManager.h in Headers */, 5DD67CB01E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.h in Headers */, 5D61FCBF1A84238C00846EE7 /* SDLHexUtility.h in Headers */, @@ -7705,7 +7696,6 @@ EED5CA021F4D18EC00F04000 /* SDLRAWH264Packetizer.m in Sources */, 9FE2471622D77AD500F8D2FC /* SDLWindowType.m in Sources */, 5D61FC851A84238C00846EE7 /* SDLDeviceLevelStatus.m in Sources */, - EE38C0C3211C440400E170AD /* SDLSecondaryTransportPrimaryProtocolHandler.m in Sources */, 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */, 5D61FD1E1A84238C00846EE7 /* SDLOnTBTClientState.m in Sources */, 5D0C29FD20D93D8C008B56CD /* SDLVideoStreamingState.m in Sources */, diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m index 1d8b7ce51..383eaa386 100644 --- a/SmartDeviceLink/SDLLogFileModuleMap.m +++ b/SmartDeviceLink/SDLLogFileModuleMap.m @@ -54,7 +54,7 @@ + (SDLLogFileModule *)sdl_iapTransportModule { } + (SDLLogFileModule *)sdl_secondaryTransportModule { - return [SDLLogFileModule moduleWithName:@"Transport/Secondary" files:[NSSet setWithArray:@[@"SDLSecondaryTransportManager", @"SDLSecondaryTransportPrimaryProtocolHandler"]]]; + return [SDLLogFileModule moduleWithName:@"Transport/Secondary" files:[NSSet setWithArray:@[@"SDLSecondaryTransportManager"]]]; } #pragma mark Low-Level diff --git a/SmartDeviceLink/SDLSecondaryTransportDelegate.h b/SmartDeviceLink/SDLSecondaryTransportDelegate.h deleted file mode 100644 index e331cea22..000000000 --- a/SmartDeviceLink/SDLSecondaryTransportDelegate.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// SDLSecondaryTransportDelegate.h -// SmartDeviceLink -// -// Created by Nicole on 3/9/20. -// Copyright © 2020 smartdevicelink. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@protocol SDLSecondaryTransportDelegate - -/// Called when the secondary transport should be destroyed. -- (void)destroySecondaryTransport; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 6b4f4d16b..7bc4e2599 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -20,9 +20,9 @@ #import "SDLOnHMIStatus.h" #import "SDLProtocol.h" #import "SDLProtocolHeader.h" +#import "SDLProtocolMessage.h" #import "SDLNotificationConstants.h" #import "SDLRPCNotificationNotification.h" -#import "SDLSecondaryTransportPrimaryProtocolHandler.h" #import "SDLStateMachine.h" #import "SDLTCPTransport.h" #import "SDLTimer.h" @@ -80,8 +80,8 @@ @interface SDLSecondaryTransportManager () // Instance of the protocol that runs on primary transport. @property (strong, nonatomic) SDLProtocol *primaryProtocol; -// A class to catch Start Service ACK and Transport Config Update frames. -@property (strong, nonatomic) SDLSecondaryTransportPrimaryProtocolHandler *primaryProtocolHandler; +/// The header of the Start Service ACK frame received on primary transport +@property (copy, nonatomic) SDLProtocolHeader *primaryRPCHeader; // Selected type of secondary transport. If 'SDLSecondaryTransportTypeDisabled' then secondary transport is disabled. @property (assign, nonatomic) SDLSecondaryTransportType secondaryTransportType; @@ -158,13 +158,16 @@ - (void)startWithPrimaryProtocol:(SDLProtocol *)primaryProtocol { } self.primaryProtocol = primaryProtocol; - self.primaryProtocolHandler = [[SDLSecondaryTransportPrimaryProtocolHandler alloc] initWithSecondaryTransportManager:self primaryProtocol:primaryProtocol]; + + @synchronized(self.primaryProtocol.protocolDelegateTable) { + [self.primaryProtocol.protocolDelegateTable addObject:self]; + } [self.stateMachine transitionToState:SDLSecondaryTransportStateStarted]; } - (void)stop { - SDLLogD(@"SDLSecondaryTransportManager stop"); + SDLLogD(@"Stopping manager"); // this method must be called in SDLLifecycleManager's state machine queue if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.stateMachineQueue)) != 0) { @@ -183,8 +186,6 @@ - (void)stop { - (void)sdl_startManager { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_onAppStateUpdated:) name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_onAppStateUpdated:) name:UIApplicationWillResignActiveNotification object:nil]; - - [self.primaryProtocolHandler start]; } - (void)sdl_stopManager { @@ -193,8 +194,6 @@ - (void)sdl_stopManager { [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil]; - [self.primaryProtocolHandler stop]; - self.streamingServiceTransportMap = [@{@(SDLServiceTypeAudio):@(SDLTransportClassInvalid), @(SDLServiceTypeVideo):@(SDLTransportClassInvalid)} mutableCopy]; self.secondaryTransportType = SDLSecondaryTransportTypeDisabled; @@ -406,6 +405,33 @@ - (nullable NSString *)sdl_getTransportClassName:(SDLTransportClass)transportCla #pragma mark - Transport management +#pragma mark Primary transport +// called from protocol's _reeiveQueue of Primary Transport +- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { + if (startServiceACK.header.serviceType != SDLServiceTypeRPC) { + return; + } + + SDLLogV(@"Received Start Service ACK header of RPC service on primary transport"); + + // keep header to acquire Session ID + self.primaryRPCHeader = startServiceACK.header; + + SDLControlFramePayloadRPCStartServiceAck *payload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:startServiceACK.payload]; + + [self onStartServiceAckReceived:payload]; +} + +// called from protocol's _reeiveQueue of Primary Transport +- (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate { + SDLControlFramePayloadTransportEventUpdate *payload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithData:transportEventUpdate.payload]; + SDLLogV(@"Recieved transport event update on primary transport: %@", payload); + + [self onTransportEventUpdateReceived:payload]; +} + +#pragma mark Secondary transport + // try establishing secondary transport. Returns NO if failed - (BOOL)sdl_connectSecondaryTransport { if (self.secondaryTransport != nil) { @@ -426,13 +452,14 @@ - (BOOL)sdl_connectSecondaryTransport { - (BOOL)disconnectSecondaryTransport { if (self.secondaryTransport == nil) { - SDLLogW(@"Attempted to disconnect secondary transport, but it's already stopped."); + SDLLogW(@"Attempted to disconnect secondary transport but it's already stopped."); return NO; } SDLLogD(@"Disconnect secondary transport"); [self.secondaryTransport disconnect]; self.secondaryTransport = nil; + self.secondaryProtocol = nil; [self.backgroundTaskManager endBackgroundTask]; @@ -453,17 +480,19 @@ - (BOOL)sdl_startTCPSecondaryTransport { SDLProtocol *protocol = [[SDLProtocol alloc] init]; transport.delegate = protocol; protocol.transport = transport; - [protocol.protocolDelegateTable addObject:self]; protocol.securityManager = self.primaryProtocol.securityManager; - self.secondaryProtocol = protocol; self.secondaryTransport = transport; + @synchronized(self.secondaryProtocol.protocolDelegateTable) { + [self.secondaryProtocol.protocolDelegateTable addObject:self]; + } + // we reuse Session ID acquired from primary transport's protocol // this is for Register Secondary Transport frame - [self.secondaryProtocol storeHeader:self.primaryProtocolHandler.primaryRPCHeader forServiceType:SDLServiceTypeControl]; + [self.secondaryProtocol storeHeader:self.primaryRPCHeader forServiceType:SDLServiceTypeControl]; // this is for video and audio services - [self.secondaryProtocol storeHeader:self.primaryProtocolHandler.primaryRPCHeader forServiceType:SDLServiceTypeRPC]; + [self.secondaryProtocol storeHeader:self.primaryRPCHeader forServiceType:SDLServiceTypeRPC]; [self.secondaryTransport connect]; return YES; @@ -476,17 +505,19 @@ - (BOOL)sdl_startIAPSecondaryTransport { SDLProtocol *protocol = [[SDLProtocol alloc] init]; transport.delegate = protocol; protocol.transport = transport; - [protocol.protocolDelegateTable addObject:self]; protocol.securityManager = self.primaryProtocol.securityManager; - self.secondaryProtocol = protocol; self.secondaryTransport = transport; + @synchronized(self.secondaryProtocol.protocolDelegateTable) { + [self.secondaryProtocol.protocolDelegateTable addObject:self]; + } + // we reuse Session ID acquired from primary transport's protocol // this is for Register Secondary Transport frame - [self.secondaryProtocol storeHeader:self.primaryProtocolHandler.primaryRPCHeader forServiceType:SDLServiceTypeControl]; + [self.secondaryProtocol storeHeader:self.primaryRPCHeader forServiceType:SDLServiceTypeControl]; // this is for video and audio services - [self.secondaryProtocol storeHeader:self.primaryProtocolHandler.primaryRPCHeader forServiceType:SDLServiceTypeRPC]; + [self.secondaryProtocol storeHeader:self.primaryRPCHeader forServiceType:SDLServiceTypeRPC]; [self.secondaryTransport connect]; return YES; diff --git a/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.h b/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.h deleted file mode 100644 index d3e8510ee..000000000 --- a/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// SDLSecondaryTransportPrimaryProtocolHandler.h -// SmartDeviceLink-iOS -// -// Created by Sho Amano on 2018/08/09. -// Copyright © 2018 Xevo Inc. All rights reserved. -// - -#import "SDLProtocolListener.h" - -@class SDLProtocol; -@class SDLSecondaryTransportManager; - -NS_ASSUME_NONNULL_BEGIN - -/** - A class to receive event from primary transport. - */ -@interface SDLSecondaryTransportPrimaryProtocolHandler : NSObject - -/** The header of Start Service ACK frame received on primary transport. */ -@property (copy, nonatomic) SDLProtocolHeader *primaryRPCHeader; - -/** - Create a new primary protocol handler with given SDLSecondaryTransportManager and SDLProtocol instances. - - @param manager instance of SDLSecondaryTransportManager - @param primaryProtocol instance of SDLProtocol for the primary transport - @return A new primary protocol handler - */ -- (instancetype)initWithSecondaryTransportManager:(SDLSecondaryTransportManager *)manager - primaryProtocol:(SDLProtocol *)primaryProtocol; - -/** - * Start the handler. - */ -- (void)start; - -/** - * Stop the handler. - */ -- (void)stop; - -@end - -NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.m b/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.m deleted file mode 100644 index 066a68999..000000000 --- a/SmartDeviceLink/SDLSecondaryTransportPrimaryProtocolHandler.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// SDLSecondaryTransportPrimaryProtocolHandler.m -// SmartDeviceLink -// -// Created by Sho Amano on 2018/08/09. -// Copyright © 2018 Xevo Inc. All rights reserved. -// - -#import - -#import "SDLSecondaryTransportPrimaryProtocolHandler.h" - -#import "SDLControlFramePayloadRPCStartServiceAck.h" -#import "SDLControlFramePayloadTransportEventUpdate.h" -#import "SDLLogMacros.h" -#import "SDLProtocol.h" -#import "SDLProtocolMessage.h" -#import "SDLSecondaryTransportManager.h" - -@interface SDLSecondaryTransportPrimaryProtocolHandler () -@property (weak, nonatomic) SDLSecondaryTransportManager *secondaryTransportManager; -@property (weak, nonatomic) SDLProtocol *primaryProtocol; -@end - -@implementation SDLSecondaryTransportPrimaryProtocolHandler - -- (instancetype)initWithSecondaryTransportManager:(SDLSecondaryTransportManager *)manager - primaryProtocol:(SDLProtocol *)primaryProtocol { - self = [super init]; - if (!self) { - return nil; - } - - _secondaryTransportManager = manager; - _primaryProtocol = primaryProtocol; - - return self; -} - -- (void)start { - @synchronized(self.primaryProtocol.protocolDelegateTable) { - [self.primaryProtocol.protocolDelegateTable addObject:self]; - } -} - -- (void)stop { - @synchronized(self.primaryProtocol.protocolDelegateTable) { - [self.primaryProtocol.protocolDelegateTable removeObject:self]; - } -} - -// called from protocol's _reeiveQueue of Primary Transport -- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { - if (startServiceACK.header.serviceType != SDLServiceTypeRPC) { - return; - } - - SDLLogV(@"Received Start Service ACK header of RPC service on primary transport"); - - // keep header to acquire Session ID - self.primaryRPCHeader = startServiceACK.header; - - SDLControlFramePayloadRPCStartServiceAck *payload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:startServiceACK.payload]; - - [self.secondaryTransportManager onStartServiceAckReceived:payload]; -} - -// called from protocol's _reeiveQueue of Primary Transport -- (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate { - SDLControlFramePayloadTransportEventUpdate *payload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithData:transportEventUpdate.payload]; - SDLLogV(@"Transport Config Update: %@", payload); - - [self.secondaryTransportManager onTransportEventUpdateReceived:payload]; -} - -@end From d4000cc00f12cbcdb74249045d5a3afa112ca17b Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 14:54:56 -0400 Subject: [PATCH 124/152] Fixed doc grammar --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index eaa75be48..ce26f9e88 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -447,7 +447,7 @@ - (void)didEnterStateSettingUpManagers { [self.encryptionLifecycleManager startWithProtocol:self.proxy.protocol]; } - // If the secondary transport manager is used, the streaming media manager will be started through `streamingServiceProtocolDidUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` + // If using the primary transport, start the streaming media manager. If using the secondary transport, the streaming media manager will be started through `streamingServiceProtocolDidUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` if (self.secondaryTransportManager == nil && self.streamManager != nil) { [self.streamManager startSecondaryTransportWithProtocol:self.proxy.protocol]; } From 977d7880ab5da86849cd520736d04cc739cd4bf8 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 15:01:30 -0400 Subject: [PATCH 125/152] Renamed variable --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.h | 2 +- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 8 ++++---- SmartDeviceLink/SDLStreamingMediaManager.m | 2 +- .../DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m | 6 +++--- SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h index 230264cfb..9af19619d 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.h @@ -26,7 +26,7 @@ NS_ASSUME_NONNULL_BEGIN @interface SDLStreamingAudioLifecycleManager : NSObject -@property (nonatomic, strong, readonly) SDLAudioStreamManager *audioManager; +@property (nonatomic, strong, readonly) SDLAudioStreamManager *audioTranscodingManager; @property (strong, nonatomic, readonly) SDLStateMachine *audioStreamStateMachine; @property (strong, nonatomic, readonly) SDLAudioStreamManagerState *currentAudioStreamState; diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 76d95803c..7bd299752 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -34,7 +34,7 @@ @interface SDLStreamingAudioLifecycleManager() -@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioManager; +@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioTranscodingManager; @property (strong, nonatomic, readwrite) SDLStateMachine *audioStreamStateMachine; @property (assign, nonatomic, readonly, getter=isHmiStateAudioStreamCapable) BOOL hmiStateAudioStreamCapable; @@ -57,7 +57,7 @@ - (instancetype)initWithConnectionManager:(id)connecti } _connectionManager = connectionManager; - _audioManager = [[SDLAudioStreamManager alloc] initWithManager:self]; + _audioTranscodingManager = [[SDLAudioStreamManager alloc] initWithManager:self]; _requestedEncryptionType = streamingConfiguration.maximumDesiredEncryption; NSMutableArray *tempMakeArray = [NSMutableArray array]; @@ -100,7 +100,7 @@ - (void)stop { _protocol = nil; _hmiLevel = SDLHMILevelNone; _connectedVehicleMake = nil; - [self.audioManager stop]; + [self.audioTranscodingManager stop]; [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } @@ -109,7 +109,7 @@ - (void)endAudioServiceWithCompletionHandler:(void (^)(void))completionHandler { SDLLogD(@"Ending audio service"); self.audioServiceEndedCompletionHandler = completionHandler; - [self.audioManager stop]; + [self.audioTranscodingManager stop]; [self.protocol endServiceWithType:SDLServiceTypeAudio]; } diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index aa702c767..907024e74 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -226,7 +226,7 @@ - (SDLTouchManager *)touchManager { } - (SDLAudioStreamManager *)audioManager { - return self.audioLifecycleManager.audioManager; + return self.audioLifecycleManager.audioTranscodingManager; } - (nullable UIViewController *)rootViewController { diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 24d6cd72a..1c3570ef2 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -25,7 +25,7 @@ @interface SDLStreamingAudioLifecycleManager() @property (weak, nonatomic) SDLProtocol *protocol; @property (copy, nonatomic, nullable) NSString *connectedVehicleMake; -@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioManager; +@property (nonatomic, strong, readwrite) SDLAudioStreamManager *audioTranscodingManager; @end QuickSpecBegin(SDLStreamingAudioLifecycleManagerSpec) @@ -50,11 +50,11 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve testConnectionManager = [[TestConnectionManager alloc] init]; streamingLifecycleManager = [[SDLStreamingAudioLifecycleManager alloc] initWithConnectionManager:testConnectionManager streamingConfiguration:testConfiguration encryptionConfiguration:encryptionConfiguration]; mockAudioStreamManager = OCMClassMock([SDLAudioStreamManager class]); - streamingLifecycleManager.audioManager = mockAudioStreamManager; + streamingLifecycleManager.audioTranscodingManager = mockAudioStreamManager; }); it(@"should initialize properties", ^{ - expect(streamingLifecycleManager.audioManager).toNot(beNil()); + expect(streamingLifecycleManager.audioTranscodingManager).toNot(beNil()); expect(@(streamingLifecycleManager.isStreamingSupported)).to(equal(@NO)); expect(@(streamingLifecycleManager.isAudioConnected)).to(equal(@NO)); expect(@(streamingLifecycleManager.isAudioEncrypted)).to(equal(@NO)); diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index c6b0ce674..46b638f09 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -146,7 +146,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto it(@"should return the audio lifecycle manager's audio manager for audioManager", ^{ [testStreamingMediaManager audioManager]; - OCMVerify([mockAudioLifecycleManager audioManager]); + OCMVerify([mockAudioLifecycleManager audioTranscodingManager]); }); it(@"should return the video lifecycle manager's rootViewController for rootViewController", ^{ @@ -290,7 +290,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto it(@"should start both the audio and video stream managers with the protocol", ^{ OCMVerify([mockAudioLifecycleManager startWithProtocol:mockProtocol]); OCMVerify([mockVideoLifecycleManager startWithProtocol:mockProtocol]); - + expect(testStreamingMediaManager.audioStarted).to(beTrue()); expect(testStreamingMediaManager.videoStarted).to(beTrue()); From 1f4f384b1584dc1832d488a921d83d2e61f5544b Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 15:08:24 -0400 Subject: [PATCH 126/152] Fixed deprecations and function formatting --- SmartDeviceLink/SDLStreamingMediaManager.m | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 907024e74..f560f3573 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -126,7 +126,10 @@ - (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { # pragma mark SDLStreamingProtocolDelegate -- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { +- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol + toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol + fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol + toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { BOOL videoProtocolUpdated = (oldVideoProtocol != newVideoProtocol); BOOL audioProtocolUpdated = (oldAudioProtocol != newAudioProtocol); @@ -202,8 +205,12 @@ - (void)sdl_startNewProtocolForAudio:(nullable SDLProtocol *)newAudioProtocol fo - (void)startWithProtocol:(SDLProtocol *)protocol { self.audioProtocol = protocol; self.videoProtocol = protocol; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" [self startAudioWithProtocol:protocol]; [self startVideoWithProtocol:protocol]; +#pragma clang diagnostic pop } - (void)startAudioWithProtocol:(SDLProtocol *)protocol { @@ -263,7 +270,7 @@ - (BOOL)isAudioEncrypted { - (BOOL)isVideoEncrypted { return self.videoLifecycleManager.isVideoEncrypted; } - + - (BOOL)isVideoStreamingPaused { return self.videoLifecycleManager.isVideoStreamingPaused; } From da7fcef989b3bc77606bd2224621e96f3391d3bd Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 15:12:03 -0400 Subject: [PATCH 127/152] Renamed protocol method --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- .../SDLSecondaryTransportManager.m | 2 +- SmartDeviceLink/SDLStreamingMediaManager.m | 4 ++-- .../SDLStreamingProtocolDelegate.h | 2 +- .../SDLStreamingVideoLifecycleManager.m | 2 +- .../SDLSecondaryTransportManagerSpec.m | 20 +++++++++---------- .../SDLStreamingMediaManagerSpec.m | 10 +++++----- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index ce26f9e88..a7314a783 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -447,7 +447,7 @@ - (void)didEnterStateSettingUpManagers { [self.encryptionLifecycleManager startWithProtocol:self.proxy.protocol]; } - // If using the primary transport, start the streaming media manager. If using the secondary transport, the streaming media manager will be started through `streamingServiceProtocolDidUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` + // If using the primary transport, start the streaming media manager. If using the secondary transport, the streaming media manager will be started through `didUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` if (self.secondaryTransportManager == nil && self.streamManager != nil) { [self.streamManager startSecondaryTransportWithProtocol:self.proxy.protocol]; } diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 7bc4e2599..02525f0c6 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -347,7 +347,7 @@ - (void)sdl_handleTransportUpdateWithPrimaryAvailable:(BOOL)primaryAvailable sec if (audioTransportUpdated.newProtocol == audioTransportUpdated.oldProtocol && videoTransportUpdated.newProtocol == videoTransportUpdated.oldProtocol) { return; } - [self.streamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:videoTransportUpdated.oldProtocol toNewVideoProtocol:videoTransportUpdated.newProtocol fromOldAudioProtocol:audioTransportUpdated.oldProtocol toNewAudioProtocol:audioTransportUpdated.newProtocol]; + [self.streamingProtocolDelegate didUpdateFromOldVideoProtocol:videoTransportUpdated.oldProtocol toNewVideoProtocol:videoTransportUpdated.newProtocol fromOldAudioProtocol:audioTransportUpdated.oldProtocol toNewAudioProtocol:audioTransportUpdated.newProtocol]; } - (struct TransportProtocolUpdated)sdl_updateService:(UInt8)service allowedTransports:(nonnull NSArray *)transportList primaryAvailable:(BOOL)primaryTransportAvailable secondaryAvailable:(BOOL)secondaryTransportAvailable { diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index f560f3573..7c32551ba 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -86,7 +86,7 @@ - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer presentationTimestamp:(CMTim #pragma mark - Secondary Transport - (void)startSecondaryTransportWithProtocol:(SDLProtocol *)protocol { - [self streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; + [self didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:protocol fromOldAudioProtocol:nil toNewAudioProtocol:protocol]; } - (void)sdl_disconnectSecondaryTransport { @@ -126,7 +126,7 @@ - (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { # pragma mark SDLStreamingProtocolDelegate -- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol +- (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { diff --git a/SmartDeviceLink/SDLStreamingProtocolDelegate.h b/SmartDeviceLink/SDLStreamingProtocolDelegate.h index 214ca99ae..259cc502b 100644 --- a/SmartDeviceLink/SDLStreamingProtocolDelegate.h +++ b/SmartDeviceLink/SDLStreamingProtocolDelegate.h @@ -22,7 +22,7 @@ NS_ASSUME_NONNULL_BEGIN /// @param newVideoProtocol protocol instance that will be used for video streaming /// @param oldAudioProtocol protocol instance that was being used for audio streaming /// @param newAudioProtocol protocol instance that will be used for audio streaming -- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; +- (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; @end diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index dddb9fa49..1966199ed 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -648,7 +648,7 @@ - (void)sdl_hmiStatusDidChange:(SDLRPCNotificationNotification *)notification { // if startWithProtocol has not been called yet, abort here if (self.protocol == nil) { - SDLLogV(@"No session established with head unit. HMI status is not relevant."); + SDLLogW(@"No session established with head unit. HMI status is not relevant."); return; } diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index 0ba6eecf1..d4ab293c4 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -164,7 +164,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve afterEach(^{ // it is possible that manager calls methods of SDLStreamingProtocolDelegate while stopping, so accept them // (Don't put OCMVerifyAll() after calling stop.) - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:OCMOCK_ANY toNewVideoProtocol:nil fromOldAudioProtocol:OCMOCK_ANY toNewAudioProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:OCMOCK_ANY toNewVideoProtocol:nil fromOldAudioProtocol:OCMOCK_ANY toNewAudioProtocol:nil]); dispatch_sync(testStateMachineQueue, ^{ [manager stop]; @@ -250,7 +250,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should configure its properties and transition to Configured state", ^{ // in this configuration, only audio service is allowed on primary transport - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -278,7 +278,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should configure its properties and transition to Configured state", ^{ // in this case, audio and video services start on primary transport (for compatibility) - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -306,7 +306,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should transition to Configured state with transport type disabled", ^{ // Since primary transport is iAP, we cannot use iAP for secondary transport. // So both services run on primary transport. - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -330,7 +330,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve it(@"should transition to Configured state with transport type disabled", ^{ // both services run on primary transport - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:testPrimaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:testPrimaryProtocol]); [testPrimaryProtocol handleBytesFromTransport:testStartServiceACKMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -689,7 +689,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Registered state", ^{ - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:secondaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:secondaryProtocol]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:secondaryProtocol fromOldAudioProtocol:nil toNewAudioProtocol:secondaryProtocol]); [testSecondaryProtocolMock handleBytesFromTransport:testRegisterSecondaryTransportAckMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -899,7 +899,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Configured state, then transition to Connecting state again", ^{ - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -919,7 +919,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Configured state", ^{ - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testPrimaryProtocol handleBytesFromTransport:testTransportEventUpdateMessage.data]; [NSThread sleepForTimeInterval:0.1]; @@ -940,7 +940,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Reconnecting state", ^{ - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); [testSecondaryProtocolMock onProtocolClosed]; [NSThread sleepForTimeInterval:0.1]; @@ -960,7 +960,7 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve }); it(@"should transition to Stopped state", ^{ - OCMExpect([testStreamingProtocolDelegate streamingServiceProtocolDidUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); + OCMExpect([testStreamingProtocolDelegate didUpdateFromOldVideoProtocol:secondaryProtocol toNewVideoProtocol:nil fromOldAudioProtocol:secondaryProtocol toNewAudioProtocol:nil]); dispatch_sync(testStateMachineQueue, ^{ [manager stop]; diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 46b638f09..d55c7e347 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -24,7 +24,7 @@ @interface SDLStreamingMediaManager() @property (strong, nonatomic, nullable) SDLProtocol *audioProtocol; @property (strong, nonatomic, nullable) SDLProtocol *videoProtocol; -- (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; +- (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol; @end @@ -313,7 +313,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto handler(); }); - [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:[OCMArg any] toNewVideoProtocol:nil fromOldAudioProtocol:[OCMArg any] toNewAudioProtocol:nil]; + [testStreamingMediaManager didUpdateFromOldVideoProtocol:[OCMArg any] toNewVideoProtocol:nil fromOldAudioProtocol:[OCMArg any] toNewAudioProtocol:nil]; }); it(@"should stop both the audio and video stream managers", ^{ @@ -357,7 +357,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto handler(); }); - [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldVideoProtocol toNewVideoProtocol:mockNewVideoProtocol fromOldAudioProtocol:mockOldAudioProtocol toNewAudioProtocol:mockNewAudioProtocol]; + [testStreamingMediaManager didUpdateFromOldVideoProtocol:mockOldVideoProtocol toNewVideoProtocol:mockNewVideoProtocol fromOldAudioProtocol:mockOldAudioProtocol toNewAudioProtocol:mockNewAudioProtocol]; }); it(@"should stop both the audio and video stream managers and call the delegate then start a new session", ^{ @@ -391,7 +391,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto handler(); }); - [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:nil toNewAudioProtocol:nil]; + [testStreamingMediaManager didUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:nil toNewAudioProtocol:nil]; }); it(@"should stop the video stream manager but not the audio stream manager", ^{ @@ -425,7 +425,7 @@ - (void)streamingServiceProtocolDidUpdateFromOldVideoProtocol:(nullable SDLProto handler(); }); - [testStreamingMediaManager streamingServiceProtocolDidUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; + [testStreamingMediaManager didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; }); it(@"should stop the audio stream manager but not the video stream manager", ^{ From b923c8995f261ceee6851e38c7a5f69d105f13e1 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 15:13:55 -0400 Subject: [PATCH 128/152] Relocated where notification is sent --- .../SDLStreamingVideoLifecycleManager.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 1966199ed..bda23f1a0 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -430,6 +430,14 @@ - (void)didEnterStateVideoStreamReady { [self sdl_disposeDisplayLink]; + [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil]; + + if (!self.isAppStateVideoStreamCapable) { + SDLLogD(@"App is in the background and can not stream video. Video will resume when app is foregrounded"); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateSuspended]; + return; + } + if (self.videoEncoder == nil) { NSError* error = nil; NSAssert(self.videoFormat != nil, @"No video format is known, but it must be if we got a protocol start service response"); @@ -456,14 +464,6 @@ - (void)didEnterStateVideoStreamReady { self.lastPresentationTimestamp = kCMTimeInvalid; } - [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil]; - - if (!self.isAppStateVideoStreamCapable) { - SDLLogD(@"App is in the background and can not stream video. Video will resume when app is foregrounded"); - [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateSuspended]; - return; - } - if (self.useDisplayLink) { dispatch_async(dispatch_get_main_queue(), ^{ NSInteger targetFramerate = ((NSNumber *)self.videoEncoderSettings[(__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate]).integerValue; From c3087ff83dddc86c04796d232cadacec0ce7daea Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 16:00:59 -0400 Subject: [PATCH 129/152] Fixed debug logs --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 2 +- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index 7bd299752..fde141a77 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -82,7 +82,7 @@ - (instancetype)initWithConnectionManager:(id)connecti } - (void)startWithProtocol:(SDLProtocol *)protocol { - SDLLogD(@"Starting with protocol: %@", self.protocol); + SDLLogD(@"Starting with protocol: %@", protocol); _protocol = protocol; @synchronized(self.protocol.protocolDelegateTable) { diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index bda23f1a0..139d23982 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -179,7 +179,7 @@ - (instancetype)initWithConnectionManager:(id)connecti } - (void)startWithProtocol:(SDLProtocol *)protocol { - SDLLogD(@"Starting with protocol: %@", self.protocol); + SDLLogD(@"Starting with protocol: %@", protocol); _protocol = protocol; @synchronized(self.protocol.protocolDelegateTable) { From 4af1c76730bde81cf0f8ebd459737ac17f42155b Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 11 Mar 2020 16:01:27 -0400 Subject: [PATCH 130/152] streaming media manager now destroys protocols --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 7c32551ba..b72f21c70 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -54,6 +54,8 @@ - (instancetype)initWithConnectionManager:(id)connecti - (void)stop { [self stopAudio]; [self stopVideo]; + self.audioProtocol = nil; + self.videoProtocol = nil; } From 7b7883926efa3848b42c3c4480a3bb70003264a4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 12 Mar 2020 08:38:39 -0400 Subject: [PATCH 131/152] Refactored methods --- SmartDeviceLink/SDLStreamingMediaManager.m | 87 +++++++++------------- 1 file changed, 34 insertions(+), 53 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index b72f21c70..b35453ba9 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -100,38 +100,12 @@ - (void)sdl_disconnectSecondaryTransport { [self.secondaryTransportManager disconnectSecondaryTransport]; } -#pragma mark Video - -/// Stops the video feature of the manager on the secondary transport. -/// @param completionHandler Called when video has stopped. -- (void)sdl_stopVideoWithCompletionHandler:(void(^)(void))completionHandler { - __weak typeof(self) weakSelf = self; - [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^() { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.videoStarted = NO; - return completionHandler(); - }]; -} - -#pragma mark Audio - -/// Stops the audio feature of the manager on the secondary transport. -/// @param completionHandler Called when audio has stopped. -- (void)sdl_stopAudioWithCompletionHandler:(void(^)(void))completionHandler { - __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.audioStarted = NO; - return completionHandler(); - }]; -} - # pragma mark SDLStreamingProtocolDelegate - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol - toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol - fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol - toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { + toNewVideoProtocol:(nullable SDLProtocol *)newVideoProtocol + fromOldAudioProtocol:(nullable SDLProtocol *)oldAudioProtocol + toNewAudioProtocol:(nullable SDLProtocol *)newAudioProtocol { BOOL videoProtocolUpdated = (oldVideoProtocol != newVideoProtocol); BOOL audioProtocolUpdated = (oldAudioProtocol != newAudioProtocol); @@ -142,30 +116,37 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol if (oldVideoProtocol != nil && oldAudioProtocol != nil) { // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. - dispatch_group_t closeServicesTask = dispatch_group_create(); - dispatch_group_enter(closeServicesTask); - dispatch_group_enter(closeServicesTask); - [self sdl_stopAudioWithCompletionHandler:^{ - dispatch_group_leave(closeServicesTask); - }]; - dispatch_group_enter(closeServicesTask); - [self sdl_stopVideoWithCompletionHandler:^{ - dispatch_group_leave(closeServicesTask); - }]; - dispatch_group_leave(closeServicesTask); - - dispatch_group_notify(closeServicesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ - [self sdl_disconnectSecondaryTransport]; - SDLLogV(@"Destroying the video and audio protocols"); - self.videoProtocol = nil; - self.audioProtocol = nil; - [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }); + dispatch_group_t closeServicesTask = dispatch_group_create(); + dispatch_group_enter(closeServicesTask); + + dispatch_group_enter(closeServicesTask); + __weak typeof(self) weakSelf = self; + [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.audioStarted = NO; + dispatch_group_leave(closeServicesTask); + }]; + dispatch_group_enter(closeServicesTask); + [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^ { + __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.videoStarted = NO; + dispatch_group_leave(closeServicesTask); + }]; + dispatch_group_leave(closeServicesTask); + + dispatch_group_notify(closeServicesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ + [self sdl_disconnectSecondaryTransport]; + SDLLogV(@"Destroying the video and audio protocols"); + self.videoProtocol = nil; + self.audioProtocol = nil; + [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }); } else if (oldVideoProtocol != nil) { // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self sdl_stopVideoWithCompletionHandler:^ { + __weak typeof(self) weakSelf = self; + [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.videoStarted = NO; [strongSelf sdl_disconnectSecondaryTransport]; SDLLogV(@"Destroying the video protocol"); strongSelf.videoProtocol = nil; @@ -173,9 +154,10 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol }]; } else if (oldAudioProtocol != nil) { // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; - [self sdl_stopAudioWithCompletionHandler:^ { + __weak typeof(self) weakSelf = self; + [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; + strongSelf.audioStarted = NO; [strongSelf sdl_disconnectSecondaryTransport]; SDLLogV(@"Destroying the audio protocol"); strongSelf.audioProtocol = nil; @@ -187,7 +169,6 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol } } - /// Starts the audio and/or video services using the new protocol. /// @param newAudioProtocol The new audio protocol /// @param newVideoProtocol The new video protocol From 612a8f99a5cddb03dc2fab0e967a3284352602cb Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 12 Mar 2020 09:56:02 -0400 Subject: [PATCH 132/152] Refactored closing & opening new sessions --- SmartDeviceLink/SDLStreamingMediaManager.m | 71 ++++++++----------- .../SDLStreamingMediaManagerSpec.m | 3 + 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index b35453ba9..0edb9538f 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -110,63 +110,50 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol BOOL audioProtocolUpdated = (oldAudioProtocol != newAudioProtocol); if (!videoProtocolUpdated && !audioProtocolUpdated) { - SDLLogV(@"The video and audio transports will not be updated since neither changed."); + SDLLogV(@"The video and audio transports did not update."); return; } - if (oldVideoProtocol != nil && oldAudioProtocol != nil) { - // Both an audio and video service are currently running. Make sure *BOTH* audio and video services have been stopped before destroying the secondary transport. Once the secondary transport has been destroyed, start the audio/video services using the new protocol. - dispatch_group_t closeServicesTask = dispatch_group_create(); - dispatch_group_enter(closeServicesTask); - - dispatch_group_enter(closeServicesTask); - __weak typeof(self) weakSelf = self; - [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.audioStarted = NO; - dispatch_group_leave(closeServicesTask); - }]; - dispatch_group_enter(closeServicesTask); - [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^ { - __strong typeof(weakSelf) strongSelf = weakSelf; - strongSelf.videoStarted = NO; - dispatch_group_leave(closeServicesTask); - }]; - dispatch_group_leave(closeServicesTask); + dispatch_group_t endServiceTask = dispatch_group_create(); + dispatch_group_enter(endServiceTask); + dispatch_group_enter(endServiceTask); - dispatch_group_notify(closeServicesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ - [self sdl_disconnectSecondaryTransport]; - SDLLogV(@"Destroying the video and audio protocols"); - self.videoProtocol = nil; - self.audioProtocol = nil; - [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; - }); - } else if (oldVideoProtocol != nil) { - // Only a video service is running. Make sure the video service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. - __weak typeof(self) weakSelf = self; + __weak typeof(self) weakSelf = self; + if (oldVideoProtocol != nil) { [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; strongSelf.videoStarted = NO; - [strongSelf sdl_disconnectSecondaryTransport]; - SDLLogV(@"Destroying the video protocol"); - strongSelf.videoProtocol = nil; - [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + dispatch_group_leave(endServiceTask); }]; - } else if (oldAudioProtocol != nil) { - // Only an audio service is running. Make sure the audio service has stopped before destroying the secondary transport and starting the new audio/video services using the new protocol. + } else { + dispatch_group_leave(endServiceTask); + } + + if (oldAudioProtocol != nil) { __weak typeof(self) weakSelf = self; [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; strongSelf.audioStarted = NO; - [strongSelf sdl_disconnectSecondaryTransport]; - SDLLogV(@"Destroying the audio protocol"); - strongSelf.audioProtocol = nil; - [strongSelf sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + dispatch_group_leave(endServiceTask); }]; } else { - // No audio and/or video service currently running. Just start the new audio and/or video services. - [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + dispatch_group_leave(endServiceTask); } + + dispatch_group_notify(endServiceTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ + [self sdl_disconnectSecondaryTransport]; + + if (oldVideoProtocol != nil) { + SDLLogV(@"Destroying the video protocol"); + self.videoProtocol = nil; + } + if (oldAudioProtocol != nil) { + SDLLogV(@"Destroying the audio protocol"); + self.audioProtocol = nil; + } + + [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; + }); } /// Starts the audio and/or video services using the new protocol. diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index d55c7e347..b5f859c37 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -285,6 +285,9 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t describe(@"starting a service on a transport when none is running", ^{ beforeEach(^{ [testStreamingMediaManager startSecondaryTransportWithProtocol:mockProtocol]; + + // Make sure the dispatch_group tasks finish before performing checks + [NSThread sleepForTimeInterval:0.5]; }); it(@"should start both the audio and video stream managers with the protocol", ^{ From ed861d6e5eaac73861dc0d811d57105305a77e99 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Thu, 12 Mar 2020 10:18:10 -0400 Subject: [PATCH 133/152] Consolidated streaming media manager tests --- .../SDLStreamingMediaManagerSpec.m | 135 +++++++----------- 1 file changed, 54 insertions(+), 81 deletions(-) diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index b5f859c37..2981495e3 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -139,118 +139,94 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t }); describe(@"getters", ^{ - it(@"should return the video lifecycle manager's touch manager for touchManager", ^{ - [testStreamingMediaManager touchManager]; - OCMVerify([mockVideoLifecycleManager touchManager]); - }); - - it(@"should return the audio lifecycle manager's audio manager for audioManager", ^{ + it(@"should return the audio lifecycle manager's properties correctly", ^{ [testStreamingMediaManager audioManager]; OCMVerify([mockAudioLifecycleManager audioTranscodingManager]); + + [testStreamingMediaManager isAudioConnected]; + OCMVerify([mockAudioLifecycleManager isAudioConnected]); + + [testStreamingMediaManager isAudioEncrypted]; + OCMVerify([mockAudioLifecycleManager isAudioEncrypted]); }); - it(@"should return the video lifecycle manager's rootViewController for rootViewController", ^{ + it(@"should return the video lifecycle manager's properties correctly", ^{ + [testStreamingMediaManager touchManager]; + OCMVerify([mockVideoLifecycleManager touchManager]); + [testStreamingMediaManager rootViewController]; OCMVerify([mockVideoLifecycleManager rootViewController]); - }); - it(@"should return the video lifecycle manager's focusableItemManager for focusableItemManager", ^{ [testStreamingMediaManager focusableItemManager]; OCMVerify([mockVideoLifecycleManager focusableItemManager]); - }); - - describe(@"when calling isStreamingSupported", ^{ - it(@"should return true if only video is streaming", ^{ - testStreamingMediaManager.videoStarted = YES; - testStreamingMediaManager.audioStarted = NO; - - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); - }); - - it(@"should return true if only audio is streaming", ^{ - testStreamingMediaManager.videoStarted = NO; - testStreamingMediaManager.audioStarted = YES; - - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); - }); - - it(@"should return true if both video and audio are streaming", ^{ - testStreamingMediaManager.videoStarted = YES; - testStreamingMediaManager.audioStarted = YES; - - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); - expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); - }); - - it(@"should return false if neither video or audio is streaming", ^{ - testStreamingMediaManager.videoStarted = NO; - testStreamingMediaManager.audioStarted = NO; - - OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); - OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); - expect(testStreamingMediaManager.isStreamingSupported).to(beFalse()); - }); - }); - - it(@"should return the audio lifecycle manager's isAudioConnected for isAudioConnected", ^{ - [testStreamingMediaManager isAudioConnected]; - OCMVerify([mockAudioLifecycleManager isAudioConnected]); - }); - it(@"should return the video lifecycle manager's isVideoConnected for isVideoConnected", ^{ [testStreamingMediaManager isVideoConnected]; OCMVerify([mockVideoLifecycleManager isVideoConnected]); - }); - - it(@"should return the audio lifecycle manager's isAudioEncrypted for isAudioEncrypted", ^{ - [testStreamingMediaManager isAudioEncrypted]; - OCMVerify([mockAudioLifecycleManager isAudioEncrypted]); - }); - it(@"should return the video lifecycle manager's isVideoEncrypted for isVideoEncrypted", ^{ [testStreamingMediaManager isVideoEncrypted]; OCMVerify([mockVideoLifecycleManager isVideoEncrypted]); - }); - it(@"should return the video lifecycle manager's isVideoStreamingPaused for isVideoStreamingPaused", ^{ [testStreamingMediaManager isVideoStreamingPaused]; OCMVerify([mockVideoLifecycleManager isVideoStreamingPaused]); - }); - it(@"should return the video lifecycle manager's screenSize for screenSize", ^{ [testStreamingMediaManager screenSize]; OCMVerify([mockVideoLifecycleManager.videoScaleManager displayViewportResolution]); - }); - it(@"should return the video lifecycle manager's videoFormat for videoFormat", ^{ [testStreamingMediaManager videoFormat]; OCMVerify([mockVideoLifecycleManager videoFormat]); - }); - it(@"should return the video lifecycle manager's supportedFormats for supportedFormats", ^{ [testStreamingMediaManager supportedFormats]; OCMVerify([mockVideoLifecycleManager supportedFormats]); - }); - it(@"should return the video lifecycle manager's pixelBufferPool for pixelBufferPool", ^{ [testStreamingMediaManager pixelBufferPool]; OCMVerify([mockVideoLifecycleManager pixelBufferPool]); - }); - it(@"should return the video lifecycle manager's requestedEncryptionType for requestedEncryptionType", ^{ - [testStreamingMediaManager requestedEncryptionType]; - OCMVerify([mockVideoLifecycleManager requestedEncryptionType]); - }); + [testStreamingMediaManager requestedEncryptionType]; + OCMVerify([mockVideoLifecycleManager requestedEncryptionType]); - it(@"should return the video lifecycle manager's showVideoBackgroundDisplay for showVideoBackgroundDisplay", ^{ [testStreamingMediaManager showVideoBackgroundDisplay]; OCMVerify([mockVideoLifecycleManager showVideoBackgroundDisplay]); }); + + describe(@"should return both the audio and vidoe lifecycle manager's properties correctly", ^{ + describe(@"when calling isStreamingSupported", ^{ + it(@"should return true if only video is streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if only audio is streaming", ^{ + testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return true if both video and audio are streaming", ^{ + testStreamingMediaManager.videoStarted = YES; + testStreamingMediaManager.audioStarted = YES; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(YES); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(YES); + expect(testStreamingMediaManager.isStreamingSupported).to(beTrue()); + }); + + it(@"should return false if neither video or audio is streaming", ^{ + testStreamingMediaManager.videoStarted = NO; + testStreamingMediaManager.audioStarted = NO; + + OCMStub([mockVideoLifecycleManager isStreamingSupported]).andReturn(NO); + OCMStub([mockAudioLifecycleManager isStreamingSupported]).andReturn(NO); + expect(testStreamingMediaManager.isStreamingSupported).to(beFalse()); + }); + }); + }); }); describe(@"setters", ^{ @@ -262,14 +238,11 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t OCMVerify([mockVideoLifecycleManager setRequestedEncryptionType:testEncryptionFlag]); }); - it(@"should set the rootViewController on the video manager", ^{ + it(@"should set the video manager properties correctly", ^{ UIViewController *testViewController = [[UIViewController alloc] init]; [testStreamingMediaManager setRootViewController:testViewController]; - OCMVerify([mockVideoLifecycleManager setRootViewController:testViewController]); - }); - it(@"should set showVideoBackgroundDisplay on the video manager", ^{ [testStreamingMediaManager setShowVideoBackgroundDisplay:NO]; OCMVerify([mockVideoLifecycleManager setShowVideoBackgroundDisplay:NO]); }); From a7190dfb327144f6d378acc9476ebc0a895add12 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 17 Mar 2020 08:55:26 -0400 Subject: [PATCH 134/152] Removed broken code that closes secondary transport --- SmartDeviceLink/SDLStreamingMediaManager.m | 2 -- 1 file changed, 2 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 0edb9538f..056935548 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -141,8 +141,6 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol } dispatch_group_notify(endServiceTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ - [self sdl_disconnectSecondaryTransport]; - if (oldVideoProtocol != nil) { SDLLogV(@"Destroying the video protocol"); self.videoProtocol = nil; From 25e4d39743a55c7d095d15006a60c881db7de672 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 17 Mar 2020 10:20:16 -0400 Subject: [PATCH 135/152] Fixed broken secondary transport disconnect --- SmartDeviceLink/SDLStreamingMediaManager.m | 5 +++++ .../SDLStreamingMediaManagerSpec.m | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 056935548..5f994b2c0 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -141,6 +141,11 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol } dispatch_group_notify(endServiceTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ + if (oldVideoProtocol != nil || oldAudioProtocol != nil) { + [self sdl_disconnectSecondaryTransport]; + SDLLogV(@"Disconnecting the secondary transport"); + } + if (oldVideoProtocol != nil) { SDLLogV(@"Destroying the video protocol"); self.videoProtocol = nil; diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m index 2981495e3..4d948b3f2 100644 --- a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -270,6 +270,8 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t expect(testStreamingMediaManager.audioStarted).to(beTrue()); expect(testStreamingMediaManager.videoStarted).to(beTrue()); + OCMReject([mockSecondaryTransportManager disconnectSecondaryTransport]); + OCMReject([mockAudioLifecycleManager endAudioServiceWithCompletionHandler:[OCMArg any]]); OCMReject([mockVideoLifecycleManager endVideoServiceWithCompletionHandler:[OCMArg any]]); }); @@ -290,6 +292,9 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t }); [testStreamingMediaManager didUpdateFromOldVideoProtocol:[OCMArg any] toNewVideoProtocol:nil fromOldAudioProtocol:[OCMArg any] toNewAudioProtocol:nil]; + + // Make sure the dispatch_group tasks finish before performing checks + [NSThread sleepForTimeInterval:0.5]; }); it(@"should stop both the audio and video stream managers", ^{ @@ -334,6 +339,9 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t }); [testStreamingMediaManager didUpdateFromOldVideoProtocol:mockOldVideoProtocol toNewVideoProtocol:mockNewVideoProtocol fromOldAudioProtocol:mockOldAudioProtocol toNewAudioProtocol:mockNewAudioProtocol]; + + // Make sure the dispatch_group tasks finish before performing checks + [NSThread sleepForTimeInterval:0.5]; }); it(@"should stop both the audio and video stream managers and call the delegate then start a new session", ^{ @@ -368,6 +376,9 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t }); [testStreamingMediaManager didUpdateFromOldVideoProtocol:mockOldProtocol toNewVideoProtocol:mockNewProtocol fromOldAudioProtocol:nil toNewAudioProtocol:nil]; + + // Make sure the dispatch_group tasks finish before performing checks + [NSThread sleepForTimeInterval:0.5]; }); it(@"should stop the video stream manager but not the audio stream manager", ^{ @@ -402,6 +413,9 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol t }); [testStreamingMediaManager didUpdateFromOldVideoProtocol:nil toNewVideoProtocol:nil fromOldAudioProtocol:mockOldProtocol toNewAudioProtocol:mockNewProtocol]; + + // Make sure the dispatch_group tasks finish before performing checks + [NSThread sleepForTimeInterval:0.5]; }); it(@"should stop the audio stream manager but not the video stream manager", ^{ From 5c6a4ba6ae5a821d7bc48e3e97f556b7096ef7a8 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 17 Mar 2020 14:17:31 -0400 Subject: [PATCH 136/152] Removed race condition disconnects --- .../SDLSecondaryTransportManager.m | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 02525f0c6..30bf8b5a6 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -294,39 +294,21 @@ - (void)willLeaveStateConnecting { self.registerTransportTimer = nil; } -- (void)willTransitionFromStateConnectingToStateConfigured { - [self disconnectSecondaryTransport]; -} - -- (void)willTransitionFromStateConnectingToStateReconnecting { - [self disconnectSecondaryTransport]; -} - -- (void)willTransitionFromStateConnectingToStateStopped { - [self disconnectSecondaryTransport]; -} - - (void)didEnterStateRegistered { SDLLogD(@"Secondary transport is registered"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:YES]; } - (void)willTransitionFromStateRegisteredToStateConfigured { - // before disconnecting Secondary Transport, stop running services - SDLLogD(@"Stopping services on secondary transport"); + SDLLogD(@"Configuring: stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; } - (void)willTransitionFromStateRegisteredToStateReconnecting { - SDLLogD(@"Stopping services on secondary transport"); + SDLLogD(@"Reconnecting: stopping services on secondary transport"); [self sdl_handleTransportUpdateWithPrimaryAvailable:YES secondaryAvailable:NO]; } -- (void)willTransitionFromStateRegisteredToStateStopped { - // sdl_handleTransportUpdateWithPrimaryAvailable is called in stop method - [self disconnectSecondaryTransport]; -} - - (void)didEnterStateReconnecting { SDLLogD(@"Secondary transport is reconnecting"); __weak typeof(self) weakSelf = self; @@ -578,6 +560,8 @@ - (void)onProtocolOpened { if ([strongSelf.stateMachine isCurrentState:SDLSecondaryTransportStateConnecting]) { SDLLogD(@"Retry secondary transport connection after registration timeout"); [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; + } else { + SDLLogD(@"Will not retry secondary transport connection because current state is: %@", strongSelf.stateMachine.currentState); } }); }; From 13daaa63d7ee46b7cb8f0e2585589290cf41ecc2 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 17 Mar 2020 14:47:44 -0400 Subject: [PATCH 137/152] Fixed transport not starting after erroring out --- SmartDeviceLink/SDLSecondaryTransportManager.m | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 30bf8b5a6..499e05edb 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -438,7 +438,7 @@ - (BOOL)disconnectSecondaryTransport { return NO; } - SDLLogD(@"Disconnect secondary transport"); + SDLLogD(@"Disconnecting secondary transport"); [self.secondaryTransport disconnect]; self.secondaryTransport = nil; self.secondaryProtocol = nil; @@ -570,6 +570,11 @@ - (void)onProtocolOpened { [self.secondaryProtocol registerSecondaryTransport]; } +- (void)onTransportError:(NSError *)error { + SDLLogE(@"The transport errored. Disconnecting the transport"); + [self disconnectSecondaryTransport]; +} + // called on transport's thread, notifying that the transport is disconnected // (Note: when transport's disconnect method is called, this method will not be called) - (void)onProtocolClosed { From 5ea445709779a8ed0f5fd17cf7a39de25fd28e82 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 08:22:33 -0400 Subject: [PATCH 138/152] Updated documentation --- SmartDeviceLink/SDLLifecycleManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index a7314a783..c328ddf51 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -447,7 +447,7 @@ - (void)didEnterStateSettingUpManagers { [self.encryptionLifecycleManager startWithProtocol:self.proxy.protocol]; } - // If using the primary transport, start the streaming media manager. If using the secondary transport, the streaming media manager will be started through `didUpdateFromOldVideoProtocol:toNewVideoProtocol:fromOldAudioProtocol:toNewAudioProtocol:` + // Starts the streaming media manager if only using the primary transport (i.e. secondary transports has been disabled in the lifecyle configuration). If using a secondary transport, setup is handled by the stream manager. if (self.secondaryTransportManager == nil && self.streamManager != nil) { [self.streamManager startSecondaryTransportWithProtocol:self.proxy.protocol]; } From 6a16fe9deebea688c32a7a357657834e05f1a953 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 08:24:47 -0400 Subject: [PATCH 139/152] Renamed private method --- SmartDeviceLink/SDLLifecycleManager.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index c328ddf51..33e410efc 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -144,7 +144,7 @@ - (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate _systemCapabilityManager = [[SDLSystemCapabilityManager alloc] initWithConnectionManager:self]; _screenManager = [[SDLScreenManager alloc] initWithConnectionManager:self fileManager:_fileManager systemCapabilityManager:_systemCapabilityManager]; - if ([self.class isStreamingConfiguration:self.configuration]) { + if ([self.class sdl_isStreamingConfiguration:self.configuration]) { _streamManager = [[SDLStreamingMediaManager alloc] initWithConnectionManager:self configuration:configuration]; } else { SDLLogV(@"Skipping StreamingMediaManager setup due to app type"); @@ -240,7 +240,7 @@ - (void)didEnterStateStarted { } else if (self.configuration.lifecycleConfig.allowedSecondaryTransports == SDLSecondaryTransportsNone) { self.proxy = [SDLProxy iapProxyWithListener:self.notificationDispatcher secondaryTransportManager:nil encryptionLifecycleManager:self.encryptionLifecycleManager]; } else { - if ([self.class isStreamingConfiguration:self.configuration]) { + if ([self.class sdl_isStreamingConfiguration:self.configuration]) { // Reuse the queue to run the secondary transport manager's state machine self.secondaryTransportManager = [[SDLSecondaryTransportManager alloc] initWithStreamingProtocolDelegate:(id)self.streamManager serialQueue:self.lifecycleQueue]; self.streamManager.secondaryTransportManager = self.secondaryTransportManager; @@ -710,7 +710,7 @@ - (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(n #pragma mark Helper Methods -+ (BOOL)isStreamingConfiguration:(SDLConfiguration *)configuration { ++ (BOOL)sdl_isStreamingConfiguration:(SDLConfiguration *)configuration { if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] || [configuration.lifecycleConfig.additionalAppTypes containsObject:SDLAppHMITypeNavigation] || From 245ba0c0d0ea483791da8311ca53693dbb7bc1d6 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 08:51:35 -0400 Subject: [PATCH 140/152] Made public variable private --- SmartDeviceLink/SDLSecondaryTransportManager.h | 3 --- SmartDeviceLink/SDLSecondaryTransportManager.m | 2 +- .../ProxySpecs/SDLSecondaryTransportManagerSpec.m | 1 + 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index 9c56e950c..c7165e890 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -36,9 +36,6 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; */ @interface SDLSecondaryTransportManager : NSObject -/// State of this manager -@property (strong, nonatomic, readonly) SDLStateMachine *stateMachine; - /// Create a new secondary transport manager. /// @param streamingProtocolDelegate a delegate to handle updates on protocol instances /// @param queue a serial dispatch queue that the internal state machine runs on diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 499e05edb..3f9c45cbc 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -74,7 +74,7 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { @interface SDLSecondaryTransportManager () /// State of this manager. -@property (strong, nonatomic, readwrite) SDLStateMachine *stateMachine; +@property (strong, nonatomic) SDLStateMachine *stateMachine; // Dedicated queue that the state machine will run on. @property (copy, nonatomic) dispatch_queue_t stateMachineQueue; diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m index d4ab293c4..04d836054 100644 --- a/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m +++ b/SmartDeviceLinkTests/ProxySpecs/SDLSecondaryTransportManagerSpec.m @@ -50,6 +50,7 @@ typedef NS_ENUM(NSInteger, SDLSecondaryTransportType) { @interface SDLSecondaryTransportManager () // we need to reach to private properties for the tests +@property (strong, nonatomic) SDLStateMachine *stateMachine; @property (assign, nonatomic) SDLSecondaryTransportType secondaryTransportType; @property (nullable, strong, nonatomic) SDLProtocol *primaryProtocol; @property (nullable, strong, nonatomic) id secondaryTransport; From ac992e887ffbea722a1b181141617f9b8b196b95 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 09:03:15 -0400 Subject: [PATCH 141/152] Made public methods private --- SmartDeviceLink/SDLSecondaryTransportManager.h | 8 -------- SmartDeviceLink/SDLSecondaryTransportManager.m | 14 ++++++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.h b/SmartDeviceLink/SDLSecondaryTransportManager.h index c7165e890..85f3cc79e 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.h +++ b/SmartDeviceLink/SDLSecondaryTransportManager.h @@ -52,14 +52,6 @@ extern SDLSecondaryTransportState *const SDLSecondaryTransportStateReconnecting; /// Destroys the secondary transport. - (BOOL)disconnectSecondaryTransport; -/// Call this method when a Start Service ACK control frame is received on primary transport. -/// @param payload The payload of Start Service ACK frame received on the primary transport. -- (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload; - -/// Call this method when Transport Event Update control frame is received on primary transport. -/// @param payload the payload of Transport Event Update frame received on the primary transport. -- (void)onTransportEventUpdateReceived:(SDLControlFramePayloadTransportEventUpdate *)payload; - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 3f9c45cbc..dc0951821 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -401,7 +401,7 @@ - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceA SDLControlFramePayloadRPCStartServiceAck *payload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:startServiceACK.payload]; - [self onStartServiceAckReceived:payload]; + [self sdl_onStartServiceAckReceived:payload]; } // called from protocol's _reeiveQueue of Primary Transport @@ -409,7 +409,7 @@ - (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUp SDLControlFramePayloadTransportEventUpdate *payload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithData:transportEventUpdate.payload]; SDLLogV(@"Recieved transport event update on primary transport: %@", payload); - [self onTransportEventUpdateReceived:payload]; + [self sdl_onTransportEventUpdateReceived:payload]; } #pragma mark Secondary transport @@ -606,8 +606,9 @@ - (void)handleProtocolRegisterSecondaryTransportNAKMessage:(SDLProtocolMessage * }); } -// called from SDLProtocol's _receiveQueue of "primary" transport -- (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload { +/// Called when a Start Service ACK control frame is received on the primary transport. +/// @param payload The payload of Start Service ACK frame received on the primary transport. +- (void)sdl_onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)payload { NSMutableArray *secondaryTransports = nil; if (payload.secondaryTransports != nil) { secondaryTransports = [NSMutableArray array]; @@ -627,8 +628,9 @@ - (void)onStartServiceAckReceived:(SDLControlFramePayloadRPCStartServiceAck *)pa }); } -// called from SDLProtocol's _receiveQueue of "primary" transport -- (void)onTransportEventUpdateReceived:(SDLControlFramePayloadTransportEventUpdate *)payload { +/// Called when a Transport Event Update control frame is received on the primary transport. +/// @param payload the payload of Transport Event Update frame +- (void)sdl_onTransportEventUpdateReceived:(SDLControlFramePayloadTransportEventUpdate *)payload { dispatch_async(_stateMachineQueue, ^{ BOOL updated = NO; From 631c9b41775d2f0a62b954a3b027ffccb44d427c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 10:34:03 -0400 Subject: [PATCH 142/152] Apply suggestions from code review Co-Authored-By: Joel Fischer --- SmartDeviceLink/SDLSecondaryTransportManager.m | 12 +++--------- SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 4 ++-- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 499e05edb..19f9259db 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -332,7 +332,7 @@ - (void)sdl_handleTransportUpdateWithPrimaryAvailable:(BOOL)primaryAvailable sec [self.streamingProtocolDelegate didUpdateFromOldVideoProtocol:videoTransportUpdated.oldProtocol toNewVideoProtocol:videoTransportUpdated.newProtocol fromOldAudioProtocol:audioTransportUpdated.oldProtocol toNewAudioProtocol:audioTransportUpdated.newProtocol]; } -- (struct TransportProtocolUpdated)sdl_updateService:(UInt8)service allowedTransports:(nonnull NSArray *)transportList primaryAvailable:(BOOL)primaryTransportAvailable secondaryAvailable:(BOOL)secondaryTransportAvailable { +- (struct TransportProtocolUpdated)sdl_updateService:(SDLServiceType)service allowedTransports:(nonnull NSArray *)transportList primaryAvailable:(BOOL)primaryTransportAvailable secondaryAvailable:(BOOL)secondaryTransportAvailable { SDLTransportClass newTransport = SDLTransportClassInvalid; // the list is in preferred order, so take a look from the beginning for (SDLTransportClassBox *transport in transportList) { @@ -388,23 +388,17 @@ - (nullable NSString *)sdl_getTransportClassName:(SDLTransportClass)transportCla #pragma mark - Transport management #pragma mark Primary transport -// called from protocol's _reeiveQueue of Primary Transport - (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK { - if (startServiceACK.header.serviceType != SDLServiceTypeRPC) { - return; - } - + if (startServiceACK.header.serviceType != SDLServiceTypeRPC) { return; } SDLLogV(@"Received Start Service ACK header of RPC service on primary transport"); - // keep header to acquire Session ID + // Keep header to acquire Session ID self.primaryRPCHeader = startServiceACK.header; SDLControlFramePayloadRPCStartServiceAck *payload = [[SDLControlFramePayloadRPCStartServiceAck alloc] initWithData:startServiceACK.payload]; - [self onStartServiceAckReceived:payload]; } -// called from protocol's _reeiveQueue of Primary Transport - (void)handleTransportEventUpdateMessage:(SDLProtocolMessage *)transportEventUpdate { SDLControlFramePayloadTransportEventUpdate *payload = [[SDLControlFramePayloadTransportEventUpdate alloc] initWithData:transportEventUpdate.payload]; SDLLogV(@"Recieved transport event update on primary transport: %@", payload); diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 139d23982..672631a3e 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -680,7 +680,7 @@ - (void)videoEncoder:(SDLH264VideoEncoder *)encoder hasEncodedFrame:(NSData *)en - (void)sdl_startVideoSession { SDLLogV(@"Attempting to start video session"); if (self.protocol == nil) { - SDLLogV(@"No transport established with head unit. Video start service request will not be sent."); + SDLLogW(@"No transport established with head unit. Video start service request will not be sent."); return; } @@ -707,7 +707,7 @@ - (void)sdl_startVideoSession { - (void)sdl_stopVideoSession { SDLLogV(@"Attempting to stop video session"); if (!self.isStreamingSupported) { - SDLLogV(@"Head unit does not support video streaming. Will not send an end video service request"); + SDLLogW(@"Head unit does not support video streaming. Will not send an end video service request"); return; } From 6636b87c5212ab6fa8f877a162870bdb5e585e39 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Fri, 20 Mar 2020 10:35:09 -0400 Subject: [PATCH 143/152] Refactored dispatch_group code --- SmartDeviceLink/SDLStreamingMediaManager.m | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index 5f994b2c0..7bdb3f0e6 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -116,43 +116,38 @@ - (void)didUpdateFromOldVideoProtocol:(nullable SDLProtocol *)oldVideoProtocol dispatch_group_t endServiceTask = dispatch_group_create(); dispatch_group_enter(endServiceTask); - dispatch_group_enter(endServiceTask); __weak typeof(self) weakSelf = self; if (oldVideoProtocol != nil) { + dispatch_group_enter(endServiceTask); [self.videoLifecycleManager endVideoServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; strongSelf.videoStarted = NO; dispatch_group_leave(endServiceTask); }]; - } else { - dispatch_group_leave(endServiceTask); } if (oldAudioProtocol != nil) { + dispatch_group_enter(endServiceTask); __weak typeof(self) weakSelf = self; [self.audioLifecycleManager endAudioServiceWithCompletionHandler:^ { __strong typeof(weakSelf) strongSelf = weakSelf; strongSelf.audioStarted = NO; dispatch_group_leave(endServiceTask); }]; - } else { - dispatch_group_leave(endServiceTask); } + dispatch_group_leave(endServiceTask); + + // This will always run dispatch_group_notify(endServiceTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{ if (oldVideoProtocol != nil || oldAudioProtocol != nil) { - [self sdl_disconnectSecondaryTransport]; SDLLogV(@"Disconnecting the secondary transport"); - } + [self sdl_disconnectSecondaryTransport]; - if (oldVideoProtocol != nil) { - SDLLogV(@"Destroying the video protocol"); - self.videoProtocol = nil; - } - if (oldAudioProtocol != nil) { - SDLLogV(@"Destroying the audio protocol"); + SDLLogD(@"Destroying the audio and video protocol and starting new audio and video protocols"); self.audioProtocol = nil; + self.videoProtocol = nil; } [self sdl_startNewProtocolForAudio:newAudioProtocol forVideo:newVideoProtocol]; From e227bf49ec61ed468fc693aee55df050605273c0 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 23 Mar 2020 08:22:45 -0400 Subject: [PATCH 144/152] Added documentation --- SmartDeviceLink/SDLLifecycleManager.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index c875f1a6f..6d82f4fad 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -710,6 +710,8 @@ - (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(n #pragma mark Helper Methods +/// Returns true if the app type set in the configuration is `NAVIGATION` or `PROJECTION`; false for any other app type. +/// @param configuration This session's configuration + (BOOL)sdl_isStreamingConfiguration:(SDLConfiguration *)configuration { if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection] || From 81b4c342492db0947f8cc6ef4295027072b6635c Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Mon, 23 Mar 2020 15:59:36 -0400 Subject: [PATCH 145/152] Added documentation to stream managers --- SmartDeviceLink/SDLStreamingAudioLifecycleManager.m | 1 + SmartDeviceLink/SDLStreamingVideoLifecycleManager.m | 1 + 2 files changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m index cd5f28192..36e0f3920 100644 --- a/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingAudioLifecycleManager.m @@ -230,6 +230,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { self.audioServiceEndedCompletionHandler = nil; } + /// Core will NAK the audio end service control frame if audio is not streaming or if video is streaming but the HMI does not recognize that audio is streaming. [self.audioStreamStateMachine transitionToState:SDLAudioStreamManagerStateStopped]; } diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index 4923d0848..bdfa9968a 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -580,6 +580,7 @@ - (void)handleProtocolEndServiceNAKMessage:(SDLProtocolMessage *)endServiceNAK { self.videoServiceEndedCompletionHandler = nil; } + /// Core will NAK the video end service control frame if video is not streaming or if video is streaming but the HMI does not recognize that video is streaming. [self.videoStreamStateMachine transitionToState:SDLVideoStreamManagerStateStopped]; } From ef9adb361687afd1c6516e7cdf5f87658ff012d4 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 24 Mar 2020 07:48:47 -0400 Subject: [PATCH 146/152] Streams now opened and closed on same thread --- SmartDeviceLink/SDLTCPTransport.m | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index 3c94eddd4..ebf1acefe 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -95,14 +95,29 @@ - (void)connect { - (void)disconnect { if (self.ioThread == nil) { - // already disconnected + SDLLogV(@"TCP transport thread already disconnected"); return; } - SDLLogD(@"Disconnecting TCP transport"); - + // Attempt to cancel the `ioThread`. Once the thread realizes it has been cancelled, the thread will cleanup the input/output streams. [self sdl_cancelIOThread]; + if (self.ioThread == nil) { + SDLLogV(@"TCP transport successfully disconnected"); + return; + } + + // The `ioThread` could not be woken up to be cancelled. Switch to the `ioThread` and perform the cleanup of the input/output streams + [self performSelector:@selector(sdl_disconnect) onThread:self.ioThread withObject:nil waitUntilDone:NO]; +} + +/// Closes the the input/output streams on the `ioThread` +- (void)sdl_disconnect { + /// We must close the input/output streams from the same thread that owns the streams' run loop, otherwise if the streams are closed from another thread a random crash may occur. + NSAssert([NSThread.currentThread.name isEqualToString:TCPIOThreadName], @"%@ should only be called on the IO thread", NSStringFromSelector(_cmd)); + + SDLLogD(@"Disconnecting TCP transport"); + if (self.ioThread != nil) { [self sdl_teardownStream:self.inputStream]; [self sdl_teardownStream:self.outputStream]; From 244b5407b7fe8fbb5e48e8c2241c757d2d9cc925 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 24 Mar 2020 15:28:06 -0400 Subject: [PATCH 147/152] Added weakSelf/strongSelf handling --- .../SDLSecondaryTransportManager.m | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index 5f38be916..b385a7afa 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -676,22 +676,28 @@ - (void)sdl_handleTransportEventUpdate { #pragma mark - App state handling - (void)sdl_onAppStateUpdated:(NSNotification *)notification { - dispatch_async(_stateMachineQueue, ^{ + __weak typeof(self) weakSelf = self; + dispatch_async(self.stateMachineQueue, ^{ + __strong typeof(self) strongSelf = weakSelf; if (notification.name == UIApplicationWillResignActiveNotification) { - if ([self sdl_isTransportOpened] && self.secondaryTransportType == SDLSecondaryTransportTypeTCP) { + if ([strongSelf sdl_isTransportOpened] && strongSelf.secondaryTransportType == SDLSecondaryTransportTypeTCP) { SDLLogD(@"Disconnecting TCP transport since the app will go to background"); // Start a background task so we can tear down the TCP socket successfully before the app is suspended - [self.backgroundTaskManager startBackgroundTask]; - [self.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; + [strongSelf.backgroundTaskManager startBackgroundTask]; + [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConfigured]; + } else { + SDLLogD(@"App will go to background. TCP transport already disconnected: %@", strongSelf.stateMachine.currentState); } } else if (notification.name == UIApplicationDidBecomeActiveNotification) { - if ([self.stateMachine isCurrentState:SDLSecondaryTransportStateConfigured] - && self.secondaryTransportType == SDLSecondaryTransportTypeTCP - && [self sdl_isTCPReady] - && [self sdl_isHMILevelNonNone]) { - SDLLogD(@"Resuming TCP transport since the app came into the foreground"); - [self.backgroundTaskManager endBackgroundTask]; - [self.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; + if ([strongSelf.stateMachine isCurrentState:SDLSecondaryTransportStateConfigured] + && strongSelf.secondaryTransportType == SDLSecondaryTransportTypeTCP + && [strongSelf sdl_isTCPReady] + && [strongSelf sdl_isHMILevelNonNone]) { + SDLLogD(@"Resuming TCP transport because the app came into the foreground"); + [strongSelf.backgroundTaskManager endBackgroundTask]; + [strongSelf.stateMachine transitionToState:SDLSecondaryTransportStateConnecting]; + } else { + SDLLogD(@"App returning to foreground. TCP transport not ready to connect: %@", strongSelf.stateMachine.currentState); } } }); From 7b5c862d82158f6cfa3fdd1ca1dafb19cb5c2845 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 31 Mar 2020 12:55:11 -0400 Subject: [PATCH 148/152] Apply suggestions from code review Co-Authored-By: Joel Fischer --- .../DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m | 1 - 1 file changed, 1 deletion(-) diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m index 1dec75718..186be93c8 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingAudioLifecycleManagerSpec.m @@ -2,7 +2,6 @@ #import #import - #import "SDLAudioStreamManager.h" #import "SDLConfiguration.h" #import "SDLControlFramePayloadAudioStartServiceAck.h" From 9cfcbd223c6895cb2a2ece795f1741f61a9b4088 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 31 Mar 2020 13:56:50 -0400 Subject: [PATCH 149/152] Added documentation to method --- SmartDeviceLink/SDLSecondaryTransportManager.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/SmartDeviceLink/SDLSecondaryTransportManager.m b/SmartDeviceLink/SDLSecondaryTransportManager.m index b385a7afa..ad2dc4659 100644 --- a/SmartDeviceLink/SDLSecondaryTransportManager.m +++ b/SmartDeviceLink/SDLSecondaryTransportManager.m @@ -675,6 +675,8 @@ - (void)sdl_handleTransportEventUpdate { #pragma mark - App state handling +/// Closes and re-opens the the secondary transport when the app is backgrounded and foregrounded on the device respectively. This is done because sockets can be reclaimed by the system at anytime when the app is not in the foreground. +/// @param notification Notification from the OS that the app's life-cycle state has changed - (void)sdl_onAppStateUpdated:(NSNotification *)notification { __weak typeof(self) weakSelf = self; dispatch_async(self.stateMachineQueue, ^{ From b77c02c0b4f9d081493acd148927921b4d85d1d5 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 31 Mar 2020 15:21:11 -0400 Subject: [PATCH 150/152] Refactored cancel timer method --- SmartDeviceLink/SDLTCPTransport.m | 43 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index ebf1acefe..a6c7cee71 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -52,8 +52,7 @@ - (instancetype)initWithHostName:(NSString *)hostName portNumber:(NSString *)por } - (void)dealloc { - SDLLogD(@"SDLTCPTransport dealloc"); - [self disconnect]; + SDLLogV(@"dealloc"); } #pragma mark - Stream Lifecycle @@ -99,13 +98,12 @@ - (void)disconnect { return; } - // Attempt to cancel the `ioThread`. Once the thread realizes it has been cancelled, the thread will cleanup the input/output streams. - [self sdl_cancelIOThread]; + [self.sendDataQueue removeAllObjects]; + self.transportErrorNotified = NO; + self.transportConnected = NO; - if (self.ioThread == nil) { - SDLLogV(@"TCP transport successfully disconnected"); - return; - } + // Attempt to cancel the `ioThread`. Once the thread realizes it has been cancelled, it will cleanup the input/output streams. + [self sdl_cancelIOThread]; // The `ioThread` could not be woken up to be cancelled. Switch to the `ioThread` and perform the cleanup of the input/output streams [self performSelector:@selector(sdl_disconnect) onThread:self.ioThread withObject:nil waitUntilDone:NO]; @@ -118,21 +116,19 @@ - (void)sdl_disconnect { SDLLogD(@"Disconnecting TCP transport"); - if (self.ioThread != nil) { + if (self.inputStream != nil) { [self sdl_teardownStream:self.inputStream]; - [self sdl_teardownStream:self.outputStream]; - - [self.connectionTimer invalidate]; + self.inputStream = nil; } - self.ioThread = nil; + if (self.outputStream != nil) { + [self sdl_teardownStream:self.outputStream]; + self.outputStream = nil; + } - self.inputStream = nil; - self.outputStream = nil; + [self sdl_cancelConnectionTimer]; - [self.sendDataQueue removeAllObjects]; - self.transportErrorNotified = NO; - self.transportConnected = NO; + self.ioThread = nil; } #pragma mark - Data Transmission @@ -170,7 +166,7 @@ - (void)sdl_tcpTransportEventLoop { [self sdl_teardownStream:self.inputStream]; [self sdl_teardownStream:self.outputStream]; - [self.connectionTimer invalidate]; + [self sdl_cancelConnectionTimer]; } } @@ -195,6 +191,13 @@ - (void)sdl_cancelIOThread { [self performSelector:@selector(sdl_doNothing) onThread:self.ioThread withObject:nil waitUntilDone:NO]; } +/// Cancels the connection timer for establishing a TCP socket with the accessory. +- (void)sdl_cancelConnectionTimer { + if (self.connectionTimer == nil) { return; } + [self.connectionTimer invalidate]; + self.connectionTimer = nil; +} + #pragma mark - NSStreamDelegate // this method runs only on the I/O thread (i.e. invoked from the run loop) @@ -207,7 +210,7 @@ - (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode { // We will get two NSStreamEventOpenCompleted events (for both input and output streams) and we don't need both. Let's use the one of output stream since we need to make sure that output stream is ready before Proxy sending Start Service frame. if (aStream == self.outputStream) { SDLLogD(@"TCP transport connected"); - [self.connectionTimer invalidate]; + [self sdl_cancelConnectionTimer]; self.transportConnected = YES; [self.delegate onTransportConnected]; } From fa2aaaa4ef5c56856459d95db00add0eb0004f65 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Tue, 31 Mar 2020 16:00:56 -0400 Subject: [PATCH 151/152] Removed unnecessary shutdown code --- SmartDeviceLink/SDLTCPTransport.m | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index a6c7cee71..b73b2d43b 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -104,31 +104,6 @@ - (void)disconnect { // Attempt to cancel the `ioThread`. Once the thread realizes it has been cancelled, it will cleanup the input/output streams. [self sdl_cancelIOThread]; - - // The `ioThread` could not be woken up to be cancelled. Switch to the `ioThread` and perform the cleanup of the input/output streams - [self performSelector:@selector(sdl_disconnect) onThread:self.ioThread withObject:nil waitUntilDone:NO]; -} - -/// Closes the the input/output streams on the `ioThread` -- (void)sdl_disconnect { - /// We must close the input/output streams from the same thread that owns the streams' run loop, otherwise if the streams are closed from another thread a random crash may occur. - NSAssert([NSThread.currentThread.name isEqualToString:TCPIOThreadName], @"%@ should only be called on the IO thread", NSStringFromSelector(_cmd)); - - SDLLogD(@"Disconnecting TCP transport"); - - if (self.inputStream != nil) { - [self sdl_teardownStream:self.inputStream]; - self.inputStream = nil; - } - - if (self.outputStream != nil) { - [self sdl_teardownStream:self.outputStream]; - self.outputStream = nil; - } - - [self sdl_cancelConnectionTimer]; - - self.ioThread = nil; } #pragma mark - Data Transmission From 6d0ca85ecabd1990f765f7452389be01ae603e91 Mon Sep 17 00:00:00 2001 From: NicoleYarroch Date: Wed, 1 Apr 2020 13:13:12 -0400 Subject: [PATCH 152/152] Added logs to TCPTransport start/stop funcs --- SmartDeviceLink/SDLTCPTransport.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SmartDeviceLink/SDLTCPTransport.m b/SmartDeviceLink/SDLTCPTransport.m index b73b2d43b..027a9f204 100644 --- a/SmartDeviceLink/SDLTCPTransport.m +++ b/SmartDeviceLink/SDLTCPTransport.m @@ -64,6 +64,8 @@ - (void)connect { return; } + SDLLogD(@"Attempting to connect"); + unsigned int port; int num = [self.portNumber intValue]; if (0 <= num && num <= 65535) { @@ -98,6 +100,8 @@ - (void)disconnect { return; } + SDLLogD(@"Disconnecting"); + [self.sendDataQueue removeAllObjects]; self.transportErrorNotified = NO; self.transportConnected = NO;