Skip to content

Commit

Permalink
Merge pull request #2 from Emotional-Wellbeing/master
Browse files Browse the repository at this point in the history
Align master and dev branches
  • Loading branch information
VicDominguez authored May 5, 2024
2 parents 5a0d09a + 5e62029 commit b588d98
Show file tree
Hide file tree
Showing 103 changed files with 17,221 additions and 1,978 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ on:
- '!*alpha*'
- '!*beta*'
- '!*rc*'
permissions:
contents: write
# jobs are run in parallel on different machines
# all steps run in series
jobs:
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
![master workflow](https://github.com/VicDominguez/SBE-App/actions/workflows/master.yml/badge.svg)
<!--[dev workflow](https://github.com/VicDominguez/SBE-pruebas/actions/workflows/master.yml/badge.svg)
-->
![master workflow](https://github.com/Emotional-Wellbeing/App/actions/workflows/master.yml/badge.svg)
![dev workflow](https://github.com/Emotional-Wellbeing/App/actions/workflows/dev.yml/badge.svg)


# SBE - App
## Español
Expand All @@ -13,4 +13,4 @@ Este trabajo se ha realizado en la Escuela Técnica Superior de Ingeniería de S
### General information
This repository contains the mobile app of Final Master Project *System for Emotional Wellbeing*, made by Victor Manuel Dominguez Rivas; belonging to *Master Degree in Distributed and Embedded Systems Software*.

This project has been realised at the School of Computer Systems Engineering (ETSISI), Polytechnic University of Madrid.
This project has been realised at the School of Computer Systems Engineering (ETSISI), Polytechnic University of Madrid.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ dependencies {
implementation "androidx.room:room-ktx:$room_version"
ksp "androidx.room:room-compiler:$room_version"

implementation "net.zetetic:android-database-sqlcipher:$sql_cipher_version"

// Live data
implementation "androidx.compose.runtime:runtime-livedata:$compose_ui_version"

Expand Down
27 changes: 8 additions & 19 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,23 @@

<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.INTERNET"/>

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.health.READ_SLEEP"/>
<uses-permission android:name="android.permission.health.WRITE_SLEEP"/>

<uses-permission android:name="android.permission.health.READ_HEART_RATE"/>
<uses-permission android:name="android.permission.health.WRITE_HEART_RATE"/>

<uses-permission android:name="android.permission.health.READ_STEPS"/>
<uses-permission android:name="android.permission.health.WRITE_STEPS"/>

<uses-permission android:name="android.permission.health.READ_DISTANCE"/>
<uses-permission android:name="android.permission.health.WRITE_DISTANCE"/>

<uses-permission android:name="android.permission.health.READ_TOTAL_CALORIES_BURNED"/>
<uses-permission android:name="android.permission.health.WRITE_TOTAL_CALORIES_BURNED"/>

<uses-permission android:name="android.permission.health.READ_ELEVATION_GAINED"/>
<uses-permission android:name="android.permission.health.WRITE_ELEVATION_GAINED"/>

<uses-permission android:name="android.permission.health.READ_WEIGHT"/>
<uses-permission android:name="android.permission.health.WRITE_WEIGHT"/>

<uses-permission android:name="android.permission.health.READ_FLOORS_CLIMBED"/>
<uses-permission android:name="android.permission.health.WRITE_FLOORS_CLIMBED"/>

<uses-permission android:name="android.permission.health.READ_EXERCISE"/>
<uses-permission android:name="android.permission.health.WRITE_EXERCISE"/>


<!-- TODO Remove usesCleartextTraffic in final version -->

<application
Expand Down
12 changes: 0 additions & 12 deletions app/src/main/java/es/upm/bienestaremocional/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import dagger.hilt.android.AndroidEntryPoint
import es.upm.bienestaremocional.data.info.AppInfo
import es.upm.bienestaremocional.data.settings.AppSettings
import es.upm.bienestaremocional.data.settings.ThemeMode
import es.upm.bienestaremocional.data.worker.WorkAdministrator
import es.upm.bienestaremocional.domain.repository.LastUploadRepository
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
Expand All @@ -21,15 +18,6 @@ class MainActivity : ComponentActivity() {
@Inject
lateinit var appSettings: AppSettings

@Inject
lateinit var appInfo: AppInfo

@Inject
lateinit var scheduler: WorkAdministrator

@Inject
lateinit var lastUploadRepository: LastUploadRepository

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import es.upm.bienestaremocional.data.settings.ThemeMode
import es.upm.bienestaremocional.ui.screens.NavGraphs
import es.upm.bienestaremocional.ui.theme.BienestarEmocionalTheme


@Composable
fun BienestarEmocionalApp(
darkTheme: ThemeMode,
dynamicColors: Boolean
dynamicColors: Boolean,
) {
BienestarEmocionalTheme(darkTheme = darkTheme.themeIsDark(), dynamicColors = dynamicColors)
{
DestinationsNavHost(navGraph = NavGraphs.root)
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import java.time.Instant

suspend fun firstTimeExecution(
notificationManager: NotificationManager,
scheduler: WorkAdministrator,
lastUploadRepository: LastUploadRepository
workAdministrator: WorkAdministrator,
lastUploadRepository: LastUploadRepository,
) {
//build channel notifications
for (appChannel in NotificationChannels.values())
Expand All @@ -21,10 +21,13 @@ suspend fun firstTimeExecution(
channel = appChannel
)
//schedule notifications
scheduler.scheduleDailyMorningNotificationWorker()
scheduler.scheduleDailyNightNotificationWorker()
scheduler.scheduleOneOffNotificationWorker()
scheduler.scheduleUploadWorker()
workAdministrator.scheduleDailyMorningNotificationWorker()
workAdministrator.scheduleDailyNightNotificationWorker()
workAdministrator.scheduleOneOffNotificationWorker()
workAdministrator.scheduleUploadWorker()
workAdministrator.scheduleUploadPhoneDataWorker()
workAdministrator.scheduleUploadTrafficDataWorker()


//insert values in last upload table
val now = obtainTimestamp(Instant.now(), null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package es.upm.bienestaremocional.data

import androidx.work.BackoffPolicy
import androidx.work.WorkRequest

object RemoteConstants {
const val SERVER_URL = "http://nispero.etsisi.upm.es:5000"
val BACKOFF_CRITERIA = BackoffPolicy.EXPONENTIAL
const val BACKOFF_INITIAL_DELAY = WorkRequest.DEFAULT_BACKOFF_DELAY_MILLIS
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ object CreditContent {
descriptionResource = R.string.credit_logo2_description,
importantContribution = false
),
Credit(
nameResource = R.string.credit_logo5_name,
descriptionResource = R.string.credit_logo5_description,
importantContribution = false
),
Credit(
nameResource = R.string.credit_logo3_name,
descriptionResource = R.string.credit_logo3_description,
Expand All @@ -53,7 +58,6 @@ object CreditContent {
descriptionResource = R.string.credit_logo4_description,
importantContribution = false
),

Credit(
nameResource = R.string.credit_app_logo_name,
descriptionResource = R.string.credit_app_logo_description,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,10 @@ private fun generateRawUUID(): String = UUID.randomUUID().toString()
* Generates a User ID using randomUUID and sha256 hash
* @return User ID in hexadecimal format
*/
fun generateUID(): String = sha512hash(generateRawUUID())
fun generateUID(): String = sha512hash(generateRawUUID())

/**
* Encrypt private user data
* @return User ID in String format
*/
fun securePrivateData(message: String): String = sha512hash(message)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package es.upm.bienestaremocional.data.crypto

import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties
import java.security.KeyStore
import javax.crypto.KeyGenerator
import javax.crypto.SecretKey

object SecretKey {
private const val secretKeyAlias = "database_key"
private const val provider = "AndroidKeyStore"
private const val algorithm = KeyProperties.KEY_ALGORITHM_AES
private const val cipherMode = KeyProperties.BLOCK_MODE_GCM

private fun generateSecretKey(): SecretKey {
val keyGenerator = KeyGenerator.getInstance(algorithm, provider)
val spec = KeyGenParameterSpec
.Builder(secretKeyAlias, KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(cipherMode)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build()

keyGenerator.init(spec)
return keyGenerator.generateKey()
}

fun getSecretKey(): SecretKey {
// Get keyStore instance, no parameters at load stage are needed
val keyStore = KeyStore.getInstance(provider).apply { load(null) }
// Get key entry
val secretKeyEntry = keyStore.getEntry(secretKeyAlias, null) as KeyStore.SecretKeyEntry?
// Get the key itself or if is null generate it
return secretKeyEntry?.secretKey ?: generateSecretKey()
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -832,60 +832,4 @@ interface AppDAO {
)
suspend fun getLastDailySymptoms(): DailySymptoms?


/**
* -------------------------------------------------------------------------------------------
* Debug
* -------------------------------------------------------------------------------------------
*/
@Query("DELETE FROM last_upload")
fun nukeLastUploadTable()

@Query("DELETE FROM one_off_round")
fun nukeOneOffRoundTable()

@Query("DELETE FROM daily_round")
fun nukeDailyRoundTable()

@Query("DELETE FROM one_off_depression")
fun nukeOneOffDepressionTable()

@Query("DELETE FROM one_off_stress")
fun nukeOneOffStressTable()

@Query("DELETE FROM one_off_loneliness")
fun nukeOneOffLonelinessTable()

@Query("DELETE FROM daily_stress")
fun nukeDailyStressTable()

@Query("DELETE FROM daily_depression")
fun nukeDailyDepressionTable()

@Query("DELETE FROM daily_loneliness")
fun nukeDailyLonelinessTable()

@Query("DELETE FROM daily_suicide")
fun nukeDailySuicideTable()

@Query("DELETE FROM daily_symptoms")
fun nukeDailySymptomsTable()


@Transaction
suspend fun nukeDatabase() {
nukeLastUploadTable()
nukeOneOffRoundTable()
nukeDailyRoundTable()

nukeOneOffDepressionTable()
nukeOneOffStressTable()
nukeOneOffLonelinessTable()

nukeDailyStressTable()
nukeDailyDepressionTable()
nukeDailyLonelinessTable()
nukeDailySuicideTable()
nukeDailySymptomsTable()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,6 @@ abstract class HealthConnectSource<T : Record>(
*/
abstract val readPermissions: Set<String>

/**
* Set that contains permissions needed to write data
*/
abstract val writePermissions: Set<String>

/**
* Checks if all permissions needed for read are granted
* @see readPermissions
Expand Down Expand Up @@ -57,21 +52,6 @@ abstract class HealthConnectSource<T : Record>(
*/
abstract suspend fun readSource(startTime: Instant, endTime: Instant): List<T>

/**
* Checks if all permissions needed for read are granted
* @see readPermissions
*/
suspend fun writePermissionsCheck(): Boolean =
healthConnectClient.hasAllPermissions(writePermissions)

/**
* Write data into health connect
* @param data: [List] of [T] with the data
*/
suspend fun writeSource(data: List<Record>) {
healthConnectClient.insertRecords(data)
}

private suspend fun HealthConnectClient.hasAllPermissions(permissions: Set<String>): Boolean {
val granted = this.permissionController.getGrantedPermissions()
return granted.containsAll(permissions)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,22 @@ import androidx.health.connect.client.permission.HealthPermission
import androidx.health.connect.client.records.DistanceRecord
import androidx.health.connect.client.request.ReadRecordsRequest
import androidx.health.connect.client.time.TimeRangeFilter
import androidx.health.connect.client.units.Length
import es.upm.bienestaremocional.data.healthconnect.HealthConnectSource
import es.upm.bienestaremocional.utils.generateInterval
import java.time.Instant
import javax.inject.Inject
import kotlin.random.Random

/**
* Implementation of Distance datasource implementing [HealthConnectSource]
* @param healthConnectClient: proportionate HealthConnect's read and write primitives
*/


class Distance @Inject constructor(
private val healthConnectClient: HealthConnectClient
) : HealthConnectSource<DistanceRecord>(healthConnectClient) {
companion object {
/**
* Make demo data
*/
fun generateDummyData(): List<DistanceRecord> {
return List(5)
{ index ->
val (init, end) = generateInterval(offsetDays = index.toLong() + 1)

val distance = Length.kilometers(Random.nextDouble(0.0, 10.0))

DistanceRecord(
startTime = init.toInstant(),
startZoneOffset = init.offset,
endTime = end.toInstant(),
endZoneOffset = end.offset,
distance = distance
)
}
}
}

override val readPermissions = setOf(
HealthPermission.getReadPermission(DistanceRecord::class)
)

override val writePermissions = setOf(
HealthPermission.getWritePermission(DistanceRecord::class)
)

override suspend fun readSource(startTime: Instant, endTime: Instant): List<DistanceRecord> {
val request = ReadRecordsRequest(
recordType = DistanceRecord::class,
Expand Down
Loading

0 comments on commit b588d98

Please sign in to comment.