Skip to content

Commit

Permalink
Merge pull request #12 from opensrp/1082-sending-receiving-data
Browse files Browse the repository at this point in the history
Sending and  receiving data
  • Loading branch information
Rkareko authored Jun 14, 2022
2 parents a561479 + aff4e0a commit 25b88cc
Show file tree
Hide file tree
Showing 54 changed files with 5,717 additions and 495 deletions.
2 changes: 1 addition & 1 deletion deps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ versions.junit5_api = '5.7.1'
versions.junit5_plugin = '1.7.1.1'
versions.ktlint = '0.41.0'
versions.mockk = '1.11.0'
versions.robolectric = '4.4'
versions.robolectric = '4.8'
versions.timber = '4.7.1'
versions.room = '2.3.0'
versions.spotless = '5.11.0'
Expand Down
78 changes: 68 additions & 10 deletions p2p-lib/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ plugins {
id 'jacoco'
id 'com.github.kt3k.coveralls'
id 'com.diffplug.spotless'
id 'maven-publish'
}
apply plugin: 'kotlin-kapt'

jacoco {
toolVersion = '0.8.7'
Expand All @@ -21,6 +23,13 @@ android {
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"


javaCompileOptions {
annotationProcessorOptions {
arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
}
}
}

buildTypes {
Expand Down Expand Up @@ -60,19 +69,23 @@ android {

dependencies { configuration ->

implementation 'androidx.core:core-ktx:1.3.0'
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.work:work-runtime-ktx:2.6.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.navigation:navigation-fragment-ktx:2.3.5'
implementation 'androidx.navigation:navigation-ui-ktx:2.3.5'
implementation'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2'
implementation 'com.google.code.gson:gson:2.8.7'
implementation 'androidx.activity:activity:1.3.1'

roomDependencies(configuration)
locationDependencies(configuration)

testImplementation 'junit:junit:4.+'
testImplementation 'junit:junit:4.13.2'

testImplementation deps.junit5_api
testRuntimeOnly deps.junit5_engine
Expand All @@ -91,12 +104,18 @@ dependencies { configuration ->

def roomDependencies(configuration) {
configuration.implementation(deps.room.ktx)
configuration.kapt(deps.room.compiler)

// sql cipher deps
configuration.implementation "net.zetetic:android-database-sqlcipher:4.5.0"
configuration.implementation "androidx.sqlite:sqlite:2.0.1"

// Room Test helpers
configuration.testImplementation(deps.room.testing)
configuration.testImplementation "androidx.room:room-testing:2.3.0"
}

// Encrypted SQLite help
configuration.implementation "com.commonsware.cwac:saferoom:1.0.2"
def locationDependencies(configuration) {
configuration.implementation 'com.google.android.gms:play-services-location:16.0.0'
}

task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'/*, 'createDebugCoverageReport'*/]) {
Expand Down Expand Up @@ -129,7 +148,9 @@ task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest'/*, 'cr
'**/*$Result.*',
'**/*$Result$*.*',
// Data Binding
'**/databinding/*'
'**/databinding/*',
// Generated room DAO implementation classes
'**/*_Impl*.*'
]

def javaDebugTree = fileTree(dir: "$project.buildDir/intermediates/javac/debug/classes/", excludes: fileFilter)
Expand Down Expand Up @@ -167,4 +188,41 @@ spotless {
ktfmt().googleStyle()
licenseHeaderFile "${project.rootProject.projectDir}/license-header.txt"
}
}
}

afterEvaluate {
publishing {
publications {
snapshot(MavenPublication) {
from(components["release"])
artifactId = "p2p-lib"
groupId = "org.smartregister"
version = "0.3.0-SNAPSHOT"
pom {
name.set("Peer to Peer Library")
}
}
}
repositories {
maven {
name = 'sonatype'
url = uri("https://oss.sonatype.org/content/repositories/snapshots/")
credentials {
username = getRepositoryUsername()
password = getRepositoryPassword()
}
}

}
}
}



def getRepositoryPassword() {
return hasProperty('sonatypePassword') ? sonatypePassword : ""
}

def getRepositoryUsername() {
return hasProperty('sonatypeUsername') ? sonatypeUsername : ""
}
47 changes: 47 additions & 0 deletions p2p-lib/schemas/org.smartregister.p2p.model.AppDatabase/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "d355d8a44926f53645f849d9d8200228",
"entities": [
{
"tableName": "p2p_received_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`app_lifetime_key` TEXT NOT NULL, `entity_type` TEXT NOT NULL, `last_updated_at` INTEGER NOT NULL, PRIMARY KEY(`entity_type`, `app_lifetime_key`))",
"fields": [
{
"fieldPath": "appLifetimeKey",
"columnName": "app_lifetime_key",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "entityType",
"columnName": "entity_type",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "lastUpdatedAt",
"columnName": "last_updated_at",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"entity_type",
"app_lifetime_key"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd355d8a44926f53645f849d9d8200228')"
]
}
}
43 changes: 27 additions & 16 deletions p2p-lib/src/main/java/org/smartregister/p2p/P2PLibrary.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ package org.smartregister.p2p

import android.content.Context
import androidx.annotation.NonNull
import androidx.annotation.Nullable
import java.util.UUID
import org.smartregister.p2p.dao.ReceiverTransferDao
import org.smartregister.p2p.dao.SenderTransferDao
import org.smartregister.p2p.data_sharing.DataSharingStrategy
import org.smartregister.p2p.data_sharing.WifiDirectDataSharingStrategy
import org.smartregister.p2p.model.AppDatabase
import org.smartregister.p2p.utils.Constants
import org.smartregister.p2p.utils.Settings
import org.smartregister.p2p.utils.isAppDebuggable
import timber.log.Timber

/** Created by Ephraim Kigamba - nek.eam@gmail.com on 14-03-2022. */
Expand All @@ -30,44 +34,44 @@ class P2PLibrary private constructor() {
private lateinit var options: Options
private var hashKey: String? = null
private var deviceUniqueIdentifier: String? = null
var dataSharingStrategy: DataSharingStrategy = WifiDirectDataSharingStrategy()

companion object {
private var instance: P2PLibrary? = null

@NonNull
fun getInstance(): P2PLibrary? {
fun getInstance(): P2PLibrary {
checkNotNull(instance) {
("Instance does not exist!!! Call P2PLibrary.init method" +
("Instance does not exist!!! Call P2PLibrary.init(P2PLibrary.Options) method " +
"in the onCreate method of " +
"your Application class ")
}
return instance
return instance!!
}
}

fun init(@NonNull options: Options) {
instance = P2PLibrary(options)
fun init(options: Options): P2PLibrary {
instance = P2PLibrary(options)
return instance!!
}
}

private constructor(@NonNull options: Options) : this() {
private constructor(options: Options) : this() {
this.options = options

// We should not override the host applications Timber trees
if (Timber.treeCount == 0) {
if (Timber.treeCount == 0 && isAppDebuggable(options.context)) {
Timber.plant(Timber.DebugTree())
}

hashKey = getHashKey()

// Start the DB
AppDatabase.getInstance(getContext(), options.dbPassphrase)
}

@NonNull
fun getDb(): AppDatabase? {
fun getDb(): AppDatabase {
return AppDatabase.getInstance(getContext(), options.dbPassphrase)
}

@NonNull
fun getHashKey(): String? {
if (hashKey == null) {
val settings = Settings(getContext())
Expand All @@ -88,17 +92,14 @@ class P2PLibrary private constructor() {
this.deviceUniqueIdentifier = deviceUniqueIdentifier
}

@Nullable
fun getDeviceUniqueIdentifier(): String? {
return deviceUniqueIdentifier
}

@NonNull
fun getUsername(): String {
return options.username
}

@NonNull
fun getContext(): Context {
return options.context
}
Expand All @@ -107,11 +108,21 @@ class P2PLibrary private constructor() {
return options.batchSize
}

fun getSenderTransferDao(): SenderTransferDao {
return options.senderTransferDao
}

fun getReceiverTransferDao(): ReceiverTransferDao {
return options.receiverTransferDao
}

/** [P2PLibrary] configurability options an */
class Options(
val context: Context,
val dbPassphrase: String,
val username: String,
val senderTransferDao: SenderTransferDao,
val receiverTransferDao: ReceiverTransferDao
) {
var batchSize: Int = Constants.DEFAULT_SHARE_BATCH_SIZE
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
package org.smartregister.p2p

import android.Manifest
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.wifi.p2p.WifiP2pGroup
import android.net.wifi.p2p.WifiP2pInfo
import android.net.wifi.p2p.WifiP2pManager
import android.os.Build
import androidx.core.app.ActivityCompat
Expand All @@ -30,12 +31,17 @@ class WifiP2pBroadcastReceiver(
private val manager: WifiP2pManager,
private val channel: WifiP2pManager.Channel,
private val listener: P2PManagerListener,
private val context: Activity
private val context: Context
) : BroadcastReceiver() {

override fun onReceive(context: Context, intent: Intent) {
when (intent.action) {
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> handleConnectionChanged()
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION -> {
val p2pGroupInfo =
intent.getParcelableExtra<WifiP2pGroup>(WifiP2pManager.EXTRA_WIFI_P2P_GROUP)
val wifiP2pInfo = intent.getParcelableExtra<WifiP2pInfo>(WifiP2pManager.EXTRA_WIFI_P2P_INFO)
listener.onConnectionInfoAvailable(wifiP2pInfo!!, p2pGroupInfo)
}
WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION ->
handleDiscoveryChanged(intent.getIntExtra(WifiP2pManager.EXTRA_DISCOVERY_STATE, -1))
WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION -> handlePeersChanged()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
package org.smartregister.p2p.dao

import androidx.annotation.NonNull
import androidx.annotation.Nullable
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query
Expand All @@ -27,22 +25,18 @@ import org.smartregister.p2p.model.P2PReceivedHistory
@Dao
interface P2pReceivedHistoryDao {

@Insert fun addReceivedHistory(@NonNull receivedP2PReceivedHistory: P2PReceivedHistory?)
@Insert fun addReceivedHistory(receivedP2PReceivedHistory: P2PReceivedHistory?)

@Update fun updateReceivedHistory(@NonNull receivedP2PReceivedHistory: P2PReceivedHistory?)
@Update fun updateReceivedHistory(receivedP2PReceivedHistory: P2PReceivedHistory?)

@Query("DELETE FROM p2p_received_history WHERE app_lifetime_key = :appLifetimeKey")
fun clearDeviceRecords(@NonNull appLifetimeKey: String?): Int
fun clearDeviceRecords(appLifetimeKey: String?): Int

@Query("SELECT * FROM p2p_received_history WHERE app_lifetime_key = :appLifetimeKey")
fun getDeviceReceivedHistory(@NonNull appLifetimeKey: String?): List<P2PReceivedHistory?>?
fun getDeviceReceivedHistory(appLifetimeKey: String?): List<P2PReceivedHistory?>?

@Nullable
@Query(
"SELECT * FROM p2p_received_history WHERE app_lifetime_key = :appLifetimeKey AND entity_type = :entityType LIMIT 1"
)
fun getHistory(
@NonNull appLifetimeKey: String?,
@NonNull entityType: String?
): P2PReceivedHistory?
fun getHistory(appLifetimeKey: String?, entityType: String?): P2PReceivedHistory?
}
Loading

0 comments on commit 25b88cc

Please sign in to comment.