Skip to content

Commit a2c85b5

Browse files
authored
Merge pull request #269 from smartdevicelink/bugfix/scm-null-check-capability
Align JS SCM and textgraphicmanager with Java Suite's
2 parents 2a24f9b + 0aac48b commit a2c85b5

10 files changed

Lines changed: 851 additions & 221 deletions

File tree

examples/js/hello-sdl/SDL.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/node/hello-sdl-tcp/SDL.min.js

Lines changed: 212 additions & 55 deletions
Large diffs are not rendered by default.

examples/node/hello-sdl/SDL.min.js

Lines changed: 212 additions & 55 deletions
Large diffs are not rendered by default.

examples/webengine/hello-sdl/SDL.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/js/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { LifecycleConfig as manager_LifecycleConfig_js} from './src/manager/Life
3737
import { SdlManager as manager_SdlManager_js} from './src/manager/SdlManager.js';
3838
import { SdlManagerListener as manager_SdlManagerListener_js} from './src/manager/SdlManagerListener.js';
3939
import { SystemCapabilityManager as manager_SystemCapabilityManager_js} from './src/manager/SystemCapabilityManager.js';
40+
import { _ManagerUtility as manager__ManagerUtility_js} from './src/manager/_ManagerUtility.js';
4041
import { _SdlManagerBase as manager__SdlManagerBase_js} from './src/manager/_SdlManagerBase.js';
4142
import { _SubManagerBase as manager__SubManagerBase_js} from './src/manager/_SubManagerBase.js';
4243
import { FileManager as manager_file_FileManager_js} from './src/manager/file/FileManager.js';
@@ -474,6 +475,7 @@ const SDL = {
474475
SdlManager: manager_SdlManager_js,
475476
SdlManagerListener: manager_SdlManagerListener_js,
476477
SystemCapabilityManager: manager_SystemCapabilityManager_js,
478+
_ManagerUtility: manager__ManagerUtility_js,
477479
_SdlManagerBase: manager__SdlManagerBase_js,
478480
_SubManagerBase: manager__SubManagerBase_js,
479481
file: {

lib/js/dist/SDL.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/js/src/manager/SystemCapabilityManager.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { FunctionID } from '../rpc/enums/FunctionID.js';
4646
import { WindowCapability } from '../rpc/structs/WindowCapability.js';
4747
import { ServiceUpdateReason } from '../rpc/enums/ServiceUpdateReason.js';
4848
import { RpcResponse } from '../rpc/RpcResponse.js';
49+
import { _ManagerUtility } from './_ManagerUtility.js';
4950

5051
class SystemCapabilityManager extends _SubManagerBase {
5152
/**
@@ -236,6 +237,8 @@ class SystemCapabilityManager extends _SubManagerBase {
236237

237238
// return if display capabilities don't exist.
238239
if (displayCapabilities === null || displayCapabilities === undefined) {
240+
defaultWindowCapability.setTextFields(_ManagerUtility.getAllTextFields());
241+
defaultWindowCapability.setImageFields(_ManagerUtility.getAllImageFields());
239242
displayCapability.setWindowCapabilities([defaultWindowCapability]);
240243
return [displayCapability];
241244
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* Copyright (c) 2020, Livio, Inc.
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
*
8+
* Redistributions of source code must retain the above copyright notice, this
9+
* list of conditions and the following disclaimer.
10+
*
11+
* Redistributions in binary form must reproduce the above copyright notice,
12+
* this list of conditions and the following
13+
* disclaimer in the documentation and/or other materials provided with the
14+
* distribution.
15+
*
16+
* Neither the name of the Livio Inc. nor the names of its contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30+
* POSSIBILITY OF SUCH DAMAGE.
31+
*/
32+
33+
import { TextField } from '../rpc/structs/TextField.js';
34+
import { ImageField } from '../rpc/structs/ImageField.js';
35+
import { TextFieldName } from '../rpc/enums/TextFieldName.js';
36+
import { ImageFieldName } from '../rpc/enums/ImageFieldName.js';
37+
import { CharacterSet } from '../rpc/enums/CharacterSet.js';
38+
import { FileType } from '../rpc/enums/FileType.js';
39+
40+
class _ManagerUtility {
41+
/**
42+
* Check to see if WindowCapability has an ImageFieldName of a given name.
43+
* @private
44+
* @param {WindowCapability} windowCapability - Represents the capabilities of the desired window
45+
* @param {ImageFieldName} name - Representing a name of a given Image field that would be stored in WindowCapability
46+
* @return {Boolean} - True if the name exists in WindowCapability, otherwise false
47+
*/
48+
static hasImageFieldOfName (windowCapability, name) {
49+
if (windowCapability === null || name === null) {
50+
return false;
51+
}
52+
if (windowCapability.getImageFields() !== null) {
53+
for (const field of windowCapability.getImageFields()) {
54+
if (field !== null && name === field.getNameParam()) {
55+
return true;
56+
}
57+
}
58+
}
59+
return false;
60+
}
61+
62+
/**
63+
* Check to see if WindowCapability has a textField of a given name.
64+
* @private
65+
* @param {WindowCapability} windowCapability - Represents the capabilities of the desired window
66+
* @param {TextFieldName} name - Representing a name of a given text field that would be stored in WindowCapability
67+
* @return {Boolean} - True if the name exists in WindowCapability, otherwise false
68+
*/
69+
static hasTextFieldOfName (windowCapability, name) {
70+
if (windowCapability === null || name === null) {
71+
return false;
72+
}
73+
if (windowCapability.getTextFields() !== null) {
74+
for (const field of windowCapability.getTextFields()) {
75+
if (field !== null && name === field.getNameParam()) {
76+
return true;
77+
}
78+
}
79+
}
80+
return false;
81+
}
82+
83+
/**
84+
* Gets the number of show lines available on the head unit
85+
* @private
86+
* @param {WindowCapability} windowCapability - Represents the capabilities of the desired window
87+
* @returns {Number} - The number of lines.
88+
*/
89+
static getMaxNumberOfMainFieldLines (windowCapability) {
90+
let highestFound = 0;
91+
if (windowCapability !== null && windowCapability.getTextFields() !== null) {
92+
for (const field of windowCapability.getTextFields()) {
93+
let fieldNumber = 0;
94+
switch (field.getNameParam()) {
95+
case TextFieldName.mainField1:
96+
fieldNumber = 1;
97+
break;
98+
case TextFieldName.mainField2:
99+
fieldNumber = 2;
100+
break;
101+
case TextFieldName.mainField3:
102+
fieldNumber = 3;
103+
break;
104+
case TextFieldName.mainField4:
105+
fieldNumber = 4;
106+
break;
107+
}
108+
if (fieldNumber > 0) {
109+
highestFound = Math.max(highestFound, fieldNumber);
110+
if (highestFound === 4) {
111+
break;
112+
}
113+
}
114+
}
115+
}
116+
return highestFound;
117+
}
118+
119+
/**
120+
* Method to get a list of all available text fields
121+
* @private
122+
* @return {TextField[]} - A list of all available text fields with CID1SET Character Set
123+
*/
124+
static getAllTextFields () {
125+
const allTextFields = [];
126+
for (const textFieldName in TextFieldName._MAP) {
127+
allTextFields.push(new TextField()
128+
.setNameParam(TextFieldName._MAP[textFieldName])
129+
.setCharacterSet(CharacterSet.CID1SET)
130+
.setWidth(500)
131+
.setRows(8));
132+
}
133+
return allTextFields;
134+
}
135+
136+
/**
137+
* Method to get a list of all available text fields
138+
* @private
139+
* @return {ImageField[]} - A list of all available Image fields with GRAPHIC_BMP, GRAPHIC_JPEG, GRAPHIC_PNG File Types
140+
*/
141+
static getAllImageFields () {
142+
const allImageFields = [];
143+
const allImageFileTypes = [FileType.GRAPHIC_BMP, FileType.GRAPHIC_JPEG, FileType.GRAPHIC_PNG];
144+
for (const imageFieldName in ImageFieldName._MAP) {
145+
allImageFields.push(new ImageField()
146+
.setNameParam(ImageFieldName._MAP[imageFieldName])
147+
.setImageTypeSupported(allImageFileTypes));
148+
}
149+
return allImageFields;
150+
}
151+
}
152+
153+
export { _ManagerUtility };

lib/js/src/manager/screen/_TextAndGraphicManagerBase.js

Lines changed: 51 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@
3333
import { _SubManagerBase } from '../_SubManagerBase.js';
3434
import { Show } from '../../rpc/messages/Show.js';
3535
import { MetadataTags } from '../../rpc/structs/MetadataTags.js';
36+
import { ImageFieldName } from '../../rpc/enums/ImageFieldName.js';
3637
import { TextFieldName } from '../../rpc/enums/TextFieldName.js';
38+
import { _ManagerUtility } from '../_ManagerUtility.js';
3739

3840
class _TextAndGraphicManagerBase extends _SubManagerBase {
3941
/**
@@ -239,11 +241,11 @@ class _TextAndGraphicManagerBase extends _SubManagerBase {
239241
_assembleShowText (show) {
240242
show = this._setBlankTextFields(show);
241243

242-
if (this._mediaTrackTextField !== null) {
244+
if (this._mediaTrackTextField !== null && this._shouldUpdateMediaTrackField()) {
243245
show.setMediaTrack(this._mediaTrackTextField);
244246
}
245247

246-
if (this._title !== null) {
248+
if (this._title !== null && this._shouldUpdateTitleField()) {
247249
show.setTemplateTitle(this._title);
248250
}
249251

@@ -252,7 +254,7 @@ class _TextAndGraphicManagerBase extends _SubManagerBase {
252254
return show;
253255
}
254256

255-
const numberOfLines = this._getNumberOfLines();
257+
const numberOfLines = this._defaultMainWindowCapability !== null ? _ManagerUtility.getMaxNumberOfMainFieldLines(this._defaultMainWindowCapability) : 4;
256258

257259
switch (numberOfLines) {
258260
case 1: show = this._assembleOneLineShowText(show, nonNullFields);
@@ -643,21 +645,14 @@ class _TextAndGraphicManagerBase extends _SubManagerBase {
643645
* @returns {Boolean} - Whether or not the primary image needs to be uploaded.
644646
*/
645647
_shouldUpdatePrimaryImage () {
646-
if (this._defaultMainWindowCapability === null || !Array.isArray(this._defaultMainWindowCapability.getImageTypeSupported())
647-
|| this._defaultMainWindowCapability.getImageTypeSupported().length > 0) {
648-
// Cannot detect if there is a secondary image, so we'll just try to detect if there's a primary image and allow it if there is.
649-
if (this._currentScreenData.getGraphic() === null || this._currentScreenData.getGraphic() === undefined) {
650-
return this._primaryGraphic !== null;
651-
} else {
652-
if (this._primaryGraphic === null) {
653-
return false;
654-
}
655-
const screenDataValue = this._currentScreenData.getGraphic().getValueParam();
656-
const secondaryGraphicValue = this._primaryGraphic.getName();
657-
return (`${screenDataValue}`).toLowerCase() === (`${secondaryGraphicValue}`).toLowerCase();
658-
}
659-
}
660-
return false;
648+
const templateSupportsPrimaryArtwork = this._templateSupportsImageField(ImageFieldName.graphic);
649+
650+
const currentScreenDataPrimaryGraphicName = (this._currentScreenData !== null && this._currentScreenData.getGraphic() !== null) ? this._currentScreenData.getGraphic().getValueParam() : null;
651+
const primaryGraphicName = this._primaryGraphic !== null ? this._primaryGraphic.getName() : null;
652+
653+
return templateSupportsPrimaryArtwork
654+
&& (`${currentScreenDataPrimaryGraphicName}`).toLowerCase() !== (`${primaryGraphicName}`).toLowerCase()
655+
&& this._primaryGraphic !== null;
661656
}
662657

663658
/**
@@ -666,46 +661,52 @@ class _TextAndGraphicManagerBase extends _SubManagerBase {
666661
* @returns {Boolean} - Whether or not the secondary image needs to be uploaded.
667662
*/
668663
_shouldUpdateSecondaryImage () {
669-
if (this._defaultMainWindowCapability === null || !Array.isArray(this._defaultMainWindowCapability.getImageTypeSupported())
670-
|| this._defaultMainWindowCapability.getImageTypeSupported().length > 0) {
671-
// Cannot detect if there is a secondary image, so we'll just try to detect if there's a primary image and allow it if there is.
672-
if (this._currentScreenData.getGraphic() === null || this._currentScreenData.getGraphic() === undefined) {
673-
return this._secondaryGraphic !== null;
674-
} else {
675-
if (this._secondaryGraphic === null) {
676-
return false;
677-
}
678-
const screenDataValue = this._currentScreenData.getGraphic().getValueParam();
679-
const secondaryGraphicValue = this._secondaryGraphic.getName();
680-
return (`${screenDataValue}`).toLowerCase() === (`${secondaryGraphicValue}`).toLowerCase();
681-
}
682-
}
683-
return false;
664+
const templateSupportsSecondaryArtwork = this._templateSupportsImageField(ImageFieldName.graphic) || this._templateSupportsImageField(ImageFieldName.secondaryGraphic);
665+
666+
const currentScreenDataSecondaryGraphicName = (this._currentScreenData !== null && this._currentScreenData.getSecondaryGraphic() !== null) ? this._currentScreenData.getSecondaryGraphic().getValueParam() : null;
667+
const secondaryGraphicName = this._secondaryGraphic !== null ? this._secondaryGraphic.getName() : null;
668+
669+
return templateSupportsSecondaryArtwork
670+
&& (`${currentScreenDataSecondaryGraphicName}`).toLowerCase() !== (`${secondaryGraphicName}`).toLowerCase()
671+
&& this._secondaryGraphic !== null;
684672
}
685673

686674
/**
687-
* Gets the number of show lines available on the head unit
675+
* Check to see if mediaTrackTextField should be updated
688676
* @private
689-
* @returns {Number} - The number of lines.
677+
* @return {Boolean} - True if mediaTrackTextField should be updated, false if not
690678
*/
691-
_getNumberOfLines () {
692-
if (this._defaultMainWindowCapability === null) {
693-
return 4;
694-
}
679+
_shouldUpdateMediaTrackField() {
680+
return this._templateSupportsTextField(TextFieldName.mediaTrack);
681+
}
695682

696-
let linesFound = 0;
697-
const textFields = this._defaultMainWindowCapability.getTextFields();
683+
/**
684+
* Check to see if title should be updated
685+
* @private
686+
* @return {Boolean} - True if title should be updated, false if not
687+
*/
688+
_shouldUpdateTitleField() {
689+
return this._templateSupportsTextField(TextFieldName.templateTitle);
690+
}
698691

699-
if (Array.isArray(textFields)) {
700-
for (const field of textFields) {
701-
const name = field.getNameParam();
702-
if (name === TextFieldName.mainField1 || name === TextFieldName.mainField2 || name === TextFieldName.mainField3 || name === TextFieldName.mainField4) {
703-
linesFound += 1;
704-
}
705-
}
706-
}
692+
/**
693+
* Check to see if template supports the specified text field
694+
* @private
695+
* @param {TextFieldName} name - The text field name to check
696+
* @return {Boolean} - True if text field is supported, false if not
697+
*/
698+
_templateSupportsTextField (name) {
699+
return this._defaultMainWindowCapability === null || _ManagerUtility.hasTextFieldOfName(this._defaultMainWindowCapability, name);
700+
}
707701

708-
return linesFound;
702+
/**
703+
* Check to see if template supports the specified image field
704+
* @private
705+
* @param {ImageFieldName} name - The image field name to check
706+
* @return {Boolean} - True if image field is supported, false if not
707+
*/
708+
_templateSupportsImageField (name) {
709+
return this._defaultMainWindowCapability === null || _ManagerUtility.hasImageFieldOfName(this._defaultMainWindowCapability, name);
709710
}
710711

711712
// SCREEN ITEM SETTERS AND GETTERS

0 commit comments

Comments
 (0)