From 12adc5d7bf1a5235280fc7a8fcea4569e6a9a768 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Wed, 4 Mar 2020 10:29:09 -0500 Subject: [PATCH 001/104] Add pcmStreamCapabilities capabilities --- ffw/UIRPC.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 3b18c2537..bdc0f879b 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1463,6 +1463,11 @@ FFW.UI = FFW.RPCObserver.create( 'bitsPerSample': '8_BIT', 'audioType': 'PCM' }], + "pcmStreamCapabilities": { + "samplingRate" : "16KHZ", + "bitsPerSample" : "16_BIT", + "audioType" : "PCM" + }, 'hmiZoneCapabilities': 'FRONT', 'softButtonCapabilities': [ { From 52a5669b0a25e621ee18ba8d6fd35eaadb65c54c Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Tue, 12 May 2020 22:43:58 +0300 Subject: [PATCH 002/104] Fix margin for icons in POI list --- css/general.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/css/general.css b/css/general.css index c2ad20a8b..f16c88292 100644 --- a/css/general.css +++ b/css/general.css @@ -1120,7 +1120,7 @@ margin-top: 90px; .list-item span { position: relative; - margin-left: 5px; + margin-left: 55px; float: left; } @@ -2417,4 +2417,4 @@ to { #addWidgetPopUp .list-item span { margin-left: 50px; -} \ No newline at end of file +} From 24563854602564260d1338e6c4461ab6a151fb16 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Wed, 13 May 2020 20:26:11 +0300 Subject: [PATCH 003/104] Fix adding new location data into POI list --- app/controller/NavigationController.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controller/NavigationController.js b/app/controller/NavigationController.js index 87000dbd2..629339c7b 100644 --- a/app/controller/NavigationController.js +++ b/app/controller/NavigationController.js @@ -49,7 +49,7 @@ SDL.NavigationController = Em.Object.create( * @param {Object} request */ sendLocation: function(request) { - this.model.LocationDetails.push( + this.model.LocationDetails.pushObject( { coordinate: { latitudeDegrees: request.params.latitudeDegrees, From 5646341f55a8392e6d304ca3243162369d67418f Mon Sep 17 00:00:00 2001 From: Shobhit Adlakha Date: Wed, 20 May 2020 15:31:24 -0400 Subject: [PATCH 004/104] Send text instead of object to popupActivate (#360) --- ffw/BasicCommunicationRPC.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ffw/BasicCommunicationRPC.js b/ffw/BasicCommunicationRPC.js index 3ea9ce58d..a1c1e9fcf 100644 --- a/ffw/BasicCommunicationRPC.js +++ b/ffw/BasicCommunicationRPC.js @@ -365,7 +365,9 @@ FFW.BasicCommunication = FFW.RPCObserver } if (response.result.method == 'SDL.GetStatusUpdate') { Em.Logger.log('SDL.GetStatusUpdate: Response from SDL!'); - SDL.PopUp.create().appendTo('body').popupActivate(response.result); + SDL.PopUp.create().appendTo('body').popupActivate( + "Update Status: " + response.result.status, null, false + ); } if (response.result.method == 'BasicCommunication.GetAppProperties') { Em.Logger.log('BasicCommunication.GetAppProperties: Response from SDL!'); From c10c3f0ca7461081723bdf000d18f26880cc0b74 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:30:17 +0300 Subject: [PATCH 005/104] Add field for current image mode value --- app/model/sdl/Abstract/data.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index 81d202896..634adc4e7 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -677,6 +677,12 @@ SDL.SDLModelData = Em.Object.create( 'Night mode', 'Highlighted mode' ], + /** + * @description Current display mode value + * @type {String} + */ + imageMode:'Highlighted mode', + windowType: { "MAIN": 0, "WIDGET": 1 From 714c72e555938cf62aae976f08407194983ec370 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Mon, 1 Jun 2020 07:02:18 -0700 Subject: [PATCH 006/104] External OnSystemRequest retry fixes (#366) * External OnSystemRequest retry fxes * Address comment fixes --- app/controller/SettingsController.js | 9 ++------- ffw/BasicCommunicationRPC.js | 6 +++--- ffw/ExternalPolicies.js | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/app/controller/SettingsController.js b/app/controller/SettingsController.js index 7d41af2dd..21c42baf3 100644 --- a/app/controller/SettingsController.js +++ b/app/controller/SettingsController.js @@ -349,14 +349,8 @@ SDL.SettingsController = Em.Object.create( SDL.SDLModel.data.policyURLs[0] ); } - if(!SDL.SDLModel.data.policyUpdateRetry.isRetry) { + if(abort !== 'ABORT' && !SDL.SDLModel.data.policyUpdateRetry.isRetry) { SDL.SDLModel.data.policyUpdateRetry.isRetry = true; - SDL.SDLModel.data.policyUpdateRetry.isIterationInProgress = true; - SDL.SDLModel.data.policyUpdateRetry.timer = setTimeout( - function() { - sendOnSystemRequest(); - }, 1000 - ); return; } var length = SDL.SDLModel.data.policyUpdateRetry.retry.length; @@ -537,6 +531,7 @@ SDL.SettingsController = Em.Object.create( if (urls.length > 0 && FLAGS.ExternalPolicies === true) { SDL.SettingsController.OnSystemRequestHandler(urls[0]); + SDL.SettingsController.policyUpdateRetry(); } else { SDL.SettingsController.OnSystemRequestHandler(); } diff --git a/ffw/BasicCommunicationRPC.js b/ffw/BasicCommunicationRPC.js index a1c1e9fcf..ec02c27b1 100644 --- a/ffw/BasicCommunicationRPC.js +++ b/ffw/BasicCommunicationRPC.js @@ -282,12 +282,12 @@ FFW.BasicCommunication = FFW.RPCObserver } else { SDL.SettingsController.OnSystemRequestHandler(); } + if (FLAGS.ExternalPolicies === true) { + SDL.SettingsController.policyUpdateRetry(); + } } else { SDL.SettingsController.requestPTUFromEndpoint(SDL.SettingsController.policyUpdateFile, data[key].default); } - if (FLAGS.ExternalPolicies === true) { - SDL.SettingsController.policyUpdateRetry(); - } } } } diff --git a/ffw/ExternalPolicies.js b/ffw/ExternalPolicies.js index 79897a48b..753b4fffa 100644 --- a/ffw/ExternalPolicies.js +++ b/ffw/ExternalPolicies.js @@ -91,7 +91,7 @@ FFW.ExternalPolicies = Em.Object.create({ Em.Logger.log('ExternalPolicies onWSMessage ' + evt.data); this.packResponseReady = true; FFW.BasicCommunication.OnSystemRequest( - this.sysReqParams.type, + this.sysReqParams.requestType, this.sysReqParams.fileName, this.sysReqParams.url, this.sysReqParams.appID From c9c8e4465da6d66ce8db204d2eeffc70cc238fc6 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:30:59 +0300 Subject: [PATCH 007/104] Add callback for image mode change for ListView --- app/controlls/List.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/app/controlls/List.js b/app/controlls/List.js index 5e28a0fd4..4c75ae36e 100644 --- a/app/controlls/List.js +++ b/app/controlls/List.js @@ -152,9 +152,27 @@ SDL.List = Em.ContainerView.extend({ classNames: 'list-item', classNameBindings: [ - 'this.voiceOver' + 'this.voiceOver', + 'dayMode', + 'nightMode', + 'highLightedMode' ], + dayMode:false, + nightMode:false, + highLightedMode:false, + + setMode:function(mode) { + mode = SDL.SDLModel.data.imageModeList.includes(mode) ? mode : SDL.SDLModel.data.imageModeList[0]; + this.set('dayMode', mode == SDL.SDLModel.data.imageModeList[0]); + this.set('nightMode', mode == SDL.SDLModel.data.imageModeList[1]); + this.set('highLightedMode', mode == SDL.SDLModel.data.imageModeList[2]); + }, + + imageModeDidChange: function() { + this.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode'), + // Dynamic property set init: function() { From fea7a418396a33859126a9325571fdf330bd68bd Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:33:42 +0300 Subject: [PATCH 008/104] Add callback for image mode change for SDLController --- app/controller/sdl/Abstract/Controller.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 5364fc12d..00d6324f3 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1549,5 +1549,26 @@ SDL.SDLController = Em.Object.extend( } return title; }, + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + if (!SDL.SDLController.model) { + return; + } + + SDL.SDLController.model.setMode(SDL.SDLModel.data.imageMode); + var commands = SDL.SDLController.model.get('currentCommandsList'); + const length = SDL.OptionsView.commands.items.length; + for(var i=0;i Date: Thu, 21 May 2020 19:34:22 +0300 Subject: [PATCH 009/104] Add callback for image mode change for TurnByTurnView --- app/view/sdl/shared/turnByTurnView.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/view/sdl/shared/turnByTurnView.js b/app/view/sdl/shared/turnByTurnView.js index 26fea3415..0c9f3b897 100644 --- a/app/view/sdl/shared/turnByTurnView.js +++ b/app/view/sdl/shared/turnByTurnView.js @@ -247,6 +247,14 @@ SDL.TurnByTurnView = SDL.SDLAbstractView.create( } ) } - ) + ), + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + SDL.TurnByTurnView.nextTurnIconImage.setMode(SDL.SDLModel.data.imageMode); + SDL.TurnByTurnView.turnIconImage.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode') } ); From 93220aae162fdc2d24acae3ac5bb53ff031a167d Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:34:49 +0300 Subject: [PATCH 010/104] Add callback for image mode change for InteractionChoicesView --- app/view/sdl/shared/interactionChoicesView.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/view/sdl/shared/interactionChoicesView.js b/app/view/sdl/shared/interactionChoicesView.js index fc94b0546..cdbb14411 100644 --- a/app/view/sdl/shared/interactionChoicesView.js +++ b/app/view/sdl/shared/interactionChoicesView.js @@ -412,6 +412,14 @@ SDL.InteractionChoicesView = SDL.SDLAbstractView.create( self.deactivate('TIMED_OUT'); }, timeout ); - } + }, + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + SDL.InteractionChoicesView.set('imageMode',SDL.SDLModel.data.imageMode); + SDL.InteractionChoicesView.updateIcons(); + }.observes('SDL.SDLModel.data.imageMode') } ); From b39ba6832d94e42b7bcbfadf096614b6b35db5b8 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:35:51 +0300 Subject: [PATCH 011/104] Add callback for image mode change for NavigationView --- app/view/navigationView.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/view/navigationView.js b/app/view/navigationView.js index 7621a621d..8f6a382ba 100644 --- a/app/view/navigationView.js +++ b/app/view/navigationView.js @@ -112,6 +112,14 @@ SDL.NavigationView = Em.ContainerView.create( action: 'setRoutes', target: 'SDL.NavigationController' } - ) + ), + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + SDL.NavigationView.POIButton.setMode(SDL.SDLModel.data.imageMode); + SDL.NavigationView.navigate.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode') } -); \ No newline at end of file +); From 6dd35839d986460cd66dc97319102d921184e858 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:36:11 +0300 Subject: [PATCH 012/104] Add callback for image mode change for InfoView --- app/view/infoView.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/view/infoView.js b/app/view/infoView.js index 69f8073d3..87b8967ee 100644 --- a/app/view/infoView.js +++ b/app/view/infoView.js @@ -176,7 +176,19 @@ SDL.InfoView = Em.ContainerView.create( icon: 'images/media/ico_cd.png', target: 'SDL.RCModulesController.currentAudioModel' } - ) + ), + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + SDL.InfoView.leftMenu.items.servicesButton.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoView.leftMenu.items.appsButton.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoView.leftMenu.items.calendarButton.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoView.leftMenu.items.goToCD.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoView.leftMenu.items.travelLinkButton.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoView.leftMenu.items.sdlButton.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode') } ) } From 7bd3febc46993dd12dcc8a3c0f1bbef7a14e9305 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:36:55 +0300 Subject: [PATCH 013/104] Add callback for image mode change for InfoAppsView --- app/view/info/appsView.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/view/info/appsView.js b/app/view/info/appsView.js index df1a5b296..709704169 100644 --- a/app/view/info/appsView.js +++ b/app/view/info/appsView.js @@ -172,6 +172,16 @@ SDL.InfoAppsView = Em.ContainerView.create({ /** Items */ items: new Array() } -) +), + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + SDL.InfoAppsView.findNewApps.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoAppsView.Asist911.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoAppsView.vehicleHealthReport.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoAppsView.getDeviceList.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode') } ); From cf05b6f0613203bf09f9674b71be6ec85c87c857 Mon Sep 17 00:00:00 2001 From: YarikMamykin Date: Thu, 21 May 2020 19:37:11 +0300 Subject: [PATCH 014/104] Rework usage of DisplayMode selection view --- app/view/home/controlButtons.js | 33 ++++----------------------------- 1 file changed, 4 insertions(+), 29 deletions(-) diff --git a/app/view/home/controlButtons.js b/app/view/home/controlButtons.js index e021b29fc..01893e46e 100644 --- a/app/view/home/controlButtons.js +++ b/app/view/home/controlButtons.js @@ -142,6 +142,7 @@ getCurrentDisplayModeClass: function() { default: return ''; } }, + /** * HMI element Select with list of supported image mode */ @@ -149,38 +150,12 @@ getCurrentDisplayModeClass: function() { elementId: 'imageMode', classNames: 'imageModeSelect', contentBinding: 'SDL.SDLModel.data.imageModeList', - selection: 'Highlighted mode', - change:function(){ - SDL.InfoAppsView.findNewApps.setMode(this.selection); - SDL.InfoAppsView.Asist911.setMode(this.selection); - SDL.InfoAppsView.vehicleHealthReport.setMode(this.selection); - SDL.InfoAppsView.getDeviceList.setMode(this.selection); - SDL.InfoView.leftMenu.items.servicesButton.setMode(this.selection); - SDL.InfoView.leftMenu.items.appsButton.setMode(this.selection); - SDL.InfoView.leftMenu.items.calendarButton.setMode(this.selection); - SDL.InfoView.leftMenu.items.goToCD.setMode(this.selection); - SDL.InfoView.leftMenu.items.travelLinkButton.setMode(this.selection); - SDL.InfoView.leftMenu.items.sdlButton.setMode(this.selection); - SDL.TurnByTurnView.nextTurnIconImage.setMode(this.selection); - SDL.TurnByTurnView.turnIconImage.setMode(this.selection); - SDL.InteractionChoicesView.set('imageMode',this.selection); - SDL.InteractionChoicesView.updateIcons(); - if (SDL.SDLController.model) { - SDL.SDLController.model.setMode(this.selection); - length=SDL.OptionsView.commands.items.length; - var commands = SDL.SDLController.model.get('currentCommandsList'); - for(var i=0;i Date: Fri, 8 May 2020 20:54:00 -0400 Subject: [PATCH 015/104] Added webEngine apps view template --- app/AppViews.js | 1 + app/view/webEngine/webEngineView.js | 43 +++++++++++++++++++++++++++++ css/webEngine.css | 9 ++++++ index.html | 2 ++ 4 files changed, 55 insertions(+) create mode 100644 app/view/webEngine/webEngineView.js create mode 100644 css/webEngine.css diff --git a/app/AppViews.js b/app/AppViews.js index c4b334801..68b50872e 100644 --- a/app/AppViews.js +++ b/app/AppViews.js @@ -45,6 +45,7 @@ SDL.AppViews = Em.ContainerView.extend( SDL.HomeView, SDL.MediaView, SDL.NavigationAppView, + SDL.WebEngineView, SDL.InfoView, SDL.PhoneView, SDL.ClimateView, diff --git a/app/view/webEngine/webEngineView.js b/app/view/webEngine/webEngineView.js new file mode 100644 index 000000000..0afa36244 --- /dev/null +++ b/app/view/webEngine/webEngineView.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @name SDL.WebEngineView + * @desc WebEngine view + * @category View + * @filesource app/view/webEngine/webEngineView.js + * @version 1.0 + */ +SDL.WebEngineView = Em.ContainerView.create( + { + /** View Id */ + elementId: 'webEngineView', + classNameBindings: [ + 'SDL.States.webViewApp.active:active_state:inactive_state' + ], + childViews: [ + ] + } + ); diff --git a/css/webEngine.css b/css/webEngine.css new file mode 100644 index 000000000..6fc424424 --- /dev/null +++ b/css/webEngine.css @@ -0,0 +1,9 @@ +/* Web Engine related control styles */ + +#webEngineView { + z-index: 2; + position: absolute; + top: 48px; + width: 800px; + height: 384px; +} \ No newline at end of file diff --git a/index.html b/index.html index ddb9bd338..9fb9b0680 100644 --- a/index.html +++ b/index.html @@ -9,6 +9,7 @@ + @@ -249,6 +250,7 @@ + From 5fe3948b4a5163301b1315c4f2d6aa6e743ce51f Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Fri, 8 May 2020 20:54:21 -0400 Subject: [PATCH 016/104] Implemented logic of switching to WEB_VIEW template --- app/StateManager.js | 21 ++++++++++++++++++++ app/controller/InfoController.js | 15 -------------- app/controller/sdl/Abstract/Controller.js | 3 +++ app/controller/sdl/MediaController.js | 20 +++++++++++++++++++ app/controller/sdl/NonMediaController.js | 24 ++++++++++++++++++++--- app/model/media/AudioModel.js | 15 -------------- 6 files changed, 65 insertions(+), 33 deletions(-) diff --git a/app/StateManager.js b/app/StateManager.js index a0bbfd3de..6f75bf662 100644 --- a/app/StateManager.js +++ b/app/StateManager.js @@ -475,6 +475,27 @@ var StateManager = Em.StateManager.extend( } } ), + webViewApp: Em.State.create( + { + modelBinding: 'SDL.RCModulesController', + enter: function() { + if (SDL.SDLModel.data.mediaPlayerActive) { + SDL.SDLController.onEventChanged('player', false); + this.model.currentAudioModel.deactivateCD(); + this.model.currentAudioModel.deactivateUSB(); + this.model.currentAudioModel.deactivateRadio(); + } + this.model.currentAudioModel.set('activeState', SDL.States.nextState); + this._super(); + }, + exit: function() { + this._super(); + SDL.SDLModel.data.stateLimited = SDL.SDLController.model.appID; + SDL.SDLModel.data.set('limitedExist', false); + SDL.SDLController.deactivateApp(); + } + } + ), /** Navigation state */ navigation: Em.State.create( { diff --git a/app/controller/InfoController.js b/app/controller/InfoController.js index 3e0e05a67..56593a39a 100644 --- a/app/controller/InfoController.js +++ b/app/controller/InfoController.js @@ -558,21 +558,6 @@ SDL.InfoController = Em.Object.create( if (SDL.SDLController.model) { SDL.SDLController.model.set('active', true); } - /** - * Go to SDL state - */ - if (SDL.SDLController.model.appType) { - for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { - if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || - SDL.SDLController.model.appType[i] == 'PROJECTION') { - SDL.BaseNavigationView.update(); - SDL.States.goToStates('navigationApp.baseNavigation'); - return; - } - } - } - SDL.States.goToStates('info.nonMedia'); - //SDL.States.goToStates('media.sdlmedia'); } } ); diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 5364fc12d..fb2dbecbe 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1188,6 +1188,9 @@ SDL.SDLController = Em.Object.extend( } SDL.InfoController.getWebAppEntryPointPath(model.policyAppID, callback); + } else if (model.webEngineApp !== true && model.appType.indexOf('TESTING') >= 0) { + SDL.PopUp.create().appendTo('body') + .popupActivate("Only Web Engine apps with app type WEB_VIEW can be activated!"); } else { FFW.BasicCommunication.ActivateApp(element.appID); } diff --git a/app/controller/sdl/MediaController.js b/app/controller/sdl/MediaController.js index 0ad257a88..1d5891b41 100644 --- a/app/controller/sdl/MediaController.js +++ b/app/controller/sdl/MediaController.js @@ -76,7 +76,27 @@ SDL.SDLMediaController = Em.Object.create( this.set('currentAppId', applicationModel.appID); // set active model SDL.SDLController.set('model', applicationModel); + + if (SDL.SDLController.model.appType) { + for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { + if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || + SDL.SDLController.model.appType[i] == 'PROJECTION') { + this.model.currentAudioModel.turnOnSDL(); + SDL.BaseNavigationView.update(); + SDL.States.goToStates('navigationApp.baseNavigation'); + return; + } + if (SDL.SDLController.model.appType[i] == 'TESTING') { + // TODO(WEBENGINE) + SDL.InfoController.turnOnSDL(); + SDL.States.goToStates('webViewApp'); + return; + } + } + } + this.model.currentAudioModel.turnOnSDL(); + SDL.States.goToStates('media.sdlmedia'); }, /** * Restore current application to active state diff --git a/app/controller/sdl/NonMediaController.js b/app/controller/sdl/NonMediaController.js index 3a5f601d9..d2ac39a5c 100644 --- a/app/controller/sdl/NonMediaController.js +++ b/app/controller/sdl/NonMediaController.js @@ -66,11 +66,29 @@ SDL.NonMediaController = Em.Object.create( this.set('currentAppId', applicationModel.appID); // set active model SDL.SDLController.set('model', applicationModel); - // send response - // FFW.BasicCommunication.ActivateApp( applicationModel.appID ); + + // go to SDL state + if (SDL.SDLController.model.appType) { + for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { + if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || + SDL.SDLController.model.appType[i] == 'PROJECTION') { + SDL.InfoController.turnOnSDL(); + SDL.BaseNavigationView.update(); + SDL.States.goToStates('navigationApp.baseNavigation'); + return; + } + if (SDL.SDLController.model.appType[i] == 'TESTING') { + // TODO(WEBENGINE) + SDL.InfoController.turnOnSDL(); + SDL.States.goToStates('webViewApp'); + return; + } + } + } + // Go to SDL state SDL.InfoController.turnOnSDL(); - //SDL.States.goToStates('info.nonMedia'); + SDL.States.goToStates('info.nonMedia'); }, /** * Restore current application to active state diff --git a/app/model/media/AudioModel.js b/app/model/media/AudioModel.js index d2622a51b..31431d946 100644 --- a/app/model/media/AudioModel.js +++ b/app/model/media/AudioModel.js @@ -343,21 +343,6 @@ SDL.AudioModel = Em.Object.extend({ if (SDL.SDLController.model) { SDL.SDLController.model.set('active', true); } - /** - * Go to SDL state - */ - if (SDL.SDLController.model.appType) { - for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { - if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || - SDL.SDLController.model.appType[i] == 'PROJECTION') { - SDL.BaseNavigationView.update(); - SDL.States.goToStates('navigationApp.baseNavigation'); - return; - } - } - } - - SDL.States.goToStates('media.sdlmedia'); }, /** From 76c83be000113f3599d6db70aedbda735c176344 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Mon, 11 May 2020 22:00:08 -0400 Subject: [PATCH 017/104] Move iframe element to webEngine view --- app/controller/InfoController.js | 13 ++++++++++--- app/controller/sdl/Abstract/Controller.js | 5 ++++- app/view/webEngine/webEngineView.js | 15 +++++++++------ css/sdl.css | 7 ------- css/webEngine.css | 15 +++++++++++++++ 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/app/controller/InfoController.js b/app/controller/InfoController.js index 56593a39a..cb9c5518a 100644 --- a/app/controller/InfoController.js +++ b/app/controller/InfoController.js @@ -325,15 +325,22 @@ SDL.InfoController = Em.Object.create( if (policyAppID in SDL.SDLModel.webApplicationFramesMap) { let frame = SDL.SDLModel.webApplicationFramesMap[policyAppID]; - document.body.removeChild(frame); + const web_engine_view = document.getElementById("webEngineView"); + if (web_engine_view) { + web_engine_view.removeChild(frame); + } } const frame_name = `web_app_frame_${policyAppID}`; let web_app_frame = document.createElement("iframe"); web_app_frame.name = frame_name; web_app_frame.id = frame_name; - web_app_frame.className = "InvisibleFrame"; - document.body.appendChild(web_app_frame); + web_app_frame.className = "WebEngineFrame"; + + const web_engine_view = document.getElementById("webEngineView"); + if (web_engine_view) { + web_engine_view.appendChild(web_app_frame); + } SDL.SDLModel.webApplicationFramesMap[policyAppID] = web_app_frame; diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index fb2dbecbe..51b60978b 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1021,7 +1021,10 @@ SDL.SDLController = Em.Object.extend( } if (app.webEngineApp && app.policyAppID in SDL.SDLModel.webApplicationFramesMap) { let frame = SDL.SDLModel.webApplicationFramesMap[app.policyAppID]; - document.body.removeChild(frame); + const web_engine_view = document.getElementById("webEngineView"); + if (web_engine_view) { + web_engine_view.removeChild(frame); + } delete SDL.SDLModel.webApplicationFramesMap[app.policyAppID]; } }, diff --git a/app/view/webEngine/webEngineView.js b/app/view/webEngine/webEngineView.js index 0afa36244..2b7043354 100644 --- a/app/view/webEngine/webEngineView.js +++ b/app/view/webEngine/webEngineView.js @@ -30,14 +30,17 @@ * @filesource app/view/webEngine/webEngineView.js * @version 1.0 */ -SDL.WebEngineView = Em.ContainerView.create( - { - /** View Id */ +SDL.WebEngineView = Em.ContainerView.create({ elementId: 'webEngineView', classNameBindings: [ 'SDL.States.webViewApp.active:active_state:inactive_state' ], childViews: [ - ] - } - ); + 'TemplateTitleLabel' + ], + + TemplateTitleLabel : SDL.Label.extend({ + elementId: 'template_title_label', + contentBinding: 'SDL.SDLController.model.templateConfiguration.template' + }) +}); diff --git a/css/sdl.css b/css/sdl.css index bf78b6aeb..318aa326e 100644 --- a/css/sdl.css +++ b/css/sdl.css @@ -1808,13 +1808,6 @@ color: green } -.InvisibleFrame { - position: absolute; - width: 0px; - height: 0px; - visibility: hidden; -} - #sdl_view_container { z-index: 501; } diff --git a/css/webEngine.css b/css/webEngine.css index 6fc424424..d6950ac50 100644 --- a/css/webEngine.css +++ b/css/webEngine.css @@ -6,4 +6,19 @@ top: 48px; width: 800px; height: 384px; +} + +#webEngineView .WebEngineFrame { + position: absolute; + width: 800px; + height: 384px; +} + +#webEngineView #template_title_label { + position: absolute; + top: 360px; + left: 322px; + width: 160px; + text-align: center; + z-index: 2; } \ No newline at end of file From 3c184445b5dc390f8ebc11f8a37a34564bb5b435 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Mon, 11 May 2020 22:00:32 -0400 Subject: [PATCH 018/104] Update capabilities and template name update --- app/controller/sdl/Abstract/Controller.js | 8 ++++++++ app/model/sdl/Abstract/data.js | 2 +- capabilities/display_capabilities.js | 20 ++++++++++++++++++++ ffw/UIRPC.js | 1 + 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 51b60978b..dbdc63444 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1506,8 +1506,16 @@ SDL.SDLController = Em.Object.extend( windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["windowID"] = windowID; } if(appID) { + var appModel = this.getApplicationModel(appID); + if (appModel && appModel.appType.indexOf('TESTING') >= 0 && windowType == "MAIN") { + delete windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["textFields"]; + delete windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["imageFields"]; + windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["templatesAvailable"].push("WEB_VIEW"); + } + windowCapability["appID"] = appID; } + return windowCapability; }, /** diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index 81d202896..201dbe59c 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -1021,7 +1021,7 @@ SDL.SDLModelData = Em.Object.create( ], "imageTypeSupported": ["STATIC", "DYNAMIC"], "numCustomPresetsAvailable": 8, - "templatesAvailable": ["TEXT_WITH_GRAPHIC", "BUTTONS_WITH_GRAPHIC", "GRAPHIC_WITH_TEXT"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], "buttonCapabilities": [ { "longPressAvailable": true, diff --git a/capabilities/display_capabilities.js b/capabilities/display_capabilities.js index 902f6c6dd..f6ba18570 100644 --- a/capabilities/display_capabilities.js +++ b/capabilities/display_capabilities.js @@ -1673,5 +1673,25 @@ SDL.templateCapabilities = { "presetBankCapabilities": { "onScreenPresetsAvailable": false } + }, + "WEB_VIEW": { + "displayCapabilities": { + "displayType": "GEN2_8_DMA", + "displayName": "SDL_HMI", + "graphicSupported": true, + "imageCapabilities": ["DYNAMIC", "STATIC"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], + "screenParams": { + "resolution": { + "resolutionWidth": 800, + "resolutionHeight": 480 + }, + "touchEventAvailable": { + "pressAvailable": true, + "multiTouchAvailable": true, + "doublePressAvailable": false + } + } + } } } \ No newline at end of file diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index e90367887..773c09069 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -223,6 +223,7 @@ FFW.UI = FFW.RPCObserver.create( let sendCapabilityUpdated = false; if("templateConfiguration" in request.params) { if (model.templateConfiguration.template !== request.params.templateConfiguration.template) { + model.templateConfiguration.template = request.params.templateConfiguration.template; sendCapabilityUpdated = true; } if ("dayColorScheme" in request.params.templateConfiguration From b58d5f59cc03c6fc4fccdc7d60b0733483f22a0b Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Tue, 12 May 2020 20:47:10 -0400 Subject: [PATCH 019/104] Add menu and exit buttons for a WebEngine apps --- app/model/sdl/Abstract/AppModel.js | 4 +-- app/view/webEngine/webEngineView.js | 50 +++++++++++++++++++++++++++-- css/webEngine.css | 22 +++++++++++-- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 89bc620f2..fb33f56f4 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -503,7 +503,7 @@ SDL.ABSAppModel = Em.Object.extend( var commands = this.get('commandsList.' + parentID); // Magic number is limit of 1000 commands added on one menu if (commands.length <= 999) { - commands[commands.length] = { + commands.pushObject({ commandID: request.params.cmdID, name: request.params.menuParams.menuName, parent: parentID, @@ -513,7 +513,7 @@ SDL.ABSAppModel = Em.Object.extend( request.params.cmdIcon.isTemplate ?request.params.cmdIcon.isTemplate : null : null, icon: request.params.cmdIcon ? request.params.cmdIcon.value : null - }; + }); if (SDL.SDLController.getApplicationModel(request.params.appID) && SDL.OptionsView.active) { SDL.SDLController.buttonsSort(parentID, this.appID); diff --git a/app/view/webEngine/webEngineView.js b/app/view/webEngine/webEngineView.js index 2b7043354..2d3fc2e54 100644 --- a/app/view/webEngine/webEngineView.js +++ b/app/view/webEngine/webEngineView.js @@ -32,15 +32,61 @@ */ SDL.WebEngineView = Em.ContainerView.create({ elementId: 'webEngineView', + classNameBindings: [ 'SDL.States.webViewApp.active:active_state:inactive_state' ], + childViews: [ - 'TemplateTitleLabel' + 'TemplateTitleLabel', + 'ExitButton', + 'MenuButton' ], + isExitButtonVisible : true, + TemplateTitleLabel : SDL.Label.extend({ elementId: 'template_title_label', contentBinding: 'SDL.SDLController.model.templateConfiguration.template' - }) + }), + + ExitButton: SDL.Button.extend({ + classNames: 'button ExitButton', + classNameBindings: ['parentView.isExitButtonVisible::inactive_state'], + text: 'EXIT', + commandID: -2, + target: 'SDL.SDLController', + action: 'onCommand', + onDown: false + }), + + MenuButton: SDL.Button.extend({ + classNames: 'button MenuButton', + classNameBindings: ['parentView.isExitButtonVisible:inactive_state'], + text: 'MENU', + target: 'SDL.SDLController', + action: 'openCommandsList', + onDown: false + }), + + trackApplicationCommands: function() { + if (SDL.SDLController.model) { + let commands = SDL.SDLController.model.get('currentCommandsList'); + if (commands == null) { + commands = []; + } + + let is_custom_commands = false; + commands.forEach(command => { + if (command.commandID >= 0) { + is_custom_commands = true; + } + }); + + this.set('isExitButtonVisible', !is_custom_commands); + } + }.observes( + 'SDL.SDLController.model.currentSubMenuId', + 'SDL.SDLController.model.currentCommandsList.@each' + ) }); diff --git a/css/webEngine.css b/css/webEngine.css index d6950ac50..d8ed44a0e 100644 --- a/css/webEngine.css +++ b/css/webEngine.css @@ -1,7 +1,6 @@ /* Web Engine related control styles */ #webEngineView { - z-index: 2; position: absolute; top: 48px; width: 800px; @@ -20,5 +19,22 @@ left: 322px; width: 160px; text-align: center; - z-index: 2; -} \ No newline at end of file + z-index: 1; +} + +#webEngineView .ExitButton { + position: absolute; + right: -1px; + width: 100px; + text-align: center; + z-index: 1; +} + +#webEngineView .MenuButton { + position: absolute; + right: -1px; + top: 345px; + width: 100px; + text-align: center; + z-index: 1; +} From e2382d78229f22a570cd289a98e16fa4cbf2f1df Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 14 May 2020 13:10:50 -0400 Subject: [PATCH 020/104] Disable touch events when WEP is losing main context --- app/controller/sdl/Abstract/Controller.js | 18 ++++++++++++++++++ app/view/sdl/addWidgetPopUp.js | 1 + 2 files changed, 19 insertions(+) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index dbdc63444..2839dfd64 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1343,6 +1343,8 @@ SDL.SDLController = Em.Object.extend( */ onSystemContextChange: function(appID, windowID) { var sysContextValue = this.get('sysContext'); + SDL.SDLController.setWebEngineFramesActive(sysContextValue == 'MAIN'); + if (( appID && SDL.SDLController.getApplicationModel(appID) != @@ -1563,5 +1565,21 @@ SDL.SDLController = Em.Object.extend( } return title; }, + + /** + * @function setWebEngineFramesActive + * @param {Boolean} isActive + * @description set touch events activity for all currently active WEP frames + */ + setWebEngineFramesActive: function(isActive) { + var frames = document.getElementsByClassName("WebEngineFrame"); + for (var i = 0; i < frames.length; ++i) { + if (isActive) { + frames[i].style.pointerEvents = null; + } else { + frames[i].style.pointerEvents = "none"; + } + } + } } ); diff --git a/app/view/sdl/addWidgetPopUp.js b/app/view/sdl/addWidgetPopUp.js index a728a04a4..c5e242ead 100644 --- a/app/view/sdl/addWidgetPopUp.js +++ b/app/view/sdl/addWidgetPopUp.js @@ -104,6 +104,7 @@ SDL.AddWidgetPopUp = Em.ContainerView.create( toggleActivity: function() { this.toggleProperty('active'); this.updateWidgetList(); + SDL.SDLController.setWebEngineFramesActive(!this.active); } } ); From 10eff43e5f810356292df0782975561bab98e713 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 4 Jun 2020 12:30:55 -0400 Subject: [PATCH 021/104] Fix exit app for WEP --- app/controller/sdl/Abstract/Controller.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 2839dfd64..63b120589 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -179,7 +179,8 @@ SDL.SDLController = Em.Object.extend( closeApplication: function(appID) { if (SDL.States.currentState.getPath('path') === 'media.sdlmedia' || SDL.States.currentState.getPath('path') === 'info.nonMedia' || - SDL.States.currentState.getPath('path') === 'navigationApp.baseNavigation') { + SDL.States.currentState.getPath('path') === 'navigationApp.baseNavigation' || + SDL.States.currentState.getPath('path') === 'webViewApp') { SDL.States.goToStates('info.apps'); } }, From 49a1cb49d52cc3d899b05e617580a2a3bf90edc8 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 4 Jun 2020 19:36:30 -0400 Subject: [PATCH 022/104] Implement proper template switching --- app/controller/sdl/MediaController.js | 48 +++++++++++++++-------- app/controller/sdl/NonMediaController.js | 49 +++++++++++++++--------- app/model/sdl/Abstract/Model.js | 4 +- app/model/sdl/Abstract/data.js | 4 ++ ffw/UIRPC.js | 16 ++++++++ 5 files changed, 86 insertions(+), 35 deletions(-) diff --git a/app/controller/sdl/MediaController.js b/app/controller/sdl/MediaController.js index 1d5891b41..907af357b 100644 --- a/app/controller/sdl/MediaController.js +++ b/app/controller/sdl/MediaController.js @@ -77,26 +77,42 @@ SDL.SDLMediaController = Em.Object.create( // set active model SDL.SDLController.set('model', applicationModel); - if (SDL.SDLController.model.appType) { - for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { - if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || - SDL.SDLController.model.appType[i] == 'PROJECTION') { - this.model.currentAudioModel.turnOnSDL(); - SDL.BaseNavigationView.update(); - SDL.States.goToStates('navigationApp.baseNavigation'); - return; - } - if (SDL.SDLController.model.appType[i] == 'TESTING') { - // TODO(WEBENGINE) - SDL.InfoController.turnOnSDL(); - SDL.States.goToStates('webViewApp'); - return; + let get_template_from_app_type = function() { + if (SDL.SDLController.model.appType) { + for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { + if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || + SDL.SDLController.model.appType[i] == 'PROJECTION') { + return 'NAV_FULLSCREEN_MAP'; + } + if (SDL.SDLController.model.appType[i] == 'TESTING') { + // TODO(WEBENGINE) + return 'WEB_ENGINE'; + } } } - } + return 'MEDIA'; + }; + + const template_name = SDL.SDLController.model.templateConfiguration.template == 'DEFAULT' ? + get_template_from_app_type() : + SDL.SDLController.model.templateConfiguration.template; this.model.currentAudioModel.turnOnSDL(); - SDL.States.goToStates('media.sdlmedia'); + switch (template_name) { + case 'NAV_FULLSCREEN_MAP' : { + SDL.BaseNavigationView.update(); + SDL.States.goToStates('navigationApp.baseNavigation'); + break; + } + case 'WEB_ENGINE' : { + SDL.InfoController.turnOnSDL(); + SDL.States.goToStates('webViewApp'); + break; + } + default: { + SDL.States.goToStates('media.sdlmedia'); + } + } }, /** * Restore current application to active state diff --git a/app/controller/sdl/NonMediaController.js b/app/controller/sdl/NonMediaController.js index d2ac39a5c..ad0a4dcc7 100644 --- a/app/controller/sdl/NonMediaController.js +++ b/app/controller/sdl/NonMediaController.js @@ -67,28 +67,41 @@ SDL.NonMediaController = Em.Object.create( // set active model SDL.SDLController.set('model', applicationModel); - // go to SDL state - if (SDL.SDLController.model.appType) { - for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { - if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || - SDL.SDLController.model.appType[i] == 'PROJECTION') { - SDL.InfoController.turnOnSDL(); - SDL.BaseNavigationView.update(); - SDL.States.goToStates('navigationApp.baseNavigation'); - return; - } - if (SDL.SDLController.model.appType[i] == 'TESTING') { - // TODO(WEBENGINE) - SDL.InfoController.turnOnSDL(); - SDL.States.goToStates('webViewApp'); - return; + let get_template_from_app_type = function() { + if (SDL.SDLController.model.appType) { + for (var i = 0; i < SDL.SDLController.model.appType.length; i++) { + if (SDL.SDLController.model.appType[i] == 'NAVIGATION' || + SDL.SDLController.model.appType[i] == 'PROJECTION') { + return 'NAV_FULLSCREEN_MAP'; + } + if (SDL.SDLController.model.appType[i] == 'TESTING') { + // TODO(WEBENGINE) + return 'WEB_ENGINE'; + } } } - } + return 'NON-MEDIA'; + }; + + const template_name = SDL.SDLController.model.templateConfiguration.template == 'DEFAULT' ? + get_template_from_app_type() : + SDL.SDLController.model.templateConfiguration.template; - // Go to SDL state SDL.InfoController.turnOnSDL(); - SDL.States.goToStates('info.nonMedia'); + switch (template_name) { + case 'NAV_FULLSCREEN_MAP' : { + SDL.BaseNavigationView.update(); + SDL.States.goToStates('navigationApp.baseNavigation'); + break; + } + case 'WEB_ENGINE' : { + SDL.States.goToStates('webViewApp'); + break; + } + default: { + SDL.States.goToStates('info.nonMedia'); + } + } }, /** * Restore current application to active state diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 6f5acfa0b..016966d01 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1496,7 +1496,9 @@ SDL.SDLModel = Em.Object.extend({ SDL.TurnByTurnView.deactivate(); - if (!SDL.SDLModel.data.phoneCallActive && reason == 'GENERAL') { + if (!SDL.SDLModel.data.phoneCallActive && + !SDL.SDLModel.data.templateChangeInProgress && + reason == 'GENERAL') { FFW.BasicCommunication.OnAppDeactivated(appID); } } diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index 201dbe59c..c9177b10e 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -129,6 +129,10 @@ SDL.SDLModelData = Em.Object.create( * Active state of phone call on HMI for Deactivate app to handle event */ phoneCallActive: false, + /** + * True, if active app is currently changing template + */ + templateChangeInProgress: false, /** * FLAG of any app in limited level exists */ diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 773c09069..1bb34b350 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -224,6 +224,14 @@ FFW.UI = FFW.RPCObserver.create( if("templateConfiguration" in request.params) { if (model.templateConfiguration.template !== request.params.templateConfiguration.template) { model.templateConfiguration.template = request.params.templateConfiguration.template; + + if (model.active) { + SDL.SDLModel.data.templateChangeInProgress = true; + SDL.States.goToStates('info.apps'); + model.turnOnSDL(); + SDL.SDLModel.data.templateChangeInProgress = false; + } + sendCapabilityUpdated = true; } if ("dayColorScheme" in request.params.templateConfiguration @@ -515,6 +523,14 @@ FFW.UI = FFW.RPCObserver.create( let sendCapabilityUpdated = false; if ("displayLayout" in request.params && model.templateConfiguration.template !== request.params.displayLayout) { model.templateConfiguration.template = request.params.displayLayout + + if (model.active) { + SDL.SDLModel.data.templateChangeInProgress = true; + SDL.States.goToStates('info.apps'); + model.turnOnSDL(); + SDL.SDLModel.data.templateChangeInProgress = false; + } + sendCapabilityUpdated = true; } if ("dayColorScheme" in request.params From a4a580607e3117b2a906d8a1737774285e9b12a9 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Sat, 6 Jun 2020 18:25:58 -0400 Subject: [PATCH 023/104] Update display capabilities according to proposal --- app/controller/sdl/Abstract/Controller.js | 39 +- capabilities/display_capabilities.js | 438 +--------------------- ffw/UIRPC.js | 4 +- 3 files changed, 40 insertions(+), 441 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 63b120589..ba437a84e 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1504,16 +1504,45 @@ SDL.SDLController = Em.Object.extend( getDefaultCapabilities: function (windowID, appID) { let windowType = (windowID === undefined || windowID === 0) ? "MAIN" : "WIDGET"; - let windowCapability = SDL.SDLModelData.defaultWindowCapability[windowType]; + let windowCapability = SDL.deepCopy(SDL.SDLModelData.defaultWindowCapability[windowType]); if(windowType === "WIDGET") { windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["windowID"] = windowID; } + if(appID) { + const is_web_view_template = function(model) { + const template = model.templateConfiguration.template; + if (template == "DEFAULT" && model.appType.indexOf('TESTING') >= 0) { + return true; + } + + return template == "WEB_VIEW"; + } + var appModel = this.getApplicationModel(appID); - if (appModel && appModel.appType.indexOf('TESTING') >= 0 && windowType == "MAIN") { - delete windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["textFields"]; - delete windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["imageFields"]; - windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["templatesAvailable"].push("WEB_VIEW"); + if (appModel && is_web_view_template(appModel) && windowType == "MAIN") { + let text_fields = windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["textFields"]; + const text_fields_to_exclude = [ + 'mainField1', 'mainField2', 'mainField3', 'mainField4', + 'mediaClock', 'mediaTrack' + ]; + for (var i = text_fields.length - 1; i >= 0; i--) { + if (text_fields_to_exclude.includes(text_fields[i].name)) { + text_fields.splice(i, 1); + } + } + + let image_fields = windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["imageFields"]; + const image_fields_to_exclude = [ + 'softButtonImage', 'menuIcon', 'graphic', 'secondaryGraphic' + ]; + for (var i = image_fields.length - 1; i >= 0; i--) { + if (image_fields_to_exclude.includes(image_fields[i].name)) { + image_fields.splice(i, 1); + } + } + + delete windowCapability["systemCapability"]["displayCapabilities"][0]["windowCapabilities"][0]["softButtonCapabilities"]; } windowCapability["appID"] = appID; diff --git a/capabilities/display_capabilities.js b/capabilities/display_capabilities.js index f6ba18570..596679154 100644 --- a/capabilities/display_capabilities.js +++ b/capabilities/display_capabilities.js @@ -362,7 +362,7 @@ SDL.templateCapabilities = { ], "graphicSupported": true, "imageCapabilities": ["DYNAMIC", "STATIC"], - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], "screenParams": { "resolution": { "resolutionWidth": 800, @@ -467,436 +467,6 @@ SDL.templateCapabilities = { "onScreenPresetsAvailable": true } }, - "ONSCREEN_PRESETS": { - "displayCapabilities": { - "displayType": "GEN2_8_DMA", - "displayName": "SDL_HMI", - "textFields": [{ - "name": "mainField1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mainField2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "statusBar", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaClock", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "mediaTrack", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "templateTitle", - "characterSet": "TYPE2SET", - "width": 100, - "rows": 1 - }, - { - "name": "alertText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "alertText3", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "initialInteractionText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "navigationText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "ETA", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "totalDistance", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderHeader", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "sliderFooter", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuName", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "secondaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "tertiaryText", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "menuTitle", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "locationName", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "locationDescription", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "addressLines", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - }, - { - "name": "phoneNumber", - "characterSet": "TYPE2SET", - "width": 500, - "rows": 1 - } - ], - "imageFields": [{ - "name": "softButtonImage", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "choiceImage", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "choiceSecondaryImage", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "vrHelpItem", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "turnIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "menuIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "cmdIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "graphic", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "secondaryGraphic", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "showConstantTBTIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "showConstantTBTNextTurnIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "showConstantTBTNextTurnIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 64, - "resolutionHeight": 64 - } - }, - { - "name": "alertIcon", - "imageTypeSupported": [ - "GRAPHIC_BMP", - "GRAPHIC_JPEG", - "GRAPHIC_PNG" - ], - "imageResolution": { - "resolutionWidth": 105, - "resolutionHeight": 65 - } - } - ], - "mediaClockFormats": [ - "CLOCK1", "CLOCK2", "CLOCK3", "CLOCKTEXT1", "CLOCKTEXT2", - "CLOCKTEXT3", "CLOCKTEXT4" - ], - "graphicSupported": true, - "imageCapabilities": ["DYNAMIC", "STATIC"], - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], - "screenParams": { - "resolution": { - "resolutionWidth": 800, - "resolutionHeight": 480 - }, - "touchEventAvailable": { - "pressAvailable": true, - "multiTouchAvailable": true, - "doublePressAvailable": false - } - }, - "numCustomPresetsAvailable": 10 - }, - "buttonCapabilities": [{ - "name": "PRESET_0", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_1", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_2", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_3", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_4", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_5", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_6", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_7", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_8", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "PRESET_9", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "OK", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "SEEKLEFT", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "SEEKRIGHT", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "TUNEUP", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }, { - "name": "TUNEDOWN", - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true - }], - "softButtonCapabilities": [{ - "shortPressAvailable": true, - "longPressAvailable": true, - "upDownAvailable": true, - "imageSupported": true - }], - "presetBankCapabilities": { - "onScreenPresetsAvailable": true - } - }, "NON-MEDIA": { "displayCapabilities": { "displayType": "GEN2_8_DMA", @@ -1239,7 +809,7 @@ SDL.templateCapabilities = { ], "graphicSupported": true, "imageCapabilities": ["DYNAMIC", "STATIC"], - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], "screenParams": { "resolution": { "resolutionWidth": 800, @@ -1645,7 +1215,7 @@ SDL.templateCapabilities = { ], "graphicSupported": true, "imageCapabilities": ["DYNAMIC", "STATIC"], - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], "screenParams": { "resolution": { "resolutionWidth": 800, @@ -1680,7 +1250,7 @@ SDL.templateCapabilities = { "displayName": "SDL_HMI", "graphicSupported": true, "imageCapabilities": ["DYNAMIC", "STATIC"], - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "NAV_FULLSCREEN_MAP", "WEB_VIEW"], "screenParams": { "resolution": { "resolutionWidth": 800, diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 1bb34b350..6c239d483 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -474,14 +474,14 @@ FFW.UI = FFW.RPCObserver.create( case 'MEDIA': case 'NON-MEDIA': case 'DEFAULT': - case 'ONSCREEN_PRESETS': case 'NAV_FULLSCREEN_MAP': + case 'WEB_VIEW': { sendResponseFlag = true; break; } } - var model = SDL.SDLController.getApplicationModel(request.params.appID); + if (sendResponseFlag) { Em.Logger.log('FFW.' + request.method + 'Response'); var displayLayout = request.params.displayLayout; From 70ce3a977a30eb31e4c91ddc41f12e9c5c202712 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Mon, 8 Jun 2020 15:14:30 -0400 Subject: [PATCH 024/104] Remove redundant buttons from WEB_VIEW template --- app/view/webEngine/webEngineView.js | 57 ++++++----------------------- css/webEngine.css | 23 ++---------- 2 files changed, 15 insertions(+), 65 deletions(-) diff --git a/app/view/webEngine/webEngineView.js b/app/view/webEngine/webEngineView.js index 2d3fc2e54..68b9015a9 100644 --- a/app/view/webEngine/webEngineView.js +++ b/app/view/webEngine/webEngineView.js @@ -38,55 +38,22 @@ SDL.WebEngineView = Em.ContainerView.create({ ], childViews: [ - 'TemplateTitleLabel', - 'ExitButton', - 'MenuButton' + 'TemplateAppTitleLabel' ], isExitButtonVisible : true, - TemplateTitleLabel : SDL.Label.extend({ + TemplateAppTitleLabel : SDL.Label.extend({ elementId: 'template_title_label', - contentBinding: 'SDL.SDLController.model.templateConfiguration.template' - }), - - ExitButton: SDL.Button.extend({ - classNames: 'button ExitButton', - classNameBindings: ['parentView.isExitButtonVisible::inactive_state'], - text: 'EXIT', - commandID: -2, - target: 'SDL.SDLController', - action: 'onCommand', - onDown: false - }), - - MenuButton: SDL.Button.extend({ - classNames: 'button MenuButton', - classNameBindings: ['parentView.isExitButtonVisible:inactive_state'], - text: 'MENU', - target: 'SDL.SDLController', - action: 'openCommandsList', - onDown: false - }), - - trackApplicationCommands: function() { - if (SDL.SDLController.model) { - let commands = SDL.SDLController.model.get('currentCommandsList'); - if (commands == null) { - commands = []; + contentBinding: 'getText', + getText: function() { + if (SDL.SDLController.model) { + return SDL.SDLController.model.appName + ' / ' + + SDL.SDLController.model.templateConfiguration.template; } - - let is_custom_commands = false; - commands.forEach(command => { - if (command.commandID >= 0) { - is_custom_commands = true; - } - }); - - this.set('isExitButtonVisible', !is_custom_commands); - } - }.observes( - 'SDL.SDLController.model.currentSubMenuId', - 'SDL.SDLController.model.currentCommandsList.@each' - ) + }.property( + 'SDL.SDLController.model.templateConfiguration.template', + 'SDL.SDLController.model.appName' + ) + }) }); diff --git a/css/webEngine.css b/css/webEngine.css index d8ed44a0e..1331231ee 100644 --- a/css/webEngine.css +++ b/css/webEngine.css @@ -15,26 +15,9 @@ #webEngineView #template_title_label { position: absolute; - top: 360px; - left: 322px; - width: 160px; - text-align: center; - z-index: 1; -} - -#webEngineView .ExitButton { - position: absolute; - right: -1px; - width: 100px; - text-align: center; - z-index: 1; -} - -#webEngineView .MenuButton { - position: absolute; - right: -1px; - top: 345px; - width: 100px; + top: 357px; + left: 175px; + width: 460px; text-align: center; z-index: 1; } From 9340a7c334ed0e26d993fbc2444df553b291d685 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Fri, 12 Jun 2020 14:36:55 -0400 Subject: [PATCH 025/104] Change debug appHmiType to the final one --- app/controller/sdl/Abstract/Controller.js | 4 ++-- app/controller/sdl/MediaController.js | 3 +-- app/controller/sdl/NonMediaController.js | 3 +-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index ba437a84e..222406e2c 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1192,7 +1192,7 @@ SDL.SDLController = Em.Object.extend( } SDL.InfoController.getWebAppEntryPointPath(model.policyAppID, callback); - } else if (model.webEngineApp !== true && model.appType.indexOf('TESTING') >= 0) { + } else if (model.webEngineApp !== true && model.appType.indexOf('WEB_VIEW') >= 0) { SDL.PopUp.create().appendTo('body') .popupActivate("Only Web Engine apps with app type WEB_VIEW can be activated!"); } else { @@ -1512,7 +1512,7 @@ SDL.SDLController = Em.Object.extend( if(appID) { const is_web_view_template = function(model) { const template = model.templateConfiguration.template; - if (template == "DEFAULT" && model.appType.indexOf('TESTING') >= 0) { + if (template == "DEFAULT" && model.appType.indexOf('WEB_VIEW') >= 0) { return true; } diff --git a/app/controller/sdl/MediaController.js b/app/controller/sdl/MediaController.js index 907af357b..675ce2171 100644 --- a/app/controller/sdl/MediaController.js +++ b/app/controller/sdl/MediaController.js @@ -84,8 +84,7 @@ SDL.SDLMediaController = Em.Object.create( SDL.SDLController.model.appType[i] == 'PROJECTION') { return 'NAV_FULLSCREEN_MAP'; } - if (SDL.SDLController.model.appType[i] == 'TESTING') { - // TODO(WEBENGINE) + if (SDL.SDLController.model.appType[i] == 'WEB_VIEW') { return 'WEB_ENGINE'; } } diff --git a/app/controller/sdl/NonMediaController.js b/app/controller/sdl/NonMediaController.js index ad0a4dcc7..dedf12d7b 100644 --- a/app/controller/sdl/NonMediaController.js +++ b/app/controller/sdl/NonMediaController.js @@ -74,8 +74,7 @@ SDL.NonMediaController = Em.Object.create( SDL.SDLController.model.appType[i] == 'PROJECTION') { return 'NAV_FULLSCREEN_MAP'; } - if (SDL.SDLController.model.appType[i] == 'TESTING') { - // TODO(WEBENGINE) + if (SDL.SDLController.model.appType[i] == 'WEB_VIEW') { return 'WEB_ENGINE'; } } From 1e70f735b0f6dcc173727ee89a4e4ae9e23221dd Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Tue, 30 Jun 2020 20:57:36 -0400 Subject: [PATCH 026/104] Fix available templates list Window capabilities structure has been updated to reflect all the latest changes in app template switching. --- app/model/sdl/Abstract/data.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index c9177b10e..3af008189 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -1025,7 +1025,7 @@ SDL.SDLModelData = Em.Object.create( ], "imageTypeSupported": ["STATIC", "DYNAMIC"], "numCustomPresetsAvailable": 8, - "templatesAvailable": ["MEDIA", "NON-MEDIA", "ONSCREEN_PRESETS", "NAV_FULLSCREEN_MAP"], + "templatesAvailable": ["MEDIA", "NON-MEDIA", "DEFAULT", "NAV_FULLSCREEN_MAP", 'WEB_VIEW'], "buttonCapabilities": [ { "longPressAvailable": true, From b2eb7eca4b940cd589ae047faca6cb9567c0cd37 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Tue, 30 Jun 2020 21:04:55 -0400 Subject: [PATCH 027/104] Fix templates list in GetCapabilities response --- ffw/UIRPC.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 6c239d483..283709456 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -991,7 +991,7 @@ FFW.UI = FFW.RPCObserver.create( ], 'graphicSupported': true, 'imageCapabilities': ['DYNAMIC', 'STATIC'], - 'templatesAvailable': ['TEMPLATE'], + 'templatesAvailable': ["MEDIA", "NON-MEDIA", "DEFAULT", "NAV_FULLSCREEN_MAP", 'WEB_VIEW'], 'screenParams': { 'resolution': { 'resolutionWidth': 800, From 0ba3af0e170fb93b6447bca8218e1df35bcc90cf Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 2 Jul 2020 00:49:38 -0400 Subject: [PATCH 028/104] Fix initial template name for app main window Now it will be calculated according to registered app HMI type. Also were removed keyword WEB_ENGINE as there is no such template name. --- app/controller/sdl/MediaController.js | 4 ++-- app/controller/sdl/NonMediaController.js | 4 ++-- app/controller/sdl/RController.js | 16 +++++++++++++++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/controller/sdl/MediaController.js b/app/controller/sdl/MediaController.js index 675ce2171..317980107 100644 --- a/app/controller/sdl/MediaController.js +++ b/app/controller/sdl/MediaController.js @@ -85,7 +85,7 @@ SDL.SDLMediaController = Em.Object.create( return 'NAV_FULLSCREEN_MAP'; } if (SDL.SDLController.model.appType[i] == 'WEB_VIEW') { - return 'WEB_ENGINE'; + return 'WEB_VIEW'; } } } @@ -103,7 +103,7 @@ SDL.SDLMediaController = Em.Object.create( SDL.States.goToStates('navigationApp.baseNavigation'); break; } - case 'WEB_ENGINE' : { + case 'WEB_VIEW' : { SDL.InfoController.turnOnSDL(); SDL.States.goToStates('webViewApp'); break; diff --git a/app/controller/sdl/NonMediaController.js b/app/controller/sdl/NonMediaController.js index dedf12d7b..fb46fb979 100644 --- a/app/controller/sdl/NonMediaController.js +++ b/app/controller/sdl/NonMediaController.js @@ -75,7 +75,7 @@ SDL.NonMediaController = Em.Object.create( return 'NAV_FULLSCREEN_MAP'; } if (SDL.SDLController.model.appType[i] == 'WEB_VIEW') { - return 'WEB_ENGINE'; + return 'WEB_VIEW'; } } } @@ -93,7 +93,7 @@ SDL.NonMediaController = Em.Object.create( SDL.States.goToStates('navigationApp.baseNavigation'); break; } - case 'WEB_ENGINE' : { + case 'WEB_VIEW' : { SDL.States.goToStates('webViewApp'); break; } diff --git a/app/controller/sdl/RController.js b/app/controller/sdl/RController.js index 2dcbc5672..1186b90cc 100644 --- a/app/controller/sdl/RController.js +++ b/app/controller/sdl/RController.js @@ -249,8 +249,22 @@ SDL.RController = SDL.SDLController.extend( const isDayColorSchemeExists = "dayColorScheme" in params ; const isNightColorSchemeExists = "nightColorScheme" in params; + let get_template_from_app_type = function(model) { + if (model.appType) { + for (var i = 0; i < model.appType.length; i++) { + if (model.appType[i] == 'NAVIGATION' || model.appType[i] == 'PROJECTION') { + return 'NAV_FULLSCREEN_MAP'; + } + if (model.appType[i] == 'WEB_VIEW') { + return 'WEB_VIEW'; + } + } + } + return model.isMedia ? 'MEDIA' : 'NON-MEDIA'; + }; + let defaultTemplateConfiguration = { - "template" : "DEFAULT" + "template" : get_template_from_app_type(model) }; const defaultColorScheme = { From 75aa3c08695755cded749ce703c571cfe15e575f Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 2 Jul 2020 13:36:23 -0400 Subject: [PATCH 029/104] Add new exit reason for WEP apps --- app/controller/sdl/Abstract/Controller.js | 40 ++++++++++++++++++----- app/controller/sdl/RController.js | 38 +++++++++++++++++---- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 222406e2c..1a0e1f607 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -92,6 +92,14 @@ SDL.SDLController = Em.Object.extend( ); break; } + case -4: + { + FFW.BasicCommunication.ExitApplication( + SDL.SDLController.model.appID, + 'RESOURCE_CONSTRAINT' + ); + break; + } default: { console.log('Unknown command with ID: ' + element.commandID); @@ -946,6 +954,8 @@ SDL.SDLController = Em.Object.extend( ) ); } + + let model = SDL.SDLController.getApplicationModel(params.appID); var exitCommand = { 'id': -10, 'params': { @@ -957,9 +967,8 @@ SDL.SDLController = Em.Object.extend( cmdID: -1 } }; - SDL.SDLController.getApplicationModel(params.appID).addCommand( - exitCommand - ); + model.addCommand(exitCommand); + exitCommand = { 'id': -10, 'params': { @@ -971,9 +980,8 @@ SDL.SDLController = Em.Object.extend( cmdID: -2 } }; - SDL.SDLController.getApplicationModel(params.appID).addCommand( - exitCommand - ); + model.addCommand(exitCommand); + exitCommand = { 'id': -10, 'params': { @@ -985,9 +993,23 @@ SDL.SDLController = Em.Object.extend( cmdID: -3 } }; - SDL.SDLController.getApplicationModel(params.appID).addCommand( - exitCommand - ); + model.addCommand(exitCommand); + + if (isWebEngineApp) { + exitCommand = { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'RESOURCE_CONSTRAINT\'', + 'position': 0 + }, + cmdID: -4 + } + }; + model.addCommand(exitCommand); + } + }, /** * Unregister application diff --git a/app/controller/sdl/RController.js b/app/controller/sdl/RController.js index 1186b90cc..871bc832f 100644 --- a/app/controller/sdl/RController.js +++ b/app/controller/sdl/RController.js @@ -370,6 +370,8 @@ SDL.RController = SDL.SDLController.extend( ) ); } + + let model = SDL.SDLController.getApplicationModel(params.appID); var exitCommand = { 'id': -10, 'params': { @@ -382,9 +384,8 @@ SDL.RController = SDL.SDLController.extend( cmdID: -1 } }; - SDL.SDLController.getApplicationModel(params.appID).addCommand( - exitCommand - ); + model.addCommand(exitCommand); + exitCommand = { 'id': -10, 'params': { @@ -397,9 +398,8 @@ SDL.RController = SDL.SDLController.extend( cmdID: -2 } }; - SDL.SDLController.getApplicationModel(params.appID).addCommand( - exitCommand - ); + model.addCommand(exitCommand); + exitCommand = { 'id': -10, 'params': { @@ -412,8 +412,24 @@ SDL.RController = SDL.SDLController.extend( cmdID: -3 } }; - let model = SDL.SDLController.getApplicationModel(params.appID); model.addCommand(exitCommand); + + if (isWebEngineApp) { + exitCommand = { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'RESOURCE_CONSTRAINT\'', + 'position': 0 + }, + + cmdID: -4 + } + }; + model.addCommand(exitCommand); + } + this.setInitalWindowTemplate(params, model); }, @@ -479,6 +495,14 @@ SDL.RController = SDL.SDLController.extend( ); break; } + case -4: + { + FFW.BasicCommunication.ExitApplication( + SDL.SDLController.model.appID, + 'RESOURCE_CONSTRAINT' + ); + break; + } default: { console.log('Unknown command with ID: ' + element.commandID); From 782ff9813866fd063129168eace0948d2c6b1949 Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 2 Jul 2020 22:07:47 -0400 Subject: [PATCH 030/104] Fix template auto change for widget with softbtn --- app/view/home/widgetContainerView.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/view/home/widgetContainerView.js b/app/view/home/widgetContainerView.js index 52221253d..8e3457b52 100644 --- a/app/view/home/widgetContainerView.js +++ b/app/view/home/widgetContainerView.js @@ -234,7 +234,10 @@ SDL.WidgetContainerView = Em.ContainerView.extend({ if('softButtons' in widgetContent) { var length = widgetContent.softButtons.length; - parentToPush.setTemplate('BUTTONS_WITH_GRAPHIC'); + if (length > 0) { + parentToPush.setTemplate('BUTTONS_WITH_GRAPHIC'); + } + for(var i = 0; i < length; ++i) { var softButton = SDL.Button.create(SDL.PresetEventsCustom,{ classNames: ['button', 'softButton', 'softButton_' + (i + 1)], From f69abf132c2a7add19caaf2edf0461488eabda82 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 7 Jul 2020 13:05:36 -0400 Subject: [PATCH 031/104] initial subtle alert implementation --- app/AppViews.js | 1 + app/controller/sdl/Abstract/Controller.js | 41 +++- app/model/sdl/Abstract/Model.js | 34 ++++ app/view/sdl/SubtleAlertPopUp.js | 232 ++++++++++++++++++++++ ffw/UIRPC.js | 55 ++++- 5 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 app/view/sdl/SubtleAlertPopUp.js diff --git a/app/AppViews.js b/app/AppViews.js index c4b334801..54b2c1d12 100644 --- a/app/AppViews.js +++ b/app/AppViews.js @@ -69,6 +69,7 @@ SDL.AppViews = Em.ContainerView.extend( SDL.BottomControls, SDL.TTSPopUp, SDL.AlertPopUp, + SDL.SubtleAlertPopUp, SDL.ServiceUpdatePopUp, SDL.AlertManeuverPopUp, SDL.AudioPassThruPopUp, diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 5364fc12d..2154e467e 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -565,6 +565,11 @@ SDL.SDLController = Em.Object.extend( SDL.AlertPopUp.deactivate(); break; } + case 'SubtleAlertPopUp': + { + SDL.SubtleAlertPopUp.deactivate(); + break; + } case 'ScrollableMessage': { SDL.ScrollableMessage.deactivate(true); @@ -606,6 +611,11 @@ SDL.SDLController = Em.Object.extend( this.onActivateSDLApp(element); break; } + case 'SubtleAlertPopUp': + { + SDL.SubtleAlertPopUp.deactivate(); + this.onActivateSDLApp(element); + } case 'ScrollableMessage': { SDL.ScrollableMessage.deactivate(); @@ -638,6 +648,16 @@ SDL.SDLController = Em.Object.extend( this.onResetTimeout(element.appID, 'UI.Alert'); break; } + case 'SubtleAlertPopUp': + { + clearTimeout(SDL.SubtleAlertPopUp.timer); + SDL.SubtleAlertPopUp.timer = setTimeout( + function() { + SDL.SubtleAlertPopUp.deactivate(); + }, SDL.SubtleAlertPopUp.timeout + ); + this.onResetTimeout(element.appID, 'UI.SubtleAlert'); + } case 'ScrollableMessage': { clearTimeout(SDL.ScrollableMessage.timer); @@ -658,6 +678,8 @@ SDL.SDLController = Em.Object.extend( closePopUp: function(methodName) { if (methodName == 'UI.Alert') { SDL.AlertPopUp.deactivate(); + } else if (methodName === 'UI.SubtleAlert') { + SDL.SubtleAlertPopUp.deactivate(); } if (methodName == 'UI.PerformAudioPassThru') { SDL.AudioPassThruPopUp.deactivate(); @@ -764,14 +786,29 @@ SDL.SDLController = Em.Object.extend( /** * Method to sent notification for Alert * - * @param {String} - * result + * @param {Number} + * result code * @param {Number} * alertRequestID */ alertResponse: function(result, alertRequestID, info) { FFW.UI.alertResponse(result, alertRequestID, info); }, + /** + * Method to sent response for SubtleAlert + * + * @param {Number} + * result code + * @param {Number} + * subtleAlertRequestID + * @param {String} + * info + * @param {Number} + * tryAgainTime time in ms until current SubtleAlert finished + */ + subtleAlertResponse: function(result, subtleAlertRequestID, info, tryAgainTime) { + FFW.UI.subtleAlertResponse(result, subtleAlertRequestID, info, tryAgainTime); + }, /** * Method to sent notification for Scrollable Message * diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 6f5acfa0b..4dfb0279a 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1142,6 +1142,40 @@ SDL.SDLModel = Em.Object.extend({ } }, + /** + * SDL UI SubtleAlert response handler show popup window + * + * @param {Object} + * message Object with parameters come from SDLCore + * @param {Number} + * subtleAlertRequestId Id of current handled request + */ + onUISubtleAlert: function(message, subtleAlertRequestId) { + + // todo collin: what other popups block subtle alert? + if (SDL.AlertPopUp.active) { + var tryAgainTime = SDL.AlertPopUp.timer._idleStart + SDL.AlertPopUp.timer._idleTimeout - Date.now(); + SDL.SDLController.subtleAlertResponse(SDL.SDLModel.data.resultCode.REJECTED, + subtleAlertRequestId, + 'an Alert is active', + tryAgainTime); + } else if (SDL.ScrollableMessage.active) { + var tryAgainTime = SDL.ScrollableMessage.timer._idleStart + SDL.ScrollableMessage.timer._idleTimeout - Date.now(); + SDL.SDLController.subtleAlertResponse(SDL.SDLModel.data.resultCode.REJECTED, + subtleAlertRequestId, + 'a ScrollableMessage is active', + tryAgainTime); + } else if (SDL.SubtleAlertPopUp.active) { + var tryAgainTime = SDL.SubtleAlertPopUp.timer._idleStart + SDL.SubtleAlertPopUp.timer._idleTimeout - Date.now(); + SDL.SDLController.subtleAlertResponse(SDL.SDLModel.data.resultCode.REJECTED, + subtleAlertRequestId, + 'another SubtleAlert is active', + tryAgainTime); + } else { + SDL.SubtleAlertPopUp.SubtleAlertActive(message, subtleAlertRequestId); + } + }, + /** * SDL UI PerformInteraction response handler show popup window * diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js new file mode 100644 index 000000000..90037feb2 --- /dev/null +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * · Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * · Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * · Neither the name of the Ford Motor Company nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +/** + * @name SDL.SubtleAlertPopUp + * @desc SubtleAlertPopUp module visual representation + * @category View + * @filesource app/view/sdl/SubtleAlertPopUp.js + * @version 1.0 + */ + +SDL.SubtleAlertPopUp = Em.ContainerView.create( + { + elementId: 'SubtleAlertPopUp', + classNames: 'SubtleAlertPopUp', + classNameBindings: [ + 'active:SubtleAlertActive' + ], + childViews: [ + 'image', + 'message1', + 'message2', + 'softbuttons' + ], + /** + * Id of current request + * + * @type {Number} + */ + alertRequestId: null, + content1: '', + content2: '', + active: false, + timer: null, + timeout: null, + reason: '', + message: undefined, + /** + * Wagning image on Alert PopUp + */ + image: Em.View.extend( + { + elementId: 'subtleAlertPopUpImage', + template: Ember.Handlebars.compile( + '' + ) + } + ), + /** + * @function imageUndefined + * @param {Object} event + * @description action if an image undefined. + */ + imageUndefined: function (event) { + event.target.style.display = 'none'; + this.message = "Requested image(s) not found"; + this.reason = "WARNINGS" + }, + /** + * @function imageLoaded + * @param {Object} event + * @description action if an image loaded. + */ + imageLoaded: function (event) { + event.target.style.display = 'block'; + }, + message1: SDL.Label.extend( + { + elementId: 'message1', + classNames: 'message1', + contentBinding: 'parentView.content1' + } + ), + message2: SDL.Label.extend( + { + elementId: 'message2', + classNames: 'message2', + contentBinding: 'parentView.content2' + } + ), + /** + * Deactivate PopUp + */ + deactivate: function (reason, info) { + this.set('active', false); + clearTimeout(this.timer); + this.set('content1', ''); + this.set('content2', ''); + if ((reason == 'timeout' && + this.softbuttons.buttons._childViews.length > 0) || + reason === 'ABORTED') { + SDL.SDLController.subtleAlertResponse( + SDL.SDLModel.data.resultCode.ABORTED, this.alertRequestId, info + ); + } else if (reason === 'WARNINGS' || + this.reason === 'WARNINGS') { + info = info ? info : this.message; + SDL.SDLController.subtleAlertResponse( + SDL.SDLModel.data.resultCode.WARNINGS, this.alertRequestId, info + ); + } else { + SDL.SDLController.subtleAlertResponse( + SDL.SDLModel.data.resultCode.SUCCESS, this.alertRequestId, info + ); + } + }, + /** + * Container for softbuttons + */ + softbuttons: Em.ContainerView.extend( + { + childViews: [ + 'buttons' + ], + buttons: Em.ContainerView.extend( + { + elementId: 'subtleAlertSoftButtons', + classNames: 'subtleAlertSoftButtons' + } + ) + } + ), + /** + * @desc Function creates Soft Buttons on AlertPoUp + * @param {Object} params + */ + addSoftButtons: function (params, appID) { + this.softbuttons.buttons.removeAllChildren(); + this.softbuttons.buttons.rerender(); + if (params) { + var softButtonsClass; + switch (params.length) { + case 1: + softButtonsClass = 'one'; + break; + case 2: + softButtonsClass = 'two'; + break; + } + for (var i = 0; i < params.length; i++) { + this.get('softbuttons.buttons.childViews') + .pushObject( + SDL.Button.create( + SDL.PresetEventsCustom, { + systemAction: params[i].systemAction, + groupName: 'AlertPopUp', + classNameBindings: ['isHighlighted:isHighlighted', + 'getCurrentDisplayModeClass'], + getCurrentDisplayModeClass: function () { + return SDL.ControlButtons.getCurrentDisplayModeClass( + SDL.ControlButtons.imageMode.selection); + }.property('SDL.ControlButtons.imageMode.selection'), + isHighlighted: params[i].isHighlighted ? true : false, + softButtonID: params[i].softButtonID, + icon: params[i].image ? params[i].image.value : '', + text: params[i].text, + classNames: 'list-item softButton ' + softButtonsClass, + elementId: 'softButton' + i, + templateName: params[i].image ? params[i].image.isTemplate ? 'rightTextOverLay' : 'rightText' : 'text', + appID: appID + } + ) + ); + } + } + }, + SubtleAlertActive: function (message, alertRequestId) { + var self = this; + this.set('alertRequestId', alertRequestId); + this.set('cancelID', message.cancelID); + this.set('reason', 'timeout'); + this.set('message', undefined); + this.addSoftButtons(message.softButtons, message.appID); + this.set('progressIndicator', message.progressIndicator); + this.set('appID', message.appID); + this.set('icon', message.alertIcon ? message.alertIcon.value : "images/sdl/Warning.png"); + for (var i = 0; i < message.alertStrings.length; i++) { + switch (message.alertStrings[i].fieldName) { + case 'alertText1': // subtleAlertText1 + { + this.set('content1', message.alertStrings[i].fieldText); + break; + } + case 'alertText2': // subtleAlertText2 + { + this.set('content2', message.alertStrings[i].fieldText); + break; + } + } + } + this.set('active', true); + this.set('timeout', message.duration ? message.duration : 30000); //default + // timeout + // defined + // for + // Alert + // popUp + clearTimeout(this.timer); + this.timer = setTimeout( + function () { + self.deactivate(self.reason, self.message); + }, this.timeout + ); + } + } +); diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index e90367887..5642b418d 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -156,6 +156,9 @@ FFW.UI = FFW.RPCObserver.create( onRPCRequest: function(request) { Em.Logger.log('FFW.UI.onRPCRequest'); if (this.validationCheck(request)) { + if (request.method === 'UI.Alert') { + request.method = 'UI.SubtleAlert'; // debug code 0242 + } switch (request.method) { case 'UI.ShowAppMenu': { @@ -190,6 +193,10 @@ FFW.UI = FFW.RPCObserver.create( }) break; } + case 'UI.SubtleAlert': + { + SDL.SDLModel.onUISubtleAlert(request.params, request.id); + } case 'UI.Show': { @@ -374,6 +381,9 @@ FFW.UI = FFW.RPCObserver.create( } else if (typeID === 26 && SDL.SliderView.active && (targetID === undefined || targetID === SDL.SliderView.cancelID)) { SDL.SliderView.deactivate(); + } else if (typeID === 64 && SDL.SubtleAlertPopUp.active + && (targetID === undefined || targetID === SDL.SubtleAlertPopUp.cancelID)) { + SDL.SubtleAlertPopUp.deactivate(); } else { this.sendError(SDL.SDLModel.data.resultCode.IGNORED, request.id, request.method, @@ -1580,8 +1590,10 @@ FFW.UI = FFW.RPCObserver.create( * id * @param {String} * method + * @param {Object} + * additional parameters to send with error */ - sendError: function(resultCode, id, method, message) { + sendError: function(resultCode, id, method, message, params) { Em.Logger.log('FFW.' + method + 'Response'); if (resultCode !== 0) { @@ -1597,6 +1609,11 @@ FFW.UI = FFW.RPCObserver.create( } } }; + + if (params) { + JSONMessage.error.data = Object.assign(JSONMessage.error.data, params); + } + this.sendMessage(JSONMessage); } }, @@ -1671,6 +1688,42 @@ FFW.UI = FFW.RPCObserver.create( } } }, + /** + * send response from onRPCRequest + * + * @param {Number} + * resultCode + * @param {Number} + * rpc id + * @param {String} + * info to send w response + * @param {Number} + * tryAgainTime + */ + subtleAlertResponse: function(resultCode, id, info, tryAgainTime) { + Em.Logger.log('FFW.UI.SubtleAlertResponse'); + switch (resultCode) { + case SDL.SDLModel.data.resultCode.WARNINGS: + case SDL.SDLModel.data.resultCode.SUCCESS: + { + if (SDL.TTSPopUp.active) { + SDL.TTSPopUp.DeactivateTTS(); + } + this.sendUIResult(resultCode, id, 'UI.SubtleAlert', info); + break; + } + case SDL.SDLModel.data.resultCode['ABORTED']: + { + this.sendError(resultCode, id, 'UI.SubtleAlert', 'SubtleAlert request aborted.'); + break; + } + case SDL.SDLModel.data.resultCode.REJECTED: + { + this.sendError(resultCode, id, 'UI.SubtleAlert', info, { tryAgainTime: tryAgainTime }); + break; + } + } + }, /** * send response from onRPCRequest * From 549cd477da915aa7f54f0c70619d840691faef76 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 8 Jul 2020 15:02:08 -0400 Subject: [PATCH 032/104] subtle alert implementation part2 --- app/controlls/Button.js | 11 ++++ app/view/sdl/SubtleAlertPopUp.js | 53 +++++++++-------- css/sdl.css | 99 ++++++++++++++++++++++++++++++++ ffw/UIRPC.js | 1 + index.html | 1 + 5 files changed, 141 insertions(+), 24 deletions(-) diff --git a/app/controlls/Button.js b/app/controlls/Button.js index 340f2c51b..353cc0b30 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -176,6 +176,17 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, '' ), + subtle: Em.Handlebars.compile( + '' + + '{{view.text}}' + ), + + subtleOverlay: Em.Handlebars.compile( + '' + + '' + + '{{view.text}}' + ), + rightText: Em.Handlebars.compile( '' + '{{view.text}}' diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js index 90037feb2..f8e57b33e 100644 --- a/app/view/sdl/SubtleAlertPopUp.js +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -41,8 +41,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( ], childViews: [ 'image', - 'message1', - 'message2', + 'messages', 'softbuttons' ], /** @@ -64,6 +63,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( image: Em.View.extend( { elementId: 'subtleAlertPopUpImage', + classNames: 'subtleAlertPopUpImageContainer', template: Ember.Handlebars.compile( ' + + From 02c7db4bff15da3bd90479727307e8cc9791e383 Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 30 Jul 2020 14:08:43 -0400 Subject: [PATCH 037/104] remove requirement of duration param --- app/controller/sdl/RPCController.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/controller/sdl/RPCController.js b/app/controller/sdl/RPCController.js index 65e8594b6..a3e87bf9f 100644 --- a/app/controller/sdl/RPCController.js +++ b/app/controller/sdl/RPCController.js @@ -1312,13 +1312,6 @@ SDL.RPCController = Em.Object.create( }; return this.resultStruct; } - if (params.duration == null) { - this.resultStruct = { - 'resultCode': SDL.SDLModel.data.resultCode.INVALID_DATA, - 'resultMessage': 'Parameter \'duration\' does not exist!' - }; - return this.resultStruct; - } if ('duration' in params && typeof params.duration != 'number') { this.resultStruct = { 'resultCode': SDL.SDLModel.data.resultCode.INVALID_DATA, From 39624c995146739a6ea0fde76fe4595dfa8e1946 Mon Sep 17 00:00:00 2001 From: Collin Date: Tue, 4 Aug 2020 10:18:11 -0400 Subject: [PATCH 038/104] Apply suggestions from code review Co-authored-by: Shobhit Adlakha --- app/view/sdl/SubtleAlertPopUp.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js index 358be0c9d..2ae7975fc 100644 --- a/app/view/sdl/SubtleAlertPopUp.js +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -79,7 +79,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( } }, /** - * Wagning image on Alert PopUp + * Warning image on Alert PopUp */ image: Em.View.extend( { @@ -96,7 +96,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( /** * @function imageUndefined * @param {Object} event - * @description action if an image undefined. + * @description action if an image is undefined. */ imageUndefined: function (event) { event.target.style.display = 'none'; @@ -106,7 +106,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( /** * @function imageLoaded * @param {Object} event - * @description action if an image loaded. + * @description action if an image is loaded. */ imageLoaded: function (event) { event.target.style.display = 'block'; From 59ab9e88cffc308c01d9104f75cc01434e76d40a Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 4 Aug 2020 10:57:52 -0400 Subject: [PATCH 039/104] subtle alert image fits inside alert container, subtle alert is blocked when alert maneuver pop up is active, alert maneuver now tracks notification end time, remove progressIndicator from subtle alert model --- app/model/sdl/Abstract/Model.js | 5 +++++ app/view/sdl/AlertManeuverPopUp.js | 3 +++ app/view/sdl/SubtleAlertPopUp.js | 7 +++---- css/sdl.css | 4 ++-- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 5a41eb3b3..612fb641b 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1172,6 +1172,11 @@ SDL.SDLModel = Em.Object.extend({ subtleAlertRequestId, 'another SubtleAlert is active', SDL.SubtleAlertPopUp.endTime - Date.now()); + } else if (SDL.AlertManeuverPopUp.activate) { + SDL.SDLController.subtleAlertResponse(SDL.SDLModel.data.resultCode.REJECTED, + subtleAlertRequestId, + 'an AlertManeuver popup is active', + SDL.AlertManeuverPopUp.endTime - Date.now()); } else { SDL.SubtleAlertPopUp.SubtleAlertActive(message, subtleAlertRequestId); } diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index e257bbab8..0374decfb 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -51,6 +51,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( content1: 'Title', content2: 'Text', activate: false, + endTime: null, timer: null, /** * Wagning image on Alert Maneuver PopUp @@ -170,12 +171,14 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( } this.set( 'activate', true ); + this.set('endTime', Date.now() + 5000); clearTimeout( this.timer ); var self = this; this.timer = setTimeout( function() { self.set( 'activate', false ); + this.set('endTime', null); FFW.Navigation.sendNavigationResult( SDL.SDLModel.data.resultCode.SUCCESS, message.id, diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js index 2ae7975fc..2fc0f9863 100644 --- a/app/view/sdl/SubtleAlertPopUp.js +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -60,7 +60,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( reason: '', message: undefined, /** - * When Alert is clicked, open the app that sent the alert + * When SubtleAlert is clicked, open the app that sent the alert */ onClick: function(event) { if (document.getElementById('SubtleAlertPopUp').contains(event.target)){ @@ -79,7 +79,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( } }, /** - * Warning image on Alert PopUp + * Warning image on Subtle Alert PopUp */ image: Em.View.extend( { @@ -180,7 +180,7 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( } ), /** - * @desc Function creates Soft Buttons on AlertPoUp + * @desc Function creates Soft Buttons on SubtleAlertPopUp * @param {Object} params */ addSoftButtons: function (params, appID) { @@ -230,7 +230,6 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( this.set('reason', 'timeout'); this.set('message', undefined); this.addSoftButtons(message.softButtons, message.appID); - this.set('progressIndicator', message.progressIndicator); this.set('appID', message.appID); this.set('icon', message.alertIcon ? message.alertIcon.value : "images/sdl/Warning.png"); for (var i = 0; i < message.alertStrings.length; i++) { diff --git a/css/sdl.css b/css/sdl.css index 65cde12c9..f207b18a5 100644 --- a/css/sdl.css +++ b/css/sdl.css @@ -1416,8 +1416,8 @@ } #SubtleAlertPopUp .subtleAlertPopUpImage { - max-width: 120px; - max-height: 120px; + max-width: 100px; + max-height: 100px; margin: auto; height: auto; width: auto; From a3a8cf3088e91f82d9685d6783f35a8fe66788c8 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 5 Aug 2020 10:13:07 -0400 Subject: [PATCH 040/104] copy context updates from alert to subtle alert --- app/controller/sdl/Abstract/Controller.js | 3 ++- app/model/sdl/Abstract/Model.js | 3 ++- app/view/sdl/SubtleAlertPopUp.js | 6 ++++++ ffw/UIRPC.js | 9 ++++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index b6ce195c3..aaf4959f9 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -258,7 +258,7 @@ SDL.SDLController = Em.Object.extend( if (SDL.SDLModel.data.VRActive) { return 'VRSESSION'; } - if (SDL.AlertPopUp.active) { + if (SDL.AlertPopUp.active || SDL.SubtleAlertPopUp.active) { return 'ALERT'; } if (SDL.SliderView.active || @@ -278,6 +278,7 @@ SDL.SDLController = Em.Object.extend( 'SDL.SDLModel.data.AudioPassThruState', 'SDL.SDLModel.data.VRActive', 'SDL.AlertPopUp.active', + 'SDL.SubtleAlertPopUp.active', 'SDL.States.info.nonMedia.active', 'SDL.States.media.sdlmedia.active', 'SDL.States.navigationApp.baseNavigation.active', diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 612fb641b..50a31ab3e 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1151,7 +1151,6 @@ SDL.SDLModel = Em.Object.extend({ * subtleAlertRequestId Id of current handled request */ onUISubtleAlert: function(message, subtleAlertRequestId) { - if (SDL.AlertPopUp.active) { SDL.SDLController.subtleAlertResponse(SDL.SDLModel.data.resultCode.REJECTED, subtleAlertRequestId, @@ -1179,7 +1178,9 @@ SDL.SDLModel = Em.Object.extend({ SDL.AlertManeuverPopUp.endTime - Date.now()); } else { SDL.SubtleAlertPopUp.SubtleAlertActive(message, subtleAlertRequestId); + return true; } + return false; }, /** diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js index 2fc0f9863..6bc969ee7 100644 --- a/app/view/sdl/SubtleAlertPopUp.js +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -161,6 +161,12 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( ); } window.removeEventListener('click', this.onClick); + SDL.SDLController.onSystemContextChange(); + SDL.SDLModel.data.registeredApps.forEach(app => { + app.activeWindows.forEach(widget => { + SDL.SDLController.onSystemContextChange(app.appID, widget.windowID); + }); + }); }, /** * Container for softbuttons diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 0e5c8e3d5..5c7fcc913 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -192,7 +192,14 @@ FFW.UI = FFW.RPCObserver.create( } case 'UI.SubtleAlert': { - SDL.SDLModel.onUISubtleAlert(request.params, request.id); + if (SDL.SDLModel.onUISubtleAlert(request.params, request.id)) { + SDL.SDLController.onSystemContextChange(request.params.appID); + } + SDL.SDLModel.data.registeredApps.forEach(app => { + app.activeWindows.forEach(widget => { + SDL.SDLController.onSystemContextChange(app.appID, widget.windowID); + }) + }) break; } case 'UI.Show': From 344a5e8102c6ed83f2e85bd396e6067278356666 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Thu, 6 Aug 2020 19:01:16 +0300 Subject: [PATCH 041/104] Feature/Refactor Fuel Information Related Vehicle Data (#318) * Update fuelRange structure with new values * Update app/model/sdl/VehicleInfoModel.js Co-authored-by: Shobhit Adlakha Co-authored-by: Ira Lytvynenko (GitHub) Co-authored-by: Shobhit Adlakha --- app/model/sdl/VehicleInfoModel.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index 3eec53096..dc37b5de5 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -210,7 +210,11 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'fuelRange': [ { 'type':'GASOLINE', - 'range': 400 + 'range': 400, + 'level': 10, + 'levelState': 'NORMAL', + 'capacity': 100, + 'capacityUnit': 'LITERS' } ], 'odometer': 23, From edd1d59a71bd4c176dd56e228086ea21247e3990 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Thu, 6 Aug 2020 13:42:36 -0400 Subject: [PATCH 042/104] Add new structure StabilityControlsStatus into VehicleData (#295) --- app/model/sdl/VehicleInfoModel.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index dc37b5de5..27b383166 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -135,7 +135,8 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'turnSignal': 'VEHICLEDATA_TURNSIGNAL', 'tirePressureValue': 'VEHICLEDATA_TIREPRESSURE_VALUE', 'tpms': 'VEHICLEDATA_TPMS', - 'cloudAppVehicleID': 'VEHICLEDATA_CLOUDAPPVEHICLEID' + 'cloudAppVehicleID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', + 'stabilityControlsStatus': 'VEHICLEDATA_STABILITYCONTROLSSTATUS' }, /** * Stored VehicleInfo Data @@ -174,6 +175,10 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'turnSignal': 'OFF', 'prndl': 'PARK', 'electronicParkBrakeStatus': 'OPEN', + 'stabilityControlsStatus': { + 'escSystem': 'OFF', + 'trailerSwayControl': 'OFF' + }, 'tirePressure': { 'pressureTelltale': 'OFF', 'leftFront': { From 567fb53ff74c6cfdc33ab600006494ef386e8b0a Mon Sep 17 00:00:00 2001 From: "Mykola Korniichuk (GitHub)" <42380041+mkorniichuk@users.noreply.github.com> Date: Thu, 6 Aug 2020 23:45:29 +0300 Subject: [PATCH 043/104] Update vehicle data with gearStatus (#367) --- app/model/sdl/VehicleInfoModel.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index 27b383166..dd1967c36 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -51,7 +51,11 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'THIRD', 'FOURTH', 'FIFTH', - 'SIXTH' + 'SIXTH', + 'SEVENTH', + 'EIGHTH', + 'NINTH', + 'TENTH' ], /** * Data changed in Odometr Input in VehicleInfo popUp @@ -112,6 +116,7 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'externalTemperature': 'VEHICLEDATA_EXTERNTEMP', 'turnSignal': 'VEHICLEDATA_TURNSIGNAL', 'vin': 'VEHICLEDATA_VIN', + 'gearStatus': 'VEHICLEDATA_GEARSTATUS', 'prndl': 'VEHICLEDATA_PRNDL', 'tirePressure': 'VEHICLEDATA_TIREPRESSURE', 'odometer': 'VEHICLEDATA_ODOMETER', @@ -174,6 +179,11 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'vin': '52-452-52-752', 'turnSignal': 'OFF', 'prndl': 'PARK', + 'gearStatus': { + 'userSelectedGear': 'DRIVE', + 'actualGear': 'PARK', + 'transmissionType': 'AUTOMATIC' + }, 'electronicParkBrakeStatus': 'OPEN', 'stabilityControlsStatus': { 'escSystem': 'OFF', From 305a2de69b2595b626302564b68037687e45e5e3 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Thu, 6 Aug 2020 23:57:11 +0300 Subject: [PATCH 044/104] Fix showing all iframes at once (#39) * Fix showing all iframes at once * fixup! Fix showing all iframes at once * fixup! Fix showing all iframes at once * fixup! Fix showing all iframes at once * fixup! Fix showing all iframes at once * fixup! Fix showing all iframes at once * Fix changing view to AudioView (#42) * Fix changing view to AudioView * fixup! Fix changing view to AudioView * fixup! Fix changing view to AudioView Co-authored-by: YarikMamykin Co-authored-by: YarikMamykin --- app/StateManager.js | 13 +++++------ app/controller/InfoController.js | 3 ++- app/controller/sdl/Abstract/Controller.js | 27 ++++++++++++++++++++++- app/model/sdl/RModel.js | 5 +++++ 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/app/StateManager.js b/app/StateManager.js index 6f75bf662..3000bf12c 100644 --- a/app/StateManager.js +++ b/app/StateManager.js @@ -479,19 +479,16 @@ var StateManager = Em.StateManager.extend( { modelBinding: 'SDL.RCModulesController', enter: function() { - if (SDL.SDLModel.data.mediaPlayerActive) { - SDL.SDLController.onEventChanged('player', false); - this.model.currentAudioModel.deactivateCD(); - this.model.currentAudioModel.deactivateUSB(); - this.model.currentAudioModel.deactivateRadio(); - } - this.model.currentAudioModel.set('activeState', SDL.States.nextState); this._super(); + SDL.SDLController.onEventChanged('player', false); + SDL.SDLController.onEventChanged(this.name, true); + SDL.SDLController.showWebViewApp(SDL.SDLController.model.appID); }, exit: function() { this._super(); - SDL.SDLModel.data.stateLimited = SDL.SDLController.model.appID; + SDL.SDLController.onEventChanged(this.name, false); SDL.SDLModel.data.set('limitedExist', false); + SDL.SDLController.hideWebApps(); SDL.SDLController.deactivateApp(); } } diff --git a/app/controller/InfoController.js b/app/controller/InfoController.js index cb9c5518a..f43963d7d 100644 --- a/app/controller/InfoController.js +++ b/app/controller/InfoController.js @@ -335,7 +335,8 @@ SDL.InfoController = Em.Object.create( let web_app_frame = document.createElement("iframe"); web_app_frame.name = frame_name; web_app_frame.id = frame_name; - web_app_frame.className = "WebEngineFrame"; + web_app_frame.className = 'WebEngineFrame'; + web_app_frame.hidden = false; const web_engine_view = document.getElementById("webEngineView"); if (web_engine_view) { diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 1a0e1f607..178326f2c 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1093,6 +1093,10 @@ SDL.SDLController = Em.Object.extend( SDL.PopUp.create().appendTo('body').popupActivate(message); } SDL.InfoAppsView.showAppList(); + + params.applications.forEach(appRecord => { + SDL.SDLModel.appIDtoPolicyAppIDMapping[appRecord.appID] = appRecord.policyAppID; + }); }, /** * SDL Driver Distraction ON/OFF switcher @@ -1632,6 +1636,27 @@ SDL.SDLController = Em.Object.extend( frames[i].style.pointerEvents = "none"; } } - } + }, + + /** + * @function hideWebApps + * @description Makes all web application view disabled + */ + hideWebApps: function() { + for(var key in SDL.SDLModel.webApplicationFramesMap) { + SDL.SDLModel.webApplicationFramesMap[key].hidden = true; + } + }, + + /** + * @function showWebViewApp + * @param {Number} appID + * @description Activates web view for application specified by appID + */ + showWebViewApp: function(appID) { + this.hideWebApps(); + let policyAppID = SDL.SDLModel.appIDtoPolicyAppIDMapping[appID]; + SDL.SDLModel.webApplicationFramesMap[policyAppID].hidden = false; + }, } ); diff --git a/app/model/sdl/RModel.js b/app/model/sdl/RModel.js index 188aa26f6..2a2b07bf8 100644 --- a/app/model/sdl/RModel.js +++ b/app/model/sdl/RModel.js @@ -61,6 +61,11 @@ SDL.RModel = SDL.SDLModel.extend({ */ webApplicationFramesMap: {}, + /** + * Map of app id and corresponding policy app ids + */ + appIDtoPolicyAppIDMapping: {}, + /** * Current drivers device flag * From 9b553b6adbc98df13730c9f273d158fa9e690f0f Mon Sep 17 00:00:00 2001 From: JackLivio Date: Fri, 7 Aug 2020 08:58:21 -0700 Subject: [PATCH 045/104] Implement additional submenus and driver distraction limits (#383) * Implement additional submenus and driver distraction limits * Fix nested submenu back button * Close menu after submenu command * Fix submenu caption * Fix switch to settings view from submenu * Fix deleteSubmenu logic --- app/controller/sdl/Abstract/Controller.js | 10 ++++- app/controller/sdl/RController.js | 5 ++- app/model/sdl/Abstract/AppModel.js | 49 ++++++++++++++++------- app/view/sdl/shared/optionsView.js | 40 ++++++++++++++++-- capabilities/systemCapabilities.js | 4 ++ ffw/UIRPC.js | 4 ++ 6 files changed, 90 insertions(+), 22 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 5364fc12d..4bee64a35 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -110,6 +110,7 @@ SDL.SDLController = Em.Object.extend( } } else { FFW.UI.onCommand(element.commandID, this.model.appID); + this.model.set('currentSubMenuId', 'top'); SDL.OptionsView.deactivate(); } }, @@ -135,7 +136,12 @@ SDL.SDLController = Em.Object.extend( * @param id {Number} */ onSubMenu: function(id) { - this.model.set('currentSubMenuId', id); + if (id >= 0 && id != 'top') { + this.model.set('currentMenuDepth', this.model.currentMenuDepth + 1); + } else { + this.model.set('currentMenuDepth', 0); + } + this.model.set('currentSubMenuId', id); }, /** * Comparison function for sort array of buttons in options list by @@ -214,10 +220,10 @@ SDL.SDLController = Em.Object.extend( * StateManager */ deactivateApp: function() { + SDL.SDLController.onSubMenu('top'); if (this.model) { SDL.SDLModel.onDeactivateApp(SDL.States.nextState, this.model.appID); } - SDL.SDLController.onSubMenu('top'); SDL.SDLController.model.set('tbtActivate', false); this.set('model', null); }, diff --git a/app/controller/sdl/RController.js b/app/controller/sdl/RController.js index 2dcbc5672..30e9820cf 100644 --- a/app/controller/sdl/RController.js +++ b/app/controller/sdl/RController.js @@ -476,13 +476,16 @@ SDL.RController = SDL.SDLController.extend( // if subMenu // activate driver destruction if necessary - if (SDL.SDLModel.data.driverDistractionState) { + var allowedDepth = SDL.systemCapabilities.driverDistractionCapability.subMenuDepth-1; + var activeDepth = SDL.SDLController.model.get('currentMenuDepth'); + if (SDL.SDLModel.data.driverDistractionState && activeDepth >= allowedDepth) { SDL.DriverDistraction.activate(); } else { this.onSubMenu(element.menuID); } } else { FFW.UI.onCommand(element.commandID, this.model.appID); + this.model.set('currentSubMenuId', 'top'); SDL.OptionsView.deactivate(); } }, diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 89bc620f2..28195e34e 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -390,21 +390,33 @@ SDL.ABSAppModel = Em.Object.extend( * @type {Number} */ currentSubMenuId: 'top', + + /** + * Count of submenu depth for DD tracking + * + * @type {Number} + */ + currentMenuDepth: 0, /** * Return current submenu name * * @return {String} */ currentSubMenuLabel: function() { - - //Param "top" is Top level menu index - var submenu, commands = this.commandsList['top']; - for (var i = 0; i < commands.length; i++) { - if (commands[i].menuID == this.currentSubMenuId) { - submenu = commands[i].name; + var commandsList = this.commandsList; + var findMenuName = (commands, menuID) => { + for (id in commands) { + var subMenuCommands = commands[id]; + for (element of subMenuCommands) { + if (element.menuID === menuID) { + return element.name; + } + } } + return 'Options'; } - return this.get('currentSubMenuId') != 'top' ? submenu : 'Options'; + return this.get('currentSubMenuId') != 'top' ? + findMenuName(commandsList, this.currentSubMenuId) : 'Options'; }.property('this.currentSubMenuId'), /** * Interaction chooses data @@ -583,7 +595,7 @@ SDL.ABSAppModel = Em.Object.extend( addSubMenu: function(request) { // parentID is equal to 'top' cause Top level menu ID - var parentID = 'top'; + var parentID = request.params.menuParams.parentID ? request.params.menuParams.parentID : 'top'; var commands = this.get('commandsList.' + parentID); // Magic number is limit of 1000 commands added on one menu if (commands.length <= 999) { @@ -592,7 +604,7 @@ SDL.ABSAppModel = Em.Object.extend( menuID: request.params.menuID, name: request.params.menuParams.menuName ? request.params.menuParams.menuName : '', - parent: 0, + parent: parentID, position: request.params.menuParams.position ? request.params.menuParams.position : 0, icon: request.params.menuIcon ? request.params.menuIcon.value : null @@ -620,13 +632,20 @@ SDL.ABSAppModel = Em.Object.extend( * @param {Number} */ deleteSubMenu: function(menuID) { - if (this.commandsList['top'].filterProperty('commandID', menuID)) { - this.get('commandsList.top').removeObjects( - this.get('commandsList.top').filterProperty('menuID', menuID) - ); - //delete(this.commandsList[menuID]); + var commandsList = this.commandsList; + for (id in commandsList) { + var filteredObjects = commandsList[id].filterProperty('menuID', menuID); + if (filteredObjects.length > 0) { + commandsList[id].removeObjects( + filteredObjects + ); + if (menuID in commandsList) { + delete(commandsList[menuID]) + } + return SDL.SDLModel.data.resultCode.SUCCESS; + } } - return SDL.SDLModel.data.resultCode.SUCCESS; + return SDL.SDLModel.data.resultCode.INVALID_ID; }, /** * SDL UI CreateInteraction response handeler push set of commands to diff --git a/app/view/sdl/shared/optionsView.js b/app/view/sdl/shared/optionsView.js index 885e49bef..62d2171ca 100644 --- a/app/view/sdl/shared/optionsView.js +++ b/app/view/sdl/shared/optionsView.js @@ -56,9 +56,23 @@ SDL.OptionsView = SDL.SDLAbstractView.create( // Extend deactivate window deactivate: function() { if (SDL.SDLController.model) { - if (SDL.SDLController.model.get('currentSubMenuId') >= 0 && - !SDL.SDLController.model.get('subMenuInitFromApp')) { - SDL.SDLController.onSubMenu('top'); + var currentSubMenuID = SDL.SDLController.model.get('currentSubMenuId'); + if (currentSubMenuID != 'top' && + currentSubMenuID >= 0 && + !SDL.SDLController.model.get('subMenuInitFromApp')) { + var commandsList = SDL.SDLController.model.get('commandsList'); + var findParentID = (commands, menuID) => { + for (id in commands) { + var subMenuCommands = commands[id]; + for (element of subMenuCommands) { + if (element.menuID === menuID) { + return element.parent; + } + } + } + return 'top'; + } + SDL.SDLController.onSubMenu(findParentID(commandsList, currentSubMenuID)); } else { SDL.SDLController.onSubMenu('top'); this._super(); @@ -94,7 +108,12 @@ SDL.OptionsView = SDL.SDLAbstractView.create( len, template; this.items = []; - len = commands.length; + if (SDL.SDLModel.data.driverDistractionState) { + var ddMaxLength = SDL.systemCapabilities.driverDistractionCapability.menuLength; + len = (ddMaxLength > commands.length) ? commands.length : ddMaxLength; + } else { + len = commands.length; + } for (i = 0; i < len; i++) { if (commands[i].menuID >= 0) { template = 'arrow'; @@ -121,6 +140,19 @@ SDL.OptionsView = SDL.SDLAbstractView.create( } ); } + if (commands.length !== len) { + this.items.push( + { + type: SDL.Button, + params: { + templateName: "text", + text: "Some Menu Items Are Hidden", + onDown: false, + disabled: true + } + } + ); + } this.list.refresh(); } }.observes( diff --git a/capabilities/systemCapabilities.js b/capabilities/systemCapabilities.js index b2f59da8c..fb0040fd1 100644 --- a/capabilities/systemCapabilities.js +++ b/capabilities/systemCapabilities.js @@ -65,5 +65,9 @@ SDL.systemCapabilities = diagonalScreenSize: 8, pixelPerInch: 96, scale: 1 + }, + driverDistractionCapability: { + menuLength: 10, + subMenuDepth: 2 } } diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index da83c7cd9..5bdc1a515 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1749,6 +1749,8 @@ FFW.UI = FFW.RPCObserver.create( */ onCommand: function(commandID, appID) { Em.Logger.log('FFW.UI.onCommand'); + var allowedDepth = SDL.systemCapabilities.driverDistractionCapability.subMenuDepth-1; + var activeDepth = SDL.SDLController.model.get('currentMenuDepth') var JSONMessage = { 'jsonrpc': '2.0', 'method': 'UI.OnCommand', @@ -1893,6 +1895,8 @@ FFW.UI = FFW.RPCObserver.create( */ OnSystemContext: function(systemContextValue, appID, windowID) { Em.Logger.log('FFW.UI.OnSystemContext'); + var allowedDepth = SDL.systemCapabilities.driverDistractionCapability.subMenuDepth-1; + var activeDepth = SDL.SDLController.model.get('currentMenuDepth') // send repsonse var JSONMessage = { 'jsonrpc': '2.0', From 92274c3178d14dd023c169494f87210a2b239939 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Fri, 7 Aug 2020 23:56:06 +0300 Subject: [PATCH 046/104] Add window status data type to vehicle data structure (#363) Co-authored-by: YarikMamykin Co-authored-by: Andrii Kalinich --- app/controller/sdl/RCModulesController.js | 18 ++++++++++++++++++ app/model/sdl/VehicleInfoModel.js | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/controller/sdl/RCModulesController.js b/app/controller/sdl/RCModulesController.js index 96a031da9..7bd0d9cd0 100644 --- a/app/controller/sdl/RCModulesController.js +++ b/app/controller/sdl/RCModulesController.js @@ -310,12 +310,30 @@ SDL.RCModulesController = Em.Object.create({ } var seatLocationNames = []; + var windowStatus = []; + const rightMostSeatIndex = SDL.VehicleModuleCoverageController.getVehicleMaxIndex(vehicleRepresentation, 'col'); + const leftMostSeatIndex = 0; + vehicleRepresentation.forEach(seat_location => { var location_name = SDL.VehicleModuleCoverageController.getLocationName(seat_location); seatLocationNames.push(location_name); + + if (vehicleRepresentation[rightMostSeatIndex].col === seat_location.col || + leftMostSeatIndex === seat_location.col) { + var location_window_status = { + "location": seat_location, + "state": { + "approximatePosition": 0, + "deviation": 0 + } + }; + windowStatus.push(location_window_status); + } }); + SDL.SDLVehicleInfoModel.vehicleData.windowStatus = windowStatus; + var self = this; var coverageSettings = SDL.VehicleModuleCoverageController.getCoverageSettings(); Object.keys(coverageSettings).forEach(module_type => { diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index dd1967c36..1051097a0 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -141,7 +141,8 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'tirePressureValue': 'VEHICLEDATA_TIREPRESSURE_VALUE', 'tpms': 'VEHICLEDATA_TPMS', 'cloudAppVehicleID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', - 'stabilityControlsStatus': 'VEHICLEDATA_STABILITYCONTROLSSTATUS' + 'stabilityControlsStatus': 'VEHICLEDATA_STABILITYCONTROLSSTATUS', + 'windowStatus': 'VEHICLEDATA_WINDOWSTATUS' }, /** * Stored VehicleInfo Data From 29a052c525d101cc60914e0e2edf86720d128c4c Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Mon, 10 Aug 2020 17:28:43 +0300 Subject: [PATCH 047/104] Add handsOffSteering data type (#364) Co-authored-by: YarikMamykin Co-authored-by: Andrii Kalinich --- app/model/sdl/VehicleInfoModel.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index 1051097a0..51433af97 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -141,6 +141,7 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'tirePressureValue': 'VEHICLEDATA_TIREPRESSURE_VALUE', 'tpms': 'VEHICLEDATA_TPMS', 'cloudAppVehicleID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', + 'handsOffSteering': 'VEHICLEDATA_HANDSOFFSTEERING', 'stabilityControlsStatus': 'VEHICLEDATA_STABILITYCONTROLSSTATUS', 'windowStatus': 'VEHICLEDATA_WINDOWSTATUS' }, @@ -331,7 +332,8 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'displayResolution': { 'width': 800, 'height': 480 - } + }, + 'handsOffSteering': false // // 'avgFuelEconomy': 0.1, // 'batteryVoltage': 12.5, From e4c61683dccdd4761e0abbe97ced9caef76a3dd7 Mon Sep 17 00:00:00 2001 From: collin Date: Wed, 12 Aug 2020 17:19:38 -0400 Subject: [PATCH 048/104] use else if in mutually exclusive cases --- app/controller/sdl/Abstract/Controller.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index aaf4959f9..12be79e0f 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -681,18 +681,14 @@ SDL.SDLController = Em.Object.extend( SDL.AlertPopUp.deactivate(); } else if (methodName === 'UI.SubtleAlert') { SDL.SubtleAlertPopUp.deactivate(); - } - if (methodName == 'UI.PerformAudioPassThru') { + } else if (methodName == 'UI.PerformAudioPassThru') { SDL.AudioPassThruPopUp.deactivate(); this.performAudioPassThruResponse(SDL.SDLModel.data.resultCode.SUCCESS); - } - if (methodName == 'UI.PerformInteraction') { + } else if (methodName == 'UI.PerformInteraction') { SDL.InteractionChoicesView.deactivate('ABORTED'); - } - if (methodName == 'UI.ScrollableMessage') { + } else if (methodName == 'UI.ScrollableMessage') { SDL.ScrollableMessage.deactivate(true); - } - if (methodName == 'UI.Slider') { + } else if (methodName == 'UI.Slider') { SDL.SliderView.deactivate(true); } // if (SDL.VRHelpListView.active) { From 6ea6956bf1ab41142fbf9008d4f643e1f85d98e3 Mon Sep 17 00:00:00 2001 From: Shobhit Adlakha Date: Mon, 17 Aug 2020 09:52:57 -0400 Subject: [PATCH 049/104] Change default character set to UTF_8 (#384) --- app/model/sdl/Abstract/data.js | 56 +++---- capabilities/display_capabilities.js | 224 +++++++++++++-------------- ffw/UIRPC.js | 116 +++++++------- 3 files changed, 198 insertions(+), 198 deletions(-) diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index 708b9a73a..48b297a7a 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -705,163 +705,163 @@ SDL.SDLModelData = Em.Object.create( "textFields": [ { "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "statusBar", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaClock", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaTrack", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { "name": "alertText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "initialInteractionText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "ETA", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "totalDistance", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderHeader", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderFooter", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "secondaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "tertiaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationDescription", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "addressLines", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "phoneNumber", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 } @@ -1186,7 +1186,7 @@ SDL.SDLModelData = Em.Object.create( "menuLayoutsAvailable": ["LIST"], "textFields": [{ "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }], diff --git a/capabilities/display_capabilities.js b/capabilities/display_capabilities.js index 902f6c6dd..96510e56d 100644 --- a/capabilities/display_capabilities.js +++ b/capabilities/display_capabilities.js @@ -38,163 +38,163 @@ SDL.templateCapabilities = { "displayName": "SDL_HMI", "textFields": [{ "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "statusBar", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaClock", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaTrack", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { "name": "alertText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "initialInteractionText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "ETA", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "totalDistance", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderHeader", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderFooter", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "secondaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "tertiaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationDescription", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "addressLines", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "phoneNumber", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 } @@ -473,163 +473,163 @@ SDL.templateCapabilities = { "displayName": "SDL_HMI", "textFields": [{ "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "statusBar", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaClock", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaTrack", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { "name": "alertText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "initialInteractionText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "ETA", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "totalDistance", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderHeader", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderFooter", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "secondaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "tertiaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationDescription", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "addressLines", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "phoneNumber", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 } @@ -903,175 +903,175 @@ SDL.templateCapabilities = { "displayName": "SDL_HMI", "textFields": [{ "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField4", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "statusBar", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaClock", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaTrack", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { "name": "alertText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "initialInteractionText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "ETA", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "totalDistance", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderHeader", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderFooter", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "secondaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "tertiaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationDescription", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "addressLines", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "phoneNumber", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 } @@ -1345,175 +1345,175 @@ SDL.templateCapabilities = { "displayName": "SDL_HMI", "textFields": [{ "name": "mainField1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mainField4", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "statusBar", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaClock", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "mediaTrack", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { "name": "alertText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "alertText3", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "scrollableMessageBody", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "initialInteractionText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "navigationText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "ETA", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "totalDistance", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText1", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "audioPassThruDisplayText2", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderHeader", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "sliderFooter", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "secondaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "tertiaryText", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "menuTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationName", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "locationDescription", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "addressLines", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 }, { "name": "phoneNumber", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 500, "rows": 1 } diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 5bdc1a515..baa5dd0d8 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -637,175 +637,175 @@ FFW.UI = FFW.RPCObserver.create( 'textFields': [ { 'name': 'mainField1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField3', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField4', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'statusBar', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mediaClock', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mediaTrack', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { 'name': 'alertText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'alertText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'alertText3', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'scrollableMessageBody', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'initialInteractionText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'navigationText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'navigationText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'ETA', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'totalDistance', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'audioPassThruDisplayText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'audioPassThruDisplayText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'sliderHeader', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'sliderFooter', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'menuName', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'secondaryText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'tertiaryText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'menuTitle', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'locationName', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'locationDescription', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'addressLines', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'phoneNumber', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 } @@ -1001,175 +1001,175 @@ FFW.UI = FFW.RPCObserver.create( "textFields": [ { 'name': 'mainField1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField3', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mainField4', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'statusBar', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mediaClock', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'mediaTrack', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { "name": "templateTitle", - "characterSet": "TYPE2SET", + "characterSet": "UTF_8", "width": 100, "rows": 1 }, { 'name': 'alertText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'alertText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'alertText3', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'scrollableMessageBody', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'initialInteractionText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'navigationText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'navigationText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'ETA', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'totalDistance', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'audioPassThruDisplayText1', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'audioPassThruDisplayText2', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'sliderHeader', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'sliderFooter', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'menuName', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'secondaryText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'tertiaryText', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'menuTitle', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'locationName', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'locationDescription', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'addressLines', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 }, { 'name': 'phoneNumber', - 'characterSet': 'TYPE2SET', + 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 } From 855347d3ec07730c7dcb90985378cf222346cfa4 Mon Sep 17 00:00:00 2001 From: JackLivio Date: Thu, 20 Aug 2020 09:45:36 -0700 Subject: [PATCH 050/104] Dynamic Menu and Image loading (#385) * Implement additional submenus and driver distraction limits * Add dynamic menu updates and image loading * Update image onerror handler * Fix img error handling in SDL.Button * Address comments * Fix merge conflict * Fix arrow submenu * Update regex to only remove ?time characters * Fix double sending * Check for duplicate --- app/controlls/Button.js | 30 +++++++++++++++++---- app/model/sdl/Abstract/AppModel.js | 9 +++++++ app/model/sdl/Abstract/data.js | 6 ++++- app/view/sdl/shared/optionsView.js | 17 +++++++----- app/view/sdl/shared/turnByTurnView.js | 4 +-- ffw/UIRPC.js | 39 +++++++++++++++++++++++++++ 6 files changed, 91 insertions(+), 14 deletions(-) diff --git a/app/controlls/Button.js b/app/controlls/Button.js index 353cc0b30..707b1b0bc 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -163,6 +163,21 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, ); }, + didInsertElement: function(){ + // $(this) wraps the ember view in a jquery object. + // `icon` is a view property defined above. + if ($(this)[0].icon) { + // this.$('img') returns a jquery instance of + // the img element inside of the SDL.Button + this.$('img').on('error', function(event) { + if(SDL.SDLController.model && SDL.SDLController.model.appID) { + var regex = /\?(.*)/g; + FFW.UI.OnUpdateFile(SDL.SDLController.model.appID, $(this)[0].icon.replace(regex, "")) + } + }.bind(this)); + } + }, + // component default template defaultTemplate: Em.Handlebars.compile( '' + @@ -173,7 +188,8 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, text: Em.Handlebars.compile('{{view.text}}'), icon: Em.Handlebars.compile( - '' + '' ), subtle: Em.Handlebars.compile( @@ -188,23 +204,27 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, ), rightText: Em.Handlebars.compile( - '' + + '' + '{{view.text}}' ), rightTextOverLay: Em.Handlebars.compile( '' + - '' + + '' + '{{view.text}}' ), arrow: Em.Handlebars.compile( - '' + + '' + '{{view.text}}' + '' ), rightIcon: Em.Handlebars.compile( - '' + + '' + '{{view.text}}' + '' ) diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 28195e34e..b66202f50 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -593,6 +593,15 @@ SDL.ABSAppModel = Em.Object.extend( * @param {Object} */ addSubMenu: function(request) { + // Check for duplicate submenu + if (request.params.menuID in this.commandsList) { + FFW.UI.sendError( + SDL.SDLModel.data.resultCode.INVALID_ID, request.id, + request.method, + 'Submenu ID already exists' + ); + return; + } // parentID is equal to 'top' cause Top level menu ID var parentID = request.params.menuParams.parentID ? request.params.menuParams.parentID : 'top'; diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index 48b297a7a..3be33206e 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -1164,7 +1164,11 @@ SDL.SDLModelData = Em.Object.create( "upDownAvailable": true, "imageSupported": true, "textSupported": true - }] + }], + "dynamicUpdateCapabilities": { + "supportedDynamicImageFieldNames": ["subMenuIcon", "menuIcon"], + "supportsDynamicSubMenus": true + } }] }], } diff --git a/app/view/sdl/shared/optionsView.js b/app/view/sdl/shared/optionsView.js index 62d2171ca..71f11a77d 100644 --- a/app/view/sdl/shared/optionsView.js +++ b/app/view/sdl/shared/optionsView.js @@ -104,6 +104,7 @@ SDL.OptionsView = SDL.SDLAbstractView.create( refreshItems: function() { if (SDL.SDLController.model) { var commands = SDL.SDLController.model.get('currentCommandsList'), + allMenuItems = SDL.SDLController.model.get('commandsList'), i, len, template; @@ -115,13 +116,18 @@ SDL.OptionsView = SDL.SDLAbstractView.create( len = commands.length; } for (i = 0; i < len; i++) { - if (commands[i].menuID >= 0) { + var menuID = commands[i].menuID; + if (menuID && menuID >= 0) { + if (allMenuItems[menuID].length === 0) { + // Notify mobile to update submenu + FFW.UI.OnUpdateSubMenu(SDL.SDLController.model.appID, menuID); + } template = 'arrow'; - }else if(commands[i].isTemplate){ + } else if (commands[i].isTemplate){ template = commands[i].isTemplate ? 'rightTextOverLay' : 'rightText'; - }else { + } else { template = commands[i].icon ? 'rightText' : 'text'; } this.items.push( @@ -131,7 +137,7 @@ SDL.OptionsView = SDL.SDLAbstractView.create( templateName: template, text: commands[i].name, commandID: commands[i].commandID, - menuID: commands[i].menuID, + menuID: menuID, icon: commands[i].icon, target: 'SDL.SDLController', action: 'onCommand', @@ -156,8 +162,7 @@ SDL.OptionsView = SDL.SDLAbstractView.create( this.list.refresh(); } }.observes( - 'SDL.SDLController.model.currentSubMenuId', - 'SDL.SDLController.model.currentCommandsList.@each' + 'SDL.SDLController.model.currentSubMenuId' ) } ) diff --git a/app/view/sdl/shared/turnByTurnView.js b/app/view/sdl/shared/turnByTurnView.js index 26fea3415..2d9ca826d 100644 --- a/app/view/sdl/shared/turnByTurnView.js +++ b/app/view/sdl/shared/turnByTurnView.js @@ -196,7 +196,7 @@ SDL.TurnByTurnView = SDL.SDLAbstractView.create( if (this._parentView != null && this._parentView.turnIcon) { return this._parentView.turnIcon; } else { - return ''; + return null; } }.property('this.parentView.turnIcon') } @@ -213,7 +213,7 @@ SDL.TurnByTurnView = SDL.SDLAbstractView.create( if (null!=this._parentView && this._parentView.nextTurnIcon) { return this._parentView.nextTurnIcon; } else { - return ''; + return null; } }.property('this.parentView.nextTurnIcon') } diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 43234f1bd..619abd363 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -2042,6 +2042,45 @@ FFW.UI = FFW.RPCObserver.create( } }; this.sendMessage(JSONMessage); + }, + /** + * Callback for requesting images from mobile application + * + * @param {integer} + * appID + * @param {string} + * fileName + */ + OnUpdateFile: function(appID, fileName) { + var JSONMessage = { + 'jsonrpc': '2.0', + 'method': 'UI.OnUpdateFile', + 'params': { + 'appID': appID, + 'fileName': fileName + } + }; + this.sendMessage(JSONMessage); + }, + /** + * Callback for requesting submenu contents from mobile application + * + * @param {integer} + * appID + * @param {integer} + * menuID + */ + OnUpdateSubMenu: function(appID, menuID) { + var JSONMessage = { + 'jsonrpc': '2.0', + 'method': 'UI.OnUpdateSubMenu', + 'params': { + 'appID': appID, + 'menuID': menuID, + 'updateSubCells': true + } + }; + this.sendMessage(JSONMessage); } } ); From 008f424d83104fe6cbe5c829b158347d2aa6d693 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 4 Sep 2020 12:15:45 -0400 Subject: [PATCH 051/104] Feature/sdl 0190 resumption data error handling (#394) * Add implementation `resumption data error handling` on the HMI * Change Global RPC processing For global RPC, the ability to respond with different resultCodes to different RPC was added. The answers are added to the queue and then subtracted for each subsequent requests. * fixed HMI sends UI.SetGlobalProperties_TTS.SetGlobalProperties_responses_with_empty_info_message * Fix RPC settings icon style * Fix result code customization for SubscribeVD Was added result code override if user specified custom code and do not subscribe to VD if code is negative * Add CreateWindow result code customization * Add DO_NOT_RESPOND support * Fix undefined result code for subscriptions The issue was that combobox are being filled with result codes in the later initialization. As a result, value bindings may set variable to undefined if result codes list is empty. To resolve that issue, initial element of SUCCESS has been added to the list before it is updated. * Add more successful result codes * fix HMI sends SetGlobalProperties response with info null * Add check if app contains app_info structure * Update year in copyright * Removed unrelated images * Add separate code customization for choice sets * Remove SoftButtons limitation for main windows * Fix capabilities check result codes Also all result code calculation functions for all interfaces have been updated to properly consider result codes if some error was raised after capabilities check * Fix AddSubMenu after conflicts resolution Co-authored-by: v-malko4 Co-authored-by: BSolonenko Co-authored-by: yurii --- app/StateManager.js | 6 + app/controller/NavigationController.js | 34 +- app/controller/SettingsController.js | 7 + app/controller/sdl/Abstract/Controller.js | 1 + app/controller/sdl/RPCController.js | 10 +- app/model/sdl/Abstract/AppModel.js | 208 ++++---- app/model/sdl/Abstract/data.js | 28 +- app/model/sdl/VehicleInfoModel.js | 29 +- app/view/settings/RPCControlView.js | 87 ++++ .../RPCControls/RPCControlConfigView.js | 221 +++++++++ .../RPCVehicleDataControlConfigView.js | 184 +++++++ .../RPCWayPointControlConfigView.js | 135 ++++++ app/view/settingsView.js | 27 +- css/general.css | 12 +- css/settings.css | 252 +++++++++- ffw/BasicCommunicationRPC.js | 37 +- ffw/NavigationRPC.js | 30 +- ffw/RCRPC.js | 28 +- ffw/RPCHelper.js | 449 ++++++++++++++++++ ffw/RPCObserver.js | 1 + ffw/TTSRPC.js | 52 +- ffw/UIRPC.js | 79 ++- ffw/VRRPC.js | 65 ++- ffw/VehicleInfoRPC.js | 55 ++- index.html | 10 + 25 files changed, 1853 insertions(+), 194 deletions(-) create mode 100644 app/view/settings/RPCControlView.js create mode 100644 app/view/settings/RPCControls/RPCControlConfigView.js create mode 100644 app/view/settings/RPCControls/RPCVehicleDataControlConfigView.js create mode 100644 app/view/settings/RPCControls/RPCWayPointControlConfigView.js create mode 100644 ffw/RPCHelper.js diff --git a/app/StateManager.js b/app/StateManager.js index e5297ce87..7e831703a 100644 --- a/app/StateManager.js +++ b/app/StateManager.js @@ -173,6 +173,12 @@ var StateManager = Em.StateManager.extend( ); this._super(); }, + rpccontrol: Em.State.create({ + rpcconfig: Em.State.create({}), + rpcwaypointconfig: Em.State.create({}), + rpcvehicledataconfig: Em.State.create({}) + } + ), policies: Em.State.create( { statisticsInfo: Em.State.create({}), diff --git a/app/controller/NavigationController.js b/app/controller/NavigationController.js index 87000dbd2..48adc391d 100644 --- a/app/controller/NavigationController.js +++ b/app/controller/NavigationController.js @@ -128,19 +128,35 @@ SDL.NavigationController = Em.Object.create( * @param {Object} request */ subscribeWayPoints: function(request) { - if (!this.model.isSubscribedOnWayPoints) { - this.model.set('isSubscribedOnWayPoints', true); - FFW.Navigation.sendNavigationResult( - SDL.SDLModel.data.resultCode.SUCCESS, - request.id, - request.method - ); + result = FFW.RPCHelper.getCustomResultCode(null, 'SubscribeWayPoints'); + + if ('DO_NOT_RESPOND' == result) { + Em.Logger.log('Do not respond on this request'); + return; + } + + if(FFW.RPCHelper.isSuccessResultCode(result)){ + if (!this.model.isSubscribedOnWayPoints) { + this.model.set('isSubscribedOnWayPoints', true); + FFW.Navigation.sendNavigationResult( + result, + request.id, + request.method + ); + } else { + FFW.Navigation.sendError( + SDL.SDLModel.data.resultCode.REJECTED, + request.id, + request.method, + 'SDL Should not send this request more than once' + ); + } } else { FFW.Navigation.sendError( - SDL.SDLModel.data.resultCode.REJECTED, + result, request.id, request.method, - 'SDL Should not send this request more than once' + 'Erroneous response is assigned by settings' ); } }, diff --git a/app/controller/SettingsController.js b/app/controller/SettingsController.js index 5de8e86e4..f39e1e070 100644 --- a/app/controller/SettingsController.js +++ b/app/controller/SettingsController.js @@ -75,7 +75,14 @@ SDL.SettingsController = Em.Object.create( editedCcpuVersionValue: "", onState: function(event) { + if(SDL.States.currentState.name === 'rpcconfig'){ + FFW.RPCHelper.setCurrentAppID(null); + } SDL.States.goToStates('settings.' + event.goToState); + if('rpccontrol.rpcconfig' === event.goToState){ + SDL.RPCControlConfigView.set('appNameLabel.content',event.appName); + FFW.RPCHelper.updateRpc(event.appID); + } }, onChildState: function(event) { SDL.States.goToStates( diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index f5ecd895f..c215efa09 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -58,6 +58,7 @@ SDL.SDLController = Em.Object.extend( SDL.InfoAppsView.showAppList(); SDL.AppPermissionsListView.showAppList(); SDL.RCModulesController.updateModuleSeatLocationContent(); + SDL.RPCControlView.showAppList(); }.observes('SDL.SDLModel.data.registeredApps.@each'), /** * Handeler for command button press diff --git a/app/controller/sdl/RPCController.js b/app/controller/sdl/RPCController.js index a3e87bf9f..dcc0f99c2 100644 --- a/app/controller/sdl/RPCController.js +++ b/app/controller/sdl/RPCController.js @@ -73,31 +73,31 @@ SDL.RPCController = Em.Object.create( capabilitiesCheck: function(key, value) { if (key == 'imageType' && value == 'STATIC') { SDL.RPCController.capabilityCheckResult = { - code: SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + code: SDL.SDLModel.data.resultCode['WARNINGS'], type: value }; } if (key == 'type' && value == 'PRE_RECORDED') { SDL.RPCController.capabilityCheckResult = { - code: SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + code: SDL.SDLModel.data.resultCode['WARNINGS'], type: value }; } if (key == 'type' && value == 'SAPI_PHONEMES') { SDL.RPCController.capabilityCheckResult = { - code: SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + code: SDL.SDLModel.data.resultCode['WARNINGS'], type: value }; } if (key == 'type' && value == 'LHPLUS_PHONEMES') { SDL.RPCController.capabilityCheckResult = { - code: SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + code: SDL.SDLModel.data.resultCode['WARNINGS'], type: value }; } if (key == 'type' && value == 'SILENCE') { SDL.RPCController.capabilityCheckResult = { - code: SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + code: SDL.SDLModel.data.resultCode['WARNINGS'], type: value }; } diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 42dbccae6..11aa76423 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -512,49 +512,62 @@ SDL.ABSAppModel = Em.Object.extend( if (!this.get('commandsList.' + parentID)) { this.commandsList[parentID] = []; } + var commands = this.get('commandsList.' + parentID); // Magic number is limit of 1000 commands added on one menu - if (commands.length <= 999) { - commands.pushObject({ - commandID: request.params.cmdID, - name: request.params.menuParams.menuName, - parent: parentID, - position: request.params.menuParams.position ? - request.params.menuParams.position : 0, - isTemplate:request.params.cmdIcon ? - request.params.cmdIcon.isTemplate ?request.params.cmdIcon.isTemplate : null - : null, - icon: request.params.cmdIcon ? request.params.cmdIcon.value : null - }); - if (SDL.SDLController.getApplicationModel(request.params.appID) && - SDL.OptionsView.active) { - SDL.SDLController.buttonsSort(parentID, this.appID); - SDL.OptionsView.commands.refreshItems(); - } - if(request.params.cmdIcon){ - var image = request.params.cmdIcon.value; - var search_offset = image.lastIndexOf('.'); - str='.png'; - var isPng=image.includes(str, search_offset); - if(!isPng){ - FFW.UI.sendUIResult( - SDL.SDLModel.data.resultCode.WARNINGS, request.id, - request.method - ); - return; - } + result = FFW.RPCHelper.getCustomResultCode(this.appID, 'uiAddCommand'); + + if ('DO_NOT_RESPOND' == result) { + Em.Logger.log('Do not respond on this request'); + return; } - if (request.id >= 0) { - FFW.UI.sendUIResult( - SDL.SDLModel.data.resultCode.SUCCESS, request.id, - request.method - ); - } - } else { + + if (FFW.RPCHelper.isSuccessResultCode(result)) { + if (commands.length <= 999) { + commands[commands.length] = { + commandID: request.params.cmdID, + name: request.params.menuParams.menuName, + parent: parentID, + position: request.params.menuParams.position ? + request.params.menuParams.position : 0, + isTemplate:request.params.cmdIcon ? + request.params.cmdIcon.isTemplate ?request.params.cmdIcon.isTemplate : null + : null, + icon: request.params.cmdIcon ? request.params.cmdIcon.value : null + }; + if (SDL.SDLController.getApplicationModel(request.params.appID) && + SDL.OptionsView.active) { + SDL.SDLController.buttonsSort(parentID, this.appID); + SDL.OptionsView.commands.refreshItems(); + } + + console.log(commands.length); + if(request.params.cmdIcon) { + var image = request.params.cmdIcon.value; + var length=image.length; + str='.png'; + var isPng=image.includes(str,length-5); + if (!isPng) { + FFW.UI.sendUIResult( + SDL.SDLModel.data.resultCode.WARNINGS, request.id, + request.method + ); + return; + } + } + if (request.id >= 0) { + FFW.UI.sendUIResult(result, request.id, request.method); + } + } else { + FFW.UI.sendError( + result, request.id, request.method, + 'Adding more than 1000 item to the top menu or to submenu is not allowed.' + ); + } + } else { FFW.UI.sendError( - SDL.SDLModel.data.resultCode.REJECTED, request.id, - request.method, - 'Adding more than 1000 item to the top menu or to submenu is not allowed.' + result, request.id, request.method, + 'Erroneous response is assigned by settings' ); } }, @@ -603,37 +616,49 @@ SDL.ABSAppModel = Em.Object.extend( return; } - // parentID is equal to 'top' cause Top level menu ID - var parentID = request.params.menuParams.parentID ? request.params.menuParams.parentID : 'top'; - var commands = this.get('commandsList.' + parentID); - // Magic number is limit of 1000 commands added on one menu - if (commands.length <= 999) { - this.commandsList[request.params.menuID] = []; - commands[commands.length] = { - menuID: request.params.menuID, - name: request.params.menuParams.menuName ? - request.params.menuParams.menuName : '', - parent: parentID, - position: request.params.menuParams.position ? - request.params.menuParams.position : 0, - icon: request.params.menuIcon ? request.params.menuIcon.value : null - }; - if (SDL.SDLController.getApplicationModel(request.params.appID) && - SDL.OptionsView.active) { - SDL.SDLController.buttonsSort(parentID, this.appID); - SDL.OptionsView.commands.refreshItems(); + // parentID is equal to 'top' cause Top level menu ID + var parentID = request.params.menuParams.parentID ? request.params.menuParams.parentID : 'top'; + var commands = this.get('commandsList.' + parentID); + + result = FFW.RPCHelper.getCustomResultCode(this.appID, 'AddSubmenu'); + if ('DO_NOT_RESPOND' == result) { + Em.Logger.log('Do not respond on this request'); + return; + } + + if(FFW.RPCHelper.isSuccessResultCode(result)) { + // Magic number is limit of 1000 commands added on one menu + if (commands.length <= 999) { + this.commandsList[request.params.menuID] = []; + commands[commands.length] = { + menuID: request.params.menuID, + name: request.params.menuParams.menuName ? + request.params.menuParams.menuName : '', + parent: parentID, + position: request.params.menuParams.position ? + request.params.menuParams.position : 0, + icon: request.params.menuIcon ? request.params.menuIcon.value : null + }; + if (SDL.SDLController.getApplicationModel(request.params.appID) && + SDL.OptionsView.active) { + SDL.SDLController.buttonsSort(parentID, this.appID); + SDL.OptionsView.commands.refreshItems(); + } + FFW.UI.sendUIResult(result, request.id, request.method); + } else { + FFW.UI.sendError( + SDL.SDLModel.data.resultCode.REJECTED, request.id, + request.method, + 'Adding more than 1000 item to the top menu or to submenu is not allowed.' + ); + } + } else { + FFW.UI.sendError( + result, request.id, + request.method, + 'Erroneous response is assigned by settings' + ); } - FFW.UI.sendUIResult( - SDL.SDLModel.data.resultCode.SUCCESS, request.id, - request.method - ); - } else { - FFW.UI.sendError( - SDL.SDLModel.data.resultCode.REJECTED, request.id, - request.method, - 'Adding more than 1000 item to the top menu or to submenu is not allowed.' - ); - } }, /** * Delete submenu and related commands from list @@ -695,31 +720,34 @@ SDL.ABSAppModel = Em.Object.extend( createWindow: function(windowParam) { var content = {}; if (windowParam.duplicateUpdatesFromWindowID === 0) { - var showStringsArray = []; - SDL.SDLController.model.appInfo.field1 ? showStringsArray.push({ - "fieldName": "mainField1", - "fieldText": SDL.SDLController.model.appInfo.field1 - }) : null ; + var app_info = SDL.SDLController.model ? SDL.SDLController.model.appInfo : null; - SDL.SDLController.model.appInfo.field2 ? showStringsArray.push({ - "fieldName": "mainField2", - "fieldText": SDL.SDLController.model.appInfo.field2 - }) : null ; + var showStringsArray = []; + if (app_info) { + showStringsArray.push({ + "fieldName": "mainField1", + "fieldText": app_info.field1 + }); + showStringsArray.push({ + "fieldName": "mainField2", + "fieldText": SDL.SDLController.model.appInfo.field2 + }); - content["showStrings"] = showStringsArray; - - content["softButtons"] = this.get("softButtons").slice(0,4); - - if (SDL.SDLController.model.appInfo.mainImage) { - content["graphic"] = { - "value" : SDL.SDLController.model.appInfo.mainImage - }; - } else if (SDL.SDLController.model.appInfo.trackIcon) { - content["graphic"] = { - "value" : SDL.SDLController.model.appInfo.trackIcon - }; + if (app_info.mainImage) { + content["graphic"] = { + "value" : app_info.mainImage + }; + } else if (app_info.trackIcon) { + content["graphic"] = { + "value" : app_info.trackIcon + }; + } } + content["showStrings"] = showStringsArray; + content["softButtons"] = windowParam.type == 'WIDGET' ? + this.get("softButtons").slice(0,4) : + this.get("softButtons"); content["templateConfiguration"] = this.templateConfiguration; windowParam.content = content; diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index ade3e9d59..b1e91d0c1 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -33,6 +33,15 @@ SDL.SDLModelData = Em.Object.create( { + + init: function(){ + this.resultCodes = Object.keys(this.resultCode); + }, + + /** + * Array of result codes + */ + resultCodes: null, /** * List of default app permissions entityes for AppPermissionsView */ @@ -459,7 +468,10 @@ SDL.SDLModelData = Em.Object.create( 'NO_DEVICES_CONNECTED': 20, 'WARNINGS': 21, 'GENERIC_ERROR': 22, - 'USER_DISALLOWED': 23 + 'USER_DISALLOWED': 23, + 'TRUNCATED_DATA': 24, + 'SAVED': 25, + 'READ_ONLY': 26 }, /** * Enum with app priority rankings @@ -472,6 +484,20 @@ SDL.SDLModelData = Em.Object.create( 'NORMAL': 4, 'NONE': 5 }, + /** + * Array of vehicle data result codes + */ + vehicleDataResultCode: [ + 'SUCCESS', + 'TRUNCATED_DATA', + 'DISALLOWED', + 'USER_DISALLOWED', + 'INVALID_ID', + 'VEHICLE_DATA_NOT_AVAILABLE', + 'DATA_ALREADY_SUBSCRIBED', + 'DATA_NOT_SUBSCRIBED', + 'IGNORED' + ], /** * Info navigationApp data for ShowConstantTBT request * diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index 51433af97..87f2cd5ca 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -457,9 +457,20 @@ SDL.SDLVehicleInfoModel = Em.Object.create( */ SubscribeVehicleData: function(message) { var subscribeVIData = {}; - for (var key in message.params) { - if (key === 'clusterModeStatus') { - key = 'clusterModes'; + var customResultCode = FFW.RPCHelper.getCustomResultCode(null, 'SubscribeVehicleData'); + + if ('DO_NOT_RESPOND' == customResultCode['SubscribeVehicleData']) { + Em.Logger.log('Do not respond on this request'); + return; + } + + const is_user_allowed_code = + FFW.RPCHelper.isSuccessResultCode(customResultCode['SubscribeVehicleData']); + + for (var key in message.params){ + subscribeVIData[key] = { + dataType: this.eVehicleDataType[key], + resultCode: customResultCode.vehicleDataStruct[key], } var vehicleDataType = this.eVehicleDataType.hasOwnProperty(key) ? @@ -489,14 +500,22 @@ SDL.SDLVehicleInfoModel = Em.Object.create( continue; } - SDL.SDLModel.subscribedData[key] = true; + if (is_user_allowed_code) { + SDL.SDLModel.subscribedData[key] = true; + } + subscribeVIData[key] = { dataType: vehicleDataType, - resultCode: 'SUCCESS' + resultCode: is_user_allowed_code ? 'SUCCESS' : 'USER_DISALLOWED' }; } var resultCode = this.CalculateSubscriptionsResultCode(subscribeVIData); + if (customResultCode['SubscribeVehicleData'] != SDL.SDLModel.data.resultCode.SUCCESS) { + // Custom result code specified by user has a higher priority for response + resultCode = customResultCode['SubscribeVehicleData']; + } + FFW.VehicleInfo.sendVISubscribeVehicleDataResult( resultCode, message.id, message.method, subscribeVIData ); diff --git a/app/view/settings/RPCControlView.js b/app/view/settings/RPCControlView.js new file mode 100644 index 000000000..9052407de --- /dev/null +++ b/app/view/settings/RPCControlView.js @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +SDL.RPCControlView = Em.ContainerView.create( + { + elementId: 'rpc_settings', + classNames: 'in_settings_view', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.active:active_state:inactive_state' + ], + childViews: [ + 'AppsList' + ], + showAppList: function() { + this.get('AppsList.list').removeAllChildren(); + this.AppsList.list.refresh(); + var i, apps = SDL.SDLModel.data.registeredApps, appIndex; + if (0 == apps.length && SDL.States.currentState.name == 'rpccontrol') { + SDL.States.goToStates('settings.policies'); + } + + this.get('AppsList.list.childViews').pushObject(SDL.Button.create( + { + action: 'onState', + target: 'SDL.SettingsController', + goToState:'rpccontrol.rpcwaypointconfig', + text: 'Subscribe Way Points', + classNames: 'list-item button' + })); + this.get('AppsList.list.childViews').pushObject(SDL.Button.create( + { + action: 'onState', + target: 'SDL.SettingsController', + goToState:'rpccontrol.rpcvehicledataconfig', + text: 'Vehicle Data', + classNames: 'list-item button' + })); + + for (i = 0; i < apps.length; i++) { + appIndex = SDL.SDLModel.data.registeredApps.indexOf(apps[i]); + this.get('AppsList.list.childViews').pushObject(SDL.Button.create( + { + action: 'onState', + target: 'SDL.SettingsController', + goToState:'rpccontrol.rpcconfig', + text: apps[i].appName, + appName: apps[i].appName, + appID: apps[i].appID, + classNames: 'list-item button', + iconBinding: 'SDL.SDLModel.data.registeredApps.' + appIndex + + '.appIcon', + disabled: apps[i].disabledToActivate, + templateName: 'rightText' + })); + } + }, + + AppsList: SDL.List.extend({ + elementId: 'rpc_settings_list', + classNames: 'rpc_settings_list', + itemsOnPage: 5, + items: new Array() + }) + } +); diff --git a/app/view/settings/RPCControls/RPCControlConfigView.js b/app/view/settings/RPCControls/RPCControlConfigView.js new file mode 100644 index 000000000..a8a2c254e --- /dev/null +++ b/app/view/settings/RPCControls/RPCControlConfigView.js @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +SDL.RPCControlConfigView = Em.ContainerView.create( + { + elementId: 'rpc_settings_deviceConfig', + classNames: 'rpc_settings_separate_view', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.rpcconfig.active:active_state:inactive_state' + ], + childViews: [ + 'backButton', + 'rpcList', + 'resultCodeTracker', + 'saveButton', + 'resetButton', + 'appNameLabel' + ], + appNameLabel: SDL.Label.extend( + { + elementId: 'appNameLabel', + classNames: 'appNameLabel' + } + ), + resetButton: SDL.Button.extend( + { + classNames: [ + 'resetButton' + ], + action: 'resetButton', + target: 'FFW.RPCHelper', + goToState: 'rpccontrol', + text:'Reset to default', + onDown: false + } + ), + saveButton: SDL.Button.extend( + { + classNames: [ + 'saveButton' + ], + action: 'saveButton', + target: 'FFW.RPCHelper', + goToState: 'rpccontrol', + text:'Save', + onDown: false + } + ), + backButton: SDL.Button.extend( + { + classNames: [ + 'backControl' + ], + action: 'onState', + target: 'SDL.SettingsController', + goToState: 'rpccontrol', + icon: 'images/media/ico_back.png', + style: 'top: 100px', + onDown: false + } + ), + rpcList: Em.ContainerView.extend( + { + elementId: 'rpcList', + classNames: 'rpcList', + childViews: [ + 'vrAddComandlabel', + 'uiAddComandlabel', + 'addSubMenulabel', + 'createInteractionChoiceSetlabel', + 'uisetGlobalPropertieslabel', + 'ttssetGlobalPropertieslabel', + 'uiCreateWindowLabel' + ], + vrAddComandlabel: SDL.Label.extend( + { + elementId: 'addComandlabel', + classNames: 'vrAddComandlabel', + content: 'VR.AddCommand' + } + ), + uiAddComandlabel: SDL.Label.extend( + { + elementId: 'addComandlabel', + classNames: 'uiAddComandlabel', + content: 'UI.AddCommand' + } + ), + addSubMenulabel: SDL.Label.extend( + { + elementId: 'addSubMenulabel', + classNames: 'addSubMenulabel', + content: 'AddSubMenu' + } + ), + createInteractionChoiceSetlabel: SDL.Label.extend( + { + elementId: 'createInteractionChoiceSetlabel', + classNames: 'createInteractionChoiceSetlabel', + content: 'CreateInteractionChoiceSet' + } + ), + uisetGlobalPropertieslabel: SDL.Label.extend( + { + elementId: 'uisetGlobalProperties', + classNames: 'uisetGlobalProperties', + content: 'UI.SetGlobalProperties' + } + ), + ttssetGlobalPropertieslabel: SDL.Label.extend( + { + elementId: 'ttssetGlobalPropertieslabel', + classNames: 'ttssetGlobalPropertieslabel', + content: 'TTS.SetGlobalProperties' + } + ), + uiCreateWindowLabel: SDL.Label.extend( + { + elementId: 'uiCreateWindowLabel', + classNames: 'uiCreateWindowLabel', + content: 'UI.CreateWindow' + } + ) + } + ), + resultCodeTracker: Em.ContainerView.extend( + { + elementId: 'resultCodeTracker', + classNames: 'resultCodeTracker', + childViews: [ + 'vrAddComandSelect', + 'uiAddComandSelect', + 'addSubMenuSelect', + 'createInteractionChoiceSetSelect', + 'uisetGlobalPropertiesSelect', + 'ttssetGlobalPropertiesSelect', + 'uiCreateWindowSelect' + ], + vrAddComandSelect: Em.Select.extend( + { + elementId: 'vrAddComandSelect', + classNames: 'vrAddComandSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.vrAddCommand' + } + ), + uiAddComandSelect: Em.Select.extend( + { + elementId: 'uiAddComandSelect', + classNames: 'uiAddComandSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.uiAddCommand' + } + ), + addSubMenuSelect: Em.Select.extend( + { + elementId: 'addSubMenuSelect', + classNames: 'addSubMenuSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.AddSubmenu' + } + ), + createInteractionChoiceSetSelect: Em.Select.extend( + { + elementId: 'createInteractionChoiceSetSelect', + classNames: 'createInteractionChoiceSetSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.createInteractionChoiceSet' + } + ), + uisetGlobalPropertiesSelect: Em.Select.extend( + { + elementId: 'uisetGlobalPropertiesSelect', + classNames: 'uisetGlobalPropertiesSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.uiSetGlobalProperties' + } + ), + ttssetGlobalPropertiesSelect: Em.Select.extend( + { + elementId: 'ttssetGlobalPropertiesSelect', + classNames: 'ttssetGlobalPropertiesSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.ttsSetGlobalProperties' + } + ), + uiCreateWindowSelect: Em.Select.extend( + { + elementId: 'uiCreateWindowSelect', + classNames: 'uiCreateWindowSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.rpcStruct.uiCreateWindow' + } + ), + } + ) + } +); diff --git a/app/view/settings/RPCControls/RPCVehicleDataControlConfigView.js b/app/view/settings/RPCControls/RPCVehicleDataControlConfigView.js new file mode 100644 index 000000000..0e4f7f91b --- /dev/null +++ b/app/view/settings/RPCControls/RPCVehicleDataControlConfigView.js @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +SDL.RPCVehicleDataControlConfigView = Em.ContainerView.create({ + elementId: 'rpc_vehicle_data_Config', + classNames: 'rpc_settings_separate_view', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.rpcvehicledataconfig.active:active_state:inactive_state' + ], + + childViews: [ + 'backButton', + 'newButton', + 'removeButton', + 'previousButton', + 'nextButton', + 'counterLabel', + 'subscribevehicleData', + 'subscribevehicleDataParams' + ], + backButton: SDL.Button.extend( + { + classNames: [ + 'backControl' + ], + action: 'onState', + target: 'SDL.SettingsController', + goToState: 'rpccontrol', + icon: 'images/media/ico_back.png', + style: 'top: 100px', + onDown: false + }), + newButton: SDL.Button.extend( + { + classNames: [ + 'newButton' + ], + action: 'newVehicleDataResponse', + target: 'FFW.RPCHelper', + text: 'New', + onDown: false + }), + removeButton: SDL.Button.extend( + { + classNames: [ + 'removeButton' + ], + isDisabled: function() { + return FFW.RPCHelper.VehicleDataResultCodes.length == 1; + }.property( + 'FFW.RPCHelper.VehicleDataRequestNumber' + + ), + disabledBinding: 'isDisabled', + action: 'removeVehicleDataResponse', + target: 'FFW.RPCHelper', + text: 'Remove', + onDown: false + }), + previousButton: SDL.Button.extend( + { + classNames: [ + 'previousButton' + ], + isDisabled: function() { + return FFW.RPCHelper.VehicleDataRequestNumber == 1; + }.property( + 'FFW.RPCHelper.VehicleDataRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'previousVehicleDataResultCode', + target: 'FFW.RPCHelper', + text: 'Previous', + onDown: false + }), + nextButton: SDL.Button.extend( + { + classNames: [ + 'nextButton' + ], + isDisabled: function() { + return FFW.RPCHelper.VehicleDataRequestNumber == + FFW.RPCHelper.VehicleDataResultCodes.length; + }.property( + 'FFW.RPCHelper.VehicleDataRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'nextVehicleDataResultCode', + target: 'FFW.RPCHelper', + text: 'Next', + onDown: false + }), + counterLabel: SDL.Label.extend( + { + elementId: 'counterLabel', + classNames: 'counterLabel', + contentBinding: 'FFW.RPCHelper.getVehicleDataStatus' + }), + subscribevehicleData: Em.ContainerView.create( + { + elementId: 'subscribevehicleData', + classNames: 'subscribevehicleData', + childViews: [ + 'label', + 'select' + ], + label: SDL.Label.extend( + { + elementId: 'label', + classNames: 'label', + content: 'SubscribeVehicleData' + }), + select: Em.Select.extend( + { + elementId: 'SubscribevehicleDataSelect', + classNames: 'select', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.SubscribeVehicleData' + }), + }), + subscribevehicleDataParams: Em.ContainerView.create( + { + elementId: 'subscribevehicleDataParams', + classNames: 'subscribevehicleDataParams', + childViews: [] + }), + isFirstInitialization: true, + initSubscribevehicleDataParams: function(){ + if(!this.isFirstInitialization){ + return; + } + this.isFirstInitialization = false; + + for(var viewsName in FFW.RPCHelper.vehicleDataStruct){ + selectValueBinding = 'FFW.RPCHelper.vehicleDataStruct.' + viewsName; + this.get('subscribevehicleDataParams.childViews').pushObject(Em.ContainerView.create({ + elementId: viewsName, + classNames: 'params', + childViews: [ + 'label', + 'select' + ], + + label: SDL.Label.extend( + { + elementId: 'label', + classNames: 'label', + content: viewsName + }), + select: Em.Select.extend( + { + elementId: viewsName + 'Select', + classNames: 'select', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: selectValueBinding + }), + })); + + } + } +}); diff --git a/app/view/settings/RPCControls/RPCWayPointControlConfigView.js b/app/view/settings/RPCControls/RPCWayPointControlConfigView.js new file mode 100644 index 000000000..ae09e0498 --- /dev/null +++ b/app/view/settings/RPCControls/RPCWayPointControlConfigView.js @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +SDL.RPCWayPointControlConfigView = Em.ContainerView.create({ + elementId: 'rpc_way_points_Config', + classNames: 'rpc_settings_separate_view', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.rpcwaypointconfig.active:active_state:inactive_state' + ], + + childViews: [ + 'backButton', + 'newButton', + 'removeButton', + 'previousButton', + 'nextButton', + 'counterLabel', + 'subscribeWayPointsSelect' + ], + backButton: SDL.Button.extend( + { + classNames: [ + 'backControl' + ], + action: 'onState', + target: 'SDL.SettingsController', + goToState: 'rpccontrol', + icon: 'images/media/ico_back.png', + style: 'top: 100px', + onDown: false + } + ), + newButton: SDL.Button.extend( + { + classNames: [ + 'newButton' + ], + action: 'newWayPointResponse', + target: 'FFW.RPCHelper', + text: 'New', + onDown: false + } + ), + removeButton: SDL.Button.extend( + { + classNames: [ + 'removeButton' + ], + isDisabled: function() { + return FFW.RPCHelper.wayPointResultCodes.length == 1; + }.property( + 'FFW.RPCHelper.SubscribeWayPointsRequestNumber' + + ), + disabledBinding: 'isDisabled', + action: 'removeWayPointResponse', + target: 'FFW.RPCHelper', + text: 'Remove', + onDown: false + } + ), + previousButton: SDL.Button.extend( + { + classNames: [ + 'previousButton' + ], + isDisabled: function() { + return FFW.RPCHelper.SubscribeWayPointsRequestNumber == 1; + }.property( + 'FFW.RPCHelper.SubscribeWayPointsRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'previousWayPointResultCode', + target: 'FFW.RPCHelper', + text: 'Previous', + onDown: false + } + ), + nextButton: SDL.Button.extend( + { + classNames: [ + 'nextButton' + ], + isDisabled: function() { + return FFW.RPCHelper.SubscribeWayPointsRequestNumber == + FFW.RPCHelper.wayPointResultCodes.length; + }.property( + 'FFW.RPCHelper.SubscribeWayPointsRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'nextWayPointResultCode', + target: 'FFW.RPCHelper', + text: 'Next', + onDown: false + } + ), + counterLabel: SDL.Label.extend( + { + elementId: 'counterLabel', + classNames: 'counterLabel', + contentBinding: 'FFW.RPCHelper.getWayPointResponseStatus' + } + ), + subscribeWayPointsSelect: Em.Select.extend( + { + elementId: 'subscribeWayPointsSelect', + classNames: 'subscribeWayPointsSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.SubscribeWayPoints' + } + ), +}); diff --git a/app/view/settingsView.js b/app/view/settingsView.js index 439ac2771..da2bf442c 100644 --- a/app/view/settingsView.js +++ b/app/view/settingsView.js @@ -43,9 +43,13 @@ SDL.SettingsView = Em.ContainerView.create( 'leftMenu', SDL.DeviceStateChangeView, SDL.PoliciesView, + SDL.RPCControlView, SDL.AppPermissionsListView, SDL.AppPermissionsView, SDL.DeviceConfigView, + SDL.RPCControlConfigView, + SDL.RPCWayPointControlConfigView, + SDL.RPCVehicleDataControlConfigView, SDL.StatisticsInfoView, SDL.SystemErrorView, SDL.ConnectionSettingsView, @@ -84,7 +88,8 @@ SDL.SettingsView = Em.ContainerView.create( 'policies', 'HMISettings', 'light', - 'seat' + 'seat', + 'rpcControl' ], policies: SDL.Button.extend( { @@ -99,6 +104,26 @@ SDL.SettingsView = Em.ContainerView.create( action: 'turnOnPoliciesSettings', target: 'SDL.SettingsController' } + ), + rpcControl: SDL.Button.extend( + { + isDisabled: function() { + return !SDL.SDLModel.data.registeredApps.length; + }.property( + 'SDL.SDLModel.data.registeredApps.length' + ), + disabledBinding: 'isDisabled', + elementId: 'rpcControl_leftMenu', + goToState: 'rpccontrol', + classNames: 'menu-item lsp1_p', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.active:info_active' + ], + text: 'RPC Control', + icon: 'images/settings/ico_settings.png', + action: 'onState', + target: 'SDL.SettingsController' + } ), HMISettings: SDL.Button.extend({ elementId: 'HMISettings_leftMenu', diff --git a/css/general.css b/css/general.css index c2ad20a8b..adb9436e4 100644 --- a/css/general.css +++ b/css/general.css @@ -2001,7 +2001,7 @@ to { display: none; } -/* Lable plus Button*/ +/* label plus Button*/ .lablePlusButton .button { float: right; right: 0px; @@ -2010,7 +2010,7 @@ to { border-left: 1px solid #393939; } -.lablePlusButton .lable span, .lablePlusButton .button span { +.lablePlusButton .label span, .lablePlusButton .button span { margin-left: 13px; } @@ -2041,7 +2041,7 @@ to { -webkit-border-radius: 4px; } -/* header lable*/ +/* header label*/ #select_system_heading_lable { position: relative; font-size: 30px; @@ -2101,7 +2101,7 @@ to { margin-top: 2px; } -/* select climate style lable*/ +/* select climate style label*/ #select_system_label { font-size: 20px; width: 135px; @@ -2152,7 +2152,7 @@ to { float: left; } -/* navigationApp select lable*/ +/* navigationApp select label*/ #sdnav_label { position: relative; float: left; @@ -2175,7 +2175,7 @@ to { margin: 50px auto; } -/* Info Lable*/ +/* Info label*/ #select_system_info { position: relative; text-align: center; diff --git a/css/settings.css b/css/settings.css index 4dc3c0fbd..e7edece02 100644 --- a/css/settings.css +++ b/css/settings.css @@ -8,6 +8,248 @@ height: 382px; background: black; z-index: 5000; + border: 1px solid white; + border-radius: 10PX; +} + +#settingsView .rpc_settings_separate_view { + top: 68px; + left:190px; + width: 495px; + height: 337px; + background: black; + z-index: 5000; + border: 1px solid white; + border-radius: 10PX; + overflow-y: scroll; +} + + .appNameLabel{ + top: 13px; + left: 213px; + font-size: 200%; + text-align: center; +} + + .backControl { + top: 20px; + width: 35px; + height: 27px; + border: 1px solid #333; + border-radius: 2px; + left: 10px; +} + + .saveButton, + .newButton { + left: 55px; + border: 1px solid #333; + border-radius: 2px; + top: 20px; + width: 60px; + height: 27px; + text-align: center; +} + +.removeButton{ + border: 1px solid #333; + border-radius: 2px; + width: 71px; + height: 27px; + text-align: center; + top: 20px; + left: 125px; +} + +.previousButton{ + border: 1px solid #333; + border-radius: 2px; + width: 71px; + height: 27px; + text-align: center; + top: 20px; + left: 280px; +} + +.nextButton{ + border: 1px solid #333; + border-radius: 2px; + width: 60px; + height: 27px; + text-align: center; + left: 360px; + top: 20px; +} + +.counterLabel{ + top: 55px; + width: 60px; + height: 27px; + text-align: center; +} + +.rpc_settings_separate_view .counterLabel{ + top: 25px; + left: 415px; + width: 60px; + height: 27px; + text-align: center; +} + + .resetButton{ + left: 125px; + border: 1px solid #333; + border-radius: 2px; + top: 20px; + width: 60px; + height: 27px; + text-align: center; + font-size: 75%; +} + +#settingsView .rpc_settings_separate_view + .rpcList{ + left: 170px; + direction: rtl; +} + + .vrAddComandlabel{ + top: 60px; +} + + .uiAddComandlabel{ + top: 85px; +} + + .addSubMenulabel{ + top: 110px; +} + +.createInteractionChoiceSetlabel { + top: 135px; + font-size: 84%; +} + +.uisetGlobalProperties { + top: 160px; +} + +.ttssetGlobalPropertieslabel { + position: absolute; + top: 185px; + font-size: 85%; +} + +.uiCreateWindowLabel { + top: 210px; +} + + .subscribeWayPoints{ + top: 185px; + left: -140px; +} + + .vehicleDataGlobal{ + top: 212px; + left: -150px; +} + + .subscribeVehicleData{ + top: 260px; + left: -140px; +} + +.subscribevehicleData{ + top: 50px; + direction: initial; + position: absolute; + height: 30px; + width: 479px; +} +.subscribevehicleData .label{ + position: absolute; + left: 10px; + top: 5px; +} +.subscribevehicleData .select{ + position: absolute; + left: 185px; + top: 5px; +} + +.subscribevehicleDataParams{ + position: relative; + height: 850px; + width: 479px; + top: 80px; +} +.subscribevehicleDataParams .params{ + top: 5px; + position: relative; + height: 30px; + width: 450px; + left: 26px; +} +.subscribevehicleDataParams .params .label{ + left: 10px; +} +.subscribevehicleDataParams .params .select{ + left: 205px; + position: absolute; +} + +#settingsView .rpc_settings_separate_view + .resultCodeTracker{ + left: 200px; + direction: ltl; +} + + .vrAddComandSelect{ + top:60px; + position: absolute; +} + +.uiAddComandSelect{ + top:85px; + position: absolute; +} + + .addSubMenuSelect{ + top: 110px; + position: absolute; +} + +.createInteractionChoiceSetSelect { + top: 135px; + position: absolute; +} + +.uisetGlobalPropertiesSelect { + top: 160px; + position: absolute; +} + +.ttssetGlobalPropertiesSelect { + top: 185px; + position: absolute; +} + +.uiCreateWindowSelect { + top: 210px; + position: absolute; +} + + .subscribeWayPointsSelect{ + top: 55px; + left: 55px; + width: 407px; + height: 18px; + position: absolute; +} + + .vehicleDataGlobalSelect{ + top: 210px; + position: absolute; } #settingsView .in_settings_separate_view .backButton, @@ -28,7 +270,7 @@ .in_light_single_view .list, .in_light_location_view .list, .in_light_interior_view .list { - height: 201px; + height: 251px; width: 700px; top: 106px; left: 50px; @@ -120,6 +362,10 @@ width: 80px; } +#settingsView .right_text { + padding-left: 50px; +} + #settingsView .in_settings_separate_view .label, .in_light_exterior_view .label, .in_light_single_view .label, @@ -213,13 +459,13 @@ z-index: 1001; margin-top: 70px; } - +#settingsView .rpc_settings_list, #settingsView .policies_settings_list { height: 251px; width: 598px; left: 10px; } - +#rpc_settings_list .list-content .ffw-button, #policies_settings_list .list-content .ffw-button { width: 537px; padding-left: 10px; diff --git a/ffw/BasicCommunicationRPC.js b/ffw/BasicCommunicationRPC.js index 1803f6f22..7753d6b3c 100644 --- a/ffw/BasicCommunicationRPC.js +++ b/ffw/BasicCommunicationRPC.js @@ -502,16 +502,21 @@ FFW.BasicCommunication = FFW.RPCObserver if (notification.method == this.onAppRegisteredNotification) { let appModel = Object.assign(notification.params.application, { "priority": notification.params.priority ? notification.params.priority : 'NONE' - }); + }); SDL.SDLModel.onAppRegistered( appModel, notification.params.vrSynonyms ); + FFW.RPCHelper.addApplication(notification.params.application.appID); this.OnFindApplications(); const mainWindowID = 0; let capability = SDL.SDLController.getDefaultCapabilities(mainWindowID, notification.params.application.appID); FFW.BasicCommunication.OnSystemCapabilityUpdated(capability); } if (notification.method == this.onAppUnregisteredNotification) { + if(notification.params.appID === FFW.RPCHelper.get('currentAppID')){ + SDL.States.goToStates('settings.rpccontrol'); + SDL.RPCControlView.showAppList(); + } // remove app from list SDL.SDLModel.onAppUnregistered(notification.params); } @@ -965,11 +970,28 @@ FFW.BasicCommunication = FFW.RPCObserver * id * @param {String} * method + * @param {String} + * info */ - sendBCResult: function(resultCode, id, method) { - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS) { + sendBCResult: function(resultCode, id, method, info) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; + this.errorResponsePull[id] = null; + this.sendBCResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); + return; + } + + Em.Logger.log('FFW.BC.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', @@ -979,7 +1001,14 @@ FFW.BasicCommunication = FFW.RPCObserver 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /** diff --git a/ffw/NavigationRPC.js b/ffw/NavigationRPC.js index e5fd97d13..ac582eaa2 100644 --- a/ffw/NavigationRPC.js +++ b/ffw/NavigationRPC.js @@ -560,22 +560,27 @@ FFW.Navigation = FFW.RPCObserver.create( * @param {Number} resultCode * @param {Number} id * @param {String} method + * @param {String} info */ - sendNavigationResult: function(resultCode, id, method) { - if (this.errorResponsePull[id] != null) { - this.sendError( - this.errorResponsePull[id].code, + sendNavigationResult: function(resultCode, id, method, info) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; + this.errorResponsePull[id] = null; + + this.sendNavigationResult( + errorStruct.code, id, method, - 'Unsupported ' + this.errorResponsePull[id].type + - ' type. Available data in request was processed.' + `Unsupported ${errorStruct.type} type. Available data in request was processed.` ); - this.errorResponsePull[id] = null; return; } - Em.Logger.log('FFW.UI.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS ||resultCode == SDL.SDLModel.data.resultCode.WARNINGS ) { + Em.Logger.log('FFW.Navigation.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', @@ -585,7 +590,14 @@ FFW.Navigation = FFW.RPCObserver.create( 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /** diff --git a/ffw/RCRPC.js b/ffw/RCRPC.js index c80995983..4b5439f17 100644 --- a/ffw/RCRPC.js +++ b/ffw/RCRPC.js @@ -359,19 +359,41 @@ FFW.RC = FFW.RPCObserver.create( * method */ sendRCResult: function(resultCode, id, method) { - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; + this.errorResponsePull[id] = null; + + this.sendRCResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); + return; + } + Em.Logger.log('FFW.RC.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', 'id': id, 'result': { - 'code': resultCode, + 'code': resultCode, // type (enum) from SDL protocol 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, GetInteriorVehicleDataConsentResponse: function(request, allowed) { diff --git a/ffw/RPCHelper.js b/ffw/RPCHelper.js new file mode 100644 index 000000000..4e46556ff --- /dev/null +++ b/ffw/RPCHelper.js @@ -0,0 +1,449 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +FFW.RPCHelper = Em.Object.create( + { + + /* + * Container for handling error of RPC + */ + appContainer:Em.Object.create({}), + + customResultCodesList: [ + 'SUCCESS' + ], + + /* + * init function. Setup helpers initial values + */ + init: function() { + for(key in this.rpcStruct){ + this.set('defaultRpcStruct.'+key, 'SUCCESS'); + }; + for(key in this.vehicleDataStruct){ + this.set('vehicleDataStruct.'+key, 'SUCCESS'); + }; + this.set('SubscribeWayPoints', 'SUCCESS'); + this.set('SubscribeVehicleData', 'SUCCESS'); + + this.VehicleDataResultCodes.push({ + SubscribeVehicleData: 'SUCCESS', + vehicleDataStruct: this.getSuccessVehicleDataStruct() + }); + }, + + /* + * addApplication function. Push new application into the app + * container with initial data + */ + addApplication: function(appID) { + if (this.customResultCodesList.length <= 1) { + let codes = SDL.deepCopy(SDL.SDLModel.data.resultCodes); + codes.push('DO_NOT_RESPOND'); + this.set('customResultCodesList', codes); + } + + if(this.appContainer[appID] === undefined ){ + this.appContainer[appID] = SDL.deepCopy(this.defaultRpcStruct); + } + }, + + /* + * isSuccessResultCode function. Checks if passed result code is + * a success result code + */ + isSuccessResultCode: function(resultCode) { + return [ + SDL.SDLModel.data.resultCode.SUCCESS, + SDL.SDLModel.data.resultCode.WARNINGS, + SDL.SDLModel.data.resultCode.WRONG_LANGUAGE, + SDL.SDLModel.data.resultCode.RETRY, + SDL.SDLModel.data.resultCode.SAVED + ].includes(resultCode); + }, + + /* + * getCustomResultCode function. Claims custom result code for + * application for a specified method. It could be overriden + * by HMI settings + */ + getCustomResultCode: function(appID, method) { + switch (method) { + case 'SubscribeWayPoints': { + return this.getNextWayPointResultCode(); + } + case 'SubscribeVehicleData': { + return this.getNextVehicleDataResultCode(); + } + } + + var code = null; + if(appID && this.appContainer.hasOwnProperty(appID) && this.appContainer[appID][method]) { + code = this.appContainer[appID][method]; + } else if(this.vehicleDataStruct[method]) { + code = this.vehicleDataStruct[method]; + } + + if (null === code) { + return SDL.SDLModel.data.resultCode.SUCCESS; + } + + if ('DO_NOT_RESPOND' == code) { + return code; + } + + return SDL.SDLModel.data.resultCode[code]; + }, + + /* + * updateRPC function. Creates list of RPC + */ + updateRpc: function(appID) { + for(key in this.appContainer[appID]){ + this.set('rpcStruct.' + key,this.appContainer[appID][key]); + }; + this.setCurrentAppID(appID); + }, + + /* + * saveButton function. Saves parameters after pressing save button + * on the RPCControl view and returns to app list + */ + saveButton: function(){ + var appName = SDL.RPCControlConfigView.appNameLabel.content; + app = SDL.SDLModel.data.registeredApps.filterProperty( + 'appName', + appName + )[0]; + for(key in this.appContainer[app.appID]){ + this.set('appContainer.'+ app.appID + '.'+key, this.rpcStruct[key]); + }; + var event = {goToState: 'rpccontrol'}; + SDL.SettingsController.onState(event); + this.setCurrentAppID(null); + }, + + /* + * resetButton function. Reset parameters to default after pressing reset button + * on the RPCControl view + */ + resetButton: function() { + for(key in this.rpcStruct){ + this.set('rpcStruct.'+key, this.defaultRpcStruct[key]); + }; + }, + + /* + * setCurrentAppID function. Sets of currentAppID parameter + */ + setCurrentAppID: function(appID){ + this.set('currentAppID', appID); + }, + + /* + * updateWayPointResultCodes function. Update SubscribeWayPoints array + */ + updateWayPointResultCodes: function(){ + index = this.SubscribeWayPointsRequestNumber - 1; + this.wayPointResultCodes[index] = this.SubscribeWayPoints; + }, + + /* + * updateVehicleDataResultCodes function. Update SubscribeVehicleData array + */ + updateVehicleDataResultCodes: function(){ + index = this.VehicleDataRequestNumber - 1; + this.VehicleDataResultCodes[index].SubscribeVehicleData = this.SubscribeVehicleData; + this.VehicleDataResultCodes[index].vehicleDataStruct = this.vehicleDataStruct; + }, + + /* + * updateSubscribeWayPoints function. Update SubscribeWayPoints parameter + */ + updateSubscribeWayPoints: function(){ + index = this.SubscribeWayPointsRequestNumber - 1; + this.set('SubscribeWayPoints', this.wayPointResultCodes[index]); + }, + + /* + * updateSubscribeVehicleData function. Update SubscribeVehicleData parameter + */ + updateSubscribeVehicleData: function(){ + index = this.VehicleDataRequestNumber - 1; + this.set('SubscribeVehicleData', this.VehicleDataResultCodes[index].SubscribeVehicleData); + this.set('vehicleDataStruct', this.VehicleDataResultCodes[index].vehicleDataStruct); + }, + + /* + * previousWayPointResultCode function. Go to previous WayPoint ResultCode + */ + previousWayPointResultCode: function(){ + this.updateWayPointResultCodes(); + this.set('SubscribeWayPointsRequestNumber', this.SubscribeWayPointsRequestNumber - 1); + this.updateSubscribeWayPoints(); + }, + + /* + * previousVehicleDataResultCode function. Go to previous VehicleData ResultCode + */ + previousVehicleDataResultCode: function(){ + this.updateVehicleDataResultCodes(); + this.set('VehicleDataRequestNumber', this.VehicleDataRequestNumber - 1); + this.updateSubscribeVehicleData(); + }, + + /* + * nextWayPointResultCode function. Go to next WayPoint ResultCode + */ + nextWayPointResultCode: function(){ + this.updateWayPointResultCodes(); + this.set('SubscribeWayPointsRequestNumber', this.SubscribeWayPointsRequestNumber + 1); + this.updateSubscribeWayPoints(); + }, + + /* + * nextVehicleDataResultCode function. Go to next WayPoint VehicleData + */ + nextVehicleDataResultCode: function(){ + this.updateVehicleDataResultCodes(); + this.set('VehicleDataRequestNumber', this.VehicleDataRequestNumber + 1); + this.updateSubscribeVehicleData(); + }, + + /* + * Add new response for SubscribeWayPoint RPC in queue + */ + newWayPointResponse: function(){ + this.updateWayPointResultCodes(); + + this.wayPointResultCodes.push('SUCCESS'); + this.set('SubscribeWayPoints', 'SUCCESS'); + this.set('SubscribeWayPointsRequestNumber', this.SubscribeWayPointsRequestNumber + 1); + }, + + /* + * removeWayPointResponse function. remove current WayPoint ResultCode + * from array + */ + removeWayPointResponse: function(){ + this.updateWayPointResultCodes(); + + index = this.SubscribeWayPointsRequestNumber - 1; + length = this.wayPointResultCodes.length; + + this.wayPointResultCodes.splice(index, 1); + + currentNumber = this.SubscribeWayPointsRequestNumber; + this.set('SubscribeWayPointsRequestNumber',0); + this.set('SubscribeWayPointsRequestNumber', Math.min(currentNumber, + this.wayPointResultCodes.length)); + + this.updateSubscribeWayPoints(); + }, + + /* + * removeVehicleDataResponse function. remove current VehicleData ResultCode + * from array + */ + removeVehicleDataResponse: function(){ + this.updateVehicleDataResultCodes(); + + index = this.VehicleDataRequestNumber - 1; + length = this.VehicleDataResultCodes.length; + + this.VehicleDataResultCodes.splice(index, 1); + + currentNumber = this.VehicleDataRequestNumber; + this.set('VehicleDataRequestNumber',0); + this.set('VehicleDataRequestNumber', Math.min(currentNumber, + this.VehicleDataResultCodes.length)); + + this.updateSubscribeVehicleData(); + }, + + /* + * Claims vehicle data structure filled with SUCCESS result codes + */ + getSuccessVehicleDataStruct:function(){ + SuccessVehicleDataStruct = {} + for(var paramName in this.vehicleDataStruct){ + SuccessVehicleDataStruct[paramName] = 'SUCCESS'; + } + return SuccessVehicleDataStruct; + }, + + /* + * Add new response for SubscribeVehicleData RPC in queue + */ + newVehicleDataResponse: function(){ + this.updateVehicleDataResultCodes(); + + successVehicleDataStruct = this.getSuccessVehicleDataStruct(); + + this.VehicleDataResultCodes.push({ + SubscribeVehicleData: 'SUCCESS', + vehicleDataStruct: successVehicleDataStruct + }); + this.set('SubscribeVehicleData', 'SUCCESS'); + this.set('vehicleDataStruct', successVehicleDataStruct); + this.set('VehicleDataRequestNumber', this.VehicleDataRequestNumber + 1); + }, + + /* + * Format string with waypoints set to display on label + */ + getWayPointResponseStatus: function() { + return this.SubscribeWayPointsRequestNumber + '/' + this.wayPointResultCodes.length; + }.property( + 'FFW.RPCHelper.SubscribeWayPointsRequestNumber' + ), + + /* + * Format string with vehicle data set to display on label + */ + getVehicleDataStatus: function() { + return this.VehicleDataRequestNumber + '/' + this.VehicleDataResultCodes.length; + }.property( + 'FFW.RPCHelper.VehicleDataRequestNumber' + ), + + /* + * Claims next result code for SubscribeWayPoints RPC + */ + getNextWayPointResultCode: function(){ + this.updateWayPointResultCodes(); + + length = this.wayPointResultCodes.length; + + code = this.wayPointResultCodes[0]; + if(length > 1){ + this.wayPointResultCodes.shift(); //remove the first element of the array + + currentNumber = this.SubscribeWayPointsRequestNumber; + this.set('SubscribeWayPointsRequestNumber', + Math.min(currentNumber, + this.wayPointResultCodes.length)); + this.updateSubscribeWayPoints(); + } else if(length == 1){ + this.set('SubscribeWayPoints', 'SUCCESS'); + } + + if ('DO_NOT_RESPOND' == code) { + return code; + } + + return SDL.SDLModel.data.resultCode[code] + }, + + /* + * Claims next result code for SubscribeVehicleData RPC + */ + getNextVehicleDataResultCode: function(){ + this.updateVehicleDataResultCodes(); + + nextVehicleDataResultCode = this.VehicleDataResultCodes[0].SubscribeVehicleData; + const next_code = 'DO_NOT_RESPOND' == nextVehicleDataResultCode ? + nextVehicleDataResultCode : SDL.SDLModel.data.resultCode[nextVehicleDataResultCode]; + + code = { + SubscribeVehicleData: next_code, + vehicleDataStruct:{} + }; + + for(var paramName in this.vehicleDataStruct){ + nextParamResultCode = this.VehicleDataResultCodes[0].vehicleDataStruct[paramName] + code.vehicleDataStruct[paramName] = nextParamResultCode; + } + + length = this.VehicleDataResultCodes.length; + if(length > 1){ + this.VehicleDataResultCodes.shift(); //remove the first element of the array + currentNumber = this.VehicleDataRequestNumber; + this.set('VehicleDataRequestNumber',0); + this.set('VehicleDataRequestNumber', Math.min(currentNumber, + this.VehicleDataResultCodes.length)); + + this.updateSubscribeVehicleData(); + } else if(length == 1){ + this.set('SubscribeVehicleData', 'SUCCESS'); + this.set('vehicleDataStruct', this.getSuccessVehicleDataStruct()); + } + + return code; + }, + + wayPointResultCodes: ['SUCCESS'], + SubscribeWayPoints: '', + SubscribeWayPointsRequestNumber: 1, + + defaultRpcStruct: {}, + currentAppID: null, + + rpcStruct: { + vrAddCommand:'', + uiAddCommand: '', + createInteractionChoiceSet: '', + AddSubmenu:'', + uiSetGlobalProperties: '', + ttsSetGlobalProperties: '', + uiCreateWindow: '' + }, + + VehicleDataResultCodes: [], + VehicleDataRequestNumber: 1, + SubscribeVehicleData: '', + vehicleDataStruct: { + speed:'', + rpm: '', + fuelLevel: '', + fuelLevel_State: '', + instantFuelConsumption: '', + externalTemperature: '', + turnSignal: '', + prndl: '', + tirePressure: '', + odometer: '', + beltStatus: '', + bodyInformation: '', + deviceStatus: '', + driverBraking: '', + wiperStatus: '', + headLampStatus: '', + engineTorque: '', + accPedalPosition: '', + steeringWheelAngle: '', + engineOilLife: '', + electronicParkBrakeStatus: '', + eCallInfo: '', + airbagStatus: '', + emergencyEvent: '', + clusterModes: '', + myKey: '', + fuelRange: '', + gps: '' + } + } +); diff --git a/ffw/RPCObserver.js b/ffw/RPCObserver.js index 01f7b2b1b..ae4b0b549 100644 --- a/ffw/RPCObserver.js +++ b/ffw/RPCObserver.js @@ -152,6 +152,7 @@ FFW.RPCObserver = Em.Object.extend( params.cmdIcon.value = params.cmdIcon.value + '?m=' + new Date().getTime(); } } + if ('menuIcon' in params) { if (params.menuIcon.imageType === 'STATIC') { delete params.menuIcon; diff --git a/ffw/TTSRPC.js b/ffw/TTSRPC.js index dc4631f38..a7d470692 100644 --- a/ffw/TTSRPC.js +++ b/ffw/TTSRPC.js @@ -201,11 +201,24 @@ FFW.TTS = FFW.RPCObserver.create( // this.errorResponsePull[request.id].type + " type. Request was not // processed."); this.errorResponsePull[request.id] = null; return; // } } - SDL.SDLModel.setProperties(request.params); + resultCode = FFW.RPCHelper.getCustomResultCode(request.params.appID, 'ttsSetGlobalProperties'); + if ('DO_NOT_RESPOND' == resultCode) { + Em.Logger.log('Do not respond on this request'); + return; + } + + let info = null; + + if(FFW.RPCHelper.isSuccessResultCode(resultCode)){ + SDL.SDLModel.setProperties(request.params); + } else { + info = 'Erroneous response is assigned by settings'; + } this.sendTTSResult( - SDL.SDLModel.data.resultCode.SUCCESS, + resultCode, request.id, - request.method + request.method, + info ); break; } @@ -369,20 +382,28 @@ FFW.TTS = FFW.RPCObserver.create( * id * @param {String} * method + * @param {String} + * info */ - sendTTSResult: function(resultCode, id, method) { - if (this.errorResponsePull[id]) { - this.sendError( - this.errorResponsePull[id].code, id, method, - 'Unsupported ' + this.errorResponsePull[id].type + - ' type. Available data in request was processed.' - ); + sendTTSResult: function(resultCode, id, method, info) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; this.errorResponsePull[id] = null; + + this.sendTTSResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); return; } - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS) { + Em.Logger.log('FFW.TTS.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', @@ -392,7 +413,14 @@ FFW.TTS = FFW.RPCObserver.create( 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /* diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index cf748e488..4456d8261 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -294,9 +294,22 @@ FFW.UI = FFW.RPCObserver.create( // this.errorResponsePull[request.id].type + " type. Request was // not processed."); this.errorResponsePull[request.id] = null; // return; } } + resultCode = FFW.RPCHelper.getCustomResultCode(request.params.appID, 'uiSetGlobalProperties'); + if ('DO_NOT_RESPOND' == resultCode) { + Em.Logger.log('Do not respond on this request'); + return; + } + + let info = null; + + if(FFW.RPCHelper.isSuccessResultCode(resultCode)){ SDL.SDLModel.setProperties(request.params); - this.sendUIResult( - SDL.SDLModel.data.resultCode.SUCCESS, request.id, request.method + } else { + info = 'Erroneous response is assigned by settings'; + } + + this.sendUIResult( + resultCode, request.id, request.method, info ); break; } @@ -1582,13 +1595,26 @@ FFW.UI = FFW.RPCObserver.create( } case 'UI.CreateWindow': { - var app = SDL.SDLController.getApplicationModel(request.params.appID); - app.createWindow(request.params); - this.sendUIResult( - SDL.SDLModel.data.resultCode.SUCCESS, request.id, request.method - ); - let capabilites = SDL.SDLController.getDefaultCapabilities(request.params.windowID, request.params.appID); - FFW.BasicCommunication.OnSystemCapabilityUpdated(capabilites); + const resultCode = FFW.RPCHelper.getCustomResultCode(request.params.appID, 'uiCreateWindow'); + if ('DO_NOT_RESPOND' == resultCode) { + Em.Logger.log('Do not respond on this request'); + return; + } + + if (FFW.RPCHelper.isSuccessResultCode(resultCode)) { + var app = SDL.SDLController.getApplicationModel(request.params.appID); + if (app) { + app.createWindow(request.params); + + this.sendUIResult(resultCode, request.id, request.method); + + let capabilites = SDL.SDLController.getDefaultCapabilities(request.params.windowID, request.params.appID); + FFW.BasicCommunication.OnSystemCapabilityUpdated(capabilites); + } + } else { + this.sendUIResult(resultCode, request.id, request.method, 'Erroneous response is assigned by settings'); + } + break; } case 'UI.DeleteWindow': @@ -1653,32 +1679,45 @@ FFW.UI = FFW.RPCObserver.create( * id * @param {String} * method + * @param {String} + * info */ sendUIResult: function(resultCode, id, method, info) { - if (this.errorResponsePull[id]) { - this.sendError( - this.errorResponsePull[id].code, id, method, - 'Unsupported ' + this.errorResponsePull[id].type + - ' type. Available data in request was processed.' - ); + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; this.errorResponsePull[id] = null; + + this.sendUIResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); return; } - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode == SDL.SDLModel.data.resultCode.SUCCESS || - resultCode == SDL.SDLModel.data.resultCode.WARNINGS) { + Em.Logger.log('FFW.UI.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', 'id': id, 'result': { 'code': resultCode, // type (enum) from SDL protocol - 'method': method, - 'info': info + 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /** diff --git a/ffw/VRRPC.js b/ffw/VRRPC.js index 1e822cab6..c519128ae 100644 --- a/ffw/VRRPC.js +++ b/ffw/VRRPC.js @@ -127,17 +127,43 @@ FFW.VR = FFW.RPCObserver.create( /* * handle RPC requests here */ + checkRequestType: function(type){ + switch(type){ + case 'Command': + return 'vrAddCommand'; + case 'Choice': + return 'createInteractionChoiceSet'; + default: return ''; + } + }, + onRPCRequest: function(request) { Em.Logger.log('FFW.VR.onRPCRequest'); if (this.validationCheck(request)) { switch (request.method) { case 'VR.AddCommand': { - SDL.SDLModel.addCommandVR(request.params); + var key = this.checkRequestType(request.params.type); + result = FFW.RPCHelper.getCustomResultCode(request.params.appID, key); + + if ('DO_NOT_RESPOND' == result) { + Em.Logger.log('Do not respond on this request'); + return; + } + + let info = null; + + if(FFW.RPCHelper.isSuccessResultCode(result)){ + SDL.SDLModel.addCommandVR(request.params); + } else { + info = 'Erroneous response is assigned by settings'; + } + this.sendVRResult( - SDL.SDLModel.data.resultCode.SUCCESS, + result, request.id, - request.method + request.method, + info ); break; } @@ -361,20 +387,28 @@ FFW.VR = FFW.RPCObserver.create( * id * @param {String} * method + * @param {String} + * info */ - sendVRResult: function(resultCode, id, method) { - if (this.errorResponsePull[id]) { - this.sendError( - this.errorResponsePull[id].code, id, method, - 'Unsupported ' + this.errorResponsePull[id].type + - ' type. Available data in request was processed.' - ); + sendVRResult: function(resultCode, id, method, info) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; this.errorResponsePull[id] = null; + + this.sendVRResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); return; } - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS) { + Em.Logger.log('FFW.VR.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', @@ -384,7 +418,14 @@ FFW.VR = FFW.RPCObserver.create( 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /* diff --git a/ffw/VehicleInfoRPC.js b/ffw/VehicleInfoRPC.js index 0b8484423..413583ce3 100644 --- a/ffw/VehicleInfoRPC.js +++ b/ffw/VehicleInfoRPC.js @@ -250,21 +250,45 @@ FFW.VehicleInfo = FFW.RPCObserver.create( * id * @param {String} * method + * @param {String} + * info */ - sendVIResult: function(resultCode, id, method) { - Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode === SDL.SDLModel.data.resultCode.SUCCESS) { + sendVIResult: function(resultCode, id, method, info) { + const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); + if (is_successful_code && this.errorResponsePull[id] != null) { + // If request was successful but some error was observed upon validation + // Then result code assigned by RPCController should be considered instead + const errorStruct = this.errorResponsePull[id]; + this.errorResponsePull[id] = null; + + this.sendVIResult( + errorStruct.code, + id, + method, + `Unsupported ${errorStruct.type} type. Available data in request was processed.` + ); + return; + } + Em.Logger.log('FFW.VI.' + method + 'Response'); + if (is_successful_code) { // send repsonse var JSONMessage = { 'jsonrpc': '2.0', 'id': id, 'result': { - 'code': resultCode, + 'code': resultCode, // type (enum) from SDL protocol 'method': method } }; + + if (info) { + JSONMessage.result.info = info; + } + this.sendMessage(JSONMessage); + } else { + this.sendError(resultCode, id, method, info); } }, /** @@ -277,17 +301,20 @@ FFW.VehicleInfo = FFW.RPCObserver.create( */ sendVISubscribeVehicleDataResult: function(resultCode, id, method, data) { Em.Logger.log('FFW.' + method + 'Response'); + if (FFW.RPCHelper.isSuccessResultCode(resultCode)) { - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'result': data - }; - - JSONMessage.result.code = resultCode; - JSONMessage.result.method = method; - this.sendMessage(JSONMessage); + // send repsonse + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'result': data, + }; + JSONMessage.result.code = resultCode; + JSONMessage.result.method = method; + this.sendMessage(JSONMessage); + } else { + this.sendGetVehicleDataError(resultCode, id, method,'Erroneous response is assigned by settings', data); + } }, /** * Send error response from onRPCRequest diff --git a/index.html b/index.html index a75963ad4..0e6b4f0ac 100644 --- a/index.html +++ b/index.html @@ -47,6 +47,7 @@ + @@ -241,6 +242,15 @@ + + + + + + From 6d32f1ba10bd6d2335d755d902788fa82c6286e9 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 4 Sep 2020 18:41:08 -0400 Subject: [PATCH 052/104] Feature/sdl 0188 interior vehicle data resumption (#395) * Added GetIVD control form and logic * Add custom response logic for GetIVD request * Add isSubscribed emulation * Remove SoftButtons limitation for main windows Co-authored-by: BSolonenko Co-authored-by: yurii Co-authored-by: YarikMamykin --- app/StateManager.js | 3 +- app/model/sdl/Abstract/AppModel.js | 2 +- app/view/settings/RPCControlView.js | 10 +- .../RPCControls/RPCGetIVDControlConfigView.js | 169 ++++++++++++++++++ app/view/settingsView.js | 1 + css/settings.css | 30 ++++ ffw/RCRPC.js | 68 +++++-- ffw/RPCHelper.js | 144 +++++++++++++++ index.html | 4 +- 9 files changed, 410 insertions(+), 21 deletions(-) create mode 100644 app/view/settings/RPCControls/RPCGetIVDControlConfigView.js diff --git a/app/StateManager.js b/app/StateManager.js index 7e831703a..9430d0861 100644 --- a/app/StateManager.js +++ b/app/StateManager.js @@ -176,7 +176,8 @@ var StateManager = Em.StateManager.extend( rpccontrol: Em.State.create({ rpcconfig: Em.State.create({}), rpcwaypointconfig: Em.State.create({}), - rpcvehicledataconfig: Em.State.create({}) + rpcvehicledataconfig: Em.State.create({}), + rpcgetivdconfig: Em.State.create({}) } ), policies: Em.State.create( diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 11aa76423..e7e935c74 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -514,7 +514,6 @@ SDL.ABSAppModel = Em.Object.extend( } var commands = this.get('commandsList.' + parentID); - // Magic number is limit of 1000 commands added on one menu result = FFW.RPCHelper.getCustomResultCode(this.appID, 'uiAddCommand'); if ('DO_NOT_RESPOND' == result) { @@ -523,6 +522,7 @@ SDL.ABSAppModel = Em.Object.extend( } if (FFW.RPCHelper.isSuccessResultCode(result)) { + // Magic number is limit of 1000 commands added on one menu if (commands.length <= 999) { commands[commands.length] = { commandID: request.params.cmdID, diff --git a/app/view/settings/RPCControlView.js b/app/view/settings/RPCControlView.js index 9052407de..921e98904 100644 --- a/app/view/settings/RPCControlView.js +++ b/app/view/settings/RPCControlView.js @@ -57,7 +57,15 @@ SDL.RPCControlView = Em.ContainerView.create( text: 'Vehicle Data', classNames: 'list-item button' })); - + this.get('AppsList.list.childViews').pushObject(SDL.Button.create( + { + action: 'onState', + target: 'SDL.SettingsController', + goToState:'rpccontrol.rpcgetivdconfig', + text: 'Get Interior Vehicle Data', + classNames: 'list-item button' + })); + for (i = 0; i < apps.length; i++) { appIndex = SDL.SDLModel.data.registeredApps.indexOf(apps[i]); this.get('AppsList.list.childViews').pushObject(SDL.Button.create( diff --git a/app/view/settings/RPCControls/RPCGetIVDControlConfigView.js b/app/view/settings/RPCControls/RPCGetIVDControlConfigView.js new file mode 100644 index 000000000..7b4e054f4 --- /dev/null +++ b/app/view/settings/RPCControls/RPCGetIVDControlConfigView.js @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2020, Ford Motor Company All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: · + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. · Redistributions in binary + * form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided + * with the distribution. · Neither the name of the Ford Motor Company nor the + * names of its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +SDL.RPCGetIVDControlConfigView = Em.ContainerView.create({ + elementId: 'rpc_get_ivd_config', + classNames: 'rpc_settings_separate_view', + classNameBindings: [ + 'SDL.States.settings.rpccontrol.rpcgetivdconfig.active:active_state:inactive_state' + ], + + childViews: [ + 'backButton', + 'newButton', + 'removeButton', + 'previousButton', + 'nextButton', + 'counterLabel', + 'customResultCodeLabel', + 'getIVDSelect', + 'subscribedLabel', + 'getIVDSubscribed' + ], + + backButton: SDL.Button.extend( + { + classNames: [ + 'backControl' + ], + action: 'onState', + target: 'SDL.SettingsController', + goToState: 'rpccontrol', + icon: 'images/media/ico_back.png', + style: 'top: 100px', + onDown: false + } + ), + + newButton: SDL.Button.extend( + { + classNames: [ + 'newButton' + ], + action: 'newGetIVDResponse', + target: 'FFW.RPCHelper', + text: 'New', + onDown: false + } + ), + + removeButton: SDL.Button.extend( + { + classNames: [ + 'removeButton' + ], + isDisabled: function() { + return FFW.RPCHelper.getIVDResultStruct.length == 1; + }.property( + 'FFW.RPCHelper.getIVDRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'removeGetIVDResponse', + target: 'FFW.RPCHelper', + text: 'Remove', + onDown: false + } + ), + + previousButton: SDL.Button.extend( + { + classNames: [ + 'previousButton' + ], + isDisabled: function() { + return FFW.RPCHelper.getIVDRequestNumber == 1; + }.property( + 'FFW.RPCHelper.getIVDRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'previousGetIVDResultCode', + target: 'FFW.RPCHelper', + text: 'Previous', + onDown: false + } + ), + + nextButton: SDL.Button.extend( + { + classNames: [ + 'nextButton' + ], + isDisabled: function() { + return FFW.RPCHelper.getIVDRequestNumber == + FFW.RPCHelper.getIVDResultStruct.length; + }.property( + 'FFW.RPCHelper.getIVDRequestNumber' + ), + disabledBinding: 'isDisabled', + action: 'nextGetIVDResultCode', + target: 'FFW.RPCHelper', + text: 'Next', + onDown: false + } + ), + + counterLabel: SDL.Label.extend( + { + elementId: 'counterLabel', + classNames: 'counterLabel', + contentBinding: 'FFW.RPCHelper.getIVDResponseStatus' + } + ), + + customResultCodeLabel: SDL.Label.extend( + { + elementId: 'customResultCodeLabel', + classNames: 'customResultCodeLabel', + content: 'Custom result code:' + } + ), + + getIVDSelect: Em.Select.extend( + { + elementId: 'getIVDSelect', + classNames: 'getIVDSelect', + contentBinding: 'FFW.RPCHelper.customResultCodesList', + valueBinding: 'FFW.RPCHelper.getIVDResult' + } + ), + + subscribedLabel: SDL.Label.extend( + { + elementId: 'subscribedLabel', + classNames: 'subscribedLabel', + content: 'isSubscribed emulation:' + } + ), + + getIVDSubscribed: Em.Select.extend( + { + elementId: 'getIVDSubscribed', + classNames: 'getIVDSubscribed', + contentBinding: 'FFW.RPCHelper.subscribeDataValues', + valueBinding: 'FFW.RPCHelper.getIVDSubscribed' + } + ) +}); diff --git a/app/view/settingsView.js b/app/view/settingsView.js index da2bf442c..4fdc518de 100644 --- a/app/view/settingsView.js +++ b/app/view/settingsView.js @@ -50,6 +50,7 @@ SDL.SettingsView = Em.ContainerView.create( SDL.RPCControlConfigView, SDL.RPCWayPointControlConfigView, SDL.RPCVehicleDataControlConfigView, + SDL.RPCGetIVDControlConfigView, SDL.StatisticsInfoView, SDL.SystemErrorView, SDL.ConnectionSettingsView, diff --git a/css/settings.css b/css/settings.css index e7edece02..8e2021d77 100644 --- a/css/settings.css +++ b/css/settings.css @@ -252,6 +252,36 @@ position: absolute; } +.customResultCodeLabel{ + top: 60px; + left: 55px; + width: 407px; + height: 18px; + position: absolute; +} + +.getIVDSelect{ + top: 80px; + left: 55px; + width: 407px; + height: 18px; + position: absolute; +} + +.subscribedLabel { + position: absolute; + top: 110px; + left: 55px; + width: 190px; +} + +.getIVDSubscribed{ + position: absolute; + top: 135px; + left: 55px; + width: 170px; +} + #settingsView .in_settings_separate_view .backButton, .in_light_exterior_view .backButton, .in_light_single_view .backButton, diff --git a/ffw/RCRPC.js b/ffw/RCRPC.js index 4b5439f17..2d83fc8e1 100644 --- a/ffw/RCRPC.js +++ b/ffw/RCRPC.js @@ -250,26 +250,60 @@ FFW.RC = FFW.RPCObserver.create( { Em.Logger.log('FFW.' + request.method + ' Request'); - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': request.id, - 'result': { - 'code': SDL.SDLModel.data.resultCode.SUCCESS, - 'method': request.method, - 'isSubscribed': request.params.subscribe, - 'moduleData': { - 'moduleType': request.params.moduleType, - 'moduleId': request.params.moduleId + const resultStruct = FFW.RPCHelper.getCustomResultCode(request.params.appID, 'GetInteriorVehicleData'); + if ('DO_NOT_RESPOND' == resultStruct.code) { + Em.Logger.log('Do not respond on this request'); + break; + } + + if (FFW.RPCHelper.isSuccessResultCode(resultStruct.code)) { + let calculate_subscribed_value = function(subscribed) { + switch (subscribed) { + case 'USE_EXISTING': { + return request.params.subscribe; + } + case 'FALSE': { + return false; + } + case 'TRUE': { + return true; + } } + return null; + }; + + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': request.id, + 'result': { + 'code': resultStruct.code, + 'method': request.method, + 'moduleData': { + 'moduleType': request.params.moduleType, + 'moduleId': request.params.moduleId + } + } + }; + + var subscribed_value = calculate_subscribed_value(resultStruct.subscribed); + if(subscribed_value != null) { + JSONMessage.result["isSubscribed"] = subscribed_value; } - }; - var data = SDL.RCModulesController.getInteriorVehicleData(request); - if(data) { - var key = Object.keys(data)[0]; - JSONMessage.result.moduleData[key] = data[key]; - this.client.send(JSONMessage); - } + var data = SDL.RCModulesController.getInteriorVehicleData(request); + if (data) { + var key = Object.keys(data)[0]; + JSONMessage.result.moduleData[key] = data[key]; + this.client.send(JSONMessage); + } + + break; + } + + this.sendError(resultStruct.code, + request.id, + request.method, + 'Erroneous response is assigned by settings'); break; } case 'RC.GetInteriorVehicleDataConsent': diff --git a/ffw/RPCHelper.js b/ffw/RPCHelper.js index 4e46556ff..0c717c54b 100644 --- a/ffw/RPCHelper.js +++ b/ffw/RPCHelper.js @@ -32,10 +32,22 @@ FFW.RPCHelper = Em.Object.create( */ appContainer:Em.Object.create({}), + /* + * List of result codes to customize + */ customResultCodesList: [ 'SUCCESS' ], + /* + * List of data subscription values + */ + subscribeDataValues: [ + 'USE_EXISTING', + 'FALSE', + 'TRUE' + ], + /* * init function. Setup helpers initial values */ @@ -98,6 +110,9 @@ FFW.RPCHelper = Em.Object.create( case 'SubscribeVehicleData': { return this.getNextVehicleDataResultCode(); } + case 'GetInteriorVehicleData': { + return this.getNextGetIVDResultCode(); + } } var code = null; @@ -180,6 +195,15 @@ FFW.RPCHelper = Em.Object.create( this.VehicleDataResultCodes[index].vehicleDataStruct = this.vehicleDataStruct; }, + /* + * updategetIVDResultCodes function. Update GetIVD array + */ + updategetIVDResultCodes: function(){ + index = this.getIVDRequestNumber - 1; + this.getIVDResultStruct[index].code = this.getIVDResult; + this.getIVDResultStruct[index].subscribed = this.getIVDSubscribed; + }, + /* * updateSubscribeWayPoints function. Update SubscribeWayPoints parameter */ @@ -188,6 +212,15 @@ FFW.RPCHelper = Em.Object.create( this.set('SubscribeWayPoints', this.wayPointResultCodes[index]); }, + /* + * updateGetIVDData function. Update getIVDResult parameter + */ + updateGetIVDData: function(){ + index = this.getIVDRequestNumber - 1; + this.set('getIVDResult', this.getIVDResultStruct[index].code); + this.set('getIVDSubscribed', this.getIVDResultStruct[index].subscribed); + }, + /* * updateSubscribeVehicleData function. Update SubscribeVehicleData parameter */ @@ -215,6 +248,15 @@ FFW.RPCHelper = Em.Object.create( this.updateSubscribeVehicleData(); }, + /* + * previousGetIVDResultCode function. Go to previous GetIVD ResultCode + */ + previousGetIVDResultCode: function(){ + this.updategetIVDResultCodes(); + this.set('getIVDRequestNumber', this.getIVDRequestNumber - 1); + this.updateGetIVDData(); + }, + /* * nextWayPointResultCode function. Go to next WayPoint ResultCode */ @@ -233,6 +275,15 @@ FFW.RPCHelper = Em.Object.create( this.updateSubscribeVehicleData(); }, + /* + * nextGetIVDResultCode function. Go to next WayPoint ResultCode + */ + nextGetIVDResultCode: function(){ + this.updategetIVDResultCodes(); + this.set('getIVDRequestNumber', this.getIVDRequestNumber + 1); + this.updateGetIVDData(); + }, + /* * Add new response for SubscribeWayPoint RPC in queue */ @@ -244,6 +295,22 @@ FFW.RPCHelper = Em.Object.create( this.set('SubscribeWayPointsRequestNumber', this.SubscribeWayPointsRequestNumber + 1); }, + /* + * Add new response for GetIVD RPC in queue + */ + newGetIVDResponse: function(){ + this.updategetIVDResultCodes(); + + this.getIVDResultStruct.push({ + code: 'SUCCESS', + subscribed: FFW.RPCHelper.subscribeDataValues[0] + } + ); + + this.set('getIVDRequestNumber', this.getIVDRequestNumber + 1); + this.updateGetIVDData(); + }, + /* * removeWayPointResponse function. remove current WayPoint ResultCode * from array @@ -284,6 +351,29 @@ FFW.RPCHelper = Em.Object.create( this.updateSubscribeVehicleData(); }, + /* + * removeGetIVDResponse function. remove current VehicleData ResultCode + * from array + */ + removeGetIVDResponse: function(){ + this.updategetIVDResultCodes(); + + index = this.getIVDRequestNumber - 1; + length = this.getIVDResultStruct.length; + + this.getIVDResultStruct.splice(index, 1); + + currentNumber = this.getIVDRequestNumber; + + // Should be set to 0 first in order to trigger refresh event binding + // on the next set + this.set('getIVDRequestNumber', 0); + this.set('getIVDRequestNumber', Math.min(currentNumber, + this.getIVDResultStruct.length)); + + this.updateGetIVDData(); + }, + /* * Claims vehicle data structure filled with SUCCESS result codes */ @@ -330,6 +420,15 @@ FFW.RPCHelper = Em.Object.create( 'FFW.RPCHelper.VehicleDataRequestNumber' ), + /* + * Format string with IVD set to display on label + */ + getIVDResponseStatus: function() { + return this.getIVDRequestNumber + '/' + this.getIVDResultStruct.length; + }.property( + 'FFW.RPCHelper.getIVDRequestNumber' + ), + /* * Claims next result code for SubscribeWayPoints RPC */ @@ -395,10 +494,55 @@ FFW.RPCHelper = Em.Object.create( return code; }, + /* + * Claims next result code for GetIVD RPC + */ + getNextGetIVDResultCode: function(){ + this.updategetIVDResultCodes(); + + length = this.getIVDResultStruct.length; + + result = this.getIVDResultStruct[0]; + if(length > 1){ + this.getIVDResultStruct.shift(); //remove the first element of the array + + currentNumber = this.getIVDRequestNumber; + length = this.getIVDResultStruct.length; + this.set('getIVDRequestNumber', Math.min(currentNumber, length)); + this.updateGetIVDData(); + + // Manually update counterLabel and nextButton if currentNumber == length + if(currentNumber == length) { + SDL.RPCGetIVDControlConfigView.nextButton.set('disabled', true); + SDL.RPCGetIVDControlConfigView.counterLabel.set('content', currentNumber + '/' + length); + } + } else if (length == 1){ + this.set('getIVDResult', 'SUCCESS'); + this.set('getIVDSubscribed', FFW.RPCHelper.subscribeDataValues[0]); + } + + if ('DO_NOT_RESPOND' == result.code) { + return result; + } + + result.code = SDL.SDLModel.data.resultCode[result.code]; + return result; + }, + wayPointResultCodes: ['SUCCESS'], SubscribeWayPoints: '', SubscribeWayPointsRequestNumber: 1, + getIVDResultStruct: [ + { + code: 'SUCCESS', + subscribed: 'USE_EXISTING' + } + ], + getIVDResult: '', + getIVDSubscribed: '', + getIVDRequestNumber: 1, + defaultRpcStruct: {}, currentAppID: null, diff --git a/index.html b/index.html index 0e6b4f0ac..67b62bcd1 100644 --- a/index.html +++ b/index.html @@ -248,7 +248,9 @@ + src="app/view/settings/RPCControls/RPCVehicleDataControlConfigView.js"> + From 88b413a3d19d59288db883b47e624554dfce5273 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Tue, 22 Sep 2020 17:16:55 -0400 Subject: [PATCH 053/104] Remove unused variables which were causing console errors --- ffw/UIRPC.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 5bdc1a515..da83c7cd9 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1749,8 +1749,6 @@ FFW.UI = FFW.RPCObserver.create( */ onCommand: function(commandID, appID) { Em.Logger.log('FFW.UI.onCommand'); - var allowedDepth = SDL.systemCapabilities.driverDistractionCapability.subMenuDepth-1; - var activeDepth = SDL.SDLController.model.get('currentMenuDepth') var JSONMessage = { 'jsonrpc': '2.0', 'method': 'UI.OnCommand', @@ -1895,8 +1893,6 @@ FFW.UI = FFW.RPCObserver.create( */ OnSystemContext: function(systemContextValue, appID, windowID) { Em.Logger.log('FFW.UI.OnSystemContext'); - var allowedDepth = SDL.systemCapabilities.driverDistractionCapability.subMenuDepth-1; - var activeDepth = SDL.SDLController.model.get('currentMenuDepth') // send repsonse var JSONMessage = { 'jsonrpc': '2.0', From f712d4ea08ef6420d868daf51d0d4470098f9c6d Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 25 Sep 2020 11:35:16 -0400 Subject: [PATCH 054/104] Fix externalTemperature subscriptions (#334) By some reason, that parameter was hardcoded in some places and specified with NULL value in vehicle data structure. Hardcoded checks were removed and value according to API has been set in editor. As webHMI is just a testing tool, it should allow editing of any vehicle data fields even if technically emulation can't have these measurements. --- app/model/sdl/MediaModel.js | 4 +--- app/model/sdl/NonMediaModel.js | 4 +--- app/model/sdl/VehicleInfoModel.js | 18 +----------------- 3 files changed, 3 insertions(+), 23 deletions(-) diff --git a/app/model/sdl/MediaModel.js b/app/model/sdl/MediaModel.js index e8d8d6ead..761bef3f1 100644 --- a/app/model/sdl/MediaModel.js +++ b/app/model/sdl/MediaModel.js @@ -40,9 +40,7 @@ SDL.SDLMediaModel = SDL.ABSAppModel.extend({ var subscribeVIData = {}; for (var key in SDL.SDLVehicleInfoModel.vehicleData) { - if (key != 'externalTemperature') { - subscribeVIData[key] = false; - } + subscribeVIData[key] = false; } this.set('subscribedData', subscribeVIData); diff --git a/app/model/sdl/NonMediaModel.js b/app/model/sdl/NonMediaModel.js index 54a07a1ab..8fc73a771 100644 --- a/app/model/sdl/NonMediaModel.js +++ b/app/model/sdl/NonMediaModel.js @@ -40,9 +40,7 @@ SDL.SDLNonMediaModel = SDL.ABSAppModel.extend({ var subscribeVIData = {}; for (var key in SDL.SDLVehicleInfoModel.vehicleData) { - if (key != 'externalTemperature') { - subscribeVIData[key] = false; - } + subscribeVIData[key] = false; } this.set('subscribedData', subscribeVIData); diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index 87f2cd5ca..cc34df060 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -177,7 +177,7 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'fuelLevel': 0.2E0, 'fuelLevel_State': 'UNKNOWN', 'instantFuelConsumption': 2.2E0, - 'externalTemperature': null, + 'externalTemperature': 20.5E0, 'vin': '52-452-52-752', 'turnSignal': 'OFF', 'prndl': 'PARK', @@ -492,14 +492,6 @@ SDL.SDLVehicleInfoModel = Em.Object.create( continue; } - if (key === 'externalTemperature') { - subscribeVIData[key] = { - dataType: vehicleDataType, - resultCode: 'VEHICLE_DATA_NOT_AVAILABLE' - }; - continue; - } - if (is_user_allowed_code) { SDL.SDLModel.subscribedData[key] = true; } @@ -551,14 +543,6 @@ SDL.SDLVehicleInfoModel = Em.Object.create( continue; } - if (key === 'externalTemperature') { - subscribeVIData[key] = { - dataType: vehicleDataType, - resultCode: 'VEHICLE_DATA_NOT_AVAILABLE' - }; - continue; - } - SDL.SDLModel.subscribedData[key] = false; subscribeVIData[key] = { dataType: vehicleDataType, From 3344399a77b5d926bc3bb42a438ce7d46948b8ad Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 29 Sep 2020 14:42:48 -0400 Subject: [PATCH 055/104] delay sending on app exit to ensure onsystemcontext is processed first on vr exit --- app/controller/sdl/Abstract/Controller.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index c215efa09..e9c0e2b23 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -177,7 +177,8 @@ SDL.SDLController = Em.Object.extend( SDL.SDLModel.data.toggleProperty('VRActive'); } if (element.commandID === -2) { //Magic number if predefined VR command USER_EXIT - this.userExitAction(element.appID); + var that = this; + setTimeout( function() { that.userExitAction(element.appID); }, 50); } else { FFW.VR.onCommand(element.commandID, element.appID, element.grammarID); } From f9a6f65649773a4ffd3881277c184cfa869163e7 Mon Sep 17 00:00:00 2001 From: collin Date: Tue, 29 Sep 2020 17:32:45 -0400 Subject: [PATCH 056/104] reply to playTone TTS Speak when over taking it --- ffw/TTSRPC.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ffw/TTSRPC.js b/ffw/TTSRPC.js index a7d470692..9a1f38b00 100644 --- a/ffw/TTSRPC.js +++ b/ffw/TTSRPC.js @@ -173,6 +173,14 @@ FFW.TTS = FFW.RPCObserver.create( 'TTS in progress. Rejected.' ); } else { + if (this.requestId) { + // playTone does not set TTSPopUp.active + FFW.TTS.sendError( + SDL.SDLModel.data.resultCode.ABORTED, this.requestId, 'TTS.Speak', + 'TTS Speak request aborted' + ); + } + this.requestId = request.id; SDL.SDLModel.onPrompt( request.params.ttsChunks, request.params.appID From cd7a2bddb3ebfa63b181bec68ca079bb82419ccd Mon Sep 17 00:00:00 2001 From: collin Date: Thu, 1 Oct 2020 16:37:26 -0400 Subject: [PATCH 057/104] change playTone response to always be sent in onPrompt --- app/model/sdl/Abstract/Model.js | 6 ++++++ ffw/TTSRPC.js | 8 -------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index eaaf79386..3cb8495cc 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1373,6 +1373,12 @@ SDL.SDLModel = Em.Object.extend({ } } SDL.TTSPopUp.ActivateTTS(message, files, appID); + } else { + FFW.TTS.sendError( + SDL.SDLModel.data.resultCode.WARNINGS, this.requestId, 'TTS.Speak', + 'No TTS Chunks provided in Speak request' + ); + this.requestId = null; } }, diff --git a/ffw/TTSRPC.js b/ffw/TTSRPC.js index 9a1f38b00..a7d470692 100644 --- a/ffw/TTSRPC.js +++ b/ffw/TTSRPC.js @@ -173,14 +173,6 @@ FFW.TTS = FFW.RPCObserver.create( 'TTS in progress. Rejected.' ); } else { - if (this.requestId) { - // playTone does not set TTSPopUp.active - FFW.TTS.sendError( - SDL.SDLModel.data.resultCode.ABORTED, this.requestId, 'TTS.Speak', - 'TTS Speak request aborted' - ); - } - this.requestId = request.id; SDL.SDLModel.onPrompt( request.params.ttsChunks, request.params.appID From f5080b6189f6b8bdc21341f85077a02fa139d5a8 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Tue, 6 Oct 2020 12:12:15 -0400 Subject: [PATCH 058/104] Fix/fix get ivd response for climate (#335) * Removed unused code from controller * Rename functions according to their logic * Disable buttons when climate is off --- app/controller/ClimateController.js | 11 +---------- app/controller/sdl/RCModulesController.js | 2 +- app/model/ClimateControlModel.js | 24 ++++++++++++++++------- app/view/climateView.js | 7 ++++++- 4 files changed, 25 insertions(+), 19 deletions(-) diff --git a/app/controller/ClimateController.js b/app/controller/ClimateController.js index 9b04a4e2e..7e4cf712c 100644 --- a/app/controller/ClimateController.js +++ b/app/controller/ClimateController.js @@ -46,15 +46,6 @@ SDL.ClimateController = Em.Object.create( return (data.unit == 'CELSIUS' ? data.value : Math.round((data.value - 32) * 5 / 9)); - }, - getClimateControlData: function() { - var properties = this.model.getDataForSending(); - var climateControlData = this.model.getClimateControlData(); - var data = SDL.SDLController.filterObjectProperty(climateControlData, properties); - if(!climateControlData.climateEnable) { - data['currentTemperature'] = this.model.getClimateControlData().currentTemperature; - } - return data; - }, + } } ); diff --git a/app/controller/sdl/RCModulesController.js b/app/controller/sdl/RCModulesController.js index 7bd0d9cd0..1a2a904fb 100644 --- a/app/controller/sdl/RCModulesController.js +++ b/app/controller/sdl/RCModulesController.js @@ -769,7 +769,7 @@ SDL.RCModulesController = Em.Object.create({ { if (data.params.moduleData.climateControlData) { var currentClimateState = - this.climateModels[location_name].getClimateControlData().climateEnable; + this.climateModels[location_name].generateClimateControlData().climateEnable; var requestedClimateState = data.params.moduleData.climateControlData.climateEnable; if(!currentClimateState) { diff --git a/app/model/ClimateControlModel.js b/app/model/ClimateControlModel.js index fbe32a7b8..a44f4f1a6 100644 --- a/app/model/ClimateControlModel.js +++ b/app/model/ClimateControlModel.js @@ -179,8 +179,11 @@ SDL.ClimateControlModel = Em.Object.extend({ return result; }, - getClimateControlData: function() { - var result = { + /** + * @description Generates object containing full climate data properties + */ + generateClimateControlData: function() { + return { fanSpeed: this.climateControlData.fanSpeed, currentTemperature: SDL.ClimateController.getTemperatureStruct( this.climateControlData.temperatureUnit, @@ -203,12 +206,19 @@ SDL.ClimateControlModel = Em.Object.extend({ heatedMirrorsEnable: this.climateControlData.heatedMirrorsEnable, climateEnable: this.climateControlData.climateEnable }; + }, - return result; + /** + * @description Gets climate data object with filtered properties + */ + getClimateControlData: function() { + const climate_data = this.generateClimateControlData(); + const filter_properties = this.getDataForSending(); + return SDL.SDLController.filterObjectProperty(climate_data, filter_properties); }, setClimateData: function(data) { - var before_set = SDL.deepCopy(this.getClimateControlData()); + var before_set = SDL.deepCopy(this.generateClimateControlData()); if(data.climateEnable != null) { this.setClimateEnable(data.climateEnable); @@ -275,7 +285,7 @@ SDL.ClimateControlModel = Em.Object.extend({ this.setHeatedMirrorsEnable(data.heatedMirrorsEnable); } - var after_set = SDL.deepCopy(this.getClimateControlData()); + var after_set = SDL.deepCopy(this.generateClimateControlData()); var properties = SDL.SDLController.getChangedProperties(before_set, after_set); @@ -297,7 +307,7 @@ SDL.ClimateControlModel = Em.Object.extend({ }, sendClimateChangeNotification: function(properties) { - var data = this.getClimateControlData(); + var data = this.generateClimateControlData(); data = SDL.SDLController.filterObjectProperty(data, properties); if (Object.keys(data).length > 0) { FFW.RC.onInteriorVehicleDataNotification({moduleType:'CLIMATE',moduleId: this.UUID, climateControlData: data}); @@ -467,7 +477,7 @@ SDL.ClimateControlModel = Em.Object.extend({ getDataForSending: function() { var dataForSending = []; - var climateData = this.getClimateControlData(); + var climateData = this.generateClimateControlData(); var climateEnable = climateData.climateEnable; if(climateEnable) { for(var key in climateData) { diff --git a/app/view/climateView.js b/app/view/climateView.js index 8b1ea43cd..2d9b1a8c4 100644 --- a/app/view/climateView.js +++ b/app/view/climateView.js @@ -125,6 +125,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'desiredTemp_minus', classNames: 'minus', templateName: 'icon', + disabledBinding: 'parentView.disabled', icon: 'images/climate/minus_ico.png', onDown: false, model: 'currentClimateModel', @@ -156,7 +157,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'desiredTemp_plus', classNames: 'plus', templateName: 'icon', - model: '', + disabledBinding: 'parentView.disabled', icon: 'images/climate/plus_ico.png', onDown: false, model: 'currentClimateModel', @@ -188,6 +189,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'fanSpeed_minus', classNames: 'minus', templateName: 'icon', + disabledBinding: 'parentView.disabled', icon: 'images/climate/minus_ico.png', onDown: false, model: 'currentClimateModel', @@ -208,6 +210,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'fanSpeed_plus', classNames: 'plus', templateName: 'icon', + disabledBinding: 'parentView.disabled', icon: 'images/climate/plus_ico.png', onDown: false, model: 'currentClimateModel', @@ -239,6 +242,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'currentTemp_minus', classNames: 'minus', templateName: 'icon', + disabledBinding: 'parentView.disabled', icon: 'images/climate/minus_ico.png', onDown: false, model: 'currentClimateModel', @@ -269,6 +273,7 @@ SDL.ClimateView = Em.ContainerView.create( elementId: 'currentTemp_plus', classNames: 'plus', templateName: 'icon', + disabledBinding: 'parentView.disabled', icon: 'images/climate/plus_ico.png', onDown: false, model: 'currentClimateModel', From 29049123977dd9dcd93a0ffe333181ccdefbf5c9 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Wed, 7 Oct 2020 20:07:15 +0300 Subject: [PATCH 059/104] Use reference to object inside of timer callback (#406) Co-authored-by: YarikMamykin --- app/view/sdl/AlertManeuverPopUp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index 0374decfb..9d11ba546 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -178,7 +178,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( var self = this; this.timer = setTimeout( function() { self.set( 'activate', false ); - this.set('endTime', null); + self.set('endTime', null); FFW.Navigation.sendNavigationResult( SDL.SDLModel.data.resultCode.SUCCESS, message.id, From 958a50bf414518d7d5105e0cc80b72957093d001 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 9 Oct 2020 09:59:39 -0400 Subject: [PATCH 060/104] Fix double send of BC.OnReady notification (#400) Looks like due to EmberJS internal issues observer function was triggered twice for the same state which causes extra sending of OnReady notification. To avoid that issue, components readiness will be perofrmed directly from the caller function. --- app/controller/sdl/Abstract/Controller.js | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index e9c0e2b23..39ebda844 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -342,9 +342,13 @@ SDL.SDLController = Em.Object.extend( for (var i = 0; i < SDL.SDLModel.data.registeredComponents.length; i++) { if (SDL.SDLModel.data.registeredComponents[i].type == component) { SDL.SDLModel.data.set('registeredComponents.' + i + '.state', true); - return; + break; } } + + if (this.areAllComponentsReady()) { + FFW.BasicCommunication.onReady(); + } }, /** * Registered components handler @@ -465,19 +469,19 @@ SDL.SDLController = Em.Object.extend( ); }, /** - * Notify SDLCore that HMI is ready and all components are registered + * Checks whether HMI is ready and all components are registered * - * @type {String} + * @return {Boolean} */ - componentsReadiness: function(component) { + areAllComponentsReady: function() { for (var i = 0; i < SDL.SDLModel.data.registeredComponents.length; i++) { if (FLAGS[SDL.SDLModel.data.registeredComponents[i].type] != SDL.SDLModel.data.registeredComponents[i].state) { - return; + return false; } } - FFW.BasicCommunication.onReady(); - }.observes('SDL.SDLModel.data.registeredComponents.@each.state'), + return true; + }, /** * Show VrHelpItems popup with necessary params * if VRPopUp is active - show data from Global Properties From 0fb5bb31e48cbe2f512ceff5e0e80bbaf755923f Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 9 Oct 2020 10:54:28 -0400 Subject: [PATCH 061/104] Remove sending of steeringWheelLocation (#399) --- app/Flags.js | 1 - ffw/UIRPC.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/app/Flags.js b/app/Flags.js index c84a50fdc..0fe90c956 100644 --- a/app/Flags.js +++ b/app/Flags.js @@ -54,7 +54,6 @@ FLAGS = Em.Object.create( Navigation: null, CAN: null, RC: null, - steeringWheelLocation: 'LEFT', /** * 0 - G * 1 - R diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 30e5cf0fd..8b7b29789 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1531,8 +1531,6 @@ FFW.UI = FFW.RPCObserver.create( 'method': 'UI.GetCapabilities' } }; - JSONMessage.result.hmiCapabilities.steeringWheelLocation - = FLAGS.steeringWheelLocation; this.sendMessage(JSONMessage); break; } From 59ef293cb33f046b23097afe432bbb119b453977 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Fri, 9 Oct 2020 19:15:32 +0300 Subject: [PATCH 062/104] Fix HMI shows seat params for one moduleid (#381) * Change SEAT module id to select view * Add updateView method to SeatModel * Fix setting temporary data of SeatView * Update SEAT module uuid with SeatLocation change * Generate seatUUID list for seatModuleUUID view Co-authored-by: YarikMamykin --- app/controller/sdl/RCModulesController.js | 8 ++++++-- app/model/SeatModel.js | 9 +++++++-- app/view/settings/SeatView.js | 17 +++++++++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/app/controller/sdl/RCModulesController.js b/app/controller/sdl/RCModulesController.js index 1a2a904fb..bb6f1002b 100644 --- a/app/controller/sdl/RCModulesController.js +++ b/app/controller/sdl/RCModulesController.js @@ -372,6 +372,7 @@ SDL.RCModulesController = Em.Object.create({ break; } case 'SEAT': { + let seatUUIDs = []; module_coverage.forEach(module_service_area => { var location_name = SDL.VehicleModuleCoverageController.getLocationName(module_service_area); self.set('seatModels.' + location_name, SDL.SeatModel.create({ @@ -379,7 +380,9 @@ SDL.RCModulesController = Em.Object.create({ UUID: this.moduleUUIDMapping[module_type][location_name]} )); self.seatModels[location_name].generateSeatCapabilities(module_service_area); + seatUUIDs.push(this.moduleUUIDMapping[module_type][location_name]); }); + SDL.SeatView.id.seatModuleUUID.set('content', seatUUIDs); break; } case 'AUDIO': { @@ -662,12 +665,13 @@ SDL.RCModulesController = Em.Object.create({ updateCurrentModels: function(location_name) { this.set('currentClimateModel', this.getCoveringModuleModel('CLIMATE', location_name)); this.set('currentAudioModel', this.getCoveringModuleModel('AUDIO', location_name)); - this.set('currentSeatModel', this.getCoveringModuleModel('SEAT', location_name)); this.set('currentRadioModel', this.getCoveringModuleModel('RADIO', location_name)); this.set('currentHMISettingsModel', this.getCoveringModuleModel('HMI_SETTINGS', location_name)); this.set('currentLightModel', this.getCoveringModuleModel('LIGHT', location_name)); - this.currentSeatModel.update(); + SDL.SeatView.id.seatModuleUUID.set('value', this.moduleUUIDMapping['SEAT'][location_name]); + SDL.SeatView.id.seatModuleUUID.trigger('change'); + this.currentRadioModel.update(); this.currentAudioModel.update(); this.currentHMISettingsModel.update(); diff --git a/app/model/SeatModel.js b/app/model/SeatModel.js index eaebcfb66..714df9616 100644 --- a/app/model/SeatModel.js +++ b/app/model/SeatModel.js @@ -208,6 +208,11 @@ SDL.SeatModel = Em.Object.extend({ SDL.deepCopy(this.tempSeatControlData)); }, + updateView: function() { + this.set('tempSeatControlData', SDL.deepCopy(this.seatControlData)); + this.update(); + }, + goToStates: function() { this.update(); }, @@ -231,7 +236,7 @@ SDL.SeatModel = Em.Object.extend({ } this.tempSeatControlData.memory = this.seatMemoryAction; - this.set('seatControlData', this.tempSeatControlData); + this.set('seatControlData', SDL.deepCopy(this.tempSeatControlData)); var memorySlot = "1"; this.memory[memorySlot] = SDL.deepCopy(this.tempSeatControlData); this.createdMemory = memorySlot; @@ -285,7 +290,7 @@ SDL.SeatModel = Em.Object.extend({ break; case 'NONE': - this.set('tempSeatControlData',this.seatControlData); + this.set('tempSeatControlData',SDL.deepCopy(this.seatControlData)); break; } } diff --git a/app/view/settings/SeatView.js b/app/view/settings/SeatView.js index ed1cd87ae..5329a8868 100644 --- a/app/view/settings/SeatView.js +++ b/app/view/settings/SeatView.js @@ -963,10 +963,23 @@ SDL.SeatView = Em.ContainerView.create({ content: 'ID' }), - seatModuleUUID: SDL.Label.create({ + seatModuleUUID: Em.Select.create({ elementId: 'seatModelCurrent', classNames: 'seatModelCurrent', - contentBinding: 'SDL.RCModulesController.currentSeatModuleID' + change: function() { + var desiredUUID = this.selection; + var location_name = ''; + for(var key in SDL.RCModulesController.seatModels) { + if(desiredUUID === SDL.RCModulesController.seatModels[key].UUID) { + location_name = SDL.RCModulesController.seatModels[key].ID; + break; + } + } + if(location_name != '') { + SDL.RCModulesController.set('currentSeatModel', SDL.RCModulesController.getCoveringModuleModel('SEAT', location_name)); + SDL.RCModulesController.currentSeatModel.updateView(); + } + } }) }), From 2cfbe48cde1a148666284db13a28671fb59bd8ec Mon Sep 17 00:00:00 2001 From: Yurii Postolov <32772773+Ypostolov@users.noreply.github.com> Date: Fri, 9 Oct 2020 19:35:28 +0300 Subject: [PATCH 063/104] fixed OnInteriorVehicleData with incorrect type on press XM radio perset button (#341) Co-authored-by: yurii --- app/model/media/AudioModels/RadioModel.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/model/media/AudioModels/RadioModel.js b/app/model/media/AudioModels/RadioModel.js index 92e2391fd..fa456ea37 100755 --- a/app/model/media/AudioModels/RadioModel.js +++ b/app/model/media/AudioModels/RadioModel.js @@ -1192,19 +1192,18 @@ SDL.RadioModel = Em.Object.extend({ this.setFrequencyInteger(parseInt(data)); } if (this.radioControlStruct.band === 'XM') { - this.setFrequencyInteger(parseInt( - (function(value){ + var getBand = function(value, stations){ var kArray = [], vArray = []; - for (key in this.xmStations) { + for (key in stations) { kArray.push(key); - vArray.push(this.xmStations[key]); + vArray.push(stations[key]); } var vIndex = vArray.indexOf(value); return kArray[vIndex]; - })(data) - )); + }; + this.setFrequencyInteger(parseInt(getBand(data,this.xmStations))); } this.updateCurrentFrequencyInfo(); From 590876aca553dc00eb123c7bf9c7642749f3d309 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Tue, 13 Oct 2020 09:39:04 -0400 Subject: [PATCH 064/104] Fix AlertManeuer soft buttons behavior (#348) The following changes were done to implement this behavior: - Timeout and request id fields were moved outside the function as it can be called from a several places - Added correct values for groupName and appID fields for AlertManeuer preset buttons - Was created separate function for AlertManeuer popup proper deactivate including TTS stop - Controller were extended to handle preset events from group of buttons on AlertManeuer popup --- app/controller/sdl/Abstract/Controller.js | 24 +++++ app/view/sdl/AlertManeuverPopUp.js | 125 ++++++++++++---------- 2 files changed, 93 insertions(+), 56 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 39ebda844..863e5cd44 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -587,6 +587,11 @@ SDL.SDLController = Em.Object.extend( SDL.AlertPopUp.deactivate(); break; } + case 'AlertManeuverPopUp': + { + SDL.AlertManeuverPopUp.deactivate(); + break; + } case 'SubtleAlertPopUp': { SDL.SubtleAlertPopUp.deactivate(); @@ -633,10 +638,17 @@ SDL.SDLController = Em.Object.extend( this.onActivateSDLApp(element); break; } + case 'AlertManeuverPopUp': + { + SDL.AlertManeuverPopUp.deactivate(); + this.onActivateSDLApp(element); + break; + } case 'SubtleAlertPopUp': { SDL.SubtleAlertPopUp.deactivate(); this.onActivateSDLApp(element); + break; } case 'ScrollableMessage': { @@ -670,6 +682,17 @@ SDL.SDLController = Em.Object.extend( this.onResetTimeout(element.appID, 'UI.Alert'); break; } + case 'AlertManeuverPopUp': + { + clearTimeout(SDL.AlertManeuverPopUp.timer); + SDL.AlertManeuverPopUp.timer = setTimeout( + function() { + SDL.AlertManeuverPopUp.deactivate(); + }, SDL.AlertManeuverPopUp.timeout + ); + this.onResetTimeout(element.appID, 'Navigation.AlertManeuver'); + break; + } case 'SubtleAlertPopUp': { clearTimeout(SDL.SubtleAlertPopUp.timer); @@ -679,6 +702,7 @@ SDL.SDLController = Em.Object.extend( }, SDL.SubtleAlertPopUp.timeout ); this.onResetTimeout(element.appID, 'UI.SubtleAlert'); + break; } case 'ScrollableMessage': { diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index 9d11ba546..806ded874 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -53,6 +53,8 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( activate: false, endTime: null, timer: null, + timeout: 5000, + alertManeuerRequestId: 0, /** * Wagning image on Alert Maneuver PopUp */ @@ -116,75 +118,86 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( * @param {Object} params */ addSoftButtons: function(params) { - if (params) { - var softButtonsClass; - switch (params.length) { - case 1: - softButtonsClass = 'one'; - break; - case 2: - softButtonsClass = 'two'; - break; - case 3: - softButtonsClass = 'three'; - break; - case 4: - softButtonsClass = 'four'; - break; + const softButtons = params.softButtons; + if (!softButtons) { + return; + } + + var softButtonsClass; + switch (softButtons.length) { + case 1: + softButtonsClass = 'one'; + break; + case 2: + softButtonsClass = 'two'; + break; + case 3: + softButtonsClass = 'three'; + break; + case 4: + softButtonsClass = 'four'; + break; + } + + for (var i = 0; i < softButtons.length; i++) { + let get_template_type = function(button_type) { + switch (softButtons[i].type) { + case "IMAGE": + return "icon"; + case "BOTH": + return "rightText"; + } + return "text"; } - for (var i = 0; i < params.length; i++) { - let get_template_type = function(button_type) { - switch (params[i].type) { - case "IMAGE": - return "icon"; - case "BOTH": - return "rightText"; + + this.get('softbuttons.childViews').pushObject( + SDL.Button.create( + SDL.PresetEventsCustom, { + softButtonID: softButtons[i].softButtonID, + icon: softButtons[i].image ? softButtons[i].image.value : '', + text: softButtons[i].text, + groupName: 'AlertManeuverPopUp', + classNames: 'list-item softButton ' + softButtonsClass, + elementId: 'softButton' + i, + templateName: get_template_type(softButtons[i].type), + systemAction: softButtons[i].systemAction, + appID: params.appID } - return "text"; - } + ) + ); + } + }, - this.get('softbuttons.childViews').pushObject( - SDL.Button.create( - SDL.PresetEventsCustom, { - softButtonID: params[i].softButtonID, - icon: params[i].image ? params[i].image.value : '', - text: params[i].text, - classNames: 'list-item softButton ' + softButtonsClass, - elementId: 'softButton' + i, - templateName: get_template_type(params[i].type), - systemAction: params[i].systemAction, - appID: params.appID - } - ) - ); - } + /** + * Deactivate PopUp + */ + deactivate: function(message) { + if (SDL.TTSPopUp.active) { + SDL.TTSPopUp.DeactivateTTS(); } + FFW.Navigation.sendNavigationResult( + SDL.SDLModel.data.resultCode.SUCCESS, + this.alertManeuerRequestId, + 'Navigation.AlertManeuver' + ); + this.set('activate', false ); + this.set('alertManeuerRequestId', 0); }, + AlertManeuverActive: function(message) { this.get('softbuttons.childViews').removeObjects( this.get('softbuttons.childViews').filterProperty('softButtonID') ); - var params = message.params; - if (params.softButtons) { - this.addSoftButtons( params.softButtons ); - } + this.addSoftButtons(message.params); - this.set( 'activate', true ); - this.set('endTime', Date.now() + 5000); + this.set('activate', true ); + this.set('alertManeuerRequestId', message.id); clearTimeout( this.timer ); - - var self = this; - this.timer = setTimeout( function() { - self.set( 'activate', false ); - self.set('endTime', null); - FFW.Navigation.sendNavigationResult( - SDL.SDLModel.data.resultCode.SUCCESS, - message.id, - message.method - ); - }, 5000 ); + this.timer = setTimeout( () => { + this.deactivate(message); + }, this.timeout); } } ); From ff3398d3606f5fa1957eeacfa9600f7ad2df2045 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Tue, 13 Oct 2020 16:41:11 +0300 Subject: [PATCH 065/104] Add check for FFW.CAN validity (#373) * Add check for FFW.CAN validity * fixup! Add check for FFW.CAN validity Co-authored-by: YarikMamykin Co-authored-by: Andrii Kalinich --- app/model/media/AudioModels/MediaCDPlayer.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/model/media/AudioModels/MediaCDPlayer.js b/app/model/media/AudioModels/MediaCDPlayer.js index 06fa787e6..fa1424e0b 100644 --- a/app/model/media/AudioModels/MediaCDPlayer.js +++ b/app/model/media/AudioModels/MediaCDPlayer.js @@ -204,6 +204,11 @@ SDL.MediaCDPlayer = Em.Object.extend({ this.prevTrack(); } + if(!FFW.CAN) { + Em.Logger.warn("CAN module is not available. Notification won't be sent"); + return; + } + var self = this, media = self.data.get('selectedItem'); @@ -227,6 +232,11 @@ SDL.MediaCDPlayer = Em.Object.extend({ playTrackPress: function() { this.play(); + if(!FFW.CAN) { + Em.Logger.warn("CAN module is not available. Notification won't be sent"); + return; + } + var self = this, media = self.data.get('selectedItem'); @@ -250,6 +260,11 @@ SDL.MediaCDPlayer = Em.Object.extend({ nextTrackPress: function() { this.nextTrack(); + if(!FFW.CAN) { + Em.Logger.warn("CAN module is not available. Notification won't be sent"); + return; + } + var self = this, media = self.data.get('selectedItem'); From b8fd838eda95e283f71965270241cebe88898910 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Tue, 13 Oct 2020 10:17:34 -0400 Subject: [PATCH 066/104] Fix preset name for OK button (#333) * Fix preset name for OK button Starting from release 5.0 HMI should use PLAY_PAUSE preset name instead of OK. * Make OK hard button switchable * fixup! Make OK hard button switchable --- app/view/home/controlButtons.js | 11 ++++++----- css/buttonControls.css | 18 ++++++++++++------ .../home/controlButtons/PlayPauseButton.png | Bin 0 -> 7776 bytes .../PlayPauseButton_pressed.png | Bin 0 -> 7935 bytes 4 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 images/home/controlButtons/PlayPauseButton.png create mode 100644 images/home/controlButtons/PlayPauseButton_pressed.png diff --git a/app/view/home/controlButtons.js b/app/view/home/controlButtons.js index e021b29fc..bc3387869 100644 --- a/app/view/home/controlButtons.js +++ b/app/view/home/controlButtons.js @@ -624,17 +624,18 @@ getCurrentDisplayModeClass: function() { OkBtn: SDL.Button.create({ elementId: 'OK', classNames: 'OkBtn', + classNameBindings: 'SDL.States.media.active:media_button', time: 0, - presetName: 'OK', + getPresetName: function() { + return SDL.States.media.active ? 'PLAY_PAUSE' : 'OK'; + }, actionDown: function() { - this._super(); - SDL.SDLController.onSoftButtonOkActionDown(this.presetName); + SDL.SDLController.onSoftButtonOkActionDown(this.getPresetName()); }, actionUp: function() { - this._super(); - SDL.SDLController.onSoftButtonOkActionUp(this.presetName); + SDL.SDLController.onSoftButtonOkActionUp(this.getPresetName()); } } ) diff --git a/css/buttonControls.css b/css/buttonControls.css index 1f0d49cd0..5c3c0e1bf 100644 --- a/css/buttonControls.css +++ b/css/buttonControls.css @@ -453,13 +453,19 @@ -webkit-transition: 0.2s; } -#OK.pressed { +#buttonControls .OkBtn.media_button { + background: url(../images/home/controlButtons/PlayPauseButton.png) no-repeat; + background-position: -55px -55px; +} + +#buttonControls .OkBtn.media_button.pressed { + background: url(../images/home/controlButtons/PlayPauseButton_pressed.png) no-repeat; + background-position: -55px -55px; +} + +#buttonControls .OkBtn.pressed { background: url(../images/home/controlButtons/OkButton_pressed.png) no-repeat; - background-position: -55px -55px !important; - width: 89px !important; - height: 90px !important; - left: 55px !important; - top: 55px !important; + background-position: -55px -55px; } #app_controlButtons { diff --git a/images/home/controlButtons/PlayPauseButton.png b/images/home/controlButtons/PlayPauseButton.png new file mode 100644 index 0000000000000000000000000000000000000000..4541786f267dc1c0e9683ad00cce89d472c8a0c7 GIT binary patch literal 7776 zcmeHs=UWr)6YdhE2myjf2t6P#qJYwkG(!`36;P27s-Xr1BubGY5PAdzL_n%k!BwMVVXFu%B?%Z?lGjq@D2Zp+AEPN~g0I=!nX+NS} zJO6huGt$l_=+X}WAaqqU31;N1mT-cIFejD~0!Yl+bc`Yp?xm-I6Z20awi|v_+4gZfPpClZ5Pbn}gz5=PjD( zW~XMLPPTMRgu2N8-KkTd5{`7(cw6rs^S9_Gx=Y`XC(h7HJbix3WIaj@ioWYlP{iw@0}o*4alp;-@z{r{W!zZ09gCN4j6b?i_? zYqh$1diCiC|3Cl5eYPP^l+)l8 zOfRlvk;nE4kOvG^*z%o~;i3T~^L4C#!hJ#S^EHffTJ=egS6V@k;lQqu==MZ`LHY*^ z(o+*gv7j>rT7sNj@LpeC9nT|^4-Wkr0)0wQ#<&;_dHny!{nbB={`zNw5taCN*I(Vh7aR=gqz98a2xF`<1m zR3ybMlv3!H?_7JsV1U0PR?vUFD@n3Z;Pej1IGU-2#AXShoBW^g{W|f$JDdg?zb`f2f z=1tcr3|_UVtY!RQUmmatwxxTjE}3U}I_1AHiKcqymCgdon8V13hy^kIZ6?lC!54b0 z0FZA+2$vH<^>0W)QVhPV`f5IDEZl#8Re#&4$dnjJ3LS{8{Y0PtW@gwcTG3_5^1A5p zds&dcqf8>N4Col6JsIB;nbBZ&E8T&Dp6);Crr{otdZV%G`SC-Z=lCkvc{nT2pNGWZ zzgpVR2y~t`@fOfh=_Qe2i`5xb#b--9K+5zaPAewKyrru6r+#Sd*psEaI90`oRwe>&*}&`%6l|a-dY4BbHaAu<(43(8?--) z{VS+wfIun>pHnE5AiaUdsdkpk0#NY2d}v5pt+H&!Eu)tTtJ3l;mG^~4irX)Sg{CKn z-L_dDBmEt$Nvds(kk`Y+DBk-=^j4YOT!V6;JPy~%5FeKDUL&{BWwgHMa;3hJkrDLg zjEW;$sk_(3EY?a^=T8HThqJ8TU+@Ou@UT!Y8=F;H!SYYueLJ3ea}e+6Kb~IwBdpnEW3W3;Y&@&f3Uou=$`Rc$^ z#uAAUaLjS{HNQARl|jdjm)W#fv0q}+TcBsQI#_}~*ah&j~m@W5ct{A_WW_*eaS4YdoFLm z_WxP3C%Nji%{-Qv0KuudkST(jGF*u9>P4<;|0&<1$<;TgwL|H8r)M zI-8aVBRj{0PjtDG^De`s0VwTr_F@WPgQPYLUg=R%GPZA%E%ce`clxfZ8gv)I0F1Y3 zIbPz=%@G{BQmh4o_uOcq1_aKvzX_Eke$i!%r%*H|aXxRoTp2@^qt1GiFNj=L5mb?D z=7IhwW<%K9BAtDgxS*R$l95lC2Q_QMbYAIY%Oer5#E@stXsGgZbcy}|*<&!sn?YxJ z*6ST>HfAj$S1yN?_hE2o@BZ(QAGFMbKY-eBr{Fd4@qNlSW4Tzq6{E?3#**G^`bkEa zFTOhqi*^_E69HcK5^Mbdh4G~Bn5Hq!VWlRxfcbOtM8POU#_vNbWj$hRP8g;#q)?rN zOjQh9L;Q6|ihDOz;9-{5HCBkBI;3*t1~t?UOv=4LD1Axj?8P~;=fNQRYWT1Xk*Bin zJTl_!La(7eRnpVL1@1ZvBIGj?gxnP+j`ojCZx!865 zlGi*9$rHH2z?!35PCv^uoj^Uo5sUUxM{p?sj!#tHc^o=u2^$V*8l$C~R|UWd8BEcE zH=?W8lA-)}gY~75kXW_@-HpTwGC|wp3gHtVCnHn#n8*SykMx2-S0TSe=v=~Y7h2AA z4lO?vulj-wrld;Xn<^3=xXS2L7-E`5gt1dH*PO-yW_rRn7w2Tp;W!#C#)n@DDEg^z zCSfq}8qjlUxRS4iP6woLD8!ZKf6nfBuZ>8(qE9bdYL5}Vv@*1e4n;o*6G)8v)&o*9 zM#>@fEFZGNFVeN*y)y}G*F+yqyp-g_?;afd{Y=|-7%MvIe?wC&`f6$r^rJ}EWuEq#`%?M|O zO8M{&CymEnQ}7>i<&G3lO>Ys=a<;T5BNQswS%C6G$Bs&~!uX|yJ z2N&m^>A>25`~K`#U#Wp7WwyZ0&p@0-wvi%!{@x}Fx1*|z5+m2K97gLQ1&ZUt$^ewPR%iY?aoZL|m|3!c2aszsR66-p{O2BER)(S698d`8uV88ljt?=@5d>|0 zad-nsFWbiq0Wjc3u`aqKWb+~wcI#Qj1g?c`yYot1Ck+6F**||W{+auaBgafA8eVUU z4+-8BzBbh_-kagPzo9dq^UU#WDU)7M(BDDPZT_M=Fo^d$y_vueJ%$^xlX%T|p2kDh zi4fiHF)){-tJ>FdMh$lo%gxWY8ds%oR^Fh@!ylbFy7K$wg6yd{%fxOD&Ybk@h0Gt^UI zxW*9U%q6U6vD4l9pg%Q>UA))~5nUnQeAU0FJ8#|)GD_QA`$omAO~|Y8!&f6Vk>7sk z3QI@x-0ZthDfexn#)AwCxAGo!XnpBkzZJ3ewa!{Yb(^%)r-HRfJKypHf3-`VsB$(= zPHG7nk?dfoRiEUi4=tvYXzlDW-DLk9T4XFYhgaNHDbA2Y_T660=yCtxyTI#94Q7&S zC<{D0rV5U(A2T&U#-44@zcX^o{&If2S~(X7g@eUdAu<=ype8E!o;bL|8y)%BhsAAb zuauD%*~Te?23>*~#gUkO2VG1Lm*8l?rwVT!G4NRS1I)X<5p4YPzl@ENu72>zm9?w% zah&PNVUM(YchxAF$J$3D_VxnI_ji)1IVfyc7gcJ>YY$NqZ7xA<*uyfG#i8OiAdmQ?{ zD@1XGqUi6nnEA46`**hv1H$p39&(SwAbgbr&S$F;gkLXXY-ys*Hvu*Q3G^X4qA!T_ z`61AhJ3)cok`KWz^s+4&%N@``@YA0gm*Lo~$tjZ7lUG|hjF$~Y1J92Z+3uMujk-6U z$>EpyIt#M`#{d&~JUsg2UyE>bhUn0?o=RmqexEw%DPtJRD#iJ>wBa(jNUNB}j>lQd zq+g)0wpuHV#WPdLe8#L!*M9v@pUXG+P>%W`mEL#dze4-vpC2op&$V+F=Q_k8W|_?@ z?DZKT-d(!F0SYN?D`6Utf452uy)4w5?>heL2q9@izqjW9NxD`4#~W{%B=+s7Q*U(h z+cUStO;+SZXNcG5o$q%V?eJxJ&d{|{Y*y02bkLm>^An$)-do+>HyfqM(}DhTDggsv zcn_`!Rl*XrOGC`-0u|8!hQAmp)xs|YN=?2WOd`^<>&cU8f{rG?`g0WPMmdqiR^T|? zw4cm~-2GD9f4GqD-nCqq_2FZriGRkc?Qh#Z@7;WZt40BIP1~Bq`tQUYc%J8EOvX7} zg{ZxBK-`B(t2P$#u+|B|ozu=4n-eR|Ao&@yZU0szGa;#}r%$@A{FXoFN)G4w2Apnn zZ2zg-a0F6sxqrxb(RJ;`T6sqot*E?fIr0k(m)hQeY3tN7FkrvKPRoKp7v4qC+biVN zvklXluL0>lZy>C|#q|XexH%odi)Pj@t@~3eC1|nhwbjPcJz#W4dZT{FP&|3>Y?avf zp`>r;-uQsq)tn?x2gb4xWnX#x2-`bvyMIQKbo|nRElANPuG665)zwx0ttyEkjcrXS zf*(M?7QA`y&a}_mn->$$JG?xj_#R1HR7=@qZ8ZM7o~d3>{(<(#9C zj^G(_7hOc=&TLmYNqF-WTg+Xc6aBXA6?r~U=Z}7 z8rN7fiPpO+J`)RmeDj%94xm-QvdHna?{$=Ti(f6lbG?$S&OEdy{nmyA=Z_A=t$mat zJt4W$^e4p`7i3j-PX)Y9%bIVB!%0xH})x z7Y5Ja?*_qe7I2t}xsXaUFFXZE)H!TtlU`7LA~6x6my=i8lc_>B(zb2|cT@3pRFxt4 zA-hy=b}$zR-V2+jF*vDiWVIrOpb>EYJ)Z1l~phq{9QY&0B95j>>~ zl{nyC;9`w!pkgjo#Ssj`FV!6E?<=K*5(6HpIQcN(t86xpM7Il-x=bqcOyxT@m;@DS z$YgT4SvfBcY8#H59rXo~#@K1R)g;_(*RwTLOmbgV?6^_qA%rn_W2;; z-VNu8fhc3Lxo(_bm#sktLRLlW(U)Ezw~pEHN1DDeAbg#+i4>H>EzM@LJh#tp zx`AP0E7t_)?)e7Hm5`^p8Zay!t^1c484G<>ehCLs9uHoPsPR~|&J@$1ORzAUlnbT$ zLzltgUfPH_W%9G>rU*?(@an`+;0V`8FHb?8mLhs~1oG?ALOLVTN0P9wQEB<=n>60z z==Xc9D}z;j`qiTZ3jy7mH98?p>dL`pB>ef(ipj34R1rHKb#{kVj09a1 z%s0Afm3ff>hNzFdONr@GZY#A4gS8|-TzC+_)GX302e64|HbxGF2B3-A84TRhN1U#9 zl!%Kt$o(#Nf#Fj6XRE*2m6x*DhVoK+rI9Hnh?ol7Oso|`stX>@Vj)w6Q%h_KlI(eI z$xif1t2}F z3shVWAyfmGhm7(taivBZO5$0c5rmx8f!kA z_88u1o%sdTWQ?o}gJPtlx$vs!K02kmM7*q$#8!yQsPExPX^XH1Sdp!37jR_~Oie1Z z4ES25+Xp)De%ak!2@$805$NV3cqcmX}#HcWkHHyal1pt z1>6oZS6rKjcw1ZBseZC1Z=!8Yu^StCTVfn35JSRCyEEXdmAY2=0q%%J!TKJ}2_bqA z@;CM-6o@SK`t%1qImq5WJ8z4P?@^`wxGessYZ(oA3b?ScmuMRHRR2Dlmb)(@Wmnj- z(Sw3A_lTl;T8=n>Y9xjlY>yPZc3;XX3A`a%drfxbJ-xlp;Q>uxwHr`q80hOlMWeCR z@EIAl?DAopf=UEi4x}Kw!U+mPC2CDy-o!N&u2?awcv*2XF|#fI`p@{gUc!7WDn#u& zrGy#FIUTzgh9=N~B0HY@GE6^>0~H6~Soyc6H04AxB3;Q-xyzr{HU0E!C^ag0nja+V zzu2~=T1PLIBl#D1|4jJOR8D_SNYb#gW{wG638nWgiL+dA8pn7M?c9}k4V&-mC+KKX z=L0k6u~{5GsLvE@Mfj$Lbms~(!dJnLi4R7-1@K)MyOwc9Bx6kyFF)ToLGg@L z;}3L;yjWoTC`B$RLcNyfr%oQgz+OaVS2Nd6_EO`%tg6AJ$J(+^E64qRt?vE()utWx zus-!ifu)LIWc<7F$MURyN&ptmhvZlZ#QB(WmfiIYz}da3<9-I>xpP_p&uF)M$v$&H z-$|+2Bx?1>x|a$$@tJT9Vu5?xdwmgb9)2Y1SGioX=XW-pAeK7$?D`ijoPy-I#;tVj zL93d3wMV`}7T*ltw9u4d@>0syTt^m)IQ%}Uv-JTYOlu)r%R=`4Q}Tgd9z#HKw)%DH zTItnwzH5*B=pOa^af#ngsee9qHz4E>ac`y75H-Q7WR{<1&EOMFaMI)M^_tfKCz*E8 z$@#e$t}HL#zNc;2A|3uObCUU(EE@ABP=JeG#l5n|utl&&i#^^@jd5msQxp603iC z9jXaylA@yqYYJDCz(N5;IFgXBX(1f)>6-a>q}%#ir{}6ndfyli7Ct-BhH9ktZhwmk z+ROaIKapOPOj``{-P~~dMzfdbigPbDr!5}4)Yp^$p$+mLRZtpgo|@4XC0pB5$*#2L i|G%OCS7Jo{3v`rQ4q4pwzDt`N1Nu6K+NGM9kpBZxWtyY_ literal 0 HcmV?d00001 diff --git a/images/home/controlButtons/PlayPauseButton_pressed.png b/images/home/controlButtons/PlayPauseButton_pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..d5accf64133d87a8483aef48e0aa599683b8cdc3 GIT binary patch literal 7935 zcmeHs=T{S7)OA7^5Q0FY6RJQGq$wQ&1f{7U5?bh0O6X0Bp-Gb}ASeh3{*Ycn3mxfA zTIf}(Gz9^rK6(Cx_v5?PbJm)fJs;+td(XLZ*4cN*=staXo0^Rp007+9)IdHbKKuUn zqM{()%Z$oD0RUV*nn;xw{^t8;&Tq}8e9X7Zd+9^NB3Rkk=F>n_1rdVJ1ISXTpie>o zdih8r@;jgcfjfN^WO+cVTu3e$g&;GT{2D2uJK4ir@e7ogu(kRdTUFJ;V$Evm83unF z9vRa?Hab*B_a~Bek88!9%}O)ec-?9slMqO1a6yxZ zhPvF6L7?T)Bv1HP03Ijq|NBOXCi%y|0_M+IP%z}bp{ z6m$5@XG9R>d5lihXb0ZuM+8bAYqkSZo?$*g?+{1fWpzBXS0aL={$Ve5ULd6gKk5GB z&^;nhY78jXAi9gO&29Ne^aSX?Cq2p>L&gC~rmgjp%prn*>zj?d$yieUl+aVm<~t(z zzsdYRL}os3vpBYI8o5r!Alqy{*XO}o4SA-*dnC^gV2XUBUeI<;57~f?*E}Gmz}EB64{cu0yy&1pI$9jd zyWfRi_0XfRXa#;=dBOaYj6rW~kZ*oP`S{r_mK?Kw*VI)09o<&lq8D6joSeZr$jJxC zZEC4l(sdBI5bxvIzA0W$G zVi-_z4rpw|!h}+m71Z}8aMQ~IXL7aimQ@mS^Q()VQ;4&#foGZ{Kq0QrnxXLtGC@d- z1q?vDwTBg?M_iu?YF2ySTwk3rPc31Jdf^%leE+6-j}A{jt`4&E8m@4)zUR3aT3;mc zkbtl<>hT?i6n^&Nsh`Swi+DdX_Tk_BKdYOV=2Eba@-W3W^=WyFNSK*Nk|uSwGvK`Iq^v&!uf8`UTYy+r{rGlGWDEjN&@&@m_HaN>cWi) zQG*YC&J0D;xLa?oFSyt+5-xN}n{s6|K~Q8tA?~L`;fgU@-=Ku@y}Ez;ArnVgDGlkU zCzDZ%6RrvWyeO;QdAfW_ZO1}-%Li+lc(6PLk1CJwyX?*V?)+ozE%bgOIV(H+N8LwY zM_ncC%em8+Dg1Z$=Wx5PdamVlm|v}epIniBRtn{>wIOog|ETbI<# z6-Li7@Mv-^&US6zgM}SEQORw(q!=Mxi4g6=mCE+-hsDtZIU_sViIKqc7A-}=mUo^6 z{ObzJc%*B;e9B4saG_DZAAd6?umWJMpl)KjuE=(xT)0Obfn(!H9(NYPhd7z|q?IyP zoh4E3teCF`);x1I%lJwP15_)qv$NxadJ{O${6xYrPYwb9j{D3Zyf;(*h?+EAfsYSe zO+J_@=dDw7wGg&+QS$g2`R@xckE^PxxLc1$ zn*?=`Ksr0Mwqo``W;69Q(7bEah zdHa|$hSU^R{`h$8L!XRvC0+Wn-kzS3xz^yoKVxvp=)N)DqgVIx&<3In`ju>@?t6ED z97CLcK5goMd1MT@ZF*ZsVxY3QD~u8a{iZpiCElKKuOnr0;^6uR_sw5Jyx(C+y=j@6 z{8cO`qzN*1k9XPeu~9~z)dLnLcRv=YSHnR(an6wYc=aKus-DQEu&zs;oO?Y$VYjDB zy=pqzGp4V&%(PzgZ9uo8FLwKl+G6rNf!m+L>-I3!T}rG~dB;FvrfC{GDq>=d3!R?? zrP!5{kVvV^WadVUIk*GIlnyMxdXG(xFHhm7bud?Lgjt4=J$8GyBK&7vy<|Bpo#0mK zQ0aHyhxEcN|4n=AG>?JnG=>Cnzxn2Y?0^L;{M7cFB0Pw^rwR6YM*iNmwzjKvuJb4y zUm-@D5sF}9a-LsIbMCM*?4CWVFQ><&Ia;a@z=(EduF@gGFbO0h%IKPeuB(8-a)BJiS=(G#jbw+Xre`@w8HxOr=~E@WdFXj>m1YY#eNkKDb4fK z{#!ahjhUiGWC0{pDDtsMc8Jr+Bh%4TqHHwpX4(uFU* zG?E4;iHW=C?4B$(dHm@4Xxd+C`l*);q*(tm+n3G+aEN6F=2&iok5_5i^65Y1wF@Qf ze#Bb(tD&yFO7srkTR8{7{vU(aJv1q(64Fosu(})9*&6ux(WA|lf14lmvhd7|2vKk{ zrRlIsw2AncWp`L-F%9X4wSb*pbgENl!Xhlr29CwC(6S`hhYm&nx*|S>lj{(wd?|kv>1+j%c_4TCTtHtWQytk$n>#;xvlKq+Y4Kr z3nNMI35$}|Krzv#C&b8|QM%e`e?H-Z0F&HPp_(a6C%e-(Pox342He)bXfAL|*;H`= zbhjgjr(lKZf{lztr2x)@PYKo~tXc>tmfET);~H3qwcvJ3lJ z;P>JyaR72!X~}uRyvXyb1f==auBF-C(+dyR;PWJHGWA-_-S?r!W*r_QvRefTEB*I! zTuMJk-cbNj--OZ!jv<{Gr;X#n9(s1ChjrM%Z~KSFE9{&P-Vgar6L7v$sE_?MVn)HX0QEhYS@Xa*>_2R> zFQfXzHxz%UGqW4~Z)pzaoZ})eFQJ?Wg!skw;f5)SIL~4oEDV|hjyL-gI4S7`Y6-xz zhNna0dAM73A|JLgY!Z?kJ_S4ii=u_NgMNjgy~orgUSD6{>b+d>op=2~SJZkm0No(A z0o-Q?__`+(;^L1jGH$kU8>}6zFD>ZXN|7>84B!xH_2*2V_b*JT-~jkk^^3qU+3Yuaa`xcBf{TZLuHz z5FY8bV^L3vBo@8?OHu{{8tY)pFw@bG2cx4Qr!^D^sce%siAv`}*(W)H2aO)kt#pK! zO=;j4l$E2ShG@eIi80>S)f5nV)eW|atwKruK)B%9f9p@oX_xs)$HZsuZapr(U+UjZOO`)tMoq_NCzT2k3^cy zErL&`JXa&{4zN08B{vyQ^_}4G@ zX)gc8eZbh2VG}*{IFZjt;g>FWsh7<8vsOAKWFgwQq6LL2M+?u_xjJXf2i{zr4G!LK zgV8JfU1^xMsQGL}3xZ$7OD{RHb(6@rY_l?w+y{|BexC9qb?owgQ%k>1Pj9h2XDsXx zi=ot*P*n>zA^>-}ITmZaWox!X!??M)4(7U5DXI25I(eKkIQMyIIZ|4F z_poooLdzW^L;oA~5eOMfhYKTGuTLrli2)TMCgs!KVhLq5hj(`EQ!@kQ{n`n^)NY!{ zb1`UaWVago^EU#(wlyK}O-YH3ytIa~BA zT%Bott^Hm!jW}Jskc;`{|Ki+#VuYh~=}4Xexl+`}8CoMhOaFivovkRjVb5epN>zolINKTH^ufNGY0Y8GBQd&>!`~9g%v`O`oGe(J7ky%@FBD?{|C4 zZEeXu9bx3c0n_^e6|Lt^U7qd1&uQ+MXu7=*hs1X0nPWj$5nr&*Kpd;Z;a1$+9Yqj@4{$41Ax&|W?;>zFQM~2?*MpXUu7_r+~aB%*olX^gp|}I zuFZ93pQB($HIJO?(uG2%!g$5xc+qQA5e}>-(hnvUwlr(QcxHpNqXhW_5Kfd@j@^V1 zWDK@F-J6ZiNyU(ZOlF*ogj^|)MJcFY#hW#5%s>79Sh={kjQyM{3C{cFWy>u0Qfs12 z&=_Df2;^!fGt7}D?Q8PcU7v2d#wna{=YJ-IcNL@S%tt>wfG!6595inI7m~{R1#W zmr8JRh5I3L05AsU*Q(|Y+^b^Z*A3Z}%;KJ=j$nqO3ewf`O+Ii@N?Z0!)7eG_sEn^3 z*a9Oa#1Y?LyCw$9QbR&%T%P$;iy$O16u#lpF>WScm%+YD0mYc{-oW43ZgM zZ7}-^y#@p8!IYe&?JszI4%0%+J^KaXL%afDvPX{gAZ5s`ZAhqmw z_1seUm)TiZeyOnwsyWlZB#&pfeK}>U^9M-PzqvTSmSR-CZ&^kmqaDq3teX8O_s=4I zFsTQzZ~9T!ZffUXw<%HUddi|tAsUVxY^Og2Ky+GXQ`{$GNm-gLwBNh`aaC15Ekr!| z^sP9IvUe(9?B%3jZP~}P9JpqUF~@)_pPu_fZhI3|;R0g$!m^$QOp!$~FoaL?#wIj|~`Z$rgta2-pw)G0^lmQ0~;)6t!Gc)a^ss}AN=c*O*`mF!c;tE+TX z`;8M)ttaZK#uoQFD6tHw(ckzq;uBmW_wSrwLUSbH`Al`F!|xB2rKBN@ohdaSh9`_#tA+$^-Nu>+4WWM-zFPMyKI`)M;3J;-mgElc&{@Nyeeg4?5#uKBN1MFR_t3Jw%Nc>&!9K?_E^+ZOD>g&QZ(*+} zDJYucn&*>VkD16to;>*ry1M53q+i7^YdgolPJ zxX7wjoT2Xy;BFvI~B__T$$NsJp4kU;&2ez9|ouK$Pc!$vFW9wqx0R@j79yn zHqxvQzHW?0-|i+y7>WO3O?|V-?JR3#%s@hy{D)#yJLM5mzbE*4r$@;Ghf*EoOddL+ zlqX^^ot{DV6Rp4etwHPs226qL!=GPVboFXJC8R#=-sqtMEe_WUXr^?DOLjSJ`<>#; zK6ckgLhbq_+QYTYB?PXgz{>ipPx6KPR+s8-;RZSg%zi1*}10hTht&q zYXs4-1`&%D82{rQ%*m=>IOO7Nr==49D2s+4%;Q# zoL7Yj@V*oFtI}|WxQ!jLcmZSppgO_4z|w*l7?pF!L2C8}tI^(P@o7tE66cQQUK7Ph znnA1rfM!7`XsgAbS;lceq|DRc*|X737PFF`f+=bhvupIdX!08S;a9}ea?v@f7Uh=G z<|fI1gU%6dhttB{b?GWHBq61Hu1H!@=7Sojok}N|grIjUUB!W?=a6ytq-DSJamRlM zTp+GFlqGv?I^}edNjwtG)|AH^x*M{H3ALBMoZ06lIQ@#nld}&*9NFxLPwYH^CHT-M z)AMtR8VCis0@a(hCY*4uP;Nwf|11fP-vY?~o%8UVv5LyJC_{1ADMT!?CP*1e_la&- z;VO}fN;c!SHyp}4(^Usa?pkj=Rw~$VWLi+a9wK?%vcz4EZahj(pJP-Zq3r8Wd8%^M zP2`!e{F(>$hH(|Fkc^H1!RfH-&&H+N#$d{gD6|wdIzW}GnFDQ!nDOD7uXrQ-B*mH7 z;|3U#H7%p=azb8%^{G?%i0mW>x&BB9WWNccOX+4stf`H`kWDbhnX)x1=AQ_5f2%Qy zyQ+FH->!^YuSOqfvEumXeaJVUgt-==pP3jL%n)IPTOrQWkV=6xV6UW6*Qt)Kx%v}x zx9Z}MjU_9HhjiJJhEg|Tp#=2z&tz_EYir<~-iM5F8H8YhugJT6Vgn!MggZy1@K3BB z+tg7gS7KK`NB`pbv$`E6@0vCwF2fC#FqKGkkY@B;k5`*$&Yup;N0kJdluU`Tvaq<1 zFd$k<`2*#2Hit5gIRy^Vw7x_!$H8eVqGTe-De$(w0@-CC1Y#lAW2wTYq;$j5Jwk>F z=$jawHNCuiqpE|-d)F$5_@E8VR17?|_}_fDLDRIFG8{um?82EXojV4GMN`PbhPzGx zNFJ|i7~3y`&;Hu>OccH!gJNOmCc%w~jQ z0XUx7%vO{rf6(wr>&s{P(AS^c?wLpon<}XSDxG=2Xu^{pTQ1_YE);KyoQb>k;!89v zZb$JbOO0)46CjIx8S-z?Ldny`WzUJhm^Q9+rSExAokIFh)X_{}dR&IYr1gT|N_!~2 z>B@aajiWVvmPqu}C(Xlb5*1IQiPSwrSu=$Onl?}mTDr}!Q5tAm4h}EMw7bKwi2nPX zC~0s7{_eiZ%zy0{O%&WXJ_FQd+s>ydLNt-rt*8=VT`2`LPV{*pn5;atiYZ?+W&2}D z3m+ffjktos9?$%!zXB&DrwZZfQJ52QUP`3;+d5{Ci(ZJFm*9H^G^-(lCr%yeA%-PW zOW@>HtuNJ1-rlvZ{r&xK`2Bc(u5m*2#V+H(@M6qjlL7r(86a8P^CFI9{(g@+4ssQo zNn~6>6wcMW(z1gh5y7l%M3=N?ckm!xgD3>vxt%VJ^C!xEvF{tFjd+PbOUh_za*Zeh z2%B%3+r$uMKH)LT0R6c4SkeOj%)od7qP$ap4BvPHHz$7oe*^vh5~KDT(%3GGkIeC% RqC{aEpsD^8S*~gs_CH?Uvm5{b literal 0 HcmV?d00001 From 9d2788877a9509c0f53c34ccc0c5f99c4de41cb2 Mon Sep 17 00:00:00 2001 From: Yurii Postolov <32772773+Ypostolov@users.noreply.github.com> Date: Tue, 13 Oct 2020 19:17:51 +0300 Subject: [PATCH 067/104] fix AlertManeuver pop_up displays the softButtons from previous requests (#393) Co-authored-by: yurii Co-authored-by: Andrii Kalinich --- app/view/sdl/AlertManeuverPopUp.js | 22 +++++++++++++--------- css/sdl.css | 11 ++++++++--- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index 806ded874..a3ad93cb7 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -97,8 +97,15 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( */ softbuttons: Em.ContainerView.extend( { - elementId: 'alertManeuverSoftButtons', - classNames: 'alertManeuverSoftButtons' + childViews: [ + 'buttons' + ], + buttons: Em.ContainerView.extend( + { + elementId: 'alertManeuverSoftButtons', + classNames: 'alertManeuverSoftButtons' + } + ) } ), /** @@ -141,7 +148,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( for (var i = 0; i < softButtons.length; i++) { let get_template_type = function(button_type) { - switch (softButtons[i].type) { + switch (button_type) { case "IMAGE": return "icon"; case "BOTH": @@ -150,13 +157,12 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( return "text"; } - this.get('softbuttons.childViews').pushObject( + this.get('softbuttons.buttons.childViews').pushObject( SDL.Button.create( SDL.PresetEventsCustom, { softButtonID: softButtons[i].softButtonID, icon: softButtons[i].image ? softButtons[i].image.value : '', text: softButtons[i].text, - groupName: 'AlertManeuverPopUp', classNames: 'list-item softButton ' + softButtonsClass, elementId: 'softButton' + i, templateName: get_template_type(softButtons[i].type), @@ -167,7 +173,6 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( ); } }, - /** * Deactivate PopUp */ @@ -185,9 +190,8 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( }, AlertManeuverActive: function(message) { - this.get('softbuttons.childViews').removeObjects( - this.get('softbuttons.childViews').filterProperty('softButtonID') - ); + this.softbuttons.buttons.removeAllChildren(); + this.softbuttons.buttons.rerender(); this.addSoftButtons(message.params); diff --git a/css/sdl.css b/css/sdl.css index 197ed0dec..34956a1e9 100644 --- a/css/sdl.css +++ b/css/sdl.css @@ -1580,9 +1580,8 @@ } #AlertPopUp .alertSoftButtons { - margin-left: 8px; top: 120px; - width: 386px; + width: 400px; } #SubtleAlertPopUp .subtleAlertSoftButtons { @@ -1614,9 +1613,15 @@ width: 362px; } +#AlertManeuverPopUp #alertManeuverSoftButtons{ + width: 400px; + height: 245px; +} + #softButton0.two { margin-top: 42px; - width: 170px; + width: 160px; + margin-left: 30px; } #softButton1.two { From 535073cc06ff2773280ec70c57ec243187a4524c Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Tue, 13 Oct 2020 20:28:13 +0300 Subject: [PATCH 068/104] Add setMode method to NonMediaModel (#370) Co-authored-by: YarikMamykin --- app/model/sdl/NonMediaModel.js | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/app/model/sdl/NonMediaModel.js b/app/model/sdl/NonMediaModel.js index 8fc73a771..9f071e60e 100644 --- a/app/model/sdl/NonMediaModel.js +++ b/app/model/sdl/NonMediaModel.js @@ -271,6 +271,29 @@ SDL.SDLNonMediaModel = SDL.ABSAppModel.extend({ sdlSetMediaClockTimer: function() { return; - } + }, + + classNameBindings: [ + 'dayMode', + 'nightMode', + 'highLightedMode' + ], + + dayMode:false, + nightMode:false, + highLightedMode:false, + + /** + * @description Method applies image mode view for model. + * @param {Number} + */ + setMode:function(mode){ + if(this.isTemplate){ + mode = SDL.SDLModel.data.imageModeList.includes(mode) ? mode : SDL.SDLModel.data.imageModeList[0]; + this.set('dayMode', mode == SDL.SDLModel.data.imageModeList[0]); + this.set('nightMode', mode == SDL.SDLModel.data.imageModeList[1]); + this.set('highLightedMode', mode == SDL.SDLModel.data.imageModeList[2]); + } + }, } ); From f95ff18c953ee6b9a381175017fea55b92dde60c Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Tue, 13 Oct 2020 21:10:36 +0300 Subject: [PATCH 069/104] Add error response for STATIC images present in request (#361) Co-authored-by: YarikMamykin --- ffw/UIRPC.js | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 8b7b29789..96ba1c838 100644 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -359,21 +359,18 @@ FFW.UI = FFW.RPCObserver.create( { // Verify if there is an unsupported data in request - //if (this.errorResponsePull[request.id] != null) { - // - ////Check if there is any available data to process the request - //if ("choiceSet" in request.params - // && request.params - // && request.params.interactionLayout != "KEYBOARD") { - // - // this.errorResponsePull[request.id].code = - // SDL.SDLModel.data.resultCode["WARNINGS"]; } else { If no - // available data sent error response and stop process current - // request this.sendError(this.errorResponsePull[request.id].code, - // request.id, request.method, "Unsupported " + - // this.errorResponsePull[request.id].type + " type. Request was - // not processed."); this.errorResponsePull[request.id] = null; - // return; } } + if (this.errorResponsePull[request.id] != null) { + if (request.params && 'choiceSet' in request.params && request.params.interactionLayout != "KEYBOARD") { + if (this.errorResponsePull[request.id].type === 'STATIC') { + this.sendError(SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + request.id, + request.method, + 'Image of STATIC type is not supported on HMI. Request was not processed'); + return; + } + } + } + if (SDL.SDLModel.uiPerformInteraction(request)) { SDL.SDLController.onSystemContextChange(); SDL.SDLModel.data.registeredApps.forEach(app => { From 9fad7f4489c8ac9c20e9b620cfa97e3a49f07424 Mon Sep 17 00:00:00 2001 From: "Ira Lytvynenko (GitHub)" Date: Tue, 13 Oct 2020 21:21:48 +0300 Subject: [PATCH 070/104] Fix/exit close cloud connection (#410) * Add Exit with Close_Cloud_Connection reason * exit commands moved to enum * Fix commands adding to model Co-authored-by: Igor Gapchuk Co-authored-by: Andrii Kalinich --- app/controller/sdl/Abstract/Controller.js | 116 ++++++++++++--------- app/controller/sdl/RController.js | 120 ++++++++++++---------- app/model/sdl/Abstract/data.js | 11 ++ 3 files changed, 142 insertions(+), 105 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 863e5cd44..ade04a54c 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -69,7 +69,7 @@ SDL.SDLController = Em.Object.extend( onCommand: function(element) { if (element.commandID < 0) { switch (element.commandID) { - case -1: + case SDL.SDLModel.data.exitCommandsEnum.DRIVER_DISTRACTION_VIOLATION: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -77,7 +77,7 @@ SDL.SDLController = Em.Object.extend( ); break; } - case -2: + case SDL.SDLModel.data.exitCommandsEnum.USER_EXIT: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -85,7 +85,7 @@ SDL.SDLController = Em.Object.extend( ); break; } - case -3: + case SDL.SDLModel.data.exitCommandsEnum.UNAUTHORIZED_TRANSPORT_REGISTRATION: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -93,7 +93,7 @@ SDL.SDLController = Em.Object.extend( ); break; } - case -4: + case SDL.SDLModel.data.exitCommandsEnum.RESOURCE_CONSTRAINT: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -101,6 +101,14 @@ SDL.SDLController = Em.Object.extend( ); break; } + case SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION: + { + FFW.BasicCommunication.ExitApplication( + SDL.SDLController.model.appID, + 'CLOSE_CLOUD_CONNECTION' + ); + break; + } default: { console.log('Unknown command with ID: ' + element.commandID); @@ -1033,49 +1041,41 @@ SDL.SDLController = Em.Object.extend( ) ); } - - let model = SDL.SDLController.getApplicationModel(params.appID); - var exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'DRIVER_DISTRACTION_VIOLATION\'', - 'position': 0 - }, - cmdID: -1 - } - }; - model.addCommand(exitCommand); - - exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'USER_EXIT\'', - 'position': 0 - }, - cmdID: -2 - } - }; - model.addCommand(exitCommand); - - exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'UNAUTHORIZED_TRANSPORT_REGISTRATION\'', - 'position': 0 - }, - cmdID: -3 - } - }; - model.addCommand(exitCommand); - - if (isWebEngineApp) { - exitCommand = { + var exitCommands = [ + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'DRIVER_DISTRACTION_VIOLATION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.DRIVER_DISTRACTION_VIOLATION + } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'USER_EXIT\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.USER_EXIT + } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'UNAUTHORIZED_TRANSPORT_REGISTRATION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.UNAUTHORIZED_TRANSPORT_REGISTRATION + } + }, + { 'id': -10, 'params': { 'menuParams': { @@ -1083,12 +1083,26 @@ SDL.SDLController = Em.Object.extend( 'menuName': 'Exit \'RESOURCE_CONSTRAINT\'', 'position': 0 }, - cmdID: -4 + cmdID: SDL.SDLModel.data.exitCommandsEnum.RESOURCE_CONSTRAINT } - }; - model.addCommand(exitCommand); - } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'CLOSE_ClOUD_CONNECTION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION + } + } + ]; + let model = SDL.SDLController.getApplicationModel(params.appID); + exitCommands.forEach(command => { + model.addCommand(command); + }); }, /** * Unregister application diff --git a/app/controller/sdl/RController.js b/app/controller/sdl/RController.js index 749da5887..85e557c99 100644 --- a/app/controller/sdl/RController.js +++ b/app/controller/sdl/RController.js @@ -370,52 +370,41 @@ SDL.RController = SDL.SDLController.extend( ) ); } - - let model = SDL.SDLController.getApplicationModel(params.appID); - var exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'DRIVER_DISTRACTION_VIOLATION\'', - 'position': 0 - }, - - cmdID: -1 - } - }; - model.addCommand(exitCommand); - - exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'USER_EXIT\'', - 'position': 0 - }, - - cmdID: -2 - } - }; - model.addCommand(exitCommand); - - exitCommand = { - 'id': -10, - 'params': { - 'menuParams': { - 'parentID': 0, - 'menuName': 'Exit \'UNAUTHORIZED_TRANSPORT_REGISTRATION\'', - 'position': 0 - }, - - cmdID: -3 - } - }; - model.addCommand(exitCommand); - - if (isWebEngineApp) { - exitCommand = { + var exitCommands = [ + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'DRIVER_DISTRACTION_VIOLATION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.DRIVER_DISTRACTION_VIOLATION + } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'USER_EXIT\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.USER_EXIT + } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'UNAUTHORIZED_TRANSPORT_REGISTRATION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.UNAUTHORIZED_TRANSPORT_REGISTRATION + } + }, + { 'id': -10, 'params': { 'menuParams': { @@ -424,11 +413,26 @@ SDL.RController = SDL.SDLController.extend( 'position': 0 }, - cmdID: -4 + cmdID: SDL.SDLModel.data.exitCommandsEnum.RESOURCE_CONSTRAINT } - }; - model.addCommand(exitCommand); - } + }, + { + 'id': -10, + 'params': { + 'menuParams': { + 'parentID': 0, + 'menuName': 'Exit \'CLOSE_ClOUD_CONNECTION\'', + 'position': 0 + }, + cmdID: SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION + } + } + ]; + + let model = SDL.SDLController.getApplicationModel(params.appID); + exitCommands.forEach(command => { + model.addCommand(command) + }); this.setInitalWindowTemplate(params, model); }, @@ -471,7 +475,7 @@ SDL.RController = SDL.SDLController.extend( onCommand: function(element) { if (element.commandID < 0) { switch (element.commandID) { - case -1: + case SDL.SDLModel.data.exitCommandsEnum.DRIVER_DISTRACTION_VIOLATION: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -479,7 +483,7 @@ SDL.RController = SDL.SDLController.extend( ); break; } - case -2: + case SDL.SDLModel.data.exitCommandsEnum.USER_EXIT: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -487,7 +491,7 @@ SDL.RController = SDL.SDLController.extend( ); break; } - case -3: + case SDL.SDLModel.data.exitCommandsEnum.UNAUTHORIZED_TRANSPORT_REGISTRATION: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -495,7 +499,7 @@ SDL.RController = SDL.SDLController.extend( ); break; } - case -4: + case SDL.SDLModel.data.exitCommandsEnum.RESOURCE_CONSTRAINT: { FFW.BasicCommunication.ExitApplication( SDL.SDLController.model.appID, @@ -503,6 +507,14 @@ SDL.RController = SDL.SDLController.extend( ); break; } + case SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION: + { + FFW.BasicCommunication.ExitApplication( + SDL.SDLController.model.appID, + 'CLOSE_CLOUD_CONNECTION' + ); + break; + } default: { console.log('Unknown command with ID: ' + element.commandID); diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index b1e91d0c1..75075f94a 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -1527,6 +1527,17 @@ SDL.SDLModelData = Em.Object.create( levelspan: 1 } ] + }, + + /** + * Enum for media Player Indicator + */ + exitCommandsEnum: { + 'DRIVER_DISTRACTION_VIOLATION': -1, + 'USER_EXIT': -2, + 'UNAUTHORIZED_TRANSPORT_REGISTRATION': -3, + 'RESOURCE_CONSTRAINT': -4, + 'CLOSE_CLOUD_CONNECTION': -5 } } ); From 727d0d3183958d343ea637a6c54c4aa717a552cc Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Tue, 13 Oct 2020 16:23:52 -0400 Subject: [PATCH 071/104] Fix sending of SetAppProperties request (#304) There was found and fixed several minor issues: - Wrong check if app has URL for a bundle download. Was always evaluated to false - App without URL is considered as a test app installed manually, so reject() was replaced with resolve() for such apps - Wrong logic for checking that app enabled flag was changed from false to true - policy app id value was not considered --- app/controller/InfoController.js | 73 +++++++++++++++++++------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/app/controller/InfoController.js b/app/controller/InfoController.js index f43963d7d..86294807e 100644 --- a/app/controller/InfoController.js +++ b/app/controller/InfoController.js @@ -158,38 +158,51 @@ SDL.InfoController = Em.Object.create( setAppProperties: function(old_properties, new_properties) { this.set('editedAppPropertiesToApply', new_properties); - if ((!'enabled' in old_properties || old_properties['enabled'] == false) && - new_properties['enabled'] === true) { - let that = this; - const policyAppID = new_properties['policyAppID']; + let is_app_installation_required = function() { + const old_app_id = old_properties['policyAppID']; + const new_app_id = new_properties['policyAppID']; - let get_app_title = function() { - let title = policyAppID; - if ('nicknames' in new_properties && new_properties['nicknames'].length > 0) { - title = new_properties['nicknames'][0]; - } - return title; - }; + const old_enabled_state = ('enabled' in old_properties) ? old_properties['enabled'] : false; + const new_enabled_state = ('enabled' in new_properties) ? new_properties['enabled'] : false; - let on_installation_failed = function() { - SDL.PopUp.create().appendTo('body').popupActivate( - `Can't install "${get_app_title()}" app from applications store...`, null, false - ); - SDL.WebAppSettingsView.editorAppSettings = old_properties; - SDL.WebAppSettingsView.showProperties(); - FFW.RPCSimpleClient.disconnect(); - }; + if (old_app_id != new_app_id) { + return new_enabled_state; + } - that.downloadAppBundle(policyAppID) - .then( function() { - Em.Logger.log(`App store: app installed successfully`); - FFW.BasicCommunication.SetAppProperties(new_properties); - FFW.RPCSimpleClient.disconnect(); - }, on_installation_failed); - return; + return new_enabled_state && !old_enabled_state; + } + + if (!is_app_installation_required()) { + FFW.BasicCommunication.SetAppProperties(new_properties); + return; } - FFW.BasicCommunication.SetAppProperties(new_properties); + let that = this; + const policyAppID = new_properties['policyAppID']; + + let get_app_title = function() { + let title = policyAppID; + if ('nicknames' in new_properties && new_properties['nicknames'].length > 0) { + title = new_properties['nicknames'][0]; + } + return title; + }; + + let on_installation_failed = function() { + SDL.PopUp.create().appendTo('body').popupActivate( + `Can't install "${get_app_title()}" app from applications store...`, null, false + ); + SDL.WebAppSettingsView.editorAppSettings = old_properties; + SDL.WebAppSettingsView.showProperties(); + FFW.RPCSimpleClient.disconnect(); + }; + + that.downloadAppBundle(policyAppID) + .then( function() { + Em.Logger.log(`App store: app installed successfully`); + FFW.BasicCommunication.SetAppProperties(new_properties); + FFW.RPCSimpleClient.disconnect(); + }, on_installation_failed); }, /** @@ -408,9 +421,9 @@ SDL.InfoController = Em.Object.create( */ downloadAppBundle: function(policyAppID) { return new Promise( (resolve, reject) => { - if (!policyAppID in SDL.InfoController.appPackageDownloadUrlsMap) { - Em.Logger.log(`App store: download URL for ${policyAppID} was not found`); - reject(); + if (!(policyAppID in SDL.InfoController.appPackageDownloadUrlsMap)) { + Em.Logger.log(`App store: download URL for ${policyAppID} was not found. Assume bundle was installed manually.`); + resolve(); } let download_url = SDL.InfoController.appPackageDownloadUrlsMap[policyAppID]; From 80aa9856b9b02f0ca7ffb215b8e1e20e35ac8f76 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Tue, 13 Oct 2020 17:39:25 -0400 Subject: [PATCH 072/104] Add support for custom menu icon and title --- app/controlls/Button.js | 11 +++++++++++ app/model/sdl/Abstract/Model.js | 5 ++++- app/model/sdl/Abstract/data.js | 2 +- app/model/sdl/MediaModel.js | 2 ++ app/model/sdl/NonMediaModel.js | 2 ++ app/view/info/nonMediaView.js | 12 ++++++++++-- app/view/media/sdlmediaView.js | 14 ++++++++++++-- app/view/navigationApp/baseNavigationView.js | 6 ++++++ capabilities/display_capabilities.js | 8 ++++---- css/general.css | 5 +++++ 10 files changed, 57 insertions(+), 10 deletions(-) diff --git a/app/controlls/Button.js b/app/controlls/Button.js index 707b1b0bc..c3c2d4d99 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -221,6 +221,17 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, '{{view.text}}' + '' ), + arrowShort: Em.Handlebars.compile( + '' + + '{{view.text}}' + + '' + ), + arrowShortOverLay: Em.Handlebars.compile( + '' + + '' + + '{{view.text}}' + + '' + ), rightIcon: Em.Handlebars.compile( ' Date: Wed, 14 Oct 2020 17:15:18 +0300 Subject: [PATCH 073/104] Fix setting `channelSetting` with SetInteriorVehicleData (#338) * Fix setting `channelSetting` with SetInterioVehicleData * fixup! Fix setting `channelSetting` with SetInterioVehicleData * fixup! fixup! Fix setting `channelSetting` with SetInterioVehicleData Co-authored-by: YarikMamykin --- app/model/media/AudioModel.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/model/media/AudioModel.js b/app/model/media/AudioModel.js index 31431d946..5fdb06d9b 100644 --- a/app/model/media/AudioModel.js +++ b/app/model/media/AudioModel.js @@ -817,12 +817,13 @@ SDL.AudioModel = Em.Object.extend({ resultNew.volume = data.volume; } for (var i = 0; i < dataLength; i++) { + if (data.equalizerSettings[i].channelId == this.tempEqualizerSettings.channelId) { + this.set('tempEqualizerSettings.channelSetting', data.equalizerSettings[i].channelSetting); + } for (var j = 0; j < currentLength; j++) { if (data.equalizerSettings[i].channelId == this.lastRadioControlStruct.equalizerSettings[j].channelId) { this.lastRadioControlStruct.equalizerSettings[j].channelSetting = SDL.deepCopy(data.equalizerSettings[i].channelSetting); - if (j == this.tempEqualizerSettIndex - 1) { - this.set('tempEqualizerSettings.equalizerSettings', data.equalizerSettings[i].equalizerSettings); - } + break; } } } @@ -873,12 +874,13 @@ SDL.AudioModel = Em.Object.extend({ resultNew.volume = data.volume; } for (var i = 0; i < dataLength; i++) { + if (data.equalizerSettings[i].channelId == this.tempEqualizerSettings.channelId) { + this.set('tempEqualizerSettings.channelSetting', data.equalizerSettings[i].channelSetting); + } for (var j = 0; j < currentLength; j++) { if (data.equalizerSettings[i].channelId == this.lastRadioControlStruct.equalizerSettings[j].channelId) { this.lastRadioControlStruct.equalizerSettings[j].channelSetting = SDL.deepCopy(data.equalizerSettings[i].channelSetting); - if (j == this.tempEqualizerSettIndex - 1) { - this.set('tempEqualizerSettings.equalizerSettings', data.equalizerSettings[i].equalizerSettings); - } + break; } } } From e43c49859335050b27bd3e1cf64588ad7b10fcde Mon Sep 17 00:00:00 2001 From: JackLivio Date: Wed, 14 Oct 2020 07:39:09 -0700 Subject: [PATCH 074/104] Fix menu ordering based on position param (#396) * Fix menu ordering based on position param * Fix position calculation and insert * Add 4 to top level index * Apply suggestions from code review Co-authored-by: Collin Co-authored-by: Collin --- app/model/sdl/Abstract/AppModel.js | 34 +++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index e7e935c74..1cd1d842d 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -524,24 +524,30 @@ SDL.ABSAppModel = Em.Object.extend( if (FFW.RPCHelper.isSuccessResultCode(result)) { // Magic number is limit of 1000 commands added on one menu if (commands.length <= 999) { - commands[commands.length] = { + var position = request.params.menuParams.position !== undefined ? + request.params.menuParams.position : commands.length; + // Add 4 to the position so the items appear after the default + // exit options. Default exit options have a request id < 0. + if (request.id >= 0 && parentID === 'top') { + position += 5; // for exit application commands + } + var newItem = { commandID: request.params.cmdID, name: request.params.menuParams.menuName, parent: parentID, - position: request.params.menuParams.position ? - request.params.menuParams.position : 0, isTemplate:request.params.cmdIcon ? request.params.cmdIcon.isTemplate ?request.params.cmdIcon.isTemplate : null : null, icon: request.params.cmdIcon ? request.params.cmdIcon.value : null - }; + }; + // Insert new item at calculated position + commands.splice(position, 0, newItem); if (SDL.SDLController.getApplicationModel(request.params.appID) && SDL.OptionsView.active) { SDL.SDLController.buttonsSort(parentID, this.appID); SDL.OptionsView.commands.refreshItems(); } - console.log(commands.length); if(request.params.cmdIcon) { var image = request.params.cmdIcon.value; var length=image.length; @@ -629,16 +635,24 @@ SDL.ABSAppModel = Em.Object.extend( if(FFW.RPCHelper.isSuccessResultCode(result)) { // Magic number is limit of 1000 commands added on one menu if (commands.length <= 999) { - this.commandsList[request.params.menuID] = []; - commands[commands.length] = { + this.commandsList[request.params.menuID] = []; + var position = request.params.menuParams.position !== undefined ? + request.params.menuParams.position : commands.length; + // Add 4 to the position so the items appear after the default + // exit options. Default exit options have a request id < 0. + if (request.id >= 0 && parentID === 'top') { + position += 5; // for exit application commands + } + + var newItem = { menuID: request.params.menuID, name: request.params.menuParams.menuName ? request.params.menuParams.menuName : '', parent: parentID, - position: request.params.menuParams.position ? - request.params.menuParams.position : 0, icon: request.params.menuIcon ? request.params.menuIcon.value : null - }; + }; + // Insert new item at calculated position + commands.splice(position, 0, newItem); if (SDL.SDLController.getApplicationModel(request.params.appID) && SDL.OptionsView.active) { SDL.SDLController.buttonsSort(parentID, this.appID); From 8948eda85016b015287a0c8017f993e6d7f76e31 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 14 Oct 2020 10:44:48 -0400 Subject: [PATCH 075/104] Add check if locationImage is not provided An error occurred if locationImage was not included in SendLocation, this adds a check to prevent that error --- app/view/navigationView.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/view/navigationView.js b/app/view/navigationView.js index 7621a621d..286552c9c 100644 --- a/app/view/navigationView.js +++ b/app/view/navigationView.js @@ -62,7 +62,8 @@ SDL.NavigationView = Em.ContainerView.create( className: 'button', text: SDL.NavigationModel.LocationDetails[i].locationName, disabled: false, - icon: SDL.NavigationModel.LocationDetails[i].locationImage.value, + icon: SDL.NavigationModel.LocationDetails[i].locationImage + ? SDL.NavigationModel.LocationDetails[i].locationImage.value : '', templateName: SDL.NavigationModel.LocationDetails[i].locationImage ? '' : 'text', action: 'openWayPoint', From e78ccd8b7c05ba3ee17b39a6bd5365e3d7944b20 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 14 Oct 2020 12:11:54 -0400 Subject: [PATCH 076/104] Fix typos in `CLOSE_CLOUD_CONNECTION` menu items --- app/controller/sdl/Abstract/Controller.js | 2 +- app/controller/sdl/RController.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index ade04a54c..b206c8ff3 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1091,7 +1091,7 @@ SDL.SDLController = Em.Object.extend( 'params': { 'menuParams': { 'parentID': 0, - 'menuName': 'Exit \'CLOSE_ClOUD_CONNECTION\'', + 'menuName': 'Exit \'CLOSE_CLOUD_CONNECTION\'', 'position': 0 }, cmdID: SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION diff --git a/app/controller/sdl/RController.js b/app/controller/sdl/RController.js index 85e557c99..2c073a6fb 100644 --- a/app/controller/sdl/RController.js +++ b/app/controller/sdl/RController.js @@ -421,7 +421,7 @@ SDL.RController = SDL.SDLController.extend( 'params': { 'menuParams': { 'parentID': 0, - 'menuName': 'Exit \'CLOSE_ClOUD_CONNECTION\'', + 'menuName': 'Exit \'CLOSE_CLOUD_CONNECTION\'', 'position': 0 }, cmdID: SDL.SDLModel.data.exitCommandsEnum.CLOSE_CLOUD_CONNECTION From 2bb1fec6c8a6efbf80137f3d327ebd13f56c4cf9 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Wed, 14 Oct 2020 21:45:25 +0300 Subject: [PATCH 077/104] Add error response for STATIC type images (#358) Co-authored-by: YarikMamykin --- ffw/UIRPC.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) mode change 100644 => 100755 ffw/UIRPC.js diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js old mode 100644 new mode 100755 index 96ba1c838..89ce38a26 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -214,16 +214,17 @@ FFW.UI = FFW.RPCObserver.create( 'secondaryGraphic' in request.params || 'softButtons' in request.params || 'customPresets' in request.params) { + + if (this.errorResponsePull[request.id].type === 'STATIC') { + this.sendError(SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], + request.id, + request.method, + 'Image of STATIC type is not supported on HMI. Request was not processed'); + return; + } + this.errorResponsePull[request.id].code = SDL.SDLModel.data.resultCode['WARNINGS']; - //} else { - // //If no available data sent error response and stop - // process current request - // this.sendError(this.errorResponsePull[request.id].code, - // request.id, request.method, "Unsupported " + - // this.errorResponsePull[request.id].type + " type. Request - // was not processed."); this.errorResponsePull[request.id] = - // null; return; } } SDL.TurnByTurnView.deactivate(); From 20cd3d1ba4df8adb803e72a05759f2d8732e6fbf Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 14 Oct 2020 14:52:03 -0400 Subject: [PATCH 078/104] Address comments --- app/view/info/nonMediaView.js | 17 ++++++++++++----- app/view/media/sdlmediaView.js | 20 ++++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/app/view/info/nonMediaView.js b/app/view/info/nonMediaView.js index c11f6ac85..37c00be5a 100644 --- a/app/view/info/nonMediaView.js +++ b/app/view/info/nonMediaView.js @@ -161,11 +161,6 @@ SDL.InfoNonMedia = Em.ContainerView.create( if (SDL.SDLController.model && SDL.SDLController.model.appID == SDL.NonMediaController.currentAppId) { - var menuTitle = SDL.SDLController.getApplicationModel(SDL.NonMediaController.currentAppId).globalProperties.menuTitle - this.get('content.optionsButton').set('text', menuTitle && menuTitle.length ? menuTitle : 'Options') - var menuIcon = SDL.SDLController.getApplicationModel(SDL.NonMediaController.currentAppId).globalProperties.menuIcon - this.get('content.optionsButton').set('icon', menuIcon && menuIcon.value && menuIcon.value.length ? menuIcon.value : null) - this.get('content.optionsButton').set('templateName', menuIcon && menuIcon.isTemplate ? 'arrowShortOverLay' : 'arrowShort') this.addItems( SDL.SDLController.model.softButtons, SDL.SDLController.model.appID @@ -174,6 +169,18 @@ SDL.InfoNonMedia = Em.ContainerView.create( }.observes('SDL.SDLController.model.softButtons.@each', 'SDL.SDLController.model.globalProperties.menuTitle', 'SDL.SDLController.model.globalProperties.menuIcon'), + updateOptionsButton: function() { + if (SDL.SDLController.model && SDL.SDLController.model.appID == + SDL.NonMediaController.currentAppId) { + var menuTitle = SDL.SDLController.model.globalProperties.menuTitle + this.get('content.optionsButton').set('text', menuTitle && menuTitle.length ? menuTitle : 'Options') + var menuIcon = SDL.SDLController.model.globalProperties.menuIcon + this.get('content.optionsButton').set('icon', menuIcon && menuIcon.value && menuIcon.value.length ? menuIcon.value : null) + this.get('content.optionsButton').set('templateName', menuIcon && menuIcon.isTemplate ? 'arrowShortOverLay' : 'arrowShort') + } + }.observes( + 'SDL.SDLController.model.globalProperties.menuTitle', + 'SDL.SDLController.model.globalProperties.menuIcon'), groupName: 'NonMediaView', diff --git a/app/view/media/sdlmediaView.js b/app/view/media/sdlmediaView.js index 2c3a79edb..3c5cdba57 100644 --- a/app/view/media/sdlmediaView.js +++ b/app/view/media/sdlmediaView.js @@ -71,21 +71,25 @@ SDL.sdlView = Em.ContainerView refreshItems: function() { if (SDL.SDLController.model && SDL.SDLController.model.appID == SDL.SDLMediaController.currentAppId) { - var menuTitle = SDL.SDLController.getApplicationModel(SDL.SDLMediaController.currentAppId).globalProperties.menuTitle - this.get('content.optionsButton').set('text', menuTitle && menuTitle.length ? menuTitle : 'Options') - var menuIcon = SDL.SDLController.getApplicationModel(SDL.SDLMediaController.currentAppId).globalProperties.menuIcon - this.get('content.optionsButton').set('icon', menuIcon && menuIcon.value && menuIcon.value.length ? menuIcon.value : null) - this.get('content.optionsButton').set('templateName', menuIcon && menuIcon.isTemplate ? 'arrowShortOverLay' : 'arrowShort') this.addItems( SDL.SDLController.model.softButtons, SDL.SDLController.model.appID ); } }.observes( - 'SDL.SDLController.model.softButtons.@each', + 'SDL.SDLController.model.softButtons.@each'), + updateOptionsButton: function() { + if (SDL.SDLController.model && SDL.SDLController.model.appID == + SDL.SDLMediaController.currentAppId) { + var menuTitle = SDL.SDLController.model.globalProperties.menuTitle + this.get('content.optionsButton').set('text', menuTitle && menuTitle.length ? menuTitle : 'Options') + var menuIcon = SDL.SDLController.model.globalProperties.menuIcon + this.get('content.optionsButton').set('icon', menuIcon && menuIcon.value && menuIcon.value.length ? menuIcon.value : null) + this.get('content.optionsButton').set('templateName', menuIcon && menuIcon.isTemplate ? 'arrowShortOverLay' : 'arrowShort') + } + }.observes( 'SDL.SDLController.model.globalProperties.menuTitle', - 'SDL.SDLController.model.globalProperties.menuIcon', - 'SDL.SDLController.model.appID'), + 'SDL.SDLController.model.globalProperties.menuIcon'), groupName: 'MediaView', elementId: 'sdl_view_container_menu', content: Em.ContainerView.extend( From 5fe2b640bcffa39dd34dbd8467a64c1e28ae0e22 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 14 Oct 2020 15:45:22 -0400 Subject: [PATCH 079/104] Apply suggestion --- app/view/info/nonMediaView.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/view/info/nonMediaView.js b/app/view/info/nonMediaView.js index 37c00be5a..dae0151ae 100644 --- a/app/view/info/nonMediaView.js +++ b/app/view/info/nonMediaView.js @@ -166,9 +166,7 @@ SDL.InfoNonMedia = Em.ContainerView.create( SDL.SDLController.model.appID ); } - }.observes('SDL.SDLController.model.softButtons.@each', - 'SDL.SDLController.model.globalProperties.menuTitle', - 'SDL.SDLController.model.globalProperties.menuIcon'), + }.observes('SDL.SDLController.model.softButtons.@each'), updateOptionsButton: function() { if (SDL.SDLController.model && SDL.SDLController.model.appID == SDL.NonMediaController.currentAppId) { From 8495d9416076e5aa788e1c6b883fe97f9c443468 Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Thu, 15 Oct 2020 06:15:05 +0300 Subject: [PATCH 080/104] Fix setting displayMode value in case of AUTO mode (#322) * Fix setting displayMode value in case of AUTO mode * fixup! Fix setting displayMode value in case of AUTO mode * fixup! Fix setting displayMode value in case of AUTO mode * fixup! Fix setting displayMode value in case of AUTO mode * fixup! Fix setting displayMode value in case of AUTO mode * fixup! Fix setting displayMode value in case of AUTO mode Co-authored-by: YarikMamykin Co-authored-by: Andrii Kalinich --- app/model/HmiSettingsModel.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/model/HmiSettingsModel.js b/app/model/HmiSettingsModel.js index 200631284..84c68a226 100644 --- a/app/model/HmiSettingsModel.js +++ b/app/model/HmiSettingsModel.js @@ -84,11 +84,22 @@ SDL.HmiSettingsModel = Em.Object.extend({ return capabilities; }, + /** + * @function defineAutoTimeValue + * @description Defines which time value should be sent + * accordingly to current system time. + * @return String (DAY or NIGHT) + */ + defineAutoTimeValue: function() { + const time = new Date().getHours(); + return (time > 7 && time < 20 ? 'DAY': 'NIGHT'); + }, + setHmiSettingsData: function(data){ var result = {}; if(data.displayMode && this.displayMode != data.displayMode) { this.set('displayMode',data.displayMode); - result.displayMode = data.displayMode; + result.displayMode = (data.displayMode === 'AUTO' ? this.defineAutoTimeValue() : data.displayMode); } if(data.temperatureUnit && this.temperatureUnit != data.temperatureUnit) { this.set('temperatureUnit',data.temperatureUnit); @@ -114,9 +125,7 @@ SDL.HmiSettingsModel = Em.Object.extend({ distanceUnit: this.distanceUnit }; if(result.displayMode == 'AUTO'){ - var time = new Date().toLocaleTimeString(); - time = parseInt(time.substring(0, time.indexOf(':'))); - result.displayMode = (time > 7 && time < 20? 'DAY': 'NIGHT'); + result.displayMode = this.defineAutoTimeValue(); } return result; }, From abe9cc55b9b3e890a48ce49e75f88bed695b553c Mon Sep 17 00:00:00 2001 From: Andrii Kalinich Date: Thu, 15 Oct 2020 00:21:07 -0400 Subject: [PATCH 081/104] fixup! Add callback for image mode change for SDLController --- app/controller/sdl/Abstract/Controller.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 00d6324f3..9b213419d 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -1554,21 +1554,12 @@ SDL.SDLController = Em.Object.extend( * @description Callback for display image mode change. */ imageModeChanged: function() { - if (!SDL.SDLController.model) { - return; - } - - SDL.SDLController.model.setMode(SDL.SDLModel.data.imageMode); - var commands = SDL.SDLController.model.get('currentCommandsList'); const length = SDL.OptionsView.commands.items.length; - for(var i=0;i Date: Mon, 12 Oct 2020 23:10:12 +0300 Subject: [PATCH 082/104] added missing text fields in UI.GetCapabilities response --- ffw/UIRPC.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 89ce38a26..c3c033764 100755 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -851,6 +851,24 @@ FFW.UI = FFW.RPCObserver.create( 'characterSet': 'UTF_8', 'width': 500, 'rows': 1 + }, + { + 'name': 'subtleAlertText1', + 'characterSet': 'UTF_8', + 'width': 500, + 'rows': 1 + }, + { + 'name': 'subtleAlertText2', + 'characterSet': 'UTF_8', + 'width': 500, + 'rows': 1 + }, + { + 'name': 'subtleAlertSoftButtonText', + 'characterSet': 'UTF_8', + 'width': 500, + 'rows': 1 } ], 'imageFields': [ @@ -1009,6 +1027,18 @@ FFW.UI = FFW.RPCObserver.create( 'resolutionWidth': 105, 'resolutionHeight': 65 } + }, + { + 'name': 'subtleAlertIcon', + 'imageTypeSupported': [ + 'GRAPHIC_BMP', + 'GRAPHIC_JPEG', + 'GRAPHIC_PNG' + ], + 'imageResolution': { + 'resolutionWidth': 105, + 'resolutionHeight': 65 + } } ], 'mediaClockFormats': [ From 92ca29b05aae6978df4a786119f66a12afc9aea6 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Mon, 19 Oct 2020 11:58:42 -0400 Subject: [PATCH 083/104] Fix nested commands removal (#415) In case when commands organized in a tree hierarchy there might be a case when applicaiton deletes command with childs. In that case SDL removes parent command first and then all its childs starting from the bottom one. In case when SDL tries to remove the last child, HMI responds with INVALID_ID because it can't find that node by menu_id as its parent was deleted first. To fix that issue, logic of commands removal was updated so now HMI responds with SUCCESS if commandsList contain the array by menuID. It makes more sense because parent node could be deleted first. --- app/model/sdl/Abstract/AppModel.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 1cd1d842d..3d18f56a7 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -681,18 +681,20 @@ SDL.ABSAppModel = Em.Object.extend( */ deleteSubMenu: function(menuID) { var commandsList = this.commandsList; + for (id in commandsList) { var filteredObjects = commandsList[id].filterProperty('menuID', menuID); + if (filteredObjects.length > 0) { - commandsList[id].removeObjects( - filteredObjects - ); - if (menuID in commandsList) { - delete(commandsList[menuID]) - } - return SDL.SDLModel.data.resultCode.SUCCESS; + commandsList[id].removeObjects(filteredObjects); } } + + if (menuID in commandsList) { + delete(commandsList[menuID]) + return SDL.SDLModel.data.resultCode.SUCCESS; + } + return SDL.SDLModel.data.resultCode.INVALID_ID; }, /** From 3daac6abc931e9f430bd5e09fec3dd798dbd9fd6 Mon Sep 17 00:00:00 2001 From: Collin Date: Mon, 19 Oct 2020 11:59:16 -0400 Subject: [PATCH 084/104] VR USER_EXIT command type changed to application (#420) * vr USER_EXIT command type changed to application so it appears in all views * use exit action for application vr command exit --- app/model/sdl/RModel.js | 2 +- app/view/sdl/VRPopUp.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/model/sdl/RModel.js b/app/model/sdl/RModel.js index 2a2b07bf8..e5740290b 100644 --- a/app/model/sdl/RModel.js +++ b/app/model/sdl/RModel.js @@ -198,7 +198,7 @@ SDL.RModel = SDL.SDLModel.extend({ 'cmdID': -2, 'vrCommands': ['USER_EXIT ' + params.appName], 'appID': params.appID, - 'type': 'Command' + 'type': 'Application' }; this.addCommandVR(message); diff --git a/app/view/sdl/VRPopUp.js b/app/view/sdl/VRPopUp.js index 79132161b..62dd9f537 100644 --- a/app/view/sdl/VRPopUp.js +++ b/app/view/sdl/VRPopUp.js @@ -69,12 +69,14 @@ SDL.VRPopUp = Em.ContainerView.create( AddCommand: function(cmdID, vrCommands, appID, type, grammarID) { if (type == 'Application') { for (var i = 0; i < vrCommands.length; i++) { + var isExit = cmdID === -2 && vrCommands[i].startsWith('USER_EXIT '); this.get('listOfCommands.list.childViews').pushObject( SDL.Button.create( { - action: 'onActivateSDLApp', + action: isExit ? 'onVRCommand' : 'onActivateSDLApp', target: 'SDL.SDLController', appID: appID, + commandID: cmdID, text: vrCommands[i], classNames: 'list-item', templateName: 'text' From ffc3294dcf963c1e875377f6409731ae7b230cfc Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 19 Oct 2020 14:27:26 -0400 Subject: [PATCH 085/104] Fix app permissions view when groups are removed --- app/controller/SettingsController.js | 4 ++++ app/view/settings/policies/appPermissionsView.js | 3 +++ 2 files changed, 7 insertions(+) diff --git a/app/controller/SettingsController.js b/app/controller/SettingsController.js index f39e1e070..624961ec9 100644 --- a/app/controller/SettingsController.js +++ b/app/controller/SettingsController.js @@ -276,6 +276,10 @@ SDL.SettingsController = Em.Object.create( ); }, simpleParseUserFriendlyMessageData: function(messages, func) { + if (!messages) { + return; + } + var tts = '', text = ''; messages.forEach( diff --git a/app/view/settings/policies/appPermissionsView.js b/app/view/settings/policies/appPermissionsView.js index c45daa3c7..8bda1b959 100644 --- a/app/view/settings/policies/appPermissionsView.js +++ b/app/view/settings/policies/appPermissionsView.js @@ -90,6 +90,9 @@ SDL.AppPermissionsView = Em.ContainerView.create( SDL.AppPermissionsView.currentAppId = appID; this.appList.items = []; for (var i = 0; i < message.length; i++) { + if (!message[i].name) { + continue; + } var text = ' - Undefined'; text = (message[i].allowed === true) ? ' - Allowed' : ' - Not allowed'; this.appList.items.push({ From d67426781078c2b8dc82b6c6059667d48b639b1d Mon Sep 17 00:00:00 2001 From: Collin Date: Mon, 19 Oct 2020 14:39:35 -0400 Subject: [PATCH 086/104] searchBar.input.value should always be string type (#423) --- app/view/sdl/shared/keyboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/view/sdl/shared/keyboard.js b/app/view/sdl/shared/keyboard.js index b10620b1e..a3dceb81f 100644 --- a/app/view/sdl/shared/keyboard.js +++ b/app/view/sdl/shared/keyboard.js @@ -79,7 +79,7 @@ SDL.Keyboard = SDL.SDLAbstractView.create( */ deactivate: function() { this._super(); - this.searchBar.input.set('value', null); + this.searchBar.input.set('value', ''); this.set('target', null); }, inputChanges: function(element) { From cc4496df122882ee223261fa977df203b3f44f55 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Mon, 19 Oct 2020 14:52:16 -0400 Subject: [PATCH 087/104] Added return statement for early resolve/reject (#425) There was noticed that in several cases promise statement continues to execute even after resolve()/reject() was called in early if statement. This is because JS has the concept "run to completion". Unless an error is thrown, a function is executed until a return statement or its end is reached. To fix that, return statements have been placed for cases where resolve/reject is called early. This prevents functions to execute unnecessary code. Since the return value of the callback is ignored, we can save a line by returning the reject/resolve statement. --- app/controller/InfoController.js | 10 +++++----- app/controller/SettingsController.js | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controller/InfoController.js b/app/controller/InfoController.js index 86294807e..97ae0470e 100644 --- a/app/controller/InfoController.js +++ b/app/controller/InfoController.js @@ -423,7 +423,7 @@ SDL.InfoController = Em.Object.create( return new Promise( (resolve, reject) => { if (!(policyAppID in SDL.InfoController.appPackageDownloadUrlsMap)) { Em.Logger.log(`App store: download URL for ${policyAppID} was not found. Assume bundle was installed manually.`); - resolve(); + return resolve(); } let download_url = SDL.InfoController.appPackageDownloadUrlsMap[policyAppID]; @@ -443,7 +443,7 @@ SDL.InfoController = Em.Object.create( if (params.success == false) { Em.Logger.log('App store: Bundle downloading was not successful'); - reject(); + return reject(); } Em.Logger.log('App store: Bundle was downloaded successfully'); @@ -489,7 +489,7 @@ SDL.InfoController = Em.Object.create( if (params.success == false) { Em.Logger.log('App store: Manifest loading was not successful'); - reject(); + return reject(); } Em.Logger.log('App store: Manifest was loaded successfully'); @@ -524,13 +524,13 @@ SDL.InfoController = Em.Object.create( } catch { Em.Logger.log(`App store: failed to parse JSON content`); - reject(); + return reject(); } Em.Logger.log(`App store: manifest parsed successfully`); if (!('entrypoint' in bundle_json)) { Em.Logger.log(`App store: entrypoint is not specified - use default`); - resolve("index.html"); + return resolve("index.html"); } resolve(bundle_json['entrypoint']); diff --git a/app/controller/SettingsController.js b/app/controller/SettingsController.js index 624961ec9..aa45fea05 100644 --- a/app/controller/SettingsController.js +++ b/app/controller/SettingsController.js @@ -421,7 +421,7 @@ SDL.SettingsController = Em.Object.create( if (params.success == false) { Em.Logger.log('PTU: Downloading PTS was not successful'); - reject(); + return reject(); } Em.Logger.log('PTU: PTS downloaded successfully'); @@ -496,7 +496,7 @@ SDL.SettingsController = Em.Object.create( if (params.success == false) { Em.Logger.log('PTU: PTU save was not successful'); - reject(); + return reject(); } Em.Logger.log('PTU: PTU saved successfully'); From 1a8cc2235db19098b7150cef2e2622801d0593ef Mon Sep 17 00:00:00 2001 From: "Yaroslav Mamykin (GitHub)" <33784535+YarikMamykin@users.noreply.github.com> Date: Mon, 19 Oct 2020 22:06:27 +0300 Subject: [PATCH 088/104] Hotfix/314 No warnings code in response in case of invalid image paths provided (#344) * Fix PerformInteraction + ScrollableMessage response * Fix Show + SetGlobalProperties response * Fix UpdateTurnList + ShowConstantTBT + SendLocation response * Fix AlertManeuverPopUp response * Fix AddCommand + AddSubMenu response * fixup! Fix AddCommand + AddSubMenu response * fixup! Fix AddCommand + AddSubMenu response Co-authored-by: YarikMamykin Co-authored-by: Andrii Kalinich --- app/controller/NavigationController.js | 113 ++++++++++++++++++-- app/model/sdl/Abstract/AppModel.js | 57 +++++++--- app/model/sdl/Abstract/Model.js | 137 ++++++++++++++++++++++++- app/view/sdl/AlertManeuverPopUp.js | 27 ++++- ffw/NavigationRPC.js | 83 +-------------- ffw/UIRPC.js | 63 ++++++++++-- 6 files changed, 366 insertions(+), 114 deletions(-) diff --git a/app/controller/NavigationController.js b/app/controller/NavigationController.js index 2923975df..76eb8ab57 100644 --- a/app/controller/NavigationController.js +++ b/app/controller/NavigationController.js @@ -63,11 +63,24 @@ SDL.NavigationController = Em.Object.create( searchAddress: request.params.address } ); - FFW.Navigation.sendNavigationResult( - SDL.SDLModel.data.resultCode.SUCCESS, - request.id, - request.method - ); + + imageList = []; + if(request.params.locationImage) { + imageList.push(request.params.locationImage.value); + } + + var callback = function(failed) { + var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; + var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + + FFW.Navigation.sendNavigationResult( + failed ? WARNINGS : SUCCESS, + request.id, + request.method, + failed ? "Requested image(s) not found" : null + ); + } + SDL.SDLModel.validateImages(request.id, callback, imageList); }, /** * Navigation view List Button action handler @@ -423,6 +436,94 @@ SDL.NavigationController = Em.Object.create( }, 2000 ); // Allow time for the initial map display - } + }, + + /** + * @desc Verifies if image is an PNG image, + * accordingly to file extension. + * @param imagePath - path to image + * @return {Boolean} true if image is PNG and false otherwise + */ + isPng: function(imagePath) { + const img_extension = '.png'; + var search_offset = imagePath.lastIndexOf('.'); + return imagePath.includes(img_extension, search_offset); + }, + + /** + * @desc Collects images paths from request + * and calls validation function. + * @param request - request data + */ + validateIcons: function(request) { + var params = request.params; + imageList = []; + var nonPngCounter = 0; + + if(params.turnList) { + var countList=params.turnList.length; + for(var i = 0; i < countList; i++) { + if(params.turnList[i].turnIcon) { + var iconPath = params.turnList[i].turnIcon.value; + if(!this.isPng(iconPath)) { + delete params.turnList[i].turnIcon; + nonPngCounter++; + continue; + } + imageList.push(iconPath); + } + } + } + if(params.softButtons) { + var countButtons=params.softButtons.length; + for(var i=0;i 0) { + FFW.Navigation.sendNavigationResult( + SDL.SDLModel.data.resultCode.WARNINGS, + request.id, + request.method, + ); + return; + } + + var callback = function(failed) { + var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; + var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + FFW.Navigation.sendNavigationResult( + failed ? WARNINGS : SUCCESS, + request.id, + request.method, + failed ? "Requested image(s) not found" : null); + } + SDL.SDLModel.validateImages(request.id, callback, imageList); + }, } ); diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index 3d18f56a7..be00b9721 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -549,21 +549,32 @@ SDL.ABSAppModel = Em.Object.extend( } if(request.params.cmdIcon) { - var image = request.params.cmdIcon.value; - var length=image.length; - str='.png'; - var isPng=image.includes(str,length-5); - if (!isPng) { - FFW.UI.sendUIResult( - SDL.SDLModel.data.resultCode.WARNINGS, request.id, - request.method - ); - return; - } - } - if (request.id >= 0) { - FFW.UI.sendUIResult(result, request.id, request.method); - } + + var image = request.params.cmdIcon.value; + if(!SDL.NavigationController.isPng(image)) { + FFW.UI.sendUIResult( + SDL.SDLModel.data.resultCode.WARNINGS, request.id, + request.method); + return; + } + + var callback = function(failed) { + var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; + var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + + FFW.UI.sendUIResult( + failed ? WARNINGS : SUCCESS, + request.id, + request.method, + failed ? "Requested image(s) not found" : null); + } + SDL.SDLModel.validateImages(request.id, callback, [image]); + return; + } + + if (request.id >= 0) { + FFW.UI.sendUIResult(result, request.id, request.method); + } } else { FFW.UI.sendError( result, request.id, request.method, @@ -658,7 +669,21 @@ SDL.ABSAppModel = Em.Object.extend( SDL.SDLController.buttonsSort(parentID, this.appID); SDL.OptionsView.commands.refreshItems(); } - FFW.UI.sendUIResult(result, request.id, request.method); + var callback = function(failed) { + var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; + var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + + FFW.UI.sendUIResult( + failed ? WARNINGS : SUCCESS, + request.id, + request.method, + failed ? "Requested image(s) not found" : null); + } + var imageList = []; + if(request.params.menuIcon) { + imageList.push(request.params.menuIcon.value); + } + SDL.SDLModel.validateImages(request.id, callback, imageList); } else { FFW.UI.sendError( SDL.SDLModel.data.resultCode.REJECTED, request.id, diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 5f6b41ee1..815afb2e2 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -973,6 +973,23 @@ SDL.SDLModel = Em.Object.extend({ request.params, messageRequestId ); } + if(request.params.softButtons) { + var imageList = []; + for(var i = 0; i < request.params.softButtons.length; i++) { + if(request.params.softButtons[i].image) { + imageList.push(request.params.softButtons[i].image.value); + } + } + var callback = function(failed) { + if(failed) { + FFW.UI.sendUIResult( + SDL.SDLModel.data.resultCode.WARNINGS, + request.id, + request.method, "Requested image(s) not found"); + } + }; + SDL.SDLModel.validateImages(request.id, callback, imageList); + } return true; } else { FFW.UI.sendError(SDL.SDLModel.data.resultCode.REJECTED, request.id, @@ -1014,6 +1031,92 @@ SDL.SDLModel = Em.Object.extend({ } }, + /** + * List of images(paths to images) to check. + */ + imageCheckList: {}, + + /** + * @function validateImages + * @description Checks if image exists by path provided in request data + * @param requestID - request id, to which images belong + * @param callback - user callback after check + * @param imageList - list of paths to check + */ + validateImages: function(requestID, callback, imageList) { + if(imageList == null || imageList.length == 0) { + callback(false); + return; + } + + this.imageCheckList[requestID] = []; + const filteredImageList = imageList.filter(function(item, pos) { + return imageList.indexOf(item) == pos; + }); + + filteredImageList.forEach(image => { + this.imageCheckList[requestID].push({ + 'path': image, + 'checkResult': null + }); + }); + + for(var i = 0; i < this.imageCheckList[requestID].length; i++) { + var image = new Image(); + image.onload = function() { + for(var i = 0; i < SDL.SDLModel.imageCheckList[requestID].length; i++) { + var formattedImgPath = this.src.substring(this.src.indexOf('://') + '://'.length); + var path = SDL.SDLModel.imageCheckList[requestID][i].path; + if(path === formattedImgPath) { + SDL.SDLModel.imageCheckList[requestID][i].checkResult = true; + break; + } + } + SDL.SDLModel.finalizeImageValidation(requestID, callback); + }; + image.onerror = function() { + for(var i = 0; i < SDL.SDLModel.imageCheckList[requestID].length; i++) { + var formattedImgPath = this.src.substring(this.src.indexOf('://') + '://'.length); + var path = SDL.SDLModel.imageCheckList[requestID][i].path; + if(path === formattedImgPath) { + SDL.SDLModel.imageCheckList[requestID][i].checkResult = false; + break; + } + } + SDL.SDLModel.finalizeImageValidation(requestID, callback); + }; + image.src = this.imageCheckList[requestID][i].path; + } + }, + + /** + * @function finalizeImageValidation + * @description Collects result of images validation. + * If validation is finished - calls user callback function. + * @param callback - user callback. + */ + finalizeImageValidation: function(requestID, callback) { + var failed = false; + var BreakException = {}; + try { + SDL.SDLModel.imageCheckList[requestID].forEach(image => { + if (image.checkResult === null) { + throw BreakException; + } + if (!image.checkResult) { + failed = true; + } + }); + } catch (exception) { + if (exception == BreakException) { + return; + } + } + + delete SDL.SDLModel.imageCheckList.requestID; + callback(failed); + }, + /** * Method to call function from DeviceListView to show list of connected * devices @@ -1207,9 +1310,37 @@ SDL.SDLModel = Em.Object.extend({ SDL.InteractionChoicesView.cancelID = message.params.cancelID; - if (message.params && message.params.choiceSet == null) { - FFW.UI.sendUIResult(SDL.SDLModel.data.resultCode.SUCCESS, - message.id, 'UI.PerformInteraction'); + if (message.params && message.params.choiceSet != null) { + imageList = []; + if(message.params.vrHelp) { + for(var i = 0; i < message.params.vrHelp.length; i++) { + var image = message.params.vrHelp[i].image; + if(image) { + imageList.push(image.value); + } + } + } + if(message.params.choiceSet) { + for(var i = 0; i < message.params.choiceSet.length; i++) { + var image = message.params.choiceSet[i].image; + if(image) { + imageList.push(image.value); + } + } + } + + var callback = function(failed) { + var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; + var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + + FFW.UI.sendUIResult( + failed ? WARNINGS : SUCCESS, + message.id, + message.method, + failed ? "Requested image(s) not found" : null); + } + SDL.SDLModel.validateImages(message.id, callback, imageList); + return true; } diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index a3ad93cb7..73cf532ac 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -55,6 +55,10 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( timer: null, timeout: 5000, alertManeuerRequestId: 0, + /** + * @desc Defines whether icons paths verified successfully. + */ + iconsAreValid: false, /** * Wagning image on Alert Maneuver PopUp */ @@ -146,6 +150,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( break; } + var imageList = []; for (var i = 0; i < softButtons.length; i++) { let get_template_type = function(button_type) { switch (button_type) { @@ -157,6 +162,10 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( return "text"; } + if (softButtons[i].image) { + imageList.push(softButtons[i].image.value); + } + this.get('softbuttons.buttons.childViews').pushObject( SDL.Button.create( SDL.PresetEventsCustom, { @@ -172,6 +181,12 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( ) ); } + + var callback = function(failed) { + SDL.AlertManeuverPopUp.iconsAreValid = !failed; + } + + SDL.SDLModel.validateImages(params.appID, callback, imageList); }, /** * Deactivate PopUp @@ -180,10 +195,17 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( if (SDL.TTSPopUp.active) { SDL.TTSPopUp.DeactivateTTS(); } + + const resultCode = this.iconsAreValid ? + SDL.SDLModel.data.resultCode.SUCCESS : SDL.SDLModel.data.resultCode.WARNINGS; + const info = this.iconsAreValid ? + null : "Requested image(s) not found"; + FFW.Navigation.sendNavigationResult( - SDL.SDLModel.data.resultCode.SUCCESS, + resultCode, this.alertManeuerRequestId, - 'Navigation.AlertManeuver' + 'Navigation.AlertManeuver', + info ); this.set('activate', false ); this.set('alertManeuerRequestId', 0); @@ -193,6 +215,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( this.softbuttons.buttons.removeAllChildren(); this.softbuttons.buttons.rerender(); + this.set('iconsAreValid', true); this.addSoftButtons(message.params); this.set('activate', true ); diff --git a/ffw/NavigationRPC.js b/ffw/NavigationRPC.js index ac582eaa2..411a6b2f6 100644 --- a/ffw/NavigationRPC.js +++ b/ffw/NavigationRPC.js @@ -175,58 +175,6 @@ FFW.Navigation = FFW.RPCObserver.create( } } }, - isPng:function(params){ - var returnValue=true; - if(params.nextTurnIcon){ - var image = params.nextTurnIcon.value; - var search_offset = image.lastIndexOf('.'); - str='.png'; - var isPng=image.includes(str, search_offset); - if(!isPng){ - delete params.nextTurnIcon; - returnValue=false; - } - } - if(params.turnIcon){ - var image = params.turnIcon.value; - var search_offset = image.lastIndexOf('.'); - str='.png'; - var isPng=image.includes(str, search_offset); - if(!isPng){ - delete params.turnIcon; - returnValue=false; - } - } - if(params.turnList){ - var countList=params.turnList.length; - for(var i=0;i Date: Tue, 20 Oct 2020 16:59:34 +0300 Subject: [PATCH 089/104] Fix softButton is not displayed properly in day/night/highlighted mode (#368) * Fix softButton is not displayed properly in day/night/highlighted mode * updated fix softButton is not displayed properly in day/night/highlighted mode * fixup! updated fix softButton is not displayed properly in day/night/highlighted mode Co-authored-by: yurii Co-authored-by: Andrii Kalinich --- app/controlls/Button.js | 5 +++ app/controlls/List.js | 10 ++++++ app/view/home/controlButtons.js | 2 ++ app/view/info/appsView.js | 1 + app/view/sdl/AlertManeuverPopUp.js | 49 +++++++++++++++++++++++------- 5 files changed, 56 insertions(+), 11 deletions(-) diff --git a/app/controlls/Button.js b/app/controlls/Button.js index c3c2d4d99..2c5dbc581 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -192,6 +192,11 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, {{bindAttr src="view.icon"}} />' ), + iconOverlay: Em.Handlebars.compile( + '' + + '' + ), + subtle: Em.Handlebars.compile( '' + '{{view.text}}' diff --git a/app/controlls/List.js b/app/controlls/List.js index 4c75ae36e..66935a588 100644 --- a/app/controlls/List.js +++ b/app/controlls/List.js @@ -116,6 +116,16 @@ SDL.List = Em.ContainerView.extend({ this.items.splice(id, 1); this.list.refresh(); }, + + /** Method setting up display mode for correspond components */ + setMode: function(mode){ + var items = this.list.get('childViews'); + + for (var i = 0; i < items.length; ++i) { + var button = items[i]; + button.setMode(mode); + } + }, /** List components */ childViews: [ diff --git a/app/view/home/controlButtons.js b/app/view/home/controlButtons.js index c669afba8..917b0105f 100644 --- a/app/view/home/controlButtons.js +++ b/app/view/home/controlButtons.js @@ -605,10 +605,12 @@ getCurrentDisplayModeClass: function() { return SDL.States.media.active ? 'PLAY_PAUSE' : 'OK'; }, actionDown: function() { + this._super(); SDL.SDLController.onSoftButtonOkActionDown(this.getPresetName()); }, actionUp: function() { + this._super(); SDL.SDLController.onSoftButtonOkActionUp(this.getPresetName()); } diff --git a/app/view/info/appsView.js b/app/view/info/appsView.js index 709704169..0cd0c1ddb 100644 --- a/app/view/info/appsView.js +++ b/app/view/info/appsView.js @@ -182,6 +182,7 @@ SDL.InfoAppsView = Em.ContainerView.create({ SDL.InfoAppsView.Asist911.setMode(SDL.SDLModel.data.imageMode); SDL.InfoAppsView.vehicleHealthReport.setMode(SDL.SDLModel.data.imageMode); SDL.InfoAppsView.getDeviceList.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoAppsView.applicationsStore.setMode(SDL.SDLModel.data.imageMode); }.observes('SDL.SDLModel.data.imageMode') } ); diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index 73cf532ac..b6e3e7afa 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -124,6 +124,19 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( templateName: 'text' } ), + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + var items = this.get('softbuttons.buttons.childViews'); + for (var i = 0; i < items.length; ++i) { + var button = items[i]; + button.setMode(SDL.SDLModel.data.imageMode); + } + this.closeButton.setMode(SDL.SDLModel.data.imageMode); + }.observes('SDL.SDLModel.data.imageMode'), + /** * @desc Function creates Soft Buttons on AlertPoUp * @param {Object} params @@ -150,18 +163,24 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( break; } - var imageList = []; - for (var i = 0; i < softButtons.length; i++) { - let get_template_type = function(button_type) { - switch (button_type) { - case "IMAGE": - return "icon"; - case "BOTH": - return "rightText"; - } - return "text"; + let is_template = function(image) { + return image != null && image.isTemplate; + } + + let get_template_type = function(button_type, image) { + switch (button_type) { + case "IMAGE": + return is_template(image) ? "iconOverlay" : "icon"; + + case "BOTH": + return is_template(image) ? "rightTextOverLay" : "rightText"; } + return "text"; + } + + var imageList = []; + for (var i = 0; i < softButtons.length; i++) { if (softButtons[i].image) { imageList.push(softButtons[i].image.value); } @@ -174,7 +193,15 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( text: softButtons[i].text, classNames: 'list-item softButton ' + softButtonsClass, elementId: 'softButton' + i, - templateName: get_template_type(softButtons[i].type), + classNameBindings: ['isHighlighted:isHighlighted', + 'getCurrentDisplayModeClass'], + + getCurrentDisplayModeClass: function() { + return SDL.ControlButtons.getCurrentDisplayModeClass(); + }.property('SDL.ControlButtons.imageMode.selection'), + + isHighlighted: softButtons[i].isHighlighted, + templateName: get_template_type(softButtons[i].type, softButtons[i].image), systemAction: softButtons[i].systemAction, appID: params.appID } From 166cb72ad6d829492ed1f512d3079017fcd05d9b Mon Sep 17 00:00:00 2001 From: yurii Date: Tue, 20 Oct 2020 23:02:22 +0300 Subject: [PATCH 090/104] Added missing fields in OnSystemCapabilityUpdated notification on app registration --- app/model/sdl/Abstract/data.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/model/sdl/Abstract/data.js b/app/model/sdl/Abstract/data.js index a644c079f..65c3d8624 100644 --- a/app/model/sdl/Abstract/data.js +++ b/app/model/sdl/Abstract/data.js @@ -900,6 +900,24 @@ SDL.SDLModelData = Em.Object.create( "characterSet": "UTF_8", "width": 500, "rows": 1 + }, + { + "name": "subtleAlertText1", + "characterSet": "UTF_8", + "width": 500, + "rows": 1 + }, + { + "name": "subtleAlertText2", + "characterSet": "UTF_8", + "width": 500, + "rows": 1 + }, + { + "name": "subtleAlertSoftButtonText", + "characterSet": "UTF_8", + "width": 500, + "rows": 1 } ], 'imageFields': [ @@ -1058,6 +1076,18 @@ SDL.SDLModelData = Em.Object.create( 'resolutionWidth': 105, 'resolutionHeight': 65 } + }, + { + 'name': 'subtleAlertIcon', + 'imageTypeSupported': [ + 'GRAPHIC_BMP', + 'GRAPHIC_JPEG', + 'GRAPHIC_PNG' + ], + 'imageResolution': { + 'resolutionWidth': 105, + 'resolutionHeight': 65 + } } ], "imageTypeSupported": ["STATIC", "DYNAMIC"], From dd0e707a1cbb8a1304fdf147f51f0b6998381b3a Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Fri, 23 Oct 2020 14:03:39 -0400 Subject: [PATCH 091/104] Fix/fix type error on file remove (#332) * Replace multiple getters with a signgle variable * Fix TypeError while iterating veHelp Was added one more check to verify if vrHelp item contains image object or not as it might be not mandatory according to HMI_API. * fixup! Fix TypeError while iterating veHelp * fixup! Fix TypeError while iterating veHelp --- app/model/sdl/Abstract/Model.js | 103 ++++++++++---------------------- 1 file changed, 33 insertions(+), 70 deletions(-) diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 815afb2e2..58854388f 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -200,48 +200,28 @@ SDL.SDLModel = Em.Object.extend({ onFileRemoved: function(params) { var result = false; + var app_model = SDL.SDLController.getApplicationModel(params.appID); + var is_image_type = ['GRAPHIC_PNG', 'GRAPHIC_BMP', 'GRAPHIC_JPEG'].includes(params.fileType); - if (( - params.fileType === 'GRAPHIC_PNG' || params.fileType === 'GRAPHIC_BMP' || - params.fileType === 'GRAPHIC_JPEG') && - SDL.SDLController.getApplicationModel(params.appID)) { - result = SDL.SDLController.getApplicationModel(params.appID). - onImageRemoved(params.fileName); - - if (SDL.SDLController.getApplicationModel(params.appID).appIcon. - indexOf(params.fileName) != -1 && - params.fileName.length == - SDL.SDLController.getApplicationModel(params.appID).appIcon.length) { - SDL.SDLController.getApplicationModel(params.appID). - set('appIcon', SDL.SDLModel.data.defaultListOfIcons.app); + if (is_image_type && app_model) { + result = app_model.onImageRemoved(params.fileName); + + if (app_model.appIcon.includes(params.fileName) && + params.fileName.length == app_model.appIcon.length) { + app_model.set('appIcon', SDL.SDLModel.data.defaultListOfIcons.app); } - if (SDL.SDLController.getApplicationModel(params.appID - ).constantTBTParams) { - - if (SDL.SDLController.getApplicationModel(params.appID - ).constantTBTParams.turnIcon && - SDL.SDLController.getApplicationModel(params.appID).constantTBTParams. - turnIcon.value.indexOf(params.fileName) != -1 && - params.fileName.length == SDL.SDLController.getApplicationModel( - params.appID - ).constantTBTParams.turnIcon.value.length) { - SDL.SDLController.getApplicationModel(params.appID - ).constantTBTParams.turnIcon.value = - SDL.SDLModel.data.defaultListOfIcons.command; + if (app_model.constantTBTParams) { + if (app_model.constantTBTParams.turnIcon && + app_model.constantTBTParams.turnIcon.value === params.fileName) { + app_model.constantTBTParams.turnIcon.value = SDL.SDLModel.data.defaultListOfIcons.command; SDL.TurnByTurnView.activate(params.appID); } - if (SDL.SDLController.getApplicationModel(params.appID - ).constantTBTParams.nextTurnIcon && - SDL.SDLController.getApplicationModel(params.appID).constantTBTParams. - nextTurnIcon.value.indexOf(params.fileName) != -1 && - params.fileName.length == SDL.SDLController.getApplicationModel( - params.appID - ).constantTBTParams.nextTurnIcon.value.length) { - SDL.SDLController.getApplicationModel(params.appID - ).constantTBTParams.nextTurnIcon.value = - SDL.SDLModel.data.defaultListOfIcons.command; + if (app_model.constantTBTParams.nextTurnIcon && + app_model.constantTBTParams.nextTurnIcon.value.indexOf(params.fileName) != -1 && + params.fileName.length == app_model.constantTBTParams.nextTurnIcon.value.length) { + app_model.constantTBTParams.nextTurnIcon.value = SDL.SDLModel.data.defaultListOfIcons.command; SDL.TurnByTurnView.activate(params.appID); } } @@ -284,42 +264,28 @@ SDL.SDLModel = Em.Object.extend({ } } - var len = SDL.SDLController.getApplicationModel(params.appID - ).turnList.length; + var len = app_model.turnList.length; for (var i = 0; i < len; i++) { - if (!SDL.SDLController.getApplicationModel(params.appID - ).turnList[i].turnIcon) { + if (!app_model.turnList[i].turnIcon) { continue; } - if (SDL.SDLController.getApplicationModel(params.appID - ).turnList[i].turnIcon.value.indexOf(params.fileName) != -1 && - params.fileName.length == SDL.SDLController.getApplicationModel( - params.appID - ).turnList[i].turnIcon.value.length) { - SDL.SDLController.getApplicationModel(params.appID - ).turnList[i].turnIcon.value = - SDL.SDLModel.data.defaultListOfIcons.command; + if (app_model.turnList[i].turnIcon.value.indexOf(params.fileName) != -1 && + params.fileName.length == app_model.turnList[i].turnIcon.value.length) { + app_model.turnList[i].turnIcon.value = SDL.SDLModel.data.defaultListOfIcons.command; } } SDL.TBTTurnList.updateList(params.appID); - if (SDL.SDLController.getApplicationModel(params.appID).softButtons) { - var len = SDL.SDLController.getApplicationModel(params.appID - ).softButtons.length; + if (app_model.softButtons) { + var len = app_model.softButtons.length; for (var i = 0; i < len; i++) { - if (!SDL.SDLController.getApplicationModel(params.appID - ).softButtons[i].image) { + if (!app_model.softButtons[i].image) { continue; } - if (SDL.SDLController.getApplicationModel(params.appID - ).softButtons[i].image.value.indexOf(params.fileName) != -1 && - params.fileName.length == SDL.SDLController.getApplicationModel( - params.appID - ).softButtons[i].image.value.length) { - SDL.SDLController.getApplicationModel(params.appID - ).softButtons[i].image.value = - SDL.SDLModel.data.defaultListOfIcons.command; + if (app_model.softButtons[i].image.value.indexOf(params.fileName) != -1 && + params.fileName.length == app_model.softButtons[i].image.value.length) { + app_model.softButtons[i].image.value = SDL.SDLModel.data.defaultListOfIcons.command; } } @@ -345,15 +311,12 @@ SDL.SDLModel = Em.Object.extend({ } } - if (SDL.SDLController.getApplicationModel(params.appID - ).globalProperties.vrHelp) { - for (var i = 0; i < SDL.SDLController.getApplicationModel(params.appID - ).globalProperties.vrHelp.length; i++) { - if (SDL.SDLController.getApplicationModel(params.appID - ).globalProperties.vrHelp[i].image.value === params.fileName) { - SDL.SDLController.getApplicationModel(params.appID - ).globalProperties.vrHelp[i].image.value = - SDL.SDLModel.data.defaultListOfIcons.command; + if (app_model.globalProperties.vrHelp) { + for (var i = 0; i < app_model.globalProperties.vrHelp.length; i++) { + if (app_model.globalProperties.vrHelp[i].image && + app_model.globalProperties.vrHelp[i].image.value === params.fileName) { + app_model.globalProperties.vrHelp[i].image.value = + SDL.SDLModel.data.defaultListOfIcons.command; } } } From 8406bef18f09847da54ab8a43e92edd8acee366c Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 23 Oct 2020 14:45:40 -0400 Subject: [PATCH 092/104] send warnings with info in error format (#428) * Fix sending errorneous response with params According to SDL specification there is no custom API params expected in "data" section of erorneous response by desgin. By that reason SDL just cuts off all such params and ignores their values. In particular case, SDL ignores `tryAgainTime` of SubtleAlert errorneous response and does not forward it to mobile. To avoid such issues, errorneous responses with custom params from API should be sent in the `result` section of response. Corresponding function has been updated to cover this test case. For case of errorneous response without custom params, errorneous message can be sent as usual. * send warnings with info in error format * move result adjustment to after error check * remove info from success schema, apply to all interfaces * fixup! remove info from success schema, apply to all interfaces fix whitespace in ttsrpc.js * apply for any success code, add TODO note * remove result code check from sendError on each interface * Update ffw/NavigationRPC.js Co-authored-by: JackLivio * apply params changes to each interface * fix spelling and whitespace Co-authored-by: Andrii Kalinich Co-authored-by: JackLivio --- ffw/BasicCommunicationRPC.js | 39 ++++++++++++------------ ffw/NavigationRPC.js | 39 ++++++++++++------------ ffw/RCRPC.js | 39 ++++++++++++------------ ffw/TTSRPC.js | 39 ++++++++++++------------ ffw/UIRPC.js | 59 ++++++++++++++++++------------------ ffw/VRRPC.js | 39 ++++++++++++------------ ffw/VehicleInfoRPC.js | 39 ++++++++++++------------ 7 files changed, 143 insertions(+), 150 deletions(-) diff --git a/ffw/BasicCommunicationRPC.js b/ffw/BasicCommunicationRPC.js index 7753d6b3c..33cd76a99 100644 --- a/ffw/BasicCommunicationRPC.js +++ b/ffw/BasicCommunicationRPC.js @@ -944,22 +944,19 @@ FFW.BasicCommunication = FFW.RPCObserver */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * send response from onRPCRequest @@ -973,7 +970,7 @@ FFW.BasicCommunication = FFW.RPCObserver * @param {String} * info */ - sendBCResult: function(resultCode, id, method, info) { + sendBCResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -990,9 +987,11 @@ FFW.BasicCommunication = FFW.RPCObserver return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.BC.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -1002,8 +1001,8 @@ FFW.BasicCommunication = FFW.RPCObserver } }; - if (info) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); diff --git a/ffw/NavigationRPC.js b/ffw/NavigationRPC.js index 411a6b2f6..2132cfa89 100644 --- a/ffw/NavigationRPC.js +++ b/ffw/NavigationRPC.js @@ -460,22 +460,19 @@ FFW.Navigation = FFW.RPCObserver.create( */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * send response from onRPCRequest @@ -485,7 +482,7 @@ FFW.Navigation = FFW.RPCObserver.create( * @param {String} method * @param {String} info */ - sendNavigationResult: function(resultCode, id, method, info) { + sendNavigationResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -502,9 +499,11 @@ FFW.Navigation = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.Navigation.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -514,8 +513,8 @@ FFW.Navigation = FFW.RPCObserver.create( } }; - if(info != null) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); diff --git a/ffw/RCRPC.js b/ffw/RCRPC.js index 2d83fc8e1..c9e661b44 100644 --- a/ffw/RCRPC.js +++ b/ffw/RCRPC.js @@ -365,22 +365,19 @@ FFW.RC = FFW.RPCObserver.create( */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * Send response from onRPCRequest @@ -392,7 +389,7 @@ FFW.RC = FFW.RPCObserver.create( * @param {String} * method */ - sendRCResult: function(resultCode, id, method) { + sendRCResult: function(resultCode, id, method, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -409,9 +406,11 @@ FFW.RC = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.RC.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -421,8 +420,8 @@ FFW.RC = FFW.RPCObserver.create( } }; - if (info) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); diff --git a/ffw/TTSRPC.js b/ffw/TTSRPC.js index a7d470692..1a9293f03 100644 --- a/ffw/TTSRPC.js +++ b/ffw/TTSRPC.js @@ -356,22 +356,19 @@ FFW.TTS = FFW.RPCObserver.create( */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * send response from onRPCRequest @@ -385,7 +382,7 @@ FFW.TTS = FFW.RPCObserver.create( * @param {String} * info */ - sendTTSResult: function(resultCode, id, method, info) { + sendTTSResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -402,9 +399,11 @@ FFW.TTS = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.TTS.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -414,8 +413,8 @@ FFW.TTS = FFW.RPCObserver.create( } }; - if (info) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 86a91b132..65b62f960 100755 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1690,32 +1690,25 @@ FFW.UI = FFW.RPCObserver.create( * id * @param {String} * method - * @param {Object} - * additional parameters to send with error + * @param {String} + * message */ - sendError: function(resultCode, id, method, message, params) { + sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode !== 0) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - - if (params) { - JSONMessage.error.data = Object.assign(JSONMessage.error.data, params); } + }; - this.sendMessage(JSONMessage); - } + this.sendMessage(JSONMessage); }, /** * send response from onRPCRequest @@ -1728,8 +1721,10 @@ FFW.UI = FFW.RPCObserver.create( * method * @param {String} * info + * @param {Object} + * params */ - sendUIResult: function(resultCode, id, method, info) { + sendUIResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -1746,9 +1741,11 @@ FFW.UI = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.UI.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -1757,9 +1754,11 @@ FFW.UI = FFW.RPCObserver.create( 'method': method, } }; - if(info != null) { - JSONMessage.result.info = info; + + if (params != null) { + Object.assign(JSONMessage.result, params); } + this.sendMessage(JSONMessage); } else { this.sendError(resultCode, id, method, info); @@ -1822,14 +1821,14 @@ FFW.UI = FFW.RPCObserver.create( this.sendUIResult(resultCode, id, 'UI.SubtleAlert', info); break; } - case SDL.SDLModel.data.resultCode['ABORTED']: + case SDL.SDLModel.data.resultCode.REJECTED: { - this.sendError(resultCode, id, 'UI.SubtleAlert', 'SubtleAlert request aborted.'); + this.sendUIResult(resultCode, id, 'UI.SubtleAlert', info, { tryAgainTime: tryAgainTime }); break; } - case SDL.SDLModel.data.resultCode.REJECTED: + case SDL.SDLModel.data.resultCode.ABORTED: { - this.sendError(resultCode, id, 'UI.SubtleAlert', info, { tryAgainTime: tryAgainTime }); + this.sendUIResult(resultCode, id, 'UI.SubtleAlert', 'SubtleAlert request aborted.'); break; } } diff --git a/ffw/VRRPC.js b/ffw/VRRPC.js index c519128ae..01a19d556 100644 --- a/ffw/VRRPC.js +++ b/ffw/VRRPC.js @@ -299,22 +299,19 @@ FFW.VR = FFW.RPCObserver.create( */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * send notification when command was triggered @@ -390,7 +387,7 @@ FFW.VR = FFW.RPCObserver.create( * @param {String} * info */ - sendVRResult: function(resultCode, id, method, info) { + sendVRResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -407,9 +404,11 @@ FFW.VR = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.VR.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -419,8 +418,8 @@ FFW.VR = FFW.RPCObserver.create( } }; - if (info) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); diff --git a/ffw/VehicleInfoRPC.js b/ffw/VehicleInfoRPC.js index 413583ce3..5764c97c1 100644 --- a/ffw/VehicleInfoRPC.js +++ b/ffw/VehicleInfoRPC.js @@ -224,22 +224,19 @@ FFW.VehicleInfo = FFW.RPCObserver.create( */ sendError: function(resultCode, id, method, message) { Em.Logger.log('FFW.' + method + 'Response'); - if (resultCode != SDL.SDLModel.data.resultCode.SUCCESS) { - - // send repsonse - var JSONMessage = { - 'jsonrpc': '2.0', - 'id': id, - 'error': { - 'code': resultCode, // type (enum) from SDL protocol - 'message': message, - 'data': { - 'method': method - } + // send response + var JSONMessage = { + 'jsonrpc': '2.0', + 'id': id, + 'error': { + 'code': resultCode, // type (enum) from SDL protocol + 'message': message, + 'data': { + 'method': method } - }; - this.sendMessage(JSONMessage); - } + } + }; + this.sendMessage(JSONMessage); }, /** * Send response from onRPCRequest @@ -253,7 +250,7 @@ FFW.VehicleInfo = FFW.RPCObserver.create( * @param {String} * info */ - sendVIResult: function(resultCode, id, method, info) { + sendVIResult: function(resultCode, id, method, info, params) { const is_successful_code = FFW.RPCHelper.isSuccessResultCode(resultCode); if (is_successful_code && this.errorResponsePull[id] != null) { // If request was successful but some error was observed upon validation @@ -270,9 +267,11 @@ FFW.VehicleInfo = FFW.RPCObserver.create( return; } + const result_response = is_successful_code && (params || !info); + Em.Logger.log('FFW.VI.' + method + 'Response'); - if (is_successful_code) { - // send repsonse + if (result_response) { + // send response var JSONMessage = { 'jsonrpc': '2.0', 'id': id, @@ -282,8 +281,8 @@ FFW.VehicleInfo = FFW.RPCObserver.create( } }; - if (info) { - JSONMessage.result.info = info; + if (params != null) { + Object.assign(JSONMessage.result, params); } this.sendMessage(JSONMessage); From e3904a720f98e793c1a6e80f1e9fa284147d8fe3 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 26 Oct 2020 17:39:52 -0400 Subject: [PATCH 093/104] Fix missing check for clusterModeStatus --- app/model/sdl/VehicleInfoModel.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index cc34df060..e142eb7a6 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -468,6 +468,10 @@ SDL.SDLVehicleInfoModel = Em.Object.create( FFW.RPCHelper.isSuccessResultCode(customResultCode['SubscribeVehicleData']); for (var key in message.params){ + if (key === 'clusterModeStatus') { + key = 'clusterModes'; + } + subscribeVIData[key] = { dataType: this.eVehicleDataType[key], resultCode: customResultCode.vehicleDataStruct[key], From dc22849280ea56443035abb794182fada9ec3084 Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Mon, 26 Oct 2020 17:40:10 -0400 Subject: [PATCH 094/104] Remove invalid tpms vehicle data item --- app/model/sdl/VehicleInfoModel.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/model/sdl/VehicleInfoModel.js b/app/model/sdl/VehicleInfoModel.js index e142eb7a6..c76f8a97f 100644 --- a/app/model/sdl/VehicleInfoModel.js +++ b/app/model/sdl/VehicleInfoModel.js @@ -139,7 +139,6 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'abs_State': 'VEHICLEDATA_ABS_STATE', 'turnSignal': 'VEHICLEDATA_TURNSIGNAL', 'tirePressureValue': 'VEHICLEDATA_TIREPRESSURE_VALUE', - 'tpms': 'VEHICLEDATA_TPMS', 'cloudAppVehicleID': 'VEHICLEDATA_CLOUDAPPVEHICLEID', 'handsOffSteering': 'VEHICLEDATA_HANDSOFFSTEERING', 'stabilityControlsStatus': 'VEHICLEDATA_STABILITYCONTROLSSTATUS', @@ -327,7 +326,6 @@ SDL.SDLVehicleInfoModel = Em.Object.create( 'frontRecommended': 2.2E0, 'rearRecommended': 2.2E0 }, - 'tpms': 'TIRES_NOT_TRAINED', 'cloudAppVehicleID': 'SDLVehicleNo123', 'displayResolution': { 'width': 800, From f25872dadc8966ac561d558805d1db43f07f99db Mon Sep 17 00:00:00 2001 From: jacobkeeler Date: Wed, 28 Oct 2020 16:32:30 -0400 Subject: [PATCH 095/104] Process remaining show message in case of UNSUPPORTED_RESOURCE --- ffw/UIRPC.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index f9301f428..b512997cb 100755 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -216,15 +216,13 @@ FFW.UI = FFW.RPCObserver.create( 'customPresets' in request.params) { if (this.errorResponsePull[request.id].type === 'STATIC') { - this.sendError(SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE'], - request.id, - request.method, - 'Image of STATIC type is not supported on HMI. Request was not processed'); - return; + this.errorResponsePull[request.id].code = + SDL.SDLModel.data.resultCode['UNSUPPORTED_RESOURCE']; + } + else { + this.errorResponsePull[request.id].code = + SDL.SDLModel.data.resultCode['WARNINGS']; } - - this.errorResponsePull[request.id].code = - SDL.SDLModel.data.resultCode['WARNINGS']; } } SDL.TurnByTurnView.deactivate(); From 95d16aac6b39b5b6e3c020031925d25963f12eca Mon Sep 17 00:00:00 2001 From: Shobhit Adlakha Date: Thu, 29 Oct 2020 12:03:32 -0400 Subject: [PATCH 096/104] Revert image validation changes for UI.PerformInteraction (#439) --- app/model/sdl/Abstract/Model.js | 43 +++++++++------------------------ 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index 58854388f..bf6c4e29c 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -1260,6 +1260,12 @@ SDL.SDLModel = Em.Object.extend({ */ uiPerformInteraction: function(message) { + if (!message.params) { + FFW.UI.sendError(SDL.SDLModel.data.resultCode.INVALID_DATA, message.id, + message.method, 'Empty message was received for UI.PerformInteraction' + ); + return false; + } if (!SDL.SDLController.getApplicationModel(message.params.appID ).activeRequests.uiPerformInteraction) { if (message.params && message.params.vrHelpTitle && @@ -1273,37 +1279,13 @@ SDL.SDLModel = Em.Object.extend({ SDL.InteractionChoicesView.cancelID = message.params.cancelID; - if (message.params && message.params.choiceSet != null) { - imageList = []; - if(message.params.vrHelp) { - for(var i = 0; i < message.params.vrHelp.length; i++) { - var image = message.params.vrHelp[i].image; - if(image) { - imageList.push(image.value); - } - } - } - if(message.params.choiceSet) { - for(var i = 0; i < message.params.choiceSet.length; i++) { - var image = message.params.choiceSet[i].image; - if(image) { - imageList.push(image.value); - } - } - } - - var callback = function(failed) { - var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; - var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; - - FFW.UI.sendUIResult( - failed ? WARNINGS : SUCCESS, - message.id, - message.method, - failed ? "Requested image(s) not found" : null); - } - SDL.SDLModel.validateImages(message.id, callback, imageList); + // Images are not validated for this request since choiceId cannot be sent back in + // the case of a WARNINGS response + if(message.params.choiceSet == null){ + FFW.UI.sendUIResult(SDL.SDLModel.data.resultCode.SUCCESS, + message.id, 'UI.PerformInteraction' + ); return true; } @@ -1315,7 +1297,6 @@ SDL.SDLModel = Em.Object.extend({ return true; } else { - FFW.UI.sendError(SDL.SDLModel.data.resultCode.REJECTED, message.id, message.method, 'UI PerformInterection REJECTED on HMI' ); From 6f75f48f8275f5736129efe620dee9632567add3 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 30 Oct 2020 10:57:27 -0400 Subject: [PATCH 097/104] add group to alert maneuver soft buttons so their system actions can work (#447) --- app/view/sdl/AlertManeuverPopUp.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index b6e3e7afa..bcdbf899e 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -191,6 +191,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( softButtonID: softButtons[i].softButtonID, icon: softButtons[i].image ? softButtons[i].image.value : '', text: softButtons[i].text, + groupName: 'AlertManeuverPopUp', classNames: 'list-item softButton ' + softButtonsClass, elementId: 'softButton' + i, classNameBindings: ['isHighlighted:isHighlighted', From 1b49961fc6352aca217a39637c0c81df9cd46d14 Mon Sep 17 00:00:00 2001 From: Yurii Postolov <32772773+Ypostolov@users.noreply.github.com> Date: Fri, 30 Oct 2020 19:18:38 +0200 Subject: [PATCH 098/104] Changed the sequence of sending OnSubtleAlertPressed and app activation messages (#437) Co-authored-by: yurii --- app/view/sdl/SubtleAlertPopUp.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/view/sdl/SubtleAlertPopUp.js b/app/view/sdl/SubtleAlertPopUp.js index 6bc969ee7..3fdfa048d 100644 --- a/app/view/sdl/SubtleAlertPopUp.js +++ b/app/view/sdl/SubtleAlertPopUp.js @@ -72,8 +72,8 @@ SDL.SubtleAlertPopUp = Em.ContainerView.create( } SDL.SubtleAlertPopUp.deactivate(); - SDL.SDLController.onSubtleAlertPressed(SDL.SubtleAlertPopUp.appID); SDL.SDLController.onActivateSDLApp({ appID: SDL.SubtleAlertPopUp.appID }); + SDL.SDLController.onSubtleAlertPressed(SDL.SubtleAlertPopUp.appID); } else{ SDL.SubtleAlertPopUp.deactivate(); } From 7637690e0e2cc90622146b768c17df92f70ba612 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Mon, 2 Nov 2020 12:54:47 -0500 Subject: [PATCH 099/104] Fix adding of HMI internal commands (#426) HMI internal commands should be added by default for each application and should not depend on HMI settings. Added check to make an exception for such commands. --- app/model/sdl/Abstract/AppModel.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/app/model/sdl/Abstract/AppModel.js b/app/model/sdl/Abstract/AppModel.js index be00b9721..6fbc75b2e 100644 --- a/app/model/sdl/Abstract/AppModel.js +++ b/app/model/sdl/Abstract/AppModel.js @@ -513,12 +513,17 @@ SDL.ABSAppModel = Em.Object.extend( this.commandsList[parentID] = []; } - var commands = this.get('commandsList.' + parentID); - result = FFW.RPCHelper.getCustomResultCode(this.appID, 'uiAddCommand'); + const is_sdl_request = request.id >= 0; + let commands = this.get('commandsList.' + parentID); + let result = SDL.SDLModel.data.resultCode.SUCCESS; - if ('DO_NOT_RESPOND' == result) { - Em.Logger.log('Do not respond on this request'); - return; + if (is_sdl_request) { + result = FFW.RPCHelper.getCustomResultCode(this.appID, 'uiAddCommand'); + + if ('DO_NOT_RESPOND' == result) { + Em.Logger.log('Do not respond on this request'); + return; + } } if (FFW.RPCHelper.isSuccessResultCode(result)) { @@ -572,7 +577,7 @@ SDL.ABSAppModel = Em.Object.extend( return; } - if (request.id >= 0) { + if (is_sdl_request) { FFW.UI.sendUIResult(result, request.id, request.method); } } else { From f7ed66ca820c436b5a9e570e991dde9f6a2b5b89 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Wed, 4 Nov 2020 09:31:21 -0500 Subject: [PATCH 100/104] Align Alert and AlerManeuver view (#452) * Fix AlertManeuver buttons behavior Do not display system defined close button when soft buttons are shown. To keep context for AlertManeuver, HMI should reset timeout using TTS interface as SDL does not listen to UI part. * Add default action to close button Also action was replaced with actionUp to avoid unnecessary buttonUp events capturing by controls on the bottom view. --- app/controller/sdl/Abstract/Controller.js | 4 ++-- app/view/sdl/AlertManeuverPopUp.js | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 1b47171c3..878bebfb7 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -698,7 +698,7 @@ SDL.SDLController = Em.Object.extend( SDL.AlertManeuverPopUp.deactivate(); }, SDL.AlertManeuverPopUp.timeout ); - this.onResetTimeout(element.appID, 'Navigation.AlertManeuver'); + FFW.TTS.OnResetTimeout(element.appID, 'Navigation.AlertManeuver'); break; } case 'SubtleAlertPopUp': @@ -758,7 +758,7 @@ SDL.SDLController = Em.Object.extend( * Method to close AlertMeneuverPopUp view */ closeAlertMeneuverPopUp: function() { - SDL.AlertManeuverPopUp.set('activate', false); + SDL.AlertManeuverPopUp.deactivate(); }, /** * Method to open Turn List view from TBT diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index bcdbf899e..d2e342fa1 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -55,6 +55,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( timer: null, timeout: 5000, alertManeuerRequestId: 0, + isCloseButtonVisible: true, /** * @desc Defines whether icons paths verified successfully. */ @@ -119,8 +120,12 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( { text: 'Close', classNames: 'closeButton softButton', - action: 'closeAlertMeneuverPopUp', - target: 'SDL.SDLController', + classNameBindings: [ + 'SDL.AlertManeuverPopUp.isCloseButtonVisible::inactive_state'], + actionUp: function() { + this._super(); + SDL.SDLController.closeAlertMeneuverPopUp(); + }, templateName: 'text' } ), @@ -215,6 +220,10 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( } SDL.SDLModel.validateImages(params.appID, callback, imageList); + + if (softButtons.length > 0) { + this.set('isCloseButtonVisible', false); + } }, /** * Deactivate PopUp @@ -244,6 +253,7 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( this.softbuttons.buttons.rerender(); this.set('iconsAreValid', true); + this.set('isCloseButtonVisible', true); this.addSoftButtons(message.params); this.set('activate', true ); From 6a15e08fcc9d711e704e06aae3ff3932359129f2 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Wed, 4 Nov 2020 10:11:25 -0500 Subject: [PATCH 101/104] Fix response params forwarding (#449) * Fix response params forwarding There was noticed a regression that HMI does not forward params in case of error. This is because of complicated and wrong logic of calculation of some corner cases. To avoid that, condition was reformatted as a more readable separate function. * Apply fix for the rest of interfaces --- ffw/BasicCommunicationRPC.js | 19 +++++++++++++++++-- ffw/NavigationRPC.js | 19 +++++++++++++++++-- ffw/RCRPC.js | 19 +++++++++++++++++-- ffw/TTSRPC.js | 19 +++++++++++++++++-- ffw/UIRPC.js | 19 +++++++++++++++++-- ffw/VRRPC.js | 19 +++++++++++++++++-- ffw/VehicleInfoRPC.js | 19 +++++++++++++++++-- 7 files changed, 119 insertions(+), 14 deletions(-) diff --git a/ffw/BasicCommunicationRPC.js b/ffw/BasicCommunicationRPC.js index 33cd76a99..668151f74 100644 --- a/ffw/BasicCommunicationRPC.js +++ b/ffw/BasicCommunicationRPC.js @@ -987,10 +987,25 @@ FFW.BasicCommunication = FFW.RPCObserver return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.BC.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/NavigationRPC.js b/ffw/NavigationRPC.js index 2132cfa89..684f04923 100644 --- a/ffw/NavigationRPC.js +++ b/ffw/NavigationRPC.js @@ -499,10 +499,25 @@ FFW.Navigation = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.Navigation.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/RCRPC.js b/ffw/RCRPC.js index c9e661b44..ad893e8f5 100644 --- a/ffw/RCRPC.js +++ b/ffw/RCRPC.js @@ -406,10 +406,25 @@ FFW.RC = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.RC.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/TTSRPC.js b/ffw/TTSRPC.js index 1a9293f03..453156f1d 100644 --- a/ffw/TTSRPC.js +++ b/ffw/TTSRPC.js @@ -399,10 +399,25 @@ FFW.TTS = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.TTS.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index b512997cb..760b6c44f 100755 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -1769,10 +1769,25 @@ FFW.UI = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.UI.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/VRRPC.js b/ffw/VRRPC.js index 01a19d556..d72b6417a 100644 --- a/ffw/VRRPC.js +++ b/ffw/VRRPC.js @@ -404,10 +404,25 @@ FFW.VR = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.VR.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', diff --git a/ffw/VehicleInfoRPC.js b/ffw/VehicleInfoRPC.js index 5764c97c1..f80d1f1dd 100644 --- a/ffw/VehicleInfoRPC.js +++ b/ffw/VehicleInfoRPC.js @@ -267,10 +267,25 @@ FFW.VehicleInfo = FFW.RPCObserver.create( return; } - const result_response = is_successful_code && (params || !info); + let is_successful_response_format = function(is_success) { + // Successful response without params, but with not-empty message + // should be sent in errorneous format to properly forward info and result code + if (is_success && info != null && params == null) { + return false; + } + + // Error response with not empty params should be sent in regular format + // to properly forward result code and params (but sacrifice info) + if (!is_success && params != null) { + return true; + } + + // Otherwise use result code calculated according to regular HMI logic + return is_success; + }; Em.Logger.log('FFW.VI.' + method + 'Response'); - if (result_response) { + if (is_successful_response_format(is_successful_code)) { // send response var JSONMessage = { 'jsonrpc': '2.0', From d3009fcf14365d2691894a35d6343c3b47ce8574 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Wed, 4 Nov 2020 11:56:56 -0500 Subject: [PATCH 102/104] Fix empty OnAppPermissionConsent (#453) HMI should not sent empty permission consents to SDL as this is invalid notification according to API. Also, was fixed appID parameter for a selected application. --- app/controller/SettingsController.js | 2 +- app/view/settings/policies/appPermissionsView.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controller/SettingsController.js b/app/controller/SettingsController.js index aa45fea05..c98a7e311 100644 --- a/app/controller/SettingsController.js +++ b/app/controller/SettingsController.js @@ -183,7 +183,7 @@ SDL.SettingsController = Em.Object.create( */ GetListOfPermissions: function(element) { FFW.BasicCommunication.GetListOfPermissions(element.appID); - SDL.AppPermissionsView.update(SDL.SDLModelData.externalConsentStatus, 0); + SDL.AppPermissionsView.update(SDL.SDLModelData.externalConsentStatus, element.appID); SDL.States.goToStates('settings.policies.appPermissions'); }, /** diff --git a/app/view/settings/policies/appPermissionsView.js b/app/view/settings/policies/appPermissionsView.js index 8bda1b959..828625831 100644 --- a/app/view/settings/policies/appPermissionsView.js +++ b/app/view/settings/policies/appPermissionsView.js @@ -73,12 +73,14 @@ SDL.AppPermissionsView = Em.ContainerView.create( } ); } - FFW.BasicCommunication.OnAppPermissionConsent( - permissions, null, 'GUI', SDL.AppPermissionsView.currentAppId - ); + if (permissions.length > 0) { + FFW.BasicCommunication.OnAppPermissionConsent( + permissions, null, 'GUI', SDL.AppPermissionsView.currentAppId + ); + } SDL.AppPermissionsView.currentAppId = null; }, - goToState: 'policies', + goToState: 'policies.appPermissionsList', icon: 'images/media/ico_back.png', onDown: false } From 32356f63f6af813fd52782aefa18ecdcfae732c4 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Wed, 4 Nov 2020 12:04:59 -0500 Subject: [PATCH 103/104] Fix/fix template image support for elements (#454) * Add template images support for POI list There was missing button template type for a left text overlay. Also, template style was not applied when list items were constructed initially * Added image mode support for missing elements --- app/controlls/Button.js | 6 ++++++ app/controlls/List.js | 2 ++ app/controlls/MenuList.js | 10 ++++++++++ app/view/info/appsView.js | 1 + app/view/mediaView.js | 32 ++++++++++++++++++++++++++++++-- app/view/navigationView.js | 7 +++---- css/media.css | 4 ---- 7 files changed, 52 insertions(+), 10 deletions(-) diff --git a/app/controlls/Button.js b/app/controlls/Button.js index 2c5dbc581..bad0154a6 100644 --- a/app/controlls/Button.js +++ b/app/controlls/Button.js @@ -187,6 +187,12 @@ SDL.Button = Em.View.extend(Ember.TargetActionSupport, templates: { text: Em.Handlebars.compile('{{view.text}}'), + textOverlay: Em.Handlebars.compile( + '' + + '' + + '{{view.text}}' + ), + icon: Em.Handlebars.compile( '' diff --git a/app/controlls/List.js b/app/controlls/List.js index 66935a588..524b49036 100644 --- a/app/controlls/List.js +++ b/app/controlls/List.js @@ -204,6 +204,8 @@ SDL.List = Em.ContainerView.extend({ } ); + element.setMode(SDL.SDLModel.data.imageMode); + // Push element to list this.get('childViews').pushObject(element); } diff --git a/app/controlls/MenuList.js b/app/controlls/MenuList.js index e8adeeb32..0635f936a 100644 --- a/app/controlls/MenuList.js +++ b/app/controlls/MenuList.js @@ -83,6 +83,16 @@ SDL.MenuList = Em.ContainerView.extend({ ); }, + /** Method setting up display mode for correspond components */ + setMode: function(mode){ + var items = this.get('content.childViews'); + + for (var i = 0; i < items.length; ++i) { + var button = items[i]; + button.setMode(mode); + } + }, + classNames: [ 'ffw_list_menu' ], diff --git a/app/view/info/appsView.js b/app/view/info/appsView.js index 0cd0c1ddb..d8b28ccfe 100644 --- a/app/view/info/appsView.js +++ b/app/view/info/appsView.js @@ -183,6 +183,7 @@ SDL.InfoAppsView = Em.ContainerView.create({ SDL.InfoAppsView.vehicleHealthReport.setMode(SDL.SDLModel.data.imageMode); SDL.InfoAppsView.getDeviceList.setMode(SDL.SDLModel.data.imageMode); SDL.InfoAppsView.applicationsStore.setMode(SDL.SDLModel.data.imageMode); + SDL.InfoAppsView.listOfApplications.setMode(SDL.SDLModel.data.imageMode); }.observes('SDL.SDLModel.data.imageMode') } ); diff --git a/app/view/mediaView.js b/app/view/mediaView.js index 97cec9f13..60e2ceb69 100644 --- a/app/view/mediaView.js +++ b/app/view/mediaView.js @@ -42,12 +42,40 @@ SDL.MediaView = Em.ContainerView.create( 'volumeMenu', 'optionsMenu', SDL.playerView, - SDL.sdlView + 'sdlView' ], /** Left Menu view component */ leftMenu: SDL.LeftMenuView, /** Volume Menu view component */ volumeMenu: SDL.VolumeMenuView, - optionsMenu: SDL.audioView + optionsMenu: SDL.audioView, + sdlView: SDL.sdlView, + + /** + * @description Callback for display image mode change. + */ + imageModeChanged: function() { + this.leftMenu.radio.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.cdButton.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.usbButton.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.bluetoothButton.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.lineInButton.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.ipodButton.setMode(SDL.SDLModel.data.imageMode); + this.leftMenu.sdlButton.setMode(SDL.SDLModel.data.imageMode); + + this.volumeMenu.currentVolume.currentVolume_minus.setMode(SDL.SDLModel.data.imageMode); + this.volumeMenu.currentVolume.currentVolume_plus.setMode(SDL.SDLModel.data.imageMode); + + this.optionsMenu.preferencesButton.optionsButton.setMode(SDL.SDLModel.data.imageMode); + + this.sdlView.innerMenu.setMode(SDL.SDLModel.data.imageMode); + this.sdlView.controlls.Controls.PrevTrackButton.setMode(SDL.SDLModel.data.imageMode); + this.sdlView.controlls.Controls.PlayButton.setMode(SDL.SDLModel.data.imageMode); + this.sdlView.controlls.Controls.NextTrackButton.setMode(SDL.SDLModel.data.imageMode); + + this.sdlView.controlls.tuneButtons.wrapper.get('childViews').forEach( (view) => { + view.setMode(SDL.SDLModel.data.imageMode); + }); + }.observes('SDL.SDLModel.data.imageMode') } ); diff --git a/app/view/navigationView.js b/app/view/navigationView.js index 565459083..335ce1d4f 100644 --- a/app/view/navigationView.js +++ b/app/view/navigationView.js @@ -54,6 +54,7 @@ SDL.NavigationView = Em.ContainerView.create( itemGenerator: function() { var items = []; for (var i = 0; i < SDL.NavigationModel.LocationDetails.length; i++) { + const img = SDL.NavigationModel.LocationDetails[i].locationImage; items.push( { type: SDL.Button, @@ -62,10 +63,8 @@ SDL.NavigationView = Em.ContainerView.create( className: 'button', text: SDL.NavigationModel.LocationDetails[i].locationName, disabled: false, - icon: SDL.NavigationModel.LocationDetails[i].locationImage - ? SDL.NavigationModel.LocationDetails[i].locationImage.value : '', - templateName: SDL.NavigationModel.LocationDetails[i].locationImage - ? '' : 'text', + icon: img ? img.value : '', + templateName: img && img.isTemplate ? 'textOverlay' : '', action: 'openWayPoint', target: 'SDL.NavigationController' } diff --git a/css/media.css b/css/media.css index 831c3370c..cff2d308b 100644 --- a/css/media.css +++ b/css/media.css @@ -105,7 +105,6 @@ position: relative; height: 50px; cursor: pointer; - background: url(../images/media/ls-item_bg.png) no-repeat; } .media-ls-item.active_state { @@ -986,7 +985,6 @@ height: 98px; border-right: 1px solid #393939; cursor: pointer; - background: url(../images/media/cd-prev-btn.png) no-repeat; } .bc-item-big.prevcd.pressed, .bc-item-big.prevusb.pressed, @@ -1003,7 +1001,6 @@ height: 98px; border-right: 1px solid #393939; cursor: pointer; - background: url(../images/media/cd_play_btn.png) no-repeat; top: 0px; position: absolute; left: 156px; @@ -1058,7 +1055,6 @@ width: 154px; height: 98px; cursor: pointer; - background: url(../images/media/cd-next-btn.png) no-repeat; top: 0px; position: absolute; left: 314px; From 7e6fd1c421cbd4b3b3a78ebd72d0cf0076a572e1 Mon Sep 17 00:00:00 2001 From: "Andrii Kalinich (GitHub)" Date: Wed, 4 Nov 2020 12:14:15 -0500 Subject: [PATCH 104/104] Fix ScrollableMessage, SetGlobalProperties, AlertManeuver (#451) The was noticed a wrong image validation logic in mentioned rpcs. In all cases HMI responds twice - first time with regular result code and the second time with the result of images validation. To fix that, image validation has been placed into the proper place in the code and appropriate breaks were added. Also, was added timer stop for AlertManeuver popup. --- app/controller/sdl/Abstract/Controller.js | 10 +++---- app/model/sdl/Abstract/Model.js | 17 ----------- app/view/sdl/AlertManeuverPopUp.js | 2 ++ app/view/sdl/shared/scrollableMessage.js | 35 +++++++++++++++++++++-- ffw/UIRPC.js | 16 ++++++----- 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/app/controller/sdl/Abstract/Controller.js b/app/controller/sdl/Abstract/Controller.js index 878bebfb7..8eda035fc 100644 --- a/app/controller/sdl/Abstract/Controller.js +++ b/app/controller/sdl/Abstract/Controller.js @@ -883,15 +883,15 @@ SDL.SDLController = Em.Object.extend( messageRequestId, 'UI.ScrollableMessage' ); - }else if(result == SDL.SDLModel.data.resultCode.WARNINGS) { + } else if(result == SDL.SDLModel.data.resultCode.WARNINGS) { FFW.UI.sendUIResult( result, messageRequestId, - 'UI.ScrollableMessage' + 'UI.ScrollableMessage', + 'Requested image(s) not found' ); - } - else { - FFW.UI.sendError( + } else { + FFW.UI.sendUIResult( result, messageRequestId, 'UI.ScrollableMessage', diff --git a/app/model/sdl/Abstract/Model.js b/app/model/sdl/Abstract/Model.js index bf6c4e29c..3854c6796 100644 --- a/app/model/sdl/Abstract/Model.js +++ b/app/model/sdl/Abstract/Model.js @@ -936,23 +936,6 @@ SDL.SDLModel = Em.Object.extend({ request.params, messageRequestId ); } - if(request.params.softButtons) { - var imageList = []; - for(var i = 0; i < request.params.softButtons.length; i++) { - if(request.params.softButtons[i].image) { - imageList.push(request.params.softButtons[i].image.value); - } - } - var callback = function(failed) { - if(failed) { - FFW.UI.sendUIResult( - SDL.SDLModel.data.resultCode.WARNINGS, - request.id, - request.method, "Requested image(s) not found"); - } - }; - SDL.SDLModel.validateImages(request.id, callback, imageList); - } return true; } else { FFW.UI.sendError(SDL.SDLModel.data.resultCode.REJECTED, request.id, diff --git a/app/view/sdl/AlertManeuverPopUp.js b/app/view/sdl/AlertManeuverPopUp.js index d2e342fa1..a6ea13838 100644 --- a/app/view/sdl/AlertManeuverPopUp.js +++ b/app/view/sdl/AlertManeuverPopUp.js @@ -233,6 +233,8 @@ SDL.AlertManeuverPopUp = Em.ContainerView.create( SDL.TTSPopUp.DeactivateTTS(); } + clearTimeout(this.timer); + const resultCode = this.iconsAreValid ? SDL.SDLModel.data.resultCode.SUCCESS : SDL.SDLModel.data.resultCode.WARNINGS; const info = this.iconsAreValid ? diff --git a/app/view/sdl/shared/scrollableMessage.js b/app/view/sdl/shared/scrollableMessage.js index d475a1dd3..557e4587c 100644 --- a/app/view/sdl/shared/scrollableMessage.js +++ b/app/view/sdl/shared/scrollableMessage.js @@ -50,6 +50,7 @@ SDL.ScrollableMessage = SDL.SDLAbstractView.create( timer: null, timeout: null, endTime: null, + areAllImagesValid: true, childViews: [ 'backButton', 'captionText', 'softButtons', 'listOfCommands' ], @@ -65,9 +66,21 @@ SDL.ScrollableMessage = SDL.SDLAbstractView.create( this.set('active', false); this.softButtons.set('page', 0); this.timeout = null; + + let calculate_result_code = function(areAllImagesValid) { + if (ABORTED) { + return SDL.SDLModel.data.resultCode.ABORTED; + } + + if (!areAllImagesValid) { + return SDL.SDLModel.data.resultCode.WARNINGS; + } + + return SDL.SDLModel.data.resultCode.SUCCESS; + }; + SDL.SDLController.scrollableMessageResponse( - ABORTED ? SDL.SDLModel.data.resultCode['ABORTED'] : - SDL.SDLModel.data.resultCode.SUCCESS, this.messageRequestId + calculate_result_code(this.areAllImagesValid), this.messageRequestId ); SDL.SDLController.onSystemContextChange(); SDL.SDLModel.data.registeredApps.forEach(app => { @@ -76,13 +89,16 @@ SDL.ScrollableMessage = SDL.SDLAbstractView.create( }) }) }, + activate: function(appName, params, messageRequestId) { if (appName) { var self = this; if (params.messageText.fieldName == 'scrollableMessageBody') { this.set('listOfCommands.items', params.messageText.fieldText); } + this.set('messageRequestId', messageRequestId); + this.set('areAllImagesValid', true); this.set('captionText.content', appName); this.softButtons.addItems(params.softButtons, params.appID); this.set('active', true); @@ -95,6 +111,21 @@ SDL.ScrollableMessage = SDL.SDLAbstractView.create( self.deactivate(); }, params.timeout ); + + if(params.softButtons) { + var imageList = []; + for(var i = 0; i < params.softButtons.length; i++) { + if(params.softButtons[i].image) { + imageList.push(params.softButtons[i].image.value); + } + } + var that = this; + var callback = function(failed) { + that.set('areAllImagesValid', !failed); + }; + + SDL.SDLModel.validateImages(messageRequestId, callback, imageList); + } } }, softButtons: SDL.MenuList.extend( diff --git a/ffw/UIRPC.js b/ffw/UIRPC.js index 760b6c44f..09a279a1a 100755 --- a/ffw/UIRPC.js +++ b/ffw/UIRPC.js @@ -343,23 +343,25 @@ FFW.UI = FFW.RPCObserver.create( } } + var that = this; var callback = function(failed) { var WARNINGS = SDL.SDLModel.data.resultCode.WARNINGS; - var SUCCESS = SDL.SDLModel.data.resultCode.SUCCESS; + var SUCCESS = resultCode; - FFW.Navigation.sendNavigationResult( - failed ? WARNINGS : SUCCESS, - request.id, - request.method, + that.sendUIResult( + failed ? WARNINGS : SUCCESS, + request.id, + request.method, failed ? "Requested image(s) not found" : null); } SDL.SDLModel.validateImages(request.id, callback, imageList); + break; } else { info = 'Erroneous response is assigned by settings'; } - this.sendUIResult( - resultCode, request.id, request.method, info + this.sendUIResult( + resultCode, request.id, request.method, info ); break; }