diff --git a/README.md b/README.md index bdc8290..1e0d5d8 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,22 @@ -### [🍍 Console](https://console.mytiki.com)   ⏐   [📚 Docs](https://docs.mytiki.com) +### [🍍 Console](https://console.mytiki.com)   ⏐   [📚 Docs](https://docs.mytiki.com) # TIKI SDK [Android] —build the new data economy -A package for adding TIKI's decentralized infrastructure to **Android** projects. Add tokenized data ownership, consent, and rewards to your app in minutes. +A package for adding TIKI's decentralized infrastructure to **Android** projects. Add tokenized data +ownership, consent, and rewards to your app in minutes. ### [🎬 How to get started ➝](https://docs.mytiki.com/docs/tiki-sdk-flutter-getting-started) + - **[API Reference ➝](https://docs.mytiki.com/reference/tiki-sdk-flutter-tiki-sdk-flutter-builder)** - **[Kotlin Docs ➝](https://tiki-sdk-android.docs.mytiki.com)** #### Basic Architecture + This SDK exposes Android native (Kotlin) APIs for the TIKI SDK by: -1. The [tiki-sdk-dart](https://github.com/tiki/tiki-sdk-dart) project is [compiled](https://dart.dev/overview) to platform native machine code. +1. The [tiki-sdk-dart](https://github.com/tiki/tiki-sdk-dart) project + is [compiled](https://dart.dev/overview) to platform native machine code. -2. Using the [Flutter Engine](https://github.com/flutter/engine) a bidirectional [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) is created to handle communication between the Android application and the SDK. \ No newline at end of file +2. Using the [Flutter Engine](https://github.com/flutter/engine) a + bidirectional [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) + is created to handle communication between the Android application and the SDK. \ No newline at end of file diff --git a/app/add-dll.gradle b/app/add-dll.gradle index 5ea7a07..cc857e5 100644 --- a/app/add-dll.gradle +++ b/app/add-dll.gradle @@ -1,36 +1,34 @@ import org.apache.commons.io.FileUtils + import java.nio.file.Files -import java.nio.file.Paths -import java.nio.file.StandardCopyOption -import java.util.zip.ZipEntry import java.util.zip.ZipFile -static void clean(String rootDir){ +static void clean(String rootDir) { FileUtils.deleteDirectory(new File("$rootDir/app/build/tmp/dlls")) FileUtils.deleteDirectory(new File("$rootDir/app/src/debug/jniLibs")) FileUtils.deleteDirectory(new File("$rootDir/app/src/main/jniLibs")) } -static void fetch(String url, String tmp){ +static void fetch(String url, String tmp) { makeDir(tmp) File zip = download(url, tmp) unzipFiles(tmp, zip) } -static void load(String src, String dest){ +static void load(String src, String dest) { File out = new File(dest) makeDir(out.getParent()) out.bytes = new File(src).bytes } -private static def makeDir(String path){ - File directory = new File(path); - if (! directory.exists()){ - directory.mkdirs(); +private static def makeDir(String path) { + File directory = new File(path) + if (!directory.exists()) { + directory.mkdirs() } } -private static File download(path, tmp){ +private static File download(path, tmp) { URL url = new URL(path) String filename = path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf('.')) File file = new File("$tmp/${filename}.zip") @@ -52,7 +50,7 @@ private static void unzipFiles(String dir, File src) { } } -static void listFiles(File f, List files){ +static void listFiles(File f, List files) { f.listFiles().each { if (it.isDirectory()) return listFiles(it, files) @@ -61,7 +59,7 @@ static void listFiles(File f, List files){ } } -static void flutter(String rootDir, String flutterEngine){ +static void flutter(String rootDir, String flutterEngine) { String flutterBucket = 'https://storage.googleapis.com/download.flutter.io/io/flutter' fetch( "$flutterBucket/arm64_v8a_debug/$flutterEngine/arm64_v8a_debug-${flutterEngine}.jar", @@ -121,7 +119,7 @@ static void flutter(String rootDir, String flutterEngine){ ) } -static void sqlite(String rootDir){ +static void sqlite(String rootDir) { String url = 'https://www.sqlite.org/2022/sqlite-android-3400000.aar' fetch(url, "$rootDir/app/build/tmp/dlls/sqlite") load( diff --git a/app/build.gradle b/app/build.gradle index cf8ac3e..8a04613 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,6 @@ buildscript { - ext.flutterEngine = "1.0.0-8f2221fbef28b478debb78dd233f5250b220ca99" - ext.sdkVersion = "0.0.23" + ext.flutterEngine = "1.0.0-c08d7d5efc9aa6eb3c30cfb3be6dc09bca5e7631" + ext.sdkVersion = "0.0.24" repositories { mavenCentral() } @@ -20,8 +20,8 @@ android { compileSdk 33 defaultConfig { minSdk 21 - versionCode 2 - versionName "0.0.5" + versionCode 3 + versionName "0.0.6" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -50,16 +50,30 @@ android { apply plugin: 'com.kezong.fat-aar' apply plugin: 'kotlin-kapt' + dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'androidx.core:core-ktx:1.9.0' - implementation("com.squareup.moshi:moshi-kotlin:1.14.0") + implementation "com.squareup.moshi:moshi-kotlin:1.14.0" kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.14.0' testImplementation 'junit:junit:4.13.2' + testImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4' androidTestImplementation 'androidx.test.ext:junit:1.1.4' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' + testImplementation 'org.mockito:mockito-core:4.11.0' + androidTestImplementation 'org.mockito:mockito-android:4.11.0' + + debugEmbed "com.squareup.moshi:moshi-kotlin:1.14.0" + releaseEmbed "com.squareup.moshi:moshi-kotlin:1.14.0" + + debugEmbed "com.squareup.moshi:moshi:1.14.0" + releaseEmbed "com.squareup.moshi:moshi:1.14.0" + + debugEmbed "com.squareup.okio:okio:2.10.0" + releaseEmbed "com.squareup.okio:okio:2.10.0" + debugEmbed "io.flutter:flutter_embedding_debug:$flutterEngine" releaseEmbed "io.flutter:flutter_embedding_release:$flutterEngine" @@ -88,7 +102,6 @@ addDll.clean(rootDir.toString()) addDll.flutter(rootDir.toString(), flutterEngine) addDll.sqlite(rootDir.toString()) - apply plugin: 'maven-publish' apply plugin: 'signing' diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index 33e2f48..e6553e8 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -1,279 +1,168 @@ - + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~" + id="ObsoleteSdkInt" message="Unnecessary; SDK_INT is always >= 21"> + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~" + id="ObsoleteSdkInt" message="Unnecessary; SDK_INT is always >= 21"> + - - + + - - + + - - + + - - + + - - + + - - + + - - + + - + errorLine2="^" id="UnusedResources" + message="The resource `R.mipmap.ic_launcher` appears to be unused"> + - + errorLine2="^" id="UnusedResources" + message="The resource `R.drawable.ic_launcher_background` appears to be unused"> + - + errorLine2="^" id="UnusedResources" + message="The resource `R.drawable.ic_launcher_foreground` appears to be unused"> + - + errorLine2="^" id="UnusedResources" + message="The resource `R.mipmap.ic_launcher_round` appears to be unused"> + - - + + - - + + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.string.first_fragment_label` appears to be unused"> + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.string.second_fragment_label` appears to be unused"> + - - + + - - + + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.string.hello_first_fragment` appears to be unused"> + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.string.hello_second_fragment` appears to be unused"> + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.style.Theme_TIKISDK` appears to be unused"> + - - + + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.style.Theme_TIKISDK_AppBarOverlay` appears to be unused"> + - + errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" id="UnusedResources" + message="The resource `R.style.Theme_TIKISDK_PopupOverlay` appears to be unused"> + diff --git a/app/src/androidTest/java/com/mytiki/tiki_sdk_android/TikiSdkTest.kt b/app/src/androidTest/java/com/mytiki/tiki_sdk_android/TikiSdkTest.kt deleted file mode 100644 index de56a05..0000000 --- a/app/src/androidTest/java/com/mytiki/tiki_sdk_android/TikiSdkTest.kt +++ /dev/null @@ -1,78 +0,0 @@ -package com.mytiki.tiki_sdk_android - -import androidx.test.ext.junit.runners.AndroidJUnit4 -import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation -import org.junit.Assert.assertEquals -import org.junit.Test -import org.junit.runner.RunWith - -const val API_KEY: String = "2b8de004-cbe0-4bd5-bda6-b266d54f5c90" -const val ORIGIN: String = "com.mytiki.tiki_sdk_android.test" - -@RunWith(AndroidJUnit4::class) -class TikiSdkTest { - - @Test - fun init_tiki_sdk() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - assert(tikiSdk.address.length > 32) - } - - @Test - fun init_tiki_sdk_with_address() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val address = tikiSdk.address - val tikiSdk2 = TikiSdk(API_KEY, ORIGIN, context, address) - assertEquals(tikiSdk.address, tikiSdk2.address) - } - - @Test - fun assign_onwership() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val ownershipId = tikiSdk.assignOwnership("source", TikiSdkDataTypeEnum.data_point, listOf("test")) - assert(ownershipId.length > 32) - } - - @Test - fun get_onwership() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val ownershipId = tikiSdk.assignOwnership("source", TikiSdkDataTypeEnum.data_point, listOf("test")) - val ownership = tikiSdk.getOwnership("source") - assertEquals(ownershipId, ownership!!.transactionId) - } - - @Test - fun modify_consent() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val ownershipId = tikiSdk.assignOwnership("source", TikiSdkDataTypeEnum.data_point, listOf("test")) - val consent = tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) - assertEquals(consent.ownershipId, ownershipId) - } - - fun get_consent() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val ownershipId = tikiSdk.assignOwnership("source", TikiSdkDataTypeEnum.data_point, listOf("test")) - val consent = tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) - val consentGet = tikiSdk.getConsent("source") - assertEquals(consent.transactionId, consentGet!!.transactionId) - } - - @Test - fun apply_consent() { - val context = getInstrumentation().targetContext - val tikiSdk = TikiSdk(API_KEY, ORIGIN, context) - val ownershipId = tikiSdk.assignOwnership("source", TikiSdkDataTypeEnum.data_point, listOf("test")) - tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) - var ok = false - tikiSdk.applyConsent("source", TikiSdkDestination.ALL, { - ok = true - }) - assert(ok) - } -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 49ca898..ba59963 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt index b658b5e..bd2ee81 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt @@ -1,62 +1,68 @@ package com.mytiki.tiki_sdk_android import android.content.Context -import com.mytiki.tiki_sdk_android.tiki_platform_channel.TikiSdkFlutterChannel +import com.mytiki.tiki_sdk_android.tiki_platform_channel.MethodEnum +import com.mytiki.tiki_sdk_android.tiki_platform_channel.TikiPlatformChannel import com.mytiki.tiki_sdk_android.tiki_platform_channel.req.* import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspBuild import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspConsentApply import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspConsentGet import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspOwnership -import com.squareup.moshi.Moshi import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.dart.DartExecutor import io.flutter.embedding.engine.loader.FlutterLoader import io.flutter.plugins.GeneratedPluginRegistrant -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.* import java.util.* /** * The TIKI SDK main class. Use this to add tokenized data ownership, consent, and rewards. * - * @constructor - * - * @param apiId The apiId for connecting to TIKI cloud. - * @param origin The default origin for all transactions. - * @param context The context of the application. Used to initialize Flutter Engine - * @param address The address of the user node in TIKI blockchain. If null a new address will be created. - */ -class TikiSdk(apiId: String, origin: String, context: Context, address: String? = null) { - - private var tikiSdkFlutterChannel: TikiSdkFlutterChannel - private val moshi = Moshi.Builder().build() - var completables: MutableMap> = mutableMapOf() - val address: String + * @constructor Create empty Tiki sdk. [init] should be called to build the SDK. + */ +class TikiSdk { + private lateinit var tikiPlatformChannel: TikiPlatformChannel + lateinit var address: String - init { - val buildRequest = ReqBuild("build", apiId, origin, address) - val buildRequestJson = buildRequest.toJson() - var jsonString: String - val loader = FlutterLoader() - loader.startInitialization(context) - loader.ensureInitializationComplete(context, null) - val flutterEngine = FlutterEngine(context) - flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()) - GeneratedPluginRegistrant.registerWith(flutterEngine) - tikiSdkFlutterChannel = TikiSdkFlutterChannel() - tikiSdkFlutterChannel.tikiSdk = this - flutterEngine.plugins.add(tikiSdkFlutterChannel) - tikiSdkFlutterChannel.channel.invokeMethod( - "build", listOf("request" to buildRequestJson) - ) - val deferred = CompletableDeferred() - completables["build"] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! + /** + * Initializes the TIKI SDK. + * + * It should be called before any other method. It sets up Flutter Engine and Platform Channel + * and builds the core of the TIKI SDK, calling TIKI SDK Dart through the Flutter Platform Channel. + * + * @param apiId The apiId for connecting to TIKI cloud. + * @param origin The default origin for all transactions. + * @param context The context of the application. Used to initialize Flutter Engine + * @param address The address of the user node in TIKI blockchain. If null a new address will be created. + * @return Deferred - use await() to complete it. + */ + fun init( + apiId: String, + origin: String, + context: Context, + address: String? = null + ): Deferred { + return MainScope().async { + val loader = FlutterLoader() + loader.startInitialization(context) + yield() + loader.ensureInitializationComplete(context, null) + val flutterEngine = FlutterEngine(context) + flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()) + GeneratedPluginRegistrant.registerWith(flutterEngine) + val tikiPlatformChannel = TikiPlatformChannel() + this@TikiSdk.tikiPlatformChannel = tikiPlatformChannel + flutterEngine.plugins.add(tikiPlatformChannel) + yield() + val rspBuild = tikiPlatformChannel + .invokeMethod( + MethodEnum.BUILD, + ReqBuild(apiId, origin, address) + ) + .await() + this@TikiSdk.address = rspBuild!!.address + return@async this@TikiSdk } - val rspBuild: RspBuild = moshi.adapter(RspBuild::class.java).fromJson(jsonString)!! - this@TikiSdk.address = rspBuild.address } /** Assign ownership to a given source. @@ -69,29 +75,20 @@ class TikiSdk(apiId: String, origin: String, context: Context, address: String? * * @return [TikiSdkOwnership] transaction Id */ - fun assignOwnership( + suspend fun assignOwnership( source: String, type: TikiSdkDataTypeEnum, contains: List, about: String? = null, origin: String? = null ): String { - val requestId = UUID.randomUUID().toString() - var jsonString: String - tikiSdkFlutterChannel.channel.invokeMethod( - "assignOwnership", mapOf( - "request" to ReqOwnershipAssign( - requestId, source, type, contains, about, origin - ).toJson() + val assignReq = ReqOwnershipAssign(source, type, contains, about, origin) + val rspAssignCompletable: CompletableDeferred = + tikiPlatformChannel.invokeMethod( + MethodEnum.ASSIGN_OWNERSHIP, assignReq ) - ) - val deferred = CompletableDeferred() - completables[requestId] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! - } - val rsp = moshi.adapter(RspOwnership::class.java).fromJson(jsonString) - return rsp!!.ownership.transactionId + val rspAssign: RspOwnership = rspAssignCompletable.await()!! + return rspAssign.ownership.transactionId } /** @@ -102,26 +99,17 @@ class TikiSdk(apiId: String, origin: String, context: Context, address: String? * * @return [TikiSdkOwnership], null if not found */ - fun getOwnership( + suspend fun getOwnership( source: String, origin: String? = null ): TikiSdkOwnership? { - val requestId = UUID.randomUUID().toString() - var jsonString: String - tikiSdkFlutterChannel.channel.invokeMethod( - "assignOwnership", mapOf( - "request" to ReqOwnershipGet( - requestId, source, origin - ).toJson() + val getReq = ReqConsentGet(source, origin) + val rspGetCompletable: CompletableDeferred = + tikiPlatformChannel.invokeMethod( + MethodEnum.GET_OWNERSHIP, getReq ) - ) - val deferred = CompletableDeferred() - completables[requestId] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! - } - val rsp = moshi.adapter(RspOwnership::class.java).fromJson(jsonString) - return rsp?.ownership + val rspGet = rspGetCompletable.await() + return rspGet?.ownership } /** @@ -138,31 +126,22 @@ class TikiSdk(apiId: String, origin: String, context: Context, address: String? * @param about String? Optional description about the data. * @param reward String? Optional reward the user will receive for granting consent. * @param expiry Date? Optional expiration for the consent. - * @return + * @return TikiSdkConsent */ - fun modifyConsent( + suspend fun modifyConsent( ownershipId: String, destination: TikiSdkDestination, about: String? = null, reward: String? = null, expiry: Date? = null ): TikiSdkConsent { - val requestId = UUID.randomUUID().toString() - var jsonString: String - tikiSdkFlutterChannel.channel.invokeMethod( - "assignOwnership", mapOf( - "request" to ReqConsentModify( - requestId, ownershipId, destination, about, reward, expiry?.time - ).toJson() + val modifyReq = ReqConsentModify(ownershipId, destination, about, reward, expiry?.time) + val rspModifyCompletable: CompletableDeferred = + tikiPlatformChannel.invokeMethod( + MethodEnum.MODIFY_CONSENT, modifyReq ) - ) - val deferred = CompletableDeferred() - completables[requestId] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! - } - val rsp = moshi.adapter(RspConsentGet::class.java).fromJson(jsonString) - return rsp!!.consent + val rspModify: RspConsentGet = rspModifyCompletable.await()!! + return rspModify.consent } /** @@ -177,26 +156,17 @@ class TikiSdk(apiId: String, origin: String, context: Context, address: String? * * @return TikiSdkConsent */ - fun getConsent( + suspend fun getConsent( source: String, origin: String? = null ): TikiSdkConsent? { - val requestId = UUID.randomUUID().toString() - var jsonString: String - tikiSdkFlutterChannel.channel.invokeMethod( - "assignOwnership", mapOf( - "request" to ReqConsentGet( - requestId, source, origin - ).toJson() + val getReq = ReqConsentGet(source, origin) + val rspConsentCompletable: CompletableDeferred = + tikiPlatformChannel.invokeMethod( + MethodEnum.GET_CONSENT, getReq ) - ) - val deferred = CompletableDeferred() - completables[requestId] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! - } - val rsp = moshi.adapter(RspConsentGet::class.java).fromJson(jsonString) - return rsp?.consent + val rspGet: RspConsentGet? = rspConsentCompletable.await() + return rspGet?.consent } /** @@ -211,32 +181,23 @@ class TikiSdk(apiId: String, origin: String, context: Context, address: String? * @param request () -> Unit * @param onBlocked ((String) -> Unit)? */ - fun applyConsent( + suspend fun applyConsent( source: String, destination: TikiSdkDestination, request: () -> Unit, onBlocked: ((value: String) -> Unit)? = null, origin: String? = null, ) { - val requestId = UUID.randomUUID().toString() - var jsonString: String - tikiSdkFlutterChannel.channel.invokeMethod( - "assignOwnership", mapOf( - "request" to ReqConsentApply( - requestId, source, destination, origin - ).toJson() + val applyReq = ReqConsentApply(source, destination, origin) + val rspApplyCompletable: CompletableDeferred = + tikiPlatformChannel.invokeMethod( + MethodEnum.APPLY_CONSENT, applyReq ) - ) - val deferred = CompletableDeferred() - completables[requestId] = deferred - runBlocking(Dispatchers.IO) { - jsonString = deferred.await()!! - } - val rsp = moshi.adapter(RspConsentApply::class.java).fromJson(jsonString) - if (rsp!!.success) { + val rspApply: RspConsentApply = rspApplyCompletable.await()!! + if (rspApply.success) { request() } else { - onBlocked?.invoke(rsp.reason ?: "no consent") + onBlocked?.invoke(rspApply.reason ?: "no consent found") } } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt index 17bbf73..434b09d 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt @@ -1,6 +1,7 @@ package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonClass +import java.util.* @JsonClass(generateAdapter = true) data class TikiSdkConsent( @@ -30,7 +31,7 @@ data class TikiSdkConsent( val reward: String? = null, /** - * The Consent expiration in milliseconds since Epoch. Null for no expiration. + * The Consent expiration. Null for no expiration. */ - val expiry: Int? = null + val expiry: Date? = null ) \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt index 32a3209..2a2442c 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt @@ -7,5 +7,8 @@ import com.squareup.moshi.JsonClass */ @JsonClass(generateAdapter = false) enum class TikiSdkDataTypeEnum { - data_point, data_stream, data_pool + data_point, + data_stream, + data_pool; + } \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt index 966952b..ec3114c 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt @@ -37,9 +37,6 @@ open class TikiSdkDestination( */ object ALL : TikiSdkDestination(listOf("*")) - /// - /// - /// /** * TikiSdkDestination.NONE * diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt new file mode 100644 index 0000000..d4309ea --- /dev/null +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt @@ -0,0 +1,29 @@ +package com.mytiki.tiki_sdk_android.tiki_platform_channel + +/** + * TIKI SDK Flutter methods. + * + * @constructor Create empty Method enum + */ +enum class MethodEnum { + BUILD { + override val methodCall: String = "build" + }, + ASSIGN_OWNERSHIP { + override val methodCall: String = "assignOwnership" + }, + GET_OWNERSHIP { + override val methodCall: String = "getOwnership" + }, + MODIFY_CONSENT { + override val methodCall: String = "modifyConsent" + }, + GET_CONSENT { + override val methodCall: String = "getConsent" + }, + APPLY_CONSENT { + override val methodCall: String = "applyConsent" + }; + + abstract val methodCall: String +} \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt new file mode 100644 index 0000000..5232ad7 --- /dev/null +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt @@ -0,0 +1,96 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ +package com.mytiki.tiki_sdk_android.tiki_platform_channel + +import android.util.Log +import androidx.annotation.NonNull +import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspError +import com.mytiki.tiki_sdk_android.util.TimeStampToDateAdapter +import com.squareup.moshi.Moshi +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import kotlinx.coroutines.CompletableDeferred +import okio.IOException +import java.util.* + +/** + * Tiki sdk flutter channel + * + * @constructor Create empty Tiki sdk flutter channel + */ +class TikiPlatformChannel : FlutterPlugin, MethodCallHandler { + + lateinit var channel: MethodChannel + var completables: MutableMap Unit)> = mutableMapOf() + + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.binaryMessenger, "tiki_sdk_flutter") + channel.setMethodCallHandler(this) + } + + override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { + val response = call.argument("response")!! + val requestId = call.argument("requestId")!! + Log.e("Ricardo - call", call.method) + Log.e("Ricardo - reqId", requestId) + Log.e("Ricardo - rsp", response) + when (call.method) { + "success" -> { + completables[requestId]?.invoke(response, null) + } + "error" -> { + val error = Moshi.Builder().build().adapter(RspError::class.java).fromJson(response) + completables[requestId]?.invoke(null, Error(error?.message)) + } + } + } + + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } + + /** + * Invoke [method] in TIKI SDK Flutter + * + * @param T The type that will be returned in the CompletableDeferred + * @param R The type of the [request] + * @param method The method to be called from TIKI SDK Flutter + * @param request The request object for the [method] + * @return CompletableDeferred holding [T] + */ + inline fun invokeMethod( + method: MethodEnum, + request: R + ): CompletableDeferred { + val moshi: Moshi = Moshi.Builder() + .add(TimeStampToDateAdapter()) + .build() + val requestId = UUID.randomUUID().toString() + val deferred = CompletableDeferred() + val jsonRequest = moshi.adapter(R::class.java).toJson(request) + channel.invokeMethod( + method.methodCall, mapOf( + "requestId" to requestId, + "request" to jsonRequest + ) + ) + completables[requestId] = { jsonString: String?, error: Error? -> + if (error != null) { + deferred.completeExceptionally(error) + } else { + try { + val response = moshi.adapter(T::class.java).fromJson(jsonString ?: "") + deferred.complete(response) + } catch (e: IOException) { + deferred.completeExceptionally(e) + } + } + } + return deferred + } +} diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiSdkFlutterChannel.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiSdkFlutterChannel.kt deleted file mode 100644 index ff89f7c..0000000 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiSdkFlutterChannel.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) TIKI Inc. - * MIT license. See LICENSE file in root directory. - */ -package com.mytiki.tiki_sdk_android.tiki_platform_channel - -import androidx.annotation.NonNull -import com.mytiki.tiki_sdk_android.TikiSdk -import com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp.RspError -import com.squareup.moshi.Moshi -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result -import org.json.JSONObject - -/** - * Tiki sdk flutter channel - * - * @constructor Create empty Tiki sdk flutter channel - */ -class TikiSdkFlutterChannel : FlutterPlugin, MethodCallHandler { - lateinit var tikiSdk: TikiSdk - lateinit var channel: MethodChannel - - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - channel = MethodChannel(flutterPluginBinding.binaryMessenger, "tiki_sdk_flutter") - channel.setMethodCallHandler(this) - } - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { - val response = call.argument("response")!! - val jsonMap = JSONObject(response) - val requestId = jsonMap["requestId"] - when (call.method) { - "success" -> { - tikiSdk.completables[requestId]?.complete(response) - } - "error" -> { - val error = Moshi.Builder().build().adapter(RspError::class.java).fromJson(response) - tikiSdk.completables[requestId]?.completeExceptionally(Error(error?.message)) - } - } - } - - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - channel.setMethodCallHandler(null) - } -} diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/Req.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/Req.kt deleted file mode 100644 index 7a65f60..0000000 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/Req.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) TIKI Inc. - * MIT license. See LICENSE file in root directory. - */ -package com.mytiki.tiki_sdk_android.tiki_platform_channel.req - -import com.squareup.moshi.JsonClass - -/** - * The base Request object for native channels. - * - * @property requestId used to identify the request in the native platform. - * @constructor Creates a new generic request - */ -@JsonClass(generateAdapter = true) -open class Req( - open val requestId: String -) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt index 884ff2b..23b6066 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt @@ -5,7 +5,6 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `build` method call in the Platform Channel. @@ -13,7 +12,7 @@ import com.squareup.moshi.Moshi * It requires an *apiId]* and an *origin]*. If no *address* is provided the SDK * will create a new one * - * @property requestId + * @property apiId * @property origin * @property address @@ -21,13 +20,7 @@ import com.squareup.moshi.Moshi */ @JsonClass(generateAdapter = true) data class ReqBuild( - override val requestId: String, val apiId: String, val origin: String, val address: String? = null -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqBuild::class.java).toJson(this) - } -} +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt index 510e9f4..132a9a1 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt @@ -6,14 +6,13 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDestination import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `applyConsent` method call in the Platform Channel. * * It uses the [source] and [destination] to verify if the consent was given. * - * @property requestId + * @property source * @property destination * @property origin @@ -21,14 +20,7 @@ import com.squareup.moshi.Moshi */ @JsonClass(generateAdapter = true) data class ReqConsentApply( - override val requestId: String, val source: String, val destination: TikiSdkDestination, val origin: String? = null -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqConsentApply::class.java).toJson(this) - } - -} +) \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt index fe45ced..c74d4d9 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt @@ -5,26 +5,17 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `getConsent` call in the Platform Channel. * - * @property requestId * @property source * @property origin * @constructor Create empty Req consent get */ @JsonClass(generateAdapter = true) data class ReqConsentGet( - override val requestId: String, val source: String, val origin: String? -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqConsentGet::class.java).toJson(this) - } - -} +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt index 0fddbdc..92d3c64 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt @@ -6,12 +6,11 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDestination import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `modifyConsent`method call in the Platform Channel. * - * @property requestId + * @property ownershipId * @property destination * @property about @@ -21,16 +20,9 @@ import com.squareup.moshi.Moshi */ @JsonClass(generateAdapter = true) data class ReqConsentModify( - override val requestId: String, val ownershipId: String, val destination: TikiSdkDestination, val about: String? = null, val reward: String? = null, val expiry: Long? = null -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqConsentModify::class.java).toJson(this) - } - -} +) \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt index b8318e4..42dc42d 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt @@ -6,12 +6,11 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDataTypeEnum import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `assignOwnership` method call in the Platform Channel. * - * @property requestId + * @property source * @property type * @property contains @@ -21,17 +20,9 @@ import com.squareup.moshi.Moshi */ @JsonClass(generateAdapter = true) data class ReqOwnershipAssign( - override val requestId: String, val source: String, val type: TikiSdkDataTypeEnum, val contains: List, val about: String? = null, val origin: String? = null -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqOwnershipAssign::class.java).toJson(this) - } - -} - +) \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt index 1511b47..1cab451 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt @@ -5,27 +5,16 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass -import com.squareup.moshi.Moshi /** * The request for the `getOwnership` method call in the Platform Channel. * - * @property requestId * @property source * @property origin * @constructor Create empty Req ownership get */ @JsonClass(generateAdapter = true) data class ReqOwnershipGet( - override val requestId: String, val source: String, val origin: String? = null -) : Req(requestId) { - - fun toJson(): String { - return Moshi.Builder().build().adapter(ReqOwnershipGet::class.java).toJson(this) - } - -} - - +) \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/Rsp.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/Rsp.kt deleted file mode 100644 index 7d147ef..0000000 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/Rsp.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) TIKI Inc. - * MIT license. See LICENSE file in root directory. - */ -package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp - -import com.squareup.moshi.JsonClass - -/** - * The base Response object for native channels. - * - * The [requestId] parameter is used to identify the request in the native platform. - * - * @property requestId - * @constructor Create empty Rsp - */ -@JsonClass(generateAdapter = true) -open class Rsp( - open val requestId: String -) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt index c78b4f5..101ccd4 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt @@ -10,12 +10,10 @@ import com.squareup.moshi.JsonClass /** * The response for the `build` method call in the Platform Channel. * - * @property requestId * @property address The [address] of the built node. * @constructor Create empty Rsp build */ @JsonClass(generateAdapter = true) data class RspBuild( - override val requestId: String, val address: String -) : Rsp(requestId) +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt index c9178e2..0efcca8 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt @@ -12,14 +12,13 @@ import com.squareup.moshi.JsonClass * It returns if the consent was applied in the *success* field. * For failed requests, a *reason* should be provided. * - * @property requestId + * @property success * @property reason * @constructor Create empty Rsp consent apply */ @JsonClass(generateAdapter = true) data class RspConsentApply( - override val requestId: String, val success: Boolean, val reason: String? = null -) : Rsp(requestId) +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt index 20761d4..afd2d0f 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt @@ -12,12 +12,11 @@ import com.squareup.moshi.JsonClass * * It returns the [consent]. Null if no consent was given. * - * @property requestId + * @property consent * @constructor Create empty Rsp consent get */ @JsonClass(generateAdapter = true) data class RspConsentGet( - override val requestId: String, val consent: TikiSdkConsent -) : Rsp(requestId) +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt index af896fd..78bc182 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt @@ -11,14 +11,13 @@ import com.squareup.moshi.JsonClass * * It returns the *message* of the error and the String representation of the [stackTrace]. * - * @property requestId + * @property message * @property stackTrace * @constructor Create empty Rsp error */ @JsonClass(generateAdapter = true) data class RspError( - override val requestId: String, val message: String, val stackTrace: String -) : Rsp(requestId) +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt index ce4cf4f..109f098 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt @@ -12,12 +12,11 @@ import com.squareup.moshi.JsonClass * * Returns the [ownership] or Null if not found. * - * @property requestId + * @property ownership * @constructor Create empty Rsp ownership */ @JsonClass(generateAdapter = true) data class RspOwnership( - override val requestId: String, val ownership: TikiSdkOwnership -) : Rsp(requestId) +) diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt new file mode 100644 index 0000000..105272f --- /dev/null +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt @@ -0,0 +1,29 @@ +package com.mytiki.tiki_sdk_android.util + +import com.squareup.moshi.* + +import java.util.* + +/** + * Time stamp to date JSON adapter for Moshi. + * + * @constructor Create empty Time stamp to date adapter + */ +class TimeStampToDateAdapter : JsonAdapter() { + + @FromJson + override fun fromJson(reader: JsonReader): Date? { + if (reader.peek() == JsonReader.Token.NULL) return reader.nextNull() + return try { + val dateAsString = reader.nextString() + Date(dateAsString.toLong()) + } catch (e: Exception) { + null + } + } + + @ToJson + override fun toJson(writer: JsonWriter, value: Date?) { + writer.value(value?.time) + } +} \ No newline at end of file diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt index 0ce7345..023030a 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt @@ -1,35 +1,42 @@ package com.mytiki.tiki_sdk_android +import com.mytiki.tiki_sdk_android.util.TimeStampToDateAdapter import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import org.junit.Assert import org.junit.Test +import java.util.* class TikiSdkConsentTest { @Test fun encode_TikiSdkConsent_from_JSON() { - val moshi: Moshi = Moshi.Builder().build() + val moshi: Moshi = Moshi.Builder() + .add(TimeStampToDateAdapter()) + .build() val adapter: JsonAdapter = moshi.adapter(TikiSdkConsent::class.java) val tikiSdkConsent = - adapter.fromJson("{\"ownershipId\":\"ownership\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}") + adapter.fromJson("{\"ownershipId\":\"ownership\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\",\"expiry\":1671842900000}") Assert.assertEquals("ownership", tikiSdkConsent?.ownershipId) Assert.assertEquals("*", tikiSdkConsent?.destination?.uses?.get(0)) Assert.assertEquals("txnId", tikiSdkConsent?.transactionId) + Assert.assertEquals(1671842900000L, tikiSdkConsent?.expiry?.time) Assert.assertNull(tikiSdkConsent?.about) Assert.assertNull(tikiSdkConsent?.reward) - Assert.assertNull(tikiSdkConsent?.expiry) } @Test fun encode_TikiSdkConsent_to_JSON() { - val moshi: Moshi = Moshi.Builder().build() + val moshi: Moshi = Moshi.Builder() + .add(TimeStampToDateAdapter()) + .build() val adapter: JsonAdapter = moshi.adapter(TikiSdkConsent::class.java) val tikiSdkConsent = TikiSdkConsent( - "ownership", TikiSdkDestination.ALL, "txnId" + "ownership", TikiSdkDestination.ALL, "txnId", null, null, Date(1671842900000L) ) + val json = adapter.toJson(tikiSdkConsent) Assert.assertEquals( - "{\"ownershipId\":\"ownership\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}", + "{\"ownershipId\":\"ownership\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\",\"expiry\":1671842900000}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt index f1c5073..142b9e0 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt @@ -14,7 +14,7 @@ class TikiSdkOwnershipTest { "{\"source\":\"source\",\"type\":\"data_point\",\"origin\":\"com.mytiki.test\",\"transactionId\":\"txnId\",\"contains\":[\"test data\"]}" val ownership = adapter.fromJson(json) Assert.assertEquals("source", ownership?.source) - Assert.assertEquals(TikiSdkDataTypeEnum.data_point.name, ownership?.type?.name) + Assert.assertEquals(TikiSdkDataTypeEnum.data_point, ownership?.type) Assert.assertEquals("com.mytiki.test", ownership?.origin) Assert.assertEquals("txnId", ownership?.transactionId) Assert.assertNull(ownership?.about) diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuildTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuildTest.kt index 552c54f..f1e0c3b 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuildTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuildTest.kt @@ -14,9 +14,8 @@ class ReqBuildTest { fun encode_ReqBuild_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqBuild::class.java) - val json = "{\"requestId\":\"reqId\",\"apiId\":\"apiId\",\"origin\":\"origin\"}" + val json = "{\"apiId\":\"apiId\",\"origin\":\"origin\"}" val reqBuild = adapter.fromJson(json) - Assert.assertEquals("reqId", reqBuild?.requestId) Assert.assertEquals("apiId", reqBuild?.apiId) Assert.assertEquals("origin", reqBuild?.origin) Assert.assertNull(reqBuild!!.address) @@ -27,10 +26,10 @@ class ReqBuildTest { fun encode_ReqBuild_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqBuild::class.java) - val req = ReqBuild("reqId", "apiId", "origin") + val req = ReqBuild("apiId", "origin") val json = adapter.toJson(req) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"apiId\":\"apiId\",\"origin\":\"origin\"}", + "{\"apiId\":\"apiId\",\"origin\":\"origin\"}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApplyTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApplyTest.kt index b361960..af214ec 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApplyTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApplyTest.kt @@ -16,10 +16,9 @@ class ReqConsentApplyTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentApply::class.java) val json = - "{\"requestId\":\"reqId\",\"source\":\"source\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}" + "{\"source\":\"source\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}" val req = adapter.fromJson(json) Assert.assertEquals(req!!.destination.paths[0], "*") - Assert.assertEquals(req.requestId, "reqId") Assert.assertEquals(req.source, "source") } @@ -27,10 +26,10 @@ class ReqConsentApplyTest { fun encode_ReqConsentApply_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentApply::class.java) - val req = ReqConsentApply("reqId", "source", TikiSdkDestination.ALL) + val req = ReqConsentApply("source", TikiSdkDestination.ALL) val json = adapter.toJson(req) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"source\":\"source\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}", + "{\"source\":\"source\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGetTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGetTest.kt index ab1a5a4..70f8c8a 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGetTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGetTest.kt @@ -14,21 +14,20 @@ class ReqConsentGetTest { fun encode_ReqConsentGet_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentGet::class.java) - val json = "{\"requestId\":\"reqId\",\"source\":\"source\",\"origin\":\"origin\"}" + val json = "{\"source\":\"source\",\"origin\":\"origin\"}" val req = adapter.fromJson(json) - Assert.assertEquals(req!!.requestId, "reqId") - Assert.assertEquals(req.source, "source") - Assert.assertEquals(req.origin, "origin") + Assert.assertEquals(req?.source, "source") + Assert.assertEquals(req?.origin, "origin") } @Test fun encode_ReqConsentGet_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentGet::class.java) - val req = ReqConsentGet("reqId", "source", "origin") + val req = ReqConsentGet("source", "origin") val json = adapter.toJson(req) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"source\":\"source\",\"origin\":\"origin\"}", + "{\"source\":\"source\",\"origin\":\"origin\"}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModifyTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModifyTest.kt index 5866f49..66ca389 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModifyTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModifyTest.kt @@ -16,21 +16,20 @@ class ReqConsentModifyTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentModify::class.java) val json = - "{\"requestId\":\"reqId\",\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}" + "{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}" val req = adapter.fromJson(json) Assert.assertEquals("*", req!!.destination.paths[0]) Assert.assertEquals("ownershipId", req.ownershipId) - Assert.assertEquals("reqId", req.requestId) } @Test fun encode_ReqConsentModify_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqConsentModify::class.java) - val req = ReqConsentModify("reqId", "ownershipId", TikiSdkDestination.ALL) + val req = ReqConsentModify("ownershipId", TikiSdkDestination.ALL) val json = adapter.toJson(req) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}", + "{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]}}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt index 66aaba4..c4e9c15 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt @@ -16,9 +16,9 @@ class ReqOwnershipAssignTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqOwnershipAssign::class.java) val json = - "{\"requestId\":\"reqId\",\"source\":\"source\",\"type\":\"data_point\",\"contains\":[\"testData\"]}" + "{\"source\":\"source\",\"type\":\"data_point\",\"contains\":[\"testData\"]}" val req = adapter.fromJson(json) - Assert.assertEquals("reqId", req!!.requestId) + Assert.assertEquals(req!!.source, "source") } @Test @@ -26,14 +26,13 @@ class ReqOwnershipAssignTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqOwnershipAssign::class.java) val req = ReqOwnershipAssign( - "reqId", "source", TikiSdkDataTypeEnum.data_point, listOf("testData") ) val json = adapter.toJson(req) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"source\":\"source\",\"type\":\"data_point\",\"contains\":[\"testData\"]}", + "{\"source\":\"source\",\"type\":\"data_point\",\"contains\":[\"testData\"]}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGetTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGetTest.kt index e09d722..4f22c26 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGetTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGetTest.kt @@ -14,17 +14,17 @@ class ReqOwnershipGetTest { fun encode_ReqOwnershipGet_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqOwnershipGet::class.java) - val json = "{\"requestId\":\"reqId\",\"source\":\"source\"}" + val json = "{\"source\":\"source\"}" val req = adapter.fromJson(json) - Assert.assertEquals("reqId", req!!.requestId) + Assert.assertEquals(req!!.source, "source") } @Test fun encode_ReqOwnershipGet_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(ReqOwnershipGet::class.java) - val req = ReqOwnershipGet("reqId", "source") + val req = ReqOwnershipGet("source") val json = adapter.toJson(req) - Assert.assertEquals("{\"requestId\":\"reqId\",\"source\":\"source\"}", json) + Assert.assertEquals("{\"source\":\"source\"}", json) } } \ No newline at end of file diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt index de89e3a..036b6c5 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt @@ -15,17 +15,17 @@ class RspBuildTest { fun encode_RspBuild_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspBuild::class.java) - val json = "{\"requestId\":\"requestId\",\"address\":\"address\"}" + val json = "{\"address\":\"address\"}" val req = adapter.fromJson(json) - Assert.assertEquals("requestId", req!!.requestId) + Assert.assertEquals("address", req!!.address) } @Test fun encode_RspBuild_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspBuild::class.java) - val req = RspBuild("requestId", "address") + val req = RspBuild("address") val json = adapter.toJson(req) - Assert.assertEquals("{\"requestId\":\"requestId\",\"address\":\"address\"}", json) + Assert.assertEquals("{\"address\":\"address\"}", json) } } \ No newline at end of file diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt index fc7a963..e06d736 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt @@ -14,17 +14,17 @@ class RspConsentApplyTest { fun encode_RspConsentApply_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspConsentApply::class.java) - val json = "{\"requestId\":\"requestId\",\"success\":true}" + val json = "{\"success\":true}" val rsp = adapter.fromJson(json) - Assert.assertEquals("requestId", rsp!!.requestId) + Assert.assertTrue(rsp!!.success) } @Test fun encode_RspConsentApply_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspConsentApply::class.java) - val rsp = RspConsentApply("requestId", true) + val rsp = RspConsentApply(true) val json = adapter.toJson(rsp) - Assert.assertEquals("{\"requestId\":\"requestId\",\"success\":true}", json) + Assert.assertEquals("{\"success\":true}", json) } } \ No newline at end of file diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt index 98f7852..241402e 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt @@ -6,6 +6,7 @@ package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.mytiki.tiki_sdk_android.TikiSdkConsent import com.mytiki.tiki_sdk_android.TikiSdkDestination +import com.mytiki.tiki_sdk_android.util.TimeStampToDateAdapter import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi import org.junit.Assert @@ -14,23 +15,27 @@ import org.junit.Test class RspConsentGetTest { @Test fun encode_RspConsentGet_from_JSON() { - val moshi: Moshi = Moshi.Builder().build() + val moshi: Moshi = Moshi.Builder() + .add(TimeStampToDateAdapter()) + .build() val adapter: JsonAdapter = moshi.adapter(RspConsentGet::class.java) val json = - "{\"requestId\":\"reqId\",\"consent\":{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}}" + "{\"consent\":{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}}" val req = adapter.fromJson(json) - Assert.assertEquals("reqId", req!!.requestId) + Assert.assertEquals(req!!.consent.ownershipId, "ownershipId") } @Test fun encode_RspConsentGet_to_JSON() { - val moshi: Moshi = Moshi.Builder().build() + val moshi: Moshi = Moshi.Builder() + .add(TimeStampToDateAdapter()) + .build() val adapter: JsonAdapter = moshi.adapter(RspConsentGet::class.java) val rsp = - RspConsentGet("reqId", TikiSdkConsent("ownershipId", TikiSdkDestination.ALL, "txnId")) + RspConsentGet(TikiSdkConsent("ownershipId", TikiSdkDestination.ALL, "txnId")) val json = adapter.toJson(rsp) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"consent\":{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}}", + "{\"consent\":{\"ownershipId\":\"ownershipId\",\"destination\":{\"paths\":[\"*\"],\"uses\":[\"*\"]},\"transactionId\":\"txnId\"}}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt index d61a561..7d0a577 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt @@ -14,19 +14,19 @@ class RspErrorTest { fun encode_RspError_from_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspError::class.java) - val json = "{\"requestId\":\"reqId\",\"message\":\"error\",\"stackTrace\":\"stackTrace\"}" + val json = "{\"message\":\"error\",\"stackTrace\":\"stackTrace\"}" val req = adapter.fromJson(json) - Assert.assertEquals("reqId", req!!.requestId) + Assert.assertEquals(req!!.message, "error") } @Test fun encode_RspError_to_JSON() { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspError::class.java) - val rsp = RspError("reqId", "error", "stackTrace") + val rsp = RspError("error", "stackTrace") val json = adapter.toJson(rsp) Assert.assertEquals( - "{\"requestId\":\"reqId\",\"message\":\"error\",\"stackTrace\":\"stackTrace\"}", + "{\"message\":\"error\",\"stackTrace\":\"stackTrace\"}", json ) } diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt index d62f0dd..39556b5 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt @@ -17,9 +17,9 @@ class RspOwnershipTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspOwnership::class.java) val json = - "{\"requestId\":\"requestId\",\"ownership\":{\"source\":\"source\",\"type\":\"data_point\",\"origin\":\"com.mytiki.rsp\",\"transactionId\":\"txnId\",\"contains\":[]}}" + "{\"ownership\":{\"source\":\"source\",\"type\":\"data_point\",\"origin\":\"com.mytiki.rsp\",\"transactionId\":\"txnId\",\"contains\":[]}}" val req = adapter.fromJson(json) - Assert.assertEquals("requestId", req!!.requestId) + Assert.assertEquals("requestId", req!!.ownership.source, "source") } @Test @@ -27,12 +27,11 @@ class RspOwnershipTest { val moshi: Moshi = Moshi.Builder().build() val adapter: JsonAdapter = moshi.adapter(RspOwnership::class.java) val rsp = RspOwnership( - "requestId", TikiSdkOwnership("source", TikiSdkDataTypeEnum.data_point, "com.mytiki.rsp", "txnId") ) val json = adapter.toJson(rsp) Assert.assertEquals( - "{\"requestId\":\"requestId\",\"ownership\":{\"source\":\"source\",\"type\":\"data_point\",\"origin\":\"com.mytiki.rsp\",\"transactionId\":\"txnId\",\"contains\":[]}}", + "{\"ownership\":{\"source\":\"source\",\"type\":\"data_point\",\"origin\":\"com.mytiki.rsp\",\"transactionId\":\"txnId\",\"contains\":[]}}", json ) } diff --git a/doc/guide/GettingStarted.md b/doc/guide/GettingStarted.md index 5db3c6c..22f9e61 100644 --- a/doc/guide/GettingStarted.md +++ b/doc/guide/GettingStarted.md @@ -26,7 +26,7 @@ repositories { Add the dependency in your App's `build.gradle` file (`PROJECT_ROOT/app/build.gradle`) ``` -implementation("com.mytiki.tiki-sdk-android:0.0.3") +implementation("com.mytiki:tiki-sdk-android:0.0.5") ``` ### Usage @@ -38,21 +38,25 @@ implementation("com.mytiki.tiki-sdk-android:0.0.3") Configuration parameters: - **apiId → String** -A unique identifier for your account. Create, revoke, and cycle Ids _(not a secret but try and treat it with care)_ at https://mytiki.com. + A unique identifier for your account. Create, revoke, and cycle Ids _(not a secret but try and treat it with care)_ at [console.mytiki.com](https://console.mytiki.com). - **origin → String** -Included in the on-chain transaction to denote the application of origination (can be overridden in individual requests). It should follow a reversed FQDN syntax. _i.e. com.mycompany.myproduct_ + Included in the on-chain transaction to denote the application of origination (can be overridden in individual requests). It should follow a reversed FQDN syntax. _i.e. com.mycompany.myproduct_ - **context → [Context](https://developer.android.com/reference/android/content/Context)** -Set the application context. Required for the [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) which communicates with the [Dart SDK](https://github.com/tiki/tiki-sdk-dart) binaries + Set the application context. Required for the [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) which communicates with the [Dart SDK](https://github.com/tiki/tiki-sdk-dart) binaries + + +- **address → String? = null** + Set the user address. If not set, a new key pair and address will be generated for the user. Example: ``` -val tiki = TikiSdk("565b3268-cdc0-4e5c-94c8-5d8f53d4577c", "com.mycompany.myproduct", context) +val tiki = TikiSdk().init("565b3268-cdc0-4e5c-94c8-5d8f53d4577c", "com.mycompany.myproduct", context) ``` #### 3. Assign ownership @@ -60,34 +64,34 @@ Data ownership can be assigned to any data point, pool, or stream, creating an i Parameters: - **source → String** -An identifier in your system corresponding to the raw data. _i.e. a user_id_ + An identifier in your system corresponding to the raw data. _i.e. a user_id_ - **type → String** -`"point"`, `"pool"`, or `"stream"` + `"data_point"`, `"data_pool"`, or `"data_stream"` + +- **contains → List<String>** + A list of metadata tags describing the represented data -- **callback → (ownershipId: String) → Unit?** -A callback function to execute on completion. Input (**String**) is the unique transaction id (use to recall the transaction record at any time) +- **origin → String? = null** + An optional override of the default origin set during initialization -- **about → String?** -An optional description to provide additional context to the transaction. Most typically as human-readable text. +- **about → String? = null** + An optional description to provide additional context to the transaction. Most typically as human-readable text. -- **contains → List<String>** -A list of metadata tags describing the represented data +Returns: - -- **origin → String?** -An optional override of the default origin set during initialization +- **String** + The unique transaction id (use to recall the transaction record at any time) Example: ``` -val callback = { response: String -> print(response) } -tiki.assignOwnership("12345", "point", callback, listOf("email_address")) +val oid = tiki.assignOwnership("12345", TikiSdkDataTypeEnum.data_point, listOf("email_address")) ``` #### 4. Modify consent @@ -95,33 +99,32 @@ Consent is given (or revoked) for data ownership records. Consent defines "who" Parameters: - **ownershipId → String** -The transaction id for the ownership grant + The transaction id for the ownership grant - **destination → [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination)** -A collection of paths and application use cases that consent has been granted (or revoked) for. + A collection of paths and application use cases that consent has been granted (or revoked) for. -- **callback → ([TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent) → Unit?)** -A callback function executed on completion. Input (**[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)**) is the modified consent. +- **about → String? = null** + An optional description to provide additional context to the transaction. Most typically as human-readable text. -- **about → String?** -An optional description to provide additional context to the transaction. Most typically as human-readable text. +- **reward → String? = null** + An optional definition of a reward promised to the user in exchange for consent. -- **reward → String?** -An optional definition of a reward promised to the user in exchange for consent. +- **expiry → [LocalDateTime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-local-date-time/-local-date-time.html)? = null** + The date upon which the consent is no longer valid. If not set, consent is perpetual. +Returns: -- **expiry → [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)?** -The date upon which the consent is no longer valid. If not set, consent is perpetual. +- **[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)** + the modified `TikiSdkConsent` Example: ``` -tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*")), { - response: TikiSdkConsent -> print(response) -}); +val consent = tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*"))) ``` #### 5. Apply consent @@ -129,25 +132,29 @@ Apply consent to a data transaction. If consent is granted for the `source` and Parameters: - **source → String** -An identifier in your system corresponding to the raw data. -_i.e. a user_id_ + An identifier in your system corresponding to the raw data. + _i.e. a user_id_ - **destination → [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination)** -The destination(s) and use case(s) for the request. + The destination(s) and use case(s) for the request. + + +- **request → () → Unit** + The function to execute if consent granted -- **request → ((String) → Unit)** -The function to execute if consent granted +- **onBlocked → (value: String) → Unit? = null** + An optional function to execute if consent is denied. -- **onBlocked → ((String) → Unit)** -An optional function to execute if consent is denied. +- **origin → String? = null** + An optional override of the default origin set during initialization Example: ``` applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { - _: String -> print("Consent Approved. Send data to backend.") + print("Consent Approved. Send data to backend.") }); ``` \ No newline at end of file diff --git a/doc/ref/KotlinDocs.md b/doc/ref/KotlinDocs.md index 3d9fd12..7c98789 100644 --- a/doc/ref/KotlinDocs.md +++ b/doc/ref/KotlinDocs.md @@ -3,7 +3,7 @@ title: Kotlin Docs category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-docs hidden: false -order: 5 +order: 6 type: link link_url: https://tiki-sdk-android.docs.mytiki.com/ --- \ No newline at end of file diff --git a/doc/ref/Source.md b/doc/ref/Source.md index 96a4b14..9a80ce2 100644 --- a/doc/ref/Source.md +++ b/doc/ref/Source.md @@ -1,9 +1,4 @@ --- -title: Source Code -category: 6386a02f5b7bf00510590f34 -slug: tiki-sdk-android-source -hidden: false -order: 4 -type: link -link_url: https://github.com/tiki/tiki-sdk-android +title: Source Code category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-source hidden: false +order: 5 type: link link_url: https://github.com/tiki/tiki-sdk-android --- diff --git a/doc/ref/TikiSdk.md b/doc/ref/TikiSdk.md index a7106ea..dd30d1a 100644 --- a/doc/ref/TikiSdk.md +++ b/doc/ref/TikiSdk.md @@ -1,140 +1,213 @@ --- -title: TikiSdk -excerpt: The primary object for interacting with the TIKI infrastructure. Use `TikiSdk` to assign ownership, modify, and apply consent. -category: 6386a02f5b7bf00510590f34 -slug: tiki-sdk-android-tiki-sdk -hidden: false -order: 1 +title: TikiSdk excerpt: The primary object for interacting with the TIKI infrastructure. +Use `TikiSdk` to assign ownership, modify, and apply consent. category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk hidden: false order: 1 --- ## Constructors -##### TikiSdk (apiId: String, origin: String, context: [Context](https://developer.android.com/reference/android/content/Context)) +##### TikiSdk (...) + +Creates an empty TikiSdk. ## Methods -##### assignOwnership(source: String, type: String, callback: (ownershipId: String) → Unit? = null, contains: List<String>? = null, about: String? = null, origin: String? = null) -Data ownership can be assigned to any data point, pool, or stream, creating an immutable, on-chain record. +##### init(...) → String + +Initializes the TIKI SDK. It should be called before any other method. It sets up Flutter Engine and +Platform Channel and builds the core of the TIKI SDK, calling TIKI SDK Dart through the Flutter +Platform Channel. + +Parameters: + +- **apiId → String** + A unique identifier for your account. Create, revoke, and cycle Ids (not a secret but try and + treat it with care) at [console.mytiki.com](https://console.mytiki.com). + + +- **origin → String** + Included in the on-chain transaction to denote the application of origination (can be overridden + in individual requests). It should follow a reversed FQDN syntax. i.e. com.mycompany.myproduct + + +- **context → [Context](https://developer.android.com/reference/android/content/Context)** + Set the application context. Required for + the [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) which + communicates with the [Dart SDK](https://github.com/tiki/tiki-sdk-dart) binaries + + +- **address → String? = null** + Set the user address (primarily for restoring the state on launch). If not set, a new key pair and + address will be generated for the user. + +##### assignOwnership(...) → String + +Data ownership can be assigned to any data point, pool, or stream, creating an immutable, on-chain +record. Parameters: + - **source → String** -An identifier in your system corresponding to the raw data. -_i.e. a user_id_ + An identifier in your system corresponding to the raw data. + _i.e. a user_id_ - **type → String** -One of `"point"`, `"pool"`, or `"stream"` + One of `"point"`, `"pool"`, or `"stream"` -- **callback → (ownershipId: String) → Unit?** -A callback function to execute on completion. Input (**String**) is the unique transaction id (use to recall the transaction record at any time) +- **contains → List<String>** + A list of metadata tags describing the represented data -- **contains → List<String>** -A list of metadata tags describing the represented data +- **origin → String? = null** + An optional override of the default origin set during initialization -- **origin → String?** -An optional override of the default origin set during initialization +- **about → String? = null** + An optional description to provide additional context to the transaction. Most typically as + human-readable text. +Returns: -- **about → String?** -An optional description to provide additional context to the transaction. Most typically as human-readable text. +- **String** + The unique transaction id (use to recall the transaction record at any time) Example: ``` -val callback = { response: String -> print(response) } -tiki.assignOwnership("12345", "point", callback, listOf("email_address")) +val tid = tiki.assignOwnership("12345", TikiSdkDataTypeEnum.data_point, listOf("email_address")) ```   -##### modifyConsent(ownershipId: String, destination: [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination), callback: (TikiSdkConsent) -> Unit? = null, about: String? = null, reward: String? = null, expiry: [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)? = null) -Consent is given (or revoked) for data ownership records. Consent defines "who" the data owner has given utilization rights. +##### modifyConsent(...) → [TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent) + +Consent is given (or revoked) for data ownership records. Consent defines "who" the data owner has +given utilization rights. Parameters: + - **ownershipId → String** -The transaction id for the ownership grant + The transaction id for the ownership grant - **destination → [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination)** -A collection of paths and application use cases that consent has been granted (or revoked) for. + A collection of paths and application use cases that consent has been granted (or revoked) for. -- **callback → ([TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent) → Unit?)** -A callback function executed on completion. Input (**[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)**) is the modified consent. +- **about → String? = null** + An optional description to provide additional context to the transaction. Most typically as + human-readable text. -- **about → String?** -An optional description to provide additional context to the transaction. Most typically as human-readable text. +- **reward → String? = null** + An optional definition of a reward promised to the user in exchange for consent. -- **reward → String?** -An optional definition of a reward promised to the user in exchange for consent. +- **expiry + → [LocalDateTime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-local-date-time/-local-date-time.html) + ? = null** + The date upon which the consent is no longer valid. If not set, consent is perpetual. +Returns: -- **expiry → [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)?** -The date upon which the consent is no longer valid. If not set, consent is perpetual. +- **[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)** + the modified `TikiSdkConsent` Example: + ``` -tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*")), { - response: TikiSdkConsent -> print(response) -}) +val consent = tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*"))) ```   -##### getConsent(source: String, callback: ([TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)) -> Unit? = null, origin: String?) -Get the latest `TikiSdkConsent` for a `source` and `origin`. If `origin` is unset, the default set during construction is used. +##### getOwnership(source: String, origin: String?) → [TikiSdkOwnership](tiki-sdk-android-tiki-sdk-ownership)? + +Get the `TikiSdkOwnership` for a `source` and `origin`. If `origin` is unset, the default set during +construction is used. Parameters: + - **source → String** An identifier in your system corresponding to the raw data. _i.e. a user_id_ +- **origin → String? = null** + An optional override of the default origin set during initialization -- **callback → ([TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent) → Unit?)** - A callback function executed on completion. Input (**[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)**) is the returned consent. +Returns: +- **[TikiSdkOwnership](tiki-sdk-android-tiki-sdk-ownership)?** + the assigned `TikiSdkOwnership` -- **origin → String?** -An optional override of the default origin set during initialization +Example: + +``` +val ownership = tiki.getOwnership("12345") +``` + +  + +##### getConsent(source: String, origin: String?) → [TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)? + +Get the latest `TikiSdkConsent` for a `source` and `origin`. If `origin` is unset, the default set +during construction is used. + +Parameters: + +- **source → String** + An identifier in your system corresponding to the raw data. + _i.e. a user_id_ + +- **origin → String? = null** + An optional override of the default origin set during initialization + +Returns: + +- **[TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)?** + the latest `TikiSdkConsent` Example: + ``` -tiki.getConsent("12345", { - response: TikiSdkConsent -> print(response) -}); +val consent = tiki.getConsent("12345") ```   -##### applyConsent(source: String, destination: [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination), request: (String) → Unit, onBlocked: (String) → Unit) -Apply consent to a data transaction. If consent is granted for the `source` and `destination` and has not expired, the request is executed. +##### applyConsent(...) + +Apply consent to a data transaction. If consent is granted for the `source` and `destination` and +has not expired, the request is executed. Parameters: + - **source → String** -An identifier in your system corresponding to the raw data. -_i.e. a user_id_ + An identifier in your system corresponding to the raw data. + _i.e. a user_id_ - **destination → [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination)** -The destination(s) and use case(s) for the request. + The destination(s) and use case(s) for the request. + +- **request → () → Unit** + The function to execute if consent granted -- **request → ((String) → Unit)** -The function to execute if consent granted +- **onBlocked → (value: String) → Unit? = null** + An optional function to execute if consent is denied. -- **onBlocked → ((String) → Unit)** -An optional function to execute if consent is denied. +- **origin → String? = null** + An optional override of the default origin set during initialization Example: + ``` applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { - _: String -> print("Consent Approved. Send data to backend.") + print("Consent Approved. Send data to backend.") }) ``` \ No newline at end of file diff --git a/doc/ref/TikiSdkConsent.md b/doc/ref/TikiSdkConsent.md index fa4f65c..4ddaa9a 100644 --- a/doc/ref/TikiSdkConsent.md +++ b/doc/ref/TikiSdkConsent.md @@ -1,44 +1,44 @@ --- -title: TikiSdkConsent -excerpt: A Consent Object. Representative of the NFT created on-chain. Requires a corresponding Data Ownership NFT (see [TikiSdk](tiki-sdk-android-tiki-sdk)). -category: 6386a02f5b7bf00510590f34 -slug: tiki-sdk-android-tiki-sdk-consent -hidden: false -order: 3 +title: TikiSdkConsent excerpt: A Consent Object. Representative of the NFT created on-chain. +Requires a corresponding Data Ownership NFT (see [TikiSdk](tiki-sdk-android-tiki-sdk)). category: +6386a02f5b7bf00510590f34 slug: tiki-sdk-android-tiki-sdk-consent hidden: false order: 3 --- ## Constructors -##### TikiSdkConsent(ownershipId: String, destination: [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination), about: String, reward: String, transactionId: String, expiry: [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)}) -Builds a TikiSdkConsent for the data identified by `ownershipId`. - -## Companions +##### TikiSdkConsent(ownershipId: String, destination: [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination), about: String, reward: String, transactionId: String, expiry: [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)}) -##### fromJson(jsonString: String) : TikiSdkConsent -Builds a TikiSdkConsent from a JSON string +Builds a TikiSdkConsent for the data identified by `ownershipId`. ## Properties ##### ownershipId ↔ String + The data ownership transaction ID corresponding to the data source consent applies to. _read / write_ ##### destination ↔ [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination) + The destination describing the allowed/disallowed paths and use cases for the consent. _read / write_ ##### reward ↔ String + An optional description of the reward owed to user in exchange for consent. _read / write_ ##### about ↔ String -An optional description to provide additional context to the transaction. Most typically as human-readable text. + +An optional description to provide additional context to the transaction. Most typically as +human-readable text. _read / write_ ##### transactionId ↔ String + The transaction id for `this` _read / write_ -##### expiry ↔ [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html) -The date the consent is valid until. Do not set (`null`) for perpetual consent. +##### expiry ↔ [LocalDateTime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-local-date-time/-local-date-time.html) + +The date the consent is valid until. Do not set (e.g., `null`) for perpetual consent. _read / write_ \ No newline at end of file diff --git a/doc/ref/TikiSdkDataTypeEnum.md b/doc/ref/TikiSdkDataTypeEnum.md new file mode 100644 index 0000000..6f12d43 --- /dev/null +++ b/doc/ref/TikiSdkDataTypeEnum.md @@ -0,0 +1,20 @@ +--- +title: TikiSdkDataTypeEnum excerpt: An enumeration of the supported data aggregation types. +category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-tiki-sdk-data-type-enum hidden: false +order: 4 +--- + +## Entries + +##### data_point → TikiSdkDataTypeEnum + +A singular data object/field i.e email address or image + +#### data_pool → TikiSdkDataTypeEnum + +An aggregation of multiple data fields and objects connected to a specific identifier. i.e. a user's +profile or purchase history + +#### data_stream → TikiSdkDataTypeEnum + +An ongoing flow of user data on regular basis. i.e. in-app analytics or location data \ No newline at end of file diff --git a/doc/ref/TikiSdkDestination.md b/doc/ref/TikiSdkDestination.md index 8f64e06..e880838 100644 --- a/doc/ref/TikiSdkDestination.md +++ b/doc/ref/TikiSdkDestination.md @@ -1,34 +1,35 @@ --- -title: TikiSdkDestination -excerpt: Defines destinations and use cases (optional) allowed or disallowed. Serializable for inclusion in transactions. -category: 6386a02f5b7bf00510590f34 -slug: tiki-sdk-android-tiki-sdk-destination -hidden: false -order: 2 +title: TikiSdkDestination excerpt: Defines destinations and use cases (optional) allowed or +disallowed. Serializable for inclusion in transactions. category: 6386a02f5b7bf00510590f34 slug: +tiki-sdk-android-tiki-sdk-destination hidden: false order: 2 --- ## Constructors ##### TikiSdkDestination(uses: List<String>, paths: List<String>) + Creates a new destination from a list of `paths` and `uses`. -## Companions +## Types + +##### ALL : TikiSdkDestination + +Create a TikiSdkDestination allowing all paths and uses (`[*]`) -##### fromJson(jsonString: String) : TikiSdkDestination -Builds a TikiSdkDestination from a JSON string +##### NONE : TikiSdkDestination + +Create a TikiSdkDestination disallowing all paths and uses (`[]`) ## Properties ##### uses → List<String> -A list of application specific uses cases applicable to the given destination. Prefix with NOT to invert. -_i.e. NOT ads_ -##### paths → List<String> -A list of paths, preferably URLs (without the scheme) or reverse FQDN. -Keep list short and use wildcard matching. Prefix with NOT to invert. -_i.e. NOT mytiki.com/ +A list of application specific uses cases applicable to the given destination. Prefix with NOT to +invert. +_i.e. NOT ads_ -## Methods +##### paths → List<String> -##### toJson() → String -Serialize the destination as a human-readable JSON string. \ No newline at end of file +A list of paths, preferably URLs (without the scheme) or reverse FQDN. Keep list short and use +wildcard matching. Prefix with NOT to invert. +_i.e. NOT mytiki.com/ \ No newline at end of file diff --git a/integration_tests/.gitignore b/integration_tests/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/integration_tests/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/integration_tests/build.gradle b/integration_tests/build.gradle new file mode 100644 index 0000000..932e4c5 --- /dev/null +++ b/integration_tests/build.gradle @@ -0,0 +1,10 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. +plugins { + id 'com.android.application' version '7.2.1' apply false + id 'com.android.library' version '7.2.1' apply false + id 'org.jetbrains.kotlin.android' version '1.7.10' apply false +} + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/integration_tests/gradle.properties b/integration_tests/gradle.properties new file mode 100644 index 0000000..cd0519b --- /dev/null +++ b/integration_tests/gradle.properties @@ -0,0 +1,23 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app"s APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true \ No newline at end of file diff --git a/integration_tests/gradle/wrapper/gradle-wrapper.jar b/integration_tests/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/integration_tests/gradle/wrapper/gradle-wrapper.jar differ diff --git a/integration_tests/gradle/wrapper/gradle-wrapper.properties b/integration_tests/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..4fcf33c --- /dev/null +++ b/integration_tests/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Thu Dec 22 15:53:15 BRT 2022 +distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME diff --git a/integration_tests/gradlew b/integration_tests/gradlew new file mode 100755 index 0000000..4f906e0 --- /dev/null +++ b/integration_tests/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/integration_tests/gradlew.bat b/integration_tests/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/integration_tests/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/integration_tests/integration_tests/.gitignore b/integration_tests/integration_tests/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/integration_tests/integration_tests/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/integration_tests/integration_tests/build.gradle b/integration_tests/integration_tests/build.gradle new file mode 100644 index 0000000..aa54342 --- /dev/null +++ b/integration_tests/integration_tests/build.gradle @@ -0,0 +1,45 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' + id 'kotlin-android-extensions' +} + +android { + compileSdk 33 + + defaultConfig { + applicationId "com.mytiki.tiki_sdk_android.integration_tests" + minSdk 21 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + implementation 'androidx.core:core-ktx:1.9.0' + implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'com.google.android.material:material:1.7.0' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" + testImplementation 'junit:junit:4.13.2' + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" + androidTestImplementation 'androidx.test.ext:junit:1.1.4' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' + implementation fileTree(include: ["app-debug.aar"], dir: '../../app/build/outputs/aar/') +} \ No newline at end of file diff --git a/integration_tests/integration_tests/proguard-rules.pro b/integration_tests/integration_tests/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/integration_tests/integration_tests/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/integration_tests/integration_tests/src/androidTest/java/com/mytiki/tiki_sdk_android/integration_tests/TikiSdkTest.kt b/integration_tests/integration_tests/src/androidTest/java/com/mytiki/tiki_sdk_android/integration_tests/TikiSdkTest.kt new file mode 100644 index 0000000..cd6db53 --- /dev/null +++ b/integration_tests/integration_tests/src/androidTest/java/com/mytiki/tiki_sdk_android/integration_tests/TikiSdkTest.kt @@ -0,0 +1,146 @@ +package com.mytiki.tiki_sdk_android.integration_tests + +import android.os.Handler +import android.util.Log +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import com.mytiki.tiki_sdk_android.TikiSdk +import com.mytiki.tiki_sdk_android.TikiSdkDataTypeEnum +import com.mytiki.tiki_sdk_android.TikiSdkDestination +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.async +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import kotlinx.coroutines.withContext +import org.junit.Assert +import org.junit.Test +import org.junit.runner.RunWith + + +@RunWith(AndroidJUnit4::class) +class TikiSdkTest { + + private val apiId: String = "2b8de004-cbe0-4bd5-bda6-b266d54f5c90" + private val origin: String = "com.mytiki.tiki_sdk_android.test" + + + @Test + fun init_tiki_sdk() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk? = null + runTest { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + assert(tikiSdk!!.address.length > 32) + } + } + + @Test + fun init_tiki_sdk_with_address() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk? = null + var tikiSdk2: TikiSdk? = null + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val address = tikiSdk!!.address + tikiSdk2 = TikiSdk().init(apiId, origin, context, address).await() + Assert.assertEquals(tikiSdk!!.address, tikiSdk2!!.address) + } + } + } + + @Test + fun assign_onwership() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val ownershipId = tikiSdk.assignOwnership( + "source", + TikiSdkDataTypeEnum.data_point, + listOf("test") + ) + assert(ownershipId.length > 32) + } + } + } + + @Test + fun get_onwership() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val ownershipId = tikiSdk.assignOwnership( + "source", + TikiSdkDataTypeEnum.data_point, + listOf("test") + ) + val ownership = tikiSdk.getOwnership("source") + Assert.assertEquals(ownershipId, ownership!!.transactionId) + } + } + } + + @Test + fun modify_consent() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val ownershipId = tikiSdk.assignOwnership( + "source", + TikiSdkDataTypeEnum.data_point, + listOf("test") + ) + val consent = tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) + Assert.assertEquals(consent.ownershipId, ownershipId) + } + } + } + + @Test + fun get_consent() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val ownershipId = tikiSdk.assignOwnership( + "source", + TikiSdkDataTypeEnum.data_point, + listOf("test") + ) + val consent = tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) + val consentGet = tikiSdk.getConsent("source") + Assert.assertEquals(consent.transactionId, consentGet!!.transactionId) + } + } + } + + @Test + fun apply_consent() { + val context = InstrumentationRegistry.getInstrumentation().targetContext + var tikiSdk: TikiSdk + runTest { + withContext(Dispatchers.Main) { + tikiSdk = TikiSdk().init(apiId, origin, context).await() + val ownershipId = + tikiSdk.assignOwnership( + "source", + TikiSdkDataTypeEnum.data_point, + listOf("test") + ) + tikiSdk.modifyConsent(ownershipId, TikiSdkDestination.ALL) + var ok = false + tikiSdk.applyConsent("source", TikiSdkDestination.ALL, { + ok = true + }) + assert(ok) + } + } + } +} \ No newline at end of file diff --git a/integration_tests/integration_tests/src/main/AndroidManifest.xml b/integration_tests/integration_tests/src/main/AndroidManifest.xml new file mode 100644 index 0000000..eb135e7 --- /dev/null +++ b/integration_tests/integration_tests/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/integration_tests/src/main/java/com/mytiki/tiki_sdk_android/integration_tests/MainActivity.kt b/integration_tests/integration_tests/src/main/java/com/mytiki/tiki_sdk_android/integration_tests/MainActivity.kt new file mode 100644 index 0000000..a9a0998 --- /dev/null +++ b/integration_tests/integration_tests/src/main/java/com/mytiki/tiki_sdk_android/integration_tests/MainActivity.kt @@ -0,0 +1,28 @@ +package com.mytiki.tiki_sdk_android.integration_tests + +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import com.mytiki.tiki_sdk_android.TikiSdk +import kotlinx.android.synthetic.main.activity_main.* +import kotlinx.coroutines.* +import java.lang.Exception + +class MainActivity : AppCompatActivity() { + var tikiSdk: TikiSdk? = null + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + val scope = MainScope() + button.setOnClickListener { + scope.launch { + tikiSdk = TikiSdk().init( + "b213d6bd-ccff-45c2-805e-4f0062d4ad5e", + "com.mytiki.tiki_sdk_android.integration_tests", + applicationContext + ).await() + Log.e("TEST", "addr: " + tikiSdk?.address) + } + } + } +} \ No newline at end of file diff --git a/integration_tests/integration_tests/src/main/res/drawable-v24/ic_launcher_foreground.xml b/integration_tests/integration_tests/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/integration_tests/integration_tests/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/integration_tests/integration_tests/src/main/res/drawable/ic_launcher_background.xml b/integration_tests/integration_tests/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/integration_tests/integration_tests/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration_tests/integration_tests/src/main/res/layout/activity_main.xml b/integration_tests/integration_tests/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..35f6ea8 --- /dev/null +++ b/integration_tests/integration_tests/src/main/res/layout/activity_main.xml @@ -0,0 +1,19 @@ + + + +