@@ -534,6 +534,31 @@ class MParticleModule(
534534 }
535535 }
536536
537+ @ReactMethod
538+ override fun setDeviceConsentState (consentState : ReadableMap ? ) {
539+ val instance = MParticle .getInstance() ? : return
540+ if (consentState == null ) {
541+ return
542+ }
543+ val state = convertToConsentState(consentState)
544+ instance.setDeviceConsentState(if (isEmptyConsentState(state)) null else state)
545+ }
546+
547+ @ReactMethod
548+ override fun clearDeviceConsentState () {
549+ MParticle .getInstance()?.setDeviceConsentState(null )
550+ }
551+
552+ @ReactMethod
553+ override fun getDeviceConsentState (callback : Callback ) {
554+ val instance = MParticle .getInstance()
555+ if (instance == null ) {
556+ callback.invoke(null )
557+ return
558+ }
559+ callback.invoke(consentStateToMap(instance.getDeviceConsentState()))
560+ }
561+
537562 protected fun getWritableMap (): WritableMap = WritableNativeMap ()
538563
539564 private fun convertIdentityAPIRequest (map : ReadableMap ? ): IdentityApiRequest {
@@ -928,17 +953,30 @@ class MParticleModule(
928953 map.getString(" location" )?.let { builder.location(it) }
929954 }
930955 if (map.hasKey(" timestamp" )) {
931- try {
932- val timestampString = map.getString(" timestamp" )
933- val timestamp = timestampString?.toLong()
934- timestamp?.let { builder.timestamp(it) }
935- } catch (ex: Exception ) {
936- Logger .warning(" failed to convert \" timestamp\" value to Long" )
937- }
956+ readConsentTimestampMillis(map, " timestamp" )?.let { builder.timestamp(it) }
938957 }
939958 return builder.build()
940959 }
941960
961+ private fun readConsentTimestampMillis (
962+ map : ReadableMap ,
963+ key : String ,
964+ ): Long? {
965+ if (! map.hasKey(key)) {
966+ return null
967+ }
968+ return try {
969+ when (map.getType(key)) {
970+ ReadableType .Number -> map.getDouble(key).toLong()
971+ ReadableType .String -> map.getString(key)?.toLongOrNull()
972+ else -> null
973+ }
974+ } catch (ex: Exception ) {
975+ Logger .warning(" failed to convert \" $key \" timestamp value to Long" )
976+ null
977+ }
978+ }
979+
942980 private fun convertToCCPAConsent (map : ReadableMap ): CCPAConsent ? {
943981 val consented =
944982 try {
@@ -963,14 +1001,67 @@ class MParticleModule(
9631001 map.getString(" location" )?.let { builder.location(it) }
9641002 }
9651003 if (map.hasKey(" timestamp" )) {
966- try {
967- val timestampString = map.getString(" timestamp" )
968- val timestamp = timestampString?.toLong()
969- timestamp?.let { builder.timestamp(it) }
970- } catch (ex: Exception ) {
971- Logger .warning(" failed to convert \" timestamp\" value to Long" )
1004+ readConsentTimestampMillis(map, " timestamp" )?.let { builder.timestamp(it) }
1005+ }
1006+ return builder.build()
1007+ }
1008+
1009+ private fun convertToConsentState (map : ReadableMap ): ConsentState {
1010+ val builder = ConsentState .builder()
1011+ if (map.hasKey(" gdpr" )) {
1012+ map.getMap(" gdpr" )?.let { gdprMap ->
1013+ val iterator = gdprMap.keySetIterator()
1014+ while (iterator.hasNextKey()) {
1015+ val purpose = iterator.nextKey()
1016+ val consentMap = gdprMap.getMap(purpose) ? : continue
1017+ convertToGDPRConsent(consentMap)?.let { builder.addGDPRConsentState(purpose, it) }
1018+ }
1019+ }
1020+ }
1021+ if (map.hasKey(" ccpa" )) {
1022+ map.getMap(" ccpa" )?.let { ccpaMap ->
1023+ convertToCCPAConsent(ccpaMap)?.let { builder.setCCPAConsentState(it) }
9721024 }
9731025 }
9741026 return builder.build()
9751027 }
1028+
1029+ private fun isEmptyConsentState (state : ConsentState ) = state.gdprConsentState.isEmpty() && state.ccpaConsentState == null
1030+
1031+ private fun consentStateToMap (state : ConsentState ? ): WritableMap ? {
1032+ if (state == null ) {
1033+ return null
1034+ }
1035+ val result = Arguments .createMap()
1036+ val gdprConsentState = state.gdprConsentState
1037+ if (gdprConsentState.isNotEmpty()) {
1038+ val gdprMap = Arguments .createMap()
1039+ for ((purpose, consent) in gdprConsentState) {
1040+ gdprMap.putMap(purpose, gdprConsentToMap(consent))
1041+ }
1042+ result.putMap(" gdpr" , gdprMap)
1043+ }
1044+ state.ccpaConsentState?.let { result.putMap(" ccpa" , ccpaConsentToMap(it)) }
1045+ return if (result.toHashMap().isEmpty()) null else result
1046+ }
1047+
1048+ private fun gdprConsentToMap (consent : GDPRConsent ): WritableMap {
1049+ val map = Arguments .createMap()
1050+ map.putBoolean(" consented" , consent.isConsented)
1051+ consent.document?.let { map.putString(" document" , it) }
1052+ consent.location?.let { map.putString(" location" , it) }
1053+ consent.hardwareId?.let { map.putString(" hardwareId" , it) }
1054+ consent.timestamp?.let { map.putDouble(" timestamp" , it.toDouble()) }
1055+ return map
1056+ }
1057+
1058+ private fun ccpaConsentToMap (consent : CCPAConsent ): WritableMap {
1059+ val map = Arguments .createMap()
1060+ map.putBoolean(" consented" , consent.isConsented)
1061+ consent.document?.let { map.putString(" document" , it) }
1062+ consent.location?.let { map.putString(" location" , it) }
1063+ consent.hardwareId?.let { map.putString(" hardwareId" , it) }
1064+ consent.timestamp?.let { map.putDouble(" timestamp" , it.toDouble()) }
1065+ return map
1066+ }
9761067}
0 commit comments