diff options
author | Bilal Alsharifi <599206+bilal-alsharifi@users.noreply.github.com> | 2020-09-01 11:47:08 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-01 11:47:08 -0400 |
commit | 30e11caebce4986594f3267984e2d6d8ead09bce (patch) | |
tree | 83dc112689f4eb171c7484d0002d035a66455f37 | |
parent | 324778e8a40568959e41089d2fe2bc3dd8f709b7 (diff) | |
parent | 95da6a22ed1f539f775f2e77d350f116c7d28b94 (diff) | |
download | sdl_android-30e11caebce4986594f3267984e2d6d8ead09bce.tar.gz |
Merge pull request #1457 from smartdevicelink/TextAndGraphicsManager-Refactor-Queues
Refactor Text & Graphic Manager to use queues
9 files changed, 1948 insertions, 1186 deletions
diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java index f1e68e9b3..11d8472c2 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/ScreenManagerTests.java @@ -21,7 +21,6 @@ import java.util.Arrays; import java.util.List; import static junit.framework.TestCase.assertEquals; -import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNull; import static junit.framework.TestCase.assertTrue; import static org.mockito.Mockito.mock; @@ -99,14 +98,11 @@ public class ScreenManagerTests { screenManager.setPrimaryGraphic(testArtwork); assertEquals(screenManager.getPrimaryGraphic(), testArtwork); } - @Test public void testSetPrimaryGraphicWithBlankImage() { screenManager.setPrimaryGraphic(null); - assertNotNull(screenManager.getPrimaryGraphic()); - assertEquals(screenManager.getPrimaryGraphic().getName(), "blankArtwork"); + assertNull(screenManager.getPrimaryGraphic()); } - @Test public void testSetSecondaryGraphic() { screenManager.setSecondaryGraphic(testArtwork); @@ -116,8 +112,7 @@ public class ScreenManagerTests { @Test public void testSetSecondaryGraphicWithBlankImage() { screenManager.setSecondaryGraphic(null); - assertNotNull(screenManager.getSecondaryGraphic()); - assertEquals(screenManager.getSecondaryGraphic().getName(), "blankArtwork"); + assertNull(screenManager.getSecondaryGraphic()); } @Test diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java index 439b7ebe9..2bb0164fb 100644 --- a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicManagerTests.java @@ -4,28 +4,34 @@ import android.content.Context; import android.net.Uri; import androidx.test.ext.junit.runners.AndroidJUnit4; +import com.livio.taskmaster.Task; +import com.livio.taskmaster.Taskmaster; import com.smartdevicelink.managers.BaseSubManager; import com.smartdevicelink.managers.ManagerUtility; import com.smartdevicelink.managers.file.FileManager; import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.managers.lifecycle.OnSystemCapabilityListener; +import com.smartdevicelink.protocol.enums.FunctionID; import com.smartdevicelink.proxy.interfaces.ISdl; -import com.smartdevicelink.proxy.rpc.MetadataTags; -import com.smartdevicelink.proxy.rpc.Show; +import com.smartdevicelink.proxy.rpc.DisplayCapability; +import com.smartdevicelink.proxy.rpc.OnHMIStatus; 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.MetadataType; +import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; import com.smartdevicelink.proxy.rpc.enums.TextAlignment; import com.smartdevicelink.proxy.rpc.enums.TextFieldName; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import org.json.JSONException; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; +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; import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; @@ -33,7 +39,12 @@ import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNull; +import static junit.framework.TestCase.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; /** * This is a unit test class for the SmartDeviceLink library manager class : @@ -49,6 +60,7 @@ public class TextAndGraphicManagerTests { @Before public void setUp() throws Exception{ Context mTestContext = getInstrumentation().getContext(); + // mock things ISdl internalInterface = mock(ISdl.class); FileManager fileManager = mock(FileManager.class); @@ -60,6 +72,38 @@ public class TextAndGraphicManagerTests { testArtwork.setUri(uri); testArtwork.setType(FileType.GRAPHIC_PNG); + Taskmaster taskmaster = new Taskmaster.Builder().build(); + taskmaster.start(); + when(internalInterface.getTaskmaster()).thenReturn(taskmaster); + + Answer<Void> onHMIStatusAnswer = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + OnRPCNotificationListener onHMIStatusListener = (OnRPCNotificationListener) args[1]; + OnHMIStatus onHMIStatusFakeNotification = new OnHMIStatus(); + onHMIStatusFakeNotification.setHmiLevel(HMILevel.HMI_FULL); + onHMIStatusListener.onNotified(onHMIStatusFakeNotification); + return null; + } + }; + doAnswer(onHMIStatusAnswer).when(internalInterface).addOnRPCNotificationListener(eq(FunctionID.ON_HMI_STATUS), any(OnRPCNotificationListener.class)); + + Answer<Void> onSystemCapabilityAnswer = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + OnSystemCapabilityListener onSystemCapabilityListener = (OnSystemCapabilityListener) args[1]; + WindowCapability windowCapability = getWindowCapability(4); + DisplayCapability displayCapability = new DisplayCapability(); + displayCapability.setWindowCapabilities(Collections.singletonList(windowCapability)); + List<DisplayCapability> capabilities = Collections.singletonList(displayCapability); + onSystemCapabilityListener.onCapabilityRetrieved(capabilities); + return null; + } + }; + doAnswer(onSystemCapabilityAnswer).when(internalInterface).addOnSystemCapabilityListener(eq(SystemCapabilityType.DISPLAYS), any(OnSystemCapabilityListener.class)); + textAndGraphicManager = new TextAndGraphicManager(internalInterface, fileManager, softButtonManager); } @@ -122,13 +166,9 @@ public class TextAndGraphicManagerTests { assertNull(textAndGraphicManager.getTextField2Type()); assertNull(textAndGraphicManager.getTextField3Type()); assertNull(textAndGraphicManager.getTextField4Type()); - assertNotNull(textAndGraphicManager.currentScreenData); - assertNull(textAndGraphicManager.inProgressUpdate); - assertNull(textAndGraphicManager.queuedImageUpdate); - assertFalse(textAndGraphicManager.hasQueuedUpdate); - assertNull(textAndGraphicManager.defaultMainWindowCapability); - assertEquals(textAndGraphicManager.currentHMILevel, HMILevel.HMI_NONE); + assertNotNull(textAndGraphicManager.defaultMainWindowCapability); + assertEquals(textAndGraphicManager.currentHMILevel, HMILevel.HMI_FULL); assertFalse(textAndGraphicManager.isDirty); assertEquals(textAndGraphicManager.getState(), BaseSubManager.SETTING_UP); assertNotNull(textAndGraphicManager.getBlankArtwork()); @@ -153,494 +193,6 @@ public class TextAndGraphicManagerTests { } @Test - public void testAssemble1Line(){ - - Show inputShow = new Show(); - - // Force it to return display with support for only 1 line of text - textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(1); - - textAndGraphicManager.setTextField1("It is"); - textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY); - - Show assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - - // test tags (just 1) - MetadataTags tags = assembledShow.getMetadataTags(); - List<MetadataType> tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - assertEquals(tags.getMainField1(), tagsList); - - textAndGraphicManager.setTextField2("Wednesday"); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); - - textAndGraphicManager.setTextField3("My"); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My"); - - textAndGraphicManager.setTextField4("Dudes"); - textAndGraphicManager.setTextField4Type(MetadataType.CURRENT_TEMPERATURE); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My - Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList.add(MetadataType.CURRENT_TEMPERATURE); - assertEquals(tags.getMainField1(), tagsList); - - // For some obscurity, lets try setting just fields 2 and 4 for a 1 line display - textAndGraphicManager.setTextField1(null); - textAndGraphicManager.setTextField3(null); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "Wednesday - Dudes"); - } - - @Test - public void testAssemble2Lines() { - - Show inputShow = new Show(); - - // Force it to return display with support for only 2 lines of text - textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(2); - - textAndGraphicManager.setTextField1("It is"); - textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY); - - Show assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - - // test tags - MetadataTags tags = assembledShow.getMetadataTags(); - List<MetadataType> tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - assertEquals(tags.getMainField1(), tagsList); - - textAndGraphicManager.setTextField2("Wednesday"); - textAndGraphicManager.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - List<MetadataType> tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - textAndGraphicManager.setTextField3("My"); - textAndGraphicManager.setTextField3Type(MetadataType.MEDIA_ALBUM); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); - assertEquals(assembledShow.getMainField2(), "My"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.CURRENT_TEMPERATURE); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.MEDIA_ALBUM); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - textAndGraphicManager.setTextField4("Dudes"); - textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); - assertEquals(assembledShow.getMainField2(), "My - Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.CURRENT_TEMPERATURE); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.MEDIA_STATION); - tagsList2.add(MetadataType.MEDIA_ALBUM); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - // For some obscurity, lets try setting just fields 2 and 4 for a 2 line display - textAndGraphicManager.setTextField1(null); - textAndGraphicManager.setTextField3(null); - textAndGraphicManager.setTextField1Type(null); - textAndGraphicManager.setTextField3Type(null); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "Wednesday"); - assertEquals(assembledShow.getMainField2(), "Dudes"); - - // And 3 fields without setting 1 - textAndGraphicManager.setTextField3("My"); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "Wednesday"); - assertEquals(assembledShow.getMainField2(), "My - Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.CURRENT_TEMPERATURE); - tagsList2.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - } - - @Test - public void testAssemble3Lines() { - - Show inputShow = new Show(); - - // Force it to return display with support for only 3 lines of text - textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(3); - - textAndGraphicManager.setTextField1("It is"); - textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY); - - Show assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), ""); - assertEquals(assembledShow.getMainField3(), ""); - - // test tags - MetadataTags tags = assembledShow.getMetadataTags(); - List<MetadataType> tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - assertEquals(tags.getMainField1(), tagsList); - - textAndGraphicManager.setTextField2("Wednesday"); - textAndGraphicManager.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), ""); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - List<MetadataType> tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - textAndGraphicManager.setTextField3("My"); - textAndGraphicManager.setTextField3Type(MetadataType.MEDIA_ALBUM); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - List<MetadataType> tagsList3 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - - textAndGraphicManager.setTextField4("Dudes"); - textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My - Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList3 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - tagsList3.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - - // Someone might not want to set the fields in order? We should handle that - textAndGraphicManager.setTextField1(null); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - try { - System.out.println(assembledShow.serializeJSON().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My - Dudes"); - } - - @Test - public void testAssemble4Lines() { - - Show inputShow = new Show(); - - textAndGraphicManager.defaultMainWindowCapability = getWindowCapability(4); - TextField tx1 = new TextField(); - TextField tx2 = new TextField(); - TextField tx3 = new TextField(); - TextField tx4 = new TextField(); - TextField tx5 = new TextField(); - TextField tx6 = new TextField(); - - tx1.setName(TextFieldName.mainField1); - tx2.setName(TextFieldName.mainField2); - tx3.setName(TextFieldName.mainField3); - tx4.setName(TextFieldName.mainField4); - tx5.setName(TextFieldName.mediaTrack); - tx6.setName(TextFieldName.templateTitle); - - List<TextField> textFieldNames = Arrays.asList(tx1,tx2,tx3,tx4,tx5,tx6); - textAndGraphicManager.defaultMainWindowCapability.setTextFields(textFieldNames); - - textAndGraphicManager.setMediaTrackTextField("HI"); - textAndGraphicManager.setTitle("bye"); - - // Force it to return display with support for only 4 lines of text - - textAndGraphicManager.setTextField1("It is"); - textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY); - - Show assembledShow = textAndGraphicManager.assembleShowText(inputShow); - - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), ""); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), ""); - assertEquals(assembledShow.getMediaTrack(), "HI"); - assertEquals(assembledShow.getTemplateTitle(), "bye"); - - // test tags - MetadataTags tags = assembledShow.getMetadataTags(); - List<MetadataType> tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - assertEquals(tags.getMainField1(), tagsList); - - textAndGraphicManager.setTextField2("Wednesday"); - textAndGraphicManager.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), ""); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - List<MetadataType> tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - textAndGraphicManager.setTextField3("My"); - textAndGraphicManager.setTextField3Type(MetadataType.MEDIA_ALBUM); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My"); - assertEquals(assembledShow.getMainField4(), ""); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - List<MetadataType> tagsList3 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - - textAndGraphicManager.setTextField4("Dudes"); - textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My"); - assertEquals(assembledShow.getMainField4(), "Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList3 = new ArrayList<>(); - List<MetadataType> tagsList4 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - tagsList4.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - assertEquals(tags.getMainField4(), tagsList4); - - // try just setting line 1 and 4 - textAndGraphicManager.setTextField2(null); - textAndGraphicManager.setTextField3(null); - textAndGraphicManager.setTextField2Type(null); - textAndGraphicManager.setTextField3Type(null); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), ""); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), "Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList4 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList4.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField4(), tagsList4); - } - - /** - * Testing if WindowCapability is null, TextFields should still update. - */ - @Test - public void testAssemble4LinesNullWindowCapability() { - - Show inputShow = new Show(); - - textAndGraphicManager.setMediaTrackTextField("HI"); - textAndGraphicManager.setTitle("bye"); - - textAndGraphicManager.setTextField1("It is"); - textAndGraphicManager.setTextField1Type(MetadataType.HUMIDITY); - - Show assembledShow = textAndGraphicManager.assembleShowText(inputShow); - - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), ""); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), ""); - assertEquals(assembledShow.getMediaTrack(), "HI"); - assertEquals(assembledShow.getTemplateTitle(), "bye"); - - // test tags - MetadataTags tags = assembledShow.getMetadataTags(); - List<MetadataType> tagsList = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - assertEquals(tags.getMainField1(), tagsList); - - textAndGraphicManager.setTextField2("Wednesday"); - textAndGraphicManager.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), ""); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - List<MetadataType> tagsList2 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - - textAndGraphicManager.setTextField3("My"); - textAndGraphicManager.setTextField3Type(MetadataType.MEDIA_ALBUM); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My"); - assertEquals(assembledShow.getMainField4(), ""); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - List<MetadataType> tagsList3 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - - textAndGraphicManager.setTextField4("Dudes"); - textAndGraphicManager.setTextField4Type(MetadataType.MEDIA_STATION); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), "Wednesday"); - assertEquals(assembledShow.getMainField3(), "My"); - assertEquals(assembledShow.getMainField4(), "Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList2 = new ArrayList<>(); - tagsList3 = new ArrayList<>(); - List<MetadataType> tagsList4 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList2.add(MetadataType.CURRENT_TEMPERATURE); - tagsList3.add(MetadataType.MEDIA_ALBUM); - tagsList4.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField2(), tagsList2); - assertEquals(tags.getMainField3(), tagsList3); - assertEquals(tags.getMainField4(), tagsList4); - - // try just setting line 1 and 4 - textAndGraphicManager.setTextField2(null); - textAndGraphicManager.setTextField3(null); - textAndGraphicManager.setTextField2Type(null); - textAndGraphicManager.setTextField3Type(null); - - assembledShow = textAndGraphicManager.assembleShowText(inputShow); - assertEquals(assembledShow.getMainField1(), "It is"); - assertEquals(assembledShow.getMainField2(), ""); - assertEquals(assembledShow.getMainField3(), ""); - assertEquals(assembledShow.getMainField4(), "Dudes"); - - // test tags - tags = assembledShow.getMetadataTags(); - tagsList = new ArrayList<>(); - tagsList4 = new ArrayList<>(); - tagsList.add(MetadataType.HUMIDITY); - tagsList4.add(MetadataType.MEDIA_STATION); - assertEquals(tags.getMainField1(), tagsList); - assertEquals(tags.getMainField4(), tagsList4); - } - - @Test public void testMediaTrackTextField() { String songTitle = "Wild For The Night"; @@ -663,22 +215,6 @@ public class TextAndGraphicManagerTests { assertEquals(textAndGraphicManager.getTextAlignment(), TextAlignment.LEFT_ALIGNED); } - @Test - public void testExtractTextFromShow(){ - - Show mainShow = new Show(); - mainShow.setMainField1("test"); - mainShow.setMainField3("Sauce"); - mainShow.setMainField4(""); - - Show newShow = textAndGraphicManager.extractTextFromShow(mainShow); - - assertEquals(newShow.getMainField1(), "test"); - assertEquals(newShow.getMainField3(), "Sauce"); - assertEquals(newShow.getMainField4(), ""); - assertNull(newShow.getMainField2()); - } - // TEST IMAGES @Test @@ -714,11 +250,40 @@ public class TextAndGraphicManagerTests { assertNull(textAndGraphicManager.getTitle()); assertNotNull(textAndGraphicManager.getBlankArtwork()); assertNull(textAndGraphicManager.currentScreenData); - assertNull(textAndGraphicManager.inProgressUpdate); - assertNull(textAndGraphicManager.queuedImageUpdate); - assertFalse(textAndGraphicManager.hasQueuedUpdate); assertNull(textAndGraphicManager.defaultMainWindowCapability); assertFalse(textAndGraphicManager.isDirty); assertEquals(textAndGraphicManager.getState(), BaseSubManager.SHUTDOWN); } + + @Test + public void testOperationManagement() { + textAndGraphicManager.isDirty = true; + textAndGraphicManager.updateOperation = null; + textAndGraphicManager.update(null); + assertEquals(textAndGraphicManager.transactionQueue.getTasksAsList().size(), 1); + + textAndGraphicManager.transactionQueue.clear(); + textAndGraphicManager.updateOperation = null; + + assertEquals(textAndGraphicManager.transactionQueue.getTasksAsList().size(), 0); + + textAndGraphicManager.isDirty = true; + textAndGraphicManager.update(null); + + assertEquals(textAndGraphicManager.transactionQueue.getTasksAsList().size(), 1); + + assertTrue(textAndGraphicManager.transactionQueue.getTasksAsList().get(0).getState() == Task.READY); + } + + @Test + public void testHasData() { + assertFalse(textAndGraphicManager.hasData()); + + textAndGraphicManager.setTextField1("HI"); + assertTrue(textAndGraphicManager.hasData()); + + textAndGraphicManager.setTextField1(null); + textAndGraphicManager.setPrimaryGraphic(testArtwork); + assertTrue(textAndGraphicManager.hasData()); + } } diff --git a/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java new file mode 100644 index 000000000..cdfab186c --- /dev/null +++ b/android/sdl_android/src/androidTest/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperationTest.java @@ -0,0 +1,902 @@ +package com.smartdevicelink.managers.screen; + +import android.content.Context; +import android.net.Uri; + +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.smartdevicelink.R; +import com.smartdevicelink.managers.CompletionListener; +import com.smartdevicelink.managers.ManagerUtility; +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.managers.file.MultipleFileCompletionListener; +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.managers.file.filetypes.SdlFile; +import com.smartdevicelink.proxy.RPCRequest; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.rpc.ImageField; +import com.smartdevicelink.proxy.rpc.MetadataTags; +import com.smartdevicelink.proxy.rpc.SdlMsgVersion; +import com.smartdevicelink.proxy.rpc.Show; +import com.smartdevicelink.proxy.rpc.ShowResponse; +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.ImageFieldName; +import com.smartdevicelink.proxy.rpc.enums.MetadataType; +import com.smartdevicelink.proxy.rpc.enums.TextAlignment; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; + +import org.json.JSONException; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation; +import static junit.framework.TestCase.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@RunWith(AndroidJUnit4.class) +public class TextAndGraphicUpdateOperationTest { + + private TextAndGraphicUpdateOperation textAndGraphicUpdateOperation; + private String textField1, textField2, textField3, textField4, mediaTrackField, title; + private MetadataType textField1Type, textField2Type, textField3Type, textField4Type; + private SdlArtwork testArtwork1, testArtwork2, testArtwork3, testArtwork4; + private TextAlignment textAlignment; + private WindowCapability defaultMainWindowCapability; + private Show currentScreenData; + private CompletionListener listener; + private TextAndGraphicManager.CurrentScreenDataUpdatedListener currentScreenDataUpdatedListener; + private SdlArtwork blankArtwork; + ISdl internalInterface; + FileManager fileManager; + + private Answer<Void> onShowSuccess = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + RPCRequest message = (RPCRequest) args[0]; + if (message instanceof Show) { + int correlationId = message.getCorrelationID(); + ShowResponse showResponse = new ShowResponse(); + showResponse.setSuccess(true); + message.getOnRPCResponseListener().onResponse(correlationId, showResponse); + } + return null; + } + }; + + private Answer<Void> onShowSuccessCanceled = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + RPCRequest message = (RPCRequest) args[0]; + if (message instanceof Show) { + int correlationId = message.getCorrelationID(); + textAndGraphicUpdateOperation.cancelTask(); + ShowResponse showResponse = new ShowResponse(); + showResponse.setSuccess(true); + message.getOnRPCResponseListener().onResponse(correlationId, showResponse); + } + return null; + } + }; + + + private Answer<Void> onImageUploadSuccessTaskCanceled = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) throws Throwable { + Object[] args = invocation.getArguments(); + MultipleFileCompletionListener listener = (MultipleFileCompletionListener) args[1]; + textAndGraphicUpdateOperation.cancelTask(); + listener.onComplete(null); + return null; + } + }; + + private Answer<Void> onArtworkUploadSuccess = new Answer<Void>() { + @Override + public Void answer(InvocationOnMock invocation) { + Object[] args = invocation.getArguments(); + MultipleFileCompletionListener listener = (MultipleFileCompletionListener) args[1]; + when(fileManager.hasUploadedFile(any(SdlFile.class))).thenReturn(true); + listener.onComplete(null); + return null; + } + }; + + + @Before + public void setUp() throws Exception { + Context mTestContext = getInstrumentation().getContext(); + // mock things + internalInterface = mock(ISdl.class); + fileManager = mock(FileManager.class); + setUpCompletionListener(); + textField1 = "It is"; + textField2 = "Wednesday"; + textField3 = "My"; + textField4 = "Dudes"; + mediaTrackField = "dudes"; + title = "dudes"; + + blankArtwork = new SdlArtwork(); + blankArtwork.setType(FileType.GRAPHIC_PNG); + blankArtwork.setName("blankArtwork"); + blankArtwork.setResourceId(R.drawable.transparent); + + textField1Type = MetadataType.MEDIA_TITLE; + textField2Type = MetadataType.MEDIA_TITLE; + textField3Type = MetadataType.MEDIA_TITLE; + textField4Type = MetadataType.MEDIA_TITLE; + + + textAlignment = TextAlignment.CENTERED; + + testArtwork1 = new SdlArtwork(); + testArtwork1.setName("testFile1"); + Uri uri1 = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl"); + testArtwork1.setUri(uri1); + testArtwork1.setType(FileType.GRAPHIC_PNG); + + testArtwork2 = new SdlArtwork(); + testArtwork2.setName("testFile2"); + Uri uri2 = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl"); + testArtwork2.setUri(uri2); + testArtwork2.setType(FileType.GRAPHIC_PNG); + + testArtwork3 = new SdlArtwork(); + testArtwork3.setName("testFile3"); + Uri uri3 = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl"); + testArtwork3.setUri(uri3); + testArtwork3.setType(FileType.GRAPHIC_PNG); + + testArtwork4 = new SdlArtwork(); + testArtwork4.setName("testFile4"); + Uri uri4 = Uri.parse("android.resource://" + mTestContext.getPackageName() + "/drawable/ic_sdl"); + testArtwork4.setUri(uri4); + testArtwork4.setType(FileType.GRAPHIC_PNG); + + currentScreenData = new Show(); + currentScreenData.setMainField1("Old"); + currentScreenData.setMainField2("Text"); + currentScreenData.setMainField3("Not"); + currentScreenData.setMainField4("Important"); + + currentScreenData.setGraphic(testArtwork1.getImageRPC()); + currentScreenData.setSecondaryGraphic(testArtwork2.getImageRPC()); + + currentScreenDataUpdatedListener = new TextAndGraphicManager.CurrentScreenDataUpdatedListener() { + @Override + public void onUpdate(Show show) { + + } + }; + + defaultMainWindowCapability = getWindowCapability(4); + + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, textField2, textField3, textField4, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + } + + + private void setUpCompletionListener() { + listener = new CompletionListener() { + @Override + public void onComplete(boolean success) { + + } + }; + + } + + private WindowCapability getWindowCapability(int numberOfMainFields) { + + TextField mainField1 = new TextField(); + mainField1.setName(TextFieldName.mainField1); + TextField mainField2 = new TextField(); + mainField2.setName(TextFieldName.mainField2); + TextField mainField3 = new TextField(); + mainField3.setName(TextFieldName.mainField3); + TextField mainField4 = new TextField(); + mainField4.setName(TextFieldName.mainField4); + + List<TextField> textFieldList = new ArrayList<>(); + + textFieldList.add(mainField1); + textFieldList.add(mainField2); + textFieldList.add(mainField3); + textFieldList.add(mainField4); + + List<TextField> returnList = new ArrayList<>(); + + if (numberOfMainFields > 0) { + for (int i = 0; i < numberOfMainFields; i++) { + returnList.add(textFieldList.get(i)); + } + } + + WindowCapability windowCapability = new WindowCapability(); + windowCapability.setTextFields(returnList); + + ImageField imageField = new ImageField(); + imageField.setName(ImageFieldName.graphic); + ImageField imageField2 = new ImageField(); + imageField2.setName(ImageFieldName.secondaryGraphic); + List<ImageField> imageFieldList = new ArrayList<>(); + imageFieldList.add(imageField); + imageFieldList.add(imageField2); + windowCapability.setImageFields(imageFieldList); + + windowCapability.setImageFields(imageFieldList); + + return windowCapability; + } + + /** + * Used to simulate WindowCapability having no capabilities set + * + * @return windowCapability that has no capabilities set + */ + private WindowCapability getNullVarWindowCapability() { + + WindowCapability windowCapability = new WindowCapability(); + return windowCapability; + } + + @Test + public void testUploads() { + doAnswer(onShowSuccess).when(internalInterface).sendRPC(any(Show.class)); + doAnswer(onArtworkUploadSuccess).when(fileManager).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class)); + when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(4, 0)); + + // Test Images need to be uploaded, sending text and uploading images + textAndGraphicUpdateOperation.onExecute(); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField1(), textField1); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField2(), textField2); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField3(), textField3); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField4(), textField4); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getAlignment(), textAlignment); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getGraphic(), testArtwork3.getImageRPC()); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getSecondaryGraphic(), testArtwork4.getImageRPC()); + + + // Test The files to be updated are already uploaded, send the full show immediately + String textField11 = "It's not"; + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField11, textField2, textField3, textField4, + mediaTrackField, title, testArtwork1, testArtwork2, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + textAndGraphicUpdateOperation.onExecute(); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField1(), textField11); + + //Test: If there are no images to update, just send the text + TextsAndGraphicsState textsAndGraphicsStateNullImages = new TextsAndGraphicsState(textField1, textField2, textField3, textField4, + mediaTrackField, title, blankArtwork, blankArtwork, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsStateNullImages, listener, currentScreenDataUpdatedListener); + textAndGraphicUpdateOperation.onExecute(); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField1(), textField1); + + // Verifies that uploadArtworks gets called only with the fist textAndGraphicsUpdateOperation.onExecute call + verify(fileManager, times(1)).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class)); + } + + @Test + public void testCanceledRightAway() { + textAndGraphicUpdateOperation.cancelTask(); + textAndGraphicUpdateOperation.onExecute(); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField1(), "Old"); + } + + @Test + public void testTaskCanceledAfterImageUpload() { + doAnswer(onShowSuccess).when(internalInterface).sendRPC(any(Show.class)); + doAnswer(onImageUploadSuccessTaskCanceled).when(fileManager).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class)); + when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 0)); + + // Test Canceled after Image upload + textAndGraphicUpdateOperation.onExecute(); + verify(internalInterface, times(1)).sendRPC(any(Show.class)); + assertEquals(textAndGraphicUpdateOperation.getCurrentScreenData().getMainField1(), textField1); + + } + + @Test + public void testTaskCanceledAfterTextSent() { + doAnswer(onShowSuccessCanceled).when(internalInterface).sendRPC(any(Show.class)); + when(internalInterface.getSdlMsgVersion()).thenReturn(new SdlMsgVersion(5, 0)); + + textAndGraphicUpdateOperation.onExecute(); + verify(fileManager, times(0)).uploadArtworks(any(List.class), any(MultipleFileCompletionListener.class)); + + } + + /** + * Test getting number of lines available to be set based off of windowCapability + */ + @Test + public void testGetMainLines() { + + // We want to test that the looping works. By default, it will return 4 if display cap is null + textAndGraphicUpdateOperation.defaultMainWindowCapability = getNullVarWindowCapability(); + + // Null test + assertEquals(0, ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(textAndGraphicUpdateOperation.defaultMainWindowCapability)); + + // The tests.java class has an example of this, but we must build it to do what + // we need it to do. Build display cap w/ 3 main fields and test that it returns 3 + textAndGraphicUpdateOperation.defaultMainWindowCapability = getWindowCapability(3); + assertEquals(ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(textAndGraphicUpdateOperation.defaultMainWindowCapability), 3); + } + + + @Test + public void testAssemble1Line() { + + Show inputShow = new Show(); + + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, null, null, null, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, MetadataType.HUMIDITY, null, null, null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(1), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + Show assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + + // test tags (just 1) + MetadataTags tags = assembledShow.getMetadataTags(); + List<MetadataType> tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + assertEquals(tags.getMainField1(), tagsList); + + textsAndGraphicsState.setTextField2(textField2); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(1), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); + + textsAndGraphicsState.setTextField3(textField3); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(1), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My"); + + textsAndGraphicsState.setTextField4(textField4); + textsAndGraphicsState.setTextField4Type(MetadataType.CURRENT_TEMPERATURE); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(1), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is - Wednesday - My - Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList.add(MetadataType.CURRENT_TEMPERATURE); + assertEquals(tags.getMainField1(), tagsList); + + // For some obscurity, lets try setting just fields 2 and 4 for a 1 line display + textsAndGraphicsState.setTextField1(null); + textsAndGraphicsState.setTextField3(null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(1), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "Wednesday - Dudes"); + } + + @Test + public void testAssemble2Lines() { + + Show inputShow = new Show(); + defaultMainWindowCapability = getWindowCapability(2); + + // Force it to return display with support for only 2 lines of text + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, null, null, null, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, MetadataType.HUMIDITY, null, null, null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + Show assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + + // test tags + MetadataTags tags = assembledShow.getMetadataTags(); + List<MetadataType> tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + assertEquals(tags.getMainField1(), tagsList); + + textsAndGraphicsState.setTextField2(textField2); + textsAndGraphicsState.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + List<MetadataType> tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + textsAndGraphicsState.setTextField3(textField3); + textsAndGraphicsState.setTextField3Type(MetadataType.MEDIA_ALBUM); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(2), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); + assertEquals(assembledShow.getMainField2(), "My"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.CURRENT_TEMPERATURE); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.MEDIA_ALBUM); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + textsAndGraphicsState.setTextField4(textField4); + textsAndGraphicsState.setTextField4Type(MetadataType.MEDIA_STATION); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(2), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is - Wednesday"); + assertEquals(assembledShow.getMainField2(), "My - Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.CURRENT_TEMPERATURE); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.MEDIA_STATION); + tagsList2.add(MetadataType.MEDIA_ALBUM); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + // For some obscurity, lets try setting just fields 2 and 4 for a 2 line display + textsAndGraphicsState.setTextField1(null); + textsAndGraphicsState.setTextField3(null); + textsAndGraphicsState.setTextField1Type(null); + textsAndGraphicsState.setTextField3Type(null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(2), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "Wednesday"); + assertEquals(assembledShow.getMainField2(), "Dudes"); + + // And 3 fields without setting 1 + textsAndGraphicsState.setTextField3(textField3); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, getWindowCapability(2), currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "Wednesday"); + assertEquals(assembledShow.getMainField2(), "My - Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.CURRENT_TEMPERATURE); + tagsList2.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + } + + @Test + public void testAssemble3Lines() { + + Show inputShow = new Show(); + + // Force it to return display with support for only 3 lines of text + defaultMainWindowCapability = getWindowCapability(3); + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, null, null, null, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, MetadataType.HUMIDITY, null, null, null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + Show assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), ""); + assertEquals(assembledShow.getMainField3(), ""); + + // test tags + MetadataTags tags = assembledShow.getMetadataTags(); + List<MetadataType> tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + assertEquals(tags.getMainField1(), tagsList); + + textsAndGraphicsState.setTextField2(textField2); + textsAndGraphicsState.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), ""); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + List<MetadataType> tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + textsAndGraphicsState.setTextField3(textField3); + textsAndGraphicsState.setTextField3Type(MetadataType.MEDIA_ALBUM); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + List<MetadataType> tagsList3 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + + textsAndGraphicsState.setTextField4(textField4); + textsAndGraphicsState.setTextField4Type(MetadataType.MEDIA_STATION); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My - Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList3 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + tagsList3.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + + // Someone might not want to set the fields in order? We should handle that + textsAndGraphicsState.setTextField1(null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + try { + System.out.println(assembledShow.serializeJSON().toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My - Dudes"); + } + + @Test + public void testAssemble4Lines() { + + Show inputShow = new Show(); + + defaultMainWindowCapability = getWindowCapability(4); + TextField tx1 = new TextField(); + TextField tx2 = new TextField(); + TextField tx3 = new TextField(); + TextField tx4 = new TextField(); + TextField tx5 = new TextField(); + TextField tx6 = new TextField(); + + tx1.setName(TextFieldName.mainField1); + tx2.setName(TextFieldName.mainField2); + tx3.setName(TextFieldName.mainField3); + tx4.setName(TextFieldName.mainField4); + tx5.setName(TextFieldName.mediaTrack); + tx6.setName(TextFieldName.templateTitle); + + List<TextField> textFieldNames = Arrays.asList(tx1, tx2, tx3, tx4, tx5, tx6); + defaultMainWindowCapability.setTextFields(textFieldNames); + + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, null, null, null, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, MetadataType.HUMIDITY, null, null, null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + textsAndGraphicsState.setMediaTrackTextField("HI"); + textsAndGraphicsState.setTitle("bye"); + + // Force it to return display with support for only 4 lines of text + Show assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), ""); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), ""); + assertEquals(assembledShow.getMediaTrack(), "HI"); + assertEquals(assembledShow.getTemplateTitle(), "bye"); + + // test tags + MetadataTags tags = assembledShow.getMetadataTags(); + List<MetadataType> tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + assertEquals(tags.getMainField1(), tagsList); + + textsAndGraphicsState.setTextField2("Wednesday"); + textsAndGraphicsState.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), ""); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + List<MetadataType> tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + textsAndGraphicsState.setTextField3("My"); + textsAndGraphicsState.setTextField3Type(MetadataType.MEDIA_ALBUM); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My"); + assertEquals(assembledShow.getMainField4(), ""); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + List<MetadataType> tagsList3 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + + textsAndGraphicsState.setTextField4("Dudes"); + textsAndGraphicsState.setTextField4Type(MetadataType.MEDIA_STATION); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My"); + assertEquals(assembledShow.getMainField4(), "Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList3 = new ArrayList<>(); + List<MetadataType> tagsList4 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + tagsList4.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + assertEquals(tags.getMainField4(), tagsList4); + + // try just setting line 1 and 4 + textsAndGraphicsState.setTextField2(null); + textsAndGraphicsState.setTextField3(null); + textsAndGraphicsState.setTextField2Type(null); + textsAndGraphicsState.setTextField3Type(null); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), ""); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), "Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList4 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList4.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField4(), tagsList4); + } + + /** + * Testing if WindowCapability is null, TextFields should still update. + */ + @Test + public void testAssemble4LinesNullWindowCapability() { + + Show inputShow = new Show(); + + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, null, null, null, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, MetadataType.HUMIDITY, null, null, null); + + textsAndGraphicsState.setMediaTrackTextField("HI"); + textsAndGraphicsState.setTitle("bye"); + + textsAndGraphicsState.setTextField1("It is"); + textsAndGraphicsState.setTextField1Type(MetadataType.HUMIDITY); + + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, null, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + Show assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), ""); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), ""); + assertEquals(assembledShow.getMediaTrack(), "HI"); + assertEquals(assembledShow.getTemplateTitle(), "bye"); + + // test tags + MetadataTags tags = assembledShow.getMetadataTags(); + List<MetadataType> tagsList = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + assertEquals(tags.getMainField1(), tagsList); + + textsAndGraphicsState.setTextField2("Wednesday"); + textsAndGraphicsState.setTextField2Type(MetadataType.CURRENT_TEMPERATURE); + + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, null, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), ""); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + List<MetadataType> tagsList2 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + + textsAndGraphicsState.setTextField3("My"); + textsAndGraphicsState.setTextField3Type(MetadataType.MEDIA_ALBUM); + + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, null, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My"); + assertEquals(assembledShow.getMainField4(), ""); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + List<MetadataType> tagsList3 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + + textsAndGraphicsState.setTextField4("Dudes"); + textsAndGraphicsState.setTextField4Type(MetadataType.MEDIA_STATION); + + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, null, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), "Wednesday"); + assertEquals(assembledShow.getMainField3(), "My"); + assertEquals(assembledShow.getMainField4(), "Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList2 = new ArrayList<>(); + tagsList3 = new ArrayList<>(); + List<MetadataType> tagsList4 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList2.add(MetadataType.CURRENT_TEMPERATURE); + tagsList3.add(MetadataType.MEDIA_ALBUM); + tagsList4.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField2(), tagsList2); + assertEquals(tags.getMainField3(), tagsList3); + assertEquals(tags.getMainField4(), tagsList4); + + // try just setting line 1 and 4 + textsAndGraphicsState.setTextField2(null); + textsAndGraphicsState.setTextField3(null); + textsAndGraphicsState.setTextField2Type(null); + textsAndGraphicsState.setTextField3Type(null); + + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, null, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + + assembledShow = textAndGraphicUpdateOperation.assembleShowText(inputShow); + assertEquals(assembledShow.getMainField1(), "It is"); + assertEquals(assembledShow.getMainField2(), ""); + assertEquals(assembledShow.getMainField3(), ""); + assertEquals(assembledShow.getMainField4(), "Dudes"); + + // test tags + tags = assembledShow.getMetadataTags(); + tagsList = new ArrayList<>(); + tagsList4 = new ArrayList<>(); + tagsList.add(MetadataType.HUMIDITY); + tagsList4.add(MetadataType.MEDIA_STATION); + assertEquals(tags.getMainField1(), tagsList); + assertEquals(tags.getMainField4(), tagsList4); + } + + @Test + public void testExtractTextFromShow() { + Show mainShow = new Show(); + mainShow.setMainField1("test"); + mainShow.setMainField3("Sauce"); + mainShow.setMainField4(""); + + Show newShow = textAndGraphicUpdateOperation.extractTextFromShow(mainShow); + + assertEquals(newShow.getMainField1(), "test"); + assertEquals(newShow.getMainField3(), "Sauce"); + assertEquals(newShow.getMainField4(), ""); + assertNull(newShow.getMainField2()); + } + + @Test + public void testCreateImageOnlyShowWithPrimaryArtwork() { + // Test null + Show testShow = textAndGraphicUpdateOperation.createImageOnlyShowWithPrimaryArtwork(null, null); + assertNull(testShow); + + // Test when artwork hasn't been uploaded + when(fileManager.hasUploadedFile(any(SdlFile.class))).thenReturn(false); + TextsAndGraphicsState textsAndGraphicsState = new TextsAndGraphicsState(textField1, textField2, textField3, textField4, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + testShow = textAndGraphicUpdateOperation.createImageOnlyShowWithPrimaryArtwork(testArtwork1, testArtwork2); + assertNull(testShow); + + // Test when artwork has been uploaded + when(fileManager.hasUploadedFile(any(SdlFile.class))).thenReturn(true); + textsAndGraphicsState = new TextsAndGraphicsState(textField1, textField2, textField3, textField4, + mediaTrackField, title, testArtwork3, testArtwork4, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); + textAndGraphicUpdateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager, defaultMainWindowCapability, currentScreenData, textsAndGraphicsState, listener, currentScreenDataUpdatedListener); + testShow = textAndGraphicUpdateOperation.createImageOnlyShowWithPrimaryArtwork(testArtwork1, testArtwork2); + assertEquals(testShow.getGraphic(), testArtwork1.getImageRPC()); + assertEquals(testShow.getSecondaryGraphic(), testArtwork2.getImageRPC()); + } + +} diff --git a/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java index 82e9a5e01..3d05bc7cd 100644 --- a/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java +++ b/android/sdl_android/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java @@ -53,8 +53,8 @@ class TextAndGraphicManager extends BaseTextAndGraphicManager { } @Override - SdlArtwork getBlankArtwork(){ - if (blankArtwork == null){ + SdlArtwork getBlankArtwork() { + if (blankArtwork == null) { blankArtwork = new SdlArtwork(); blankArtwork.setType(FileType.GRAPHIC_PNG); blankArtwork.setName("blankArtwork"); diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java index 80daf4d2e..6d05b93eb 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseScreenManager.java @@ -78,6 +78,7 @@ abstract class BaseScreenManager extends BaseSubManager { // Sub manager listener private final CompletionListener subManagerListener = new CompletionListener() { + @Override public synchronized void onComplete(boolean success) { if (softButtonManager != null && textAndGraphicManager != null && voiceCommandManager != null && menuManager != null && choiceSetManager != null && subscribeButtonManager != null) { @@ -248,6 +249,9 @@ abstract class BaseScreenManager extends BaseSubManager { * @return an SdlArtwork object represents the current primaryGraphic */ public SdlArtwork getPrimaryGraphic() { + if (this.textAndGraphicManager.getPrimaryGraphic() == null || textAndGraphicManager.getPrimaryGraphic().getName() == null || this.textAndGraphicManager.getPrimaryGraphic().getName().equals(textAndGraphicManager.getBlankArtwork().getName())) { + return null; + } return this.textAndGraphicManager.getPrimaryGraphic(); } @@ -267,6 +271,9 @@ abstract class BaseScreenManager extends BaseSubManager { * @return an SdlArtwork object represents the current secondaryGraphic */ public SdlArtwork getSecondaryGraphic() { + if (this.textAndGraphicManager.getSecondaryGraphic() == null || textAndGraphicManager.getSecondaryGraphic().getName() == null || this.textAndGraphicManager.getSecondaryGraphic().getName().equals(textAndGraphicManager.getBlankArtwork().getName())) { + return null; + } return this.textAndGraphicManager.getSecondaryGraphic(); } diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java b/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java index ad43b5526..9c756e758 100644 --- a/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java +++ b/base/src/main/java/com/smartdevicelink/managers/screen/BaseTextAndGraphicManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Livio, Inc. + * Copyright (c) 2019 - 2020 Livio, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,61 +33,51 @@ package com.smartdevicelink.managers.screen; import androidx.annotation.NonNull; +import com.livio.taskmaster.Queue; +import com.livio.taskmaster.Task; import com.smartdevicelink.managers.BaseSubManager; import com.smartdevicelink.managers.CompletionListener; -import com.smartdevicelink.managers.ManagerUtility; import com.smartdevicelink.managers.file.FileManager; -import com.smartdevicelink.managers.file.MultipleFileCompletionListener; import com.smartdevicelink.managers.file.filetypes.SdlArtwork; import com.smartdevicelink.managers.lifecycle.OnSystemCapabilityListener; import com.smartdevicelink.managers.lifecycle.SystemCapabilityManager; import com.smartdevicelink.protocol.enums.FunctionID; import com.smartdevicelink.proxy.RPCNotification; -import com.smartdevicelink.proxy.RPCResponse; import com.smartdevicelink.proxy.interfaces.ISdl; import com.smartdevicelink.proxy.rpc.DisplayCapability; -import com.smartdevicelink.proxy.rpc.MetadataTags; import com.smartdevicelink.proxy.rpc.OnHMIStatus; import com.smartdevicelink.proxy.rpc.Show; 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.MetadataType; import com.smartdevicelink.proxy.rpc.enums.PredefinedWindows; import com.smartdevicelink.proxy.rpc.enums.SystemCapabilityType; import com.smartdevicelink.proxy.rpc.enums.TextAlignment; -import com.smartdevicelink.proxy.rpc.enums.TextFieldName; import com.smartdevicelink.proxy.rpc.listeners.OnRPCNotificationListener; -import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; -import com.smartdevicelink.util.CompareUtils; import com.smartdevicelink.util.DebugTool; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; -import java.util.Map; import static com.smartdevicelink.proxy.rpc.enums.TextAlignment.CENTERED; /** * <strong>TextAndGraphicManager</strong> <br> - * + * <p> * Note: This class must be accessed through the SdlManager. Do not instantiate it by itself. <br> - * */ abstract class BaseTextAndGraphicManager extends BaseSubManager { private static final String TAG = "TextAndGraphicManager"; - boolean isDirty, hasQueuedUpdate; - volatile Show inProgressUpdate; - Show currentScreenData, queuedImageUpdate; + boolean isDirty; + Show currentScreenData; HMILevel currentHMILevel; + private final WeakReference<SoftButtonManager> softButtonManager; WindowCapability defaultMainWindowCapability; - private boolean pendingHMIFull, batchingUpdates; + private boolean batchingUpdates; private final WeakReference<FileManager> fileManager; - private final WeakReference<SoftButtonManager> softButtonManager; - private CompletionListener queuedUpdateListener, inProgressListener, pendingHMIListener; SdlArtwork blankArtwork; private OnRPCNotificationListener hmiListener; private OnSystemCapabilityListener onDisplaysCapabilityListener; @@ -95,6 +85,9 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { private TextAlignment textAlignment; private String textField1, textField2, textField3, textField4, mediaTrackTextField, title; private MetadataType textField1Type, textField2Type, textField3Type, textField4Type; + TextAndGraphicUpdateOperation updateOperation; + private CompletionListener currentOperationListener; + Queue transactionQueue; //Constructors @@ -105,12 +98,11 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { this.softButtonManager = new WeakReference<>(softButtonManager); batchingUpdates = false; isDirty = false; - pendingHMIFull = false; textAlignment = CENTERED; currentHMILevel = HMILevel.HMI_NONE; currentScreenData = new Show(); + this.transactionQueue = newTransactionQueue(); addListeners(); - getBlankArtwork(); } @Override @@ -120,8 +112,7 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { } @Override - public void dispose(){ - + public void dispose() { textField1 = null; textField1Type = null; textField2 = null; @@ -137,15 +128,15 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { secondaryGraphic = null; blankArtwork = null; defaultMainWindowCapability = null; - inProgressUpdate = null; - queuedImageUpdate = null; currentScreenData = null; - queuedUpdateListener = null; - pendingHMIListener = null; - inProgressListener = null; - hasQueuedUpdate = false; isDirty = false; - pendingHMIFull = false; + updateOperation = null; + + // Cancel the operations + if (transactionQueue != null) { + transactionQueue.close(); + transactionQueue = null; + } // remove listeners internalInterface.removeOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, hmiListener); @@ -154,66 +145,32 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { super.dispose(); } - private void addListeners() { - // add listener - hmiListener = new OnRPCNotificationListener() { - @Override - public void onNotified(RPCNotification notification) { - OnHMIStatus onHMIStatus = (OnHMIStatus)notification; - if (onHMIStatus.getWindowID() != null && onHMIStatus.getWindowID() != PredefinedWindows.DEFAULT_WINDOW.getValue()) { - return; - } - currentHMILevel = onHMIStatus.getHmiLevel(); - if (currentHMILevel == HMILevel.HMI_FULL){ - if (pendingHMIFull){ - DebugTool.logInfo(TAG, "Acquired HMI_FULL with pending update. Sending now"); - pendingHMIFull = false; - sdlUpdate(pendingHMIListener); - pendingHMIListener = null; - } - } - } - }; - internalInterface.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, hmiListener); - - - onDisplaysCapabilityListener = new OnSystemCapabilityListener() { - @Override - public void onCapabilityRetrieved(Object capability) { - // instead of using the parameter it's more safe to use the convenience method - List<DisplayCapability> capabilities = SystemCapabilityManager.convertToList(capability, DisplayCapability.class); - if (capabilities == null || capabilities.size() == 0) { - DebugTool.logError(TAG, "TextAndGraphic Manager - Capabilities sent here are null or empty"); - }else { - DisplayCapability display = capabilities.get(0); - for (WindowCapability windowCapability : display.getWindowCapabilities()) { - int currentWindowID = windowCapability.getWindowID() != null ? windowCapability.getWindowID() : PredefinedWindows.DEFAULT_WINDOW.getValue(); - if (currentWindowID == PredefinedWindows.DEFAULT_WINDOW.getValue()) { - defaultMainWindowCapability = windowCapability; - } - } - } - } + private Queue newTransactionQueue() { + Queue queue = internalInterface.getTaskmaster().createQueue("TextAndGraphicManager", 3, false); + queue.pause(); + return queue; + } - @Override - public void onError(String info) { - DebugTool.logError(TAG, "Display Capability cannot be retrieved"); - defaultMainWindowCapability = null; - } - }; - this.internalInterface.addOnSystemCapabilityListener(SystemCapabilityType.DISPLAYS, onDisplaysCapabilityListener); + // Suspend the queue if the WindowCapabilities are null + // OR if the HMI level is NONE since we want to delay sending RPCs until we're in non-NONE + private void updateTransactionQueueSuspended() { + if (defaultMainWindowCapability == null || HMILevel.HMI_NONE.equals(currentHMILevel)) { + DebugTool.logInfo(TAG, String.format("Suspending the transaction queue. Current HMI level is NONE: %b, window capabilities are null: %b", HMILevel.HMI_NONE.equals(currentHMILevel), defaultMainWindowCapability == null)); + transactionQueue.pause(); + } else { + DebugTool.logInfo(TAG, "Starting the transaction queue"); + transactionQueue.resume(); + } } // Upload / Send protected void update(CompletionListener listener) { - // check if is batch update if (batchingUpdates) { return; } - - if (isDirty){ + if (isDirty) { isDirty = false; sdlUpdate(listener); } else if (listener != null) { @@ -221,754 +178,330 @@ abstract class BaseTextAndGraphicManager extends BaseSubManager { } } - private synchronized void sdlUpdate(CompletionListener listener){ - - // make sure hmi is not none - if (currentHMILevel == null || currentHMILevel == HMILevel.HMI_NONE){ - //Trying to send show on HMI_NONE, waiting for full - pendingHMIFull = true; - if (listener != null){ - pendingHMIListener = listener; - } - return; - } - - //Updating Text and Graphics - if (inProgressUpdate != null){ - - //In progress update exists, queueing update - if (queuedUpdateListener != null){ - - //Queued update already exists, superseding previous queued update - queuedUpdateListener.onComplete(false); - queuedUpdateListener = null; - } - - if (listener != null){ - queuedUpdateListener = listener; - } - - hasQueuedUpdate = true; - - return; - } - - Show fullShow = new Show(); - fullShow.setAlignment(textAlignment); - fullShow = assembleShowText(fullShow); - fullShow = assembleShowImages(fullShow); - - inProgressListener = listener; - - if (!shouldUpdatePrimaryImage() && !shouldUpdateSecondaryImage()){ - - //No Images to send, only sending text - inProgressUpdate = extractTextFromShow(fullShow); - sendShow(); - - }else if (!sdlArtworkNeedsUpload(primaryGraphic) && (secondaryGraphic == blankArtwork || !sdlArtworkNeedsUpload(secondaryGraphic))){ - - //Images already uploaded, sending full update - // The files to be updated are already uploaded, send the full show immediately - inProgressUpdate = fullShow; - sendShow(); - } else{ - - // Images need to be uploaded, sending text and uploading images - inProgressUpdate = fullShow; - final Show thisUpdate = fullShow; - - uploadImages(new CompletionListener() { - @Override - public void onComplete(boolean success) { - if (!success){ - DebugTool.logError(TAG, "Error uploading image"); - inProgressUpdate = extractTextFromShow(inProgressUpdate); - sendShow(); - } - // Check if queued image update still matches our images (there could have been a new Show in the meantime) - // and send a new update if it does. Since the images will already be on the head unit, the whole show will be sent - if (thisUpdate.getGraphic() != null && thisUpdate.getGraphic().equals(queuedImageUpdate.getGraphic()) || - (thisUpdate.getSecondaryGraphic() != null && queuedImageUpdate.getSecondaryGraphic() != null) && thisUpdate.getSecondaryGraphic().equals(queuedImageUpdate.getSecondaryGraphic())){ - // Queued image update matches the images we need, sending update - sendShow(); - } - // Else, Queued image update does not match the images we need, skipping update - } - }); - queuedImageUpdate = fullShow; - } - } - - private void sendShow(){ - inProgressUpdate.setOnRPCResponseListener(new OnRPCResponseListener() { - @Override - public void onResponse(int correlationId, RPCResponse response) { - handleResponse(response.getSuccess()); - } - - private void handleResponse(boolean success){ - if (success){ - updateCurrentScreenDataState(inProgressUpdate); - } - - inProgressUpdate = null; - if (inProgressListener != null){ - inProgressListener.onComplete(success); - inProgressListener = null; - } - - if (hasQueuedUpdate){ - //Queued update exists, sending another update - hasQueuedUpdate = false; - CompletionListener temp = queuedUpdateListener; - queuedUpdateListener = null; - sdlUpdate(temp); - } - } - }); - - if (this.softButtonManager.get() != null) { - this.softButtonManager.get().setCurrentMainField1(inProgressUpdate.getMainField1()); - } - internalInterface.sendRPC(inProgressUpdate); - } - - // Images - - private void uploadImages(final CompletionListener listener) { - - List<SdlArtwork> artworksToUpload = new ArrayList<>(); - - // add primary image - if (shouldUpdatePrimaryImage() && !primaryGraphic.isStaticIcon()){ - artworksToUpload.add(primaryGraphic); - } - - // add secondary image - if (shouldUpdateSecondaryImage() && !secondaryGraphic.isStaticIcon()){ - artworksToUpload.add(secondaryGraphic); - } - - if (artworksToUpload.size() == 0 && (primaryGraphic.isStaticIcon() || secondaryGraphic.isStaticIcon())){ - DebugTool.logInfo(TAG, "Upload attempted on static icons, sending them without upload instead"); - listener.onComplete(true); - } - - // use file manager to upload art - if (fileManager.get() != null) { - fileManager.get().uploadArtworks(artworksToUpload, new MultipleFileCompletionListener() { - @Override - public void onComplete(Map<String, String> errors) { - if (errors != null) { - DebugTool.logError(TAG, "Error Uploading Artworks. Error: " + errors.toString()); - listener.onComplete(false); - } else { - listener.onComplete(true); - } - } - }); - } - } - - private Show assembleShowImages(Show show){ - - if (shouldUpdatePrimaryImage()){ - show.setGraphic(primaryGraphic.getImageRPC()); - } - - if (shouldUpdateSecondaryImage()){ - show.setSecondaryGraphic(secondaryGraphic.getImageRPC()); - } - - return show; - } - - // Text - - Show assembleShowText(Show show){ - - show = setBlankTextFields(show); - - if (mediaTrackTextField != null && shouldUpdateMediaTrackField()) { - show.setMediaTrack(mediaTrackTextField); - } - - if (title != null && shouldUpdateTitleField()) { - show.setTemplateTitle(title); - } - - List<String> nonNullFields = findValidMainTextFields(); - if (nonNullFields.isEmpty()){ - return show; - } - - int numberOfLines = defaultMainWindowCapability != null ? ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(defaultMainWindowCapability) : 4; - - switch (numberOfLines) { - case 1: show = assembleOneLineShowText(show, nonNullFields); - break; - case 2: show = assembleTwoLineShowText(show); - break; - case 3: show = assembleThreeLineShowText(show); - break; - case 4: show = assembleFourLineShowText(show); - break; - } - - return show; - } - - private Show assembleOneLineShowText(Show show, List<String> showFields){ - - StringBuilder showString1 = new StringBuilder(); - for (int i = 0; i < showFields.size(); i++) { - if (i > 0) { - showString1.append(" - ").append(showFields.get(i)); - }else{ - showString1.append(showFields.get(i)); - } - } - show.setMainField1(showString1.toString()); - - MetadataTags tags = new MetadataTags(); - tags.setMainField1(findNonNullMetadataFields()); - - show.setMetadataTags(tags); - - return show; - } - - private Show assembleTwoLineShowText(Show show){ - - StringBuilder tempString = new StringBuilder(); - MetadataTags tags = new MetadataTags(); - - if (textField1 != null && textField1.length() > 0) { - tempString.append(textField1); - if (textField1Type != null){ - tags.setMainField1(textField1Type); + private synchronized void sdlUpdate(final CompletionListener listener) { + if (this.transactionQueue.getTasksAsList().size() > 0) { + // Transactions already in queue, we need to clear it out + transactionQueue.clear(); + updateOperation = null; + if (currentOperationListener != null) { + currentOperationListener.onComplete(false); } } - if (textField2 != null && textField2.length() > 0) { - if (( textField3 == null || !(textField3.length() > 0)) && (textField4 == null || !(textField4.length() > 0))){ - // text does not exist in slots 3 or 4, put text2 in slot 2 - show.setMainField2(textField2); - if (textField2Type != null){ - tags.setMainField2(textField2Type); - } - } else if (textField1 != null && textField1.length() > 0) { - // If text 1 exists, put it in slot 1 formatted - tempString.append(" - ").append(textField2); - if (textField2Type != null){ - List<MetadataType> typeList = new ArrayList<>(); - typeList.add(textField2Type); - if (textField1Type != null){ - typeList.add(textField1Type); - } - tags.setMainField1(typeList); - } - }else { - // If text 1 does not exist, put it in slot 1 unformatted - tempString.append(textField2); - if (textField2Type != null){ - tags.setMainField1(textField2Type); - } + // Task can be READY, about to start and popped of the queue, so we have to cancel it, to prevent it from starting + if (updateOperation != null && updateOperation.getState() == Task.READY) { + updateOperation.cancelTask(); + if (currentOperationListener != null) { + currentOperationListener.onComplete(false); } } - // set mainfield 1 - show.setMainField1(tempString.toString()); - - // new stringbuilder object - tempString = new StringBuilder(); - - if (textField3 != null && textField3.length() > 0){ - // If text 3 exists, put it in slot 2 - tempString.append(textField3); - if (textField3Type != null){ - List<MetadataType> typeList = new ArrayList<>(); - typeList.add(textField3Type); - tags.setMainField2(typeList); - } + // If Task is IN_PROGRESS, it’s not on the queue, we need to mark it as cancelled. The task will return at some point when it checks its status and call the listener back + if (updateOperation != null && updateOperation.getState() == Task.IN_PROGRESS) { + updateOperation.cancelTask(); } - if (textField4 != null && textField4.length() > 0){ - if (textField3 != null && textField3.length() > 0){ - // If text 3 exists, put it in slot 2 formatted - tempString.append(" - ").append(textField4); - if (textField4Type != null){ - List<MetadataType> typeList = new ArrayList<>(); - typeList.add(textField4Type); - if (textField3Type != null){ - typeList.add(textField3Type); - } - tags.setMainField2(typeList); - } - } else { - // If text 3 does not exist, put it in slot 3 unformatted - tempString.append(textField4); - if (textField4Type != null){ - tags.setMainField2(textField4Type); - } - } - } + currentOperationListener = listener; - if (tempString.toString().length() > 0){ - show.setMainField2(tempString.toString()); - } - - show.setMetadataTags(tags); - return show; - } - - private Show assembleThreeLineShowText(Show show){ - - MetadataTags tags = new MetadataTags(); - - if (textField1 != null && textField1.length() > 0) { - show.setMainField1(textField1); - if (textField1Type != null){ - tags.setMainField1(textField1Type); - } - } - - if (textField2 != null && textField2.length() > 0) { - show.setMainField2(textField2); - if (textField2Type != null){ - tags.setMainField2(textField2Type); - } - } - - StringBuilder tempString = new StringBuilder(); - - if (textField3 != null && textField3.length() > 0){ - tempString.append(textField3); - if (textField3Type != null){ - tags.setMainField3(textField3Type); - } - } - - if (textField4 != null && textField4.length() > 0) { - if (textField3 != null && textField3.length() > 0) { - // If text 3 exists, put it in slot 3 formatted - tempString.append(" - ").append(textField4); - if (textField4Type != null){ - List<MetadataType> tags4 = new ArrayList<>(); - if (textField3Type != null){ - tags4.add(textField3Type); - } - tags4.add(textField4Type); - tags.setMainField3(tags4); - } - } else { - // If text 3 does not exist, put it in slot 3 formatted - tempString.append(textField4); - if (textField4Type != null){ - tags.setMainField3(textField4Type); - } + CurrentScreenDataUpdatedListener currentScreenDataUpdateListener = new CurrentScreenDataUpdatedListener() { + @Override + public void onUpdate(Show show) { + updatePendingOperationsWithNewScreenData(show); + currentScreenData = show; } - } + }; - show.setMainField3(tempString.toString()); - show.setMetadataTags(tags); - return show; + updateOperation = new TextAndGraphicUpdateOperation(internalInterface, fileManager.get(), defaultMainWindowCapability, currentScreenData, currentState(), currentOperationListener, currentScreenDataUpdateListener); + transactionQueue.add(updateOperation, false); } - private Show assembleFourLineShowText(Show show){ - - MetadataTags tags = new MetadataTags(); - - if (textField1 != null && textField1.length() > 0) { - show.setMainField1(textField1); - if (textField1Type != null){ - tags.setMainField1(textField1Type); + //Updates pending task with current screen data + void updatePendingOperationsWithNewScreenData(Show newScreenData) { + for (Task task : transactionQueue.getTasksAsList()) { + if (!(task instanceof TextAndGraphicUpdateOperation)) { + continue; } + ((TextAndGraphicUpdateOperation) task).setCurrentScreenData(newScreenData); } - - if (textField2 != null && textField2.length() > 0) { - show.setMainField2(textField2); - if (textField2Type != null){ - tags.setMainField2(textField2Type); - } + if (this.softButtonManager.get() != null && newScreenData.getMainField1() != null) { + this.softButtonManager.get().setCurrentMainField1(currentScreenData.getMainField1()); } - - if (textField3 != null && textField3.length() > 0) { - show.setMainField3(textField3); - if (textField3Type != null){ - tags.setMainField3(textField3Type); - } - } - - if (textField4 != null && textField4.length() > 0) { - show.setMainField4(textField4); - if (textField4Type != null){ - tags.setMainField4(textField4Type); - } - } - - show.setMetadataTags(tags); - return show; } - // Extraction - - Show extractTextFromShow(Show show){ - - Show newShow = new Show(); - newShow.setMainField1(show.getMainField1()); - newShow.setMainField2(show.getMainField2()); - newShow.setMainField3(show.getMainField3()); - newShow.setMainField4(show.getMainField4()); - newShow.setTemplateTitle(show.getTemplateTitle()); - - return newShow; - } - - private Show setBlankTextFields(Show newShow){ - - newShow.setMainField1(""); - newShow.setMainField2(""); - newShow.setMainField3(""); - newShow.setMainField4(""); - newShow.setMediaTrack(""); - newShow.setTemplateTitle(""); - - return newShow; - } - - private void updateCurrentScreenDataState(Show show){ - - if (show == null){ - DebugTool.logError(TAG, "can not updateCurrentScreenDataFromShow from null show"); - return; - } - - // If the items are null, they were not updated, so we can't just set it directly - if (show.getMainField1() != null){ - currentScreenData.setMainField1(show.getMainField1()); - } - if (show.getMainField2() != null){ - currentScreenData.setMainField2(show.getMainField2()); - } - if (show.getMainField3() != null){ - currentScreenData.setMainField3(show.getMainField3()); - } - if (show.getMainField4() != null){ - currentScreenData.setMainField4(show.getMainField4()); - } - if (show.getTemplateTitle() != null){ - currentScreenData.setTemplateTitle(show.getTemplateTitle()); - } - if (show.getMediaTrack() != null){ - currentScreenData.setMediaTrack(show.getMediaTrack()); - } - if (show.getMetadataTags() != null){ - currentScreenData.setMetadataTags(show.getMetadataTags()); - } - if (show.getAlignment() != null){ - currentScreenData.setAlignment(show.getAlignment()); - } - if (show.getGraphic() != null){ - currentScreenData.setGraphic(show.getGraphic()); - } - if (show.getSecondaryGraphic() != null){ - currentScreenData.setSecondaryGraphic(show.getSecondaryGraphic()); - } + interface CurrentScreenDataUpdatedListener { + void onUpdate(Show show); } - // Helpers - private List<String> findValidMainTextFields(){ + private List<String> findNonNullTextFields() { List<String> array = new ArrayList<>(); - if (textField1 != null && textField1.length() > 0) { + if (textField1 != null) { array.add(textField1); } - if (textField2 != null && textField2.length() > 0) { + if (textField2 != null) { array.add(textField2); } - if (textField3 != null && textField3.length() > 0) { + if (textField3 != null) { array.add(textField3); } - if (textField4 != null && textField4.length() > 0) { + if (textField4 != null) { array.add(textField4); } - return array; - } - - - private List<MetadataType> findNonNullMetadataFields(){ - List<MetadataType> array = new ArrayList<>(); - - if (textField1Type != null) { - array.add(textField1Type); - } - - if (textField2Type != null) { - array.add(textField2Type); + if (title != null) { + array.add(title); } - if (textField3Type != null) { - array.add(textField3Type); - } - - if (textField4Type != null) { - array.add(textField4Type); + if (mediaTrackTextField != null) { + array.add(mediaTrackTextField); } return array; } - abstract SdlArtwork getBlankArtwork(); + Boolean hasData() { + boolean hasTextFields = (findNonNullTextFields().size() > 0); + boolean hasImageFields = (primaryGraphic != null) || (secondaryGraphic != null); - @SuppressWarnings("BooleanMethodIsAlwaysInverted") - private boolean sdlArtworkNeedsUpload(SdlArtwork artwork){ - if (fileManager.get() != null) { - return artwork != null && !fileManager.get().hasUploadedFile(artwork) && !artwork.isStaticIcon(); - } - return false; + return hasTextFields || hasImageFields; } - /** - * Check to see if primaryGraphic should be updated - * @return true if primaryGraphic should be updated, false if not - */ - private boolean shouldUpdatePrimaryImage() { - boolean templateSupportsPrimaryArtwork = templateSupportsImageField(ImageFieldName.graphic); - - String currentScreenDataPrimaryGraphicName = (currentScreenData != null && currentScreenData.getGraphic() != null) ? currentScreenData.getGraphic().getValue() : null; - String primaryGraphicName = primaryGraphic != null ? primaryGraphic.getName() : null; - return templateSupportsPrimaryArtwork - && !CompareUtils.areStringsEqual(currentScreenDataPrimaryGraphicName, primaryGraphicName, true, true) - && primaryGraphic != null; - } - - /** - * Check to see if secondaryGraphic should be updated - * @return true if secondaryGraphic should be updated, false if not - */ - private boolean shouldUpdateSecondaryImage() { - boolean templateSupportsSecondaryArtwork = (templateSupportsImageField(ImageFieldName.graphic) || templateSupportsImageField(ImageFieldName.secondaryGraphic)); - - String currentScreenDataSecondaryGraphicName = (currentScreenData != null && currentScreenData.getSecondaryGraphic() != null) ? currentScreenData.getSecondaryGraphic().getValue() : null; - String secondaryGraphicName = secondaryGraphic != null ? secondaryGraphic.getName() : null; - return templateSupportsSecondaryArtwork - && !CompareUtils.areStringsEqual(currentScreenDataSecondaryGraphicName, secondaryGraphicName, true, true) - && secondaryGraphic != null; - } - - /** - * Check to see if template supports the specified image field - * @return true if image field is supported, false if not - */ - private boolean templateSupportsImageField(ImageFieldName name) { - return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasImageFieldOfName(defaultMainWindowCapability, name); - } + abstract SdlArtwork getBlankArtwork(); - /** - * Check to see if mediaTrackTextField should be updated - * @return true if mediaTrackTextField should be updated, false if not - */ - private boolean shouldUpdateMediaTrackField() { - return templateSupportsTextField(TextFieldName.mediaTrack); - } - /** - * Check to see if title should be updated - * @return true if title should be updated, false if not - */ - private boolean shouldUpdateTitleField() { - return templateSupportsTextField(TextFieldName.templateTitle); - } + // Convert to State - /** - * Check to see if field should be updated - * @return true if field should be updated, false if not - */ - private boolean templateSupportsTextField(TextFieldName name) { - return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasTextFieldOfName(defaultMainWindowCapability, name); + private TextsAndGraphicsState currentState() { + return new TextsAndGraphicsState(textField1, textField2, textField3, textField4, mediaTrackTextField, + title, primaryGraphic, secondaryGraphic, textAlignment, textField1Type, textField2Type, textField3Type, textField4Type); } - // SCREEN ITEM SETTERS AND GETTERS + // Getters / Setters - void setTextAlignment(TextAlignment textAlignment){ + void setTextAlignment(TextAlignment textAlignment) { this.textAlignment = textAlignment; // If we aren't batching, send the update immediately, if we are, set ourselves as dirty (so we know we should send an update after the batch ends) - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - TextAlignment getTextAlignment(){ + TextAlignment getTextAlignment() { return textAlignment; } - void setMediaTrackTextField(String mediaTrackTextField){ + void setMediaTrackTextField(String mediaTrackTextField) { this.mediaTrackTextField = mediaTrackTextField; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getMediaTrackTextField(){ + String getMediaTrackTextField() { return mediaTrackTextField; } - void setTextField1(String textField1){ + void setTextField1(String textField1) { this.textField1 = textField1; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getTextField1(){ + String getTextField1() { return textField1; } - void setTextField2(String textField2){ + void setTextField2(String textField2) { this.textField2 = textField2; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getTextField2(){ + String getTextField2() { return textField2; } - void setTextField3(String textField3){ + void setTextField3(String textField3) { this.textField3 = textField3; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getTextField3(){ + String getTextField3() { return textField3; } - void setTextField4(String textField4){ + void setTextField4(String textField4) { this.textField4 = textField4; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getTextField4(){ + String getTextField4() { return textField4; } - void setTextField1Type(MetadataType textField1Type){ + void setTextField1Type(MetadataType textField1Type) { this.textField1Type = textField1Type; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - MetadataType getTextField1Type(){ + MetadataType getTextField1Type() { return textField1Type; } - void setTextField2Type(MetadataType textField2Type){ + void setTextField2Type(MetadataType textField2Type) { this.textField2Type = textField2Type; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - MetadataType getTextField2Type(){ + MetadataType getTextField2Type() { return textField2Type; } - void setTextField3Type(MetadataType textField3Type){ + void setTextField3Type(MetadataType textField3Type) { this.textField3Type = textField3Type; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - MetadataType getTextField3Type(){ + MetadataType getTextField3Type() { return textField3Type; } - void setTextField4Type(MetadataType textField4Type){ + void setTextField4Type(MetadataType textField4Type) { this.textField4Type = textField4Type; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - MetadataType getTextField4Type(){ + MetadataType getTextField4Type() { return textField4Type; } - void setTitle(String title){ + void setTitle(String title) { this.title = title; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - String getTitle(){ + String getTitle() { return title; } - void setPrimaryGraphic(SdlArtwork primaryGraphic){ + void setPrimaryGraphic(SdlArtwork primaryGraphic) { this.primaryGraphic = primaryGraphic; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - SdlArtwork getPrimaryGraphic(){ + SdlArtwork getPrimaryGraphic() { return primaryGraphic; } - void setSecondaryGraphic(SdlArtwork secondaryGraphic){ + void setSecondaryGraphic(SdlArtwork secondaryGraphic) { this.secondaryGraphic = secondaryGraphic; - if (!batchingUpdates){ + if (!batchingUpdates) { sdlUpdate(null); - }else{ + } else { isDirty = true; } } - SdlArtwork getSecondaryGraphic(){ + SdlArtwork getSecondaryGraphic() { return secondaryGraphic; } - void setBatchUpdates(boolean batching){ + void setBatchUpdates(boolean batching) { this.batchingUpdates = batching; } + private void addListeners() { + // add listener + hmiListener = new OnRPCNotificationListener() { + @Override + public void onNotified(RPCNotification notification) { + OnHMIStatus onHMIStatus = (OnHMIStatus) notification; + if (onHMIStatus.getWindowID() != null && onHMIStatus.getWindowID() != PredefinedWindows.DEFAULT_WINDOW.getValue()) { + return; + } + currentHMILevel = onHMIStatus.getHmiLevel(); + updateTransactionQueueSuspended(); + } + }; + internalInterface.addOnRPCNotificationListener(FunctionID.ON_HMI_STATUS, hmiListener); + + onDisplaysCapabilityListener = new OnSystemCapabilityListener() { + @Override + public void onCapabilityRetrieved(Object capability) { + // instead of using the parameter it's more safe to use the convenience method + List<DisplayCapability> capabilities = SystemCapabilityManager.convertToList(capability, DisplayCapability.class); + if (capabilities == null || capabilities.size() == 0) { + DebugTool.logError(TAG, "TextAndGraphic Manager - Capabilities sent here are null or empty"); + defaultMainWindowCapability = null; + } else { + DisplayCapability display = capabilities.get(0); + for (WindowCapability windowCapability : display.getWindowCapabilities()) { + int currentWindowID = windowCapability.getWindowID() != null ? windowCapability.getWindowID() : PredefinedWindows.DEFAULT_WINDOW.getValue(); + if (currentWindowID == PredefinedWindows.DEFAULT_WINDOW.getValue()) { + defaultMainWindowCapability = windowCapability; + } + } + } + // Update the queue's suspend state + updateTransactionQueueSuspended(); + if (hasData()) { + sdlUpdate(null); + } + } + + @Override + public void onError(String info) { + DebugTool.logError(TAG, "Display Capability cannot be retrieved"); + defaultMainWindowCapability = null; + updateTransactionQueueSuspended(); + } + }; + this.internalInterface.addOnSystemCapabilityListener(SystemCapabilityType.DISPLAYS, onDisplaysCapabilityListener); + } } diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java b/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java new file mode 100644 index 000000000..5f29e0cf9 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicUpdateOperation.java @@ -0,0 +1,638 @@ +package com.smartdevicelink.managers.screen; + +import com.livio.taskmaster.Task; +import com.smartdevicelink.managers.CompletionListener; +import com.smartdevicelink.managers.ManagerUtility; +import com.smartdevicelink.managers.file.FileManager; +import com.smartdevicelink.managers.file.MultipleFileCompletionListener; +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.proxy.RPCResponse; +import com.smartdevicelink.proxy.interfaces.ISdl; +import com.smartdevicelink.proxy.rpc.MetadataTags; +import com.smartdevicelink.proxy.rpc.Show; +import com.smartdevicelink.proxy.rpc.WindowCapability; +import com.smartdevicelink.proxy.rpc.enums.ImageFieldName; +import com.smartdevicelink.proxy.rpc.enums.MetadataType; +import com.smartdevicelink.proxy.rpc.enums.TextFieldName; +import com.smartdevicelink.proxy.rpc.listeners.OnRPCResponseListener; +import com.smartdevicelink.util.CompareUtils; +import com.smartdevicelink.util.DebugTool; + +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +/** + * Created by Julian Kast on 8/23/20. + */ +class TextAndGraphicUpdateOperation extends Task { + + private static final String TAG = "TextAndGraphicUpdateOperation"; + private final WeakReference<ISdl> internalInterface; + private final WeakReference<FileManager> fileManager; + WindowCapability defaultMainWindowCapability; + private Show currentScreenData; + private TextsAndGraphicsState updatedState; + private CompletionListener listener; + private TextAndGraphicManager.CurrentScreenDataUpdatedListener currentScreenDataUpdateListener; + + TextAndGraphicUpdateOperation(ISdl internalInterface, FileManager fileManager, WindowCapability currentCapabilities, + Show currentScreenData, TextsAndGraphicsState newState, CompletionListener listener, TextAndGraphicManager.CurrentScreenDataUpdatedListener currentScreenDataUpdateListener) { + super("TextAndGraphicUpdateOperation"); + this.internalInterface = new WeakReference<>(internalInterface); + this.fileManager = new WeakReference<>(fileManager); + this.defaultMainWindowCapability = currentCapabilities; + this.currentScreenData = currentScreenData; + this.updatedState = newState; + this.listener = listener; + this.currentScreenDataUpdateListener = currentScreenDataUpdateListener; + } + + @Override + public void onExecute() { + start(); + } + + private void start() { + if (getState() == Task.CANCELED) { + finishOperation(false); + return; + } + + // Build a show with everything from `self.newState`, we'll pull things out later if we can. + Show fullShow = new Show(); + fullShow.setAlignment(updatedState.getTextAlignment()); + fullShow = assembleShowText(fullShow); + fullShow = assembleShowImages(fullShow); + + if (!shouldUpdatePrimaryImage() && !shouldUpdateSecondaryImage()) { + DebugTool.logInfo(TAG, "No images to send, sending text"); + // If there are no images to update, just send the text + sendShow(extractTextFromShow(fullShow), new CompletionListener() { + @Override + public void onComplete(boolean success) { + finishOperation(success); + } + }); + + } else if (!sdlArtworkNeedsUpload(updatedState.getPrimaryGraphic()) && !sdlArtworkNeedsUpload(updatedState.getSecondaryGraphic())) { + DebugTool.logInfo(TAG, "Images already uploaded, sending full update"); + // The files to be updated are already uploaded, send the full show immediately + sendShow(fullShow, new CompletionListener() { + @Override + public void onComplete(boolean success) { + finishOperation(success); + } + }); + } else { + DebugTool.logInfo(TAG, "Images need to be uploaded, sending text and uploading images"); + + sendShow(extractTextFromShow(fullShow), new CompletionListener() { + @Override + public void onComplete(boolean success) { + if (getState() == Task.CANCELED) { + finishOperation(false); + return; + } + uploadImagesAndSendWhenDone(new CompletionListener() { + @Override + public void onComplete(boolean success) { + finishOperation(success); + } + }); + + } + }); + } + } + + private void sendShow(final Show show, final CompletionListener listener) { + show.setOnRPCResponseListener(new OnRPCResponseListener() { + @Override + public void onResponse(int correlationId, RPCResponse response) { + DebugTool.logInfo(TAG, "Text and Graphic update completed"); + if (response.getSuccess()) { + updateCurrentScreenDataFromShow(show); + } + listener.onComplete(response.getSuccess()); + + } + }); + internalInterface.get().sendRPC(show); + } + + + private void uploadImagesAndSendWhenDone(final CompletionListener listener) { + uploadImages(new CompletionListener() { + @Override + public void onComplete(boolean success) { + Show showWithGraphics = createImageOnlyShowWithPrimaryArtwork(updatedState.getPrimaryGraphic(), updatedState.getSecondaryGraphic()); + if (showWithGraphics != null) { + DebugTool.logInfo(TAG, "Sending update with the successfully uploaded images"); + sendShow(showWithGraphics, new CompletionListener() { + @Override + public void onComplete(boolean success) { + listener.onComplete(success); + } + }); + } else { + DebugTool.logWarning(TAG, "All images failed to upload. No graphics to show, skipping update."); + listener.onComplete(false); + } + } + }); + } + + private void uploadImages(final CompletionListener listener) { + List<SdlArtwork> artworksToUpload = new ArrayList<>(); + + // add primary image + if (shouldUpdatePrimaryImage() && !updatedState.getPrimaryGraphic().isStaticIcon()) { + artworksToUpload.add(updatedState.getPrimaryGraphic()); + } + + // add secondary image + if (shouldUpdateSecondaryImage() && !updatedState.getSecondaryGraphic().isStaticIcon()) { + artworksToUpload.add(updatedState.getSecondaryGraphic()); + } + + if (artworksToUpload.size() == 0) { + DebugTool.logInfo(TAG, "No artworks need an upload, sending them without upload instead"); + listener.onComplete(true); + } + + // use file manager to upload art + if (fileManager.get() != null) { + fileManager.get().uploadArtworks(artworksToUpload, new MultipleFileCompletionListener() { + @Override + public void onComplete(Map<String, String> errors) { + if (getState() == Task.CANCELED) { + finishOperation(false); + return; + } + if (errors != null) { + DebugTool.logError(TAG, "Text and graphic manager artwork failed to upload with error: " + errors.toString()); + listener.onComplete(false); + } else { + listener.onComplete(true); + } + } + }); + } + } + + private Show assembleShowImages(Show show) { + if (shouldUpdatePrimaryImage()) { + show.setGraphic(updatedState.getPrimaryGraphic().getImageRPC()); + } + + if (shouldUpdateSecondaryImage()) { + show.setSecondaryGraphic(updatedState.getSecondaryGraphic().getImageRPC()); + } + + return show; + } + + Show createImageOnlyShowWithPrimaryArtwork(SdlArtwork primaryArtwork, SdlArtwork secondaryArtwork) { + Show newShow = new Show(); + newShow.setGraphic((primaryArtwork != null && !(sdlArtworkNeedsUpload(primaryArtwork))) ? primaryArtwork.getImageRPC() : null); + newShow.setSecondaryGraphic((secondaryArtwork != null && !(sdlArtworkNeedsUpload(secondaryArtwork))) ? secondaryArtwork.getImageRPC() : null); + if (newShow.getGraphic() == null && newShow.getSecondaryGraphic() == null) { + DebugTool.logInfo(TAG, "No graphics to upload"); + return null; + } + return newShow; + } + + Show assembleShowText(Show show) { + show = setBlankTextFields(show); + + if (updatedState.getMediaTrackTextField() != null && shouldUpdateMediaTrackField()) { + show.setMediaTrack(updatedState.getMediaTrackTextField()); + } + + if (updatedState.getTitle() != null && shouldUpdateTitleField()) { + show.setTemplateTitle(updatedState.getTitle()); + } + + List<String> nonNullFields = findValidMainTextFields(); + if (nonNullFields.isEmpty()) { + return show; + } + + int numberOfLines = defaultMainWindowCapability != null ? ManagerUtility.WindowCapabilityUtility.getMaxNumberOfMainFieldLines(defaultMainWindowCapability) : 4; + + switch (numberOfLines) { + case 1: + show = assembleOneLineShowText(show, nonNullFields); + break; + case 2: + show = assembleTwoLineShowText(show); + break; + case 3: + show = assembleThreeLineShowText(show); + break; + case 4: + show = assembleFourLineShowText(show); + break; + } + return show; + } + + private Show assembleOneLineShowText(Show show, List<String> showFields) { + StringBuilder showString1 = new StringBuilder(); + for (int i = 0; i < showFields.size(); i++) { + if (i > 0) { + showString1.append(" - ").append(showFields.get(i)); + } else { + showString1.append(showFields.get(i)); + } + } + show.setMainField1(showString1.toString()); + MetadataTags tags = new MetadataTags(); + tags.setMainField1(findNonNullMetadataFields()); + show.setMetadataTags(tags); + + return show; + } + + private Show assembleTwoLineShowText(Show show) { + StringBuilder tempString = new StringBuilder(); + MetadataTags tags = new MetadataTags(); + + if (updatedState.getTextField1() != null && updatedState.getTextField1().length() > 0) { + tempString.append(updatedState.getTextField1()); + if (updatedState.getTextField1Type() != null) { + tags.setMainField1(updatedState.getTextField1Type()); + } + } + + if (updatedState.getTextField2() != null && updatedState.getTextField2().length() > 0) { + if ((updatedState.getTextField3() == null || !(updatedState.getTextField3().length() > 0)) && (updatedState.getTextField4() == null || !(updatedState.getTextField4().length() > 0))) { + // text does not exist in slots 3 or 4, put text2 in slot 2 + show.setMainField2(updatedState.getTextField2()); + if (updatedState.getTextField2Type() != null) { + tags.setMainField2(updatedState.getTextField2Type()); + } + } else if (updatedState.getTextField1() != null && updatedState.getTextField1().length() > 0) { + // If text 1 exists, put it in slot 1 formatted + tempString.append(" - ").append(updatedState.getTextField2()); + if (updatedState.getTextField2Type() != null) { + List<MetadataType> typeList = new ArrayList<>(); + typeList.add(updatedState.getTextField2Type()); + if (updatedState.getTextField1Type() != null) { + typeList.add(updatedState.getTextField1Type()); + } + tags.setMainField1(typeList); + } + } else { + // If text 1 does not exist, put it in slot 1 unformatted + tempString.append(updatedState.getTextField2()); + if (updatedState.getTextField2Type() != null) { + tags.setMainField1(updatedState.getTextField2Type()); + } + } + } + + // set mainField1 + show.setMainField1(tempString.toString()); + + // new stringBuilder object + tempString = new StringBuilder(); + + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + // If text 3 exists, put it in slot 2 + tempString.append(updatedState.getTextField3()); + if (updatedState.getTextField3Type() != null) { + List<MetadataType> typeList = new ArrayList<>(); + typeList.add(updatedState.getTextField3Type()); + tags.setMainField2(typeList); + } + } + + if (updatedState.getTextField4() != null && updatedState.getTextField4().length() > 0) { + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + // If text 3 exists, put it in slot 2 formatted + tempString.append(" - ").append(updatedState.getTextField4()); + if (updatedState.getTextField4Type() != null) { + List<MetadataType> typeList = new ArrayList<>(); + typeList.add(updatedState.getTextField4Type()); + if (updatedState.getTextField3Type() != null) { + typeList.add(updatedState.getTextField3Type()); + } + tags.setMainField2(typeList); + } + } else { + // If text 3 does not exist, put it in slot 3 unformatted + tempString.append(updatedState.getTextField4()); + if (updatedState.getTextField4Type() != null) { + tags.setMainField2(updatedState.getTextField4Type()); + } + } + } + + if (tempString.toString().length() > 0) { + show.setMainField2(tempString.toString()); + } + + show.setMetadataTags(tags); + return show; + } + + private Show assembleThreeLineShowText(Show show) { + MetadataTags tags = new MetadataTags(); + + if (updatedState.getTextField1() != null && updatedState.getTextField1().length() > 0) { + show.setMainField1(updatedState.getTextField1()); + if (updatedState.getTextField1Type() != null) { + tags.setMainField1(updatedState.getTextField1Type()); + } + } + + if (updatedState.getTextField2() != null && updatedState.getTextField2().length() > 0) { + show.setMainField2(updatedState.getTextField2()); + if (updatedState.getTextField2Type() != null) { + tags.setMainField2(updatedState.getTextField2Type()); + } + } + + StringBuilder tempString = new StringBuilder(); + + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + tempString.append(updatedState.getTextField3()); + if (updatedState.getTextField3Type() != null) { + tags.setMainField3(updatedState.getTextField3Type()); + } + } + + if (updatedState.getTextField4() != null && updatedState.getTextField4().length() > 0) { + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + // If text 3 exists, put it in slot 3 formatted + tempString.append(" - ").append(updatedState.getTextField4()); + if (updatedState.getTextField4Type() != null) { + List<MetadataType> tags4 = new ArrayList<>(); + if (updatedState.getTextField3Type() != null) { + tags4.add(updatedState.getTextField3Type()); + } + tags4.add(updatedState.getTextField4Type()); + tags.setMainField3(tags4); + } + } else { + // If text 3 does not exist, put it in slot 3 formatted + tempString.append(updatedState.getTextField4()); + if (updatedState.getTextField4Type() != null) { + tags.setMainField3(updatedState.getTextField4Type()); + } + } + } + show.setMainField3(tempString.toString()); + show.setMetadataTags(tags); + return show; + } + + private Show assembleFourLineShowText(Show show) { + MetadataTags tags = new MetadataTags(); + if (updatedState.getTextField1() != null && updatedState.getTextField1().length() > 0) { + show.setMainField1(updatedState.getTextField1()); + if (updatedState.getTextField1Type() != null) { + tags.setMainField1(updatedState.getTextField1Type()); + } + } + + if (updatedState.getTextField2() != null && updatedState.getTextField2().length() > 0) { + show.setMainField2(updatedState.getTextField2()); + if (updatedState.getTextField2Type() != null) { + tags.setMainField2(updatedState.getTextField2Type()); + } + } + + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + show.setMainField3(updatedState.getTextField3()); + if (updatedState.getTextField3Type() != null) { + tags.setMainField3(updatedState.getTextField3Type()); + } + } + + if (updatedState.getTextField4() != null && updatedState.getTextField4().length() > 0) { + show.setMainField4(updatedState.getTextField4()); + if (updatedState.getTextField4Type() != null) { + tags.setMainField4(updatedState.getTextField4Type()); + } + } + + show.setMetadataTags(tags); + + return show; + } + + // Extraction + + Show extractTextFromShow(Show show) { + Show newShow = new Show(); + newShow.setMainField1(show.getMainField1()); + newShow.setMainField2(show.getMainField2()); + newShow.setMainField3(show.getMainField3()); + newShow.setMainField4(show.getMainField4()); + newShow.setTemplateTitle(show.getTemplateTitle()); + newShow.setMetadataTags(show.getMetadataTags()); + newShow.setAlignment(show.getAlignment()); + + return newShow; + } + + private Show setBlankTextFields(Show newShow) { + newShow.setMainField1(""); + newShow.setMainField2(""); + newShow.setMainField3(""); + newShow.setMainField4(""); + newShow.setMediaTrack(""); + newShow.setTemplateTitle(""); + + return newShow; + } + + private void updateCurrentScreenDataFromShow(Show show) { + if (show == null) { + DebugTool.logError(TAG, "can not updateCurrentScreenDataFromShow from null show"); + return; + } + + // If the items are null, they were not updated, so we can't just set it directly + if (show.getMainField1() != null) { + currentScreenData.setMainField1(show.getMainField1()); + } + if (show.getMainField2() != null) { + currentScreenData.setMainField2(show.getMainField2()); + } + if (show.getMainField3() != null) { + currentScreenData.setMainField3(show.getMainField3()); + } + if (show.getMainField4() != null) { + currentScreenData.setMainField4(show.getMainField4()); + } + if (show.getTemplateTitle() != null) { + currentScreenData.setTemplateTitle(show.getTemplateTitle()); + } + if (show.getMediaTrack() != null) { + currentScreenData.setMediaTrack(show.getMediaTrack()); + } + if (show.getMetadataTags() != null) { + currentScreenData.setMetadataTags(show.getMetadataTags()); + } + if (show.getAlignment() != null) { + currentScreenData.setAlignment(show.getAlignment()); + } + if (show.getGraphic() != null) { + currentScreenData.setGraphic(show.getGraphic()); + } + if (show.getSecondaryGraphic() != null) { + currentScreenData.setSecondaryGraphic(show.getSecondaryGraphic()); + } + if (currentScreenDataUpdateListener != null) { + currentScreenDataUpdateListener.onUpdate(currentScreenData); + } + } + + // Helpers + + private List<String> findValidMainTextFields() { + List<String> array = new ArrayList<>(); + + if (updatedState.getTextField1() != null && updatedState.getTextField1().length() > 0) { + array.add(updatedState.getTextField1()); + } + + if (updatedState.getTextField2() != null && updatedState.getTextField2().length() > 0) { + array.add(updatedState.getTextField2()); + } + + if (updatedState.getTextField3() != null && updatedState.getTextField3().length() > 0) { + array.add(updatedState.getTextField3()); + } + + if (updatedState.getTextField4() != null && updatedState.getTextField4().length() > 0) { + array.add(updatedState.getTextField4()); + } + + return array; + } + + + private List<MetadataType> findNonNullMetadataFields() { + List<MetadataType> array = new ArrayList<>(); + + if (updatedState.getTextField1Type() != null) { + array.add(updatedState.getTextField1Type()); + } + + if (updatedState.getTextField2Type() != null) { + array.add(updatedState.getTextField2Type()); + } + + if (updatedState.getTextField3Type() != null) { + array.add(updatedState.getTextField3Type()); + } + + if (updatedState.getTextField4Type() != null) { + array.add(updatedState.getTextField4Type()); + } + + return array; + } + + @SuppressWarnings("BooleanMethodIsAlwaysInverted") + private boolean sdlArtworkNeedsUpload(SdlArtwork artwork) { + if (fileManager.get() != null) { + return artwork != null && !fileManager.get().hasUploadedFile(artwork) && !artwork.isStaticIcon(); + } + return false; + } + + /** + * Check to see if primaryGraphic should be updated + * + * @return true if primaryGraphic should be updated, false if not + */ + private boolean shouldUpdatePrimaryImage() { + boolean templateSupportsPrimaryArtwork = templateSupportsImageField(ImageFieldName.graphic); + String currentScreenDataPrimaryGraphicName = (currentScreenData != null && currentScreenData.getGraphic() != null) ? currentScreenData.getGraphic().getValue() : null; + String primaryGraphicName = updatedState.getPrimaryGraphic() != null ? updatedState.getPrimaryGraphic().getName() : null; + + boolean graphicMatchesExisting = CompareUtils.areStringsEqual(currentScreenDataPrimaryGraphicName, primaryGraphicName, true, true); + + return templateSupportsPrimaryArtwork && !graphicMatchesExisting; + } + + /** + * Check to see if secondaryGraphic should be updated + * + * @return true if secondaryGraphic should be updated, false if not + */ + private boolean shouldUpdateSecondaryImage() { + boolean templateSupportsSecondaryArtwork = templateSupportsImageField(ImageFieldName.secondaryGraphic); + String currentScreenDataSecondaryGraphicName = (currentScreenData != null && currentScreenData.getSecondaryGraphic() != null) ? currentScreenData.getSecondaryGraphic().getValue() : null; + String secondaryGraphicName = updatedState.getSecondaryGraphic() != null ? updatedState.getSecondaryGraphic().getName() : null; + + boolean graphicMatchesExisting = CompareUtils.areStringsEqual(currentScreenDataSecondaryGraphicName, secondaryGraphicName, true, true); + + // Cannot detect if there is a secondary image below v5.0, so we'll just try to detect if the primary image is allowed and allow the secondary image if it is. + if (internalInterface.get().getSdlMsgVersion().getMajorVersion() >= 5) { + return templateSupportsSecondaryArtwork && !graphicMatchesExisting; + } else { + return templateSupportsImageField(ImageFieldName.graphic) && !graphicMatchesExisting; + } + } + + /** + * Check to see if template supports the specified image field + * + * @return true if image field is supported, false if not + */ + private boolean templateSupportsImageField(ImageFieldName name) { + return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasImageFieldOfName(defaultMainWindowCapability, name); + } + + /** + * Check to see if mediaTrackTextField should be updated + * + * @return true if mediaTrackTextField should be updated, false if not + */ + private boolean shouldUpdateMediaTrackField() { + return templateSupportsTextField(TextFieldName.mediaTrack); + } + + /** + * Check to see if title should be updated + * + * @return true if title should be updated, false if not + */ + private boolean shouldUpdateTitleField() { + return templateSupportsTextField(TextFieldName.templateTitle); + } + + /** + * Check to see if field should be updated + * + * @return true if field should be updated, false if not + */ + private boolean templateSupportsTextField(TextFieldName name) { + return defaultMainWindowCapability == null || ManagerUtility.WindowCapabilityUtility.hasTextFieldOfName(defaultMainWindowCapability, name); + } + + Show getCurrentScreenData() { + return currentScreenData; + } + + void setCurrentScreenData(Show currentScreenData) { + this.currentScreenData = currentScreenData; + } + + private void finishOperation(boolean success) { + DebugTool.logInfo(TAG, "Finishing text and graphic update operation"); + if(listener != null){ + listener.onComplete(success); + } + onFinished(); + } +} diff --git a/base/src/main/java/com/smartdevicelink/managers/screen/TextsAndGraphicsState.java b/base/src/main/java/com/smartdevicelink/managers/screen/TextsAndGraphicsState.java new file mode 100644 index 000000000..bd6f749a3 --- /dev/null +++ b/base/src/main/java/com/smartdevicelink/managers/screen/TextsAndGraphicsState.java @@ -0,0 +1,122 @@ +package com.smartdevicelink.managers.screen; + +import com.smartdevicelink.managers.file.filetypes.SdlArtwork; +import com.smartdevicelink.proxy.rpc.enums.MetadataType; +import com.smartdevicelink.proxy.rpc.enums.TextAlignment; + +class TextsAndGraphicsState { + private String textField1, textField2, textField3, textField4, mediaTrackTextField, title; + private MetadataType textField1Type, textField2Type, textField3Type, textField4Type; + private TextAlignment textAlignment; + private SdlArtwork primaryGraphic, secondaryGraphic; + + TextsAndGraphicsState(String textField1, String textField2, String textField3, String textField4, String mediaTrackTextField, + String title, SdlArtwork primaryGraphic, SdlArtwork secondaryGraphic, TextAlignment textAlignment, + MetadataType textField1Type, MetadataType textField2Type, MetadataType textField3Type, MetadataType textField4Type) { + this.textField1 = textField1; + this.textField2 = textField2; + this.textField3 = textField3; + this.textField4 = textField4; + this.mediaTrackTextField = mediaTrackTextField; + this.title = title; + this.primaryGraphic = primaryGraphic; + this.secondaryGraphic = secondaryGraphic; + this.textAlignment = textAlignment; + this.textField1Type = textField1Type; + this.textField2Type = textField2Type; + this.textField3Type = textField3Type; + this.textField4Type = textField4Type; + } + + String getTextField1() { + return textField1; + } + + void setTextField1(String textField1) { + this.textField1 = textField1; + } + + String getTextField2() { + return textField2; + } + + void setTextField2(String textField2) { + this.textField2 = textField2; + } + + String getTextField3() { + return textField3; + } + + void setTextField3(String textField3) { + this.textField3 = textField3; + } + + String getTextField4() { + return textField4; + } + + void setTextField4(String textField4) { + this.textField4 = textField4; + } + + String getMediaTrackTextField() { + return mediaTrackTextField; + } + + void setMediaTrackTextField(String mediaTrackTextField) { + this.mediaTrackTextField = mediaTrackTextField; + } + + String getTitle() { + return title; + } + + void setTitle(String title) { + this.title = title; + } + + MetadataType getTextField1Type() { + return textField1Type; + } + + void setTextField1Type(MetadataType textField1Type) { + this.textField1Type = textField1Type; + } + + MetadataType getTextField2Type() { + return textField2Type; + } + + void setTextField2Type(MetadataType textField2Type) { + this.textField2Type = textField2Type; + } + + MetadataType getTextField3Type() { + return textField3Type; + } + + void setTextField3Type(MetadataType textField3Type) { + this.textField3Type = textField3Type; + } + + MetadataType getTextField4Type() { + return textField4Type; + } + + void setTextField4Type(MetadataType textField4Type) { + this.textField4Type = textField4Type; + } + + TextAlignment getTextAlignment() { + return textAlignment; + } + + SdlArtwork getPrimaryGraphic() { + return primaryGraphic; + } + + SdlArtwork getSecondaryGraphic() { + return secondaryGraphic; + } +} diff --git a/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java b/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java index 961e9e196..b84734a52 100644 --- a/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java +++ b/javaSE/src/main/java/com/smartdevicelink/managers/screen/TextAndGraphicManager.java @@ -45,10 +45,10 @@ import com.smartdevicelink.proxy.rpc.enums.FileType; */ class TextAndGraphicManager extends BaseTextAndGraphicManager { - TextAndGraphicManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager, @NonNull SoftButtonManager softButtonManager) { + TextAndGraphicManager(@NonNull ISdl internalInterface, @NonNull FileManager fileManager, @NonNull SoftButtonManager softButtonManager) { super(internalInterface, fileManager, softButtonManager); } - + @Override SdlArtwork getBlankArtwork(){ if (blankArtwork == null){ |