From b8ce32ed094122638ab6a85d70094d4dbb3b94f6 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Mon, 10 Jul 2023 10:19:49 +0200 Subject: [PATCH 1/5] Block unsafe events when a background sync is underway --- .../org/commcare/session/SessionNavigationResponder.java | 3 +++ src/main/java/org/commcare/session/SessionNavigator.java | 7 +++++++ .../test/utilities/MockSessionNavigationResponder.java | 9 +++++++++ 3 files changed, 19 insertions(+) diff --git a/src/main/java/org/commcare/session/SessionNavigationResponder.java b/src/main/java/org/commcare/session/SessionNavigationResponder.java index 3ab504892a..4630479e87 100644 --- a/src/main/java/org/commcare/session/SessionNavigationResponder.java +++ b/src/main/java/org/commcare/session/SessionNavigationResponder.java @@ -2,6 +2,8 @@ import org.javarosa.core.model.condition.EvaluationContext; +import java.util.concurrent.locks.ReentrantLock; + /** * Interface defining all functionality to be implemented by any class that will receive and * process status codes from a SessionNavigator @@ -19,4 +21,5 @@ public interface SessionNavigationResponder { // Provide a hook to the current evaluation context that the SessionNavigator will use EvaluationContext getEvalContextForNavigator(); + ReentrantLock getBackgroundSyncLock(); } diff --git a/src/main/java/org/commcare/session/SessionNavigator.java b/src/main/java/org/commcare/session/SessionNavigator.java index b09ccea26b..cade818f3a 100644 --- a/src/main/java/org/commcare/session/SessionNavigator.java +++ b/src/main/java/org/commcare/session/SessionNavigator.java @@ -28,6 +28,7 @@ public class SessionNavigator { public static final int START_SYNC_REQUEST = 7; public static final int PROCESS_QUERY_REQUEST = 8; public static final int REPORT_CASE_AUTOSELECT = 9; + public static final int FORM_ENTRY_ATTEMPT_DURING_SYNC = 10; private final SessionNavigationResponder responder; private CommCareSession currentSession; @@ -107,6 +108,12 @@ private void readyToProceed() { else if (currentSession.getForm() == null) { sendResponse(NO_CURRENT_FORM); } else { + // The current state indicate that a form needs to be instantiated but a background sync is ongoing + if (responder.getBackgroundSyncLock().isLocked()) { + sendResponse(FORM_ENTRY_ATTEMPT_DURING_SYNC); + return; + } + sendResponse(START_FORM_ENTRY); } } diff --git a/src/test/java/org/commcare/test/utilities/MockSessionNavigationResponder.java b/src/test/java/org/commcare/test/utilities/MockSessionNavigationResponder.java index 64913365a5..14667f1418 100644 --- a/src/test/java/org/commcare/test/utilities/MockSessionNavigationResponder.java +++ b/src/test/java/org/commcare/test/utilities/MockSessionNavigationResponder.java @@ -5,6 +5,8 @@ import org.commcare.session.SessionNavigationResponder; import org.javarosa.core.model.condition.EvaluationContext; +import java.util.concurrent.locks.ReentrantLock; + /** * A mock implementer of the SessionNavigationResponder interface, for testing purposes * @@ -14,9 +16,11 @@ public class MockSessionNavigationResponder implements SessionNavigationResponde private final SessionWrapper sessionWrapper; private int lastReceivedResultCode; + private ReentrantLock backgroungSyncLock; public MockSessionNavigationResponder(SessionWrapper sessionWrapper) { this.sessionWrapper = sessionWrapper; + this.backgroungSyncLock = new ReentrantLock(); } public int getLastResultCode() { @@ -38,4 +42,9 @@ public EvaluationContext getEvalContextForNavigator() { return sessionWrapper.getEvaluationContext(); } + @Override + public ReentrantLock getBackgroundSyncLock() { + return backgroungSyncLock; + } + } From f84f11ffcbd1380f0a3478b78754205abe58e81c Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Thu, 13 Jul 2023 14:59:49 +0200 Subject: [PATCH 2/5] Skip certain restore elements during parsing --- .../org/commcare/data/xml/DataModelPullParser.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/commcare/data/xml/DataModelPullParser.java b/src/main/java/org/commcare/data/xml/DataModelPullParser.java index d76f26e0d2..ee9f3307c1 100644 --- a/src/main/java/org/commcare/data/xml/DataModelPullParser.java +++ b/src/main/java/org/commcare/data/xml/DataModelPullParser.java @@ -10,6 +10,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.LinkedHashSet; +import java.util.List; import java.util.Vector; /** @@ -28,13 +29,14 @@ public class DataModelPullParser extends ElementParser { private final InputStream is; private final String requiredRootEnvelope = null; private final CommCareOTARestoreListener rListener; + private List blocksToSkipParsing; public DataModelPullParser(InputStream is, TransactionParserFactory factory) throws InvalidStructureException, IOException { this(is, factory, false); } public DataModelPullParser(InputStream is, TransactionParserFactory factory, CommCareOTARestoreListener rl) throws InvalidStructureException, IOException { - this(is, factory, false, false, rl); + this(is, factory, false, false, rl, null); } public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean deep) throws InvalidStructureException, IOException { @@ -42,10 +44,10 @@ public DataModelPullParser(InputStream is, TransactionParserFactory factory, boo } public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep) throws InvalidStructureException, IOException { - this(is, factory, failfast, deep, null); + this(is, factory, failfast, deep, null, null); } - public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep, CommCareOTARestoreListener rListener) throws InvalidStructureException, IOException { + public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep, CommCareOTARestoreListener rListener, List blocksToSkipParsing) throws InvalidStructureException, IOException { super(ElementParser.instantiateParser(is)); this.is = is; this.failfast = failfast; @@ -53,6 +55,7 @@ public DataModelPullParser(InputStream is, TransactionParserFactory factory, boo errors = new Vector<>(); this.deep = deep; this.rListener = rListener; + this.blocksToSkipParsing = blocksToSkipParsing; } @Override @@ -126,6 +129,11 @@ private void parseBlock(String root, LinkedHashSet parsers) t continue; } + if (blocksToSkipParsing != null && blocksToSkipParsing.equals(name)) { + this.skipBlock(name); + continue; + } + TransactionParser transaction = factory.getParser(parser); if (transaction == null) { if (deep) { From 34ed46090d981a2b45274f0df8e5e32e394db652 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Fri, 14 Jul 2023 15:10:37 +0200 Subject: [PATCH 3/5] Fix check around blocks to skip parsing --- src/main/java/org/commcare/data/xml/DataModelPullParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/commcare/data/xml/DataModelPullParser.java b/src/main/java/org/commcare/data/xml/DataModelPullParser.java index ee9f3307c1..7b2a1979d4 100644 --- a/src/main/java/org/commcare/data/xml/DataModelPullParser.java +++ b/src/main/java/org/commcare/data/xml/DataModelPullParser.java @@ -129,7 +129,7 @@ private void parseBlock(String root, LinkedHashSet parsers) t continue; } - if (blocksToSkipParsing != null && blocksToSkipParsing.equals(name)) { + if (blocksToSkipParsing != null && blocksToSkipParsing.contains(name)) { this.skipBlock(name); continue; } From 91a601df1c283c6f288ab925038d155ddcae6190 Mon Sep 17 00:00:00 2001 From: Ahmad Vazirna Date: Wed, 26 Jul 2023 17:51:21 +0200 Subject: [PATCH 4/5] Remove skip parsing logic --- .../org/commcare/data/xml/DataModelPullParser.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/commcare/data/xml/DataModelPullParser.java b/src/main/java/org/commcare/data/xml/DataModelPullParser.java index 7b2a1979d4..d76f26e0d2 100644 --- a/src/main/java/org/commcare/data/xml/DataModelPullParser.java +++ b/src/main/java/org/commcare/data/xml/DataModelPullParser.java @@ -10,7 +10,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.LinkedHashSet; -import java.util.List; import java.util.Vector; /** @@ -29,14 +28,13 @@ public class DataModelPullParser extends ElementParser { private final InputStream is; private final String requiredRootEnvelope = null; private final CommCareOTARestoreListener rListener; - private List blocksToSkipParsing; public DataModelPullParser(InputStream is, TransactionParserFactory factory) throws InvalidStructureException, IOException { this(is, factory, false); } public DataModelPullParser(InputStream is, TransactionParserFactory factory, CommCareOTARestoreListener rl) throws InvalidStructureException, IOException { - this(is, factory, false, false, rl, null); + this(is, factory, false, false, rl); } public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean deep) throws InvalidStructureException, IOException { @@ -44,10 +42,10 @@ public DataModelPullParser(InputStream is, TransactionParserFactory factory, boo } public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep) throws InvalidStructureException, IOException { - this(is, factory, failfast, deep, null, null); + this(is, factory, failfast, deep, null); } - public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep, CommCareOTARestoreListener rListener, List blocksToSkipParsing) throws InvalidStructureException, IOException { + public DataModelPullParser(InputStream is, TransactionParserFactory factory, boolean failfast, boolean deep, CommCareOTARestoreListener rListener) throws InvalidStructureException, IOException { super(ElementParser.instantiateParser(is)); this.is = is; this.failfast = failfast; @@ -55,7 +53,6 @@ public DataModelPullParser(InputStream is, TransactionParserFactory factory, boo errors = new Vector<>(); this.deep = deep; this.rListener = rListener; - this.blocksToSkipParsing = blocksToSkipParsing; } @Override @@ -129,11 +126,6 @@ private void parseBlock(String root, LinkedHashSet parsers) t continue; } - if (blocksToSkipParsing != null && blocksToSkipParsing.contains(name)) { - this.skipBlock(name); - continue; - } - TransactionParser transaction = factory.getParser(parser); if (transaction == null) { if (deep) { From 7055c5934d8473ce73b9b41ef2c6b2e8848b0439 Mon Sep 17 00:00:00 2001 From: Martin Riese Date: Fri, 22 Sep 2023 16:45:51 -0500 Subject: [PATCH 5/5] Clickable icon UI --- src/main/java/org/commcare/suite/model/Style.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/org/commcare/suite/model/Style.java b/src/main/java/org/commcare/suite/model/Style.java index 32fa390942..dea02e4a29 100644 --- a/src/main/java/org/commcare/suite/model/Style.java +++ b/src/main/java/org/commcare/suite/model/Style.java @@ -41,6 +41,7 @@ enum DisplayFormat { Graph, Phone, Markdown, + ClickableIcon, } public DisplayFormat getDisplayFormat() { @@ -94,6 +95,9 @@ private void setDisplayFormatFromString(String displayFormat){ case "markdown": setDisplayFormat(DisplayFormat.Markdown); break; + case "clickable-icon": + setDisplayFormat(DisplayFormat.ClickableIcon); + break; } }