diff --git a/.idea/dictionaries/mh.xml b/.idea/dictionaries/mh.xml
index 92d80a7..d711466 100644
--- a/.idea/dictionaries/mh.xml
+++ b/.idea/dictionaries/mh.xml
@@ -5,6 +5,7 @@
ciphertext
coronawarncompanion
coronawarndetails
+ covid
datapoint
diagnosiskeys
encryptor
@@ -12,6 +13,7 @@
gmsreadout
hkdf
hmac
+ huebler
protos
rpik
rpis
@@ -21,4 +23,4 @@
vals
-
+
\ No newline at end of file
diff --git a/app/src/main/java/org/tosl/coronawarncompanion/matchentries/MatchesRecyclerViewAdapter.java b/app/src/main/java/org/tosl/coronawarncompanion/matchentries/MatchesRecyclerViewAdapter.java
index 34a088d..bc0e8d6 100644
--- a/app/src/main/java/org/tosl/coronawarncompanion/matchentries/MatchesRecyclerViewAdapter.java
+++ b/app/src/main/java/org/tosl/coronawarncompanion/matchentries/MatchesRecyclerViewAdapter.java
@@ -66,12 +66,12 @@
public class MatchesRecyclerViewAdapter extends RecyclerView.Adapter {
private static final String TAG = "CRRecyclerViewAdapter";
- private final int gridColor = Color.parseColor("#E0E0E0");
- private final int redColor = Color.parseColor("#FF0000");
- private final int orangeColor = Color.parseColor("#FFA500");
- private final int yellowColor = Color.parseColor("#FFFF00");
- private final int greenColor = Color.parseColor("#00FF00");
- private final int blackColor = Color.parseColor("#000000");
+ private static final int gridColor = Color.parseColor("#E0E0E0");
+ private static final int redColor = Color.parseColor("#FF0000");
+ private static final int orangeColor = Color.parseColor("#FFA500");
+ private static final int yellowColor = Color.parseColor("#FFFF00");
+ private static final int greenColor = Color.parseColor("#00FF00");
+ private static final int blackColor = Color.parseColor("#000000");
private final ArrayList> mValues;
private CWCApplication mApp;
@@ -128,7 +128,7 @@ public void onBindViewHolder(final ViewHolder holder, int position) {
hasReportType = true;
}
- MatchEntryDetails matchEntryDetails = getMatchEntryDetails(list);
+ MatchEntryDetails matchEntryDetails = getMatchEntryDetails(list, mApp.getTimeZoneOffsetSeconds());
int minTimestampLocalTZDay0 = matchEntryDetails.minTimestampLocalTZDay0;
int maxTimestampLocalTZDay0 = matchEntryDetails.maxTimestampLocalTZDay0;
@@ -168,7 +168,7 @@ public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mChartView.getLineData().getDataSetByIndex(1).setVisible(this.showAllScans);
}
- public class MatchEntryDetails {
+ public static class MatchEntryDetails {
public ArrayList dataPoints;
public ArrayList dotColors;
public ArrayList dataPointsMinAttenuation;
@@ -182,7 +182,8 @@ public MatchEntryDetails() {
}
}
- private MatchEntryDetails getMatchEntryDetails(ArrayList list) {
+ public static MatchEntryDetails getMatchEntryDetails(ArrayList list,
+ int timeZoneOffset) {
// Threshold value for break detection:
final int pauseThresholdSeconds = 10;
@@ -210,7 +211,6 @@ private MatchEntryDetails getMatchEntryDetails(ArrayList lis
//Log.d(TAG, "RSSI: "+rssi+" dBm");
int attenuation = txPower - rssi;
//Log.d(TAG, "Attenuation: "+attenuation+" dB");
- int timeZoneOffset = mApp.getTimeZoneOffsetSeconds();
int timestampLocalTZ = scanRecord.getTimestamp() + timeZoneOffset;
// reduce to "day0", to improve resolution within the float x value:
int timestampLocalTZDay0 = timestampLocalTZ % (24*3600);
@@ -318,7 +318,7 @@ private MatchEntryDetails getMatchEntryDetails(ArrayList lis
return result;
}
- private int getDotColorForAttenuation(int attenuation) {
+ private static int getDotColorForAttenuation(int attenuation) {
if (attenuation < 55) {
return redColor;
} else if (attenuation <= 63) {
diff --git a/app/src/test/java/org/tosl/coronawarncompanion/ExampleUnitTest.java b/app/src/test/java/org/tosl/coronawarncompanion/ExampleUnitTest.java
deleted file mode 100644
index f9a9d4a..0000000
--- a/app/src/test/java/org/tosl/coronawarncompanion/ExampleUnitTest.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.tosl.coronawarncompanion;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() {
- assertEquals(4, 2 + 2);
- }
-}
diff --git a/app/src/test/java/org/tosl/coronawarncompanion/MatchesRecyclerViewAdapterUnitTest.java b/app/src/test/java/org/tosl/coronawarncompanion/MatchesRecyclerViewAdapterUnitTest.java
new file mode 100644
index 0000000..c4b8813
--- /dev/null
+++ b/app/src/test/java/org/tosl/coronawarncompanion/MatchesRecyclerViewAdapterUnitTest.java
@@ -0,0 +1,107 @@
+package org.tosl.coronawarncompanion;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Test;
+import org.tosl.coronawarncompanion.diagnosiskeys.DiagnosisKeysProtos;
+import org.tosl.coronawarncompanion.gmsreadout.ContactRecordsProtos;
+import org.tosl.coronawarncompanion.matchentries.MatchesRecyclerViewAdapter;
+import org.tosl.coronawarncompanion.matcher.Matcher;
+
+import java.util.ArrayList;
+
+import static org.junit.Assert.*;
+import static org.tosl.coronawarncompanion.tools.Utils.getENINFromSeconds;
+
+/**
+ * Local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class MatchesRecyclerViewAdapterUnitTest {
+
+ @Test
+ public void getMatchEntryDetails_isCorrect() {
+
+ // create content
+
+ final int daysSinceEpoch = 18000;
+ final int numGroups = 10;
+ final int numEntriesPerGroup = 20;
+
+ DiagnosisKeysProtos.TemporaryExposureKeyExport.Builder dkImportBuilder =
+ DiagnosisKeysProtos.TemporaryExposureKeyExport.newBuilder();
+ byte[] keyBytes = new byte[] {(byte) 0, (byte) 1, (byte) 2, (byte) 3,
+ (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9,
+ (byte) 10, (byte) 11, (byte) 12, (byte) 13, (byte) 14, (byte) 15};
+ @SuppressWarnings("deprecation") DiagnosisKeysProtos.TemporaryExposureKey.Builder dkBuilder =
+ DiagnosisKeysProtos.TemporaryExposureKey.newBuilder()
+ .setKeyData(ByteString.copyFrom(keyBytes))
+ .setTransmissionRiskLevel(8)
+ .setRollingStartIntervalNumber(getENINFromSeconds(daysSinceEpoch*24*3600))
+ .setRollingPeriod(144)
+ .setReportType(DiagnosisKeysProtos.TemporaryExposureKey.ReportType.CONFIRMED_TEST);
+ dkImportBuilder.addKeys(dkBuilder.build());
+ DiagnosisKeysProtos.TemporaryExposureKeyExport dkImport = dkImportBuilder.build();
+
+ byte[] aemBytes = new byte[] {(byte) 0, (byte) 1, (byte) 2, (byte) 3};
+ byte[] aemXorBytes = new byte[] {(byte) 0, (byte) 1, (byte) 2, (byte) 3};
+
+ int TimestampLocalTZ = daysSinceEpoch * 24*3600;
+
+ ArrayList list = new ArrayList<>();
+ for (int groupPos = 0; groupPos < numGroups; groupPos++) {
+ for (int entryPos = 0; entryPos < numEntriesPerGroup; entryPos++) {
+ int startTimestampLocalTZ = TimestampLocalTZ;
+ TimestampLocalTZ += 3;
+ int endTimestampLocalTZ = TimestampLocalTZ;
+ TimestampLocalTZ += 3;
+
+ DiagnosisKeysProtos.TemporaryExposureKey dk = dkImport.getKeys(0);
+ byte[] rpiBytes = {(byte) 0, (byte) 1, (byte) 2, (byte) 3,
+ (byte) 4, (byte) 5, (byte) 6, (byte) 7, (byte) 8, (byte) 9,
+ (byte) 10, (byte) 11, (byte) 12, (byte) 13, (byte) 14, (byte) 15};
+
+ ContactRecordsProtos.ContactRecords.Builder contactRecordsBuilder1 =
+ ContactRecordsProtos.ContactRecords.newBuilder()
+ .addRecord(ContactRecordsProtos.ScanRecord.newBuilder()
+ .setTimestamp(startTimestampLocalTZ)
+ .setRssi(-50)
+ .setAem(ByteString.copyFrom(aemBytes))
+ );
+ ContactRecordsProtos.ContactRecords contactRecords1 = contactRecordsBuilder1.build();
+ Matcher.MatchEntry entry1 = new Matcher.MatchEntry(dk, rpiBytes, contactRecords1,
+ startTimestampLocalTZ, endTimestampLocalTZ, aemXorBytes);
+ list.add(entry1);
+
+ ContactRecordsProtos.ContactRecords.Builder contactRecordsBuilder2 =
+ ContactRecordsProtos.ContactRecords.newBuilder()
+ .addRecord(ContactRecordsProtos.ScanRecord.newBuilder()
+ .setTimestamp(startTimestampLocalTZ+1)
+ .setRssi(-50)
+ .setAem(ByteString.copyFrom(aemBytes))
+ );
+ ContactRecordsProtos.ContactRecords contactRecords2 = contactRecordsBuilder2.build();
+ Matcher.MatchEntry entry2 = new Matcher.MatchEntry(dk, rpiBytes, contactRecords2,
+ startTimestampLocalTZ, endTimestampLocalTZ, aemXorBytes);
+ list.add(entry2);
+ }
+ TimestampLocalTZ += 4*60;
+ }
+
+ // assert that the list contains the correct number of items
+ assertEquals(numGroups*numEntriesPerGroup*2, list.size());
+
+ // run getMatchEntryDetails()
+ MatchesRecyclerViewAdapter.MatchEntryDetails matchEntryDetails =
+ MatchesRecyclerViewAdapter.getMatchEntryDetails(list,0);
+
+ // assert that no entry was lost in the process
+ assertEquals(list.size(),
+ matchEntryDetails.dataPoints.size()+matchEntryDetails.dataPointsMinAttenuation.size());
+ assertEquals(list.size(),
+ matchEntryDetails.dotColors.size()+matchEntryDetails.dotColorsMinAttenuation.size());
+ // assert that there's a color for each dataPoint
+ assertEquals(matchEntryDetails.dataPoints.size(), matchEntryDetails.dotColors.size());
+ }
+}