Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Added support for setting a custom CarWindow screen resolution #923

Merged
merged 8 commits into from
Apr 9, 2018
1 change: 1 addition & 0 deletions SmartDeviceLink-iOS.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLStreamingMediaConfiguration.h',
'SmartDeviceLink/SDLStreamingMediaManager.h',
'SmartDeviceLink/SDLStreamingMediaManagerConstants.h',
'SmartDeviceLink/SDLStreamingMediaManagerDataSource.h',
'SmartDeviceLink/SDLSubscribeButton.h',
'SmartDeviceLink/SDLSubscribeButtonResponse.h',
'SmartDeviceLink/SDLSubscribeVehicleData.h',
Expand Down
4 changes: 2 additions & 2 deletions SmartDeviceLink-iOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@
5D8204311BD001C700D0A41B /* SDLArtwork.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D82042F1BD001C700D0A41B /* SDLArtwork.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8204321BD001C700D0A41B /* SDLArtwork.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8204301BD001C700D0A41B /* SDLArtwork.m */; };
5D850AB01D4907C500E6E7EE /* TestLockScreenAppIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 5D850AAF1D4907C500E6E7EE /* TestLockScreenAppIcon.png */; };
5D8A09811F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8A09801F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h */; };
5D8A09811F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8A09801F54B4E5002502A2 /* SDLStreamingMediaManagerDataSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8B174F1AC9D266006A6E1C /* SDLDialNumber.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8B174D1AC9D266006A6E1C /* SDLDialNumber.h */; settings = {ATTRIBUTES = (Public, ); }; };
5D8B17501AC9D266006A6E1C /* SDLDialNumber.m in Sources */ = {isa = PBXBuildFile; fileRef = 5D8B174E1AC9D266006A6E1C /* SDLDialNumber.m */; };
5D8B17531AC9E11B006A6E1C /* SDLDialNumberResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 5D8B17511AC9E11B006A6E1C /* SDLDialNumberResponse.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -2287,7 +2287,7 @@
5DBF0D5F1F3B3DB4008AF2C9 /* SDLControlFrameVideoStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFrameVideoStartServiceAckSpec.m; path = ControlFramePayloadSpecs/SDLControlFrameVideoStartServiceAckSpec.m; sourceTree = "<group>"; };
5DC09ED91F2F7FEC00F4AB1D /* SDLControlFramePayloadNakSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLControlFramePayloadNakSpec.m; path = ControlFramePayloadSpecs/SDLControlFramePayloadNakSpec.m; sourceTree = "<group>"; };
5DC978251B7A38640012C2F1 /* SDLGlobalsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLGlobalsSpec.m; path = UtilitiesSpecs/SDLGlobalsSpec.m; sourceTree = "<group>"; };
5DCA93821EE0844D0015768E /* SmartDeviceLink.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SmartDeviceLink.podspec; sourceTree = SOURCE_ROOT; };
5DCA93821EE0844D0015768E /* SmartDeviceLink.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = SmartDeviceLink.podspec; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
5DCD7ADC1FCCA8D100A0FC7F /* SDLCarWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLCarWindow.h; sourceTree = "<group>"; };
5DCD7ADD1FCCA8D200A0FC7F /* SDLCarWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLCarWindow.m; sourceTree = "<group>"; };
5DCD7AE61FCCA8E400A0FC7F /* SDLScreenshotViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLScreenshotViewController.h; sourceTree = "<group>"; };
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
1 change: 1 addition & 0 deletions SmartDeviceLink.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ ss.public_header_files = [
'SmartDeviceLink/SDLStreamingMediaConfiguration.h',
'SmartDeviceLink/SDLStreamingMediaManager.h',
'SmartDeviceLink/SDLStreamingMediaManagerConstants.h',
'SmartDeviceLink/SDLStreamingMediaManagerDataSource.h',
'SmartDeviceLink/SDLSubscribeButton.h',
'SmartDeviceLink/SDLSubscribeButtonResponse.h',
'SmartDeviceLink/SDLSubscribeVehicleData.h',
Expand Down
23 changes: 18 additions & 5 deletions SmartDeviceLink/SDLStreamingMediaLifecycleManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -347,23 +347,22 @@ - (void)didEnterStateVideoStreamStarting {
SDLLogV(@"Capability: %@", capability);

if (capability != nil) {
// If we got a response, get our preferred formats and resolutions
// If we got a response, get the head unit's preferred formats and resolutions
weakSelf.preferredFormats = capability.supportedFormats;
weakSelf.preferredResolutions = @[capability.preferredResolution];

if (weakSelf.dataSource != nil) {
SDLLogV(@"Calling data source for modified preferred formats and resolutions");
SDLLogV(@"Calling data source for modified preferred formats");
weakSelf.preferredFormats = [weakSelf.dataSource preferredVideoFormatOrderFromHeadUnitPreferredOrder:weakSelf.preferredFormats];
weakSelf.preferredResolutions = [weakSelf.dataSource resolutionFromHeadUnitPreferredResolution:weakSelf.preferredResolutions.firstObject];
}

if (weakSelf.focusableItemManager != nil) {
weakSelf.focusableItemManager.enableHapticDataRequests = capability.hapticSpatialDataSupported.boolValue;
}

SDLLogD(@"Got specialized video capabilites, preferred formats: %@, resolutions: %@ haptics enabled %@", weakSelf.preferredFormats, weakSelf.preferredResolutions, (capability.hapticSpatialDataSupported.boolValue ? @"YES" : @"NO"));
SDLLogD(@"Got specialized video capabilites, preferred formats: %@, haptics enabled %@", weakSelf.preferredFormats, (capability.hapticSpatialDataSupported.boolValue ? @"YES" : @"NO"));
} else {
// If we can't get capabilities, we're assuming it's H264 RAW at whatever the display capabilities said in the RAIR. We also aren't going to call the data source because they have no options.
// If no response, assume that the format is H264 RAW and get the screen resolution from the RAI response's display capabilities.
SDLVideoStreamingFormat *format = [[SDLVideoStreamingFormat alloc] initWithCodec:SDLVideoStreamingCodecH264 protocol:SDLVideoStreamingProtocolRAW];
SDLImageResolution *resolution = [[SDLImageResolution alloc] initWithWidth:(uint16_t)weakSelf.screenSize.width height:(uint16_t)weakSelf.screenSize.height];
weakSelf.preferredFormats = @[format];
Expand All @@ -376,6 +375,12 @@ - (void)didEnterStateVideoStreamStarting {
SDLLogD(@"Using generic video capabilites, preferred formats: %@, resolutions: %@, haptics disabled", weakSelf.preferredFormats, weakSelf.preferredResolutions);
}

if (weakSelf.dataSource != nil) {
SDLLogV(@"Calling data source for modified preferred resolutions");
weakSelf.preferredResolutions = [weakSelf.dataSource resolutionFromHeadUnitPreferredResolution:weakSelf.preferredResolutions.firstObject];
SDLLogD(@"Got specialized video resolutions: %@", weakSelf.preferredResolutions);
}

[self sdl_sendVideoStartService];
}];
}
Expand Down Expand Up @@ -518,6 +523,14 @@ - (void)sdl_handleVideoStartServiceAck:(SDLProtocolMessage *)videoStartServiceAc
// This is the definitive screen size that will be used
if (videoAckPayload.height != SDLControlFrameInt32NotFound && videoAckPayload.width != SDLControlFrameInt32NotFound) {
_screenSize = 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;
CGSize newScreenSize = CGSizeMake(preferredResolution.resolutionWidth.floatValue, preferredResolution.resolutionHeight.floatValue);
if (!CGSizeEqualToSize(self.screenSize, newScreenSize)) {
SDLLogW(@"The preferred resolution does not match the screen dimensions returned by the Register App Interface Response. Video may look distorted or video may not show up on the head unit");
_screenSize = CGSizeMake(preferredResolution.resolutionWidth.floatValue, preferredResolution.resolutionHeight.floatValue);
}
} // else we are using the screen size we got from the RAIR earlier

// Figure out the definitive format that will be used. If the protocol / codec weren't passed in the payload, it's probably a system that doesn't support those properties, which also means it's a system that requires H.264 RAW encoding
Expand Down
1 change: 1 addition & 0 deletions SmartDeviceLink/SmartDeviceLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[];
#import "SDLTouchManager.h"
#import "SDLTouchManagerDelegate.h"
#import "SDLSecurityType.h"
#import "SDLStreamingMediaManagerDataSource.h"

// Files
#import "SDLArtwork.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ @interface SDLSoftButtonManager()

QuickSpecBegin(SDLSoftButtonManagerSpec)

fdescribe(@"a soft button manager", ^{
describe(@"a soft button manager", ^{
__block SDLSoftButtonManager *testManager = nil;

__block SDLFileManager *testFileManager = nil;
Expand Down
42 changes: 42 additions & 0 deletions SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,48 @@ __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILeve
expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady));
});
});

context(@"with missing screen height and screen width values", ^{
__block SDLImageResolution *preferredResolutionLow = nil;
__block SDLImageResolution *preferredResolutionHigh = nil;


beforeEach(^{
preferredResolutionLow = [[SDLImageResolution alloc] initWithWidth:10 height:10];
preferredResolutionHigh = [[SDLImageResolution alloc] initWithWidth:100 height:100];
streamingLifecycleManager.preferredResolutions = @[preferredResolutionLow, preferredResolutionHigh];

testVideoStartServicePayload = [[SDLControlFramePayloadVideoStartServiceAck alloc] initWithMTU:testMTU height:SDLControlFrameInt32NotFound width:SDLControlFrameInt32NotFound protocol:nil codec:nil];
testVideoMessage = [[SDLV2ProtocolMessage alloc] initWithHeader:testVideoHeader andPayload:testVideoStartServicePayload.data];

expect(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero));
});

context(@"If the data source is nil", ^{
beforeEach(^{
streamingLifecycleManager.dataSource = nil;
[streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage];
});

it(@"should not replace the existing screen resolution", ^{
expect(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero));
expect(streamingLifecycleManager.dataSource).to(beNil());
});
});

context(@"If the preferred resolution was set in the data source", ^{
beforeEach(^{
streamingLifecycleManager.dataSource = testDataSource;
[streamingLifecycleManager handleProtocolStartServiceACKMessage:testVideoMessage];
});

it(@"should set the screen size using the first provided preferred resolution", ^{
CGSize preferredFormat = CGSizeMake(preferredResolutionLow.resolutionWidth.floatValue, preferredResolutionLow.resolutionHeight.floatValue);
expect(CGSizeEqualToSize(streamingLifecycleManager.screenSize, preferredFormat));
expect(streamingLifecycleManager.dataSource).toNot(beNil());
});
});
});
});

describe(@"after receiving a Video Start NAK", ^{
Expand Down