Skip to content

Commit 55e9660

Browse files
committed
Merge branch 'release-2.5.9'
* release-2.5.9: (24 commits) Update versionCode and versionName Update translations from POEditor Add Russian translation from POEditor Fix incorrect hourly schedules for the second day day after schedule creation Allow hourly repetition schedules every 5 and 10 hours Update gradle plugin and kotlin versions to 3.2.1 and 1.2.71 CI: use api 28 image to avoid re-download of build-tools Add 5 min delay option ids.xml: Remove inner values Update Gradle plugin and Gradle versions to 3.2.0 and 4.6 build.gradle: Make global buildscript dependency versions ext variables build.gradle: Update Kotlin version to 1.2.70 build.gradle: substitute library version repetitions for ext variables build.gradle: Don't specify buildToolsVersion build: use 'implementation' instead of 'compile' for secure preference dependency PreferenceUtils: add missing apply() Initialize default preferences on application startup Add secure window preference EncryptionProvider: ditch GSON serialization for simpler base64 encoding Refactor security classes ...
2 parents 0bca126 + d342e78 commit 55e9660

30 files changed

+1041
-95
lines changed

.gitlab-ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
image: circleci/android:api-27-alpha
1+
image: circleci/android:api-28-alpha
22

33
before_script:
44
- export GRADLE_USER_HOME="$(pwd)/.gradle"

Calendula/build.gradle

