diff --git a/SmartDeviceLink/SDLCarWindow.m b/SmartDeviceLink/SDLCarWindow.m old mode 100755 new mode 100644 index 5e2e02557..bc96f2c8f --- a/SmartDeviceLink/SDLCarWindow.m +++ b/SmartDeviceLink/SDLCarWindow.m @@ -21,6 +21,7 @@ #import "SDLStreamingMediaConfiguration.h" #import "SDLStreamingVideoLifecycleManager.h" #import "SDLStreamingMediaManagerConstants.h" +#import "SDLVideoStreamingCapability.h" NS_ASSUME_NONNULL_BEGIN @@ -71,7 +72,7 @@ - (void)syncFrame { return; } - CGRect bounds = self.rootViewController.view.bounds; + CGRect bounds = self.sdl_getScaledScreenSizeFrame; UIGraphicsBeginImageContextWithOptions(bounds.size, YES, 1.0f); switch (self.renderingType) { @@ -120,13 +121,18 @@ - (void)sdl_didReceiveVideoStreamStarted:(NSNotification *)notification { dispatch_async(dispatch_get_main_queue(), ^{ // If the video stream has started, we want to resize the streamingViewController to the size from the RegisterAppInterface - self.rootViewController.view.frame = CGRectMake(0, 0, self.streamManager.screenSize.width, self.streamManager.screenSize.height); + self.rootViewController.view.frame = self.sdl_getScaledScreenSizeFrame; self.rootViewController.view.bounds = self.rootViewController.view.frame; - + SDLLogD(@"Video stream started, setting CarWindow frame to: %@", NSStringFromCGRect(self.rootViewController.view.bounds)); }); } +- (CGRect)sdl_getScaledScreenSizeFrame { + float scale = self.streamManager.videoStreamingCapability.scale.floatValue; + return CGRectMake(0, 0, self.streamManager.screenSize.width / scale, self.streamManager.screenSize.height / scale); +} + - (void)sdl_didReceiveVideoStreamStopped:(NSNotification *)notification { self.videoStreamStarted = false; diff --git a/SmartDeviceLink/SDLRPCParameterNames.h b/SmartDeviceLink/SDLRPCParameterNames.h index 50b018dbb..024d95c20 100644 --- a/SmartDeviceLink/SDLRPCParameterNames.h +++ b/SmartDeviceLink/SDLRPCParameterNames.h @@ -139,6 +139,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameDestinationETA; extern SDLRPCParameterName const SDLRPCParameterNameDetails; extern SDLRPCParameterName const SDLRPCParameterNameDeviceInfo; extern SDLRPCParameterName const SDLRPCParameterNameDeviceStatus; +extern SDLRPCParameterName const SDLRPCParameterNameDiagonalScreenSize; extern SDLRPCParameterName const SDLRPCParameterNameDialNumberEnabled; extern SDLRPCParameterName const SDLRPCParameterNameDIDLocation; extern SDLRPCParameterName const SDLRPCParameterNameDIDResult; @@ -443,6 +444,7 @@ extern SDLRPCParameterName const SDLRPCParameterNamePhoneCall; extern SDLRPCParameterName const SDLRPCParameterNamePhoneCapability; extern SDLRPCParameterName const SDLRPCParameterNamePhoneNumber; extern SDLRPCParameterName const SDLRPCParameterNamePhoneRoaming; +extern SDLRPCParameterName const SDLRPCParameterNamePixelPerInch; extern SDLRPCParameterName const SDLRPCParameterNamePlaylistName; extern SDLRPCParameterName const SDLRPCParameterNamePlayTone; extern SDLRPCParameterName const SDLRPCParameterNamePosition; @@ -514,6 +516,7 @@ extern SDLRPCParameterName const SDLRPCParameterNameRPM; extern SDLRPCParameterName const SDLRPCParameterNameRadioText; extern SDLRPCParameterName const SDLRPCParameterNameSamplingRate; extern SDLRPCParameterName const SDLRPCParameterNameSatellites; +extern SDLRPCParameterName const SDLRPCParameterNameScale; extern SDLRPCParameterName const SDLRPCParameterNameScreenParams; extern SDLRPCParameterName const SDLRPCParameterNameScrollableMessageBody; extern SDLRPCParameterName const SDLRPCParameterNameSDLVersion; diff --git a/SmartDeviceLink/SDLRPCParameterNames.m b/SmartDeviceLink/SDLRPCParameterNames.m index 06d6b78f5..752cc448b 100644 --- a/SmartDeviceLink/SDLRPCParameterNames.m +++ b/SmartDeviceLink/SDLRPCParameterNames.m @@ -137,6 +137,7 @@ SDLRPCParameterName const SDLRPCParameterNameDeviceInfo = @"deviceInfo"; SDLRPCParameterName const SDLRPCParameterNameDeviceStatus = @"deviceStatus"; SDLRPCParameterName const SDLRPCParameterNameDetails = @"details"; +SDLRPCParameterName const SDLRPCParameterNameDiagonalScreenSize = @"diagonalScreenSize"; SDLRPCParameterName const SDLRPCParameterNameDialNumberEnabled = @"dialNumberEnabled"; SDLRPCParameterName const SDLRPCParameterNameDIDLocation = @"didLocation"; SDLRPCParameterName const SDLRPCParameterNameDIDResult = @"didResult"; @@ -437,6 +438,7 @@ SDLRPCParameterName const SDLRPCParameterNamePhoneCapability = @"phoneCapability"; SDLRPCParameterName const SDLRPCParameterNamePhoneNumber = @"phoneNumber"; SDLRPCParameterName const SDLRPCParameterNamePhoneRoaming = @"phoneRoaming"; +SDLRPCParameterName const SDLRPCParameterNamePixelPerInch = @"pixelPerInch"; SDLRPCParameterName const SDLRPCParameterNamePrimaryColor = @"primaryColor"; SDLRPCParameterName const SDLRPCParameterNamePlaylistName = @"playlistName"; SDLRPCParameterName const SDLRPCParameterNamePlayTone = @"playTone"; @@ -509,6 +511,7 @@ SDLRPCParameterName const SDLRPCParameterNameRadioText = @"RT"; SDLRPCParameterName const SDLRPCParameterNameSamplingRate = @"samplingRate"; SDLRPCParameterName const SDLRPCParameterNameSatellites = @"satellites"; +SDLRPCParameterName const SDLRPCParameterNameScale = @"scale"; SDLRPCParameterName const SDLRPCParameterNameScreenParams = @"screenParams"; SDLRPCParameterName const SDLRPCParameterNameScrollableMessageBody = @"scrollableMessageBody"; SDLRPCParameterName const SDLRPCParameterNameSDLVersion = @"sdlVersion"; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h index ca6188904..2b7a47ff3 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.h @@ -22,6 +22,7 @@ @class SDLStateMachine; @class SDLStreamingMediaConfiguration; @class SDLTouchManager; +@class SDLVideoStreamingCapability; @protocol SDLConnectionManagerType; @protocol SDLFocusableItemLocatorType; @@ -35,6 +36,7 @@ NS_ASSUME_NONNULL_BEGIN @property (strong, nonatomic, readonly) SDLStateMachine *videoStreamStateMachine; @property (strong, nonatomic, readonly) SDLVideoStreamManagerState *currentVideoStreamState; +@property (nullable, strong, nonatomic, readonly) SDLVideoStreamingCapability *videoStreamingCapability; @property (strong, nonatomic, readonly) SDLStateMachine *appStateMachine; @property (strong, nonatomic, readonly) SDLAppState *currentAppState; diff --git a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m index c0d92c30d..c1530fbb5 100644 --- a/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m +++ b/SmartDeviceLink/SDLStreamingVideoLifecycleManager.m @@ -58,6 +58,8 @@ @interface SDLStreamingVideoLifecycleManager() @property (assign, nonatomic, readonly, getter=isAppStateVideoStreamCapable) BOOL appStateVideoStreamCapable; @property (assign, nonatomic, readonly, getter=isHmiStateVideoStreamCapable) BOOL hmiStateVideoStreamCapable; +@property (nullable, strong, nonatomic, readwrite) SDLVideoStreamingCapability *videoStreamingCapability; + @property (strong, nonatomic, readwrite) SDLStateMachine *videoStreamStateMachine; @property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine; @@ -393,7 +395,9 @@ - (void)didEnterStateVideoStreamReady { NSAssert(self.videoFormat != nil, @"No video format is known, but it must be if we got a protocol start service response"); SDLLogD(@"Attempting to create video encoder"); - self.videoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:self.videoFormat.protocol dimensions:self.screenSize ssrc:self.ssrc properties:self.videoEncoderSettings delegate:self error:&error]; + float scale = self.videoStreamingCapability.scale.floatValue; + CGSize scaledScreenSize = CGSizeMake(self.screenSize.width / scale, self.screenSize.height / scale); + self.videoEncoder = [[SDLH264VideoEncoder alloc] initWithProtocol:self.videoFormat.protocol dimensions:scaledScreenSize ssrc:self.ssrc properties:self.videoEncoderSettings delegate:self error:&error]; if (error || self.videoEncoder == nil) { SDLLogE(@"Could not create a video encoder: %@", error); @@ -710,6 +714,8 @@ - (void)sdl_requestVideoCapabilities:(SDLVideoCapabilityResponseHandler)response } SDLVideoStreamingCapability *videoCapability = ((SDLGetSystemCapabilityResponse *)response).systemCapability.videoStreamingCapability; + self.videoStreamingCapability = videoCapability; + self.touchManager.videoStreamingCapability = videoCapability; SDLLogD(@"Video capabilities response received: %@", videoCapability); responseHandler(videoCapability); }]; diff --git a/SmartDeviceLink/SDLTouchManager.h b/SmartDeviceLink/SDLTouchManager.h index 185aae174..9e01a8b0c 100644 --- a/SmartDeviceLink/SDLTouchManager.h +++ b/SmartDeviceLink/SDLTouchManager.h @@ -14,6 +14,7 @@ @protocol SDLTouchManagerDelegate; @class SDLTouch; +@class SDLVideoStreamingCapability; NS_ASSUME_NONNULL_BEGIN @@ -78,6 +79,11 @@ typedef void(^SDLTouchEventHandler)(SDLTouch *touch, SDLTouchType type); */ @property (nonatomic, assign, getter=isTouchEnabled) BOOL touchEnabled; +/** + Provides all video streaming capabilities defined in the HMI. + */ +@property (nullable, strong, nonatomic) SDLVideoStreamingCapability *videoStreamingCapability; + /** * @abstract * Cancels pending touch event timers that may be in progress. diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m index 1f4f4adea..7f2ca8593 100644 --- a/SmartDeviceLink/SDLTouchManager.m +++ b/SmartDeviceLink/SDLTouchManager.m @@ -22,6 +22,7 @@ #import "SDLTouchCoord.h" #import "SDLTouchEvent.h" #import "SDLTouchManagerDelegate.h" +#import "SDLVideoStreamingCapability.h" NS_ASSUME_NONNULL_BEGIN @@ -184,7 +185,8 @@ - (void)sdl_onTouchEvent:(SDLRPCNotificationNotification *)notification { return; } - SDLOnTouchEvent* onTouchEvent = (SDLOnTouchEvent*)notification.notification; + SDLOnTouchEvent *onTouchEvent = (SDLOnTouchEvent *)notification.notification; + onTouchEvent = [self sdl_applyScaleToEventCoordinates:onTouchEvent.copy]; SDLTouchType touchType = onTouchEvent.type; [onTouchEvent.event enumerateObjectsUsingBlock:^(SDLTouchEvent *touchEvent, NSUInteger idx, BOOL *stop) { @@ -212,6 +214,26 @@ - (void)sdl_onTouchEvent:(SDLRPCNotificationNotification *)notification { }]; } +/** + * Modifies the existing coordinates of the SDLOnTouchEvent, based on the received 'scale' value. + + * This will match the coordinates to the scaled resolution of the video. + + * @param onTouchEvent A SDLOnTouchEvent with coordinates. + */ +- (SDLOnTouchEvent *)sdl_applyScaleToEventCoordinates:(SDLOnTouchEvent *)onTouchEvent { + float scale = self.videoStreamingCapability.scale.floatValue; + if (scale > 1) { + for (SDLTouchEvent *touchEvent in onTouchEvent.event) { + for (SDLTouchCoord *coord in touchEvent.coord) { + coord.x = @(coord.x.floatValue / scale); + coord.y = @(coord.y.floatValue / scale); + } + } + } + return onTouchEvent; +} + #pragma mark - Private /** * Handles a BEGIN touch event sent by Core diff --git a/SmartDeviceLink/SDLVideoStreamingCapability.h b/SmartDeviceLink/SDLVideoStreamingCapability.h index c15c73a8f..bd3da80ea 100644 --- a/SmartDeviceLink/SDLVideoStreamingCapability.h +++ b/SmartDeviceLink/SDLVideoStreamingCapability.h @@ -18,7 +18,12 @@ NS_ASSUME_NONNULL_BEGIN */ @interface SDLVideoStreamingCapability : SDLRPCStruct -- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported; +- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported __deprecated_msg("Use initWithPreferredResolution:maxBitrate:supportedFormats:hapticDataSupported:diagonalScreenSize:pixelPerInch:scale: instead");; + +/** + Contains information about this system's video streaming capabilities + */ +- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported diagonalScreenSize:(float)diagonalScreenSize pixelPerInch:(float)pixelPerInch scale:(float)scale; /** The preferred resolution of a video stream for decoding and rendering on HMI @@ -48,6 +53,27 @@ NS_ASSUME_NONNULL_BEGIN */ @property (nullable, strong, nonatomic) NSNumber *hapticSpatialDataSupported; +/** + The diagonal screen size in inches. + + Optional + */ +@property (nullable, strong, nonatomic) NSNumber *diagonalScreenSize; + +/** + PPI is the diagonal resolution in pixels divided by the diagonal screen size in inches. + + Optional + */ +@property (nullable, strong, nonatomic) NSNumber *pixelPerInch; + +/** + The scaling factor the app should use to change the size of the projecting view. + + Optional + */ +@property (nullable, strong, nonatomic) NSNumber *scale; + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLVideoStreamingCapability.m b/SmartDeviceLink/SDLVideoStreamingCapability.m index 8f2d0d630..c24f698bd 100644 --- a/SmartDeviceLink/SDLVideoStreamingCapability.m +++ b/SmartDeviceLink/SDLVideoStreamingCapability.m @@ -18,6 +18,10 @@ @implementation SDLVideoStreamingCapability - (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported { + return [self initWithPreferredResolution:preferredResolution maxBitrate:maxBitrate supportedFormats:supportedFormats hapticDataSupported:hapticDataSupported diagonalScreenSize:0 pixelPerInch:0 scale:SDLVideoStreamingCapability.sdl_DefaultScale.floatValue]; +} + +- (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)preferredResolution maxBitrate:(int32_t)maxBitrate supportedFormats:(nullable NSArray *)supportedFormats hapticDataSupported:(BOOL)hapticDataSupported diagonalScreenSize:(float)diagonalScreenSize pixelPerInch:(float)pixelPerInch scale:(float)scale { self = [self init]; if (!self) { return self; @@ -27,6 +31,9 @@ - (instancetype)initWithPreferredResolution:(nullable SDLImageResolution *)prefe self.preferredResolution = preferredResolution; self.supportedFormats = supportedFormats; self.hapticSpatialDataSupported = @(hapticDataSupported); + self.diagonalScreenSize = @(diagonalScreenSize); + self.pixelPerInch = @(pixelPerInch); + self.scale = @(scale); return self; } @@ -63,6 +70,38 @@ - (void)setHapticSpatialDataSupported:(nullable NSNumber *)hapticSpatia return [self.store sdl_objectForName:SDLRPCParameterNameHapticSpatialDataSupported ofClass:NSNumber.class error:nil]; } +- (void)setDiagonalScreenSize:(nullable NSNumber *)diagonalScreenSize { + [self.store sdl_setObject:diagonalScreenSize forName:SDLRPCParameterNameDiagonalScreenSize]; +} + +- (nullable NSNumber *)diagonalScreenSize { + return [self.store sdl_objectForName:SDLRPCParameterNameDiagonalScreenSize ofClass:NSNumber.class error:nil]; +} + +- (void)setPixelPerInch:(nullable NSNumber *)pixelPerInch { + [self.store sdl_setObject:pixelPerInch forName:SDLRPCParameterNamePixelPerInch]; +} + +- (nullable NSNumber *)pixelPerInch { + return [self.store sdl_objectForName:SDLRPCParameterNamePixelPerInch ofClass:NSNumber.class error:nil]; +} + +- (void)setScale:(nullable NSNumber *)scale { + [self.store sdl_setObject:scale forName:SDLRPCParameterNameScale]; +} + +- (nullable NSNumber *)scale { + NSNumber *scale = [self.store sdl_objectForName:SDLRPCParameterNameScale ofClass:NSNumber.class error:nil]; + if (scale != nil) { + return scale; + } + return SDLVideoStreamingCapability.sdl_DefaultScale; +} + ++ (NSNumber *)sdl_DefaultScale { + return @1.0; +} + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m index 31737c214..24c2b0935 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingVideoLifecycleManagerSpec.m @@ -40,6 +40,7 @@ @interface SDLStreamingVideoLifecycleManager () @property (copy, nonatomic, readonly) NSString *appName; @property (copy, nonatomic, readonly) NSString *videoStreamBackgroundString; +@property (strong, nonatomic, readwrite) SDLVideoStreamingCapability *videoStreamingCapability; @end QuickSpecBegin(SDLStreamingVideoLifecycleManagerSpec) @@ -411,6 +412,14 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); describe(@"sending a video capabilities request", ^{ + __block SDLImageResolution *resolution = [[SDLImageResolution alloc] initWithWidth:42 height:69]; + __block int32_t maxBitrate = 12345; + __block NSArray *testFormats = @[[[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH265 protocol:SDLVideoStreamingProtocolRTMP], [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]]; + __block BOOL testHapticsSupported = YES; + __block float diagonalScreenSize = 22.0; + __block float pixelPerInch = 96.0; + __block float scale = 1.0; + beforeEach(^{ [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamManagerStateStarting fromOldState:nil callEnterTransition:YES]; }); @@ -443,22 +452,13 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream }); context(@"and receiving a response", ^{ - __block SDLImageResolution *resolution = nil; - __block int32_t maxBitrate = 0; - __block NSArray *testFormats = nil; - __block BOOL testHapticsSupported = NO; - beforeEach(^{ SDLGetSystemCapabilityResponse *response = [[SDLGetSystemCapabilityResponse alloc] init]; response.success = @YES; response.systemCapability = [[SDLSystemCapability alloc] init]; response.systemCapability.systemCapabilityType = SDLSystemCapabilityTypeVideoStreaming; - - resolution = [[SDLImageResolution alloc] initWithWidth:42 height:69]; - maxBitrate = 12345; - testFormats = @[[[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH265 protocol:SDLVideoStreamingProtocolRTMP], [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRTP]]; - testHapticsSupported = YES; - response.systemCapability.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:testFormats hapticDataSupported:testHapticsSupported]; + + response.systemCapability.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:testFormats hapticDataSupported:testHapticsSupported diagonalScreenSize:diagonalScreenSize pixelPerInch:pixelPerInch scale:scale]; [testConnectionManager respondToLastRequestWithResponse:response]; }); @@ -485,6 +485,12 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream expect(preferredResolution.resolutionHeight).to(equal(@69)); expect(preferredResolution.resolutionWidth).to(equal(@42)); }); + + it(@"should have correct video streaming capability values", ^{ + expect(streamingLifecycleManager.videoStreamingCapability.diagonalScreenSize).to(equal(22.0)); + expect(streamingLifecycleManager.videoStreamingCapability.pixelPerInch).to(equal(96.0)); + expect(streamingLifecycleManager.videoStreamingCapability.scale).to(equal(1.0)); + }); }); }); }); @@ -507,6 +513,8 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel, SDLVideoStream testVideoHeader.frameData = SDLFrameInfoStartServiceACK; testVideoHeader.encrypted = YES; testVideoHeader.serviceType = SDLServiceTypeVideo; + + streamingLifecycleManager.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:testFormats hapticDataSupported:testHapticsSupported diagonalScreenSize:diagonalScreenSize pixelPerInch:pixelPerInch scale:scale]; }); context(@"with data", ^{ diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m index 42286b97b..4e41d7c65 100755 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m @@ -33,7 +33,7 @@ testNavigationCapability = [[SDLNavigationCapability alloc] initWithSendLocation:YES waypoints:NO]; testPhoneCapability = [[SDLPhoneCapability alloc] initWithDialNumber:YES]; testRemoteControlCapabilities = [[SDLRemoteControlCapabilities alloc] initWithClimateControlCapabilities:nil radioControlCapabilities:nil buttonCapabilities:nil seatControlCapabilities:nil audioControlCapabilities:nil hmiSettingsControlCapabilities:nil lightControlCapabilities:nil]; - testVideoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:[[SDLImageResolution alloc] initWithWidth:50 height:50] maxBitrate:5 supportedFormats:@[] hapticDataSupported:false]; + testVideoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:[[SDLImageResolution alloc] initWithWidth:50 height:50] maxBitrate:5 supportedFormats:@[] hapticDataSupported:false diagonalScreenSize:22.0 pixelPerInch:96.0 scale:1.0]; }); it(@"Should set and get correctly", ^ { @@ -128,6 +128,9 @@ int32_t maxBitrate = 100; BOOL hapticDataSupported = YES; + float diagonalScreenSize = 22.0; + float pixelPerInch = 96.0; + float scale = 1.0; SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init]; format1.codec = SDLVideoStreamingCodecH264; @@ -139,7 +142,7 @@ NSArray *formatArray = @[format1, format2]; - SDLVideoStreamingCapability *testVidStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported]; + SDLVideoStreamingCapability *testVidStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported diagonalScreenSize:diagonalScreenSize pixelPerInch:pixelPerInch scale:scale]; SDLSystemCapability *testStruct = [[SDLSystemCapability alloc] initWithVideoStreamingCapability:testVidStruct]; expect(testStruct.systemCapabilityType).to(equal(SDLSystemCapabilityTypeVideoStreaming)); diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m index 7c83fe99b..f202548c6 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLVideoStreamingCapabilitySpec.m @@ -28,6 +28,9 @@ NSNumber *maxBitrate = @100; NSNumber *hapticDataSupported = @NO; + NSNumber *diagonalScreenSize = @22; + NSNumber *pixelPerInch = @96; + NSNumber *scale = @1; SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init]; format1.codec = SDLVideoStreamingCodecH264; @@ -42,7 +45,10 @@ NSMutableDictionary* dict = [@{SDLRPCParameterNamePreferredResolution: resolution, SDLRPCParameterNameMaxBitrate: maxBitrate, SDLRPCParameterNameSupportedFormats: formatArray, - SDLRPCParameterNameHapticSpatialDataSupported: hapticDataSupported} mutableCopy]; + SDLRPCParameterNameHapticSpatialDataSupported: hapticDataSupported, + SDLRPCParameterNameDiagonalScreenSize: diagonalScreenSize, + SDLRPCParameterNamePixelPerInch: pixelPerInch, + SDLRPCParameterNameScale: scale} mutableCopy]; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" SDLVideoStreamingCapability* testStruct = [[SDLVideoStreamingCapability alloc] initWithDictionary:dict]; @@ -60,6 +66,9 @@ expect(testStruct.preferredResolution).to(beNil()); expect(testStruct.maxBitrate).to(beNil()); expect(testStruct.supportedFormats).to(beNil()); + expect(testStruct.diagonalScreenSize).to(beNil()); + expect(testStruct.pixelPerInch).to(beNil()); + expect(testStruct.scale).to(equal(1)); }); it(@"Should initialize correctly with initWithVideoStreaming:maxBitrate:suportedFormats", ^ { @@ -69,6 +78,9 @@ int32_t maxBitrate = 100; NSNumber *hapticDataSupported = @YES; + float diagonalScreenSize = 22.0; + float pixelPerInch = 96.0; + float scale = 1.0; SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init]; format1.codec = SDLVideoStreamingCodecH264; @@ -80,12 +92,15 @@ NSArray *formatArray = @[format1, format2]; - SDLVideoStreamingCapability *testStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported]; + SDLVideoStreamingCapability *testStruct = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:resolution maxBitrate:maxBitrate supportedFormats:formatArray hapticDataSupported:hapticDataSupported diagonalScreenSize:diagonalScreenSize pixelPerInch:pixelPerInch scale:scale]; expect(testStruct.preferredResolution).to(equal(resolution)); expect(testStruct.maxBitrate).to(equal(maxBitrate)); expect(testStruct.supportedFormats).to(equal(formatArray)); expect(testStruct.hapticSpatialDataSupported).to(equal(hapticDataSupported)); + expect(testStruct.diagonalScreenSize).to(equal(diagonalScreenSize)); + expect(testStruct.pixelPerInch).to(equal(pixelPerInch)); + expect(testStruct.scale).to(equal(scale)); }); }); diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m index 24a06dcb0..60c43adec 100644 --- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m +++ b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m @@ -23,6 +23,8 @@ #import "SDLTouchManagerDelegate.h" #import "SDLTouchType.h" #import "SDLTouch.h" +#import "SDLVideoStreamingCapability.h" +#import "SDLImageResolution.h" @interface SDLTouchManager () @@ -263,6 +265,7 @@ __block void (^performTouchEvent)(SDLTouchManager* touchManager, SDLOnTouchEvent describe(@"When receiving a tap gesture", ^{ __block SDLTouchCoord* firstTouchCoord; + __block SDLTouchCoord* firstTouchCoordEnd; __block NSUInteger firstTouchTimeStamp; __block SDLOnTouchEvent* firstOnTouchEventStart; __block SDLOnTouchEvent* firstOnTouchEventEnd; @@ -272,19 +275,24 @@ __block void (^performTouchEvent)(SDLTouchManager* touchManager, SDLOnTouchEvent firstTouchCoord.x = @(controlPoint.x); firstTouchCoord.y = @(controlPoint.y); firstTouchTimeStamp = [[NSDate date] timeIntervalSince1970] * 1000.0; + + firstTouchCoordEnd = firstTouchCoord.copy; - SDLTouchEvent* touchEvent = [[SDLTouchEvent alloc] init]; - touchEvent.touchEventId = @0; - touchEvent.coord = [NSArray arrayWithObject:firstTouchCoord]; - touchEvent.timeStamp = [NSArray arrayWithObject:@(firstTouchTimeStamp)]; + SDLTouchEvent *touchEventStart = [[SDLTouchEvent alloc] init]; + touchEventStart.touchEventId = @0; + touchEventStart.coord = [NSArray arrayWithObject:firstTouchCoord]; + touchEventStart.timeStamp = [NSArray arrayWithObject:@(firstTouchTimeStamp)]; + + SDLTouchEvent *touchEventEnd = touchEventStart.copy; + touchEventEnd.coord = [NSArray arrayWithObject:firstTouchCoordEnd]; firstOnTouchEventStart = [[SDLOnTouchEvent alloc] init]; firstOnTouchEventStart.type = SDLTouchTypeBegin; - firstOnTouchEventStart.event = [NSArray arrayWithObject:touchEvent]; + firstOnTouchEventStart.event = [NSArray arrayWithObject:touchEventStart]; firstOnTouchEventEnd = [[SDLOnTouchEvent alloc] init]; firstOnTouchEventEnd.type = SDLTouchTypeEnd; - firstOnTouchEventEnd.event = [NSArray arrayWithObject:touchEvent]; + firstOnTouchEventEnd.event = [NSArray arrayWithObject:touchEventEnd]; }); describe(@"when receiving a single tap", ^{ @@ -309,6 +317,44 @@ __block void (^performTouchEvent)(SDLTouchManager* touchManager, SDLOnTouchEvent expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled))); }); + + it(@"should correctly use scale = 1.5 to calculate coordinates", ^{ + singleTapTests = ^(NSInvocation* invocation) { + CGPoint point; + [invocation getArgument:&point atIndex:4]; + controlPoint = CGPointMake(66.666664123535156, 133.33332824707031); + expect(@(CGPointEqualToPoint(point, controlPoint))).to(beTruthy()); + }; + + touchManager.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:[[SDLImageResolution alloc] initWithWidth:50 height:50] maxBitrate:5 supportedFormats:@[] hapticDataSupported:false diagonalScreenSize:22.0 pixelPerInch:96.0 scale:1.5]; + + performTouchEvent(touchManager, firstOnTouchEventStart); + performTouchEvent(touchManager, firstOnTouchEventEnd); + + expectedDidCallSingleTap = YES; + expectedNumTimesHandlerCalled = 2; + }); + + it(@"should correctly use scale = 0.75 to calculate coordinates", ^{ + singleTapTests = ^(NSInvocation* invocation) { + CGPoint point; + [invocation getArgument:&point atIndex:4]; + controlPoint = CGPointMake(133.33332824707031, 266.66665649414063); + expect(@(CGPointEqualToPoint(point, controlPoint))).to(beTruthy()); + }; + + touchManager.videoStreamingCapability = [[SDLVideoStreamingCapability alloc] initWithPreferredResolution:[[SDLImageResolution alloc] initWithWidth:50 height:50] maxBitrate:5 supportedFormats:@[] hapticDataSupported:false diagonalScreenSize:22.0 pixelPerInch:96.0 scale:0.75]; + + performTouchEvent(touchManager, firstOnTouchEventStart); + performTouchEvent(touchManager, firstOnTouchEventEnd); + + expectedDidCallSingleTap = YES; + expectedNumTimesHandlerCalled = 2; + }); + + afterEach(^{ + touchManager.videoStreamingCapability.scale = @(1.0); + }); }); describe(@"when receiving a single tap with small movement", ^{ @@ -355,10 +401,6 @@ __block void (^performTouchEvent)(SDLTouchManager* touchManager, SDLOnTouchEvent expectedDidCallSingleTap = YES; expectedNumTimesHandlerCalled = 3; - - expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse()); - - expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled))); }); });