diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java index 16ea857f55..81f9123616 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/choiceset/ChoiceSetManagerTests.java @@ -40,18 +40,23 @@ import com.smartdevicelink.managers.BaseSubManager; import com.smartdevicelink.managers.ISdl; import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.proxy.rpc.ImageField; import com.smartdevicelink.proxy.rpc.KeyboardCapabilities; import com.smartdevicelink.proxy.rpc.KeyboardLayoutCapability; import com.smartdevicelink.proxy.rpc.KeyboardProperties; import com.smartdevicelink.proxy.rpc.SdlMsgVersion; +import com.smartdevicelink.proxy.rpc.TextField; import com.smartdevicelink.proxy.rpc.WindowCapability; import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.ImageFieldName; import com.smartdevicelink.proxy.rpc.enums.KeyboardInputMask; import com.smartdevicelink.proxy.rpc.enums.KeyboardLayout; import com.smartdevicelink.proxy.rpc.enums.KeypressMode; import com.smartdevicelink.proxy.rpc.enums.Language; import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; import com.smartdevicelink.proxy.rpc.enums.TriggerSource; +import com.smartdevicelink.test.TestValues; import org.junit.After; import org.junit.Before; @@ -231,7 +236,8 @@ public void testAddUniqueNamesToCells() { ChoiceCell cell4 = new ChoiceCell("McDonalds", "4 mile away", null, null, null, null); ChoiceCell cell5 = new ChoiceCell("Starbucks", "5 mile away", null, null, null, null); ChoiceCell cell6 = new ChoiceCell("Meijer", "6 mile away", null, null, null, null); - LinkedHashSet cellList = new LinkedHashSet<>(); + List cellList = new ArrayList<>(); + cellList.add(cell1); cellList.add(cell2); cellList.add(cell3); @@ -468,4 +474,51 @@ public void testDismissingQueuedKeyboard() { verify(testKeyboardOp, times(0)).dismissKeyboard(); verify(testKeyboardOp2, times(1)).dismissKeyboard(); } + + @Test + public void testUniquenessForAvailableFields() { + WindowCapability windowCapability = new WindowCapability(); + TextField secondaryText = new TextField(); + secondaryText.setName(TextFieldName.secondaryText); + TextField tertiaryText = new TextField(); + tertiaryText.setName(TextFieldName.tertiaryText); + + List textFields = new ArrayList<>(); + textFields.add(secondaryText); + textFields.add(tertiaryText); + windowCapability.setTextFields(textFields); + + ImageField choiceImage = new ImageField(); + choiceImage.setName(ImageFieldName.choiceImage); + ImageField choiceSecondaryImage = new ImageField(); + choiceSecondaryImage.setName(ImageFieldName.choiceSecondaryImage); + List imageFieldList = new ArrayList<>(); + imageFieldList.add(choiceImage); + imageFieldList.add(choiceSecondaryImage); + windowCapability.setImageFields(imageFieldList); + + csm.defaultMainWindowCapability = windowCapability; + + ChoiceCell cell1 = new ChoiceCell("Item 1", "null", "tertiaryText", null, TestValues.GENERAL_ARTWORK, TestValues.GENERAL_ARTWORK); + ChoiceCell cell2 = new ChoiceCell("Item 1", "null2", "tertiaryText2", null, null, null); + List choiceCellList = new ArrayList<>(); + choiceCellList.add(cell1); + choiceCellList.add(cell2); + + List removedProperties = csm.removeUnusedProperties(choiceCellList); + assertNotNull(removedProperties.get(0).getSecondaryText()); + + textFields.remove(secondaryText); + textFields.remove(tertiaryText); + imageFieldList.remove(choiceImage); + imageFieldList.remove(choiceSecondaryImage); + + removedProperties = csm.removeUnusedProperties(choiceCellList); + csm.addUniqueNamesBasedOnStrippedCells(removedProperties, choiceCellList); + assertEquals(choiceCellList.get(1).getUniqueText(), "Item 1 (2)"); + + + } + + } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java index 2419023f60..e71d8295c7 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/menu/MenuManagerTests.java @@ -43,17 +43,22 @@ import com.smartdevicelink.protocol.enums.FunctionID; import com.smartdevicelink.proxy.RPCRequest; import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.rpc.ImageField; import com.smartdevicelink.proxy.rpc.OnCommand; import com.smartdevicelink.proxy.rpc.OnHMIStatus; import com.smartdevicelink.proxy.rpc.SdlMsgVersion; import com.smartdevicelink.proxy.rpc.SetGlobalProperties; +import com.smartdevicelink.proxy.rpc.TextField; import com.smartdevicelink.proxy.rpc.WindowCapability; import com.smartdevicelink.proxy.rpc.enums.FileType; import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.ImageFieldName; import com.smartdevicelink.proxy.rpc.enums.MenuLayout; import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; import com.smartdevicelink.proxy.rpc.enums.TriggerSource; import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; +import com.smartdevicelink.test.TestValues; import org.junit.After; import org.junit.Before; @@ -63,6 +68,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -598,6 +604,111 @@ public void testAllowingNonUniqueTitles() { assertEquals(menuManager.menuCells.get(3).getSubCells().get(3).getUniqueTitle(), "A"); } + @Test + public void testUniquenessForAvailableFields() { + WindowCapability windowCapability = new WindowCapability(); + TextField menuSubMenuSecondaryText = new TextField(); + menuSubMenuSecondaryText.setName(TextFieldName.menuSubMenuSecondaryText); + TextField menuSubMenuTertiaryText = new TextField(); + menuSubMenuTertiaryText.setName(TextFieldName.menuSubMenuTertiaryText); + TextField menuCommandSecondaryText = new TextField(); + menuCommandSecondaryText.setName(TextFieldName.menuCommandSecondaryText); + TextField menuCommandTertiaryText = new TextField(); + menuCommandTertiaryText.setName(TextFieldName.menuCommandTertiaryText); + List textFields = new ArrayList<>(); + textFields.add(menuSubMenuSecondaryText); + textFields.add(menuSubMenuTertiaryText); + textFields.add(menuCommandSecondaryText); + textFields.add(menuCommandTertiaryText); + windowCapability.setTextFields(textFields); + + ImageField cmdIcon = new ImageField(); + cmdIcon.setName(ImageFieldName.cmdIcon); + ImageField menuSubMenuSecondaryImage = new ImageField(); + menuSubMenuSecondaryImage.setName(ImageFieldName.menuSubMenuSecondaryImage); + ImageField menuCommandSecondaryImage = new ImageField(); + menuCommandSecondaryImage.setName(ImageFieldName.menuCommandSecondaryImage); + List imageFieldList = new ArrayList<>(); + imageFieldList.add(cmdIcon); + imageFieldList.add(menuSubMenuSecondaryImage); + imageFieldList.add(menuCommandSecondaryImage); + windowCapability.setImageFields(imageFieldList); + menuManager.defaultMainWindowCapability = windowCapability; + + assertNull(menuManager.removeUnusedProperties(null)); + + MenuCell cell1 = new MenuCell("Text1", "SecondaryText", "TText", TestValues.GENERAL_ARTWORK, TestValues.GENERAL_ARTWORK, null, new MenuSelectionListener() { + @Override + public void onTriggered(TriggerSource trigger) { + + } + }); + + MenuCell cell2 = new MenuCell("Text1", "SecondaryText2", "TText2", null, null, null, new MenuSelectionListener() { + @Override + public void onTriggered(TriggerSource trigger) { + + } + }); + + MenuCell subCell1 = new MenuCell("SubCell1", "Secondary Text", "TText", TestValues.GENERAL_ARTWORK, TestValues.GENERAL_ARTWORK, null, new MenuSelectionListener() { + @Override + public void onTriggered(TriggerSource trigger) { + } + }); + + MenuCell subCell2 = new MenuCell("SubCell1", "Secondary Text2", "TText2", null, null, null, new MenuSelectionListener() { + @Override + public void onTriggered(TriggerSource trigger) { + } + }); + + List subCellList = new ArrayList<>(); + subCellList.add(subCell1); + subCellList.add(subCell2); + + + MenuCell cell3 = new MenuCell("Test Cell 3 (sub menu)", "SecondaryText", "TText", MenuLayout.LIST, TestValues.GENERAL_ARTWORK, TestValues.GENERAL_ARTWORK, subCellList); + MenuCell cell4 = new MenuCell("Test Cell 3 (sub menu)", null, null, MenuLayout.LIST, null, null, subCellList); + + List menuCellList = new ArrayList<>(); + menuCellList.add(cell1); + menuCellList.add(cell2); + menuCellList.add(cell3); + menuCellList.add(cell4); + + List removedProperties = menuManager.removeUnusedProperties(menuCellList); + assertNotNull(removedProperties.get(0).getSecondaryText()); + menuManager.addUniqueNamesBasedOnStrippedCells(removedProperties, menuCellList); + assertEquals(menuCellList.get(1).getUniqueTitle(), "Text1"); + + // Remove menuCommandSecondaryText as a supported TextField + textFields.remove(menuCommandSecondaryText); + textFields.remove(menuCommandTertiaryText); + imageFieldList.remove(cmdIcon); + imageFieldList.remove(menuCommandSecondaryImage); + imageFieldList.remove(menuSubMenuSecondaryImage); + textFields.remove(menuSubMenuSecondaryText); + textFields.remove(menuSubMenuTertiaryText); + textFields.remove(menuSubMenuSecondaryImage); + + // Test removeUnusedProperties + removedProperties = menuManager.removeUnusedProperties(menuCellList); + assertNull(removedProperties.get(0).getSecondaryText()); + assertNull(removedProperties.get(0).getTertiaryText()); + + menuManager.addUniqueNamesBasedOnStrippedCells(removedProperties, menuCellList); + assertEquals(menuCellList.get(1).getUniqueTitle(), "Text1 (2)"); + + // SubCell test + assertEquals(menuCellList.get(3).getUniqueTitle(), "Test Cell 3 (sub menu) (2)"); + assertEquals(menuCellList.get(2).getSubCells().get(1).getUniqueTitle(), "SubCell1 (2)"); + + + } + + + // HELPERS // Emulate what happens when Core sends OnHMIStatus notification @@ -849,4 +960,5 @@ private List createDynamicMenu6_forUniqueNamesTest() { return Arrays.asList(A, B, C, D); } + } diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java index 746d498659..8939097185 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/choiceset/BaseChoiceSetManager.java @@ -42,6 +42,7 @@ import com.smartdevicelink.managers.BaseSubManager; import com.smartdevicelink.managers.CompletionListener; import com.smartdevicelink.managers.ISdl; +import com.smartdevicelink.managers.ManagerUtility; import com.smartdevicelink.managers.file.FileManager; import com.smartdevicelink.managers.lifecycle.OnSystemCapabilityListener; import com.smartdevicelink.managers.lifecycle.SystemCapabilityManager; @@ -54,6 +55,7 @@ import com.smartdevicelink.proxy.rpc.OnHMIStatus; import com.smartdevicelink.proxy.rpc.WindowCapability; import com.smartdevicelink.proxy.rpc.enums.HMILevel; +import com.smartdevicelink.proxy.rpc.enums.ImageFieldName; import com.smartdevicelink.proxy.rpc.enums.InteractionMode; import com.smartdevicelink.proxy.rpc.enums.KeyboardLayout; import com.smartdevicelink.proxy.rpc.enums.KeypressMode; @@ -61,11 +63,13 @@ import com.smartdevicelink.proxy.rpc.enums.PredefinedWindows; import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; import com.smartdevicelink.proxy.rpc.enums.SystemContext; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; import com.smartdevicelink.proxy.rpc.enums.TriggerSource; import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; import com.smartdevicelink.util.DebugTool; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -540,7 +544,7 @@ HashSet choicesToBeRemovedFromPendingWithArray(List choi * E.g. Choices param contains 2 cells with text/title "Address" will be handled by updating the uniqueText/uniqueTitle of the second cell to "Address (2)". * @param choices The list of choiceCells to be uploaded. */ - void addUniqueNamesToCells(LinkedHashSet choices) { + void addUniqueNamesToCells(List choices) { HashMap dictCounter = new HashMap<>(); for (ChoiceCell cell : choices) { @@ -556,16 +560,80 @@ void addUniqueNamesToCells(LinkedHashSet choices) { } } + void addUniqueNamesBasedOnStrippedCells(List strippedCells, List unstrippedCells) { + if (strippedCells == null || unstrippedCells == null || strippedCells.size() != unstrippedCells.size()) { + return; + } + // Tracks how many of each cell primary text there are so that we can append numbers to make each unique as necessary + HashMap dictCounter = new HashMap<>(); + for (int i = 0; i < strippedCells.size(); i++) { + ChoiceCell cell = strippedCells.get(i); + Integer counter = dictCounter.get(cell); + if (counter != null) { + counter++; + dictCounter.put(cell, counter); + } else { + dictCounter.put(cell, 1); + } + + counter = dictCounter.get(cell); + + if (counter > 1) { + unstrippedCells.get(i).setUniqueText(unstrippedCells.get(i).getText() + " (" + counter + ")"); + } + } + } + + private List cloneChoiceCellList(List originalList) { + if (originalList == null) { + return null; + } + + List clone = new ArrayList<>(); + for (ChoiceCell choiceCell : originalList) { + clone.add(choiceCell.clone()); + } + return clone; + } + private LinkedHashSet getChoicesToBeUploadedWithArray(List choices) { - LinkedHashSet choiceSet = new LinkedHashSet<>(choices); - // If we're running on a connection < RPC 7.1, we need to de-duplicate cells because presenting them will fail if we have the same cell primary text. + // Clone choices + List choicesClone = cloneChoiceCellList(choices); if (choices != null && internalInterface.getSdlMsgVersion() != null && (internalInterface.getSdlMsgVersion().getMajorVersion() < 7 || (internalInterface.getSdlMsgVersion().getMajorVersion() == 7 && internalInterface.getSdlMsgVersion().getMinorVersion() == 0))) { - addUniqueNamesToCells(choiceSet); + // If we're on < RPC 7.1, all primary texts need to be unique, so we don't need to check removed properties and duplicate cells + addUniqueNamesToCells(choicesClone); + } else { + List strippedCellsClone = removeUnusedProperties(choicesClone); + addUniqueNamesBasedOnStrippedCells(strippedCellsClone, choicesClone); } - choiceSet.removeAll(preloadedChoices); - return choiceSet; + LinkedHashSet choiceCloneLinkedHash = new LinkedHashSet<>(choicesClone); + choiceCloneLinkedHash.removeAll(preloadedChoices); + return choiceCloneLinkedHash; + } + + List removeUnusedProperties(List choiceCells) { + List strippedCellsClone = cloneChoiceCellList(choiceCells); + //Clone Cells + for (ChoiceCell cell : strippedCellsClone) { + // Strip away fields that cannot be used to determine uniqueness visually including fields not supported by the HMI + cell.setVoiceCommands(null); + + if (!hasImageFieldOfName(ImageFieldName.choiceImage)) { + cell.setArtwork(null); + } + if (!hasTextFieldOfName(TextFieldName.secondaryText)) { + cell.setSecondaryText(null); + } + if (!hasTextFieldOfName(TextFieldName.tertiaryText)) { + cell.setTertiaryText(null); + } + if (!hasImageFieldOfName(ImageFieldName.choiceSecondaryImage)) { + cell.setSecondaryArtwork(null); + } + } + return strippedCellsClone; } void updateIdsOnChoices(LinkedHashSet choices) { @@ -672,6 +740,14 @@ public void onNotified(RPCNotification notification) { // ADDITIONAL HELPERS + private boolean hasImageFieldOfName(ImageFieldName imageFieldName) { + return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasImageFieldOfName(defaultMainWindowCapability, imageFieldName); + } + + private boolean hasTextFieldOfName(TextFieldName textFieldName) { + return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasTextFieldOfName(defaultMainWindowCapability, textFieldName); + } + boolean setUpChoiceSet(ChoiceSet choiceSet) { List choices = choiceSet.getChoices(); @@ -695,9 +771,8 @@ boolean setUpChoiceSet(ChoiceSet choiceSet) { int choiceCellWithVoiceCommandCount = 0; for (ChoiceCell cell : choices) { - uniqueChoiceCells.add(cell); - + // Not using cloned cell here because we set the clone's VoiceCommands to null for visual check only if (cell.getVoiceCommands() != null) { uniqueVoiceCommands.addAll(cell.getVoiceCommands()); choiceCellWithVoiceCommandCount += 1; diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java index 3c409059ad..149d3fa2b8 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/menu/BaseMenuManager.java @@ -176,11 +176,9 @@ public void setMenuCells(@NonNull List cells) { // Create a deep copy of the list so future changes by developers don't affect the algorithm logic List clonedCells = cloneMenuCellsList(cells); - // If we're running on a connection < RPC 7.1, we need to de-duplicate cells because presenting them will fail if we have the same cell primary text. - if (clonedCells != null && internalInterface.getSdlMsgVersion() != null - && (internalInterface.getSdlMsgVersion().getMajorVersion() < 7 - || (internalInterface.getSdlMsgVersion().getMajorVersion() == 7 && internalInterface.getSdlMsgVersion().getMinorVersion() == 0))) { - addUniqueNamesToCells(clonedCells); + // Check for cell lists with completely duplicate information, or any duplicate voiceCommands and return if it fails (logs are in the called method). + if (clonedCells != null && !menuCellsAreUnique(clonedCells, new ArrayList())) { + return; } if (currentHMILevel == null || currentHMILevel.equals(HMILevel.HMI_NONE) || currentSystemContext.equals(SystemContext.SYSCTXT_MENU)) { @@ -194,6 +192,23 @@ public void setMenuCells(@NonNull List cells) { } waitingOnHMIUpdate = false; + // If we're running on a connection < RPC 7.1, we need to de-duplicate cells because presenting them will fail if we have the same cell primary text. + if (clonedCells != null && internalInterface.getSdlMsgVersion() != null + && (internalInterface.getSdlMsgVersion().getMajorVersion() < 7 + || (internalInterface.getSdlMsgVersion().getMajorVersion() == 7 && internalInterface.getSdlMsgVersion().getMinorVersion() == 0))) { + addUniqueNamesToCellsWithDuplicatePrimaryText(clonedCells); + } else { + // On > RPC 7.1, at this point all cells are unique when considering all properties, + // but we also need to check if any cells will _appear_ as duplicates when displayed on the screen. + // To check that, we'll remove properties from the set cells based on the system capabilities + // (we probably don't need to consider them changing between now and when they're actually sent to the HU unless the menu layout changes) + // and check for uniqueness again. Then we'll add unique identifiers to primary text if there are duplicates. + // Then we transfer the primary text identifiers back to the main cells and add those to an operation to be sent. + List strippedCellsClone = removeUnusedProperties(clonedCells); + addUniqueNamesBasedOnStrippedCells(strippedCellsClone, clonedCells); + + } + // Update our Lists // set old list if (menuCells != null) { @@ -205,11 +220,6 @@ public void setMenuCells(@NonNull List cells) { menuCells.addAll(clonedCells); } - // Check for cell lists with completely duplicate information, or any duplicate voiceCommands and return if it fails (logs are in the called method). - if (!menuCellsAreUnique(menuCells, new ArrayList())) { - return; - } - // Upload the Artworks List artworksToBeUploaded = findAllArtworksToBeUploadedFromCells(menuCells); if (artworksToBeUploaded.size() > 0 && fileManager.get() != null) { @@ -1441,7 +1451,7 @@ private List cloneMenuCellsList(List originalList) { return clone; } - private void addUniqueNamesToCells(List cells) { + private void addUniqueNamesToCellsWithDuplicatePrimaryText(List cells) { HashMap dictCounter = new HashMap<>(); for (MenuCell cell : cells) { @@ -1456,11 +1466,80 @@ private void addUniqueNamesToCells(List cells) { } if (cell.getSubCells() != null && cell.getSubCells().size() > 0) { - addUniqueNamesToCells(cell.getSubCells()); + addUniqueNamesToCellsWithDuplicatePrimaryText(cell.getSubCells()); } } } + void addUniqueNamesBasedOnStrippedCells(List strippedCells, List unstrippedCells) { + if (strippedCells == null || unstrippedCells == null || strippedCells.size() != unstrippedCells.size()) { + return; + } + // Tracks how many of each cell primary text there are so that we can append numbers to make each unique as necessary + HashMap dictCounter = new HashMap<>(); + for (int i = 0; i < strippedCells.size(); i++) { + MenuCell cell = strippedCells.get(i); + Integer counter = dictCounter.get(cell); + if (counter != null) { + counter = counter + 1; + dictCounter.put(cell, counter); + } else { + dictCounter.put(cell, 1); + } + counter = dictCounter.get(cell); + if (counter > 1) { + unstrippedCells.get(i).setUniqueTitle(unstrippedCells.get(i).getTitle() + " (" + counter + ")"); + } + + if (cell.getSubCells() != null && cell.getSubCells().size() > 0) { + addUniqueNamesBasedOnStrippedCells(cell.getSubCells(), unstrippedCells.get(i).getSubCells()); + } + + } + + + } + + List removeUnusedProperties(List menuCells) { + if (menuCells == null) { + return null; + } + List removePropertiesClone = cloneMenuCellsList(menuCells); + for (MenuCell cell : removePropertiesClone) { + // Strip away fields that cannot be used to determine uniqueness visually including fields not supported by the HMI + cell.setVoiceCommands(null); + + // Don't check ImageFieldName.subMenuIcon because it was added in 7.0 when the feature was added in 5.0. + // Just assume that if cmdIcon is not available, the submenu icon is not either. + if (!hasImageFieldOfName(ImageFieldName.cmdIcon)) { + cell.setIcon(null); + } + // Check for subMenu fields supported + if (cell.getSubCells() != null) { + if (!hasTextFieldOfName(TextFieldName.menuSubMenuSecondaryText)) { + cell.setSecondaryText(null); + } + if (!hasTextFieldOfName(TextFieldName.menuSubMenuTertiaryText)) { + cell.setTertiaryText(null); + } + if (!hasImageFieldOfName(ImageFieldName.menuSubMenuSecondaryImage)) { + cell.setSecondaryArtwork(null); + } + cell.setSubCells(removeUnusedProperties(cell.getSubCells())); + } else { + if (!hasTextFieldOfName(TextFieldName.menuCommandSecondaryText)) { + cell.setSecondaryText(null); + } + if (!hasTextFieldOfName(TextFieldName.menuCommandTertiaryText)) { + cell.setTertiaryText(null); + } + if (!hasImageFieldOfName(ImageFieldName.menuCommandSecondaryImage)) { + cell.setSecondaryArtwork(null); + } + } + } + return removePropertiesClone; + } /** * Check for cell lists with completely duplicate information, or any duplicate voiceCommands