+22-20
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,11 @@ task copyTestClasses(type: Copy) {
7373

7474
android {
7575
compileSdkVersion 27
76-
buildToolsVersion '27.0.3'
7776
defaultConfig {
78-
minSdkVersion 16
77+
minSdkVersion 18
7978
targetSdkVersion 26
80-
versionCode 39
81-
versionName "2.5.8"
79+
versionCode 40
80+
versionName "2.5.9"
8281
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
8382
applicationId "es.usc.citius.servando.calendula"
8483
multiDexEnabled true
@@ -174,12 +173,12 @@ dependencies {
174173

175174
// Memory leak debugging
176175
// 1.5.2 held back because of a bug with gradle 3.0
177-
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5.1'
178-
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
179-
alphaImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
180-
betaImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
181-
testImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
182-
androidTestImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.1'
176+
debugImplementation "com.squareup.leakcanary:leakcanary-android:$libVersions.leakcanary"
177+
releaseImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$libVersions.leakcanary"
178+
alphaImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$libVersions.leakcanary"
179+
betaImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$libVersions.leakcanary"
180+
testImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$libVersions.leakcanary"
181+
androidTestImplementation "com.squareup.leakcanary:leakcanary-android-no-op:$libVersions.leakcanary"
183182

184183
/********** SUPPORT **********/
185184
// Multidex support
@@ -210,18 +209,18 @@ dependencies {
210209
testImplementation 'junit:junit:4.12'
211210

212211
// Mockito
213-
testImplementation "org.mockito:mockito-inline:2.13.0"
214-
androidTestImplementation "org.mockito:mockito-android:2.13.0"
212+
testImplementation "org.mockito:mockito-inline:$libVersions.mockito"
213+
androidTestImplementation "org.mockito:mockito-android:$libVersions.mockito"
215214

216215
// Support testing
217-
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:3.0.2'
218-
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
219-
androidTestImplementation 'com.android.support.test:rules:1.0.2'
220-
androidTestImplementation 'com.android.support.test:runner:1.0.2'
216+
androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$libVersions.android.espresso"
217+
androidTestImplementation "com.android.support.test.espresso:espresso-core:$libVersions.android.espresso"
218+
androidTestImplementation "com.android.support.test:rules:$libVersions.android.test"
219+
androidTestImplementation "com.android.support.test:runner:$libVersions.android.test"
221220

222221
// Roboelectric
223-
testImplementation "org.robolectric:robolectric:3.8"
224-
testImplementation "org.robolectric:shadows-multidex:3.8"
222+
testImplementation "org.robolectric:robolectric:$libVersions.robolectric"
223+
testImplementation "org.robolectric:shadows-multidex:$libVersions.robolectric"
225224

226225
/********** UTILITIES **********/
227226
// HTML parsing
@@ -256,8 +255,8 @@ dependencies {
256255
implementation 'joda-time:joda-time:2.9.7'
257256

258257
// View/resource binding
259-
kapt 'com.jakewharton:butterknife-compiler:8.8.1'
260-
implementation 'com.jakewharton:butterknife:8.8.1'
258+
kapt "com.jakewharton:butterknife-compiler:$libVersions.butterknife"
259+
implementation "com.jakewharton:butterknife:$libVersions.butterknife"
261260

262261
/********** VIEWS AND VIEW UTILITIES **********/
263262
// About page with libraries
@@ -317,6 +316,9 @@ dependencies {
317316
implementation 'com.mikepenz:fastadapter-extensions:2.1.0@aar'
318317
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
319318

319+
// Secured preferences
320+
implementation 'online.devliving:securedpreferencestore:0.7.3'
321+
320322

321323
}
322324

Calendula/src/main/AndroidManifest.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
-->
1818

1919
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
20-
package="es.usc.citius.servando.calendula">
20+
package="es.usc.citius.servando.calendula"
21+
xmlns:tools="http://schemas.android.com/tools">
2122

2223
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2324
<uses-permission android:name="android.permission.VIBRATE"/>
@@ -37,6 +38,7 @@
3738
<application
3839
android:name=".CalendulaApp"
3940
android:allowBackup="true"
41+
tools:replace="allowBackup"
4042
android:icon="@mipmap/ic_launcher"
4143
android:label="@string/app_name"
4244
android:theme="@style/AppTheme">

Calendula/src/main/java/es/usc/citius/servando/calendula/CalendulaActivity.java

+14
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
import android.content.pm.PackageManager;
2626
import android.graphics.Color;
2727
import android.graphics.drawable.Drawable;
28+
import android.os.Bundle;
2829
import android.support.annotation.ColorInt;
2930
import android.support.annotation.Nullable;
3031
import android.support.v7.app.AppCompatActivity;
3132
import android.support.v7.widget.Toolbar;
3233
import android.view.MenuItem;
34+
import android.view.WindowManager;
3335

3436
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
3537
import com.mikepenz.iconics.IconicsDrawable;
@@ -45,6 +47,8 @@
4547
import es.usc.citius.servando.calendula.pinlock.UnlockStateManager;
4648
import es.usc.citius.servando.calendula.util.LogUtil;
4749
import es.usc.citius.servando.calendula.util.PermissionUtils;
50+
import es.usc.citius.servando.calendula.util.PreferenceKeys;
51+
import es.usc.citius.servando.calendula.util.PreferenceUtils;
4852
import es.usc.citius.servando.calendula.util.ScreenUtils;
4953

5054

@@ -65,6 +69,16 @@ public boolean onOptionsItemSelected(MenuItem item) {
6569
return super.onOptionsItemSelected(item);
6670
}
6771

72+
@Override
73+
protected void onCreate(@Nullable Bundle savedInstanceState) {
74+
super.onCreate(savedInstanceState);
75+
// set FLAG secure if the secure_window preference is enabled
76+
if (PreferenceUtils.getBoolean(PreferenceKeys.SECURE_WINDOW, false)) {
77+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
78+
WindowManager.LayoutParams.FLAG_SECURE);
79+
}
80+
}
81+
6882
protected CalendulaActivity setupToolbar(@Nullable String title, @ColorInt int color, @ColorInt int iconColor) {
6983
// set up the toolbar
7084
toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.toolbar);

Calendula/src/main/java/es/usc/citius/servando/calendula/activities/ConfirmActivity.java

+1
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
203203
}
204204

205205
public void showDelayDialog() {
206+
//TODO allow custom delay values
206207
final int[] values = this.getResources().getIntArray(R.array.delays_array_values);
207208
AlertDialog.Builder builder = new AlertDialog.Builder(this);
208209
builder.setTitle(R.string.notification_delay)

Calendula/src/main/java/es/usc/citius/servando/calendula/activities/ConfirmSchedulesActivity.java

+1-4
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,7 @@ public void createSchedule(final Schedule s, List<ScheduleItem> items, Medicine
193193
DailyAgenda.instance().addItem(patient, item, false);
194194
}
195195
} else {
196-
for (DateTime time : s.hourlyItemsToday()) {
197-
LocalTime timeToday = time.toLocalTime();
198-
DailyAgenda.instance().addItem(patient, s, timeToday);
199-
}
196+
DailyAgenda.instance().generateItemsForHourlySchedule(patient, s);
200197
}
201198
// save and fire event
202199
DB.schedules().saveAndFireEvent(s);

Calendula/src/main/java/es/usc/citius/servando/calendula/activities/ScheduleCreationActivity.java

+3-10
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@
4242
import com.j256.ormlite.misc.TransactionManager;
4343

4444
import org.greenrobot.eventbus.Subscribe;
45-
import org.joda.time.DateTime;
46-
import org.joda.time.LocalTime;
4745

4846
import java.util.ArrayList;
4947
import java.util.List;
@@ -125,10 +123,7 @@ public Object call() throws Exception {
125123
DailyAgenda.instance().addItem(patient, item, false);
126124
}
127125
} else {
128-
for (DateTime time : s.hourlyItemsToday()) {
129-
LocalTime timeToday = time.toLocalTime();
130-
DailyAgenda.instance().addItem(patient, s, timeToday);
131-
}
126+
DailyAgenda.instance().generateItemsForHourlySchedule(patient, s);
132127
}
133128
// save and fire event
134129
DB.schedules().saveAndFireEvent(s);
@@ -193,10 +188,7 @@ public Object call() throws Exception {
193188
}
194189
} else {
195190
DB.dailyScheduleItems().removeAllFrom(s);
196-
for (DateTime time : s.hourlyItemsToday()) {
197-
LocalTime timeToday = time.toLocalTime();
198-
DailyAgenda.instance().addItem(patient, s, timeToday);
199-
}
191+
DailyAgenda.instance().generateItemsForHourlySchedule(patient, s);
200192
}
201193

202194
// save and fire event
@@ -216,6 +208,7 @@ public Object call() throws Exception {
216208
}
217209
}
218210

211+
219212
public void saveSchedule() {
220213

221214
if (!validateBeforeSave()) {

Calendula/src/main/java/es/usc/citius/servando/calendula/fragments/ScheduleTimetableFragment.java

+11-15
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
package es.usc.citius.servando.calendula.fragments;
2020

21+
import android.annotation.SuppressLint;
2122
import android.app.AlertDialog;
2223
import android.app.DatePickerDialog;
2324
import android.content.ContextWrapper;
@@ -337,7 +338,7 @@ void setupStartEndDatePickers(View rootView) {
337338
@Override
338339
public Resources getResources() {
339340
Resources r = super.getResources();
340-
if(wrappedResources == null) {
341+
if (wrappedResources == null) {
341342
wrappedResources = new Resources(r.getAssets(), r.getDisplayMetrics(), r.getConfiguration()) {
342343
@NonNull
343344
@Override
@@ -546,27 +547,22 @@ void showIntervalPickerDIalog() {
546547
}
547548

548549
void showHourlyPickerDIalog() {
549-
/*NumberPickerBuilder npb =
550-
new NumberPickerBuilder().setDecimalVisibility(NumberPicker.INVISIBLE)
551-
.setMinNumber(1)
552-
.setMaxNumber(24)
553-
.setPlusMinusVisibility(NumberPicker.INVISIBLE)
554-
.setFragmentManager(getActivity().getSupportFragmentManager())
555-
.setTargetFragment(this)
556-
.setReference(REF_DIALOG_HOURLY_INTERVAL)
557-
.setStyleResId(R.style.BetterPickersDialogFragment_Calendula);
558-
npb.show();*/
559550

560551
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
561552
b.setTitle(getString(R.string.dialog_interval_title));
562-
final String[] types = {"2", "3", "4", "6", "8", "12"};
563-
b.setItems(types, new DialogInterface.OnClickListener() {
564553

554+
final int[] hourlyRepValues = getContext().getResources().getIntArray(R.array.hourly_repetition_values);
555+
// final String[] hourlyRepDisplay = getContext().getResources().getStringArray(R.array.hourly_repetition_display);
556+
557+
b.setItems(R.array.hourly_repetition_display, new DialogInterface.OnClickListener() {
558+
559+
@SuppressLint("SetTextI18n")
560+
//the int is put into a button with just the value, no need for localization
565561
@Override
566562
public void onClick(DialogInterface dialog, int which) {
567563
dialog.dismiss();
568-
int result = Integer.valueOf(types[which]);
569-
hourlyIntervalEditText.setText("" + result);
564+
final int result = hourlyRepValues[which];
565+
hourlyIntervalEditText.setText(Integer.toString(result));
570566
schedule.rule().setFrequency(Frequency.HOURLY);
571567
schedule.rule().setInterval(result);
572568
}

Calendula/src/main/java/es/usc/citius/servando/calendula/modules/modules/BaseModule.java

+8
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import android.app.PendingIntent;
2323
import android.content.Context;
2424
import android.content.Intent;
25+
import android.os.Build;
2526

2627
import com.evernote.android.job.JobManager;
2728
import com.mikepenz.iconics.Iconics;
@@ -47,6 +48,8 @@
4748
import es.usc.citius.servando.calendula.util.PreferenceKeys;
4849
import es.usc.citius.servando.calendula.util.PreferenceUtils;
4950
import es.usc.citius.servando.calendula.util.PresentationsTypeface;
51+
import es.usc.citius.servando.calendula.util.security.SecuredVault;
52+
import es.usc.citius.servando.calendula.util.security.SecurityProvider;
5053

5154

5255
public class BaseModule extends CalendulaModule {
@@ -95,6 +98,11 @@ public void setupUpdateDailyAgendaAlarm(Context ctx) {
9598
protected void onApplicationStartup(Context ctx) {
9699
PreferenceUtils.init(ctx);
97100

101+
// initialize secured vault
102+
if (!Build.FINGERPRINT.equals("robolectric")) {
103+
SecurityProvider.init(ctx);
104+
}
105+
98106
// initialize SQLite engine
99107
initializeDatabase(ctx);
100108

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Calendula - An assistant for personal medication management.
3+
* Copyright (C) 2016 CITIUS - USC
4+
*
5+
* Calendula is free software; you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation; either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this software. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
package es.usc.citius.servando.calendula.persistence.typeSerializers;
20+
21+
import com.j256.ormlite.field.FieldType;
22+
import com.j256.ormlite.field.SqlType;
23+
import com.j256.ormlite.field.types.BaseDataType;
24+
import com.j256.ormlite.support.DatabaseResults;
25+
26+
import java.nio.charset.Charset;
27+
import java.sql.SQLException;
28+
29+
import es.usc.citius.servando.calendula.util.security.SecurityProvider;
30+
31+
public class SecureStringPersister extends BaseDataType {
32+
33+
private static final SecureStringPersister singleton = new SecureStringPersister();
34+
private static Charset UTF8 = Charset.forName("UTF-8");
35+
36+
public SecureStringPersister() {
37+
super(SqlType.STRING, new Class<?>[]{String.class});
38+
}
39+
40+
public static SecureStringPersister getSingleton() {
41+
return singleton;
42+
}
43+
44+
@Override
45+
public Object parseDefaultString(FieldType fieldType, String defaultStr) throws SQLException {
46+
return defaultStr;
47+
}
48+
49+
@Override
50+
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
51+
return results.getString(columnPos);
52+
}
53+
54+
@Override
55+
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) throws SQLException {
56+
if (sqlArg == null) {
57+
return null;
58+
}
59+
if (((String) sqlArg).isEmpty()) {
60+
return "";
61+
}
62+
return SecurityProvider.getEncryptionProvider().decrypt((String) sqlArg);
63+
}
64+
65+
@Override
66+
public Object javaToSqlArg(FieldType fieldType, Object javaObject) throws SQLException {
67+
if (javaObject == null) {
68+
return null;
69+
}
70+
if (((String) javaObject).isEmpty()) {
71+
return "";
72+
}
73+
return SecurityProvider.getEncryptionProvider().encrypt((String) javaObject);
74+
}
75+
}

0 commit comments

Comments
 (0)