diff options
author | Joel Fischer <joeljfischer@gmail.com> | 2017-08-18 10:35:14 -0400 |
---|---|---|
committer | Joel Fischer <joeljfischer@gmail.com> | 2017-08-18 10:35:14 -0400 |
commit | 493b36f11b2b618bd9a3c86ff4a57e8cf096b37c (patch) | |
tree | f8b97dfda0fcd30a3b123c03eab83e6bd3fdd948 | |
parent | e516eabe852c637bb2499a96ce14278f9c70f83c (diff) | |
parent | e6848c716f3b0768ded3c298c5c67a5ecbd8a855 (diff) | |
download | sdl_ios-493b36f11b2b618bd9a3c86ff4a57e8cf096b37c.tar.gz |
Merge branch 'release/5.0.0' into feature/SDL_0075_OEM_specific_HID_support_5.0
# Conflicts:
# SmartDeviceLink-iOS.podspec
# SmartDeviceLink-iOS.xcodeproj/project.pbxproj
# SmartDeviceLink.podspec
61 files changed, 3393 insertions, 1237 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c320da23..deab4e0bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 5.0.0 Release Notes (in-progress) +### Breaking Changes +* `SDLProxy streamingMediaManager` is now removed. If you wish to use a streaming media manager, you must use the `streamingMediaManager` on `SDLManager`. + # 4.6.1 Release Notes ### Bug Fixes * Fixes a bug where an app would crash if connected while the app is foregrounded and the vehicle is already in motion. diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec index 2f39e4bc3..e9021321c 100644 --- a/SmartDeviceLink-iOS.podspec +++ b/SmartDeviceLink-iOS.podspec @@ -7,6 +7,7 @@ s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS" s.license = { :type => "New BSD", :file => "LICENSE" } s.author = { "SmartDeviceLink Team" => "developer@smartdevicelink.com" } s.platform = :ios, "8.0" +s.dependency 'BiSON', '~> 1.0' s.source = { :git => "https://github.com/smartdevicelink/sdl_ios.git", :tag => s.version.to_s } s.requires_arc = true s.resource_bundles = { 'SmartDeviceLink' => ['SmartDeviceLink/Assets/**/*'] } @@ -17,293 +18,297 @@ s.subspec 'Default' do |ss| ss.source_files = 'SmartDeviceLink/*.{h,m}' ss.public_header_files = [ -'SmartDeviceLink/SmartDeviceLink.h', -'SmartDeviceLink/SDLJingle.h', -'SmartDeviceLink/SDLProxy.h', -'SmartDeviceLink/SDLProxyFactory.h', -'SmartDeviceLink/SDLProxyListener.h', -'SmartDeviceLink/SDLSecurityType.h', -'SmartDeviceLink/SDLStreamingMediaManager.h', -'SmartDeviceLink/SDLTouchManager.h', -'SmartDeviceLink/SDLTouchManagerDelegate.h', -'SmartDeviceLink/SDLSiphonServer.h', -'SmartDeviceLink/SDLAbstractTransport.h', -'SmartDeviceLink/SDLIAPSessionDelegate.h', -'SmartDeviceLink/SDLIAPTransport.h', -'SmartDeviceLink/SDLTCPTransport.h', -'SmartDeviceLink/SDLTransportDelegate.h', +'SmartDeviceLink/NSNumber+NumberType.h', 'SmartDeviceLink/SDLAbstractProtocol.h', -'SmartDeviceLink/SDLProtocol.h', -'SmartDeviceLink/SDLProtocolListener.h', -'SmartDeviceLink/SDLProtocolHeader.h', -'SmartDeviceLink/SDLProtocolMessage.h', -'SmartDeviceLink/SDLEnum.h', -'SmartDeviceLink/SDLRPCMessage.h', -'SmartDeviceLink/SDLRPCNotification.h', -'SmartDeviceLink/SDLRPCRequest.h', -'SmartDeviceLink/SDLRPCResponse.h', -'SmartDeviceLink/SDLRPCStruct.h', +'SmartDeviceLink/SDLAbstractTransport.h', 'SmartDeviceLink/SDLAddCommand.h', +'SmartDeviceLink/SDLAddCommandResponse.h', 'SmartDeviceLink/SDLAddSubMenu.h', +'SmartDeviceLink/SDLAddSubMenuResponse.h', +'SmartDeviceLink/SDLAirbagStatus.h', 'SmartDeviceLink/SDLAlert.h', 'SmartDeviceLink/SDLAlertManeuver.h', -'SmartDeviceLink/SDLChangeRegistration.h', -'SmartDeviceLink/SDLCreateInteractionChoiceSet.h', -'SmartDeviceLink/SDLDeleteCommand.h', -'SmartDeviceLink/SDLDeleteFile.h', -'SmartDeviceLink/SDLDeleteInteractionChoiceSet.h', -'SmartDeviceLink/SDLDeleteSubMenu.h', -'SmartDeviceLink/SDLDiagnosticMessage.h', -'SmartDeviceLink/SDLDialNumber.h', -'SmartDeviceLink/SDLEncodedSyncPData.h', -'SmartDeviceLink/SDLEndAudioPassThru.h', -'SmartDeviceLink/SDLGetDTCs.h', -'SmartDeviceLink/SDLGetSystemCapability.h', -'SmartDeviceLink/SDLGetVehicleData.h', -'SmartDeviceLink/SDLGetWaypoints.h', -'SmartDeviceLink/SDLListFiles.h', -'SmartDeviceLink/SDLMacros.h', -'SmartDeviceLink/SDLPerformAudioPassThru.h', -'SmartDeviceLink/SDLPerformInteraction.h', -'SmartDeviceLink/SDLPutFile.h', -'SmartDeviceLink/SDLReadDID.h', -'SmartDeviceLink/SDLRegisterAppInterface.h', -'SmartDeviceLink/SDLResetGlobalProperties.h', -'SmartDeviceLink/SDLScrollableMessage.h', -'SmartDeviceLink/SDLSendHapticData.h', -'SmartDeviceLink/SDLSendLocation.h', -'SmartDeviceLink/SDLSetAppIcon.h', -'SmartDeviceLink/SDLSetDisplayLayout.h', -'SmartDeviceLink/SDLSetGlobalProperties.h', -'SmartDeviceLink/SDLSetMediaClockTimer.h', -'SmartDeviceLink/SDLShow.h', -'SmartDeviceLink/SDLShowConstantTBT.h', -'SmartDeviceLink/SDLSlider.h', -'SmartDeviceLink/SDLSpeak.h', -'SmartDeviceLink/SDLSubscribeButton.h', -'SmartDeviceLink/SDLSubscribeVehicleData.h', -'SmartDeviceLink/SDLSubscribeWaypoints.h', -'SmartDeviceLink/SDLSyncPData.h', -'SmartDeviceLink/SDLUnregisterAppInterface.h', -'SmartDeviceLink/SDLUnsubscribeButton.h', -'SmartDeviceLink/SDLUnsubscribeVehicleData.h', -'SmartDeviceLink/SDLUnsubscribeWaypoints.h', -'SmartDeviceLink/SDLUpdateTurnList.h', -'SmartDeviceLink/SDLAddCommandResponse.h', -'SmartDeviceLink/SDLAddSubMenuResponse.h', 'SmartDeviceLink/SDLAlertManeuverResponse.h', 'SmartDeviceLink/SDLAlertResponse.h', -'SmartDeviceLink/SDLChangeRegistrationResponse.h', -'SmartDeviceLink/SDLCreateInteractionChoiceSetResponse.h', -'SmartDeviceLink/SDLDeleteCommandResponse.h', -'SmartDeviceLink/SDLDeleteFileResponse.h', -'SmartDeviceLink/SDLDeleteInteractionChoiceSetResponse.h', -'SmartDeviceLink/SDLDeleteSubMenuResponse.h', -'SmartDeviceLink/SDLDiagnosticMessageResponse.h', -'SmartDeviceLink/SDLDialNumberResponse.h', -'SmartDeviceLink/SDLEncodedSyncPDataResponse.h', -'SmartDeviceLink/SDLEndAudioPassThruResponse.h', -'SmartDeviceLink/SDLGenericResponse.h', -'SmartDeviceLink/SDLGetDTCsResponse.h', -'SmartDeviceLink/SDLGetSystemCapabilityResponse.h', -'SmartDeviceLink/SDLGetVehicleDataResponse.h', -'SmartDeviceLink/SDLGetWaypointsResponse.h', -'SmartDeviceLink/SDLListFilesResponse.h', -'SmartDeviceLink/SDLPerformAudioPassThruResponse.h', -'SmartDeviceLink/SDLPerformInteractionResponse.h', -'SmartDeviceLink/SDLPutFileResponse.h', -'SmartDeviceLink/SDLReadDIDResponse.h', -'SmartDeviceLink/SDLRegisterAppInterfaceResponse.h', -'SmartDeviceLink/SDLResetGlobalPropertiesResponse.h', -'SmartDeviceLink/SDLScrollableMessageResponse.h', -'SmartDeviceLink/SDLSendHapticDataResponse.h', -'SmartDeviceLink/SDLSendLocationResponse.h', -'SmartDeviceLink/SDLSetAppIconResponse.h', -'SmartDeviceLink/SDLSetDisplayLayoutResponse.h', -'SmartDeviceLink/SDLSetGlobalPropertiesResponse.h', -'SmartDeviceLink/SDLSetMediaClockTimerResponse.h', -'SmartDeviceLink/SDLShowConstantTBTResponse.h', -'SmartDeviceLink/SDLShowResponse.h', -'SmartDeviceLink/SDLSliderResponse.h', -'SmartDeviceLink/SDLSpeakResponse.h', -'SmartDeviceLink/SDLSubscribeButtonResponse.h', -'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h', -'SmartDeviceLink/SDLSubscribeWaypointsResponse.h', -'SmartDeviceLink/SDLSyncPDataResponse.h', -'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h', -'SmartDeviceLink/SDLUnsubscribeButtonResponse.h', -'SmartDeviceLink/SDLUnsubscribeVehicleDataResponse.h', -'SmartDeviceLink/SDLUnsubscribeWaypointsResponse.h', -'SmartDeviceLink/SDLUpdateTurnListResponse.h', -'SmartDeviceLink/SDLOnAppInterfaceUnregistered.h', -'SmartDeviceLink/SDLOnAudioPassThru.h', -'SmartDeviceLink/SDLOnButtonEvent.h', -'SmartDeviceLink/SDLOnButtonPress.h', -'SmartDeviceLink/SDLOnCommand.h', -'SmartDeviceLink/SDLOnDriverDistraction.h', -'SmartDeviceLink/SDLOnEncodedSyncPData.h', -'SmartDeviceLink/SDLOnHMIStatus.h', -'SmartDeviceLink/SDLOnHashChange.h', -'SmartDeviceLink/SDLOnKeyboardInput.h', -'SmartDeviceLink/SDLOnLanguageChange.h', -'SmartDeviceLink/SDLOnLockScreenStatus.h', -'SmartDeviceLink/SDLOnPermissionsChange.h', -'SmartDeviceLink/SDLOnSyncPData.h', -'SmartDeviceLink/SDLOnSystemRequest.h', -'SmartDeviceLink/SDLOnTBTClientState.h', -'SmartDeviceLink/SDLOnTouchEvent.h', -'SmartDeviceLink/SDLOnVehicleData.h', -'SmartDeviceLink/SDLOnWaypointChange.h', -'SmartDeviceLink/SDLAirbagStatus.h', -'SmartDeviceLink/SDLAppInfo.h', -'SmartDeviceLink/SDLAudioPassThruCapabilities.h', -'SmartDeviceLink/SDLBeltStatus.h', -'SmartDeviceLink/SDLBodyInformation.h', -'SmartDeviceLink/SDLButtonCapabilities.h', -'SmartDeviceLink/SDLChoice.h', -'SmartDeviceLink/SDLClusterModeStatus.h', -'SmartDeviceLink/SDLDIDResult.h', -'SmartDeviceLink/SDLDateTime.h', -'SmartDeviceLink/SDLDeviceInfo.h', -'SmartDeviceLink/SDLDeviceStatus.h', -'SmartDeviceLink/SDLDisplayCapabilities.h', -'SmartDeviceLink/SDLECallInfo.h', -'SmartDeviceLink/SDLEmergencyEvent.h', -'SmartDeviceLink/SDLGPSData.h', -'SmartDeviceLink/SDLHMICapabilities.h', -'SmartDeviceLink/SDLHMIPermissions.h', -'SmartDeviceLink/SDLHeadLampStatus.h', -'SmartDeviceLink/SDLImage.h', -'SmartDeviceLink/SDLImageField.h', -'SmartDeviceLink/SDLImageResolution.h', -'SmartDeviceLink/SDLKeyboardProperties.h', -'SmartDeviceLink/SDLMenuParams.h', -'SmartDeviceLink/SDLMyKey.h', -'SmartDeviceLink/SDLNavigationCapability.h', -'SmartDeviceLink/SDLOasisAddress.h', -'SmartDeviceLink/SDLParameterPermissions.h', -'SmartDeviceLink/SDLPermissionItem.h', -'SmartDeviceLink/SDLPhoneCapability.h', -'SmartDeviceLink/SDLPresetBankCapabilities.h', -'SmartDeviceLink/SDLScreenParams.h', -'SmartDeviceLink/SDLSingleTireStatus.h', -'SmartDeviceLink/SDLSoftButton.h', -'SmartDeviceLink/SDLSoftButtonCapabilities.h', -'SmartDeviceLink/SDLSpatialStruct.h', -'SmartDeviceLink/SDLStartTime.h', -'SmartDeviceLink/SDLSyncMsgVersion.h', -'SmartDeviceLink/SDLSystemCapability.h', -'SmartDeviceLink/SDLTTSChunk.h', -'SmartDeviceLink/SDLTextField.h', -'SmartDeviceLink/SDLTireStatus.h', -'SmartDeviceLink/SDLTouchCoord.h', -'SmartDeviceLink/SDLTouchEvent.h', -'SmartDeviceLink/SDLTouchEventCapabilities.h', -'SmartDeviceLink/SDLTurn.h', -'SmartDeviceLink/SDLVRHelpItem.h', -'SmartDeviceLink/SDLVehicleDataResult.h', -'SmartDeviceLink/SDLVehicleType.h', 'SmartDeviceLink/SDLAmbientLightStatus.h', 'SmartDeviceLink/SDLAppHMIType.h', +'SmartDeviceLink/SDLAppInfo.h', 'SmartDeviceLink/SDLAppInterfaceUnregisteredReason.h', +'SmartDeviceLink/SDLArtwork.h', +'SmartDeviceLink/SDLAudioPassThruCapabilities.h', 'SmartDeviceLink/SDLAudioStreamingState.h', 'SmartDeviceLink/SDLAudioType.h', +'SmartDeviceLink/SDLBeltStatus.h', 'SmartDeviceLink/SDLBitsPerSample.h', +'SmartDeviceLink/SDLBodyInformation.h', +'SmartDeviceLink/SDLButtonCapabilities.h', 'SmartDeviceLink/SDLButtonEventMode.h', 'SmartDeviceLink/SDLButtonName.h', 'SmartDeviceLink/SDLButtonPressMode.h', 'SmartDeviceLink/SDLCarModeStatus.h', +'SmartDeviceLink/SDLChangeRegistration.h', +'SmartDeviceLink/SDLChangeRegistrationResponse.h', 'SmartDeviceLink/SDLCharacterSet.h', +'SmartDeviceLink/SDLChoice.h', +'SmartDeviceLink/SDLClusterModeStatus.h', 'SmartDeviceLink/SDLCompassDirection.h', 'SmartDeviceLink/SDLComponentVolumeStatus.h', +'SmartDeviceLink/SDLConfiguration.h', +'SmartDeviceLink/SDLCreateInteractionChoiceSet.h', +'SmartDeviceLink/SDLCreateInteractionChoiceSetResponse.h', +'SmartDeviceLink/SDLDateTime.h', +'SmartDeviceLink/SDLDeleteCommand.h', +'SmartDeviceLink/SDLDeleteCommandResponse.h', +'SmartDeviceLink/SDLDeleteFile.h', +'SmartDeviceLink/SDLDeleteFileResponse.h', +'SmartDeviceLink/SDLDeleteInteractionChoiceSet.h', +'SmartDeviceLink/SDLDeleteInteractionChoiceSetResponse.h', +'SmartDeviceLink/SDLDeleteSubMenu.h', +'SmartDeviceLink/SDLDeleteSubMenuResponse.h', 'SmartDeviceLink/SDLDeliveryMode.h', +'SmartDeviceLink/SDLDeviceInfo.h', 'SmartDeviceLink/SDLDeviceLevelStatus.h', +'SmartDeviceLink/SDLDeviceStatus.h', +'SmartDeviceLink/SDLDiagnosticMessage.h', +'SmartDeviceLink/SDLDiagnosticMessageResponse.h', +'SmartDeviceLink/SDLDialNumber.h', +'SmartDeviceLink/SDLDialNumberResponse.h', +'SmartDeviceLink/SDLDIDResult.h', 'SmartDeviceLink/SDLDimension.h', +'SmartDeviceLink/SDLDisplayCapabilities.h', 'SmartDeviceLink/SDLDisplayType.h', 'SmartDeviceLink/SDLDriverDistractionState.h', 'SmartDeviceLink/SDLECallConfirmationStatus.h', +'SmartDeviceLink/SDLECallInfo.h', +'SmartDeviceLink/SDLEmergencyEvent.h', 'SmartDeviceLink/SDLEmergencyEventType.h', +'SmartDeviceLink/SDLEncodedSyncPData.h', +'SmartDeviceLink/SDLEncodedSyncPDataResponse.h', +'SmartDeviceLink/SDLEndAudioPassThru.h', +'SmartDeviceLink/SDLEndAudioPassThruResponse.h', +'SmartDeviceLink/SDLEnum.h', +'SmartDeviceLink/SDLErrorConstants.h', +'SmartDeviceLink/SDLFile.h', +'SmartDeviceLink/SDLFileManager.h', +'SmartDeviceLink/SDLFileManagerConstants.h', 'SmartDeviceLink/SDLFileType.h', 'SmartDeviceLink/SDLFuelCutoffStatus.h', +'SmartDeviceLink/SDLGenericResponse.h', +'SmartDeviceLink/SDLGetDTCs.h', +'SmartDeviceLink/SDLGetDTCsResponse.h', +'SmartDeviceLink/SDLGetSystemCapability.h', +'SmartDeviceLink/SDLGetSystemCapabilityResponse.h', +'SmartDeviceLink/SDLGetVehicleData.h', +'SmartDeviceLink/SDLGetVehicleDataResponse.h', +'SmartDeviceLink/SDLGetWaypoints.h', +'SmartDeviceLink/SDLGetWaypointsResponse.h', 'SmartDeviceLink/SDLGlobalProperty.h', +'SmartDeviceLink/SDLGPSData.h', +'SmartDeviceLink/SDLHeadLampStatus.h', +'SmartDeviceLink/SDLHMICapabilities.h', 'SmartDeviceLink/SDLHMILevel.h', +'SmartDeviceLink/SDLHMIPermissions.h', 'SmartDeviceLink/SDLHMIZoneCapabilities.h', +'SmartDeviceLink/SDLIAPSessionDelegate.h', +'SmartDeviceLink/SDLIAPTransport.h', 'SmartDeviceLink/SDLIgnitionStableStatus.h', 'SmartDeviceLink/SDLIgnitionStatus.h', +'SmartDeviceLink/SDLImage.h', +'SmartDeviceLink/SDLImageField.h', 'SmartDeviceLink/SDLImageFieldName.h', +'SmartDeviceLink/SDLImageResolution.h', 'SmartDeviceLink/SDLImageType.h', 'SmartDeviceLink/SDLInteractionMode.h', 'SmartDeviceLink/SDLKeyboardEvent.h', 'SmartDeviceLink/SDLKeyboardLayout.h', +'SmartDeviceLink/SDLKeyboardProperties.h', 'SmartDeviceLink/SDLKeypressMode.h', 'SmartDeviceLink/SDLLanguage.h', 'SmartDeviceLink/SDLLayoutMode.h', +'SmartDeviceLink/SDLLifecycleConfiguration.h', +'SmartDeviceLink/SDLListFiles.h', +'SmartDeviceLink/SDLListFilesResponse.h', 'SmartDeviceLink/SDLLocationCoordinate.h', 'SmartDeviceLink/SDLLocationDetails.h', +'SmartDeviceLink/SDLLockScreenConfiguration.h', 'SmartDeviceLink/SDLLockScreenStatus.h', +'SmartDeviceLink/SDLLockScreenViewController.h', +'SmartDeviceLink/SDLLogConfiguration.h', +'SmartDeviceLink/SDLLogConstants.h', +'SmartDeviceLink/SDLLogFileModule.h', +'SmartDeviceLink/SDLLogFilter.h', +'SmartDeviceLink/SDLLogMacros.h', +'SmartDeviceLink/SDLLogManager.h', +'SmartDeviceLink/SDLLogTarget.h', +'SmartDeviceLink/SDLLogTargetAppleSystemLog.h', +'SmartDeviceLink/SDLLogTargetFile.h', +'SmartDeviceLink/SDLLogTargetOSLog.h', +'SmartDeviceLink/SDLMacros.h', 'SmartDeviceLink/SDLMaintenanceModeStatus.h', +'SmartDeviceLink/SDLManager.h', +'SmartDeviceLink/SDLManagerDelegate.h', 'SmartDeviceLink/SDLMediaClockFormat.h', -'SmartDeviceLink/SDLPRNDL.h', +'SmartDeviceLink/SDLMenuParams.h', +'SmartDeviceLink/SDLMetadataTags.h', +'SmartDeviceLink/SDLMetadataType.h', +'SmartDeviceLink/SDLMyKey.h', +'SmartDeviceLink/SDLNavigationCapability.h', +'SmartDeviceLink/SDLNotificationConstants.h', +'SmartDeviceLink/SDLOasisAddress.h', +'SmartDeviceLink/SDLOnAppInterfaceUnregistered.h', +'SmartDeviceLink/SDLOnAudioPassThru.h', +'SmartDeviceLink/SDLOnButtonEvent.h', +'SmartDeviceLink/SDLOnButtonPress.h', +'SmartDeviceLink/SDLOnCommand.h', +'SmartDeviceLink/SDLOnDriverDistraction.h', +'SmartDeviceLink/SDLOnEncodedSyncPData.h', +'SmartDeviceLink/SDLOnHashChange.h', +'SmartDeviceLink/SDLOnHMIStatus.h', +'SmartDeviceLink/SDLOnKeyboardInput.h', +'SmartDeviceLink/SDLOnLanguageChange.h', +'SmartDeviceLink/SDLOnLockScreenStatus.h', +'SmartDeviceLink/SDLOnPermissionsChange.h', +'SmartDeviceLink/SDLOnSyncPData.h', +'SmartDeviceLink/SDLOnSystemRequest.h', +'SmartDeviceLink/SDLOnTBTClientState.h', +'SmartDeviceLink/SDLOnTouchEvent.h', +'SmartDeviceLink/SDLOnVehicleData.h', +'SmartDeviceLink/SDLOnWaypointChange.h', +'SmartDeviceLink/SDLParameterPermissions.h', +'SmartDeviceLink/SDLPerformAudioPassThru.h', +'SmartDeviceLink/SDLPerformAudioPassThruResponse.h', +'SmartDeviceLink/SDLPerformInteraction.h', +'SmartDeviceLink/SDLPerformInteractionResponse.h', +'SmartDeviceLink/SDLPermissionConstants.h', +'SmartDeviceLink/SDLPermissionItem.h', +'SmartDeviceLink/SDLPermissionManager.h', 'SmartDeviceLink/SDLPermissionStatus.h', +'SmartDeviceLink/SDLPhoneCapability.h', +'SmartDeviceLink/SDLPinchGesture.h', 'SmartDeviceLink/SDLPowerModeQualificationStatus.h', 'SmartDeviceLink/SDLPowerModeStatus.h', 'SmartDeviceLink/SDLPredefinedLayout.h', 'SmartDeviceLink/SDLPrerecordedSpeech.h', +'SmartDeviceLink/SDLPresetBankCapabilities.h', 'SmartDeviceLink/SDLPrimaryAudioSource.h', -'SmartDeviceLink/SDLRPCMessageType.h', +'SmartDeviceLink/SDLPRNDL.h', +'SmartDeviceLink/SDLProtocol.h', +'SmartDeviceLink/SDLProtocolHeader.h', +'SmartDeviceLink/SDLProtocolListener.h', +'SmartDeviceLink/SDLProtocolMessage.h', +'SmartDeviceLink/SDLProxy.h', +'SmartDeviceLink/SDLProxyFactory.h', +'SmartDeviceLink/SDLProxyListener.h', +'SmartDeviceLink/SDLPutFile.h', +'SmartDeviceLink/SDLPutFileResponse.h', +'SmartDeviceLink/SDLReadDID.h', +'SmartDeviceLink/SDLReadDIDResponse.h', +'SmartDeviceLink/SDLRegisterAppInterface.h', +'SmartDeviceLink/SDLRegisterAppInterfaceResponse.h', 'SmartDeviceLink/SDLRequestType.h', +'SmartDeviceLink/SDLResetGlobalProperties.h', +'SmartDeviceLink/SDLResetGlobalPropertiesResponse.h', 'SmartDeviceLink/SDLResult.h', +'SmartDeviceLink/SDLRPCMessage.h', +'SmartDeviceLink/SDLRPCMessageType.h', +'SmartDeviceLink/SDLRPCNotification.h', +'SmartDeviceLink/SDLRPCNotificationNotification.h', +'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCResponse.h', +'SmartDeviceLink/SDLRPCResponseNotification.h', +'SmartDeviceLink/SDLRPCStruct.h', 'SmartDeviceLink/SDLSamplingRate.h', +'SmartDeviceLink/SDLScreenParams.h', +'SmartDeviceLink/SDLScrollableMessage.h', +'SmartDeviceLink/SDLScrollableMessageResponse.h', +'SmartDeviceLink/SDLSecurityType.h', +'SmartDeviceLink/SDLSendLocation.h', +'SmartDeviceLink/SDLSendLocationResponse.h', +'SmartDeviceLink/SDLSetAppIcon.h', +'SmartDeviceLink/SDLSetAppIconResponse.h', +'SmartDeviceLink/SDLSetDisplayLayout.h', +'SmartDeviceLink/SDLSetDisplayLayoutResponse.h', +'SmartDeviceLink/SDLSetGlobalProperties.h', +'SmartDeviceLink/SDLSetGlobalPropertiesResponse.h', +'SmartDeviceLink/SDLSetMediaClockTimer.h', +'SmartDeviceLink/SDLSetMediaClockTimerResponse.h', +'SmartDeviceLink/SDLShow.h', +'SmartDeviceLink/SDLShowConstantTBT.h', +'SmartDeviceLink/SDLShowConstantTBTResponse.h', +'SmartDeviceLink/SDLShowResponse.h', +'SmartDeviceLink/SDLSingleTireStatus.h', +'SmartDeviceLink/SDLSlider.h', +'SmartDeviceLink/SDLSliderResponse.h', +'SmartDeviceLink/SDLSoftButton.h', +'SmartDeviceLink/SDLSoftButtonCapabilities.h', 'SmartDeviceLink/SDLSoftButtonType.h', +'SmartDeviceLink/SDLSpeak.h', +'SmartDeviceLink/SDLSpeakResponse.h', 'SmartDeviceLink/SDLSpeechCapabilities.h', +'SmartDeviceLink/SDLStartTime.h', +'SmartDeviceLink/SDLStreamingMediaConfiguration.h', +'SmartDeviceLink/SDLStreamingMediaManager.h', +'SmartDeviceLink/SDLStreamingMediaManagerConstants.h', +'SmartDeviceLink/SDLSubscribeButton.h', +'SmartDeviceLink/SDLSubscribeButtonResponse.h', +'SmartDeviceLink/SDLSubscribeVehicleData.h', +'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h', +'SmartDeviceLink/SDLSubscribeWaypoints.h', +'SmartDeviceLink/SDLSubscribeWaypointsResponse.h', +'SmartDeviceLink/SDLSyncMsgVersion.h', +'SmartDeviceLink/SDLSyncPData.h', +'SmartDeviceLink/SDLSyncPDataResponse.h', 'SmartDeviceLink/SDLSystemAction.h', +'SmartDeviceLink/SDLSystemCapability.h', 'SmartDeviceLink/SDLSystemCapabilityType.h', 'SmartDeviceLink/SDLSystemContext.h', 'SmartDeviceLink/SDLTBTState.h', +'SmartDeviceLink/SDLTCPTransport.h', 'SmartDeviceLink/SDLTextAlignment.h', +'SmartDeviceLink/SDLTextField.h', 'SmartDeviceLink/SDLTextFieldName.h', 'SmartDeviceLink/SDLTimerMode.h', +'SmartDeviceLink/SDLTireStatus.h', +'SmartDeviceLink/SDLTouch.h', +'SmartDeviceLink/SDLTouchCoord.h', +'SmartDeviceLink/SDLTouchEvent.h', +'SmartDeviceLink/SDLTouchEventCapabilities.h', +'SmartDeviceLink/SDLTouchManager.h', +'SmartDeviceLink/SDLTouchManagerDelegate.h', 'SmartDeviceLink/SDLTouchType.h', +'SmartDeviceLink/SDLTransportDelegate.h', 'SmartDeviceLink/SDLTriggerSource.h', +'SmartDeviceLink/SDLTTSChunk.h', +'SmartDeviceLink/SDLTurn.h', +'SmartDeviceLink/SDLUnregisterAppInterface.h', +'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h', +'SmartDeviceLink/SDLUnsubscribeButton.h', +'SmartDeviceLink/SDLUnsubscribeButtonResponse.h', +'SmartDeviceLink/SDLUnsubscribeVehicleData.h', +'SmartDeviceLink/SDLUnsubscribeVehicleDataResponse.h', +'SmartDeviceLink/SDLUnsubscribeWaypoints.h', +'SmartDeviceLink/SDLUnsubscribeWaypointsResponse.h', 'SmartDeviceLink/SDLUpdateMode.h', -'SmartDeviceLink/SDLVRCapabilities.h', +'SmartDeviceLink/SDLUpdateTurnList.h', +'SmartDeviceLink/SDLUpdateTurnListResponse.h', 'SmartDeviceLink/SDLVehicleDataActiveStatus.h', 'SmartDeviceLink/SDLVehicleDataEventStatus.h', 'SmartDeviceLink/SDLVehicleDataNotificationStatus.h', +'SmartDeviceLink/SDLVehicleDataResult.h', 'SmartDeviceLink/SDLVehicleDataResultCode.h', 'SmartDeviceLink/SDLVehicleDataStatus.h', 'SmartDeviceLink/SDLVehicleDataType.h', +'SmartDeviceLink/SDLVehicleType.h', +'SmartDeviceLink/SDLVideoStreamingCapability.h', +'SmartDeviceLink/SDLVideoStreamingCodec.h', +'SmartDeviceLink/SDLVideoStreamingFormat.h', +'SmartDeviceLink/SDLVideoStreamingProtocol.h', +'SmartDeviceLink/SDLVrCapabilities.h', +'SmartDeviceLink/SDLVrHelpItem.h', 'SmartDeviceLink/SDLWarningLightStatus.h', 'SmartDeviceLink/SDLWaypointType.h', 'SmartDeviceLink/SDLWiperStatus.h', -'SmartDeviceLink/SDLConfiguration.h', -'SmartDeviceLink/SDLLifecycleConfiguration.h', -'SmartDeviceLink/SDLLockScreenConfiguration.h', -'SmartDeviceLink/SDLArtwork.h', -'SmartDeviceLink/SDLFile.h', -'SmartDeviceLink/SDLFileManager.h', -'SmartDeviceLink/SDLFileManagerConstants.h', -'SmartDeviceLink/SDLLockScreenViewController.h', -'SmartDeviceLink/SDLManager.h', -'SmartDeviceLink/SDLManagerDelegate.h', -'SmartDeviceLink/SDLPermissionConstants.h', -'SmartDeviceLink/SDLPermissionManager.h', -'SmartDeviceLink/NSNumber+NumberType.h', -'SmartDeviceLink/SDLErrorConstants.h', -'SmartDeviceLink/SDLNotificationConstants.h', -'SmartDeviceLink/SDLRequestHandler.h', -'SmartDeviceLink/SDLRPCNotificationNotification.h', -'SmartDeviceLink/SDLRPCResponseNotification.h', -'SmartDeviceLink/SDLLogTarget.h', -'SmartDeviceLink/SDLLogTargetAppleSystemLog.h', -'SmartDeviceLink/SDLLogTargetFile.h', -'SmartDeviceLink/SDLLogTargetOSLog.h', -'SmartDeviceLink/SDLLogFileModule.h', -'SmartDeviceLink/SDLLogFilter.h', -'SmartDeviceLink/SDLLogConstants.h', -'SmartDeviceLink/SDLLogConfiguration.h', -'SmartDeviceLink/SDLLogManager.h', -'SmartDeviceLink/SDLLogMacros.h' +'SmartDeviceLink/SmartDeviceLink.h', ] end diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj index 0bcbdfa58..b5868a23e 100644 --- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj +++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj @@ -860,6 +860,9 @@ 5DA23FF31F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF21F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m */; }; 5DA23FF61F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF51F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m */; }; 5DA23FF81F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FF71F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m */; }; + 5DA23FFD1F312DBA009C0313 /* SDLVideoEncoderDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA23FFC1F312DBA009C0313 /* SDLVideoEncoderDelegate.h */; }; + 5DA240001F325621009C0313 /* SDLStreamingMediaConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA23FFE1F325621009C0313 /* SDLStreamingMediaConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5DA240011F325621009C0313 /* SDLStreamingMediaConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA23FFF1F325621009C0313 /* SDLStreamingMediaConfiguration.m */; }; 5DA3F3541BC448060026F2D0 /* NSMapTable+Subscripting.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA3F3521BC448060026F2D0 /* NSMapTable+Subscripting.h */; }; 5DA3F3551BC448060026F2D0 /* NSMapTable+Subscripting.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA3F3531BC448060026F2D0 /* NSMapTable+Subscripting.m */; }; 5DA3F35A1BC448480026F2D0 /* SDLError.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA3F3581BC448480026F2D0 /* SDLError.h */; }; @@ -870,6 +873,8 @@ 5DA3F3711BC4489A0026F2D0 /* SDLManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA3F36F1BC4489A0026F2D0 /* SDLManager.m */; }; 5DA49CE51F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DA49CE31F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.h */; }; 5DA49CE61F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DA49CE41F1EA83300E65FC5 /* SDLControlFramePayloadRPCStartService.m */; }; + 5DA8A0E91E955F710039C50D /* SDLStreamingMediaManagerConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966F31E56977C00413EAB /* SDLStreamingMediaManagerConstants.m */; }; + 5DA8A0EA1E955FE00039C50D /* SDLLogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06301E64A9C600A5CF03 /* SDLLogModel.m */; }; 5DAE06731BDEC6C000F9B498 /* SDLFileSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAE06721BDEC6C000F9B498 /* SDLFileSpec.m */; }; 5DAE06751BDEC6D600F9B498 /* SDLArtworkSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DAE06741BDEC6D600F9B498 /* SDLArtworkSpec.m */; }; 5DB1BCD31D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB1BCD01D243A8E002FFC37 /* SDLDeleteFileOperationSpec.m */; }; @@ -896,6 +901,8 @@ 5DB996611F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */; }; 5DBAE0AB1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */; }; 5DBAE0AD1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */; }; + 5DBEFA541F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */; }; + 5DBEFA581F436132009EE295 /* SDLFakeSecurityManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */; }; 5DBF06231E64A83F00A5CF03 /* SDLLogManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06211E64A83F00A5CF03 /* SDLLogManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5DBF06241E64A83F00A5CF03 /* SDLLogManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06221E64A83F00A5CF03 /* SDLLogManager.m */; }; 5DBF06271E64A91D00A5CF03 /* SDLLogFileModule.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06251E64A91D00A5CF03 /* SDLLogFileModule.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -904,7 +911,6 @@ 5DBF062D1E64A93A00A5CF03 /* SDLLogFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF062B1E64A93A00A5CF03 /* SDLLogFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5DBF062E1E64A93A00A5CF03 /* SDLLogFilter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF062C1E64A93A00A5CF03 /* SDLLogFilter.m */; }; 5DBF06311E64A9C600A5CF03 /* SDLLogModel.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF062F1E64A9C600A5CF03 /* SDLLogModel.h */; }; - 5DBF06321E64A9C600A5CF03 /* SDLLogModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06301E64A9C600A5CF03 /* SDLLogModel.m */; }; 5DBF06351E64A9FE00A5CF03 /* SDLLogConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06331E64A9FE00A5CF03 /* SDLLogConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5DBF06391E64ABBE00A5CF03 /* SDLLogConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBF06371E64ABBE00A5CF03 /* SDLLogConfiguration.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5DBF063A1E64ABBE00A5CF03 /* SDLLogConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 5DBF06381E64ABBE00A5CF03 /* SDLLogConfiguration.m */; }; @@ -944,16 +950,22 @@ 88EED83F1F33C5A400E6C42E /* SDLSendHapticData.m in Sources */ = {isa = PBXBuildFile; fileRef = 88EED83D1F33C5A400E6C42E /* SDLSendHapticData.m */; }; 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31981F2F7B5700BDC38D /* SDLVideoStreamingCodec.h */; }; 8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31991F2F7B5700BDC38D /* SDLVideoStreamingCodec.m */; }; - 8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; }; + 8B7B319E1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B319C1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B319F1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B319D1F2F7CF700BDC38D /* SDLVideoStreamingProtocol.m */; }; - 8B7B31A21F2F7FEA00BDC38D /* SDLVideoStreamingFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31A01F2F7FEA00BDC38D /* SDLVideoStreamingFormat.h */; }; + 8B7B31A21F2F7FEA00BDC38D /* SDLVideoStreamingFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31A01F2F7FEA00BDC38D /* SDLVideoStreamingFormat.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B31A31F2F7FEA00BDC38D /* SDLVideoStreamingFormat.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31A11F2F7FEA00BDC38D /* SDLVideoStreamingFormat.m */; }; - 8B7B31A61F2F875200BDC38D /* SDLVideoStreamingCapability.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31A41F2F875200BDC38D /* SDLVideoStreamingCapability.h */; }; + 8B7B31A61F2F875200BDC38D /* SDLVideoStreamingCapability.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B7B31A41F2F875200BDC38D /* SDLVideoStreamingCapability.h */; settings = {ATTRIBUTES = (Public, ); }; }; 8B7B31A71F2F875200BDC38D /* SDLVideoStreamingCapability.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31A51F2F875200BDC38D /* SDLVideoStreamingCapability.m */; }; 8B7B31A91F2FB8BC00BDC38D /* SDLVideoStreamingProtocolSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31A81F2FB8BC00BDC38D /* SDLVideoStreamingProtocolSpec.m */; }; 8B7B31AB1F2FB93500BDC38D /* SDLVideoStreamingCodecSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31AA1F2FB93500BDC38D /* SDLVideoStreamingCodecSpec.m */; }; 8B7B31AF1F2FBA0200BDC38D /* SDLVideoStreamingCapabilitySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31AE1F2FBA0200BDC38D /* SDLVideoStreamingCapabilitySpec.m */; }; 8B7B31B11F2FBD9500BDC38D /* SDLVideoStreamingFormatSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B7B31B01F2FBD9500BDC38D /* SDLVideoStreamingFormatSpec.m */; }; + 8B9376D71F3349FC009605C4 /* SDLMetadataTags.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8B9376D81F3349FC009605C4 /* SDLMetadataTags.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */; }; + 8B9376DB1F33656C009605C4 /* SDLMetadataTagsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B9376DA1F33656C009605C4 /* SDLMetadataTagsSpec.m */; }; + 8BBEA6061F324165003EEA26 /* SDLMetadataType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8BBEA6041F324165003EEA26 /* SDLMetadataType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8BBEA6071F324165003EEA26 /* SDLMetadataType.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BBEA6051F324165003EEA26 /* SDLMetadataType.m */; }; + 8BBEA6091F324832003EEA26 /* SDLMetadataTypeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */; }; 97E26DEC1E807AD70074A3C7 /* SDLMutableDataQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 97E26DEA1E807AD70074A3C7 /* SDLMutableDataQueue.h */; }; 97E26DED1E807AD70074A3C7 /* SDLMutableDataQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 97E26DEB1E807AD70074A3C7 /* SDLMutableDataQueue.m */; }; DA0C46AD1DCD35080001F2A8 /* SDLNames.m in Sources */ = {isa = PBXBuildFile; fileRef = DA0C46AC1DCD35080001F2A8 /* SDLNames.m */; }; @@ -966,6 +978,12 @@ DA4353EA1D2721680099B8C4 /* SDLTouchManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */; }; DA4353EB1D2721680099B8C4 /* SDLTouchSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */; }; DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4F47951E771AA100FC809E /* SDLEnum.m */; }; + DA6223BD1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = DA6223BB1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h */; }; + DA6223BE1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = DA6223BC1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m */; }; + DA8966EB1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */; }; + DA8966EC1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */; }; + DA8966EF1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */; }; + DA8966F21E56973700413EAB /* SDLStreamingMediaManagerConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8966F11E56973700413EAB /* SDLStreamingMediaManagerConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA96C0661D4D4F730022F520 /* SDLAppInfoSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA96C0651D4D4F730022F520 /* SDLAppInfoSpec.m */; }; DA9F7E631DCBFAC800ACAE48 /* SDLDateTime.h in Headers */ = {isa = PBXBuildFile; fileRef = DA9F7E611DCBFAC800ACAE48 /* SDLDateTime.h */; settings = {ATTRIBUTES = (Public, ); }; }; DA9F7E641DCBFAC800ACAE48 /* SDLDateTime.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7E621DCBFAC800ACAE48 /* SDLDateTime.m */; }; @@ -1006,12 +1024,15 @@ DA9F7EB21DCC084300ACAE48 /* SDLDeliveryModeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB11DCC084300ACAE48 /* SDLDeliveryModeSpec.m */; }; DA9F7EB41DCC086400ACAE48 /* SDLDateTimeSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB31DCC086400ACAE48 /* SDLDateTimeSpec.m */; }; DA9F7EB61DCC086A00ACAE48 /* SDLOasisAddressSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA9F7EB51DCC086A00ACAE48 /* SDLOasisAddressSpec.m */; }; + DAA41D551DF66B2000BC7337 /* SDLVideoEncoder.h in Headers */ = {isa = PBXBuildFile; fileRef = DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */; }; + DAA41D561DF66B2000BC7337 /* SDLVideoEncoder.m in Sources */ = {isa = PBXBuildFile; fileRef = DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */; }; + DABB62171E4A900C0034C567 /* SDLVideoEncoderSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */; }; DAC572571D1067270004288B /* SDLTouchManager.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572551D1067270004288B /* SDLTouchManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAC572581D1067270004288B /* SDLTouchManager.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572561D1067270004288B /* SDLTouchManager.m */; }; DAC5725B1D10B81E0004288B /* SDLTouch.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572591D10B81E0004288B /* SDLTouch.m */; }; - DAC5725C1D10B81E0004288B /* SDLTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC5725A1D10B81E0004288B /* SDLTouch.h */; }; + DAC5725C1D10B81E0004288B /* SDLTouch.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC5725A1D10B81E0004288B /* SDLTouch.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAC572621D10C5020004288B /* SDLPinchGesture.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572601D10C5020004288B /* SDLPinchGesture.m */; }; - DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572611D10C5020004288B /* SDLPinchGesture.h */; }; + DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572611D10C5020004288B /* SDLPinchGesture.h */; settings = {ATTRIBUTES = (Public, ); }; }; DAC572661D10C5640004288B /* CGPoint_Util.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572641D10C5640004288B /* CGPoint_Util.m */; }; DAC572671D10C5640004288B /* CGPoint_Util.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572651D10C5640004288B /* CGPoint_Util.h */; }; DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572681D10D5FC0004288B /* dispatch_timer.m */; }; @@ -1428,7 +1449,7 @@ 5D616B5B1D5A23E400553F6B /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/SDLLockScreen.strings; sourceTree = "<group>"; }; 5D61FA1C1A84237100846EE7 /* SmartDeviceLink.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SmartDeviceLink.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5D61FA1F1A84237100846EE7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 5D61FA201A84237100846EE7 /* SmartDeviceLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SmartDeviceLink.h; sourceTree = "<group>"; }; + 5D61FA201A84237100846EE7 /* SmartDeviceLink.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SmartDeviceLink.h; sourceTree = "<group>"; wrapsLines = 0; }; 5D61FA261A84237100846EE7 /* SmartDeviceLinkTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SmartDeviceLinkTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5D61FA2E1A84237100846EE7 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 5D61FA3C1A84238A00846EE7 /* SDLAbstractProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLAbstractProtocol.h; sourceTree = "<group>"; }; @@ -1969,6 +1990,9 @@ 5DA23FF21F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadAudioStartServiceAckSpec.m; sourceTree = "<group>"; }; 5DA23FF51F2FAA31009C0313 /* SDLControlFramePayloadRPCStartServiceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartServiceSpec.m; sourceTree = "<group>"; }; 5DA23FF71F2FAF2D009C0313 /* SDLControlFramePayloadRPCStartServiceAckSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadRPCStartServiceAckSpec.m; sourceTree = "<group>"; }; + 5DA23FFC1F312DBA009C0313 /* SDLVideoEncoderDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoEncoderDelegate.h; sourceTree = "<group>"; }; + 5DA23FFE1F325621009C0313 /* SDLStreamingMediaConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaConfiguration.h; sourceTree = "<group>"; }; + 5DA23FFF1F325621009C0313 /* SDLStreamingMediaConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaConfiguration.m; sourceTree = "<group>"; }; 5DA3F3521BC448060026F2D0 /* NSMapTable+Subscripting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMapTable+Subscripting.h"; sourceTree = "<group>"; }; 5DA3F3531BC448060026F2D0 /* NSMapTable+Subscripting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMapTable+Subscripting.m"; sourceTree = "<group>"; }; 5DA3F3581BC448480026F2D0 /* SDLError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLError.h; sourceTree = "<group>"; }; @@ -2006,6 +2030,9 @@ 5DB9965F1F28C6ED002D8795 /* SDLControlFramePayloadVideoStartServiceAck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLControlFramePayloadVideoStartServiceAck.m; sourceTree = "<group>"; }; 5DBAE0AA1D3588AC00CE00BF /* SDLNotificationDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLNotificationDispatcherSpec.m; path = DevAPISpecs/SDLNotificationDispatcherSpec.m; sourceTree = "<group>"; }; 5DBAE0AC1D368D1A00CE00BF /* SDLResponseDispatcherSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLResponseDispatcherSpec.m; path = DevAPISpecs/SDLResponseDispatcherSpec.m; sourceTree = "<group>"; }; + 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLStreamingMediaConfigurationSpec.m; path = DevAPISpecs/SDLStreamingMediaConfigurationSpec.m; sourceTree = "<group>"; }; + 5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDLFakeSecurityManager.h; path = DevAPISpecs/SDLFakeSecurityManager.h; sourceTree = "<group>"; }; + 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLFakeSecurityManager.m; path = DevAPISpecs/SDLFakeSecurityManager.m; sourceTree = "<group>"; }; 5DBF06211E64A83F00A5CF03 /* SDLLogManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLogManager.h; sourceTree = "<group>"; }; 5DBF06221E64A83F00A5CF03 /* SDLLogManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLogManager.m; sourceTree = "<group>"; }; 5DBF06251E64A91D00A5CF03 /* SDLLogFileModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLogFileModule.h; sourceTree = "<group>"; }; @@ -2065,6 +2092,12 @@ 8B7B31AA1F2FB93500BDC38D /* SDLVideoStreamingCodecSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCodecSpec.m; sourceTree = "<group>"; }; 8B7B31AE1F2FBA0200BDC38D /* SDLVideoStreamingCapabilitySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingCapabilitySpec.m; sourceTree = "<group>"; }; 8B7B31B01F2FBD9500BDC38D /* SDLVideoStreamingFormatSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoStreamingFormatSpec.m; sourceTree = "<group>"; }; + 8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMetadataTags.h; sourceTree = "<group>"; }; + 8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTags.m; sourceTree = "<group>"; }; + 8B9376DA1F33656C009605C4 /* SDLMetadataTagsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTagsSpec.m; sourceTree = "<group>"; }; + 8BBEA6041F324165003EEA26 /* SDLMetadataType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMetadataType.h; sourceTree = "<group>"; }; + 8BBEA6051F324165003EEA26 /* SDLMetadataType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataType.m; sourceTree = "<group>"; }; + 8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMetadataTypeSpec.m; sourceTree = "<group>"; }; 97E26DEA1E807AD70074A3C7 /* SDLMutableDataQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMutableDataQueue.h; sourceTree = "<group>"; }; 97E26DEB1E807AD70074A3C7 /* SDLMutableDataQueue.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMutableDataQueue.m; sourceTree = "<group>"; }; DA0C46AC1DCD35080001F2A8 /* SDLNames.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLNames.m; sourceTree = "<group>"; }; @@ -2077,6 +2110,14 @@ DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchManagerSpec.m; path = UtilitiesSpecs/Touches/SDLTouchManagerSpec.m; sourceTree = "<group>"; }; DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchSpec.m; path = UtilitiesSpecs/Touches/SDLTouchSpec.m; sourceTree = "<group>"; }; DA4F47951E771AA100FC809E /* SDLEnum.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLEnum.m; sourceTree = "<group>"; }; + DA6223BB1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CVPixelBufferRef+SDLUtil.h"; sourceTree = "<group>"; }; + DA6223BC1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CVPixelBufferRef+SDLUtil.m"; sourceTree = "<group>"; }; + DA661E2B1E553E7E001C1345 /* SDLStreamingMediaManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaManagerSpec.m; sourceTree = "<group>"; }; + DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaLifecycleManager.h; sourceTree = "<group>"; }; + DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaLifecycleManager.m; sourceTree = "<group>"; }; + DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaLifecycleManagerSpec.m; sourceTree = "<group>"; }; + DA8966F11E56973700413EAB /* SDLStreamingMediaManagerConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLStreamingMediaManagerConstants.h; sourceTree = "<group>"; }; + DA8966F31E56977C00413EAB /* SDLStreamingMediaManagerConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLStreamingMediaManagerConstants.m; sourceTree = "<group>"; }; DA96C0651D4D4F730022F520 /* SDLAppInfoSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLAppInfoSpec.m; sourceTree = "<group>"; }; DA9F7E611DCBFAC800ACAE48 /* SDLDateTime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLDateTime.h; sourceTree = "<group>"; }; DA9F7E621DCBFAC800ACAE48 /* SDLDateTime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDateTime.m; sourceTree = "<group>"; }; @@ -2117,6 +2158,9 @@ DA9F7EB11DCC084300ACAE48 /* SDLDeliveryModeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDeliveryModeSpec.m; sourceTree = "<group>"; }; DA9F7EB31DCC086400ACAE48 /* SDLDateTimeSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLDateTimeSpec.m; sourceTree = "<group>"; }; DA9F7EB51DCC086A00ACAE48 /* SDLOasisAddressSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLOasisAddressSpec.m; sourceTree = "<group>"; }; + DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLVideoEncoder.h; sourceTree = "<group>"; }; + DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoEncoder.m; sourceTree = "<group>"; }; + DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLVideoEncoderSpec.m; sourceTree = "<group>"; }; DAC572551D1067270004288B /* SDLTouchManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLTouchManager.h; sourceTree = "<group>"; }; DAC572561D1067270004288B /* SDLTouchManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTouchManager.m; sourceTree = "<group>"; }; DAC572591D10B81E0004288B /* SDLTouch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLTouch.m; sourceTree = "<group>"; }; @@ -2235,6 +2279,7 @@ 162E82041A9BDE8A00906325 /* SDLLockScreenStatusSpec.m */, 162E82051A9BDE8A00906325 /* SDLMaintenanceModeStatusSpec.m */, 162E82061A9BDE8A00906325 /* SDLMediaClockFormatSpec.m */, + 8BBEA6081F324832003EEA26 /* SDLMetadataTypeSpec.m */, 162E82071A9BDE8A00906325 /* SDLPermissionStatusSpec.m */, 162E82081A9BDE8A00906325 /* SDLPowerModeQualificationStatusSpec.m */, 162E82091A9BDE8A00906325 /* SDLPowerModeStatusSpec.m */, @@ -2442,6 +2487,7 @@ DA9F7EAD1DCC063400ACAE48 /* SDLLocationCoordinateSpec.m */, DA9F7EAE1DCC063400ACAE48 /* SDLLocationDetailsSpec.m */, 162E82A21A9BDE8A00906325 /* SDLMenuParamsSpec.m */, + 8B9376DA1F33656C009605C4 /* SDLMetadataTagsSpec.m */, 162E82A31A9BDE8A00906325 /* SDLMyKeySpec.m */, 5D0A9F921F15560B00CC80DD /* SDLNavigationCapabilitySpec.m */, DA9F7EB51DCC086A00ACAE48 /* SDLOasisAddressSpec.m */, @@ -2775,8 +2821,6 @@ 5D61FB641A84238B00846EE7 /* SDLProxy.m */, 5D61FB651A84238B00846EE7 /* SDLProxyFactory.h */, 5D61FB661A84238B00846EE7 /* SDLProxyFactory.m */, - 5D53C46B1B7A99B9003526EA /* SDLStreamingMediaManager.h */, - 5D53C46C1B7A99B9003526EA /* SDLStreamingMediaManager.m */, ); name = Proxy; sourceTree = "<group>"; @@ -3092,6 +3136,8 @@ DA9F7E981DCC052C00ACAE48 /* SDLLocationDetails.m */, 5D61FB0B1A84238A00846EE7 /* SDLMenuParams.h */, 5D61FB0C1A84238A00846EE7 /* SDLMenuParams.m */, + 8B9376D51F3349FC009605C4 /* SDLMetadataTags.h */, + 8B9376D61F3349FC009605C4 /* SDLMetadataTags.m */, 5D61FB0D1A84238A00846EE7 /* SDLMyKey.h */, 5D61FB0E1A84238A00846EE7 /* SDLMyKey.m */, 5D00AC751F15283E004000D9 /* SDLNavigationCapability.h */, @@ -3229,6 +3275,8 @@ 5D61FB081A84238A00846EE7 /* SDLMaintenanceModeStatus.m */, 5D61FB091A84238A00846EE7 /* SDLMediaClockFormat.h */, 5D61FB0A1A84238A00846EE7 /* SDLMediaClockFormat.m */, + 8BBEA6041F324165003EEA26 /* SDLMetadataType.h */, + 8BBEA6051F324165003EEA26 /* SDLMetadataType.m */, 5D61FB421A84238B00846EE7 /* SDLPermissionStatus.h */, 5D61FB431A84238B00846EE7 /* SDLPermissionStatus.m */, 5D61FB461A84238B00846EE7 /* SDLPowerModeQualificationStatus.h */, @@ -3481,6 +3529,7 @@ isa = PBXGroup; children = ( 5D59DD461B14FDEE00BE744D /* SDLLockScreenStatusManagerSpec.m */, + DA661E2B1E553E7E001C1345 /* SDLStreamingMediaManagerSpec.m */, ); name = ProxySpecs; sourceTree = "<group>"; @@ -3664,12 +3713,14 @@ 5D8204171BCD80A200D0A41B /* Configurations */ = { isa = PBXGroup; children = ( + 5D82041C1BCD8E6100D0A41B /* SDLConfiguration.h */, + 5D82041D1BCD8E6100D0A41B /* SDLConfiguration.m */, 5D6F7A2C1BC5650B0070BF37 /* SDLLifecycleConfiguration.h */, 5D6F7A2D1BC5650B0070BF37 /* SDLLifecycleConfiguration.m */, 5D8204181BCD80BA00D0A41B /* SDLLockScreenConfiguration.h */, 5D8204191BCD80BA00D0A41B /* SDLLockScreenConfiguration.m */, - 5D82041C1BCD8E6100D0A41B /* SDLConfiguration.h */, - 5D82041D1BCD8E6100D0A41B /* SDLConfiguration.m */, + 5DA23FFE1F325621009C0313 /* SDLStreamingMediaConfiguration.h */, + 5DA23FFF1F325621009C0313 /* SDLStreamingMediaConfiguration.m */, ); name = Configurations; sourceTree = "<group>"; @@ -3806,14 +3857,6 @@ name = Notifications; sourceTree = "<group>"; }; - 5DA3F3611BC448690026F2D0 /* Handler Additions */ = { - isa = PBXGroup; - children = ( - 5D6F7A2A1BC45BF70070BF37 /* SDLRequestHandler.h */, - ); - name = "Handler Additions"; - sourceTree = "<group>"; - }; 5DA49C8C1F1E549000E65FC5 /* BSON */ = { isa = PBXGroup; children = ( @@ -3876,8 +3919,10 @@ 5DB1BCDB1D243DA8002FFC37 /* Configurations */ = { isa = PBXGroup; children = ( + 5DBEFA551F434F8A009EE295 /* Utilities */, 5DB1BCDC1D243DC3002FFC37 /* SDLLifecycleConfigurationSpec.m */, 5DB1BCDE1D243DD3002FFC37 /* SDLLockScreenConfigurationSpec.m */, + 5DBEFA531F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m */, 5DB1BCE01D243DDE002FFC37 /* SDLConfigurationSpec.m */, ); name = Configurations; @@ -3913,6 +3958,7 @@ 5DB92D201AC47AC400C15BB0 /* UtilitiesSpecs */ = { isa = PBXGroup; children = ( + DABB62151E4A8FF20034C567 /* Video Encoding */, DA1166D71D14601C00438CEA /* Touches */, 5DEE55BE1B8509A5004F0D0F /* HTTP Connection */, 5DB92D2B1AC4A32A00C15BB0 /* Prioritized Objects */, @@ -3971,6 +4017,7 @@ 5DBAE0A51D355EE700CE00BF /* Lock Screen */, 5D82042A1BCEA91E00D0A41B /* Files */, 5D8204291BCEA91400D0A41B /* Permissions */, + DA8966E71E56937100413EAB /* Streaming */, ); name = Managers; sourceTree = "<group>"; @@ -3987,6 +4034,7 @@ 5DBAE0A81D35886E00CE00BF /* Managers */ = { isa = PBXGroup; children = ( + DA8966ED1E5693D100413EAB /* Streaming */, 5D1654541D3E753100554D93 /* Lifecycle */, 5D76E31A1D3805E600647CFA /* LockScreen */, 5D9F507F1BE7E6C900FEF399 /* Permissions */, @@ -4005,6 +4053,15 @@ name = Dispatchers; sourceTree = "<group>"; }; + 5DBEFA551F434F8A009EE295 /* Utilities */ = { + isa = PBXGroup; + children = ( + 5DBEFA561F436132009EE295 /* SDLFakeSecurityManager.h */, + 5DBEFA571F436132009EE295 /* SDLFakeSecurityManager.m */, + ); + name = Utilities; + sourceTree = "<group>"; + }; 5DBF063D1E64BDAE00A5CF03 /* Log Targets */ = { isa = PBXGroup; children = ( @@ -4034,26 +4091,6 @@ name = File; sourceTree = "<group>"; }; - 5DD67CAD1E65DD9C009CD394 /* Apple SysLog */ = { - isa = PBXGroup; - children = ( - 5DD67CAE1E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.h */, - 5DD67CAF1E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.m */, - ); - name = "Apple SysLog"; - sourceTree = "<group>"; - }; - 5DD67CC01E68AE66009CD394 /* Modules */ = { - isa = PBXGroup; - children = ( - 5DBF06251E64A91D00A5CF03 /* SDLLogFileModule.h */, - 5DBF06261E64A91D00A5CF03 /* SDLLogFileModule.m */, - 5DD67CC11E68AE82009CD394 /* SDLLogFileModuleMap.h */, - 5DD67CC21E68AE82009CD394 /* SDLLogFileModuleMap.m */, - ); - name = Modules; - sourceTree = "<group>"; - }; 5DC09ED71F2F7F1A00F4AB1D /* Control Frame Payloads */ = { isa = PBXGroup; children = ( @@ -4074,23 +4111,24 @@ name = General; sourceTree = "<group>"; }; - 5DCC199D1B8221D2004FFAD9 /* HTTP Connection */ = { + 5DD67CAD1E65DD9C009CD394 /* Apple SysLog */ = { isa = PBXGroup; children = ( - 5DCC199E1B8221F3004FFAD9 /* SDLURLSession.h */, - 5DCC199F1B8221F3004FFAD9 /* SDLURLSession.m */, - 5DCC19A21B822804004FFAD9 /* SDLURLRequestTask.h */, - 5DCC19A31B822804004FFAD9 /* SDLURLRequestTask.m */, + 5DD67CAE1E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.h */, + 5DD67CAF1E65DDB7009CD394 /* SDLLogTargetAppleSystemLog.m */, ); - name = "HTTP Connection"; + name = "Apple SysLog"; sourceTree = "<group>"; }; - 5DE372A71ACC35C100849FAA /* @protocols */ = { + 5DD67CC01E68AE66009CD394 /* Modules */ = { isa = PBXGroup; children = ( - 5DE372A51ACC35B400849FAA /* SDLDebugToolConsole.h */, + 5DBF06251E64A91D00A5CF03 /* SDLLogFileModule.h */, + 5DBF06261E64A91D00A5CF03 /* SDLLogFileModule.m */, + 5DD67CC11E68AE82009CD394 /* SDLLogFileModuleMap.h */, + 5DD67CC21E68AE82009CD394 /* SDLLogFileModuleMap.m */, ); - name = "@protocols"; + name = Modules; sourceTree = "<group>"; }; 5DEE55BE1B8509A5004F0D0F /* HTTP Connection */ = { @@ -4114,6 +4152,64 @@ name = Touches; sourceTree = "<group>"; }; + DA8966E71E56937100413EAB /* Streaming */ = { + isa = PBXGroup; + children = ( + DA8966F01E56970C00413EAB /* Utilities */, + DAA41D521DF66B1100BC7337 /* Video Encoding */, + DA8966E81E56938C00413EAB /* Lifecycle */, + 5D53C46B1B7A99B9003526EA /* SDLStreamingMediaManager.h */, + 5D53C46C1B7A99B9003526EA /* SDLStreamingMediaManager.m */, + ); + name = Streaming; + sourceTree = "<group>"; + }; + DA8966E81E56938C00413EAB /* Lifecycle */ = { + isa = PBXGroup; + children = ( + DA8966E91E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h */, + DA8966EA1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m */, + ); + name = Lifecycle; + sourceTree = "<group>"; + }; + DA8966ED1E5693D100413EAB /* Streaming */ = { + isa = PBXGroup; + children = ( + DA8966EE1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m */, + ); + name = Streaming; + sourceTree = "<group>"; + }; + DA8966F01E56970C00413EAB /* Utilities */ = { + isa = PBXGroup; + children = ( + DA6223BB1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h */, + DA6223BC1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m */, + DA8966F11E56973700413EAB /* SDLStreamingMediaManagerConstants.h */, + DA8966F31E56977C00413EAB /* SDLStreamingMediaManagerConstants.m */, + ); + name = Utilities; + sourceTree = "<group>"; + }; + DAA41D521DF66B1100BC7337 /* Video Encoding */ = { + isa = PBXGroup; + children = ( + DAA41D531DF66B2000BC7337 /* SDLVideoEncoder.h */, + DAA41D541DF66B2000BC7337 /* SDLVideoEncoder.m */, + 5DA23FFC1F312DBA009C0313 /* SDLVideoEncoderDelegate.h */, + ); + name = "Video Encoding"; + sourceTree = "<group>"; + }; + DABB62151E4A8FF20034C567 /* Video Encoding */ = { + isa = PBXGroup; + children = ( + DABB62161E4A900C0034C567 /* SDLVideoEncoderSpec.m */, + ); + name = "Video Encoding"; + sourceTree = "<group>"; + }; DAC5724C1D0FE3B60004288B /* Touches */ = { isa = PBXGroup; children = ( @@ -4160,6 +4256,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 8BBEA6061F324165003EEA26 /* SDLMetadataType.h in Headers */, 5DA3F35A1BC448480026F2D0 /* SDLError.h in Headers */, 5DA3F35F1BC448590026F2D0 /* SDLNotificationConstants.h in Headers */, 5DE5ABB71B0E38C90067BB02 /* SDLSystemRequest.h in Headers */, @@ -4183,6 +4280,7 @@ 5DBF06271E64A91D00A5CF03 /* SDLLogFileModule.h in Headers */, 5D61FC531A84238C00846EE7 /* SDLButtonEventMode.h in Headers */, 5D61FC781A84238C00846EE7 /* SDLDeleteFileResponse.h in Headers */, + 5DA240001F325621009C0313 /* SDLStreamingMediaConfiguration.h in Headers */, 5D61FC5F1A84238C00846EE7 /* SDLCharacterSet.h in Headers */, 5DD67CC71E68B568009CD394 /* SDLLogMacros.h in Headers */, 5D61FCFF1A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.h in Headers */, @@ -4221,6 +4319,7 @@ 5D9FDA901F2A7D3400A495C8 /* bson_array.h in Headers */, 5D61FDCB1A84238C00846EE7 /* SDLTextFieldName.h in Headers */, 5D61FD8B1A84238C00846EE7 /* SDLSetMediaClockTimer.h in Headers */, + DA6223BD1E7B088200878689 /* CVPixelBufferRef+SDLUtil.h in Headers */, 5D61FD031A84238C00846EE7 /* SDLOnButtonEvent.h in Headers */, 5D61FDAF1A84238C00846EE7 /* SDLSubscribeButtonResponse.h in Headers */, 5D61FCB51A84238C00846EE7 /* SDLGetVehicleData.h in Headers */, @@ -4251,6 +4350,7 @@ 5D61FCCB1A84238C00846EE7 /* SDLIgnitionStatus.h in Headers */, 5D61FCB71A84238C00846EE7 /* SDLGetVehicleDataResponse.h in Headers */, 5D61FDA91A84238C00846EE7 /* SDLSpeechCapabilities.h in Headers */, + 5DA23FFD1F312DBA009C0313 /* SDLVideoEncoderDelegate.h in Headers */, 5D61FCE01A84238C00846EE7 /* SDLKeyboardEvent.h in Headers */, 5D3E48751D6F3B330000BFEF /* SDLAsynchronousOperation.h in Headers */, DA9F7E631DCBFAC800ACAE48 /* SDLDateTime.h in Headers */, @@ -4263,6 +4363,7 @@ 5D61FDC71A84238C00846EE7 /* SDLTextAlignment.h in Headers */, 5D61FD051A84238C00846EE7 /* SDLOnButtonPress.h in Headers */, 5D61FCC51A84238C00846EE7 /* SDLHMIZoneCapabilities.h in Headers */, + DAA41D551DF66B2000BC7337 /* SDLVideoEncoder.h in Headers */, 8B7B319A1F2F7B5700BDC38D /* SDLVideoStreamingCodec.h in Headers */, 5D61FCAF1A84238C00846EE7 /* SDLGenericResponse.h in Headers */, 5D61FC4F1A84238C00846EE7 /* SDLBodyInformation.h in Headers */, @@ -4396,6 +4497,7 @@ 5D61FC821A84238C00846EE7 /* SDLDeviceInfo.h in Headers */, 5D61FCA91A84238C00846EE7 /* SDLFileType.h in Headers */, 8877F5EE1F34A72200DC128A /* SDLSendHapticDataResponse.h in Headers */, + DA8966F21E56973700413EAB /* SDLStreamingMediaManagerConstants.h in Headers */, 5DD67CB81E661C4A009CD394 /* SDLLogTargetFile.h in Headers */, 5D61FD591A84238C00846EE7 /* SDLReadDID.h in Headers */, 5D82041A1BCD80BA00D0A41B /* SDLLockScreenConfiguration.h in Headers */, @@ -4437,7 +4539,6 @@ 5D61FD911A84238C00846EE7 /* SDLShowConstantTBT.h in Headers */, 5D61FC331A84238C00846EE7 /* SDLAddSubMenuResponse.h in Headers */, 5D61FD5D1A84238C00846EE7 /* SDLRegisterAppInterface.h in Headers */, - 8BD729A61F2A2CF30029AC93 /* SDLVideoStreamingCodec.h in Headers */, 5D61FC9A1A84238C00846EE7 /* SDLEmergencyEvent.h in Headers */, 5D61FC651A84238C00846EE7 /* SDLCompassDirection.h in Headers */, 5D61FC8E1A84238C00846EE7 /* SDLDimension.h in Headers */, @@ -4456,15 +4557,16 @@ 5D61FCA31A84238C00846EE7 /* SDLEndAudioPassThru.h in Headers */, 5D61FCB11A84238C00846EE7 /* SDLGetDTCs.h in Headers */, 5D61FDFF1A84238C00846EE7 /* SDLVehicleDataEventStatus.h in Headers */, - 8BD729AA1F2A41F40029AC93 /* SDLVideoStreamingProtocol.h in Headers */, 5D61FC5B1A84238C00846EE7 /* SDLChangeRegistration.h in Headers */, 5D61FD5B1A84238C00846EE7 /* SDLReadDIDResponse.h in Headers */, 5D61FDEF1A84238C00846EE7 /* SDLUpdateMode.h in Headers */, + DA8966EB1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.h in Headers */, 5D61FDDB1A84238C00846EE7 /* SDLTriggerSource.h in Headers */, 5D61FD8F1A84238C00846EE7 /* SDLShow.h in Headers */, 5D61FDDD1A84238C00846EE7 /* SDLTTSChunk.h in Headers */, 5D61FC371A84238C00846EE7 /* SDLAlert.h in Headers */, 5D61FCC11A84238C00846EE7 /* SDLHMILevel.h in Headers */, + 8B9376D71F3349FC009605C4 /* SDLMetadataTags.h in Headers */, 5D61FD471A84238C00846EE7 /* SDLProtocolListener.h in Headers */, 5D61FCA01A84238C00846EE7 /* SDLEncodedSyncPDataResponse.h in Headers */, 5D61FD271A84238C00846EE7 /* SDLPerformAudioPassThruResponse.h in Headers */, @@ -4513,7 +4615,6 @@ 5D61FD6F1A84238C00846EE7 /* SDLRPCPayload.h in Headers */, 5D61FCF01A84238C00846EE7 /* SDLLockScreenStatusManager.h in Headers */, 5D61FD311A84238C00846EE7 /* SDLPolicyDataParser.h in Headers */, - 8BD729B21F2A61DF0029AC93 /* SDLVideoStreamingCapability.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -4731,7 +4832,8 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 8BD729AB1F2A41F40029AC93 /* SDLVideoStreamingProtocol.m in Sources */, + 5DA8A0EA1E955FE00039C50D /* SDLLogModel.m in Sources */, + 5DA8A0E91E955F710039C50D /* SDLStreamingMediaManagerConstants.m in Sources */, 332A914F1CED9CC60043824C /* SDLAppInfo.m in Sources */, DA9F7E841DCC047200ACAE48 /* SDLWaypointType.m in Sources */, 5D61FC561A84238C00846EE7 /* SDLButtonName.m in Sources */, @@ -4741,6 +4843,7 @@ 5D61FC441A84238C00846EE7 /* SDLAppInterfaceUnregisteredReason.m in Sources */, 5D61FD531A84238C00846EE7 /* SDLProxyFactory.m in Sources */, 5D61FDCA1A84238C00846EE7 /* SDLTextField.m in Sources */, + DAA41D561DF66B2000BC7337 /* SDLVideoEncoder.m in Sources */, 5D61FC9D1A84238C00846EE7 /* SDLEmergencyEventType.m in Sources */, 5D61FCAC1A84238C00846EE7 /* SDLFuelCutoffStatus.m in Sources */, 5D61FC871A84238C00846EE7 /* SDLDeviceStatus.m in Sources */, @@ -4756,7 +4859,6 @@ 5D61FDEE1A84238C00846EE7 /* SDLUnsubscribeVehicleDataResponse.m in Sources */, 8B7B319B1F2F7B5700BDC38D /* SDLVideoStreamingCodec.m in Sources */, 5D535DC61B72473800CF7760 /* SDLGlobals.m in Sources */, - 5DBF06321E64A9C600A5CF03 /* SDLLogModel.m in Sources */, 5D61FCAE1A84238C00846EE7 /* SDLFunctionID.m in Sources */, 5D61FC421A84238C00846EE7 /* SDLAppHMIType.m in Sources */, 5D61FD421A84238C00846EE7 /* SDLPRNDL.m in Sources */, @@ -4890,6 +4992,7 @@ 5D9FDA931F2A7D3400A495C8 /* bson_util.c in Sources */, 5D61FD511A84238C00846EE7 /* SDLProxy.m in Sources */, 5D61FD461A84238C00846EE7 /* SDLProtocolHeader.m in Sources */, + 8BBEA6071F324165003EEA26 /* SDLMetadataType.m in Sources */, 5D61FDBC1A84238C00846EE7 /* SDLSystemAction.m in Sources */, 5D61FC381A84238C00846EE7 /* SDLAlert.m in Sources */, 5D61FD2C1A84238C00846EE7 /* SDLPerformInteractionResponse.m in Sources */, @@ -4908,7 +5011,6 @@ 5D61FCC61A84238C00846EE7 /* SDLHMIZoneCapabilities.m in Sources */, 5D61FD161A84238C00846EE7 /* SDLOnLockScreenStatus.m in Sources */, 5D61FDAE1A84238C00846EE7 /* SDLSubscribeButton.m in Sources */, - 8BD729AF1F2A5AA10029AC93 /* SDLVideoStreamingFormat.m in Sources */, DA9F7E6C1DCBFB0700ACAE48 /* SDLDeliveryMode.m in Sources */, 5D61FC581A84238C00846EE7 /* SDLButtonPressMode.m in Sources */, 5D00AC781F15283E004000D9 /* SDLNavigationCapability.m in Sources */, @@ -4927,7 +5029,6 @@ 5D61FDD01A84238C00846EE7 /* SDLTireStatus.m in Sources */, 5D61FC321A84238C00846EE7 /* SDLAddSubMenu.m in Sources */, 5D61FDF61A84238C00846EE7 /* SDLV1ProtocolHeader.m in Sources */, - 8BD729B31F2A61DF0029AC93 /* SDLVideoStreamingCapability.m in Sources */, 5D61FDAA1A84238C00846EE7 /* SDLSpeechCapabilities.m in Sources */, 5D61FDB41A84238C00846EE7 /* SDLSubscribeVehicleDataResponse.m in Sources */, 5D61FD121A84238C00846EE7 /* SDLOnKeyboardInput.m in Sources */, @@ -4942,7 +5043,6 @@ 5D61FC7F1A84238C00846EE7 /* SDLDeleteSubMenu.m in Sources */, 5D61FCE91A84238C00846EE7 /* SDLLanguage.m in Sources */, 5D61FC3E1A84238C00846EE7 /* SDLAlertResponse.m in Sources */, - 8BD729A71F2A2CF30029AC93 /* SDLVideoStreamingCodec.m in Sources */, 5D61FD8C1A84238C00846EE7 /* SDLSetMediaClockTimer.m in Sources */, 5D61FE121A84238C00846EE7 /* SDLWarningLightStatus.m in Sources */, 5D61FCB81A84238C00846EE7 /* SDLGetVehicleDataResponse.m in Sources */, @@ -4969,6 +5069,7 @@ 5D61FE061A84238C00846EE7 /* SDLVehicleDataResultCode.m in Sources */, 5D61FCA41A84238C00846EE7 /* SDLEndAudioPassThru.m in Sources */, 5D8B17541AC9E11B006A6E1C /* SDLDialNumberResponse.m in Sources */, + DA6223BE1E7B088200878689 /* CVPixelBufferRef+SDLUtil.m in Sources */, 5D61FC851A84238C00846EE7 /* SDLDeviceLevelStatus.m in Sources */, 5D9FDA981F2A7D3F00A495C8 /* emhashmap.c in Sources */, 5D61FD1E1A84238C00846EE7 /* SDLOnTBTClientState.m in Sources */, @@ -4978,6 +5079,7 @@ 5D61FCB21A84238C00846EE7 /* SDLGetDTCs.m in Sources */, 5D61FD441A84238C00846EE7 /* SDLProtocol.m in Sources */, 5D61FC341A84238C00846EE7 /* SDLAddSubMenuResponse.m in Sources */, + 5DA240011F325621009C0313 /* SDLStreamingMediaConfiguration.m in Sources */, 5D6F7A2F1BC5650B0070BF37 /* SDLLifecycleConfiguration.m in Sources */, 5D61FD141A84238C00846EE7 /* SDLOnLanguageChange.m in Sources */, 5D61FE041A84238C00846EE7 /* SDLVehicleDataResult.m in Sources */, @@ -4988,6 +5090,7 @@ 5D61FCEB1A84238C00846EE7 /* SDLLayoutMode.m in Sources */, 5D61FC2E1A84238C00846EE7 /* SDLAddCommand.m in Sources */, 5D1665C51CF8CA2700CC4CA1 /* SDLListFilesOperation.m in Sources */, + 8B9376D81F3349FC009605C4 /* SDLMetadataTags.m in Sources */, 5D61FE021A84238C00846EE7 /* SDLVehicleDataNotificationStatus.m in Sources */, 5D61FDD81A84238C00846EE7 /* SDLTouchType.m in Sources */, DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */, @@ -5040,6 +5143,7 @@ 5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */, 5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */, 5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */, + DA8966EC1E56939F00413EAB /* SDLStreamingMediaLifecycleManager.m in Sources */, DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */, 5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */, 5D61FD081A84238C00846EE7 /* SDLOnCommand.m in Sources */, @@ -5105,6 +5209,8 @@ 1680B11A1A9CD7AD00DBD79E /* SDLAbstractProtocolSpec.m in Sources */, 1680B1151A9CD7AD00DBD79E /* SDLV2ProtocolHeaderSpec.m in Sources */, 162E83101A9BDE8B00906325 /* SDLOnAudioPassThruSpec.m in Sources */, + DABB62171E4A900C0034C567 /* SDLVideoEncoderSpec.m in Sources */, + 5DBEFA581F436132009EE295 /* SDLFakeSecurityManager.m in Sources */, 162E82D91A9BDE8A00906325 /* SDLDisplayTypeSpec.m in Sources */, 162E83871A9BDE8B00906325 /* SDLPermissionItemSpec.m in Sources */, 162E82E31A9BDE8B00906325 /* SDLIgnitionStatusSpec.m in Sources */, @@ -5112,6 +5218,7 @@ DA9F7EB41DCC086400ACAE48 /* SDLDateTimeSpec.m in Sources */, 162E82E41A9BDE8B00906325 /* SDLImageFieldNameSpec.m in Sources */, 162E82ED1A9BDE8B00906325 /* SDLMaintenanceModeStatusSpec.m in Sources */, + 8B9376DB1F33656C009605C4 /* SDLMetadataTagsSpec.m in Sources */, 5DB92D2D1AC4A34F00C15BB0 /* SDLPrioritizedObjectCollectionSpec.m in Sources */, 5D43466D1E6F522000B639C6 /* SDLLogModelSpec.m in Sources */, 5DA23FF31F2FA35C009C0313 /* SDLControlFramePayloadAudioStartServiceAckSpec.m in Sources */, @@ -5161,6 +5268,7 @@ 162E834F1A9BDE8B00906325 /* SDLDeleteCommandResponseSpec.m in Sources */, 162E83231A9BDE8B00906325 /* SDLAddSubMenuSpec.m in Sources */, DA4353E91D2721680099B8C4 /* DispatchTimerSpec.m in Sources */, + DA8966EF1E5693E300413EAB /* SDLStreamingMediaLifecycleManagerSpec.m in Sources */, 162E82F21A9BDE8B00906325 /* SDLPredefinedLayoutSpec.m in Sources */, 162E83521A9BDE8B00906325 /* SDLDeleteSubMenuResponseSpec.m in Sources */, 162E82E91A9BDE8B00906325 /* SDLKeypressModeSpec.m in Sources */, @@ -5188,6 +5296,7 @@ DA4353DF1D271FD10099B8C4 /* CGPointUtilSpec.m in Sources */, 162E83291A9BDE8B00906325 /* SDLDeleteFileSpec.m in Sources */, 1680B11D1A9CD7AD00DBD79E /* SDLProtocolMessageDisassemblerSpec.m in Sources */, + 8BBEA6091F324832003EEA26 /* SDLMetadataTypeSpec.m in Sources */, DA9F7E9E1DCC05B900ACAE48 /* SDLWaypointTypeSpec.m in Sources */, 162E838E1A9BDE8B00906325 /* SDLSyncMsgVersionSpec.m in Sources */, 5D76E31C1D3805FF00647CFA /* SDLLockScreenManagerSpec.m in Sources */, @@ -5268,11 +5377,11 @@ 162E833D1A9BDE8B00906325 /* SDLShowConstantTBTSpec.m in Sources */, 162E83651A9BDE8B00906325 /* SDLShowConstantTBTResponseSpec.m in Sources */, 162E82F91A9BDE8B00906325 /* SDLSamplingRateSpec.m in Sources */, + 5DBEFA541F434B9E009EE295 /* SDLStreamingMediaConfigurationSpec.m in Sources */, 162E82CB1A9BDE8A00906325 /* SDLAppHMITypeSpec.m in Sources */, 162E83031A9BDE8B00906325 /* SDLTriggerSource.m in Sources */, 162E82D61A9BDE8A00906325 /* SDLComponentVolumeStatusSpec.m in Sources */, 162E835C1A9BDE8B00906325 /* SDLPutFileResponseSpec.m in Sources */, - 8BD729B51F2A711D0029AC93 /* SDLVideoStreamingCodecSpec.m in Sources */, DA9F7EAA1DCC061A00ACAE48 /* SDLSubscribeWaypointsResponseSpec.m in Sources */, 162E835F1A9BDE8B00906325 /* SDLResetGlobalPropertiesResponseSpec.m in Sources */, 162E835E1A9BDE8B00906325 /* SDLRegisterAppInterfaceResponseSpec.m in Sources */, @@ -5300,7 +5409,6 @@ 162E83311A9BDE8B00906325 /* SDLListFilesSpec.m in Sources */, DA9F7EB01DCC063400ACAE48 /* SDLLocationDetailsSpec.m in Sources */, 5DC978261B7A38640012C2F1 /* SDLGlobalsSpec.m in Sources */, - 8BF9DE071F2BAEEE004FFCBB /* SDLVideoStreamingFormatSpec.m in Sources */, 162E82FF1A9BDE8B00906325 /* SDLTextAlignmentSpec.m in Sources */, 162E831F1A9BDE8B00906325 /* SDLOnTouchEventSpec.m in Sources */, 162E83921A9BDE8B00906325 /* SDLTouchEventCapabilitiesSpec.m in Sources */, @@ -5316,7 +5424,6 @@ 162E831D1A9BDE8B00906325 /* SDLOnSystemRequestSpec.m in Sources */, 162E835D1A9BDE8B00906325 /* SDLReadDIDResponseSpec.m in Sources */, 162E82D41A9BDE8A00906325 /* SDLCharacterSetSpec.m in Sources */, - 8BF9DE091F2BAF0C004FFCBB /* SDLVideoStreamingCapabilitySpec.m in Sources */, 162E830F1A9BDE8B00906325 /* SDLOnAppInterfaceUnregisteredSpec.m in Sources */, 162E83971A9BDE8B00906325 /* SDLVehicleTypeSpec.m in Sources */, 1680B1131A9CD7AD00DBD79E /* SDLProtocolHeaderSpec.m in Sources */, diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec index a88b5e620..ed181d5a8 100644 --- a/SmartDeviceLink.podspec +++ b/SmartDeviceLink.podspec @@ -6,293 +6,318 @@ s.summary = "Connect your app with cars!" s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS" s.license = { :type => "New BSD", :file => "LICENSE" } s.author = { "SmartDeviceLink Team" => "developer@smartdevicelink.com" } -s.platform = :ios, "6.0" +s.platform = :ios, "8.0" +s.dependency 'BiSON', '~> 1.0' s.source = { :git => "https://github.com/smartdevicelink/sdl_ios.git", :tag => s.version.to_s } -s.source_files = "SmartDeviceLink/*.{h,m}" s.requires_arc = true -s.resource_bundles = { 'SmartDeviceLink' => ['SmartDeviceLink/Assets/**/*', 'SmartDeviceLink/iOS 7 Assets/*'] } -s.public_header_files = [ -'SmartDeviceLink/SmartDeviceLink.h', -'SmartDeviceLink/SDLJingle.h', -'SmartDeviceLink/SDLProxy.h', -'SmartDeviceLink/SDLProxyFactory.h', -'SmartDeviceLink/SDLProxyListener.h', -'SmartDeviceLink/SDLSecurityType.h', -'SmartDeviceLink/SDLStreamingMediaManager.h', -'SmartDeviceLink/SDLTTSChunkFactory.h', -'SmartDeviceLink/SDLTouchManager.h', -'SmartDeviceLink/SDLTouchManagerDelegate.h', -'SmartDeviceLink/SDLConsoleController.h', -'SmartDeviceLink/SDLDebugTool.h', -'SmartDeviceLink/SDLDebugToolConsole.h', -'SmartDeviceLink/SDLSiphonServer.h', -'SmartDeviceLink/SDLAbstractTransport.h', -'SmartDeviceLink/SDLIAPSessionDelegate.h', -'SmartDeviceLink/SDLIAPTransport.h', -'SmartDeviceLink/SDLTCPTransport.h', -'SmartDeviceLink/SDLTransportDelegate.h', +s.resource_bundles = { 'SmartDeviceLink' => ['SmartDeviceLink/Assets/**/*'] } + +s.default_subspecs = 'Default' + +s.subspec 'Default' do |ss| +ss.source_files = 'SmartDeviceLink/*.{h,m}' + +ss.public_header_files = [ +'SmartDeviceLink/NSNumber+NumberType.h', 'SmartDeviceLink/SDLAbstractProtocol.h', -'SmartDeviceLink/SDLProtocol.h', -'SmartDeviceLink/SDLProtocolListener.h', -'SmartDeviceLink/SDLProtocolHeader.h', -'SmartDeviceLink/SDLProtocolMessage.h', -'SmartDeviceLink/SDLEnum.h', -'SmartDeviceLink/SDLRPCMessage.h', -'SmartDeviceLink/SDLRPCNotification.h', -'SmartDeviceLink/SDLRPCRequest.h', -'SmartDeviceLink/SDLRPCResponse.h', -'SmartDeviceLink/SDLRPCStruct.h', -'SmartDeviceLink/SDLRPCRequestFactory.h', +'SmartDeviceLink/SDLAbstractTransport.h', 'SmartDeviceLink/SDLAddCommand.h', +'SmartDeviceLink/SDLAddCommandResponse.h', 'SmartDeviceLink/SDLAddSubMenu.h', +'SmartDeviceLink/SDLAddSubMenuResponse.h', +'SmartDeviceLink/SDLAirbagStatus.h', 'SmartDeviceLink/SDLAlert.h', 'SmartDeviceLink/SDLAlertManeuver.h', -'SmartDeviceLink/SDLChangeRegistration.h', -'SmartDeviceLink/SDLCreateInteractionChoiceSet.h', -'SmartDeviceLink/SDLDeleteCommand.h', -'SmartDeviceLink/SDLDeleteFile.h', -'SmartDeviceLink/SDLDeleteInteractionChoiceSet.h', -'SmartDeviceLink/SDLDeleteSubMenu.h', -'SmartDeviceLink/SDLDiagnosticMessage.h', -'SmartDeviceLink/SDLDialNumber.h', -'SmartDeviceLink/SDLEncodedSyncPData.h', -'SmartDeviceLink/SDLEndAudioPassThru.h', -'SmartDeviceLink/SDLGetDTCs.h', -'SmartDeviceLink/SDLGetSystemCapability.h', -'SmartDeviceLink/SDLGetVehicleData.h', -'SmartDeviceLink/SDLGetWaypoints.h', -'SmartDeviceLink/SDLListFiles.h', -'SmartDeviceLink/SDLPerformAudioPassThru.h', -'SmartDeviceLink/SDLPerformInteraction.h', -'SmartDeviceLink/SDLPutFile.h', -'SmartDeviceLink/SDLReadDID.h', -'SmartDeviceLink/SDLRegisterAppInterface.h', -'SmartDeviceLink/SDLResetGlobalProperties.h', -'SmartDeviceLink/SDLScrollableMessage.h', -'SmartDeviceLink/SDLSendHapticData.h', -'SmartDeviceLink/SDLSendLocation.h', -'SmartDeviceLink/SDLSetAppIcon.h', -'SmartDeviceLink/SDLSetDisplayLayout.h', -'SmartDeviceLink/SDLSetGlobalProperties.h', -'SmartDeviceLink/SDLSetMediaClockTimer.h', -'SmartDeviceLink/SDLShow.h', -'SmartDeviceLink/SDLShowConstantTBT.h', -'SmartDeviceLink/SDLSlider.h', -'SmartDeviceLink/SDLSpeak.h', -'SmartDeviceLink/SDLSubscribeButton.h', -'SmartDeviceLink/SDLSubscribeVehicleData.h', -'SmartDeviceLink/SDLSubscribeWaypoints.h', -'SmartDeviceLink/SDLSyncPData.h', -'SmartDeviceLink/SDLUnregisterAppInterface.h', -'SmartDeviceLink/SDLUnsubscribeButton.h', -'SmartDeviceLink/SDLUnsubscribeVehicleData.h', -'SmartDeviceLink/SDLUnsubscribeWaypoints.h', -'SmartDeviceLink/SDLUpdateTurnList.h', -'SmartDeviceLink/SDLAddCommandResponse.h', -'SmartDeviceLink/SDLAddSubMenuResponse.h', 'SmartDeviceLink/SDLAlertManeuverResponse.h', 'SmartDeviceLink/SDLAlertResponse.h', -'SmartDeviceLink/SDLChangeRegistrationResponse.h', -'SmartDeviceLink/SDLCreateInteractionChoiceSetResponse.h', -'SmartDeviceLink/SDLDeleteCommandResponse.h', -'SmartDeviceLink/SDLDeleteFileResponse.h', -'SmartDeviceLink/SDLDeleteInteractionChoiceSetResponse.h', -'SmartDeviceLink/SDLDeleteSubMenuResponse.h', -'SmartDeviceLink/SDLDiagnosticMessageResponse.h', -'SmartDeviceLink/SDLDialNumberResponse.h', -'SmartDeviceLink/SDLEncodedSyncPDataResponse.h', -'SmartDeviceLink/SDLEndAudioPassThruResponse.h', -'SmartDeviceLink/SDLGenericResponse.h', -'SmartDeviceLink/SDLGetDTCsResponse.h', -'SmartDeviceLink/SDLGetSystemCapabilityResponse.h', -'SmartDeviceLink/SDLGetVehicleDataResponse.h', -'SmartDeviceLink/SDLGetWaypointsResponse.h', -'SmartDeviceLink/SDLListFilesResponse.h', -'SmartDeviceLink/SDLPerformAudioPassThruResponse.h', -'SmartDeviceLink/SDLPerformInteractionResponse.h', -'SmartDeviceLink/SDLPutFileResponse.h', -'SmartDeviceLink/SDLReadDIDResponse.h', -'SmartDeviceLink/SDLRegisterAppInterfaceResponse.h', -'SmartDeviceLink/SDLResetGlobalPropertiesResponse.h', -'SmartDeviceLink/SDLScrollableMessageResponse.h', -'SmartDeviceLink/SDLSendHapticDataResponse.h', -'SmartDeviceLink/SDLSendLocationResponse.h', -'SmartDeviceLink/SDLSetAppIconResponse.h', -'SmartDeviceLink/SDLSetDisplayLayoutResponse.h', -'SmartDeviceLink/SDLSetGlobalPropertiesResponse.h', -'SmartDeviceLink/SDLSetMediaClockTimerResponse.h', -'SmartDeviceLink/SDLShowConstantTBTResponse.h', -'SmartDeviceLink/SDLShowResponse.h', -'SmartDeviceLink/SDLSliderResponse.h', -'SmartDeviceLink/SDLSpeakResponse.h', -'SmartDeviceLink/SDLSubscribeButtonResponse.h', -'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h', -'SmartDeviceLink/SDLSubscribeWaypointsResponse.h', -'SmartDeviceLink/SDLSyncPDataResponse.h', -'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h', -'SmartDeviceLink/SDLUnsubscribeButtonResponse.h', -'SmartDeviceLink/SDLUnsubscribeVehicleDataResponse.h', -'SmartDeviceLink/SDLUnsubscribeWaypointsResponse.h', -'SmartDeviceLink/SDLUpdateTurnListResponse.h', -'SmartDeviceLink/SDLOnAppInterfaceUnregistered.h', -'SmartDeviceLink/SDLOnAudioPassThru.h', -'SmartDeviceLink/SDLOnButtonEvent.h', -'SmartDeviceLink/SDLOnButtonPress.h', -'SmartDeviceLink/SDLOnCommand.h', -'SmartDeviceLink/SDLOnDriverDistraction.h', -'SmartDeviceLink/SDLOnEncodedSyncPData.h', -'SmartDeviceLink/SDLOnHMIStatus.h', -'SmartDeviceLink/SDLOnHashChange.h', -'SmartDeviceLink/SDLOnKeyboardInput.h', -'SmartDeviceLink/SDLOnLanguageChange.h', -'SmartDeviceLink/SDLOnLockScreenStatus.h', -'SmartDeviceLink/SDLOnPermissionsChange.h', -'SmartDeviceLink/SDLOnSyncPData.h', -'SmartDeviceLink/SDLOnSystemRequest.h', -'SmartDeviceLink/SDLOnTBTClientState.h', -'SmartDeviceLink/SDLOnTouchEvent.h', -'SmartDeviceLink/SDLOnVehicleData.h', -'SmartDeviceLink/SDLOnWaypointChange.h', -'SmartDeviceLink/SDLAirbagStatus.h', -'SmartDeviceLink/SDLAppInfo.h', -'SmartDeviceLink/SDLAudioPassThruCapabilities.h', -'SmartDeviceLink/SDLBeltStatus.h', -'SmartDeviceLink/SDLBodyInformation.h', -'SmartDeviceLink/SDLButtonCapabilities.h', -'SmartDeviceLink/SDLChoice.h', -'SmartDeviceLink/SDLClusterModeStatus.h', -'SmartDeviceLink/SDLDIDResult.h', -'SmartDeviceLink/SDLDateTime.h', -'SmartDeviceLink/SDLDeviceInfo.h', -'SmartDeviceLink/SDLDeviceStatus.h', -'SmartDeviceLink/SDLDisplayCapabilities.h', -'SmartDeviceLink/SDLECallInfo.h', -'SmartDeviceLink/SDLEmergencyEvent.h', -'SmartDeviceLink/SDLGPSData.h', -'SmartDeviceLink/SDLHMICapabilities.h', -'SmartDeviceLink/SDLHMIPermissions.h', -'SmartDeviceLink/SDLHeadLampStatus.h', -'SmartDeviceLink/SDLImage.h', -'SmartDeviceLink/SDLImageField.h', -'SmartDeviceLink/SDLImageResolution.h', -'SmartDeviceLink/SDLKeyboardProperties.h', -'SmartDeviceLink/SDLMenuParams.h', -'SmartDeviceLink/SDLMyKey.h', -'SmartDeviceLink/SDLNavigationCapability.h', -'SmartDeviceLink/SDLOasisAddress.h', -'SmartDeviceLink/SDLParameterPermissions.h', -'SmartDeviceLink/SDLPermissionItem.h', -'SmartDeviceLink/SDLPhoneCapability.h', -'SmartDeviceLink/SDLPresetBankCapabilities.h', -'SmartDeviceLink/SDLScreenParams.h', -'SmartDeviceLink/SDLSingleTireStatus.h', -'SmartDeviceLink/SDLSoftButton.h', -'SmartDeviceLink/SDLSoftButtonCapabilities.h', -'SmartDeviceLink/SDLSpatialStruct.h', -'SmartDeviceLink/SDLStartTime.h', -'SmartDeviceLink/SDLSyncMsgVersion.h', -'SmartDeviceLink/SDLSystemCapability.h', -'SmartDeviceLink/SDLTTSChunk.h', -'SmartDeviceLink/SDLTextField.h', -'SmartDeviceLink/SDLTireStatus.h', -'SmartDeviceLink/SDLTouchCoord.h', -'SmartDeviceLink/SDLTouchEvent.h', -'SmartDeviceLink/SDLTouchEventCapabilities.h', -'SmartDeviceLink/SDLTurn.h', -'SmartDeviceLink/SDLVRHelpItem.h', -'SmartDeviceLink/SDLVehicleDataResult.h', -'SmartDeviceLink/SDLVehicleType.h', 'SmartDeviceLink/SDLAmbientLightStatus.h', 'SmartDeviceLink/SDLAppHMIType.h', +'SmartDeviceLink/SDLAppInfo.h', 'SmartDeviceLink/SDLAppInterfaceUnregisteredReason.h', +'SmartDeviceLink/SDLArtwork.h', +'SmartDeviceLink/SDLAudioPassThruCapabilities.h', 'SmartDeviceLink/SDLAudioStreamingState.h', 'SmartDeviceLink/SDLAudioType.h', +'SmartDeviceLink/SDLBeltStatus.h', 'SmartDeviceLink/SDLBitsPerSample.h', +'SmartDeviceLink/SDLBodyInformation.h', +'SmartDeviceLink/SDLButtonCapabilities.h', 'SmartDeviceLink/SDLButtonEventMode.h', 'SmartDeviceLink/SDLButtonName.h', 'SmartDeviceLink/SDLButtonPressMode.h', 'SmartDeviceLink/SDLCarModeStatus.h', +'SmartDeviceLink/SDLChangeRegistration.h', +'SmartDeviceLink/SDLChangeRegistrationResponse.h', 'SmartDeviceLink/SDLCharacterSet.h', +'SmartDeviceLink/SDLChoice.h', +'SmartDeviceLink/SDLClusterModeStatus.h', 'SmartDeviceLink/SDLCompassDirection.h', 'SmartDeviceLink/SDLComponentVolumeStatus.h', +'SmartDeviceLink/SDLConfiguration.h', +'SmartDeviceLink/SDLCreateInteractionChoiceSet.h', +'SmartDeviceLink/SDLCreateInteractionChoiceSetResponse.h', +'SmartDeviceLink/SDLDateTime.h', +'SmartDeviceLink/SDLDeleteCommand.h', +'SmartDeviceLink/SDLDeleteCommandResponse.h', +'SmartDeviceLink/SDLDeleteFile.h', +'SmartDeviceLink/SDLDeleteFileResponse.h', +'SmartDeviceLink/SDLDeleteInteractionChoiceSet.h', +'SmartDeviceLink/SDLDeleteInteractionChoiceSetResponse.h', +'SmartDeviceLink/SDLDeleteSubMenu.h', +'SmartDeviceLink/SDLDeleteSubMenuResponse.h', 'SmartDeviceLink/SDLDeliveryMode.h', +'SmartDeviceLink/SDLDeviceInfo.h', 'SmartDeviceLink/SDLDeviceLevelStatus.h', +'SmartDeviceLink/SDLDeviceStatus.h', +'SmartDeviceLink/SDLDiagnosticMessage.h', +'SmartDeviceLink/SDLDiagnosticMessageResponse.h', +'SmartDeviceLink/SDLDialNumber.h', +'SmartDeviceLink/SDLDialNumberResponse.h', +'SmartDeviceLink/SDLDIDResult.h', 'SmartDeviceLink/SDLDimension.h', +'SmartDeviceLink/SDLDisplayCapabilities.h', 'SmartDeviceLink/SDLDisplayType.h', 'SmartDeviceLink/SDLDriverDistractionState.h', 'SmartDeviceLink/SDLECallConfirmationStatus.h', +'SmartDeviceLink/SDLECallInfo.h', +'SmartDeviceLink/SDLEmergencyEvent.h', 'SmartDeviceLink/SDLEmergencyEventType.h', +'SmartDeviceLink/SDLEncodedSyncPData.h', +'SmartDeviceLink/SDLEncodedSyncPDataResponse.h', +'SmartDeviceLink/SDLEndAudioPassThru.h', +'SmartDeviceLink/SDLEndAudioPassThruResponse.h', +'SmartDeviceLink/SDLEnum.h', +'SmartDeviceLink/SDLErrorConstants.h', +'SmartDeviceLink/SDLFile.h', +'SmartDeviceLink/SDLFileManager.h', +'SmartDeviceLink/SDLFileManagerConstants.h', 'SmartDeviceLink/SDLFileType.h', 'SmartDeviceLink/SDLFuelCutoffStatus.h', +'SmartDeviceLink/SDLGenericResponse.h', +'SmartDeviceLink/SDLGetDTCs.h', +'SmartDeviceLink/SDLGetDTCsResponse.h', +'SmartDeviceLink/SDLGetSystemCapability.h', +'SmartDeviceLink/SDLGetSystemCapabilityResponse.h', +'SmartDeviceLink/SDLGetVehicleData.h', +'SmartDeviceLink/SDLGetVehicleDataResponse.h', +'SmartDeviceLink/SDLGetWaypoints.h', +'SmartDeviceLink/SDLGetWaypointsResponse.h', 'SmartDeviceLink/SDLGlobalProperty.h', +'SmartDeviceLink/SDLGPSData.h', +'SmartDeviceLink/SDLHeadLampStatus.h', +'SmartDeviceLink/SDLHMICapabilities.h', 'SmartDeviceLink/SDLHMILevel.h', +'SmartDeviceLink/SDLHMIPermissions.h', 'SmartDeviceLink/SDLHMIZoneCapabilities.h', +'SmartDeviceLink/SDLIAPSessionDelegate.h', +'SmartDeviceLink/SDLIAPTransport.h', 'SmartDeviceLink/SDLIgnitionStableStatus.h', 'SmartDeviceLink/SDLIgnitionStatus.h', +'SmartDeviceLink/SDLImage.h', +'SmartDeviceLink/SDLImageField.h', 'SmartDeviceLink/SDLImageFieldName.h', +'SmartDeviceLink/SDLImageResolution.h', 'SmartDeviceLink/SDLImageType.h', 'SmartDeviceLink/SDLInteractionMode.h', 'SmartDeviceLink/SDLKeyboardEvent.h', 'SmartDeviceLink/SDLKeyboardLayout.h', +'SmartDeviceLink/SDLKeyboardProperties.h', 'SmartDeviceLink/SDLKeypressMode.h', 'SmartDeviceLink/SDLLanguage.h', 'SmartDeviceLink/SDLLayoutMode.h', +'SmartDeviceLink/SDLLifecycleConfiguration.h', +'SmartDeviceLink/SDLListFiles.h', +'SmartDeviceLink/SDLListFilesResponse.h', 'SmartDeviceLink/SDLLocationCoordinate.h', 'SmartDeviceLink/SDLLocationDetails.h', +'SmartDeviceLink/SDLLockScreenConfiguration.h', 'SmartDeviceLink/SDLLockScreenStatus.h', +'SmartDeviceLink/SDLLockScreenViewController.h', +'SmartDeviceLink/SDLLogConfiguration.h', +'SmartDeviceLink/SDLLogConstants.h', +'SmartDeviceLink/SDLLogFileModule.h', +'SmartDeviceLink/SDLLogFilter.h', +'SmartDeviceLink/SDLLogMacros.h', +'SmartDeviceLink/SDLLogManager.h', +'SmartDeviceLink/SDLLogTarget.h', +'SmartDeviceLink/SDLLogTargetAppleSystemLog.h', +'SmartDeviceLink/SDLLogTargetFile.h', +'SmartDeviceLink/SDLLogTargetOSLog.h', +'SmartDeviceLink/SDLMacros.h', 'SmartDeviceLink/SDLMaintenanceModeStatus.h', +'SmartDeviceLink/SDLManager.h', +'SmartDeviceLink/SDLManagerDelegate.h', 'SmartDeviceLink/SDLMediaClockFormat.h', -'SmartDeviceLink/SDLPRNDL.h', +'SmartDeviceLink/SDLMenuParams.h', +'SmartDeviceLink/SDLMetadataTags.h', +'SmartDeviceLink/SDLMetadataType.h', +'SmartDeviceLink/SDLMyKey.h', +'SmartDeviceLink/SDLNavigationCapability.h', +'SmartDeviceLink/SDLNotificationConstants.h', +'SmartDeviceLink/SDLOasisAddress.h', +'SmartDeviceLink/SDLOnAppInterfaceUnregistered.h', +'SmartDeviceLink/SDLOnAudioPassThru.h', +'SmartDeviceLink/SDLOnButtonEvent.h', +'SmartDeviceLink/SDLOnButtonPress.h', +'SmartDeviceLink/SDLOnCommand.h', +'SmartDeviceLink/SDLOnDriverDistraction.h', +'SmartDeviceLink/SDLOnEncodedSyncPData.h', +'SmartDeviceLink/SDLOnHashChange.h', +'SmartDeviceLink/SDLOnHMIStatus.h', +'SmartDeviceLink/SDLOnKeyboardInput.h', +'SmartDeviceLink/SDLOnLanguageChange.h', +'SmartDeviceLink/SDLOnLockScreenStatus.h', +'SmartDeviceLink/SDLOnPermissionsChange.h', +'SmartDeviceLink/SDLOnSyncPData.h', +'SmartDeviceLink/SDLOnSystemRequest.h', +'SmartDeviceLink/SDLOnTBTClientState.h', +'SmartDeviceLink/SDLOnTouchEvent.h', +'SmartDeviceLink/SDLOnVehicleData.h', +'SmartDeviceLink/SDLOnWaypointChange.h', +'SmartDeviceLink/SDLParameterPermissions.h', +'SmartDeviceLink/SDLPerformAudioPassThru.h', +'SmartDeviceLink/SDLPerformAudioPassThruResponse.h', +'SmartDeviceLink/SDLPerformInteraction.h', +'SmartDeviceLink/SDLPerformInteractionResponse.h', +'SmartDeviceLink/SDLPermissionConstants.h', +'SmartDeviceLink/SDLPermissionItem.h', +'SmartDeviceLink/SDLPermissionManager.h', 'SmartDeviceLink/SDLPermissionStatus.h', +'SmartDeviceLink/SDLPhoneCapability.h', +'SmartDeviceLink/SDLPinchGesture.h', 'SmartDeviceLink/SDLPowerModeQualificationStatus.h', 'SmartDeviceLink/SDLPowerModeStatus.h', 'SmartDeviceLink/SDLPredefinedLayout.h', 'SmartDeviceLink/SDLPrerecordedSpeech.h', +'SmartDeviceLink/SDLPresetBankCapabilities.h', 'SmartDeviceLink/SDLPrimaryAudioSource.h', -'SmartDeviceLink/SDLRPCMessageType.h', +'SmartDeviceLink/SDLPRNDL.h', +'SmartDeviceLink/SDLProtocol.h', +'SmartDeviceLink/SDLProtocolHeader.h', +'SmartDeviceLink/SDLProtocolListener.h', +'SmartDeviceLink/SDLProtocolMessage.h', +'SmartDeviceLink/SDLProxy.h', +'SmartDeviceLink/SDLProxyFactory.h', +'SmartDeviceLink/SDLProxyListener.h', +'SmartDeviceLink/SDLPutFile.h', +'SmartDeviceLink/SDLPutFileResponse.h', +'SmartDeviceLink/SDLReadDID.h', +'SmartDeviceLink/SDLReadDIDResponse.h', +'SmartDeviceLink/SDLRegisterAppInterface.h', +'SmartDeviceLink/SDLRegisterAppInterfaceResponse.h', 'SmartDeviceLink/SDLRequestType.h', +'SmartDeviceLink/SDLResetGlobalProperties.h', +'SmartDeviceLink/SDLResetGlobalPropertiesResponse.h', 'SmartDeviceLink/SDLResult.h', +'SmartDeviceLink/SDLRPCMessage.h', +'SmartDeviceLink/SDLRPCMessageType.h', +'SmartDeviceLink/SDLRPCNotification.h', +'SmartDeviceLink/SDLRPCNotificationNotification.h', +'SmartDeviceLink/SDLRPCRequest.h', +'SmartDeviceLink/SDLRPCResponse.h', +'SmartDeviceLink/SDLRPCResponseNotification.h', +'SmartDeviceLink/SDLRPCStruct.h', 'SmartDeviceLink/SDLSamplingRate.h', +'SmartDeviceLink/SDLScreenParams.h', +'SmartDeviceLink/SDLScrollableMessage.h', +'SmartDeviceLink/SDLScrollableMessageResponse.h', +'SmartDeviceLink/SDLSecurityType.h', +'SmartDeviceLink/SDLSendHapticData.h', +'SmartDeviceLink/SDLSendHapticDataResponse.h', +'SmartDeviceLink/SDLSendLocation.h', +'SmartDeviceLink/SDLSendLocationResponse.h', +'SmartDeviceLink/SDLSetAppIcon.h', +'SmartDeviceLink/SDLSetAppIconResponse.h', +'SmartDeviceLink/SDLSetDisplayLayout.h', +'SmartDeviceLink/SDLSetDisplayLayoutResponse.h', +'SmartDeviceLink/SDLSetGlobalProperties.h', +'SmartDeviceLink/SDLSetGlobalPropertiesResponse.h', +'SmartDeviceLink/SDLSetMediaClockTimer.h', +'SmartDeviceLink/SDLSetMediaClockTimerResponse.h', +'SmartDeviceLink/SDLShow.h', +'SmartDeviceLink/SDLShowConstantTBT.h', +'SmartDeviceLink/SDLShowConstantTBTResponse.h', +'SmartDeviceLink/SDLShowResponse.h', +'SmartDeviceLink/SDLSingleTireStatus.h', +'SmartDeviceLink/SDLSlider.h', +'SmartDeviceLink/SDLSliderResponse.h', +'SmartDeviceLink/SDLSoftButton.h', +'SmartDeviceLink/SDLSoftButtonCapabilities.h', 'SmartDeviceLink/SDLSoftButtonType.h', +'SmartDeviceLink/SDLSpatialStruct.h', +'SmartDeviceLink/SDLSpeak.h', +'SmartDeviceLink/SDLSpeakResponse.h', 'SmartDeviceLink/SDLSpeechCapabilities.h', +'SmartDeviceLink/SDLStartTime.h', +'SmartDeviceLink/SDLStreamingMediaConfiguration.h', +'SmartDeviceLink/SDLStreamingMediaManager.h', +'SmartDeviceLink/SDLStreamingMediaManagerConstants.h', +'SmartDeviceLink/SDLSubscribeButton.h', +'SmartDeviceLink/SDLSubscribeButtonResponse.h', +'SmartDeviceLink/SDLSubscribeVehicleData.h', +'SmartDeviceLink/SDLSubscribeVehicleDataResponse.h', +'SmartDeviceLink/SDLSubscribeWaypoints.h', +'SmartDeviceLink/SDLSubscribeWaypointsResponse.h', +'SmartDeviceLink/SDLSyncMsgVersion.h', +'SmartDeviceLink/SDLSyncPData.h', +'SmartDeviceLink/SDLSyncPDataResponse.h', 'SmartDeviceLink/SDLSystemAction.h', +'SmartDeviceLink/SDLSystemCapability.h', 'SmartDeviceLink/SDLSystemCapabilityType.h', 'SmartDeviceLink/SDLSystemContext.h', 'SmartDeviceLink/SDLTBTState.h', +'SmartDeviceLink/SDLTCPTransport.h', 'SmartDeviceLink/SDLTextAlignment.h', +'SmartDeviceLink/SDLTextField.h', 'SmartDeviceLink/SDLTextFieldName.h', 'SmartDeviceLink/SDLTimerMode.h', +'SmartDeviceLink/SDLTireStatus.h', +'SmartDeviceLink/SDLTouch.h', +'SmartDeviceLink/SDLTouchCoord.h', +'SmartDeviceLink/SDLTouchEvent.h', +'SmartDeviceLink/SDLTouchEventCapabilities.h', +'SmartDeviceLink/SDLTouchManager.h', +'SmartDeviceLink/SDLTouchManagerDelegate.h', 'SmartDeviceLink/SDLTouchType.h', +'SmartDeviceLink/SDLTransportDelegate.h', 'SmartDeviceLink/SDLTriggerSource.h', +'SmartDeviceLink/SDLTTSChunk.h', +'SmartDeviceLink/SDLTurn.h', +'SmartDeviceLink/SDLUnregisterAppInterface.h', +'SmartDeviceLink/SDLUnregisterAppInterfaceResponse.h', +'SmartDeviceLink/SDLUnsubscribeButton.h', +'SmartDeviceLink/SDLUnsubscribeButtonResponse.h', +'SmartDeviceLink/SDLUnsubscribeVehicleData.h', +'SmartDeviceLink/SDLUnsubscribeVehicleDataResponse.h', +'SmartDeviceLink/SDLUnsubscribeWaypoints.h', +'SmartDeviceLink/SDLUnsubscribeWaypointsResponse.h', 'SmartDeviceLink/SDLUpdateMode.h', -'SmartDeviceLink/SDLVRCapabilities.h', +'SmartDeviceLink/SDLUpdateTurnList.h', +'SmartDeviceLink/SDLUpdateTurnListResponse.h', 'SmartDeviceLink/SDLVehicleDataActiveStatus.h', 'SmartDeviceLink/SDLVehicleDataEventStatus.h', 'SmartDeviceLink/SDLVehicleDataNotificationStatus.h', +'SmartDeviceLink/SDLVehicleDataResult.h', 'SmartDeviceLink/SDLVehicleDataResultCode.h', 'SmartDeviceLink/SDLVehicleDataStatus.h', 'SmartDeviceLink/SDLVehicleDataType.h', +'SmartDeviceLink/SDLVehicleType.h', +'SmartDeviceLink/SDLVideoStreamingCapability.h', +'SmartDeviceLink/SDLVideoStreamingCodec.h', +'SmartDeviceLink/SDLVideoStreamingFormat.h', +'SmartDeviceLink/SDLVideoStreamingProtocol.h', +'SmartDeviceLink/SDLVrCapabilities.h', +'SmartDeviceLink/SDLVrHelpItem.h', 'SmartDeviceLink/SDLWarningLightStatus.h', 'SmartDeviceLink/SDLWaypointType.h', 'SmartDeviceLink/SDLWiperStatus.h', -'SmartDeviceLink/SDLConfiguration.h', -'SmartDeviceLink/SDLLifecycleConfiguration.h', -'SmartDeviceLink/SDLLockScreenConfiguration.h', -'SmartDeviceLink/SDLArtwork.h', -'SmartDeviceLink/SDLFile.h', -'SmartDeviceLink/SDLFileManager.h', -'SmartDeviceLink/SDLFileManagerConstants.h', -'SmartDeviceLink/SDLLockScreenViewController.h', -'SmartDeviceLink/SDLManager.h', -'SmartDeviceLink/SDLManagerDelegate.h', -'SmartDeviceLink/SDLPermissionConstants.h', -'SmartDeviceLink/SDLPermissionManager.h', -'SmartDeviceLink/NSNumber+NumberType.h', -'SmartDeviceLink/SDLErrorConstants.h', -'SmartDeviceLink/SDLNotificationConstants.h', -'SmartDeviceLink/SDLRequestHandler.h', -'SmartDeviceLink/SDLRPCNotificationNotification.h', -'SmartDeviceLink/SDLRPCResponseNotification.h' +'SmartDeviceLink/SmartDeviceLink.h', ] +end + +s.subspec 'Swift' do |ss| +ss.dependency 'SmartDeviceLink-iOS/Default' +ss.source_files = 'SmartDeviceLinkSwift/*.swift' +end end diff --git a/SmartDeviceLink/Assets/Base.lproj/SDLLockScreen.storyboard b/SmartDeviceLink/Assets/Base.lproj/SDLLockScreen.storyboard index 9eb887c73..b2b1a555a 100644 --- a/SmartDeviceLink/Assets/Base.lproj/SDLLockScreen.storyboard +++ b/SmartDeviceLink/Assets/Base.lproj/SDLLockScreen.storyboard @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="UTF-8"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="sao-xX-Ugl"> +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="sao-xX-Ugl"> <device id="retina4_7" orientation="portrait"> <adaptation id="fullscreen"/> </device> <dependencies> <deployment version="1808" identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> </dependencies> diff --git a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.h b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.h new file mode 100644 index 000000000..674c20215 --- /dev/null +++ b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.h @@ -0,0 +1,23 @@ +// +// CVPixelBufferRef+SDLUtil.h +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 3/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import <CoreVideo/CVPixelBuffer.h> + +NS_ASSUME_NONNULL_BEGIN + +/** + Take a CVPixelBuffer frame and append some text onto it, attempting to fit it to the rect. This is used for a "blank" screen when streaming navigation is pushed to the background or otherwise disabled in progress. + + @param pixelBuffer The pixel buffer to draw text over + @param text The text to draw + @return Whether or not it succeeded. + */ +Boolean CVPixelBufferAddText(CVPixelBufferRef CV_NONNULL pixelBuffer, NSString *text); + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m new file mode 100644 index 000000000..5f561de00 --- /dev/null +++ b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m @@ -0,0 +1,103 @@ +// +// CVPixelBufferRef+SDLUtil.m +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 3/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "CVPixelBufferRef+SDLUtil.h" + +NS_ASSUME_NONNULL_BEGIN + +UIFont * _Nullable sdl_findFontSizeToFitText(CGSize size, NSString *text) { + CGFloat fontSize = 100; + + do { + CGSize textSize = [text boundingRectWithSize:CGSizeMake(size.width, CGFLOAT_MAX) + options:NSStringDrawingUsesLineFragmentOrigin + attributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:fontSize]} + context:nil].size; + + if (textSize.height <= size.height) { + break; + } + + fontSize -= 10.0; + } while (fontSize > 0.0); + + return (fontSize > 0) ? [UIFont boldSystemFontOfSize:fontSize] : nil; +} + +UIImage * _Nullable sdl_createTextImage(NSString *text, CGSize size) { + UIFont *font = sdl_findFontSizeToFitText(size, text); + + if (!font) { + NSLog(@"Text cannot fit inside frame"); + return nil; + } + + CGRect frame = CGRectMake(0, 0, size.width, size.height); + UIGraphicsBeginImageContextWithOptions(frame.size, NO, 1.0); + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor); + CGContextFillRect(context, frame); + CGContextSaveGState(context); + + NSMutableParagraphStyle* textStyle = NSMutableParagraphStyle.defaultParagraphStyle.mutableCopy; + textStyle.alignment = NSTextAlignmentCenter; + + NSDictionary* textAttributes = @{ + NSFontAttributeName: font, + NSForegroundColorAttributeName: [UIColor whiteColor], + NSParagraphStyleAttributeName: textStyle + }; + CGRect textFrame = [text boundingRectWithSize:size + options:NSStringDrawingUsesLineFragmentOrigin + attributes:textAttributes + context:nil]; + + CGRect textInset = CGRectMake(0, + (frame.size.height - CGRectGetHeight(textFrame)) / 2.0, + frame.size.width, + frame.size.height); + + [text drawInRect:textInset + withAttributes:textAttributes]; + + CGContextRestoreGState(context); + UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); + + return image; +} + +Boolean CVPixelBufferAddText(CVPixelBufferRef CV_NONNULL pixelBuffer, NSString *text) { + size_t width = CVPixelBufferGetWidth(pixelBuffer); + size_t height = CVPixelBufferGetHeight(pixelBuffer); + + UIImage *image = sdl_createTextImage(text, CGSizeMake(width, height)); + if (!image) { + NSLog(@"Could not create text image."); + return false; + } + + CVPixelBufferLockBaseAddress(pixelBuffer, 0); + void *data = CVPixelBufferGetBaseAddress(pixelBuffer); + + CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef context = CGBitmapContextCreate(data, width, height, + 8, CVPixelBufferGetBytesPerRow(pixelBuffer), rgbColorSpace, + kCGBitmapByteOrder32Little | + kCGImageAlphaPremultipliedFirst); + CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.CGImage); + CGColorSpaceRelease(rgbColorSpace); + + CGContextRelease(context); + + CVPixelBufferUnlockBaseAddress(pixelBuffer, 0); + + return true; +} + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/Info.plist b/SmartDeviceLink/Info.plist index 827e5db1e..e790eb616 100644 --- a/SmartDeviceLink/Info.plist +++ b/SmartDeviceLink/Info.plist @@ -15,7 +15,7 @@ <key>CFBundlePackageType</key> <string>FMWK</string> <key>CFBundleShortVersionString</key> - <string>4.6.1</string> + <string>5.0.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> diff --git a/SmartDeviceLink/SDLConfiguration.h b/SmartDeviceLink/SDLConfiguration.h index 679f16e01..52706376b 100644 --- a/SmartDeviceLink/SDLConfiguration.h +++ b/SmartDeviceLink/SDLConfiguration.h @@ -11,6 +11,7 @@ @class SDLLifecycleConfiguration; @class SDLLockScreenConfiguration; @class SDLLogConfiguration; +@class SDLStreamingMediaConfiguration; NS_ASSUME_NONNULL_BEGIN @@ -26,19 +27,41 @@ NS_ASSUME_NONNULL_BEGIN */ @property (copy, nonatomic, readonly) SDLLockScreenConfiguration *lockScreenConfig; - /** The log configuration. */ @property (copy, nonatomic, readonly) SDLLogConfiguration *loggingConfig; /** + The configuration + */ +@property (copy, nonatomic, readonly) SDLStreamingMediaConfiguration *streamingMediaConfig; + +/** + Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. + + @param lifecycleConfiguration The lifecycle configuration to be used. + @return The configuration + */ +- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfiguration __deprecated_msg(("Use initWithLifecycle:lockScreen:logging: instead")); + +/** Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. @param lifecycleConfiguration The lifecycle configuration to be used. @return The configuration */ -- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfiguration; ++ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfiguration __deprecated_msg(("Use configurationWithLifecycle:lockScreen:logging: instead")); + +/** + * Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. + * + * @param lifecycleConfig The lifecycle configuration to be used. + * @param lockScreenConfig The lockscreen configuration to be used, or `enabledConfiguration` if nil. + * + * @return The configuration + */ +- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig __deprecated_msg(("Use initWithLifecycle:lockScreen:logging: instead")); /** * Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. @@ -48,7 +71,7 @@ NS_ASSUME_NONNULL_BEGIN * * @return The configuration */ -- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig; ++ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig __deprecated_msg(("Use configurationWithLifecycle:lockScreen:logging: instead")); /** Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and logging configuration. @@ -61,32 +84,36 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig; /** - Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. + Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and logging configuration. - @param lifecycleConfiguration The lifecycle configuration to be used. + @param lifecycleConfig The lifecycle configuration to be used. + @param lockScreenConfig The lockscreen configuration to be used, or `enabledConfiguration` if nil. + @param logConfig The logging configuration to be used, or `defaultConfiguration` if nil. @return The configuration */ -+ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfiguration; ++ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig; /** - * Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and a default logging configuration. - * - * @param lifecycleConfig The lifecycle configuration to be used. - * @param lockScreenConfig The lockscreen configuration to be used, or `enabledConfiguration` if nil. - * - * @return The configuration + Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, logging, and streaming media configuration. + + @param lifecycleConfig The lifecycle configuration to be used. + @param lockScreenConfig The lockscreen configuration to be used, or `enabledConfiguration` if nil. + @param logConfig The logging configuration to be used, or `defaultConfiguration` if nil. + @param streamingMediaConfig The streaming media configuration to be used, or nil because it is not needed. + @return The configuration */ -+ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig; +- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig streamingMedia:(nullable SDLStreamingMediaConfiguration *)streamingMediaConfig; /** - Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, and logging configuration. + Create a new configuration to be passed into SDLManager with a custom lifecycle, lock screen, logging, and streaming media configuration. @param lifecycleConfig The lifecycle configuration to be used. @param lockScreenConfig The lockscreen configuration to be used, or `enabledConfiguration` if nil. @param logConfig The logging configuration to be used, or `defaultConfiguration` if nil. + @param streamingMediaConfig The streaming media configuration to be used, or nil because it is not needed. @return The configuration */ -+ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig; ++ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig streamingMedia:(nullable SDLStreamingMediaConfiguration *)streamingMediaConfig; @end diff --git a/SmartDeviceLink/SDLConfiguration.m b/SmartDeviceLink/SDLConfiguration.m index 550f68496..ebb7477d9 100644 --- a/SmartDeviceLink/SDLConfiguration.m +++ b/SmartDeviceLink/SDLConfiguration.m @@ -11,6 +11,7 @@ #import "SDLLifecycleConfiguration.h" #import "SDLLockScreenConfiguration.h" #import "SDLLogConfiguration.h" +#import "SDLStreamingMediaConfiguration.h" NS_ASSUME_NONNULL_BEGIN @@ -49,6 +50,29 @@ NS_ASSUME_NONNULL_BEGIN return [[self alloc] initWithLifecycle:lifecycleConfig lockScreen:lockScreenConfig logging:logConfig]; } +- (instancetype)initWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig streamingMedia:(nullable SDLStreamingMediaConfiguration *)streamingMediaConfig { + self = [super init]; + if (!self) { + return nil; + } + + _lifecycleConfig = lifecycleConfig; + _lockScreenConfig = lockScreenConfig ?: [SDLLockScreenConfiguration enabledConfiguration]; + _loggingConfig = logConfig ?: [SDLLogConfiguration defaultConfiguration]; + + if (_streamingMediaConfig != nil) { + NSAssert(!([_lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || [_lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection]), @"You should only set a streaming media configuration if your app is a NAVIGATION or PROJECTION HMI type"); + _streamingMediaConfig = streamingMediaConfig; + } else { + NSAssert(([_lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] || [_lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection]), @"If your app is a NAVIGATION or PROJECTION HMI type, you must set a streaming media configuration on SDLConfiguration"); + } + + return self; +} + ++ (instancetype)configurationWithLifecycle:(SDLLifecycleConfiguration *)lifecycleConfig lockScreen:(nullable SDLLockScreenConfiguration *)lockScreenConfig logging:(nullable SDLLogConfiguration *)logConfig streamingMedia:(nullable SDLStreamingMediaConfiguration *)streamingMediaConfig { + return [[self alloc] initWithLifecycle:lifecycleConfig lockScreen:lockScreenConfig logging:logConfig streamingMedia:streamingMediaConfig]; +} #pragma mark - NSCopying diff --git a/SmartDeviceLink/SDLLifecycleConfiguration.h b/SmartDeviceLink/SDLLifecycleConfiguration.h index 36b11ea63..33a9afd2c 100644 --- a/SmartDeviceLink/SDLLifecycleConfiguration.h +++ b/SmartDeviceLink/SDLLifecycleConfiguration.h @@ -6,7 +6,7 @@ // Copyright © 2015 smartdevicelink. All rights reserved. // -#import <UIKit/UIKit.h> +#import <Foundation/Foundation.h> #import "SDLAppHMIType.h" #import "SDLLanguage.h" @@ -14,8 +14,6 @@ @class SDLFile; @class SDLTTSChunk; -@protocol SDLSecurityType; - NS_ASSUME_NONNULL_BEGIN @@ -118,11 +116,6 @@ NS_ASSUME_NONNULL_BEGIN */ @property (copy, nonatomic, nullable) NSArray<NSString *> *voiceRecognitionCommandNames; -/** - * Set security managers which could be used. This is primarily used with video streaming applications to authenticate and perhaps encrypt traffic data. - */ -@property (copy, nonatomic, nullable) NSArray<Class<SDLSecurityType>> *securityManagers; - @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLLifecycleConfiguration.m b/SmartDeviceLink/SDLLifecycleConfiguration.m index c5b9e7071..1688246bd 100644 --- a/SmartDeviceLink/SDLLifecycleConfiguration.m +++ b/SmartDeviceLink/SDLLifecycleConfiguration.m @@ -9,6 +9,7 @@ #import "SDLLifecycleConfiguration.h" #import "SDLFile.h" +#import "SDLVideoEncoder.h" static NSString *const DefaultTCPIPAddress = @"192.168.0.1"; static UInt16 const DefaultTCPIPPort = 12345; diff --git a/SmartDeviceLink/SDLLifecycleManager.h b/SmartDeviceLink/SDLLifecycleManager.h index 18e45cfb1..18450f218 100644 --- a/SmartDeviceLink/SDLLifecycleManager.h +++ b/SmartDeviceLink/SDLLifecycleManager.h @@ -60,7 +60,7 @@ typedef void (^SDLManagerReadyBlock)(BOOL success, NSError *_Nullable error); @property (strong, nonatomic) SDLFileManager *fileManager; @property (strong, nonatomic) SDLPermissionManager *permissionManager; -@property (strong, nonatomic, readonly, nullable) SDLStreamingMediaManager *streamManager; +@property (strong, nonatomic, nullable) SDLStreamingMediaManager *streamManager; @property (strong, nonatomic) SDLLockScreenManager *lockScreenManager; @property (strong, nonatomic, readonly) SDLNotificationDispatcher *notificationDispatcher; diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m index fac00b535..e38e5084c 100644 --- a/SmartDeviceLink/SDLLifecycleManager.m +++ b/SmartDeviceLink/SDLLifecycleManager.m @@ -11,6 +11,7 @@ #import "SDLLifecycleManager.h" #import "NSMapTable+Subscripting.h" +#import "SDLAbstractProtocol.h" #import "SDLConfiguration.h" #import "SDLConnectionManagerType.h" #import "SDLLogMacros.h" @@ -40,6 +41,8 @@ #import "SDLResult.h" #import "SDLSetAppIcon.h" #import "SDLStateMachine.h" +#import "SDLStreamingMediaConfiguration.h" +#import "SDLStreamingMediaManager.h" #import "SDLUnregisterAppInterface.h" @@ -77,7 +80,7 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Lifecycle - (instancetype)init { - return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration disabledConfiguration]] delegate:nil]; + return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration disabledConfiguration] logging:[SDLLogConfiguration defaultConfiguration]] delegate:nil]; } - (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate:(nullable id<SDLManagerDelegate>)delegate { @@ -86,6 +89,8 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; return nil; } + SDLLogV(@"Creating Lifecycle Manager"); + // Dependencies _configuration = [configuration copy]; _delegate = delegate; @@ -104,6 +109,14 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; _fileManager = [[SDLFileManager alloc] initWithConnectionManager:self]; _permissionManager = [[SDLPermissionManager alloc] init]; _lockScreenManager = [[SDLLockScreenManager alloc] initWithConfiguration:_configuration.lockScreenConfig notificationDispatcher:_notificationDispatcher presenter:[[SDLLockScreenPresenter alloc] init]]; + + if ([configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeNavigation] + || [configuration.lifecycleConfig.appType isEqualToEnum:SDLAppHMITypeProjection]) { + SDLLogV(@"Creating StreamingMediaManager for app type: %@", configuration.lifecycleConfig.appType); + _streamManager = [[SDLStreamingMediaManager alloc] initWithEncryption:configuration.streamingMediaConfig.maximumDesiredEncryption videoEncoderSettings:configuration.streamingMediaConfig.customVideoEncoderSettings]; + } else { + SDLLogV(@"Skipping StreamingMediaManager setup due to app type"); + } // Notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(transportDidConnect) name:SDLTransportDidConnect object:_notificationDispatcher]; @@ -136,10 +149,6 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; #pragma mark Getters -- (nullable SDLStreamingMediaManager *)streamManager { - return self.proxy.streamingMediaManager; -} - - (SDLState *)lifecycleState { return self.lifecycleStateMachine.currentState; } @@ -212,8 +221,8 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; - (void)didEnterStateConnected { // If we have security managers, add them to the proxy - if (self.configuration.lifecycleConfig.securityManagers != nil) { - [self.proxy addSecurityManagers:self.configuration.lifecycleConfig.securityManagers forAppId:self.configuration.lifecycleConfig.appId]; + if (self.configuration.streamingMediaConfig.securityManagers != nil) { + [self.proxy addSecurityManagers:self.configuration.streamingMediaConfig.securityManagers forAppId:self.configuration.lifecycleConfig.appId]; } // Build a register app interface request with the configuration data @@ -265,6 +274,19 @@ SDLLifecycleState *const SDLLifecycleStateReady = @"Ready"; dispatch_group_leave(managerGroup); }]; + + + if (self.streamManager != nil) { + dispatch_group_enter(managerGroup); + } + + [self.streamManager startWithProtocol:self.proxy.protocol completionHandler:^(BOOL success, NSError * _Nullable error) { + if (!success) { + SDLLogE(@"Streaming media manager was unable to start; error: %@", error); + } + + dispatch_group_leave(managerGroup); + }]; // We're done synchronously calling all startup methods, so we can now wait. dispatch_group_leave(managerGroup); diff --git a/SmartDeviceLink/SDLMacros.h b/SmartDeviceLink/SDLMacros.h index 146555832..1ab0bb6d0 100644 --- a/SmartDeviceLink/SDLMacros.h +++ b/SmartDeviceLink/SDLMacros.h @@ -18,4 +18,12 @@ #endif #endif +#ifndef SDL_SUPPORTS_CLASS_PROPERTIES + #if defined(SWIFT_CLASS_EXTRA) + #define SDL_SUPPORTS_CLASS_PROPERTIES FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8) + #else + #define SDL_SUPPORTS_CLASS_PROPERTIES NO + #endif +#endif + #endif /* SDLMacros_h */ diff --git a/SmartDeviceLink/SDLManager.m b/SmartDeviceLink/SDLManager.m index e66feb1f7..41c5612ac 100644 --- a/SmartDeviceLink/SDLManager.m +++ b/SmartDeviceLink/SDLManager.m @@ -35,7 +35,7 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark Lifecycle - (instancetype)init { - return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration enabledConfiguration]] delegate:nil]; + return [self initWithConfiguration:[SDLConfiguration configurationWithLifecycle:[SDLLifecycleConfiguration defaultConfigurationWithAppName:@"SDL APP" appId:@"001"] lockScreen:[SDLLockScreenConfiguration enabledConfiguration] logging:[SDLLogConfiguration defaultConfiguration]] delegate:nil]; } - (instancetype)initWithConfiguration:(SDLConfiguration *)configuration delegate:(nullable id<SDLManagerDelegate>)delegate { diff --git a/SmartDeviceLink/SDLMetadataTags.h b/SmartDeviceLink/SDLMetadataTags.h new file mode 100644 index 000000000..a1820c56e --- /dev/null +++ b/SmartDeviceLink/SDLMetadataTags.h @@ -0,0 +1,61 @@ +// +// SDLMetadataTags.h +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/3/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLRPCMessage.h" +#import "SDLMetadataType.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLMetadataTags : SDLRPCStruct + +/** + * @abstract Constructs a newly allocated SDLMetadataType object with NSArrays + */ +- (instancetype)initWithTextFieldTypes:(nullable NSArray<SDLMetadataType> *)mainField1 mainField2:(nullable NSArray<SDLMetadataType> *)mainField2; + +- (instancetype)initWithTextFieldTypes:(nullable NSArray<SDLMetadataType> *)mainField1 mainField2:(nullable NSArray<SDLMetadataType> *)mainField2 mainField3:(nullable NSArray<SDLMetadataType> *)mainField3 mainField4:(nullable NSArray<SDLMetadataType> *)mainField4; + +/** + * @abstract The type of data contained in the "mainField1" text field, Optional. + * + * minsize= 0 + * + * maxsize= 5 + */ +@property (nullable, strong, nonatomic) NSArray<SDLMetadataType> *mainField1; + +/** + * @abstract The type of data contained in the "mainField2" text field, Optional. + * + * minsize= 0 + * + * maxsize= 5 + */ +@property (nullable, strong, nonatomic) NSArray<SDLMetadataType> *mainField2; + +/** + * @abstract The type of data contained in the "mainField3" text field, Optional. + * + * minsize= 0 + * + * maxsize= 5 + */ +@property (nullable, strong, nonatomic) NSArray<SDLMetadataType> *mainField3; + +/** + * @abstract The type of data contained in the "mainField4" text field, Optional. + * + * minsize= 0 + * + * maxsize= 5 + */ +@property (nullable, strong, nonatomic) NSArray<SDLMetadataType> *mainField4; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLMetadataTags.m b/SmartDeviceLink/SDLMetadataTags.m new file mode 100644 index 000000000..656f8871c --- /dev/null +++ b/SmartDeviceLink/SDLMetadataTags.m @@ -0,0 +1,78 @@ +// +// SDLMetadataStruct.m +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/3/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLMetadataTags.h" + +#import "NSMutableDictionary+Store.h" +#import "SDLNames.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation SDLMetadataTags + +- (instancetype)initWithTextFieldTypes:(nullable NSArray<SDLMetadataType> *)mainField1 mainField2:(nullable NSArray<SDLMetadataType> *)mainField2 { + self = [self init]; + if (!self) { + return self; + } + + self.mainField1 = mainField1; + self.mainField2 = mainField2; + + return self; +} + +- (instancetype)initWithTextFieldTypes:(nullable NSArray<SDLMetadataType> *)mainField1 mainField2:(nullable NSArray<SDLMetadataType> *)mainField2 mainField3:(nullable NSArray<SDLMetadataType> *)mainField3 mainField4:(nullable NSArray<SDLMetadataType> *)mainField4 { + self = [self init]; + if (!self) { + return self; + } + + self.mainField1 = mainField1; + self.mainField2 = mainField2; + self.mainField3 = mainField3; + self.mainField4 = mainField4; + + return self; +} + +- (void)setMainField1:(nullable NSArray<SDLMetadataType> *)mainField1 { + [store sdl_setObject:mainField1 forName:SDLNameMainField1]; +} + +- (nullable NSArray<SDLMetadataType> *)mainField1 { + return [store sdl_objectForName:SDLNameMainField1]; +} + +- (void)setMainField2:(nullable NSArray<SDLMetadataType> *)mainField2 { + [store sdl_setObject:mainField2 forName:SDLNameMainField2]; +} + +- (nullable NSArray<SDLMetadataType> *)mainField2 { + return [store sdl_objectForName:SDLNameMainField2]; +} + +- (void)setMainField3:(nullable NSArray<SDLMetadataType> *)mainField3 { + [store sdl_setObject:mainField3 forName:SDLNameMainField3]; +} + +- (nullable NSArray<SDLMetadataType> *)mainField3 { + return [store sdl_objectForName:SDLNameMainField3]; +} + +- (void)setMainField4:(nullable NSArray<SDLMetadataType> *)mainField4 { + [store sdl_setObject:mainField4 forName:SDLNameMainField4]; +} + +- (nullable NSArray<SDLMetadataType> *)mainField4 { + return [store sdl_objectForName:SDLNameMainField4]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLMetadataType.h b/SmartDeviceLink/SDLMetadataType.h new file mode 100644 index 000000000..cc6518b1c --- /dev/null +++ b/SmartDeviceLink/SDLMetadataType.h @@ -0,0 +1,80 @@ +// +// SDLMetadataType.h +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/2/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLEnum.h" + +/** + * Text Field Types + */ +typedef SDLEnum SDLMetadataType SDL_SWIFT_ENUM; + +/** + * @abstract SDLMetadataType: *mediaTitle* + */ +extern SDLMetadataType const SDLMetadataTypeMediaTitle; + +/** + * @abstract SDLMetadataType: *mediaArtist* + */ +extern SDLMetadataType const SDLMetadataTypeMediaArtist; + +/** + * @abstract SDLMetadataType: *mediaAlbum* + */ +extern SDLMetadataType const SDLMetadataTypeMediaAlbum; + +/** + * @abstract SDLMetadataType: *mediaYear* + */ +extern SDLMetadataType const SDLMetadataTypeMediaYear; + +/** + * @abstract SDLMetadataType: *mediaGenre* + */ +extern SDLMetadataType const SDLMetadataTypeMediaGenre; + +/** + * @abstract SDLMetadataType: *mediaStation* + */ +extern SDLMetadataType const SDLMetadataTypeMediaStation; + +/** + * @abstract SDLMetadataType: *rating* + */ +extern SDLMetadataType const SDLMetadataTypeRating; + +/** + * @abstract SDLMetadataType: *currentTemperature* + */ +extern SDLMetadataType const SDLMetadataTypeCurrentTemperature; + +/** + * @abstract SDLMetadataType: *maximumTemperature* + */ +extern SDLMetadataType const SDLMetadataTypeMaximumTemperature; + +/** + * @abstract SDLMetadataType: *minimumTemperature* + */ +extern SDLMetadataType const SDLMetadataTypeMinimumTemperature; + +/** + * @abstract SDLMetadataType: *weatherTerm* + */ +extern SDLMetadataType const SDLMetadataTypeWeatherTerm; + +/** + * @abstract SDLMetadataType: *humidity* + */ +extern SDLMetadataType const SDLMetadataTypeHumidity; + +/** + The data in this field is not of a common type or should not be processed. Any time a field does not have a type parameter it is considered as the none type. + */ +extern SDLMetadataType const SDLMetadataTypeNone; + diff --git a/SmartDeviceLink/SDLMetadataType.m b/SmartDeviceLink/SDLMetadataType.m new file mode 100644 index 000000000..ad032569b --- /dev/null +++ b/SmartDeviceLink/SDLMetadataType.m @@ -0,0 +1,23 @@ +// +// SDLTextFieldType.m +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/2/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLMetadataType.h" + +SDLMetadataType const SDLMetadataTypeMediaTitle = @"mediaTitle"; +SDLMetadataType const SDLMetadataTypeMediaArtist = @"mediaArtist"; +SDLMetadataType const SDLMetadataTypeMediaAlbum = @"mediaAlbum"; +SDLMetadataType const SDLMetadataTypeMediaYear = @"mediaYear"; +SDLMetadataType const SDLMetadataTypeMediaGenre = @"mediaGenre"; +SDLMetadataType const SDLMetadataTypeMediaStation = @"mediaStation"; +SDLMetadataType const SDLMetadataTypeRating = @"rating"; +SDLMetadataType const SDLMetadataTypeCurrentTemperature = @"currentTemperature"; +SDLMetadataType const SDLMetadataTypeMaximumTemperature = @"maximumTemperature"; +SDLMetadataType const SDLMetadataTypeMinimumTemperature = @"minimumTemperature"; +SDLMetadataType const SDLMetadataTypeWeatherTerm = @"weatherTerm"; +SDLMetadataType const SDLMetadataTypeHumidity = @"humidity"; +SDLMetadataType const SDLMetadataTypeNone = @"none"; diff --git a/SmartDeviceLink/SDLNames.h b/SmartDeviceLink/SDLNames.h index 0060abec9..e611743b6 100644 --- a/SmartDeviceLink/SDLNames.h +++ b/SmartDeviceLink/SDLNames.h @@ -205,6 +205,10 @@ extern SDLName const SDLNameMainField1; extern SDLName const SDLNameMainField2; extern SDLName const SDLNameMainField3; extern SDLName const SDLNameMainField4; +extern SDLName const SDLNameMainField1Type; +extern SDLName const SDLNameMainField2Type; +extern SDLName const SDLNameMainField3Type; +extern SDLName const SDLNameMainField4Type; extern SDLName const SDLNameMajorVersion; extern SDLName const SDLNameMake; extern SDLName const SDLNameManeuverComplete; @@ -224,6 +228,7 @@ extern SDLName const SDLNameMenuTitle; extern SDLName const SDLNameMessageData; extern SDLName const SDLNameMessageDataResult; extern SDLName const SDLNameMessageLength; +extern SDLName const SDLNameMetadataTags; extern SDLName const SDLNameMiddleRow1BeltDeployed; extern SDLName const SDLNameMiddleRow1BuckleBelted; extern SDLName const SDLNameMiddleRow2BuckleBelted; diff --git a/SmartDeviceLink/SDLNames.m b/SmartDeviceLink/SDLNames.m index 7a3df991c..a8a527383 100644 --- a/SmartDeviceLink/SDLNames.m +++ b/SmartDeviceLink/SDLNames.m @@ -222,6 +222,7 @@ SDLName const SDLNameMenuTitle = @"menuTitle"; SDLName const SDLNameMessageData = @"messageData"; SDLName const SDLNameMessageDataResult = @"messageDataResult"; SDLName const SDLNameMessageLength = @"messageLength"; +SDLName const SDLNameMetadataTags = @"metadataTags"; SDLName const SDLNameMiddleRow1BeltDeployed = @"middleRow1BeltDeployed"; SDLName const SDLNameMiddleRow1BuckleBelted = @"middleRow1BuckleBelted"; SDLName const SDLNameMiddleRow2BuckleBelted = @"middleRow2BuckleBelted"; diff --git a/SmartDeviceLink/SDLPinchGesture.h b/SmartDeviceLink/SDLPinchGesture.h index 714a97312..024ea8fc6 100644 --- a/SmartDeviceLink/SDLPinchGesture.h +++ b/SmartDeviceLink/SDLPinchGesture.h @@ -59,4 +59,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END
\ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLProxy.h b/SmartDeviceLink/SDLProxy.h index 81d1743f0..80018677c 100644 --- a/SmartDeviceLink/SDLProxy.h +++ b/SmartDeviceLink/SDLProxy.h @@ -28,7 +28,6 @@ __deprecated_msg("Use SDLManager instead") @property (strong, nonatomic) SDLTimer *startSessionTimer; @property (copy, nonatomic) NSString *debugConsoleGroupName; @property (readonly, copy, nonatomic) NSString *proxyVersion; -@property (nullable, nonatomic, strong, readonly) SDLStreamingMediaManager *streamingMediaManager; - (id)initWithTransport:(SDLAbstractTransport *)transport protocol:(SDLAbstractProtocol *)protocol diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m index b933011a0..9b65076ca 100644 --- a/SmartDeviceLink/SDLProxy.m +++ b/SmartDeviceLink/SDLProxy.m @@ -53,7 +53,6 @@ static float DefaultConnectionTimeout = 45.0; @property (copy, nonatomic) NSString *appId; @property (strong, nonatomic) NSMutableSet<NSObject<SDLProxyListener> *> *mutableProxyListeners; -@property (nullable, nonatomic, strong, readwrite) SDLStreamingMediaManager *streamingMediaManager; @property (nullable, nonatomic, strong) SDLDisplayCapabilities *displayCapabilities; @property (nonatomic, strong) NSMutableDictionary<SDLVehicleMake *, Class> *securityManagers; @property (nonatomic, strong) NSURLSession* urlSession; @@ -153,22 +152,6 @@ static float DefaultConnectionTimeout = 45.0; return SDLProxyVersion; } -- (nullable SDLStreamingMediaManager *)streamingMediaManager { - if (_streamingMediaManager == nil) { - if (self.displayCapabilities == nil) { - return nil; - } - _streamingMediaManager = [[SDLStreamingMediaManager alloc] initWithProtocol:self.protocol displayCapabilities:self.displayCapabilities]; - [self.protocol.protocolDelegateTable addObject:_streamingMediaManager]; - - // HAX: The cast is a result of a compiler bug throwing a warning when it shouldn't - [self.mutableProxyListeners addObject:(id<SDLProxyListener>)_streamingMediaManager.touchManager]; - } - - return _streamingMediaManager; -} - - #pragma mark - SecurityManager - (void)addSecurityManagers:(NSArray<Class> *)securityManagerClasses forAppId:(NSString *)appId { @@ -343,10 +326,7 @@ static float DefaultConnectionTimeout = 45.0; - (void)handleRegisterAppInterfaceResponse:(SDLRPCResponse *)response { SDLRegisterAppInterfaceResponse *registerResponse = (SDLRegisterAppInterfaceResponse *)response; - self.displayCapabilities = registerResponse.displayCapabilities; - if (_streamingMediaManager) { - _streamingMediaManager.displayCapabilties = registerResponse.displayCapabilities; - } + self.protocol.securityManager = [self securityManagerForMake:registerResponse.vehicleType.make]; if (self.protocol.securityManager && [self.protocol.securityManager respondsToSelector:@selector(setAppId:)]) { self.protocol.securityManager.appId = self.appId; diff --git a/SmartDeviceLink/SDLShow.h b/SmartDeviceLink/SDLShow.h index d18c52647..5c44548ae 100644 --- a/SmartDeviceLink/SDLShow.h +++ b/SmartDeviceLink/SDLShow.h @@ -4,9 +4,12 @@ #import "SDLRPCRequest.h" #import "SDLTextAlignment.h" +#import "SDLMetadataType.h" @class SDLImage; @class SDLSoftButton; +@class SDLMetadataTags; + /** * Updates the application's display text area, regardless of whether or not @@ -37,11 +40,17 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 alignment:(nullable SDLTextAlignment)alignment; +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField1Type:(nullable SDLMetadataType)mainField1Type mainField2:(nullable NSString *)mainField2 mainField2Type:(nullable SDLMetadataType)mainField2Type alignment:(nullable SDLTextAlignment)alignment; + - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment; +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField1Type:(nullable SDLMetadataType)mainField1Type mainField2:(nullable NSString *)mainField2 mainField2Type:(nullable SDLMetadataType)mainField2Type mainField3:(nullable NSString *)mainField3 mainField3Type:(nullable SDLMetadataType)mainField3Type mainField4:(nullable NSString *)mainField4 mainField4Type:(nullable SDLMetadataType)mainField4Type alignment:(nullable SDLTextAlignment)alignment; + - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack; -- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack graphic:(nullable SDLImage *)graphic softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons customPresets:(nullable NSArray<NSString *> *)customPresets; +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack graphic:(nullable SDLImage *)graphic softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons customPresets:(nullable NSArray<NSString *> *)customPresets __deprecated_msg(("Use initWithMainField1:(NSString *)mainField1 (NSString *)mainField2 (NSString *)mainField3 (NSString *)mainField4 (SDLTextAlignment *)alignment (NSString *)statusBar (NSString *)mediaClock (NSString *)mediaTrack (SDLImage *)graphic (NSArray<SDLSoftButton *> *)softButtons (NSArray<NSString *> *)customPresets (SDLMetadataStruct *)metadata instead")); + +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack graphic:(nullable SDLImage *)graphic softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons customPresets:(nullable NSArray<NSString *> *)customPresets textFieldMetadata:(nullable SDLMetadataTags *)metadata; /** * @abstract The text displayed in a single-line display, or in the upper display @@ -231,6 +240,19 @@ NS_ASSUME_NONNULL_BEGIN */ @property (strong, nonatomic, nullable) NSArray<NSString *> *customPresets; +/** + * @abstract Text Field Metadata + * + * @discussion A Vector value representing the Custom Presets defined by the + * App + * <p> + * App defined metadata information. See MetadataStruct. Uses mainField1, mainField2, mainField3, mainField4. + * If omitted on supported displays, the currently set metadata tags will not change. + * If any text field contains no tags or the none tag, the metadata tag for that textfield should be removed. + * @since SmartDeviceLink 2.0 + */ +@property (strong, nonatomic, nullable) SDLMetadataTags *metadataTags; + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLShow.m b/SmartDeviceLink/SDLShow.m index a01c1f316..80f4f9d18 100644 --- a/SmartDeviceLink/SDLShow.m +++ b/SmartDeviceLink/SDLShow.m @@ -6,6 +6,8 @@ #import "NSMutableDictionary+Store.h" #import "SDLImage.h" +#import "SDLMetadataTags.h" +#import "SDLMetadataType.h" #import "SDLNames.h" #import "SDLSoftButton.h" @@ -23,12 +25,52 @@ NS_ASSUME_NONNULL_BEGIN return [self initWithMainField1:mainField1 mainField2:mainField2 mainField3:nil mainField4:nil alignment:alignment]; } +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField1Type:(nullable SDLMetadataType)mainField1Type mainField2:(nullable NSString *)mainField2 mainField2Type:(nullable SDLMetadataType)mainField2Type alignment:(nullable SDLTextAlignment)alignment { + self = [self init]; + if (!self) { + return nil; + } + + NSArray<SDLMetadataType> *field1Array = @[mainField1Type]; + NSArray<SDLMetadataType> *field2Array = @[mainField2Type]; + SDLMetadataTags* metadataTags = [[SDLMetadataTags alloc] initWithTextFieldTypes:field1Array mainField2:field2Array]; + + self.mainField1 = mainField1; + self.mainField2 = mainField2; + self.alignment = alignment; + self.metadataTags = metadataTags; + + return self; +} + - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment { - return [self initWithMainField1:mainField1 mainField2:mainField2 mainField3:mainField3 mainField4:mainField4 alignment:alignment statusBar:nil mediaClock:nil mediaTrack:nil graphic:nil softButtons:nil customPresets:nil]; + return [self initWithMainField1:mainField1 mainField2:mainField2 mainField3:mainField3 mainField4:mainField4 alignment:alignment statusBar:nil mediaClock:nil mediaTrack:nil graphic:nil softButtons:nil customPresets:nil textFieldMetadata:nil]; +} + +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField1Type:(nullable SDLMetadataType)mainField1Type mainField2:(nullable NSString *)mainField2 mainField2Type:(nullable SDLMetadataType)mainField2Type mainField3:(nullable NSString *)mainField3 mainField3Type:(nullable SDLMetadataType)mainField3Type mainField4:(nullable NSString *)mainField4 mainField4Type:(nullable SDLMetadataType)mainField4Type alignment:(nullable SDLTextAlignment)alignment{ + self = [self init]; + if (!self) { + return nil; + } + + NSArray<SDLMetadataType> *field1Array = @[mainField1Type]; + NSArray<SDLMetadataType> *field2Array = @[mainField2Type]; + NSArray<SDLMetadataType> *field3Array = @[mainField3Type]; + NSArray<SDLMetadataType> *field4Array = @[mainField4Type]; + SDLMetadataTags* metadataTags = [[SDLMetadataTags alloc] initWithTextFieldTypes:field1Array mainField2:field2Array mainField3:field3Array mainField4:field4Array]; + + self.mainField1 = mainField1; + self.mainField2 = mainField2; + self.mainField3 = mainField3; + self.mainField4 = mainField4; + self.alignment = alignment; + self.metadataTags = metadataTags; + + return self; } - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack { - return [self initWithMainField1:mainField1 mainField2:mainField2 mainField3:nil mainField4:nil alignment:alignment statusBar:statusBar mediaClock:mediaClock mediaTrack:mediaTrack graphic:nil softButtons:nil customPresets:nil]; + return [self initWithMainField1:mainField1 mainField2:mainField2 mainField3:nil mainField4:nil alignment:alignment statusBar:statusBar mediaClock:mediaClock mediaTrack:mediaTrack graphic:nil softButtons:nil customPresets:nil textFieldMetadata:nil]; } - (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack graphic:(nullable SDLImage *)graphic softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons customPresets:(nullable NSArray<NSString *> *)customPresets { @@ -52,6 +94,29 @@ NS_ASSUME_NONNULL_BEGIN return self; } +- (instancetype)initWithMainField1:(nullable NSString *)mainField1 mainField2:(nullable NSString *)mainField2 mainField3:(nullable NSString *)mainField3 mainField4:(nullable NSString *)mainField4 alignment:(nullable SDLTextAlignment)alignment statusBar:(nullable NSString *)statusBar mediaClock:(nullable NSString *)mediaClock mediaTrack:(nullable NSString *)mediaTrack graphic:(nullable SDLImage *)graphic softButtons:(nullable NSArray<SDLSoftButton *> *)softButtons customPresets:(nullable NSArray<NSString *> *)customPresets textFieldMetadata:(nullable SDLMetadataTags *)metadata { + self = [self init]; + if (!self) { + return nil; + } + + self.mainField1 = mainField1; + self.mainField2 = mainField2; + self.mainField3 = mainField3; + self.mainField4 = mainField4; + self.statusBar = statusBar; + self.mediaClock = mediaClock; + self.mediaTrack = mediaTrack; + self.alignment = alignment; + self.graphic = graphic; + self.softButtons = [softButtons mutableCopy]; + self.customPresets = [customPresets mutableCopy]; + self.metadataTags = metadata; + + return self; + +} + - (void)setMainField1:(nullable NSString *)mainField1 { [parameters sdl_setObject:mainField1 forName:SDLNameMainField1]; } @@ -148,6 +213,14 @@ NS_ASSUME_NONNULL_BEGIN return [parameters sdl_objectForName:SDLNameCustomPresets]; } +- (void)setMetadataTags:(nullable SDLMetadataTags *)metadataTags { + [parameters sdl_setObject:metadataTags forName:SDLNameMetadataTags]; +} + +- (nullable SDLMetadataTags *)metadataTags { + return [parameters sdl_objectForName:SDLNameMetadataTags ofClass:SDLMetadataTags.class]; +} + @end NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStateMachine.m b/SmartDeviceLink/SDLStateMachine.m index 2d197344d..f86a002b2 100644 --- a/SmartDeviceLink/SDLStateMachine.m +++ b/SmartDeviceLink/SDLStateMachine.m @@ -45,7 +45,8 @@ SDLStateMachineTransitionFormat const SDLStateMachineTransitionFormatDidEnter = } if (states[initialState] == nil) { - @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Attempted to start with an SDLState that is not in the states dictionary" userInfo:nil]; + NSString *reasonMessage = [NSString stringWithFormat:@"Attempted to start with an SDLState (%@) that is not in the states dictionary", initialState]; + @throw [NSException exceptionWithName:NSInternalInconsistencyException reason:reasonMessage userInfo:nil]; } _target = target; diff --git a/SmartDeviceLink/SDLStreamingMediaConfiguration.h b/SmartDeviceLink/SDLStreamingMediaConfiguration.h new file mode 100644 index 000000000..033ce6ea3 --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaConfiguration.h @@ -0,0 +1,77 @@ +// +// SDLStreamingMediaConfiguration.h +// SmartDeviceLink-iOS +// +// Created by Joel Fischer on 8/2/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +#import "SDLStreamingMediaManagerConstants.h" + +@protocol SDLSecurityType; + + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLStreamingMediaConfiguration : NSObject <NSCopying> + +/** + * Set security managers which could be used. This is primarily used with video streaming applications to authenticate and perhaps encrypt traffic data. + */ +@property (copy, nonatomic, nullable) NSArray<Class<SDLSecurityType>> *securityManagers; + +/** + * What encryption level video/audio streaming should be. The default is SDLStreamingEncryptionFlagAuthenticateAndEncrypt. + */ +@property (assign, nonatomic) SDLStreamingEncryptionFlag maximumDesiredEncryption; + +/** + * Properties to use for applications that utilitze the video encoder for streaming. + */ +@property (copy, nonatomic, nullable) NSDictionary<NSString *, id> *customVideoEncoderSettings; + +/** + Manually set all the properties to the streaming media configuration + + @param securityManagers The security managers to use or nil for none. + @param encryptionFlag The maximum encrpytion supported. If the connected head unit supports less than set here, it will still connect, but if it supports more than set here, it will not connect. + @param videoSettings Custom video encoder settings to be used in video streaming. + @return The configuration + */ +- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings; + +/** + Create a secure configuration for each of the security managers provided. + + @param securityManagers The security managers to be used. The encryption flag will be set to AuthenticateAndEncrypt if any security managers are set. + @return The configuration + */ +- (instancetype)initSecureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers; + +/** + Create a secure configuration for each of the security managers provided. + + @param securityManagers The security managers to be used. The encryption flag will be set to AuthenticateAndEncrypt if any security managers are set. + @return The configuration + */ ++ (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers; + +/** + Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually. + + @return The configuration + */ +- (instancetype)initInsecureConfiguration; + +/** + Create an insecure video streaming configuration. No security managers will be provided and the encryption flag will be set to None. If you'd like custom video encoder settings, you can set the property manually. + + @return The configuration + */ ++ (instancetype)insecureConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaConfiguration.m b/SmartDeviceLink/SDLStreamingMediaConfiguration.m new file mode 100644 index 000000000..4eb6d81b8 --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaConfiguration.m @@ -0,0 +1,56 @@ +// +// SDLStreamingMediaConfiguration.m +// SmartDeviceLink-iOS +// +// Created by Joel Fischer on 8/2/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLStreamingMediaConfiguration.h" + + +NS_ASSUME_NONNULL_BEGIN + +@implementation SDLStreamingMediaConfiguration + +- (instancetype)initWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *_Nullable)securityManagers encryptionFlag:(SDLStreamingEncryptionFlag)encryptionFlag videoSettings:(NSDictionary<NSString *, id> *_Nullable)videoSettings { + self = [super init]; + if (!self) { + return nil; + } + + _securityManagers = securityManagers; + _maximumDesiredEncryption = encryptionFlag; + _customVideoEncoderSettings = videoSettings; + + return self; +} + +- (instancetype)initSecureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers { + NSAssert(securityManagers.count > 0, @"A secure streaming media configuration requires security managers to be passed."); + SDLStreamingEncryptionFlag encryptionFlag = SDLStreamingEncryptionFlagAuthenticateAndEncrypt; + + return [self initWithSecurityManagers:securityManagers encryptionFlag:encryptionFlag videoSettings:nil]; +} + ++ (instancetype)secureConfigurationWithSecurityManagers:(NSArray<Class<SDLSecurityType>> *)securityManagers { + return [[self alloc] initSecureConfigurationWithSecurityManagers:securityManagers]; +} + +- (instancetype)initInsecureConfiguration { + return [self initWithSecurityManagers:nil encryptionFlag:SDLStreamingEncryptionFlagNone videoSettings:nil]; +} + ++ (instancetype)insecureConfiguration { + return [[self alloc] initInsecureConfiguration]; +} + +#pragma mark NSCopying + +- (id)copyWithZone:(nullable NSZone *)zone { + return [[self.class allocWithZone:zone] initWithSecurityManagers:_securityManagers encryptionFlag:_maximumDesiredEncryption videoSettings:_customVideoEncoderSettings]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h new file mode 100644 index 000000000..d1b0e446a --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.h @@ -0,0 +1,160 @@ +// +// SDLStreamingMediaLifecycleManager.h +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 2/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> +#import <VideoToolbox/VideoToolbox.h> + +#import "SDLHMILevel.h" +#import "SDLProtocolListener.h" +#import "SDLStreamingMediaManagerConstants.h" + +@class SDLAbstractProtocol; +@class SDLStateMachine; +@class SDLTouchManager; + +NS_ASSUME_NONNULL_BEGIN + +typedef NSString SDLAppState; +extern SDLAppState *const SDLAppStateInactive; +extern SDLAppState *const SDLAppStateActive; + +typedef NSString SDLVideoStreamState; +extern SDLVideoStreamState *const SDLVideoStreamStateStopped; +extern SDLVideoStreamState *const SDLVideoStreamStateStarting; +extern SDLVideoStreamState *const SDLVideoStreamStateReady; +extern SDLVideoStreamState *const SDLVideoStreamStateShuttingDown; + +typedef NSString SDLAudioStreamState; +extern SDLAudioStreamState *const SDLAudioStreamStateStopped; +extern SDLAudioStreamState *const SDLAudioStreamStateStarting; +extern SDLAudioStreamState *const SDLAudioStreamStateReady; +extern SDLAudioStreamState *const SDLAudioStreamStateShuttingDown; + + +#pragma mark - Interface + +@interface SDLStreamingMediaLifecycleManager : NSObject <SDLProtocolListener> + +@property (strong, nonatomic, readonly) SDLStateMachine *appStateMachine; +@property (strong, nonatomic, readonly) SDLStateMachine *videoStreamStateMachine; +@property (strong, nonatomic, readonly) SDLStateMachine *audioStreamStateMachine; + +@property (strong, nonatomic, readonly) SDLAppState *currentAppState; +@property (strong, nonatomic, readonly) SDLAudioStreamState *currentAudioStreamState; +@property (strong, nonatomic, readonly) SDLVideoStreamState *currentVideoStreamState; + +@property (copy, nonatomic, nullable) SDLHMILevel hmiLevel; + +@property (assign, nonatomic, readonly, getter=shouldRestartVideoStream) BOOL restartVideoStream; + +/** + * Touch Manager responsible for providing touch event notifications. + */ +@property (nonatomic, strong, readonly) SDLTouchManager *touchManager; + +/** + * Whether or not video streaming is supported + * + * @see SDLRegisterAppInterface SDLDisplayCapabilities + */ +@property (assign, nonatomic, readonly, getter=isVideoStreamingSupported) BOOL videoStreamingSupported; + +/** + * Whether or not audio streaming is supported. Currently this is the same as videoStreamingSupported. + */ +@property (assign, nonatomic, readonly, getter=isAudioStreamingSupported) BOOL audioStreamingSupported; + +/** + * Whether or not the video session is connected. + */ +@property (assign, nonatomic, readonly, getter=isVideoConnected) BOOL videoConnected; + +/** + * Whether or not the video session is encrypted. This may be different than the requestedEncryptionType. + */ +@property (assign, nonatomic, readonly, getter=isVideoEncrypted) BOOL videoEncrypted; + +/** + * Whether or not the audio session is connected. + */ +@property (assign, nonatomic, readonly, getter=isAudioConnected) BOOL audioConnected; + +/** + * Whether or not the audio session is encrypted. This may be different than the requestedEncryptionType. + */ +@property (assign, nonatomic, readonly, getter=isAudioEncrypted) BOOL audioEncrypted; + +/** + * Whether or not the video stream is paused due to either the application being backgrounded, the HMI state being either NONE or BACKGROUND, or the video stream not being ready. + */ +@property (assign, nonatomic, readonly, getter=isVideoStreamingPaused) BOOL videoStreamingPaused; + +/** + * This is the current screen size of a connected display. This will be the size the video encoder uses to encode the raw image data. + */ +@property (assign, nonatomic, readonly) CGSize screenSize; + +/** + * 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). + * @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; + +/** + * The requested encryption type when a session attempts to connect. This setting applies to both video and audio sessions. + * + * DEFAULT: SDLStreamingEncryptionFlagAuthenticateAndEncrypt + */ +@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType; + +/** + * Creates a streaming manager with a specified encryption type. + * + * @param encryption The encryption type requested when starting to stream. + * @param videoEncoderSettings The video encoder settings to use with SDLVideoEncoder. + * + * @return An instance of SDLStreamingMediaManager + */ +- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings 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`. + * + * @param completionHandler The block to be called when the manager's setup is complete. + */ +- (void)startWithProtocol:(SDLAbstractProtocol*)protocol completionHandler:(void (^)(BOOL success, NSError *__nullable error))completionHandler; + +/** + * Stop the manager. This method is used internally. + */ +- (void)stop; + +/** + * 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. + * + * @param imageBuffer A CVImageBufferRef to be encoded by Video Toolbox + * + * @return Whether or not the data was successfully encoded and sent. + */ +- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer; + +/** + * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback + * + * @param audioData The data in PCM audio format, to be played + * + * @return Whether or not the data was successfully sent. + */ +- (BOOL)sendAudioData:(NSData *)audioData; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m new file mode 100644 index 000000000..b56313eba --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaLifecycleManager.m @@ -0,0 +1,540 @@ +// +// SDLStreamingMediaLifecycleManager.m +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 2/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLStreamingMediaLifecycleManager.h" + +#import "SDLAbstractProtocol.h" +#import "SDLDisplayCapabilities.h" +#import "SDLGlobals.h" +#import "SDLHMILevel.h" +#import "SDLImageResolution.h" +#import "SDLLogMacros.h" +#import "SDLNotificationConstants.h" +#import "SDLOnHMIStatus.h" +#import "SDLRegisterAppInterfaceResponse.h" +#import "SDLRPCNotificationNotification.h" +#import "SDLRPCResponseNotification.h" +#import "SDLScreenParams.h" +#import "SDLStateMachine.h" +#import "SDLTouchManager.h" +#import "SDLVideoEncoder.h" + +#import "CVPixelBufferRef+SDLUtil.h" + + +NS_ASSUME_NONNULL_BEGIN + +SDLAppState *const SDLAppStateInactive = @"AppInactive"; +SDLAppState *const SDLAppStateActive = @"AppActive"; + +SDLVideoStreamState *const SDLVideoStreamStateStopped = @"VideoStreamStopped"; +SDLVideoStreamState *const SDLVideoStreamStateStarting = @"VideoStreamStarting"; +SDLVideoStreamState *const SDLVideoStreamStateReady = @"VideoStreamReady"; +SDLVideoStreamState *const SDLVideoStreamStateShuttingDown = @"VideoStreamShuttingDown"; + +SDLAudioStreamState *const SDLAudioStreamStateStopped = @"AudioStreamStopped"; +SDLAudioStreamState *const SDLAudioStreamStateStarting = @"AudioStreamStarting"; +SDLAudioStreamState *const SDLAudioStreamStateReady = @"AudioStreamReady"; +SDLAudioStreamState *const SDLAudioStreamStateShuttingDown = @"AudioStreamShuttingDown"; + +static NSUInteger const SDLFramesToSendOnBackground = 30; + + +@interface SDLStreamingMediaLifecycleManager () <SDLVideoEncoderDelegate> + +@property (weak, nonatomic) SDLAbstractProtocol *protocol; + +@property (assign, nonatomic, readonly, getter=isAppStateVideoStreamCapable) BOOL appStateVideoStreamCapable; +@property (assign, nonatomic, readonly, getter=isHmiStateAudioStreamCapable) BOOL hmiStateAudioStreamCapable; +@property (assign, nonatomic, readonly, getter=isHmiStateVideoStreamCapable) BOOL hmiStateVideoStreamCapable; + +@property (assign, nonatomic, readwrite) BOOL restartVideoStream; + +@property (strong, nonatomic, nullable) SDLVideoEncoder *videoEncoder; +@property (copy, nonatomic) NSDictionary<NSString *, id> *videoEncoderSettings; + +@property (strong, nonatomic, readwrite) SDLStateMachine *appStateMachine; +@property (strong, nonatomic, readwrite) SDLStateMachine *videoStreamStateMachine; +@property (strong, nonatomic, readwrite) SDLStateMachine *audioStreamStateMachine; + +@property (assign, nonatomic) CV_NULLABLE CVPixelBufferRef backgroundingPixelBuffer; + +@end + + +@implementation SDLStreamingMediaLifecycleManager + +#pragma mark - Public +#pragma mark Lifecycle + +- (instancetype)init { + return [self initWithEncryption:SDLStreamingEncryptionFlagAuthenticateAndEncrypt videoEncoderSettings:nil]; +} + +- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings { + self = [super init]; + if (!self) { + return nil; + } + + SDLLogV(@"Creating StreamingLifecycleManager"); + + _videoEncoderSettings = videoEncoderSettings ?: SDLVideoEncoder.defaultVideoEncoderSettings; + + _requestedEncryptionType = encryption; + _screenSize = SDLDefaultScreenSize; + _backgroundingPixelBuffer = NULL; + + SDLAppState *initialState = SDLAppStateInactive; + switch ([[UIApplication sharedApplication] applicationState]) { + case UIApplicationStateActive: { + initialState = SDLAppStateActive; + } break; + case UIApplicationStateInactive: // fallthrough + case UIApplicationStateBackground: { + initialState = SDLAppStateInactive; + } break; + default: break; + } + + _touchManager = [[SDLTouchManager alloc] init]; + + _appStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:initialState states:[self.class sdl_appStateTransitionDictionary]]; + _videoStreamStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLVideoStreamStateStopped states:[self.class sdl_videoStreamStateTransitionDictionary]]; + _audioStreamStateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLAudioStreamStateStopped states:[self.class sdl_audioStreamingStateTransitionDictionary]]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_didReceiveRegisterAppInterfaceResponse:) name:SDLDidReceiveRegisterAppInterfaceResponse object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_hmiLevelDidChange:) name:SDLDidChangeHMIStatusNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationDidBecomeActiveNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_appStateDidUpdate:) name:UIApplicationWillResignActiveNotification object:nil]; + + return self; +} + +- (void)startWithProtocol:(SDLAbstractProtocol *)protocol completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler { + _protocol = protocol; + + if (![self.protocol.protocolDelegateTable containsObject:self]) { + [self.protocol.protocolDelegateTable addObject:self]; + } + + completionHandler(YES, nil); +} + +- (void)stop { + [self sdl_stopAudioSession]; + [self sdl_stopVideoSession]; + + self.restartVideoStream = NO; + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped]; +} + +- (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { + if (!self.isVideoConnected) { + SDLLogW(@"Attempted to send video data, but not connected"); + return NO; + } else if (!self.isAppStateVideoStreamCapable) { + SDLLogW(@"Attempted to send video data, but app is not in the foreground"); + return NO; + } else if (!self.isHmiStateVideoStreamCapable) { + SDLLogW(@"Attempted to send video data, but the app is not in LIMITED or FULL HMI state"); + return NO; + } + + return [self.videoEncoder encodeFrame:imageBuffer]; +} + +- (BOOL)sendAudioData:(NSData*)audioData { + if (!self.isAudioConnected) { + return NO; + } + + if (self.isAudioEncrypted) { + [self.protocol sendEncryptedRawData:audioData onService:SDLServiceTypeAudio]; + } else { + [self.protocol sendRawData:audioData withServiceType:SDLServiceTypeAudio]; + } + return YES; +} + +#pragma mark Getters +- (BOOL)isAudioConnected { + return [self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateReady]; +} + +- (BOOL)isVideoConnected { + return [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady]; +} + +- (BOOL)isVideoStreamingPaused { + return !(self.isVideoConnected && self.isHmiStateVideoStreamCapable && self.isAppStateVideoStreamCapable); +} + +- (CVPixelBufferPoolRef __nullable)pixelBufferPool { + return self.videoEncoder.pixelBufferPool; +} + +- (SDLAppState *)currentAppState { + return self.appStateMachine.currentState; +} + +- (SDLAudioStreamState *)currentAudioStreamState { + return self.audioStreamStateMachine.currentState; +} + +- (SDLVideoStreamState *)currentVideoStreamState { + return self.videoStreamStateMachine.currentState; +} + +#pragma mark - State Machines +#pragma mark App State ++ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_appStateTransitionDictionary { + return @{ + // Will go from Inactive to Active if coming from a Phone Call. + // Will go from Inactive to IsRegainingActive if coming from Background. + SDLAppStateInactive : @[SDLAppStateActive], + SDLAppStateActive : @[SDLAppStateInactive] + }; +} + +- (void)sdl_appStateDidUpdate:(NSNotification*)notification { + if (notification.name == UIApplicationWillResignActiveNotification) { + [self.appStateMachine transitionToState:SDLAppStateInactive]; + } else if (notification.name == UIApplicationDidBecomeActiveNotification) { + [self.appStateMachine transitionToState:SDLAppStateActive]; + } +} + +- (void)didEnterStateAppInactive { + SDLLogD(@"Manager became inactive"); + if (!self.protocol) { return; } + + [self sdl_sendBackgroundFrames]; + [self.touchManager cancelPendingTouches]; + self.restartVideoStream = YES; +} + +// Per Apple's guidelines: https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/StrategiesforHandlingAppStateTransitions/StrategiesforHandlingAppStateTransitions.html +// We should be waiting to start any OpenGL drawing until UIApplicationDidBecomeActive is called. +- (void)didEnterStateAppActive { + SDLLogD(@"Manager became active"); + if (!self.protocol) { return; } + + [self sdl_startVideoSession]; + [self sdl_startAudioSession]; +} + +#pragma mark Video Streaming ++ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_videoStreamStateTransitionDictionary { + return @{ + SDLVideoStreamStateStopped : @[SDLVideoStreamStateStarting], + SDLVideoStreamStateStarting : @[SDLVideoStreamStateStopped, SDLVideoStreamStateReady], + SDLVideoStreamStateReady : @[SDLVideoStreamStateShuttingDown, SDLVideoStreamStateStopped], + SDLVideoStreamStateShuttingDown : @[SDLVideoStreamStateStopped] + }; +} + +- (void)didEnterStateVideoStreamStopped { + SDLLogD(@"Video stream stopped"); + _videoEncrypted = NO; + + if (_videoEncoder != nil) { + [_videoEncoder stop]; + _videoEncoder = nil; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStopNotification object:nil]; + + if (self.shouldRestartVideoStream) { + self.restartVideoStream = NO; + [self sdl_startVideoSession]; + } +} + +- (void)didEnterStateVideoStreamStarting { + SDLLogD(@"Video stream starting"); + self.restartVideoStream = NO; + + // Decide if we need to start a secure service or not + if (self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) { + [self.protocol startSecureServiceWithType:SDLServiceTypeVideo completionHandler:^(BOOL success, NSError *error) { + // This only fires if we fail + if (error) { + SDLLogE(@"TLS setup error: %@", error); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped]; + } + }]; + } else { + [self.protocol startServiceWithType:SDLServiceTypeVideo]; + } +} + +- (void)didEnterStateVideoStreamReady { + SDLLogD(@"Video stream ready"); + if (self.videoEncoder == nil) { + NSError* error = nil; + self.videoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:self.screenSize properties:self.videoEncoderSettings delegate:self error:&error]; + + if (error) { + SDLLogE(@"Could not create a video encoder: %@", error); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped]; + return; + } + + if (!self.backgroundingPixelBuffer) { + CVPixelBufferRef backgroundingPixelBuffer = [self.videoEncoder newPixelBuffer]; + if (CVPixelBufferAddText(backgroundingPixelBuffer, @"") == NO) { + SDLLogE(@"Could not create a backgrounding frame"); + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped]; + return; + } + + self.backgroundingPixelBuffer = backgroundingPixelBuffer; + } + } + + [[NSNotificationCenter defaultCenter] postNotificationName:SDLVideoStreamDidStartNotification object:nil]; +} + +- (void)didEnterStateVideoStreamShuttingDown { + SDLLogD(@"Video stream shutting down"); + [self.protocol endServiceWithType:SDLServiceTypeVideo]; +} + +#pragma mark Audio ++ (NSDictionary<SDLState *, SDLAllowableStateTransitions *> *)sdl_audioStreamingStateTransitionDictionary { + return @{ + SDLAudioStreamStateStopped : @[SDLAudioStreamStateStarting], + SDLAudioStreamStateStarting : @[SDLAudioStreamStateStopped, SDLAudioStreamStateReady], + SDLAudioStreamStateReady : @[SDLAudioStreamStateShuttingDown, SDLAudioStreamStateStopped], + SDLAudioStreamStateShuttingDown : @[SDLAudioStreamStateStopped] + }; +} + +- (void)didEnterStateAudioStreamStopped { + SDLLogD(@"Audio stream stopped"); + _audioEncrypted = NO; + + [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStopNotification object:nil]; +} + +- (void)didEnterStateAudioStreamStarting { + SDLLogD(@"Audio stream starting"); + if (self.requestedEncryptionType != SDLStreamingEncryptionFlagNone) { + [self.protocol startSecureServiceWithType:SDLServiceTypeAudio completionHandler:^(BOOL success, NSError *error) { + // This only fires if we fail!! + if (error) { + SDLLogE(@"TLS setup error: %@", error); + [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped]; + } + }]; + } else { + [self.protocol startServiceWithType:SDLServiceTypeAudio]; + } +} + +- (void)didEnterStateAudioStreamReady { + SDLLogD(@"Audio stream ready"); + [[NSNotificationCenter defaultCenter] postNotificationName:SDLAudioStreamDidStartNotification object:nil]; +} + +- (void)didEnterStateAudioStreamShuttingDown { + SDLLogD(@"Audio stream shutting down"); + [self.protocol endServiceWithType:SDLServiceTypeAudio]; +} + +#pragma mark - SDLProtocolListener +- (void)handleProtocolStartSessionACK:(SDLProtocolHeader *)header { + switch (header.serviceType) { + case SDLServiceTypeAudio: { + _audioEncrypted = header.encrypted; + + [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateReady]; + } break; + case SDLServiceTypeVideo: { + _videoEncrypted = header.encrypted; + + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateReady]; + } break; + default: break; + } +} + +- (void)handleProtocolStartSessionNACK:(SDLServiceType)serviceType { + [self sdl_transitionToStoppedState:serviceType]; +} + +- (void)handleProtocolEndSessionACK:(SDLServiceType)serviceType { + [self sdl_transitionToStoppedState:serviceType]; +} + +- (void)handleProtocolEndSessionNACK:(SDLServiceType)serviceType { + [self sdl_transitionToStoppedState:serviceType]; +} + +#pragma mark - SDLVideoEncoderDelegate +- (void)videoEncoder:(SDLVideoEncoder *)encoder hasEncodedFrame:(NSData *)encodedVideo { + SDLLogV(@"Video encoder encoded frame, sending"); + // Do we care about app state here? I don't think so… + BOOL capableVideoStreamState = [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady]; + + if (self.isHmiStateVideoStreamCapable && capableVideoStreamState) { + if (self.isVideoEncrypted) { + [self.protocol sendEncryptedRawData:encodedVideo onService:SDLServiceTypeVideo]; + } else { + [self.protocol sendRawData:encodedVideo withServiceType:SDLServiceTypeVideo]; + } + } +} + +#pragma mark - SDL RPC Notification callbacks +- (void)sdl_didReceiveRegisterAppInterfaceResponse:(SDLRPCResponseNotification*)notification { + NSAssert([notification.response isKindOfClass:[SDLRegisterAppInterfaceResponse class]], @"A notification was sent with an unanticipated object"); + if (![notification.response isKindOfClass:[SDLRegisterAppInterfaceResponse class]]) { + return; + } + + SDLRegisterAppInterfaceResponse* registerResponse = (SDLRegisterAppInterfaceResponse*)notification.response; + + _videoStreamingSupported = registerResponse.displayCapabilities.graphicSupported.boolValue; + _audioStreamingSupported = registerResponse.displayCapabilities.graphicSupported.boolValue; + + if (!self.isVideoStreamingSupported) { + SDLLogE(@"Graphics are not supported on this head unit. We are are assuming screen size is also unavailable."); + return; + } + + SDLImageResolution* resolution = registerResponse.displayCapabilities.screenParams.resolution; + if (resolution != nil) { + _screenSize = CGSizeMake(resolution.resolutionWidth.floatValue, + resolution.resolutionHeight.floatValue); + } else { + _screenSize = SDLDefaultScreenSize; + } +} + +- (void)sdl_hmiLevelDidChange:(SDLRPCNotificationNotification *)notification { + NSAssert([notification.notification isKindOfClass:[SDLOnHMIStatus class]], @"A notification was sent with an unanticipated object"); + if (![notification.notification isKindOfClass:[SDLOnHMIStatus class]]) { + return; + } + + SDLOnHMIStatus *hmiStatus = (SDLOnHMIStatus*)notification.notification; + + self.hmiLevel = hmiStatus.hmiLevel; + + if (self.isHmiStateVideoStreamCapable) { + [self sdl_startVideoSession]; + } else { + [self sdl_stopVideoSession]; + } + + if (self.isHmiStateAudioStreamCapable) { + [self sdl_startAudioSession]; + } else { + [self sdl_stopAudioSession]; + } +} + + +#pragma mark - Streaming session helpers + +- (void)sdl_startVideoSession { + if (!self.isVideoStreamingSupported) { + return; + } + + if (self.shouldRestartVideoStream + && [self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateReady]) { + [self sdl_stopVideoSession]; + return; + } + + if ([self.videoStreamStateMachine isCurrentState:SDLVideoStreamStateStopped] + && self.isHmiStateVideoStreamCapable + && self.isAppStateVideoStreamCapable) { + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStarting]; + } else { + SDLLogE(@"Unable to start video stream\n" + "State: %@\n" + "HMI state: %@\n" + "App state: %@", self.videoStreamStateMachine.currentState, self.hmiLevel, self.appStateMachine.currentState); + } +} + +- (void)sdl_startAudioSession { + if (!self.isAudioStreamingSupported) { + return; + } + + if ([self.audioStreamStateMachine isCurrentState:SDLAudioStreamStateStopped] + && self.isHmiStateAudioStreamCapable) { + [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStarting]; + } +} + +- (void)sdl_stopVideoSession { + if (!self.isVideoStreamingSupported) { + return; + } + + if (self.isVideoConnected) { + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateShuttingDown]; + } +} + +- (void)sdl_stopAudioSession { + if (!self.isAudioStreamingSupported) { + return; + } + + if (self.isAudioConnected) { + [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateShuttingDown]; + } +} + +- (void)sdl_transitionToStoppedState:(SDLServiceType)serviceType { + switch (serviceType) { + case SDLServiceTypeAudio: + [self.audioStreamStateMachine transitionToState:SDLAudioStreamStateStopped]; + break; + case SDLServiceTypeVideo: + [self.videoStreamStateMachine transitionToState:SDLVideoStreamStateStopped]; + break; + default: + break; + } +} + +- (void)sdl_sendBackgroundFrames { + if (!self.backgroundingPixelBuffer) { + return; + } + + for (int frameCount = 0; frameCount < SDLFramesToSendOnBackground; frameCount++) { + [self.videoEncoder encodeFrame:self.backgroundingPixelBuffer]; + } +} + +#pragma mark Getters +- (BOOL)isAppStateVideoStreamCapable { + return [self.appStateMachine isCurrentState:SDLAppStateActive]; +} + +- (BOOL)isHmiStateAudioStreamCapable { + return YES; +} + +- (BOOL)isHmiStateVideoStreamCapable { + return [self.hmiLevel isEqualToEnum:SDLHMILevelLimited] || [self.hmiLevel isEqualToEnum:SDLHMILevelFull]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaManager.h b/SmartDeviceLink/SDLStreamingMediaManager.h index 375c3bb61..232856d40 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.h +++ b/SmartDeviceLink/SDLStreamingMediaManager.h @@ -9,52 +9,16 @@ #import <Foundation/Foundation.h> #import <VideoToolbox/VideoToolbox.h> -#import "SDLProtocolListener.h" +#import "SDLStreamingMediaManagerConstants.h" @class SDLAbstractProtocol; -@class SDLDisplayCapabilities; @class SDLTouchManager; - NS_ASSUME_NONNULL_BEGIN -typedef NS_ENUM(NSInteger, SDLStreamingVideoError) { - SDLStreamingVideoErrorHeadUnitNACK = 0, - SDLSTreamingVideoErrorInvalidOperatingSystemVersion __deprecated_enum_msg("Use SDLStreamingVideoErrorInvalidOperatingSystemVersion instead") = 1, - SDLStreamingVideoErrorInvalidOperatingSystemVersion = 1, - SDLStreamingVideoErrorConfigurationCompressionSessionCreationFailure = 2, - SDLStreamingVideoErrorConfigurationAllocationFailure = 3, - SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure = 4 -}; - -typedef NS_ENUM(NSInteger, SDLEncryptionFlag) { - SDLEncryptionFlagNone, - SDLEncryptionFlagAuthenticateOnly, - SDLEncryptionFlagAuthenticateAndEncrypt -}; - -typedef NS_ENUM(NSInteger, SDLStreamingAudioError) { - SDLStreamingAudioErrorHeadUnitNACK -}; - -extern NSString *const SDLErrorDomainStreamingMediaVideo; -extern NSString *const SDLErrorDomainStreamingMediaAudio; - -extern CGSize const SDLDefaultScreenSize; - -typedef void (^SDLStreamingStartBlock)(BOOL success, NSError *__nullable error); -typedef void (^SDLStreamingEncryptionStartBlock)(BOOL success, BOOL encryption, NSError *__nullable error); - - #pragma mark - Interface -@interface SDLStreamingMediaManager : NSObject <SDLProtocolListener> - -@property (assign, nonatomic, readonly) BOOL videoSessionConnected; -@property (assign, nonatomic, readonly) BOOL audioSessionConnected; - -@property (assign, nonatomic, readonly) BOOL videoSessionEncrypted; -@property (assign, nonatomic, readonly) BOOL audioSessionEncrypted; +@interface SDLStreamingMediaManager : NSObject /** * Touch Manager responsible for providing touch event notifications. @@ -62,23 +26,41 @@ typedef void (^SDLStreamingEncryptionStartBlock)(BOOL success, BOOL encryption, @property (nonatomic, strong, readonly) SDLTouchManager *touchManager; /** - * The settings used in a VTCompressionSessionRef encoder. These will be verified when the video stream is started. Acceptable properties for this are located in VTCompressionProperties. If set to nil, the defaultVideoEncoderSettings will be used. + * Whether or not video streaming is supported * - * @warning Video streaming must not be connected to update the encoder properties. If it is running, issue a stopVideoSession before updating. + * @see SDLRegisterAppInterface SDLDisplayCapabilities */ -@property (strong, nonatomic, null_resettable) NSDictionary<NSString *, id> *videoEncoderSettings; +@property (assign, nonatomic, readonly, getter=isVideoStreamingSupported) BOOL videoStreamingSupported; /** - * Display capabilties that will set the screenSize property. If set to nil, the SDLDefaultScreenSize will be used. - * - * @warning Video streaming must not be connected to update the encoder properties. If it is running, issue a stopVideoSession before updating. + * Whether or not audio streaming is supported. Currently this is the same as videoStreamingSupported. + */ +@property (assign, nonatomic, readonly, getter=isAudioStreamingSupported) BOOL audioStreamingSupported; + +/** + * Whether or not the video session is connected. + */ +@property (assign, nonatomic, readonly, getter=isVideoConnected) BOOL videoConnected; + +/** + * Whether or not the video session is encrypted. This may be different than the requestedEncryptionType. + */ +@property (assign, nonatomic, readonly, getter=isVideoEncrypted) BOOL videoEncrypted; + +/** + * Whether or not the audio session is connected. */ -@property (strong, nonatomic, null_resettable) SDLDisplayCapabilities *displayCapabilties; +@property (assign, nonatomic, readonly, getter=isAudioConnected) BOOL audioConnected; /** - * Provides default video encoder settings used. + * Whether or not the audio session is encrypted. This may be different than the requestedEncryptionType. */ -@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *defaultVideoEncoderSettings; +@property (assign, nonatomic, readonly, getter=isAudioEncrypted) BOOL audioEncrypted; + +/** + * Whether or not the video stream is paused due to either the application being backgrounded, the HMI state being either NONE or BACKGROUND, or the video stream not being ready. + */ +@property (assign, nonatomic, readonly, getter=isVideoStreamingPaused) BOOL videoStreamingPaused; /** * This is the current screen size of a connected display. This will be the size the video encoder uses to encode the raw image data. @@ -93,30 +75,34 @@ typedef void (^SDLStreamingEncryptionStartBlock)(BOOL success, BOOL encryption, */ @property (assign, nonatomic, readonly, nullable) CVPixelBufferPoolRef pixelBufferPool; - -- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol __deprecated_msg(("Please use initWithProtocol:displayCapabilities: instead")); - -- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities *)displayCapabilities; +/** + * The requested encryption type when a session attempts to connect. This setting applies to both video and audio sessions. + * + * DEFAULT: SDLStreamingEncryptionFlagAuthenticateAndEncrypt + */ +@property (assign, nonatomic) SDLStreamingEncryptionFlag requestedEncryptionType; /** - * This method will attempt to start a streaming video session. It will set up iOS's video encoder, and call out to the head unit asking if it will start a video session. This will not use encryption. + * Creates a streaming manager with a specified encryption type. + * + * @param encryption The encryption type requested when starting to stream. + * @param videoEncoderSettings The video encoder settings to use with SDLVideoEncoder. * - * @param startBlock A block that will be called with the result of attempting to start a video session + * @return An instance of SDLStreamingMediaManager */ -- (void)startVideoSessionWithStartBlock:(SDLStreamingStartBlock)startBlock; +- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings NS_DESIGNATED_INITIALIZER; /** - * Start a video session either with with no encryption (the default), with authentication but no encryption (this will attempt a TLS authentication with the other side, but will not physically encrypt the data after that), or authentication and encryption, which will encrypt all video data being sent. + * 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`. * - * @param encryptionFlag Whether and how much security to apply to the video session. - * @param startBlock A block that will be called with the result of attempting to start a video session + * @param completionHandler The block to be called when the manager's setup is complete. */ -- (void)startVideoSessionWithTLS:(SDLEncryptionFlag)encryptionFlag startBlock:(SDLStreamingEncryptionStartBlock)startBlock; +- (void)startWithProtocol:(SDLAbstractProtocol*)protocol completionHandler:(void (^)(BOOL success, NSError *__nullable error))completionHandler; /** - * This method will stop a running video session if there is one running. + * Stop the manager. This method is used internally. */ -- (void)stopVideoSession; +- (void)stop; /** * 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. @@ -128,28 +114,14 @@ typedef void (^SDLStreamingEncryptionStartBlock)(BOOL success, BOOL encryption, - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer; /** - * This method will attempt to start an audio session - * - * @param startBlock A block that will be called with the result of attempting to start an audio session - */ -- (void)startAudioSessionWithStartBlock:(SDLStreamingStartBlock)startBlock; - -// TODO: Documentation -- (void)startAudioSessionWithTLS:(SDLEncryptionFlag)encryptionFlag startBlock:(SDLStreamingEncryptionStartBlock)startBlock; - -/** - * This method will stop a running audio session if there is one running. - */ -- (void)stopAudioSession; - -/** * This method receives PCM audio data and will attempt to send that data across to the head unit for immediate playback * - * @param pcmAudioData The data in PCM audio format, to be played + * @param audioData The data in PCM audio format, to be played * * @return Whether or not the data was successfully sent. */ -- (BOOL)sendAudioData:(NSData *)pcmAudioData; +- (BOOL)sendAudioData:(NSData *)audioData; + @end diff --git a/SmartDeviceLink/SDLStreamingMediaManager.m b/SmartDeviceLink/SDLStreamingMediaManager.m index e8a99d609..1c4291931 100644 --- a/SmartDeviceLink/SDLStreamingMediaManager.m +++ b/SmartDeviceLink/SDLStreamingMediaManager.m @@ -8,594 +8,105 @@ #import "SDLStreamingMediaManager.h" -#import <UIKit/UIKit.h> - -#import "SDLAbstractProtocol.h" -#import "SDLLogMacros.h" -#import "SDLDisplayCapabilities.h" -#import "SDLGlobals.h" -#import "SDLImageResolution.h" -#import "SDLScreenParams.h" +#import "SDLStreamingMediaLifecycleManager.h" #import "SDLTouchManager.h" -NSString *const SDLErrorDomainStreamingMediaVideo = @"com.sdl.streamingmediamanager.video"; -NSString *const SDLErrorDomainStreamingMediaAudio = @"com.sdl.streamingmediamanager.audio"; - -CGSize const SDLDefaultScreenSize = {800, 480}; - NS_ASSUME_NONNULL_BEGIN @interface SDLStreamingMediaManager () -@property (assign, nonatomic, nullable) VTCompressionSessionRef compressionSession; - -@property (assign, nonatomic, nullable) CFDictionaryRef pixelBufferOptions; - -@property (assign, nonatomic) NSUInteger currentFrameNumber; - -@property (assign, nonatomic, readwrite) BOOL videoSessionConnected; -@property (assign, nonatomic, readwrite) BOOL audioSessionConnected; - -@property (assign, nonatomic, readwrite) BOOL videoSessionEncrypted; -@property (assign, nonatomic, readwrite) BOOL audioSessionEncrypted; - -@property (weak, nonatomic) SDLAbstractProtocol *protocol; - -@property (copy, nonatomic, nullable) SDLStreamingEncryptionStartBlock videoStartBlock; -@property (copy, nonatomic, nullable) SDLStreamingEncryptionStartBlock audioStartBlock; - -@property (nonatomic, strong, readwrite) SDLTouchManager *touchManager; +@property (strong, nonatomic) SDLStreamingMediaLifecycleManager *lifecycleManager; @end @implementation SDLStreamingMediaManager -#pragma mark - Class Lifecycle - -- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol displayCapabilities:(SDLDisplayCapabilities *)displayCapabilities { - self = [self init]; - if (!self) { - return nil; - } - - _protocol = protocol; - - _displayCapabilties = displayCapabilities; - [self sdl_updateScreenSizeFromDisplayCapabilities:displayCapabilities]; - - return self; -} - -- (instancetype)initWithProtocol:(SDLAbstractProtocol *)protocol { - self = [self init]; - if (!self) { - return nil; - } - - _protocol = protocol; +#pragma mark - Public +#pragma mark Lifecycle - return self; +- (instancetype)init { + return [self initWithEncryption:SDLStreamingEncryptionFlagAuthenticateAndEncrypt videoEncoderSettings:nil]; } -- (instancetype)init { +- (instancetype)initWithEncryption:(SDLStreamingEncryptionFlag)encryption videoEncoderSettings:(nullable NSDictionary<NSString *, id> *)videoEncoderSettings { self = [super init]; if (!self) { return nil; } - - _compressionSession = NULL; - - _currentFrameNumber = 0; - _videoSessionConnected = NO; - _audioSessionConnected = NO; - _videoSessionEncrypted = NO; - _audioSessionEncrypted = NO; - _protocol = nil; - - _videoStartBlock = nil; - _audioStartBlock = nil; - - _screenSize = SDLDefaultScreenSize; - _videoEncoderSettings = self.defaultVideoEncoderSettings; - _touchManager = [[SDLTouchManager alloc] init]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(sdl_applicationDidEnterBackground:) - name:UIApplicationDidEnterBackgroundNotification - object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self - selector:@selector(sdl_applicationDidResignActive:) - name:UIApplicationWillResignActiveNotification - object:nil]; + + _lifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithEncryption:encryption videoEncoderSettings:videoEncoderSettings]; return self; } -- (void)dealloc { - _pixelBufferOptions = nil; +- (void)startWithProtocol:(SDLAbstractProtocol *)protocol completionHandler:(void (^)(BOOL, NSError * _Nullable))completionHandler { + [self.lifecycleManager startWithProtocol:protocol completionHandler:completionHandler]; } -#pragma mark - Streaming media lifecycle - -- (void)startVideoSessionWithStartBlock:(SDLStreamingStartBlock)startBlock { - [self startVideoSessionWithTLS:SDLEncryptionFlagNone - startBlock:^(BOOL success, BOOL encryption, NSError *_Nullable error) { - startBlock(success, error); - }]; +- (void)stop { + [self.lifecycleManager stop]; } -- (void)startVideoSessionWithTLS:(SDLEncryptionFlag)encryptionFlag startBlock:(SDLStreamingEncryptionStartBlock)startBlock { - self.videoStartBlock = [startBlock copy]; - self.videoSessionEncrypted = (encryptionFlag == SDLEncryptionFlagAuthenticateAndEncrypt ? YES : NO); - - if (encryptionFlag != SDLEncryptionFlagNone) { - __weak typeof(self) weakSelf = self; - [self.protocol startSecureServiceWithType:SDLServiceTypeVideo - completionHandler:^(BOOL success, NSError *error) { - typeof(weakSelf) strongSelf = weakSelf; - // If success, we will get an ACK or NACK, so those methods will handle calling the video block - if (!success) { - if (strongSelf.videoStartBlock == nil) { - return; - } - - strongSelf.videoStartBlock(NO, NO, error); - strongSelf.videoStartBlock = nil; - } - }]; - } else { - [self.protocol startServiceWithType:SDLServiceTypeVideo]; - } -} - -- (void)stopVideoSession { - if (!self.videoSessionConnected) { - return; - } - - [self.protocol endServiceWithType:SDLServiceTypeVideo]; -} - -- (void)startAudioSessionWithStartBlock:(SDLStreamingStartBlock)startBlock { - [self startAudioSessionWithTLS:SDLEncryptionFlagNone - startBlock:^(BOOL success, BOOL encryption, NSError *_Nullable error) { - startBlock(success, error); - }]; -} - -- (void)startAudioSessionWithTLS:(SDLEncryptionFlag)encryptionFlag startBlock:(SDLStreamingEncryptionStartBlock)startBlock { - self.audioStartBlock = [startBlock copy]; - self.audioSessionEncrypted = (encryptionFlag == SDLEncryptionFlagAuthenticateAndEncrypt ? YES : NO); - - if (encryptionFlag != SDLEncryptionFlagNone) { - __weak typeof(self) weakSelf = self; - [self.protocol startSecureServiceWithType:SDLServiceTypeAudio - completionHandler:^(BOOL success, NSError *error) { - typeof(weakSelf) strongSelf = weakSelf; - // If this passes, we will get an ACK or NACK, so those methods will handle calling the audio block - if (!success) { - if (strongSelf.audioStartBlock == nil) { - return; - } - - strongSelf.audioStartBlock(NO, NO, error); - strongSelf.audioStartBlock = nil; - } - }]; - } else { - [self.protocol startServiceWithType:SDLServiceTypeAudio]; - } -} - -- (void)stopAudioSession { - if (!self.audioSessionConnected) { - return; - } - - [self.protocol endServiceWithType:SDLServiceTypeAudio]; -} - - -#pragma mark - Send media data - - (BOOL)sendVideoData:(CVImageBufferRef)imageBuffer { - if (!self.videoSessionConnected) { - return NO; - } - - // TODO (Joel F.)[2015-08-17]: Somehow monitor connection to make sure we're not clogging the connection with data. - // This will come out in -[self sdl_videoEncoderOutputCallback] - OSStatus status = VTCompressionSessionEncodeFrame(_compressionSession, imageBuffer, CMTimeMake(self.currentFrameNumber++, 30), kCMTimeInvalid, NULL, (__bridge void *)self, NULL); - - return (status == noErr); -} - -- (BOOL)sendAudioData:(NSData *)pcmAudioData { - if (!self.audioSessionConnected) { - return NO; - } - - dispatch_async([self.class sdl_streamingDataSerialQueue], ^{ - @autoreleasepool { - if (self.audioSessionEncrypted) { - [self.protocol sendEncryptedRawData:pcmAudioData onService:SDLServiceTypeAudio]; - } else { - [self.protocol sendRawData:pcmAudioData withServiceType:SDLServiceTypeAudio]; - } - } - }); - - return YES; -} - -#pragma mark - Update video encoder - -- (void)setVideoEncoderSettings:(NSDictionary<NSString *, id> *_Nullable)videoEncoderSettings { - if (self.videoSessionConnected) { - @throw [NSException exceptionWithName:SDLErrorDomainStreamingMediaVideo reason:@"Cannot update video encoder settings while video session is connected." userInfo:nil]; - return; - } - - if (videoEncoderSettings) { - _videoEncoderSettings = videoEncoderSettings; - } else { - _videoEncoderSettings = self.defaultVideoEncoderSettings; - } -} - -- (void)setDisplayCapabilties:(SDLDisplayCapabilities *_Nullable)displayCapabilties { - if (self.videoSessionConnected) { - @throw [NSException exceptionWithName:SDLErrorDomainStreamingMediaVideo reason:@"Cannot update video encoder settings while video session is connected." userInfo:nil]; - return; - } - - _displayCapabilties = displayCapabilties; - [self sdl_updateScreenSizeFromDisplayCapabilities:displayCapabilties]; -} - -- (NSDictionary<NSString *, id> *)defaultVideoEncoderSettings { - static NSDictionary<NSString *, id> *defaultVideoEncoderSettings = nil; - if (defaultVideoEncoderSettings == nil) { - defaultVideoEncoderSettings = @{ - (__bridge NSString *)kVTCompressionPropertyKey_ProfileLevel: (__bridge NSString *)kVTProfileLevel_H264_Baseline_AutoLevel, - (__bridge NSString *)kVTCompressionPropertyKey_RealTime: @YES - }; - } - return defaultVideoEncoderSettings; + return [self.lifecycleManager sendVideoData:imageBuffer]; } -- (CVPixelBufferPoolRef _Nullable)pixelBufferPool { - return VTCompressionSessionGetPixelBufferPool(self.compressionSession); +- (BOOL)sendAudioData:(NSData*)audioData { + return [self.lifecycleManager sendAudioData:audioData]; } -#pragma mark - SDLProtocolListener Methods - -- (void)handleProtocolStartSessionACK:(SDLProtocolHeader *)header { - switch (header.serviceType) { - case SDLServiceTypeAudio: { - self.audioSessionConnected = YES; - self.audioSessionEncrypted = header.encrypted; - - if (self.audioStartBlock == nil) { - return; - } - - self.audioStartBlock(YES, header.encrypted, nil); - self.audioStartBlock = nil; - } break; - case SDLServiceTypeVideo: { - NSError *error = nil; - BOOL success = [self sdl_configureVideoEncoderWithError:&error]; - - if (!success) { - [self sdl_teardownCompressionSession]; - [self.protocol endServiceWithType:SDLServiceTypeVideo]; - - if (self.videoStartBlock == nil) { - return; - } - - self.videoStartBlock(NO, header.encrypted, error); - self.videoStartBlock = nil; - - return; - } - - self.videoSessionConnected = YES; - self.videoSessionEncrypted = header.encrypted; - if (self.videoStartBlock == nil) { - return; - } +#pragma mark - Getters - self.videoStartBlock(YES, header.encrypted, nil); - self.videoStartBlock = nil; - } break; - default: break; - } +- (SDLTouchManager *)touchManager { + return self.lifecycleManager.touchManager; } -- (void)handleProtocolStartSessionNACK:(SDLServiceType)serviceType { - switch (serviceType) { - case SDLServiceTypeAudio: { - NSError *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaAudio code:SDLStreamingAudioErrorHeadUnitNACK userInfo:nil]; - - if (self.audioStartBlock == nil) { - return; - } - - self.audioStartBlock(NO, NO, error); - self.audioStartBlock = nil; - } break; - case SDLServiceTypeVideo: { - NSError *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorHeadUnitNACK userInfo:nil]; - - if (self.videoStartBlock == nil) { - return; - } - - self.videoStartBlock(NO, NO, error); - self.videoStartBlock = nil; - } break; - default: break; - } +- (BOOL)isAudioStreamingSupported { + return self.lifecycleManager.isAudioStreamingSupported; } -- (void)handleProtocolEndSessionACK:(SDLServiceType)serviceType { - switch (serviceType) { - case SDLServiceTypeAudio: { - self.audioSessionConnected = NO; - } break; - case SDLServiceTypeVideo: { - self.videoSessionConnected = NO; - [self sdl_teardownCompressionSession]; - } break; - default: break; - } +- (BOOL)isVideoStreamingSupported { + return self.lifecycleManager.isVideoStreamingSupported; } -- (void)handleProtocolEndSessionNACK:(SDLServiceType)serviceType { - // TODO (Joel F.)[2015-08-17]: This really, really shouldn't ever happen. Should we assert? Do nothing? We don't have any additional info on why this failed. +- (BOOL)isAudioConnected { + return self.lifecycleManager.isAudioConnected; } - -#pragma mark - Video Encoding - -#pragma mark Lifecycle - -- (void)sdl_teardownCompressionSession { - if (self.compressionSession != NULL) { - VTCompressionSessionInvalidate(self.compressionSession); - CFRelease(self.compressionSession); - self.compressionSession = NULL; - } +- (BOOL)isVideoConnected { + return self.lifecycleManager.isVideoConnected; } - -#pragma mark Callbacks - -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) { - SDLLogE(@"Error encoding video frame: %lld", (int64_t)status); - return; - } - - if (outputCallbackRefCon == NULL || sourceFrameRefCon == NULL || sampleBuffer == NULL) { - return; - } - - SDLStreamingMediaManager *mediaManager = (__bridge SDLStreamingMediaManager *)sourceFrameRefCon; - NSData *elementaryStreamData = [mediaManager.class sdl_encodeElementaryStreamWithSampleBuffer:sampleBuffer]; - - if (mediaManager.videoSessionEncrypted) { - [mediaManager.protocol sendEncryptedRawData:elementaryStreamData onService:SDLServiceTypeVideo]; - } else { - [mediaManager.protocol sendRawData:elementaryStreamData withServiceType:SDLServiceTypeVideo]; - } +- (BOOL)isAudioEncrypted { + return self.lifecycleManager.isAudioEncrypted; } - -#pragma mark Configuration - -- (BOOL)sdl_configureVideoEncoderWithError:(NSError *__autoreleasing *)error { - OSStatus status; - - // Create a compression session - status = VTCompressionSessionCreate(NULL, self.screenSize.width, self.screenSize.height, kCMVideoCodecType_H264, NULL, self.pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); - - if (status != noErr) { - // TODO: Log the error - if (error != NULL) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status) }]; - } - - return NO; - } - - CFRelease(self.pixelBufferOptions); - _pixelBufferOptions = nil; - - // Validate that the video encoder properties are valid. - CFDictionaryRef supportedProperties; - status = VTSessionCopySupportedPropertyDictionary(self.compressionSession, &supportedProperties); - if (status != noErr) { - if (error != NULL) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }]; - } - - return NO; - } - - for (NSString *key in self.videoEncoderSettings.allKeys) { - if (CFDictionaryContainsKey(supportedProperties, (__bridge CFStringRef)key) == false) { - if (error != NULL) { - NSString *description = [NSString stringWithFormat:@"\"%@\" is not a supported key.", key]; - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{NSLocalizedDescriptionKey: description}]; - } - CFRelease(supportedProperties); - return NO; - } - } - CFRelease(supportedProperties); - - // Populate the video encoder settings from provided dictionary. - for (NSString *key in self.videoEncoderSettings.allKeys) { - id value = self.videoEncoderSettings[key]; - - status = VTSessionSetProperty(self.compressionSession, (__bridge CFStringRef)key, (__bridge CFTypeRef)value); - if (status != noErr) { - if (error != NULL) { - *error = [NSError errorWithDomain:SDLErrorDomainStreamingMediaVideo code:SDLStreamingVideoErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }]; - } - - return NO; - } - } - - return YES; +- (BOOL)isVideoEncrypted { + return self.lifecycleManager.isVideoEncrypted; } - -#pragma mark Elementary Stream Formatting - -+ (NSData *)sdl_encodeElementaryStreamWithSampleBuffer:(CMSampleBufferRef)sampleBuffer { - // Creating an elementaryStream: http://stackoverflow.com/questions/28396622/extracting-h264-from-cmblockbuffer - - NSMutableData *elementaryStream = [NSMutableData data]; - BOOL isIFrame = NO; - CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, 0); - - if (CFArrayGetCount(attachmentsArray)) { - CFBooleanRef notSync; - CFDictionaryRef dict = CFArrayGetValueAtIndex(attachmentsArray, 0); - BOOL keyExists = CFDictionaryGetValueIfPresent(dict, - kCMSampleAttachmentKey_NotSync, - (const void **)¬Sync); - - // Find out if the sample buffer contains an I-Frame (sync frame). If so we will write the SPS and PPS NAL units to the elementary stream. - isIFrame = !keyExists || !CFBooleanGetValue(notSync); - } - - // This is the start code that we will write to the elementary stream before every NAL unit - static const size_t startCodeLength = 4; - static const uint8_t startCode[] = {0x00, 0x00, 0x00, 0x01}; - - // Write the SPS and PPS NAL units to the elementary stream before every I-Frame - if (isIFrame) { - CMFormatDescriptionRef description = CMSampleBufferGetFormatDescription(sampleBuffer); - - // Find out how many parameter sets there are - size_t numberOfParameterSets; - CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description, - 0, - NULL, - NULL, - &numberOfParameterSets, - NULL); - - // Write each parameter set to the elementary stream - for (int i = 0; i < numberOfParameterSets; i++) { - const uint8_t *parameterSetPointer; - size_t parameterSetLength; - CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description, - i, - ¶meterSetPointer, - ¶meterSetLength, - NULL, - NULL); - - // Write the parameter set to the elementary stream - [elementaryStream appendBytes:startCode length:startCodeLength]; - [elementaryStream appendBytes:parameterSetPointer length:parameterSetLength]; - } - } - - // Get a pointer to the raw AVCC NAL unit data in the sample buffer - size_t blockBufferLength = 0; - char *bufferDataPointer = NULL; - CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBuffer); - - CMBlockBufferGetDataPointer(blockBufferRef, 0, NULL, &blockBufferLength, &bufferDataPointer); - - // Loop through all the NAL units in the block buffer and write them to the elementary stream with start codes instead of AVCC length headers - size_t bufferOffset = 0; - static const int AVCCHeaderLength = 4; - while (bufferOffset < blockBufferLength - AVCCHeaderLength) { - // Read the NAL unit length - uint32_t NALUnitLength = 0; - memcpy(&NALUnitLength, bufferDataPointer + bufferOffset, AVCCHeaderLength); - - // Convert the length value from Big-endian to Little-endian - NALUnitLength = CFSwapInt32BigToHost(NALUnitLength); - [elementaryStream appendBytes:startCode length:startCodeLength]; - - // Write the NAL unit without the AVCC length header to the elementary stream - [elementaryStream appendBytes:bufferDataPointer + bufferOffset + AVCCHeaderLength length:NALUnitLength]; - - // Move to the next NAL unit in the block buffer - bufferOffset += AVCCHeaderLength + NALUnitLength; - } - - - return elementaryStream; + +- (BOOL)isVideoStreamingPaused { + return self.lifecycleManager.isVideoStreamingPaused; } -#pragma mark - Private static singleton variables - -+ (dispatch_queue_t)sdl_streamingDataSerialQueue { - static dispatch_queue_t streamingDataQueue = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - streamingDataQueue = dispatch_queue_create("com.sdl.videoaudiostreaming.encoder", DISPATCH_QUEUE_SERIAL); - }); - - return streamingDataQueue; +- (CGSize)screenSize { + return self.lifecycleManager.screenSize; } -- (CFDictionaryRef _Nullable)pixelBufferOptions { - if (_pixelBufferOptions == nil) { - CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - - OSType pixelFormatType = kCVPixelFormatType_32BGRA; - - CFNumberRef pixelFormatNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormatType); - - CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanFalse); - CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferCGBitmapContextCompatibilityKey, kCFBooleanFalse); - CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, pixelFormatNumberRef); - - CFRelease(pixelFormatNumberRef); - - _pixelBufferOptions = pixelBufferOptions; - } - return _pixelBufferOptions; +- (CVPixelBufferPoolRef __nullable)pixelBufferPool { + return self.lifecycleManager.pixelBufferPool; } -#pragma mark - Private Functions -- (void)sdl_applicationDidEnterBackground:(NSNotification *)notification { - [self.touchManager cancelPendingTouches]; +- (SDLStreamingEncryptionFlag)requestedEncryptionType { + return self.lifecycleManager.requestedEncryptionType; } -- (void)sdl_applicationDidResignActive:(NSNotification *)notification { - [self.touchManager cancelPendingTouches]; -} - -- (void)sdl_updateScreenSizeFromDisplayCapabilities:(SDLDisplayCapabilities *)displayCapabilities { - if (displayCapabilities.graphicSupported.boolValue == false) { - SDLLogW(@"Graphics not supported on the remote system, screen size is also likely unavailable"); - return; - } - SDLImageResolution *resolution = displayCapabilities.screenParams.resolution; - if (resolution != nil) { - _screenSize = CGSizeMake(resolution.resolutionWidth.floatValue, - resolution.resolutionHeight.floatValue); - } else { - _screenSize = SDLDefaultScreenSize; - } - _pixelBufferOptions = nil; +#pragma mark - Setters +- (void)setRequestedEncryptionType:(SDLStreamingEncryptionFlag)requestedEncryptionType { + self.lifecycleManager.requestedEncryptionType = requestedEncryptionType; } @end diff --git a/SmartDeviceLink/SDLStreamingMediaManagerConstants.h b/SmartDeviceLink/SDLStreamingMediaManagerConstants.h new file mode 100644 index 000000000..2fc007d6f --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaManagerConstants.h @@ -0,0 +1,27 @@ +// +// SDLStreamingMediaManagerConstants.h +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 2/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <UIKit/UIKit.h> + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, SDLStreamingEncryptionFlag) { + SDLStreamingEncryptionFlagNone, + SDLStreamingEncryptionFlagAuthenticateOnly, + SDLStreamingEncryptionFlagAuthenticateAndEncrypt +}; + +extern CGSize const SDLDefaultScreenSize; + +extern NSString *const SDLVideoStreamDidStartNotification; +extern NSString *const SDLVideoStreamDidStopNotification; + +extern NSString *const SDLAudioStreamDidStartNotification; +extern NSString *const SDLAudioStreamDidStopNotification; + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLStreamingMediaManagerConstants.m b/SmartDeviceLink/SDLStreamingMediaManagerConstants.m new file mode 100644 index 000000000..1c65284d3 --- /dev/null +++ b/SmartDeviceLink/SDLStreamingMediaManagerConstants.m @@ -0,0 +1,18 @@ +// +// SDLStreamingMediaManagerConstants.m +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 2/16/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <UIKit/UIKit.h> +#import "SDLStreamingMediaManagerConstants.h" + +CGSize const SDLDefaultScreenSize = {0, 0}; + +NSString *const SDLVideoStreamDidStartNotification = @"com.sdl.videoStreamDidStart"; +NSString *const SDLVideoStreamDidStopNotification = @"com.sdl.videoStreamDidStop"; + +NSString *const SDLAudioStreamDidStartNotification = @"com.sdl.audioStreamDidStart"; +NSString *const SDLAudioStreamDidStopNotification = @"com.sdl.audioStreamDidStop"; diff --git a/SmartDeviceLink/SDLTouch.h b/SmartDeviceLink/SDLTouch.h index d56cea961..cead4adb2 100644 --- a/SmartDeviceLink/SDLTouch.h +++ b/SmartDeviceLink/SDLTouch.h @@ -62,4 +62,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END
\ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLTouch.m b/SmartDeviceLink/SDLTouch.m index 97e7e3d0c..ca1d06441 100644 --- a/SmartDeviceLink/SDLTouch.m +++ b/SmartDeviceLink/SDLTouch.m @@ -60,4 +60,4 @@ NS_ASSUME_NONNULL_BEGIN @end -NS_ASSUME_NONNULL_END
\ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLTouchManager.h b/SmartDeviceLink/SDLTouchManager.h index 94f52b1b0..c81f9e17a 100644 --- a/SmartDeviceLink/SDLTouchManager.h +++ b/SmartDeviceLink/SDLTouchManager.h @@ -6,18 +6,31 @@ // Copyright © 2016 smartdevicelink. All rights reserved. // -#import "SDLTouchManagerDelegate.h" #import <UIKit/UIKit.h> -#import "SDLProxyListener.h" + +#import "SDLTouchManagerDelegate.h" + +#import "SDLTouchType.h" + +@class SDLTouch; NS_ASSUME_NONNULL_BEGIN -@interface SDLTouchManager : NSObject <SDLProxyListener> +typedef void(^SDLTouchEventHandler)(SDLTouch *touch, SDLTouchType type); + + +@interface SDLTouchManager : NSObject @property (nonatomic, weak, nullable) id<SDLTouchManagerDelegate> touchEventDelegate; /** * @abstract + * Returns all OnTouchEvent notifications as SDLTouch and SDLTouchType objects. + */ +@property (copy, nonatomic, nullable) SDLTouchEventHandler touchEventHandler; + +/** + * @abstract * Distance between two taps on the screen, in the head unit's coordinate system, used * for registering double-tap callbacks. * @remark diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m index a2154b9df..8e16411dd 100644 --- a/SmartDeviceLink/SDLTouchManager.m +++ b/SmartDeviceLink/SDLTouchManager.m @@ -12,12 +12,15 @@ #import "dispatch_timer.h" #import "SDLLogMacros.h" +#import "SDLNotificationConstants.h" #import "SDLOnTouchEvent.h" #import "SDLPinchGesture.h" +#import "SDLProxyListener.h" +#import "SDLRPCNotificationNotification.h" #import "SDLTouch.h" #import "SDLTouchCoord.h" #import "SDLTouchEvent.h" -#import "SDLTouchType.h" + NS_ASSUME_NONNULL_BEGIN @@ -87,6 +90,8 @@ static NSUInteger const MaximumNumberOfTouches = 2; _tapDistanceThreshold = 50.0f; _touchEnabled = YES; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sdl_onTouchEvent:) name:SDLDidReceiveTouchEventNotification object:nil]; + return self; } @@ -95,34 +100,34 @@ static NSUInteger const MaximumNumberOfTouches = 2; [self sdl_cancelSingleTapTimer]; } -#pragma mark - SDLProxyListener Delegate -- (void)onProxyOpened { -} -- (void)onProxyClosed { -} -- (void)onOnHMIStatus:(SDLOnHMIStatus *)notification { -} -- (void)onOnDriverDistraction:(SDLOnDriverDistraction *)notification { -} +#pragma mark - SDLDidReceiveTouchEventNotification -- (void)onOnTouchEvent:(SDLOnTouchEvent *)notification { - if (!self.isTouchEnabled) { +- (void)sdl_onTouchEvent:(SDLRPCNotificationNotification *)notification { + if (!self.isTouchEnabled + || (!self.touchEventHandler && !self.touchEventDelegate) + || ![notification.notification isKindOfClass:SDLOnTouchEvent.class]) { return; } - - SDLTouchEvent *touchEvent = notification.event.firstObject; - + + SDLOnTouchEvent* onTouchEvent = (SDLOnTouchEvent*)notification.notification; + + SDLTouchType touchType = onTouchEvent.type; + SDLTouchEvent *touchEvent = onTouchEvent.event.firstObject; SDLTouch *touch = [[SDLTouch alloc] initWithTouchEvent:touchEvent]; - if (touch.identifier > MaximumNumberOfTouches) { + if (self.touchEventHandler) { + self.touchEventHandler(touch, touchType); + } + + if (!self.touchEventDelegate || (touch.identifier > MaximumNumberOfTouches)) { return; } - if ([notification.type isEqualToEnum:SDLTouchTypeBegin]) { + if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) { [self sdl_handleTouchBegan:touch]; - } else if ([notification.type isEqualToEnum:SDLTouchTypeMove]) { + } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) { [self sdl_handleTouchMoved:touch]; - } else if ([notification.type isEqualToEnum:SDLTouchTypeEnd]) { + } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) { [self sdl_handleTouchEnded:touch]; } } diff --git a/SmartDeviceLink/SDLVideoEncoder.h b/SmartDeviceLink/SDLVideoEncoder.h new file mode 100644 index 000000000..e48f8c311 --- /dev/null +++ b/SmartDeviceLink/SDLVideoEncoder.h @@ -0,0 +1,70 @@ +// +// SDLVideoEncoder.h +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 12/5/16. +// Copyright © 2016 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> +#import <VideoToolbox/VideoToolbox.h> + +#import "SDLMacros.h" +#import "SDLVideoEncoderDelegate.h" + +@class SDLVideoEncoder; + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, SDLVideoEncoderError) { + SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure = 0, + SDLVideoEncoderErrorConfigurationAllocationFailure = 1, + SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure = 2 +}; + +extern NSString *const SDLErrorDomainVideoEncoder; + + +@interface SDLVideoEncoder : NSObject + +@property (nonatomic, weak, nullable) id<SDLVideoEncoderDelegate> delegate; + +/** + * The settings used in a VTCompressionSessionRef encoder. These will be verified when the video stream is started. Acceptable properties for this are located in VTCompressionProperties. + * + */ +@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *videoEncoderSettings; + +/** + * Provides default video encoder settings used. + */ +#if SDL_SUPPORTS_CLASS_PROPERTIES +@property (class, strong, nonatomic, readonly) NSDictionary<NSString *, id> *defaultVideoEncoderSettings; +#else ++ (NSDictionary<NSString *, id>*)defaultVideoEncoderSettings; +#endif + +/** + * 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). + * @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; + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithDimensions:(CGSize)dimensions properties:(NSDictionary<NSString *, id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError **)error NS_DESIGNATED_INITIALIZER; + +- (void)stop; + +- (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer; + +/** + * Creates a new pixel buffer using the pixelBufferPool property. + */ +- (CVPixelBufferRef CV_NULLABLE)newPixelBuffer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLVideoEncoder.m b/SmartDeviceLink/SDLVideoEncoder.m new file mode 100644 index 000000000..91eed8631 --- /dev/null +++ b/SmartDeviceLink/SDLVideoEncoder.m @@ -0,0 +1,274 @@ +// +// SDLVideoEncoder.m +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 12/5/16. +// Copyright © 2016 smartdevicelink. All rights reserved. +// + +#import "SDLVideoEncoder.h" + +#import "SDLLogMacros.h" + + +NS_ASSUME_NONNULL_BEGIN + +NSString *const SDLErrorDomainVideoEncoder = @"com.sdl.videoEncoder"; +static NSDictionary<NSString *, id>* _defaultVideoEncoderSettings; + + +@interface SDLVideoEncoder () + +@property (assign, nonatomic, nullable) VTCompressionSessionRef compressionSession; +@property (assign, nonatomic, nullable) CFDictionaryRef sdl_pixelBufferOptions; +@property (assign, nonatomic) NSUInteger currentFrameNumber; + +@end + + +@implementation SDLVideoEncoder + ++ (void)initialize { + if (self != [SDLVideoEncoder class]) { + return; + } + + _defaultVideoEncoderSettings = @{ + (__bridge NSString *)kVTCompressionPropertyKey_ProfileLevel: (__bridge NSString *)kVTProfileLevel_H264_Baseline_AutoLevel, + (__bridge NSString *)kVTCompressionPropertyKey_RealTime: @YES + }; +} + +- (instancetype)initWithDimensions:(CGSize)dimensions properties:(NSDictionary<NSString *,id> *)properties delegate:(id<SDLVideoEncoderDelegate> __nullable)delegate error:(NSError * _Nullable __autoreleasing *)error { + self = [super init]; + if (!self) { + return nil; + } + + _compressionSession = NULL; + _currentFrameNumber = 0; + _videoEncoderSettings = properties; + + _delegate = delegate; + + OSStatus status; + + // Create a compression session + status = VTCompressionSessionCreate(NULL, dimensions.width, dimensions.height, kCMVideoCodecType_H264, NULL, self.sdl_pixelBufferOptions, NULL, &sdl_videoEncoderOutputCallback, (__bridge void *)self, &_compressionSession); + + if (status != noErr) { + if (!*error) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionCreationFailure userInfo:@{ @"OSStatus": @(status) }]; + SDLLogE(@"Error attempting to create video compression session: %@", *error); + } + + return nil; + } + + CFRelease(_sdl_pixelBufferOptions); + _sdl_pixelBufferOptions = nil; + + // Validate that the video encoder properties are valid. + CFDictionaryRef supportedProperties; + status = VTSessionCopySupportedPropertyDictionary(self.compressionSession, &supportedProperties); + if (status != noErr) { + if (!*error) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }]; + } + + return nil; + } + + 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}]; + } + CFRelease(supportedProperties); + return nil; + } + } + CFRelease(supportedProperties); + + // Populate the video encoder settings from provided dictionary. + for (NSString *key in videoEncoderKeys) { + id value = self.videoEncoderSettings[key]; + + status = VTSessionSetProperty(self.compressionSession, (__bridge CFStringRef)key, (__bridge CFTypeRef)value); + if (status != noErr) { + if (!*error) { + *error = [NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ @"OSStatus": @(status) }]; + } + + return nil; + } + } + + return self; +} + +- (void)stop { + if (self.compressionSession != NULL) { + VTCompressionSessionInvalidate(self.compressionSession); + CFRelease(self.compressionSession); + self.compressionSession = NULL; + } +} + +- (BOOL)encodeFrame:(CVImageBufferRef)imageBuffer { + OSStatus status = VTCompressionSessionEncodeFrame(_compressionSession, imageBuffer, CMTimeMake(self.currentFrameNumber++, 30), kCMTimeInvalid, NULL, (__bridge void *)self, NULL); + + return (status == noErr); +} + +- (CVPixelBufferRef CV_NULLABLE)newPixelBuffer { + if (self.pixelBufferPool == NULL) { + return NULL; + } + + CVPixelBufferRef pixelBuffer; + CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, + self.pixelBufferPool, + &pixelBuffer); + + return pixelBuffer; +} + +#pragma mark - Public +#pragma mark Getters ++ (NSDictionary<NSString *, id> *)defaultVideoEncoderSettings { + return _defaultVideoEncoderSettings; +} + +- (CVPixelBufferPoolRef CV_NULLABLE)pixelBufferPool { + return VTCompressionSessionGetPixelBufferPool(self.compressionSession); +} + +#pragma mark - Private +#pragma mark Callback +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) { + SDLLogW(@"Error encoding video frame: %d", (int)status); + return; + } + + if (outputCallbackRefCon == NULL || sourceFrameRefCon == NULL || sampleBuffer == NULL) { + return; + } + + SDLVideoEncoder *encoder = (__bridge SDLVideoEncoder *)sourceFrameRefCon; + NSData *elementaryStreamData = [encoder.class sdl_encodeElementaryStreamWithSampleBuffer:sampleBuffer]; + + if ([encoder.delegate respondsToSelector:@selector(videoEncoder:hasEncodedFrame:)]) { + [encoder.delegate videoEncoder:encoder hasEncodedFrame:elementaryStreamData]; + } +} + +#pragma mark Getters +- (CFDictionaryRef _Nullable)sdl_pixelBufferOptions { + if (_sdl_pixelBufferOptions == nil) { + CFMutableDictionaryRef pixelBufferOptions = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + + OSType pixelFormatType = kCVPixelFormatType_32BGRA; + + CFNumberRef pixelFormatNumberRef = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pixelFormatType); + + CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferCGImageCompatibilityKey, kCFBooleanFalse); + CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferCGBitmapContextCompatibilityKey, kCFBooleanFalse); + CFDictionarySetValue(pixelBufferOptions, kCVPixelBufferPixelFormatTypeKey, pixelFormatNumberRef); + + CFRelease(pixelFormatNumberRef); + + _sdl_pixelBufferOptions = pixelBufferOptions; + } + + return _sdl_pixelBufferOptions; +} + +#pragma mark Helpers ++ (NSData *)sdl_encodeElementaryStreamWithSampleBuffer:(CMSampleBufferRef)sampleBuffer { + // Creating an elementaryStream: http://stackoverflow.com/questions/28396622/extracting-h264-from-cmblockbuffer + NSMutableData *elementaryStream = [NSMutableData data]; + BOOL isIFrame = NO; + CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, 0); + + if (CFArrayGetCount(attachmentsArray)) { + CFBooleanRef notSync; + CFDictionaryRef dict = CFArrayGetValueAtIndex(attachmentsArray, 0); + BOOL keyExists = CFDictionaryGetValueIfPresent(dict, kCMSampleAttachmentKey_NotSync, (const void **)¬Sync); + + // Find out if the sample buffer contains an I-Frame (sync frame). If so we will write the SPS and PPS NAL units to the elementary stream. + isIFrame = !keyExists || !CFBooleanGetValue(notSync); + } + + // This is the start code that we will write to the elementary stream before every NAL unit + static const size_t startCodeLength = 4; + static const uint8_t startCode[] = {0x00, 0x00, 0x00, 0x01}; + + // Write the SPS and PPS NAL units to the elementary stream before every I-Frame + if (isIFrame) { + CMFormatDescriptionRef description = CMSampleBufferGetFormatDescription(sampleBuffer); + + // Find out how many parameter sets there are + size_t numberOfParameterSets; + CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description, + 0, + NULL, + NULL, + &numberOfParameterSets, + NULL); + + // Write each parameter set to the elementary stream + for (int i = 0; i < numberOfParameterSets; i++) { + const uint8_t *parameterSetPointer; + size_t parameterSetLength; + CMVideoFormatDescriptionGetH264ParameterSetAtIndex(description, + i, + ¶meterSetPointer, + ¶meterSetLength, + NULL, + NULL); + + // Write the parameter set to the elementary stream + [elementaryStream appendBytes:startCode length:startCodeLength]; + [elementaryStream appendBytes:parameterSetPointer length:parameterSetLength]; + } + } + + // Get a pointer to the raw AVCC NAL unit data in the sample buffer + size_t blockBufferLength = 0; + char *bufferDataPointer = NULL; + CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBuffer); + + CMBlockBufferGetDataPointer(blockBufferRef, 0, NULL, &blockBufferLength, &bufferDataPointer); + + // Loop through all the NAL units in the block buffer and write them to the elementary stream with start codes instead of AVCC length headers + size_t bufferOffset = 0; + static const int AVCCHeaderLength = 4; + while (bufferOffset < blockBufferLength - AVCCHeaderLength) { + // Read the NAL unit length + uint32_t NALUnitLength = 0; + memcpy(&NALUnitLength, bufferDataPointer + bufferOffset, AVCCHeaderLength); + + // Convert the length value from Big-endian to Little-endian + NALUnitLength = CFSwapInt32BigToHost(NALUnitLength); + [elementaryStream appendBytes:startCode length:startCodeLength]; + + // Write the NAL unit without the AVCC length header to the elementary stream + [elementaryStream appendBytes:bufferDataPointer + bufferOffset + AVCCHeaderLength length:NALUnitLength]; + + // Move to the next NAL unit in the block buffer + bufferOffset += AVCCHeaderLength + NALUnitLength; + } + + + return elementaryStream; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLink/SDLVideoEncoderDelegate.h b/SmartDeviceLink/SDLVideoEncoderDelegate.h new file mode 100644 index 000000000..db4294106 --- /dev/null +++ b/SmartDeviceLink/SDLVideoEncoderDelegate.h @@ -0,0 +1,17 @@ +// +// SDLVideoEncoderDelegate.h +// SmartDeviceLink-iOS +// +// Created by Joel Fischer on 8/1/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +@class SDLVideoEncoder; + +@protocol SDLVideoEncoderDelegate <NSObject> + +- (void)videoEncoder:(SDLVideoEncoder *)encoder hasEncodedFrame:(NSData*)encodedVideo; + +@end diff --git a/SmartDeviceLink/SmartDeviceLink.h b/SmartDeviceLink/SmartDeviceLink.h index 7d8382c09..bc87a7e92 100644 --- a/SmartDeviceLink/SmartDeviceLink.h +++ b/SmartDeviceLink/SmartDeviceLink.h @@ -188,8 +188,10 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLLocationCoordinate.h" #import "SDLLocationDetails.h" #import "SDLMenuParams.h" +#import "SDLMetadataTags.h" #import "SDLMyKey.h" #import "SDLNavigationCapability.h" +#import "SDLOasisAddress.h" #import "SDLParameterPermissions.h" #import "SDLPermissionItem.h" #import "SDLPhoneCapability.h" @@ -211,6 +213,8 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLTurn.h" #import "SDLVehicleDataResult.h" #import "SDLVehicleType.h" +#import "SDLVideoStreamingCapability.h" +#import "SDLVideoStreamingFormat.h" #import "SDLVrHelpItem.h" // Enums @@ -252,6 +256,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLLockScreenStatus.h" #import "SDLMaintenanceModeStatus.h" #import "SDLMediaClockFormat.h" +#import "SDLMetadataType.h" #import "SDLPRNDL.h" #import "SDLPermissionStatus.h" #import "SDLPowerModeQualificationStatus.h" @@ -281,6 +286,8 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLVehicleDataResultCode.h" #import "SDLVehicleDataStatus.h" #import "SDLVehicleDataType.h" +#import "SDLVideoStreamingCodec.h" +#import "SDLVideoStreamingProtocol.h" #import "SDLVrCapabilities.h" #import "SDLWarningLightStatus.h" #import "SDLWaypointType.h" @@ -291,6 +298,7 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLConfiguration.h" #import "SDLLifecycleConfiguration.h" #import "SDLLockScreenConfiguration.h" +#import "SDLStreamingMediaConfiguration.h" // Files #import "SDLArtwork.h" @@ -309,10 +317,15 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLPermissionConstants.h" #import "SDLPermissionManager.h" +// Touches +#import "SDLPinchGesture.h" +#import "SDLTouch.h" + // Utilities #import "NSNumber+NumberType.h" #import "SDLErrorConstants.h" #import "SDLNotificationConstants.h" +#import "SDLStreamingMediaManagerConstants.h" // Notifications #import "SDLRPCNotificationNotification.h" @@ -329,3 +342,6 @@ FOUNDATION_EXPORT const unsigned char SmartDeviceLinkVersionString[]; #import "SDLLogTargetAppleSystemLog.h" #import "SDLLogTargetFile.h" #import "SDLLogTargetOSLog.h" + +// Macros +#import "SDLMacros.h" diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m index 9d86dfbc2..358e9f816 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLConfigurationSpec.m @@ -3,35 +3,18 @@ #import "SDLConfiguration.h" #import "SDLLifecycleConfiguration.h" +#import "SDLLogConfiguration.h" #import "SDLLockScreenConfiguration.h" QuickSpecBegin(SDLConfigurationSpec) describe(@"a configuration", ^{ __block SDLConfiguration *testConfig = nil; - - context(@"created with a custom lifecycle and default lockscreen config", ^{ - __block SDLLifecycleConfiguration *someLifecycleConfig = nil; - __block NSString *someAppName = nil; - __block NSString *someAppId = nil; - - beforeEach(^{ - someAppName = @"some name"; - someAppId = @"some id"; - someLifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:someAppName appId:someAppId]; - - testConfig = [SDLConfiguration configurationWithLifecycle:someLifecycleConfig lockScreen:[SDLLockScreenConfiguration enabledConfiguration]]; - }); - - it(@"should contain the correct configs", ^{ - expect(testConfig.lifecycleConfig).to(equal(someLifecycleConfig)); - expect(@(testConfig.lockScreenConfig.enableAutomaticLockScreen)).to(equal(@YES)); - }); - }); - - context(@"created with a custom lifecycle and lockscreen config", ^{ + + context(@"created with custom configs", ^{ __block SDLLifecycleConfiguration *someLifecycleConfig = nil; __block SDLLockScreenConfiguration *someLockscreenConfig = nil; + __block SDLLogConfiguration *someLogConfig = nil; __block NSString *someAppName = nil; __block NSString *someAppId = nil; @@ -46,13 +29,15 @@ describe(@"a configuration", ^{ someLifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:someAppName appId:someAppId]; someLockscreenConfig = [SDLLockScreenConfiguration enabledConfigurationWithAppIcon:someImage backgroundColor:someBackgroundColor]; + someLogConfig = [SDLLogConfiguration defaultConfiguration]; - testConfig = [SDLConfiguration configurationWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig]; + testConfig = [SDLConfiguration configurationWithLifecycle:someLifecycleConfig lockScreen:someLockscreenConfig logging:someLogConfig]; }); it(@"should contain the correct configs", ^{ expect(testConfig.lifecycleConfig).to(equal(someLifecycleConfig)); expect(testConfig.lockScreenConfig).to(equal(someLockscreenConfig)); + expect(testConfig.loggingConfig).to(equal(someLogConfig)); }); }); }); diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.h b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.h new file mode 100644 index 000000000..48e0c710c --- /dev/null +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.h @@ -0,0 +1,31 @@ +// +// SDLFakeSecurityManager.h +// SmartDeviceLink-iOS +// +// Created by Joel Fischer on 8/15/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +#import "SDLSecurityType.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface SDLFakeSecurityManager : NSObject <SDLSecurityType> + +@property (copy, nonatomic) NSString *appId; + +- (void)initializeWithAppId:(NSString *)appId completionHandler:(void (^)(NSError *_Nullable error))completionHandler; +- (void)stop; + +- (nullable NSData *)runHandshakeWithClientData:(NSData *)data error:(NSError **)error; + +- (nullable NSData *)encryptData:(NSData *)data withError:(NSError **)error; +- (nullable NSData *)decryptData:(NSData *)data withError:(NSError **)error; + ++ (NSSet<NSString *> *)availableMakes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.m new file mode 100644 index 000000000..e50dab063 --- /dev/null +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFakeSecurityManager.m @@ -0,0 +1,37 @@ +// +// SDLFakeSecurityManager.m +// SmartDeviceLink-iOS +// +// Created by Joel Fischer on 8/15/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import "SDLFakeSecurityManager.h" + +@implementation SDLFakeSecurityManager + +- (void)initializeWithAppId:(NSString *)appId completionHandler:(void (^)(NSError *_Nullable error))completionHandler { + +} + +- (void)stop { + +} + +- (nullable NSData *)runHandshakeWithClientData:(NSData *)data error:(NSError **)error { + return nil; +} + +- (nullable NSData *)encryptData:(NSData *)data withError:(NSError **)error { + return nil; +} + +- (nullable NSData *)decryptData:(NSData *)data withError:(NSError **)error { + return nil; +} + ++ (NSSet<NSString *> *)availableMakes { + return [NSSet set]; +} + +@end diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleConfigurationSpec.m index fac25a59f..16be756f0 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleConfigurationSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleConfigurationSpec.m @@ -37,7 +37,6 @@ describe(@"a lifecycle configuration", ^{ expect(testConfig.ttsName).to(beNil()); expect(testConfig.voiceRecognitionCommandNames).to(beNil()); expect(testConfig.resumeHash).to(beNil()); - expect(testConfig.securityManagers).to(beNil()); }); describe(@"after setting properties manually", ^{ @@ -81,7 +80,6 @@ describe(@"a lifecycle configuration", ^{ expect(testConfig.ttsName).to(haveCount(@1)); expect(testConfig.voiceRecognitionCommandNames).to(haveCount(@(someSynonyms.count))); expect(testConfig.resumeHash).to(match(someResumeHashString)); - expect(testConfig.securityManagers).to(beNil()); }); }); }); @@ -109,12 +107,11 @@ describe(@"a lifecycle configuration", ^{ expect(@(testConfig.tcpDebugPort)).to(equal(@(somePort))); expect(@([testConfig.appType isEqualToEnum:SDLAppHMITypeDefault])).to(equal(@YES)); expect(@([testConfig.language isEqualToEnum:SDLLanguageEnUs])).to(equal(@YES)); - expect(@([[testConfig.languagesSupported firstObject] isEqualToString:SDLLanguageEnUs])).to(equal(@YES)); + expect(@([[testConfig.languagesSupported firstObject] isEqualToEnum:SDLLanguageEnUs])).to(equal(@YES)); expect(testConfig.shortAppName).to(beNil()); expect(testConfig.ttsName).to(beNil()); expect(testConfig.voiceRecognitionCommandNames).to(beNil()); expect(testConfig.resumeHash).to(beNil()); - expect(testConfig.securityManagers).to(beNil()); }); describe(@"after setting properties manually", ^{ @@ -156,7 +153,6 @@ describe(@"a lifecycle configuration", ^{ expect(testConfig.ttsName).to(contain(someTTSChunk)); expect(testConfig.ttsName).to(haveCount(@1)); expect(testConfig.voiceRecognitionCommandNames).to(haveCount(@(someSynonyms.count))); - expect(testConfig.securityManagers).to(beNil()); }); }); }); diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m index 15ed788e4..92f721803 100644 --- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m @@ -19,11 +19,13 @@ #import "SDLPermissionManager.h" #import "SDLProxy.h" #import "SDLProxyFactory.h" +#import "SDLProtocol.h" #import "SDLRegisterAppInterface.h" #import "SDLRegisterAppInterfaceResponse.h" #import "SDLResult.h" #import "SDLShow.h" #import "SDLStateMachine.h" +#import "SDLStreamingMediaManager.h" #import "SDLTextAlignment.h" #import "SDLUnregisterAppInterface.h" #import "SDLUnregisterAppInterfaceResponse.h" @@ -61,23 +63,28 @@ xdescribe(@"a lifecycle manager", ^{ __block SDLConfiguration *testConfig = nil; __block id managerDelegateMock = OCMProtocolMock(@protocol(SDLManagerDelegate)); + __block id protocolMock = OCMClassMock([SDLAbstractProtocol class]); __block id proxyBuilderClassMock = OCMStrictClassMock([SDLProxyFactory class]); __block id proxyMock = OCMClassMock([SDLProxy class]); __block id lockScreenManagerMock = OCMClassMock([SDLLockScreenManager class]); __block id fileManagerMock = OCMClassMock([SDLFileManager class]); __block id permissionManagerMock = OCMClassMock([SDLPermissionManager class]); + __block id streamingManagerMock = OCMClassMock([SDLStreamingMediaManager class]); beforeEach(^{ OCMStub([proxyBuilderClassMock buildSDLProxyWithListener:[OCMArg any]]).andReturn(proxyMock); + OCMStub([(SDLProxy*)proxyMock protocol]).andReturn(protocolMock); SDLLifecycleConfiguration *testLifecycleConfig = [SDLLifecycleConfiguration defaultConfigurationWithAppName:@"Test App" appId:@"Test Id"]; testLifecycleConfig.shortAppName = @"Short Name"; + testLifecycleConfig.appType = SDLAppHMITypeNavigation; testConfig = [SDLConfiguration configurationWithLifecycle:testLifecycleConfig lockScreen:[SDLLockScreenConfiguration disabledConfiguration]]; testManager = [[SDLLifecycleManager alloc] initWithConfiguration:testConfig delegate:managerDelegateMock]; testManager.lockScreenManager = lockScreenManagerMock; testManager.fileManager = fileManagerMock; testManager.permissionManager = permissionManagerMock; + testManager.streamManager = streamingManagerMock; }); it(@"should initialize properties", ^{ @@ -87,12 +94,13 @@ xdescribe(@"a lifecycle manager", ^{ expect(@(testManager.lastCorrelationId)).to(equal(@0)); expect(testManager.fileManager).toNot(beNil()); expect(testManager.permissionManager).toNot(beNil()); - expect(testManager.streamManager).to(beNil()); + expect(testManager.streamManager).toNot(beNil()); expect(testManager.proxy).to(beNil()); expect(testManager.registerResponse).to(beNil()); expect(testManager.lockScreenManager).toNot(beNil()); expect(testManager.notificationDispatcher).toNot(beNil()); expect(testManager.responseDispatcher).toNot(beNil()); + expect(testManager.streamManager).toNot(beNil()); expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES)); }); @@ -222,11 +230,13 @@ xdescribe(@"a lifecycle manager", ^{ describe(@"after receiving a register app interface response", ^{ __block NSError *fileManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil]; __block NSError *permissionManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil]; + __block NSError *streamingManagerStartError = [NSError errorWithDomain:@"testDomain" code:0 userInfo:nil]; beforeEach(^{ OCMStub([(SDLLockScreenManager *)lockScreenManagerMock start]); OCMStub([fileManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), fileManagerStartError, nil])]); OCMStub([permissionManagerMock startWithCompletionHandler:([OCMArg invokeBlockWithArgs:@(YES), permissionManagerStartError, nil])]); + OCMStub([streamingManagerMock startWithProtocol:protocolMock completionHandler:([OCMArg invokeBlockWithArgs:@(YES), streamingManagerStartError, nil])]); // Send an RAI response to move the lifecycle forward [testManager.lifecycleStateMachine transitionToState:SDLLifecycleStateRegistered]; @@ -238,6 +248,7 @@ xdescribe(@"a lifecycle manager", ^{ OCMVerify([(SDLLockScreenManager *)lockScreenManagerMock start]); OCMVerify([fileManagerMock startWithCompletionHandler:[OCMArg any]]); OCMVerify([permissionManagerMock startWithCompletionHandler:[OCMArg any]]); + OCMVerify([streamingManagerMock startWithProtocol:[OCMArg any] completionHandler:[OCMArg any]]); }); itBehavesLike(@"unable to send an RPC", ^{ return @{ @"manager": testManager }; }); diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m new file mode 100644 index 000000000..d9a166487 --- /dev/null +++ b/SmartDeviceLinkTests/DevAPISpecs/SDLStreamingMediaConfigurationSpec.m @@ -0,0 +1,83 @@ +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> +#import <VideoToolbox/VideoToolbox.h> + +#import "SDLStreamingMediaConfiguration.h" + +#import "SDLFakeSecurityManager.h" + +QuickSpecBegin(SDLStreamingMediaConfigurationSpec) + +describe(@"a streaming media configuration", ^{ + __block SDLStreamingMediaConfiguration *testConfig = nil; + + context(@"that is created with insecure settings", ^{ + beforeEach(^{ + testConfig = [SDLStreamingMediaConfiguration insecureConfiguration]; + }); + + it(@"should have properly set properties", ^{ + expect(testConfig.securityManagers).to(beNil()); + expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(SDLStreamingEncryptionFlagNone))); + expect(testConfig.customVideoEncoderSettings).to(beNil()); + }); + + describe(@"after setting properties manually", ^{ + __block SDLStreamingEncryptionFlag someEncryptionFlag = SDLStreamingEncryptionFlagNone; + __block NSDictionary<NSString *, id> *someVideoEncoderSettings = nil; + + beforeEach(^{ + someVideoEncoderSettings = @{ + (__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1 + }; + + testConfig.maximumDesiredEncryption = someEncryptionFlag; + testConfig.customVideoEncoderSettings = someVideoEncoderSettings; + }); + + it(@"should have properly set properties", ^{ + expect(testConfig.securityManagers).to(beNil()); + expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(someEncryptionFlag))); + expect(testConfig.customVideoEncoderSettings).to(equal(someVideoEncoderSettings)); + }); + }); + }); + + context(@"that is created with secure settings", ^{ + __block SDLFakeSecurityManager *testFakeSecurityManager = nil; + + beforeEach(^{ + testFakeSecurityManager = [[SDLFakeSecurityManager alloc] init]; + + testConfig = [SDLStreamingMediaConfiguration secureConfigurationWithSecurityManagers:@[testFakeSecurityManager]]; + }); + + it(@"should have properly set properties", ^{ + expect(testConfig.securityManagers).to(contain(testFakeSecurityManager)); + expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(SDLStreamingEncryptionFlagAuthenticateAndEncrypt))); + expect(testConfig.customVideoEncoderSettings).to(beNil()); + }); + + describe(@"after setting properties manually", ^{ + __block SDLStreamingEncryptionFlag someEncryptionFlag = SDLStreamingEncryptionFlagNone; + __block NSDictionary<NSString *, id> *someVideoEncoderSettings = nil; + + beforeEach(^{ + someVideoEncoderSettings = @{ + (__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1 + }; + + testConfig.maximumDesiredEncryption = someEncryptionFlag; + testConfig.customVideoEncoderSettings = someVideoEncoderSettings; + }); + + it(@"should have properly set properties", ^{ + expect(testConfig.securityManagers).to(contain(testFakeSecurityManager)); + expect(@(testConfig.maximumDesiredEncryption)).to(equal(@(someEncryptionFlag))); + expect(testConfig.customVideoEncoderSettings).to(equal(someVideoEncoderSettings)); + }); + }); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m b/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m index c83cd1242..f2aeb1303 100644 --- a/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m +++ b/SmartDeviceLinkTests/ProtocolSpecs/HeaderSpecs/SDLProtocolHeaderSpec.m @@ -22,7 +22,7 @@ describe(@"HeaderForVersion Tests", ^ { }); it(@"Should return latest version for unknown version", ^ { - expect([SDLProtocolHeader headerForVersion:5]).to(raiseException().named(NSInvalidArgumentException)); + expect([SDLProtocolHeader headerForVersion:5]).to(beAKindOf(SDLV2ProtocolHeader.class)); }); }); diff --git a/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMetadataTypeSpec.m b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMetadataTypeSpec.m new file mode 100644 index 000000000..1ede591ee --- /dev/null +++ b/SmartDeviceLinkTests/RPCSpecs/EnumSpecs/SDLMetadataTypeSpec.m @@ -0,0 +1,36 @@ +// +// SDLMetadataTypeSpec.m +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/2/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> + +#import "SDLMetadataType.h" + +QuickSpecBegin(SDLMetadataTypeSpec) + +describe(@"Individual Enum Value Tests", ^ { + it(@"Should match internal values", ^ { + expect(SDLMetadataTypeMediaTitle).to(equal(@"mediaTitle")); + expect(SDLMetadataTypeMediaArtist).to(equal(@"mediaArtist")); + expect(SDLMetadataTypeMediaAlbum).to(equal(@"mediaAlbum")); + expect(SDLMetadataTypeMediaYear).to(equal(@"mediaYear")); + expect(SDLMetadataTypeMediaGenre).to(equal(@"mediaGenre")); + expect(SDLMetadataTypeMediaStation).to(equal(@"mediaStation")); + expect(SDLMetadataTypeRating).to(equal(@"rating")); + expect(SDLMetadataTypeCurrentTemperature).to(equal(@"currentTemperature")); + expect(SDLMetadataTypeMaximumTemperature).to(equal(@"maximumTemperature")); + expect(SDLMetadataTypeMinimumTemperature).to(equal(@"minimumTemperature")); + expect(SDLMetadataTypeWeatherTerm).to(equal(@"weatherTerm")); + expect(SDLMetadataTypeHumidity).to(equal(@"humidity")); + expect(SDLMetadataTypeNone).to(equal(@"none")); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m index 5c20ecf78..80733245e 100644 --- a/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/RequestSpecs/SDLShowSpec.m @@ -9,22 +9,26 @@ #import <Nimble/Nimble.h> #import "SDLImage.h" +#import "SDLMetadataTags.h" +#import "SDLMetadataType.h" #import "SDLNames.h" #import "SDLShow.h" #import "SDLSoftButton.h" #import "SDLTextAlignment.h" - QuickSpecBegin(SDLShowSpec) SDLImage* image1 = [[SDLImage alloc] init]; SDLImage* image2 = [[SDLImage alloc] init]; SDLSoftButton* button = [[SDLSoftButton alloc] init]; +NSArray<SDLMetadataType> *formatArray = @[SDLMetadataTypeMediaArtist,SDLMetadataTypeMediaTitle]; +SDLMetadataTags* testMetadata = [[SDLMetadataTags alloc] initWithTextFieldTypes:formatArray mainField2:formatArray mainField3:formatArray mainField4:formatArray]; + describe(@"Getter/Setter Tests", ^ { it(@"Should set and get correctly", ^ { SDLShow* testRequest = [[SDLShow alloc] init]; - + testRequest.mainField1 = @"field1"; testRequest.mainField2 = @"field2"; testRequest.mainField3 = @"field3"; @@ -37,7 +41,8 @@ describe(@"Getter/Setter Tests", ^ { testRequest.secondaryGraphic = image2; testRequest.softButtons = [@[button] mutableCopy]; testRequest.customPresets = [@[@"preset1", @"preset2"] mutableCopy]; - + testRequest.metadataTags = testMetadata; + expect(testRequest.mainField1).to(equal(@"field1")); expect(testRequest.mainField2).to(equal(@"field2")); expect(testRequest.mainField3).to(equal(@"field3")); @@ -50,8 +55,10 @@ describe(@"Getter/Setter Tests", ^ { expect(testRequest.secondaryGraphic).to(equal(image2)); expect(testRequest.softButtons).to(equal([@[button] mutableCopy])); expect(testRequest.customPresets).to(equal([@[@"preset1", @"preset2"] mutableCopy])); + expect(testRequest.metadataTags).to(equal(testMetadata)); + }); - + it(@"Should get correctly when initialized", ^ { NSMutableDictionary* dict = [@{SDLNameRequest: @{SDLNameParameters: @@ -66,10 +73,11 @@ describe(@"Getter/Setter Tests", ^ { SDLNameGraphic:image1, SDLNameSecondaryGraphic:image2, SDLNameSoftButtons:[@[button] mutableCopy], - SDLNameCustomPresets:[@[@"preset1", @"preset2"] mutableCopy]}, + SDLNameCustomPresets:[@[@"preset1", @"preset2"] mutableCopy], + SDLNameMetadataTags:testMetadata}, SDLNameOperationName:SDLNameShow}} mutableCopy]; SDLShow* testRequest = [[SDLShow alloc] initWithDictionary:dict]; - + expect(testRequest.mainField1).to(equal(@"field1")); expect(testRequest.mainField2).to(equal(@"field2")); expect(testRequest.mainField3).to(equal(@"field3")); @@ -82,11 +90,12 @@ describe(@"Getter/Setter Tests", ^ { expect(testRequest.secondaryGraphic).to(equal(image2)); expect(testRequest.softButtons).to(equal([@[button] mutableCopy])); expect(testRequest.customPresets).to(equal([@[@"preset1", @"preset2"] mutableCopy])); + expect(testRequest.metadataTags).to(equal(testMetadata)); }); - + it(@"Should return nil if not set", ^ { SDLShow* testRequest = [[SDLShow alloc] init]; - + expect(testRequest.mainField1).to(beNil()); expect(testRequest.mainField2).to(beNil()); expect(testRequest.mainField3).to(beNil()); @@ -99,6 +108,7 @@ describe(@"Getter/Setter Tests", ^ { expect(testRequest.secondaryGraphic).to(beNil()); expect(testRequest.softButtons).to(beNil()); expect(testRequest.customPresets).to(beNil()); + expect(testRequest.metadataTags).to(beNil()); }); }); diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m index 0d3b57ece..72cc3df64 100644 --- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLHMICapabilitiesSpec.m @@ -43,7 +43,8 @@ describe(@"SDLHMICapabilities struct", ^{ beforeEach(^{ NSDictionary<NSString *, NSNumber *> *structInitDict = @{ SDLNameNavigation: someNavigationState, - SDLNamePhoneCall: somePhoneCallState + SDLNamePhoneCall: somePhoneCallState, + SDLNameVideoStreaming: someVideoStreamState }; testStruct = [[SDLHMICapabilities alloc] initWithDictionary:[structInitDict mutableCopy]]; }); diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMetadataTagsSpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMetadataTagsSpec.m new file mode 100644 index 000000000..db7d2d855 --- /dev/null +++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLMetadataTagsSpec.m @@ -0,0 +1,41 @@ +// +// SDLMetadataTagsSpec.m +// SmartDeviceLink-iOS +// +// Created by Brett McIsaac on 8/3/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> + +#import "SDLMetadataTags.h" +#import "SDLNames.h" +#import "SDLMetadataType.h" + +QuickSpecBegin(SDLMetadataTagsSpec) + +describe(@"Initialization tests", ^{ + it(@"Should get correctly when initialized with Arrays", ^ { + NSArray<SDLMetadataType> *formatArray = @[SDLMetadataTypeMediaArtist, SDLMetadataTypeMediaTitle]; + SDLMetadataTags* testStruct = [[SDLMetadataTags alloc] initWithTextFieldTypes:formatArray mainField2:formatArray mainField3:formatArray mainField4:formatArray]; + + expect(testStruct.mainField1).to(equal(formatArray)); + expect(testStruct.mainField2).to(equal(formatArray)); + expect(testStruct.mainField3).to(equal(formatArray)); + expect(testStruct.mainField4).to(equal(formatArray)); + }); + + it(@"Should return nil if not set", ^ { + SDLMetadataTags *testStruct = [[SDLMetadataTags alloc] init]; + + expect(testStruct.mainField1).to(beNil()); + expect(testStruct.mainField2).to(beNil()); + expect(testStruct.mainField3).to(beNil()); + expect(testStruct.mainField4).to(beNil()); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m new file mode 100644 index 000000000..613313bcd --- /dev/null +++ b/SmartDeviceLinkTests/SDLStreamingMediaLifecycleManagerSpec.m @@ -0,0 +1,352 @@ +// +// SDLStreamingMediaLifecycleManagerSpec.m +// SmartDeviceLink-iOS +// + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> +#import <OCMock/OCMock.h> + +#import "SDLDisplayCapabilities.h" +#import "SDLImageResolution.h" +#import "SDLNotificationConstants.h" +#import "SDLRPCNotificationNotification.h" +#import "SDLRegisterAppInterfaceResponse.h" +#import "SDLRPCResponseNotification.h" +#import "SDLScreenParams.h" +#import "SDLStateMachine.h" +#import "SDLStreamingMediaLifecycleManager.h" +#import "SDLProtocol.h" +#import "SDLOnHMIStatus.h" +#import "SDLHMILevel.h" + +QuickSpecBegin(SDLStreamingMediaLifecycleManagerSpec) + +describe(@"the streaming media manager", ^{ + __block SDLStreamingMediaLifecycleManager *streamingLifecycleManager = nil; + __block SDLStreamingEncryptionFlag streamingEncryptionFlag = SDLStreamingEncryptionFlagAuthenticateOnly; + __block NSDictionary<NSString *, id> *someVideoEncoderSettings = nil; + __block NSString *someBackgroundTitleString = nil; + + __block void (^sendNotificationForHMILevel)(SDLHMILevel hmiLevel) = ^(SDLHMILevel hmiLevel) { + SDLOnHMIStatus *hmiStatus = [[SDLOnHMIStatus alloc] init]; + hmiStatus.hmiLevel = hmiLevel; + SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidChangeHMIStatusNotification object:self rpcNotification:hmiStatus]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; + + [NSThread sleepForTimeInterval:0.1]; + }; + + beforeEach(^{ + someVideoEncoderSettings = @{ + (__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1 + }; + someBackgroundTitleString = @"Open Test App"; + streamingLifecycleManager = [[SDLStreamingMediaLifecycleManager alloc] initWithEncryption:streamingEncryptionFlag videoEncoderSettings:someVideoEncoderSettings]; + }); + + it(@"should initialize properties", ^{ + expect(streamingLifecycleManager.touchManager).toNot(beNil()); + expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoConnected)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioConnected)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoEncrypted)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioEncrypted)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoStreamingPaused)).to(equal(@YES)); + expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero))).to(equal(@YES)); + expect(@(streamingLifecycleManager.pixelBufferPool == NULL)).to(equal(@YES)); + expect(@(streamingLifecycleManager.requestedEncryptionType)).to(equal(@(streamingEncryptionFlag))); + expect(streamingLifecycleManager.currentAppState).to(equal(SDLAppStateActive)); + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStopped)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped)); + }); + + describe(@"when started", ^{ + __block BOOL readyHandlerSuccess = NO; + __block NSError *readyHandlerError = nil; + + __block id protocolMock = OCMClassMock([SDLAbstractProtocol class]); + + beforeEach(^{ + readyHandlerSuccess = NO; + readyHandlerError = nil; + + [streamingLifecycleManager startWithProtocol:protocolMock completionHandler:^(BOOL success, NSError * _Nullable error) { + readyHandlerSuccess = success; + readyHandlerError = error; + }]; + }); + + + it(@"should be ready to stream", ^{ + expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoConnected)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioConnected)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoEncrypted)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioEncrypted)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isVideoStreamingPaused)).to(equal(@YES)); + expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeZero))).to(equal(@YES)); + expect(@(streamingLifecycleManager.pixelBufferPool == NULL)).to(equal(@YES)); + expect(streamingLifecycleManager.currentAppState).to(equal(SDLAppStateActive)); + expect(streamingLifecycleManager.currentAudioStreamState).to(match(SDLAudioStreamStateStopped)); + expect(streamingLifecycleManager.currentVideoStreamState).to(match(SDLVideoStreamStateStopped)); + + }); + + describe(@"after receiving a register app interface notification", ^{ + __block SDLRegisterAppInterfaceResponse *someRegisterAppInterfaceResponse = nil; + __block SDLDisplayCapabilities *someDisplayCapabilities = nil; + __block SDLScreenParams *someScreenParams = nil; + __block SDLImageResolution *someImageResolution = nil; + + beforeEach(^{ + someImageResolution = [[SDLImageResolution alloc] init]; + someImageResolution.resolutionWidth = @(600); + someImageResolution.resolutionHeight = @(100); + + someScreenParams = [[SDLScreenParams alloc] init]; + someScreenParams.resolution = someImageResolution; + }); + + describe(@"that does not support graphics", ^{ + beforeEach(^{ + someDisplayCapabilities = [[SDLDisplayCapabilities alloc] init]; + someDisplayCapabilities.graphicSupported = @NO; + + someDisplayCapabilities.screenParams = someScreenParams; + + someRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init]; + someRegisterAppInterfaceResponse.displayCapabilities = someDisplayCapabilities; + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:someRegisterAppInterfaceResponse]; + + [[NSNotificationCenter defaultCenter] postNotification:notification]; + [NSThread sleepForTimeInterval:0.1]; + }); + + it(@"should not support streaming", ^{ + expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@NO)); + expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@NO)); + }); + }); + + describe(@"that supports graphics", ^{ + beforeEach(^{ + someDisplayCapabilities = [[SDLDisplayCapabilities alloc] init]; + someDisplayCapabilities.graphicSupported = @YES; + + someDisplayCapabilities.screenParams = someScreenParams; + + someRegisterAppInterfaceResponse = [[SDLRegisterAppInterfaceResponse alloc] init]; + someRegisterAppInterfaceResponse.displayCapabilities = someDisplayCapabilities; + SDLRPCResponseNotification *notification = [[SDLRPCResponseNotification alloc] initWithName:SDLDidReceiveRegisterAppInterfaceResponse object:self rpcResponse:someRegisterAppInterfaceResponse]; + + [[NSNotificationCenter defaultCenter] postNotification:notification]; + [NSThread sleepForTimeInterval:0.1]; + }); + + it(@"should support streaming", ^{ + expect(@(streamingLifecycleManager.isVideoStreamingSupported)).to(equal(@YES)); + expect(@(streamingLifecycleManager.isAudioStreamingSupported)).to(equal(@YES)); + expect(@(CGSizeEqualToSize(streamingLifecycleManager.screenSize, CGSizeMake(600, 100)))).to(equal(@YES)); + }); + }); + }); + + describe(@"if the app state is active", ^{ + __block id streamStub = nil; + + beforeEach(^{ + streamStub = OCMPartialMock(streamingLifecycleManager); + + OCMStub([streamStub isAudioStreamingSupported]).andReturn(YES); + OCMStub([streamStub isVideoStreamingSupported]).andReturn(YES); + + [streamingLifecycleManager.appStateMachine setToState:SDLAppStateActive fromOldState:nil callEnterTransition:NO]; + }); + + describe(@"and both streams are open", ^{ + beforeEach(^{ + [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateReady fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateReady fromOldState:nil callEnterTransition:NO]; + }); + + describe(@"and the hmi state is limited", ^{ + beforeEach(^{ + streamingLifecycleManager.hmiLevel = SDLHMILevelLimited; + }); + + describe(@"and the hmi state changes to", ^{ + context(@"none", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelNone); + }); + + it(@"should close only the video stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown)); + }); + }); + + context(@"background", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelBackground); + }); + + it(@"should close only the video stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown)); + }); + }); + + context(@"limited", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelLimited); + }); + + it(@"should not close either stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady)); + }); + }); + + context(@"full", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelFull); + }); + + it(@"should not close either stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady)); + }); + }); + }); + + describe(@"and the app state changes to", ^{ + context(@"inactive", ^{ + beforeEach(^{ + [streamingLifecycleManager.appStateMachine setToState:SDLAppStateInactive fromOldState:nil callEnterTransition:YES]; + }); + + it(@"should flag to restart the video stream", ^{ + expect(@(streamingLifecycleManager.shouldRestartVideoStream)).to(equal(@YES)); + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady)); + }); + }); + }); + }); + + describe(@"and the hmi state is full", ^{ + beforeEach(^{ + streamingLifecycleManager.hmiLevel = SDLHMILevelFull; + }); + + context(@"and hmi state changes to none", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelNone); + }); + + it(@"should close only the video stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown)); + }); + }); + + context(@"and hmi state changes to background", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelBackground); + }); + + it(@"should close only the video stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateShuttingDown)); + }); + }); + + context(@"and hmi state changes to limited", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelLimited); + }); + + it(@"should not close either stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady)); + }); + }); + + context(@"and hmi state changes to full", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelFull); + }); + + it(@"should not close either stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateReady)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateReady)); + }); + }); + }); + }); + + describe(@"and both streams are closed", ^{ + beforeEach(^{ + [streamingLifecycleManager.audioStreamStateMachine setToState:SDLAudioStreamStateStopped fromOldState:nil callEnterTransition:NO]; + [streamingLifecycleManager.videoStreamStateMachine setToState:SDLVideoStreamStateStopped fromOldState:nil callEnterTransition:NO]; + }); + + describe(@"and the hmi state is none", ^{ + beforeEach(^{ + streamingLifecycleManager.hmiLevel = SDLHMILevelNone; + }); + + context(@"and hmi state changes to none", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelNone); + }); + + it(@"should only start the audio stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped)); + }); + }); + + context(@"and hmi state changes to background", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelBackground); + }); + + it(@"should only start the audio stream", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStopped)); + }); + }); + + context(@"and hmi state changes to limited", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelLimited); + }); + + it(@"should start both streams", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting)); + }); + }); + + context(@"and hmi state changes to full", ^{ + beforeEach(^{ + sendNotificationForHMILevel(SDLHMILevelFull); + }); + + it(@"should start both streams", ^{ + expect(streamingLifecycleManager.currentAudioStreamState).to(equal(SDLAudioStreamStateStarting)); + expect(streamingLifecycleManager.currentVideoStreamState).to(equal(SDLVideoStreamStateStarting)); + }); + }); + }); + }); + }); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m new file mode 100644 index 000000000..404fa1f05 --- /dev/null +++ b/SmartDeviceLinkTests/SDLStreamingMediaManagerSpec.m @@ -0,0 +1,16 @@ +// +// SDLStreamingMediaManagerSpec.m +// SmartDeviceLink-iOS +// +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> + +#import "SDLStreamingMediaManager.h" + +QuickSpecBegin(SDLStreamingMediaManagerSpec) + +describe(@"the streaming media manager", ^{ + +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/SDLVideoEncoderSpec.m b/SmartDeviceLinkTests/SDLVideoEncoderSpec.m new file mode 100644 index 000000000..c621f6a84 --- /dev/null +++ b/SmartDeviceLinkTests/SDLVideoEncoderSpec.m @@ -0,0 +1,95 @@ +// +// SDLVideoEncoderSpec.m +// SmartDeviceLink-iOS +// +// Created by Muller, Alexander (A.) on 2/7/17. +// Copyright © 2017 smartdevicelink. All rights reserved. +// + +#import <Foundation/Foundation.h> + +#import <Quick/Quick.h> +#import <Nimble/Nimble.h> +#import <OCMock/OCMock.h> + +#import "SDLVideoEncoder.h" +#import <AVFoundation/AVFoundation.h> + +QuickSpecBegin(SDLVideoEncoderSpec) + +describe(@"a video encoder", ^{ + __block SDLVideoEncoder *testVideoEncoder = nil; + __block CGSize testSize = CGSizeMake(100, 200); + __block id videoEncoderDelegateMock = OCMProtocolMock(@protocol(SDLVideoEncoderDelegate)); + __block NSError *testError = nil; + + context(@"if using default video encoder settings", ^{ + + beforeEach(^{ + testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:SDLVideoEncoder.defaultVideoEncoderSettings delegate:videoEncoderDelegateMock error:&testError]; + }); + + it(@"should initialize properties", ^{ + expect(testVideoEncoder).toNot(beNil()); + expect(testVideoEncoder.videoEncoderSettings).to(equal(SDLVideoEncoder.defaultVideoEncoderSettings)); + expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@NO)); + expect(testError).to(beNil()); + + NSDictionary *pixelBufferProperties = (__bridge NSDictionary*)CVPixelBufferPoolGetPixelBufferAttributes(testVideoEncoder.pixelBufferPool); + expect(pixelBufferProperties[(__bridge NSString*)kCVPixelBufferWidthKey]).to(equal(@100)); + expect(pixelBufferProperties[(__bridge NSString*)kCVPixelBufferHeightKey]).to(equal(@200)); + }); + + context(@"when stopping", ^{ + beforeEach(^{ + [testVideoEncoder stop]; + }); + + it(@"should have a nil pixel buffer pool", ^{ + expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@YES)); + }); + }); + }); + + context(@"is using custom video encoder settings", ^{ + __block NSDictionary *testSettings = nil; + + context(@"that is a valid setting", ^{ + beforeEach(^{ + testSettings = @{ + (__bridge NSString *)kVTCompressionPropertyKey_ExpectedFrameRate : @1 + }; + testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError]; + }); + + it(@"should initialize properties", ^{ + expect(testVideoEncoder).toNot(beNil()); + expect(testVideoEncoder.videoEncoderSettings).to(equal(testSettings)); + expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@NO)); + expect(testError).to(beNil()); + + NSDictionary *pixelBufferProperties = (__bridge NSDictionary*)CVPixelBufferPoolGetPixelBufferAttributes(testVideoEncoder.pixelBufferPool); + expect(pixelBufferProperties[(__bridge NSString*)kCVPixelBufferWidthKey]).to(equal(@100)); + expect(pixelBufferProperties[(__bridge NSString*)kCVPixelBufferHeightKey]).to(equal(@200)); + }); + }); + + context(@"that is not a valid setting", ^{ + beforeEach(^{ + testSettings = @{ + @"Bad" : @"Property" + }; + testVideoEncoder = [[SDLVideoEncoder alloc] initWithDimensions:testSize properties:testSettings delegate:videoEncoderDelegateMock error:&testError]; + }); + + it(@"should not be initialized", ^{ + expect(testVideoEncoder).to(beNil()); + expect(testVideoEncoder.videoEncoderSettings).to(beNil()); + expect(@(testVideoEncoder.pixelBufferPool == NULL)).to(equal(@YES)); + expect(testError).to(equal([NSError errorWithDomain:SDLErrorDomainVideoEncoder code:SDLVideoEncoderErrorConfigurationCompressionSessionSetPropertyFailure userInfo:@{ NSLocalizedDescriptionKey : @"\"Bad\" is not a supported key." }])); + }); + }); + }); +}); + +QuickSpecEnd diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLPinchGestureSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLPinchGestureSpec.m index 370b7876d..61c82061e 100644 --- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLPinchGestureSpec.m +++ b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLPinchGestureSpec.m @@ -15,6 +15,7 @@ #import "SDLPinchGesture.h" #import "SDLTouchCoord.h" #import "SDLTouchEvent.h" +#import "SDLTouch.h" QuickSpecBegin(SDLPinchGestureSpec) diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m index 72394edb2..0be612b96 100644 --- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m +++ b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m @@ -12,11 +12,14 @@ #import <Nimble/Nimble.h> #import <OCMock/OCMock.h> +#import "SDLNotificationConstants.h" #import "SDLOnTouchEvent.h" +#import "SDLRPCNotificationNotification.h" #import "SDLTouchCoord.h" #import "SDLTouchEvent.h" #import "SDLTouchManager.h" #import "SDLTouchType.h" +#import "SDLTouch.h" QuickSpecBegin(SDLTouchManagerSpec) @@ -61,15 +64,20 @@ describe(@"SDLTouchManager Tests", ^{ __block CGFloat additionalWaitTime = 1.0f; + __block NSUInteger numTimesHandlerCalled = 0; + __block void (^performTouchEvent)(SDLTouchManager* touchManager, SDLOnTouchEvent* onTouchEvent) = ^(SDLTouchManager* touchManager, SDLOnTouchEvent* onTouchEvent) { - SEL onOnTouchEvent = NSSelectorFromString(@"onOnTouchEvent:"); - ((void ( *)(id, SEL, id))[touchManager methodForSelector:onOnTouchEvent])(touchManager, onOnTouchEvent, onTouchEvent); + SDLRPCNotificationNotification *notification = [[SDLRPCNotificationNotification alloc] initWithName:SDLDidReceiveTouchEventNotification object:nil rpcNotification:onTouchEvent]; + [[NSNotificationCenter defaultCenter] postNotification:notification]; }; beforeEach(^{ touchManager = [[SDLTouchManager alloc] init]; delegateMock = OCMProtocolMock(@protocol(SDLTouchManagerDelegate)); touchManager.touchEventDelegate = delegateMock; + touchManager.touchEventHandler = ^(SDLTouch *touch, SDLTouchType type) { + numTimesHandlerCalled++; + }; controlPoint = CGPointMake(100, 200); didCallSingleTap = NO; @@ -161,7 +169,7 @@ describe(@"SDLTouchManager Tests", ^{ }; }); - describe(@"single finger", ^{ + describe(@"Single Finger", ^{ __block SDLTouchCoord* firstTouchCoord; __block NSUInteger firstTouchTimeStamp; @@ -190,8 +198,10 @@ describe(@"SDLTouchManager Tests", ^{ }); describe(@"when receiving a single tap", ^{ - it(@"should correctly handle a single tap", ^{ - + + beforeEach(^{ + numTimesHandlerCalled = 0; + singleTapTests = ^(NSInvocation* invocation) { __unsafe_unretained SDLTouchManager* touchManagerCallback; @@ -205,9 +215,10 @@ describe(@"SDLTouchManager Tests", ^{ }; performTouchEvent(touchManager, firstOnTouchEventStart); - performTouchEvent(touchManager, firstOnTouchEventEnd); - + }); + + it(@"should correctly handle a single tap", ^{ expect(@(didCallSingleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beTruthy()); expect(@(didCallDoubleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallBeginPan)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); @@ -217,6 +228,10 @@ describe(@"SDLTouchManager Tests", ^{ expect(@(didCallMovePinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallEndPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@2)); + }); }); describe(@"when receiving a double tap", ^{ @@ -242,6 +257,8 @@ describe(@"SDLTouchManager Tests", ^{ context(@"near the same point", ^{ beforeEach(^{ + numTimesHandlerCalled = 0; + SDLTouchCoord* touchCoord = [[SDLTouchCoord alloc] init]; touchCoord.x = @(firstTouchCoord.x.floatValue + touchManager.tapDistanceThreshold); touchCoord.y = @(firstTouchCoord.y.floatValue + touchManager.tapDistanceThreshold); @@ -254,9 +271,7 @@ describe(@"SDLTouchManager Tests", ^{ averagePoint = CGPointMake((firstTouchCoord.x.floatValue + touchCoord.x.floatValue) / 2.0f, (firstTouchCoord.y.floatValue + touchCoord.y.floatValue) / 2.0f); - }); - - it(@"should issue delegate callbacks", ^{ + doubleTapTests = ^(NSInvocation* invocation) { __unsafe_unretained SDLTouchManager* touchManagerCallback; @@ -273,7 +288,10 @@ describe(@"SDLTouchManager Tests", ^{ performTouchEvent(touchManager, firstOnTouchEventEnd); performTouchEvent(touchManager, secondOnTouchEventStart); performTouchEvent(touchManager, secondOnTouchEventEnd); - + + }); + + it(@"should issue delegate callbacks", ^{ expect(@(didCallSingleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallDoubleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beTruthy()); expect(@(didCallBeginPan)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); @@ -283,10 +301,16 @@ describe(@"SDLTouchManager Tests", ^{ expect(@(didCallMovePinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallEndPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@4)); + }); }); context(@"not near the same point", ^{ beforeEach(^{ + numTimesHandlerCalled = 0; + SDLTouchCoord* touchCoord = [[SDLTouchCoord alloc] init]; touchCoord.x = @(firstTouchCoord.x.floatValue + touchManager.tapDistanceThreshold + 1); touchCoord.y = @(firstTouchCoord.y.floatValue + touchManager.tapDistanceThreshold + 1); @@ -296,14 +320,15 @@ describe(@"SDLTouchManager Tests", ^{ secondOnTouchEventStart.event = [NSArray arrayWithObject:secondTouchEvent]; secondOnTouchEventEnd.event = [NSArray arrayWithObject:secondTouchEvent]; - }); - - it(@"should should not issue delegate callbacks", ^{ + performTouchEvent(touchManager, firstOnTouchEventStart); performTouchEvent(touchManager, firstOnTouchEventEnd); performTouchEvent(touchManager, secondOnTouchEventStart); performTouchEvent(touchManager, secondOnTouchEventEnd); - + + }); + + it(@"should should not issue delegate callbacks", ^{ expect(@(didCallSingleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallDoubleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallBeginPan)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); @@ -313,6 +338,10 @@ describe(@"SDLTouchManager Tests", ^{ expect(@(didCallMovePinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallEndPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@4)); + }); }); }); }); @@ -331,6 +360,8 @@ describe(@"SDLTouchManager Tests", ^{ __block SDLOnTouchEvent* panEndOnTouchEvent; beforeEach(^{ + numTimesHandlerCalled = 0; + // Finger touch down panStartPoint = controlPoint; @@ -400,9 +431,7 @@ describe(@"SDLTouchManager Tests", ^{ panEndOnTouchEvent = [[SDLOnTouchEvent alloc] init]; panEndOnTouchEvent.event = [NSArray arrayWithObject:panEndTouchEvent]; panEndOnTouchEvent.type = SDLTouchTypeEnd; - }); - - it(@"should correctly give all pan callbacks", ^{ + panStartTests = ^(NSInvocation* invocation) { __unsafe_unretained SDLTouchManager* touchManagerCallback; @@ -441,12 +470,14 @@ describe(@"SDLTouchManager Tests", ^{ expect(touchManagerCallback).to(equal(touchManager)); expect(@(CGPointEqualToPoint(point, panEndPoint))).to(beTruthy()); }; - + performTouchEvent(touchManager, panStartOnTouchEvent); performTouchEvent(touchManager, panMoveOnTouchEvent); performTouchEvent(touchManager, panSecondMoveOnTouchEvent); performTouchEvent(touchManager, panEndOnTouchEvent); - + }); + + it(@"should correctly give all pan callbacks", ^{ expect(@(didCallSingleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallDoubleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallBeginPan)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beTruthy()); @@ -455,7 +486,10 @@ describe(@"SDLTouchManager Tests", ^{ expect(@(didCallBeginPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallMovePinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallEndPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); - + }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@4)); }); }); context(@"when receiving a pinch", ^{ @@ -471,6 +505,8 @@ describe(@"SDLTouchManager Tests", ^{ __block SDLOnTouchEvent* pinchEndSecondFingerOnTouchEvent; beforeEach(^{ + numTimesHandlerCalled = 0; + // First finger touch down SDLTouchCoord* firstFingerTouchCoord = [[SDLTouchCoord alloc] init]; firstFingerTouchCoord.x = @(controlPoint.x); @@ -548,9 +584,7 @@ describe(@"SDLTouchManager Tests", ^{ pinchEndCenter = CGPointMake((firstFingerTouchCoord.x.floatValue + secondFingerEndTouchCoord.x.floatValue) / 2.0f, (firstFingerTouchCoord.y.floatValue + secondFingerEndTouchCoord.y.floatValue) / 2.0f); - }); - - it(@"should correctly give all pinch callback", ^{ + pinchStartTests = ^(NSInvocation* invocation) { __unsafe_unretained SDLTouchManager* touchManagerCallback; @@ -589,12 +623,14 @@ describe(@"SDLTouchManager Tests", ^{ expect(touchManagerCallback).to(equal(touchManager)); expect(@(CGPointEqualToPoint(point, pinchEndCenter))).to(beTruthy()); }; - + performTouchEvent(touchManager, pinchStartFirstFingerOnTouchEvent); performTouchEvent(touchManager, pinchStartSecondFingerOnTouchEvent); performTouchEvent(touchManager, pinchMoveSecondFingerOnTouchEvent); performTouchEvent(touchManager, pinchEndSecondFingerOnTouchEvent); - + }); + + it(@"should correctly give all pinch callback", ^{ expect(@(didCallSingleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallDoubleTap)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); expect(@(didCallBeginPan)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beFalsy()); @@ -604,6 +640,10 @@ describe(@"SDLTouchManager Tests", ^{ expect(@(didCallMovePinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beTruthy()); expect(@(didCallEndPinch)).withTimeout(touchManager.tapTimeThreshold + additionalWaitTime).toEventually(beTruthy()); }); + + it(@"should run the handler", ^{ + expect(@(numTimesHandlerCalled)).to(equal(@4)); + }); }); }); }); diff --git a/SmartDeviceLink_Example/Info.plist b/SmartDeviceLink_Example/Info.plist index d3b02b4be..46063b5e1 100644 --- a/SmartDeviceLink_Example/Info.plist +++ b/SmartDeviceLink_Example/Info.plist @@ -15,7 +15,7 @@ <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> - <string>4.6.1</string> + <string>5.0.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> |