Skip to content

Commit 264e4a7

Browse files
committed
Fix merge conflicts
2 parents cf5d507 + 9786a14 commit 264e4a7

45 files changed

Lines changed: 1663 additions & 50 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/PULL_REQUEST_TEMPLATE.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This PR makes **[no / minor / major]** API changes.
99

1010
### Testing Plan
1111
- [ ] I have verified that I have not introduced new warnings in this PR (or explain why below)
12+
- [ ] I have verified that this PR passes lint validation
1213
- [ ] I have run the unit tests with this PR
1314
- [ ] I have tested this PR against Core and verified behavior (if applicable, if not applicable, explain why below).
1415

lib/js/src/manager/screen/_ScreenManagerBase.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ class _ScreenManagerBase extends _SubManagerBase {
457457

458458
/**
459459
* Preload choices to improve performance while presenting a choice set at a later time
460-
* @param {ChoiceCell[]} choices - a list of ChoiceCell objects that will be part of a choice set later
460+
* @param {ChoiceCell[]} choices - a list of ChoiceCell objects that will be part of a choice set later
461461
* @returns {Promise} - A promise.
462462
*/
463463
async preloadChoices (choices) {

lib/js/src/manager/screen/choiceset/KeyboardListener.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class KeyboardListener {
4646
this._updateAutocompleteWithInput = null;
4747
this._updateCharacterSetWithInput = null;
4848
this._onKeyboardDidSendEvent = null;
49+
this._onKeyboardInputMaskHasChanged = null;
4950
}
5051

5152
/**
@@ -98,6 +99,16 @@ class KeyboardListener {
9899
return this;
99100
}
100101

102+
/**
103+
* Set the onKeyboardInputMaskHasChanged function.
104+
* @param {function} listener - A function to be invoked when the event occurs.
105+
* @returns {KeyboardListener} - A reference to this instance to allow method chaining.
106+
*/
107+
setOnKeyboardInputMaskHasChanged (listener) {
108+
this._onKeyboardInputMaskHasChanged = listener;
109+
return this;
110+
}
111+
101112
/**
102113
* Safely attempts to invoke the onUserDidSubmitInput event.
103114
* The keyboard session completed with some input.
@@ -162,6 +173,17 @@ class KeyboardListener {
162173
this._onKeyboardDidSendEvent(event, currentInputText);
163174
}
164175
}
176+
177+
/**
178+
* Safely attempts to invoke the onKeyboardInputMaskHasChanged event.
179+
* Implement this to be notified of all events occurring on the keyboard
180+
* @param {KeyboardEvent} event - The event that occurred
181+
*/
182+
onKeyboardInputMaskHasChanged (event) {
183+
if (typeof this._onKeyboardInputMaskHasChanged === 'function') {
184+
this._onKeyboardInputMaskHasChanged(event);
185+
}
186+
}
165187
}
166188

167189
export { KeyboardListener };

lib/js/src/manager/screen/choiceset/_ChoiceSetManagerBase.js

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,8 @@ class _ChoiceSetManagerBase extends _SubManagerBase {
402402
console.warn('ChoiceSetManager: There is a current or pending choice set, cancelling and continuing.');
403403
}
404404

405+
customKeyboardConfig = this._createValidKeyboardConfigurationBasedOnKeyboardCapabilitiesFromConfiguration(customKeyboardConfig);
406+
405407
if (customKeyboardConfig === null) {
406408
customKeyboardConfig = this._keyboardConfiguration !== null ? this._keyboardConfiguration : this._defaultKeyboardConfiguration();
407409
}
@@ -445,16 +447,68 @@ class _ChoiceSetManagerBase extends _SubManagerBase {
445447
* @param {KeyboardProperties} keyboardConfiguration - The custom keyboard configuration to be used when the keyboard is displayed
446448
*/
447449
setKeyboardConfiguration (keyboardConfiguration = null) {
448-
if (keyboardConfiguration === null) {
450+
const properties = this._createValidKeyboardConfigurationBasedOnKeyboardCapabilitiesFromConfiguration(keyboardConfiguration);
451+
if (properties === null) {
449452
this._keyboardConfiguration = this._defaultKeyboardConfiguration();
450453
} else {
451-
this._keyboardConfiguration = new KeyboardProperties()
452-
.setLanguage(keyboardConfiguration.getLanguage() === null ? Language.EN_US : keyboardConfiguration.getLanguage())
453-
.setKeyboardLayout(keyboardConfiguration.getKeyboardLayout() === null ? KeyboardLayout.QWERTZ : keyboardConfiguration.getKeyboardLayout())
454-
.setKeypressMode(keyboardConfiguration.getKeypressMode() === null ? KeypressMode.RESEND_CURRENT_ENTRY : keyboardConfiguration.getKeypressMode())
455-
.setLimitedCharacterList(keyboardConfiguration.getLimitedCharacterList())
456-
.setAutoCompleteText(keyboardConfiguration.getAutoCompleteText());
454+
this._keyboardConfiguration = properties;
455+
}
456+
}
457+
458+
/**
459+
* Takes a keyboard configuration and creates a valid version of it, if possible, based on keyboardCapabilities
460+
* @param {KeyboardProperties} keyboardConfiguration - The custom keyboard configuration to be used when the keyboard is displayed
461+
* @returns {KeyboardProperties|null} Returns KeyboardProperties or null if the keyboard layout is not supported
462+
*/
463+
_createValidKeyboardConfigurationBasedOnKeyboardCapabilitiesFromConfiguration (keyboardConfiguration = null) {
464+
/**
465+
* @type {KeyboardCapabilities}
466+
*/
467+
const keyboardCapabilities = (this._defaultMainWindowCapability && this._defaultMainWindowCapability.getKeyboardCapabilities()) || null;
468+
469+
// If there are no keyboard capabilities, if there is no passed keyboard configuration, or if there is no layout to the passed keyboard configuration, just pass back the passed in configuration
470+
if (keyboardCapabilities === null || keyboardConfiguration === null || keyboardConfiguration.getKeyboardLayout() === null) {
471+
return keyboardConfiguration;
472+
}
473+
474+
/**
475+
* @type {KeyboardLayoutCapability}
476+
*/
477+
let selectedLayoutCapability = null;
478+
479+
for (const layoutCapability of keyboardCapabilities.getSupportedKeyboards()) {
480+
if (layoutCapability.getKeyboardLayout() === keyboardConfiguration.getKeyboardLayout()) {
481+
selectedLayoutCapability = layoutCapability;
482+
break;
483+
}
484+
}
485+
486+
if (selectedLayoutCapability === null) {
487+
console.error(`Configured keyboard layout is not supported: ${keyboardConfiguration.getKeyboardLayout()}`);
488+
return null;
489+
}
490+
491+
const modifiedKeyboardConfiguration = new KeyboardProperties(keyboardConfiguration.getParameters());
492+
493+
const customKeys = keyboardConfiguration.getCustomKeys();
494+
if (!customKeys || !Array.isArray(customKeys) || customKeys.length === 0) {
495+
modifiedKeyboardConfiguration.setCustomKeys(null);
496+
} else {
497+
// If there are more custom keys than are allowed for the selected keyboard layout, we need to trim the number of keys to only use the first n number of custom keys, where n is the number of allowed custom keys for that layout.
498+
const numConfigurableKeys = selectedLayoutCapability.getNumConfigurableKeys();
499+
if (customKeys.length > numConfigurableKeys) {
500+
modifiedKeyboardConfiguration.setCustomKeys(customKeys.slice(0, numConfigurableKeys));
501+
console.warn(`${customKeys.length} custom keys set, but the selected layout: ${keyboardConfiguration.getKeyboardLayout()} only supports ${numConfigurableKeys}. Dropping the rest.`);
502+
}
457503
}
504+
505+
// If the keyboard does not support masking input characters, we will remove it from the keyboard configuration
506+
if (!keyboardCapabilities.getMaskInputCharactersSupported()) {
507+
modifiedKeyboardConfiguration.setMaskInputCharacters(null);
508+
console.warn('Mask input characters is not supported');
509+
}
510+
511+
return modifiedKeyboardConfiguration;
458512
}
459513

460514

@@ -536,7 +590,7 @@ class _ChoiceSetManagerBase extends _SubManagerBase {
536590
}
537591

538592
/**
539-
* Defauly keyboard properties object
593+
* Default keyboard properties object
540594
* @returns {KeyboardProperties} - A KeyboardProperties RPC
541595
*/
542596
_defaultKeyboardConfiguration () {

lib/js/src/manager/screen/choiceset/_PresentChoiceSetOperation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ class _PresentChoiceSetOperation extends _Task {
306306
} else if (onKeyboardInput.getEvent() === KeyboardEvent.ENTRY_ABORTED || onKeyboardInput.getEvent() === KeyboardEvent.ENTRY_CANCELLED) {
307307
// notify of abort / cancelation
308308
this._keyboardListener.onKeyboardDidAbortWithReason(onKeyboardInput.getEvent());
309+
} else if (onKeyboardInput.getEvent() === KeyboardEvent.INPUT_KEY_MASK_ENABLED || onKeyboardInput.getEvent() === KeyboardEvent.INPUT_KEY_MASK_DISABLED) {
310+
this._keyboardListener.onKeyboardInputMaskHasChanged(onKeyboardInput.getEvent());
309311
}
310312
};
311313

lib/js/src/manager/screen/choiceset/_PresentKeyboardOperation.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ class _PresentKeyboardOperation extends _Task {
249249
} else if (onKeyboardInput.getEvent() === KeyboardEvent.ENTRY_ABORTED || onKeyboardInput.getEvent() === KeyboardEvent.ENTRY_CANCELLED) {
250250
// notify of abort / cancelation
251251
this._keyboardListener.onKeyboardDidAbortWithReason(onKeyboardInput.getEvent());
252+
} else if (onKeyboardInput.getEvent() === KeyboardEvent.INPUT_KEY_MASK_ENABLED || onKeyboardInput.getEvent() === KeyboardEvent.INPUT_KEY_MASK_DISABLED) {
253+
this._keyboardListener.onKeyboardInputMaskHasChanged(onKeyboardInput.getEvent());
252254
}
253255
};
254256

lib/js/src/rpc/enums/ImageFieldName.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,26 @@ class ImageFieldName extends Enum {
196196
return ImageFieldName._MAP.subtleAlertIcon;
197197
}
198198

199+
/**
200+
* Get the enum value for menuCommandSecondaryImage.
201+
* @since SmartDeviceLink 7.1.0
202+
* The secondary image field for AddCommand
203+
* @returns {String} - The enum value.
204+
*/
205+
static get menuCommandSecondaryImage () {
206+
return ImageFieldName._MAP.menuCommandSecondaryImage;
207+
}
208+
209+
/**
210+
* Get the enum value for menuSubMenuSecondaryImage.
211+
* @since SmartDeviceLink 7.1.0
212+
* The secondary image field for AddSubMenu
213+
* @returns {String} - The enum value.
214+
*/
215+
static get menuSubMenuSecondaryImage () {
216+
return ImageFieldName._MAP.menuSubMenuSecondaryImage;
217+
}
218+
199219
/**
200220
* Get the value for the given enum key
201221
* @param {*} key - A key to find in the map of the subclass
@@ -240,6 +260,8 @@ ImageFieldName._MAP = Object.freeze({
240260
'alertIcon': 'alertIcon',
241261
'subMenuIcon': 'subMenuIcon',
242262
'subtleAlertIcon': 'subtleAlertIcon',
263+
'menuCommandSecondaryImage': 'menuCommandSecondaryImage',
264+
'menuSubMenuSecondaryImage': 'menuSubMenuSecondaryImage',
243265
});
244266

245267
export { ImageFieldName };

lib/js/src/rpc/enums/KeyboardEvent.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable camelcase */
22
/*
3-
* Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
3+
* Copyright (c) 2021, SmartDeviceLink Consortium, Inc.
44
* All rights reserved.
55
*
66
* Redistribution and use in source and binary forms, with or without
@@ -88,6 +88,24 @@ class KeyboardEvent extends Enum {
8888
return KeyboardEvent._MAP.ENTRY_ABORTED;
8989
}
9090

91+
/**
92+
* Get the enum value for INPUT_KEY_MASK_ENABLED.
93+
* @since SmartDeviceLink 7.1.0
94+
* @returns {String} - The enum value.
95+
*/
96+
static get INPUT_KEY_MASK_ENABLED () {
97+
return KeyboardEvent._MAP.INPUT_KEY_MASK_ENABLED;
98+
}
99+
100+
/**
101+
* Get the enum value for INPUT_KEY_MASK_DISABLED.
102+
* @since SmartDeviceLink 7.1.0
103+
* @returns {String} - The enum value.
104+
*/
105+
static get INPUT_KEY_MASK_DISABLED () {
106+
return KeyboardEvent._MAP.INPUT_KEY_MASK_DISABLED;
107+
}
108+
91109
/**
92110
* Get the value for the given enum key
93111
* @param {*} key - A key to find in the map of the subclass
@@ -121,6 +139,8 @@ KeyboardEvent._MAP = Object.freeze({
121139
'ENTRY_VOICE': 'ENTRY_VOICE',
122140
'ENTRY_CANCELLED': 'ENTRY_CANCELLED',
123141
'ENTRY_ABORTED': 'ENTRY_ABORTED',
142+
'INPUT_KEY_MASK_ENABLED': 'INPUT_KEY_MASK_ENABLED',
143+
'INPUT_KEY_MASK_DISABLED': 'INPUT_KEY_MASK_DISABLED',
124144
});
125145

126146
export { KeyboardEvent };
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/* eslint-disable camelcase */
2+
/*
3+
* Copyright (c) 2021, SmartDeviceLink Consortium, Inc.
4+
* All rights reserved.
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions are met:
8+
*
9+
* Redistributions of source code must retain the above copyright notice, this
10+
* list of conditions and the following disclaimer.
11+
*
12+
* Redistributions in binary form must reproduce the above copyright notice,
13+
* this list of conditions and the following
14+
* disclaimer in the documentation and/or other materials provided with the
15+
* distribution.
16+
*
17+
* Neither the name of the SmartDeviceLink Consortium Inc. nor the names of
18+
* its contributors may be used to endorse or promote products derived
19+
* from this software without specific prior written permission.
20+
*
21+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*/
33+
34+
import { Enum } from '../../util/Enum.js';
35+
36+
/**
37+
* Enumeration listing possible input character masking.
38+
* @typedef {Enum} KeyboardInputMask
39+
* @property {Object} _MAP
40+
*/
41+
class KeyboardInputMask extends Enum {
42+
/**
43+
* Constructor for KeyboardInputMask.
44+
* @class
45+
* @since SmartDeviceLink 7.1.0
46+
*/
47+
constructor () {
48+
super();
49+
}
50+
51+
/**
52+
* Get the enum value for ENABLE_INPUT_KEY_MASK.
53+
* @returns {String} - The enum value.
54+
*/
55+
static get ENABLE_INPUT_KEY_MASK () {
56+
return KeyboardInputMask._MAP.ENABLE_INPUT_KEY_MASK;
57+
}
58+
59+
/**
60+
* Get the enum value for DISABLE_INPUT_KEY_MASK.
61+
* @returns {String} - The enum value.
62+
*/
63+
static get DISABLE_INPUT_KEY_MASK () {
64+
return KeyboardInputMask._MAP.DISABLE_INPUT_KEY_MASK;
65+
}
66+
67+
/**
68+
* Get the enum value for USER_CHOICE_INPUT_KEY_MASK.
69+
* @returns {String} - The enum value.
70+
*/
71+
static get USER_CHOICE_INPUT_KEY_MASK () {
72+
return KeyboardInputMask._MAP.USER_CHOICE_INPUT_KEY_MASK;
73+
}
74+
75+
/**
76+
* Get the value for the given enum key
77+
* @param {*} key - A key to find in the map of the subclass
78+
* @returns {*} - Returns a value if found, or null if not found
79+
*/
80+
static valueForKey (key) {
81+
return KeyboardInputMask._valueForKey(key, KeyboardInputMask._MAP);
82+
}
83+
84+
/**
85+
* Get the key for the given enum value
86+
* @param {*} value - A primitive value to find the matching key for in the map of the subclass
87+
* @returns {*} - Returns a key if found, or null if not found
88+
*/
89+
static keyForValue (value) {
90+
return KeyboardInputMask._keyForValue(value, KeyboardInputMask._MAP);
91+
}
92+
93+
/**
94+
* Retrieve all enumerated values for this class
95+
* @returns {*} - Returns an array of values
96+
*/
97+
static values () {
98+
return Object.values(KeyboardInputMask._MAP);
99+
}
100+
}
101+
102+
KeyboardInputMask._MAP = Object.freeze({
103+
'ENABLE_INPUT_KEY_MASK': 'ENABLE_INPUT_KEY_MASK',
104+
'DISABLE_INPUT_KEY_MASK': 'DISABLE_INPUT_KEY_MASK',
105+
'USER_CHOICE_INPUT_KEY_MASK': 'USER_CHOICE_INPUT_KEY_MASK',
106+
});
107+
108+
export { KeyboardInputMask };

lib/js/src/rpc/enums/KeyboardLayout.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable camelcase */
22
/*
3-
* Copyright (c) 2020, SmartDeviceLink Consortium, Inc.
3+
* Copyright (c) 2021, SmartDeviceLink Consortium, Inc.
44
* All rights reserved.
55
*
66
* Redistribution and use in source and binary forms, with or without
@@ -72,6 +72,15 @@ class KeyboardLayout extends Enum {
7272
return KeyboardLayout._MAP.AZERTY;
7373
}
7474

75+
/**
76+
* Get the enum value for NUMERIC.
77+
* @since SmartDeviceLink 7.1.0
78+
* @returns {String} - The enum value.
79+
*/
80+
static get NUMERIC () {
81+
return KeyboardLayout._MAP.NUMERIC;
82+
}
83+
7584
/**
7685
* Get the value for the given enum key
7786
* @param {*} key - A key to find in the map of the subclass
@@ -103,6 +112,7 @@ KeyboardLayout._MAP = Object.freeze({
103112
'QWERTY': 'QWERTY',
104113
'QWERTZ': 'QWERTZ',
105114
'AZERTY': 'AZERTY',
115+
'NUMERIC': 'NUMERIC',
106116
});
107117

108118
export { KeyboardLayout };

0 commit comments

Comments
 (0)