Skip to content

Commit

Permalink
Merge pull request #1252 from dhis2/master-dev
Browse files Browse the repository at this point in the history
fix: [MASTER-DEV] Version 1.1.1
  • Loading branch information
vgarciabnz authored May 6, 2020
2 parents c22cf59 + 4c69cff commit 4a268ad
Show file tree
Hide file tree
Showing 19 changed files with 96 additions and 34 deletions.
4 changes: 2 additions & 2 deletions core/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ ext {
buildToolsVersion: "28.0.3",
minSdkVersion : 19,
targetSdkVersion : 28,
versionCode : 210,
versionName : "1.1.0"
versionCode : 211,
versionName : "1.1.1"
]

libraries = [
Expand Down
4 changes: 2 additions & 2 deletions core/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
# Properties which are consumed by plugins/gradle-mvn-push.gradle plugin.
# They are used for publishing artifact to snapshot repository.

VERSION_NAME=1.1.0
VERSION_CODE=210
VERSION_NAME=1.1.1
VERSION_CODE=211

GROUP=org.hisp.dhis

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.hisp.dhis.android.core.arch.storage.internal.InMemoryUnsecureStore;
import org.hisp.dhis.android.core.arch.storage.internal.InsecureStore;
import org.hisp.dhis.android.core.arch.storage.internal.SecureStore;
import org.hisp.dhis.android.core.maintenance.D2Error;

import java.util.Collections;

Expand All @@ -51,7 +52,7 @@ public static D2 forNewDatabase() {
return forNewDatabaseInternal(new InMemorySecureStore(), new InMemoryUnsecureStore());
}

public static D2 forNewDatabaseWithAndroidSecureStore() {
public static D2 forNewDatabaseWithAndroidSecureStore() throws D2Error {
Context context = InstrumentationRegistry.getTargetContext().getApplicationContext();
return forNewDatabaseInternal(new AndroidSecureStore(context), new AndroidInsecureStore(context));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

import androidx.test.InstrumentationRegistry;

import org.hisp.dhis.android.core.maintenance.D2Error;
import org.hisp.dhis.android.core.utils.runner.D2JunitRunner;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -43,7 +44,7 @@ public class CredentialsSecureStorageMockIntegrationShould {
private ObjectKeyValueStore<Credentials> credentialsSecureStore;

@Before
public void setUp() {
public void setUp() throws D2Error {
credentialsSecureStore =
new CredentialsSecureStoreImpl(
new AndroidSecureStore(InstrumentationRegistry.getContext().getApplicationContext()));
Expand Down
2 changes: 2 additions & 0 deletions core/src/main/assets/migrations/72.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Related to ANDROSDK-1138
UPDATE D2Error SET errorComponent = 'SDK' WHERE errorComponent IS NULL;
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

class BaseDatabaseOpenHelper {

static final int VERSION = 71;
static final int VERSION = 72;

private final AssetManager assetManager;
private final int targetVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class DatabaseMigrationExecutor {
private final DatabaseAdapter databaseAdapter;
private final DatabaseMigrationParser parser;

private static final int SNAPSHOT_VERSION = 71;
private static final int SNAPSHOT_VERSION = 72;

DatabaseMigrationExecutor(DatabaseAdapter databaseAdapter, AssetManager assetManager) {
this.databaseAdapter = databaseAdapter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ParentDatabaseAdapter implements DatabaseAdapter {

private DatabaseAdapter getAdapter() {
if (adapter == null) {
throw new RuntimeException("Database not yet created. Please login first.");
throw new RuntimeException("Please login to access the database.");
} else {
return adapter;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@

import androidx.annotation.NonNull;

import org.hisp.dhis.android.core.maintenance.D2Error;
import org.hisp.dhis.android.core.maintenance.D2ErrorCode;
import org.hisp.dhis.android.core.maintenance.D2ErrorComponent;

import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.Charset;
Expand All @@ -55,6 +59,7 @@
import java.security.cert.CertificateException;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.crypto.BadPaddingException;
Expand All @@ -77,7 +82,7 @@ public final class AndroidSecureStore implements SecureStore {

private final SharedPreferences preferences;

public AndroidSecureStore(Context context) {
public AndroidSecureStore(Context context) throws D2Error {
preferences = context.getSharedPreferences(PREFERENCES_FILE, Context.MODE_PRIVATE);

KeyStore ks;
Expand All @@ -95,7 +100,7 @@ public AndroidSecureStore(Context context) {
}
} catch (KeyStoreException | CertificateException | IOException |
NoSuchAlgorithmException | UnrecoverableKeyException ex) {
return;
throw keyStoreError(ex, D2ErrorCode.CANT_ACCESS_KEYSTORE);
}

// Create a start and end time, for the validity range of the key pair that's about to be
Expand Down Expand Up @@ -126,24 +131,24 @@ public AndroidSecureStore(Context context) {
kpGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException | NoSuchProviderException e) {
deleteKeyStoreEntry(ks, ALIAS);
throw new RuntimeException("Couldn't initialize AndroidSecureStore");
throw keyStoreError(e, D2ErrorCode.CANT_INSTANTIATE_KEYSTORE);
}
}

public void setData(@NonNull String key, @NonNull String data) {
KeyStore ks = null;
try {
ks = KeyStore.getInstance(KEYSTORE_PROVIDER_ANDROID_KEYSTORE);

ks.load(null);

if (ks.getCertificate(ALIAS) == null) {
return;
throw new RuntimeException("Couldn't find certificate for key: " + key);
}

PublicKey publicKey = ks.getCertificate(ALIAS).getPublicKey();

if (publicKey == null) {
return;
throw new RuntimeException("Couldn't find publicKey for key: " + key);
}

String value = encrypt(publicKey, data.getBytes(CHARSET));
Expand All @@ -155,7 +160,7 @@ public void setData(@NonNull String key, @NonNull String data) {
| IllegalBlockSizeException | BadPaddingException | KeyStoreException |
CertificateException | IOException e) {
deleteKeyStoreEntry(ks, ALIAS);
throw new RuntimeException("Couldn't store value in AndroidSecureStore for key: " + key);
throw new RuntimeException("Couldn't store value in AndroidSecureStore for key: " + key, e);
}
}

Expand All @@ -173,7 +178,7 @@ public String getData(@NonNull String key) {
| UnrecoverableEntryException | InvalidKeyException | NoSuchPaddingException
| IllegalBlockSizeException | BadPaddingException e) {
deleteKeyStoreEntry(ks, ALIAS);
throw new RuntimeException("Couldn't get value from AndroidSecureStore for key: " + key);
throw new RuntimeException("Couldn't get value from AndroidSecureStore for key: " + key, e);
}
}

Expand Down Expand Up @@ -211,4 +216,14 @@ private void deleteKeyStoreEntry(KeyStore ks, String entry) {
Log.w("SECURE_STORE", "Cannot deleted entry " + entry);
}
}

private D2Error keyStoreError(Exception ex, D2ErrorCode d2ErrorCode) {
return D2Error.builder()
.errorComponent(D2ErrorComponent.SDK)
.errorCode(d2ErrorCode)
.errorDescription(ex.getMessage())
.originalException(ex)
.created(new Date())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore;
import org.hisp.dhis.android.core.arch.db.stores.internal.ObjectStore;
import org.hisp.dhis.android.core.arch.handlers.internal.HandleAction;
import org.hisp.dhis.android.core.arch.helpers.internal.EnumHelper;
import org.hisp.dhis.android.core.common.DataColumns;
import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.common.internal.DataStatePropagator;
Expand Down Expand Up @@ -140,12 +141,14 @@ private void handleEventImportSummaries(EnrollmentImportSummary enrollmentImport
}

private void handleNoteImportSummary(String enrollmentUid, State state) {
State newNoteState = state.equals(State.SYNCED) ? State.SYNCED : State.TO_POST;
String whereClause = new WhereClauseBuilder()
.appendKeyStringValue(DataColumns.STATE, State.TO_POST)
.appendInKeyStringValues(
DataColumns.STATE, EnumHelper.asStringList(State.uploadableStatesIncludingError()))
.appendKeyStringValue(NoteTableInfo.Columns.ENROLLMENT, enrollmentUid).build();
List<Note> notes = noteStore.selectWhere(whereClause);
for (Note note : notes) {
noteStore.update(note.toBuilder().state(state).build());
noteStore.update(note.toBuilder().state(newNoteState).build());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore;
import org.hisp.dhis.android.core.arch.db.stores.internal.ObjectStore;
import org.hisp.dhis.android.core.arch.handlers.internal.HandleAction;
import org.hisp.dhis.android.core.arch.helpers.internal.EnumHelper;
import org.hisp.dhis.android.core.common.DataColumns;
import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.enrollment.internal.EnrollmentStore;
Expand Down Expand Up @@ -167,12 +168,14 @@ private void deleteEventConflicts(String eventUid) {
}

private void handleNoteImportSummary(String eventUid, State state) {
State newNoteState = state.equals(State.SYNCED) ? State.SYNCED : State.TO_POST;
String whereClause = new WhereClauseBuilder()
.appendKeyStringValue(DataColumns.STATE, State.TO_POST)
.appendInKeyStringValues(
DataColumns.STATE, EnumHelper.asStringList(State.uploadableStatesIncludingError()))
.appendKeyStringValue(NoteTableInfo.Columns.EVENT, eventUid).build();
List<Note> notes = noteStore.selectWhere(whereClause);
for (Note note : notes) {
noteStore.update(note.toBuilder().state(state).build());
noteStore.update(note.toBuilder().state(newNoteState).build());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,22 @@

package org.hisp.dhis.android.core.event.internal;

import androidx.annotation.NonNull;

import org.hisp.dhis.android.core.arch.api.executors.internal.APICallExecutor;
import org.hisp.dhis.android.core.arch.call.D2Progress;
import org.hisp.dhis.android.core.arch.call.internal.D2ProgressManager;
import org.hisp.dhis.android.core.arch.db.querybuilders.internal.WhereClauseBuilder;
import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore;
import org.hisp.dhis.android.core.arch.helpers.UidsHelper;
import org.hisp.dhis.android.core.arch.helpers.internal.EnumHelper;
import org.hisp.dhis.android.core.common.DataColumns;
import org.hisp.dhis.android.core.common.State;
import org.hisp.dhis.android.core.event.Event;
import org.hisp.dhis.android.core.imports.TrackerImportConflict;
import org.hisp.dhis.android.core.imports.internal.EventWebResponse;
import org.hisp.dhis.android.core.note.Note;
import org.hisp.dhis.android.core.note.NoteTableInfo;
import org.hisp.dhis.android.core.systeminfo.DHISVersionManager;
import org.hisp.dhis.android.core.systeminfo.SystemInfo;
import org.hisp.dhis.android.core.systeminfo.internal.SystemInfoModuleDownloader;
Expand All @@ -49,7 +57,6 @@

import javax.inject.Inject;

import androidx.annotation.NonNull;
import dagger.Reusable;
import io.reactivex.Observable;

Expand All @@ -62,6 +69,7 @@ public final class EventPostCall {
// adapter and stores
private final EventStore eventStore;
private final TrackedEntityDataValueStore trackedEntityDataValueStore;
private final IdentifiableObjectStore<Note> noteStore;
private final EventImportHandler eventImportHandler;

private final APICallExecutor apiCallExecutor;
Expand All @@ -72,13 +80,15 @@ public final class EventPostCall {
@NonNull EventService eventService,
@NonNull EventStore eventStore,
@NonNull TrackedEntityDataValueStore trackedEntityDataValueStore,
@NonNull IdentifiableObjectStore<Note> noteStore,
@NonNull APICallExecutor apiCallExecutor,
@NonNull EventImportHandler eventImportHandler,
@NonNull SystemInfoModuleDownloader systemInfoDownloader) {
this.versionManager = versionManager;
this.eventService = eventService;
this.eventStore = eventStore;
this.trackedEntityDataValueStore = trackedEntityDataValueStore;
this.noteStore = noteStore;
this.apiCallExecutor = apiCallExecutor;
this.eventImportHandler = eventImportHandler;
this.systemInfoDownloader = systemInfoDownloader;
Expand Down Expand Up @@ -120,25 +130,46 @@ List<Event> queryDataToSync(List<Event> filteredEvents) {
trackedEntityDataValueStore.querySingleEventsTrackedEntityDataValues();

List<Event> events = filteredEvents == null ? eventStore.querySingleEventsToPost() : filteredEvents;
List<Event> eventRecreated = new ArrayList<>();
List<Note> notes = queryNotesToSync();

List<Event> eventRecreated = new ArrayList<>();
for (Event event : events) {
List<TrackedEntityDataValue> dataValuesForEvent = dataValueMap.get(event.uid());
List<Note> eventNotes = getEventNotes(notes, event.uid());

Event.Builder eventBuilder = event.toBuilder()
.trackedEntityDataValues(dataValuesForEvent)
.notes(eventNotes);
if (versionManager.is2_30()) {
eventRecreated.add(event.toBuilder()
.trackedEntityDataValues(dataValuesForEvent)
.geometry(null)
.build());
} else {
eventRecreated.add(event.toBuilder().trackedEntityDataValues(dataValuesForEvent).build());
eventBuilder.geometry(null);
}
eventRecreated.add(eventBuilder.build());
}

markPartitionsAsUploading(eventRecreated);

return eventRecreated;
}

private List<Note> queryNotesToSync() {
String whereNotesClause = new WhereClauseBuilder()
.appendInKeyStringValues(
DataColumns.STATE, EnumHelper.asStringList(State.uploadableStatesIncludingError()))
.appendKeyStringValue(NoteTableInfo.Columns.NOTE_TYPE, Note.NoteType.EVENT_NOTE)
.build();
return noteStore.selectWhere(whereNotesClause);
}

private List<Note> getEventNotes(List<Note> allNotes, String eventUid) {
List<Note> eventNotes = new ArrayList<>();
for (Note note : allNotes) {
if (eventUid.equals(note.event())) {
eventNotes.add(note);
}
}
return eventNotes;
}

private void handleWebResponse(EventWebResponse webResponse) {
if (webResponse == null || webResponse.response() == null) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ public enum D2ErrorCode {
APP_NAME_NOT_SET,
APP_VERSION_NOT_SET,
BAD_CREDENTIALS,
CANT_ACCESS_KEYSTORE,
CANT_CREATE_EXISTING_OBJECT,
CANT_DELETE_NON_EXISTING_OBJECT,
CANT_INSTANTIATE_KEYSTORE,
COULD_NOT_RESERVE_VALUE_ON_SERVER,
FILE_NOT_FOUND,
FAIL_RESIZING_IMAGE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.hisp.dhis.android.core.arch.db.stores.internal.IdentifiableObjectStore;
import org.hisp.dhis.android.core.arch.helpers.CollectionsHelper;
import org.hisp.dhis.android.core.arch.helpers.UidsHelper;
import org.hisp.dhis.android.core.arch.helpers.internal.EnumHelper;
import org.hisp.dhis.android.core.common.CoreColumns;
import org.hisp.dhis.android.core.common.DataColumns;
import org.hisp.dhis.android.core.common.State;
Expand Down Expand Up @@ -197,7 +198,9 @@ List<List<TrackedEntityInstance>> getPartitionsToSync(List<TrackedEntityInstance
Map<String, List<TrackedEntityAttributeValue>> attributeValueMap =
trackedEntityAttributeValueStore.queryTrackedEntityAttributeValueToPost();
String whereNotesClause = new WhereClauseBuilder()
.appendKeyStringValue(DataColumns.STATE, State.TO_POST).build();
.appendKeyStringValue(
DataColumns.STATE, EnumHelper.asStringList(State.uploadableStatesIncludingError()))
.build();
List<Note> notes = noteStore.selectWhere(whereNotesClause);

List<TrackedEntityInstance> targetTrackedEntityInstances;
Expand Down
1 change: 1 addition & 0 deletions docs/content/developer/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Compatibility table between DHIS2 Android SDK library, DHIS2 core and Android SD
| 1.0.2 | 2.29 -> 2.33 | 19 - 28 |
| 1.0.3 | 2.29 -> 2.33 | 19 - 28 |
| 1.1.0 | 2.29 -> 2.34 | 19 - 28 |
| 1.1.1 | 2.29 -> 2.34 | 19 - 28 |
2 changes: 1 addition & 1 deletion docs/content/developer/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ if changed, will encrypt or decrypt the current database without data loss.

### Encryption performance
- Database size: the database size is approximately the same, regardless of being encrypted or not.
- Speed: reads and writes are on average 25% slower using an encrypted database.
- Speed: reads and writes are on average 5 to 10% slower using an encrypted database.
2 changes: 1 addition & 1 deletion docs/content/developer/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Include dependency in build.gradle.

```gradle
dependencies {
implementation "org.hisp.dhis:android-core:1.1.0"
implementation "org.hisp.dhis:android-core:1.1.1"
...
}
```
Expand Down
Loading

0 comments on commit 4a268ad

Please sign in to comment.