Skip to content

Commit

Permalink
Merge pull request #22 from atomicrobot/main
Browse files Browse the repository at this point in the history
Pull out static values that were causing exceptions when launching from a background Firebase message
  • Loading branch information
asmodeoux committed Nov 13, 2023
2 parents c3854b0 + 7257cee commit 816afcb
Show file tree
Hide file tree
Showing 11 changed files with 151 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,9 @@ object Mapper {
return result
}

fun chatClientToMap(chatClient: ConversationsClient): Map<String, Any> {
fun chatClientToMap(pluginInstance: TwilioConversationsPlugin, chatClient: ConversationsClient): Map<String, Any> {
return mapOf(
"channels" to channelsToMap(chatClient.myConversations),
"channels" to channelsToMap(pluginInstance, chatClient.myConversations),
"myIdentity" to chatClient.myIdentity,
"connectionState" to chatClient.connectionState.toString(),
"users" to usersToMap(chatClient.subscribedUsers),
Expand Down Expand Up @@ -121,33 +121,33 @@ object Mapper {
}
}

private fun channelsToMap(channels: List<Conversation>): Map<String, Any> {
val subscribedChannelsMap = channels.map { channelToMap(it) }
private fun channelsToMap(pluginInstance: TwilioConversationsPlugin, channels: List<Conversation>): Map<String, Any> {
val subscribedChannelsMap = channels.map { channelToMap(pluginInstance, it) }
return mapOf(
"subscribedChannels" to subscribedChannelsMap
)
}

fun channelToMap(channel: Conversation?): Map<String, Any?>? {
fun channelToMap(pluginInstance: TwilioConversationsPlugin, channel: Conversation?): Map<String, Any?>? {
if (channel == null) {
return null
}

// Setting flutter event listener for the given channel if one does not yet exist.
if (!TwilioConversationsPlugin.channelChannels.containsKey(channel.sid)) {
TwilioConversationsPlugin.channelChannels[channel.sid] = EventChannel(TwilioConversationsPlugin.messenger, "flutter_twilio_conversations/${channel.sid}")
TwilioConversationsPlugin.channelChannels[channel.sid]?.setStreamHandler(object : EventChannel.StreamHandler {
if (!pluginInstance.channelChannels.containsKey(channel.sid)) {
pluginInstance.channelChannels[channel.sid] = EventChannel(pluginInstance.messenger, "flutter_twilio_conversations/${channel.sid}")
pluginInstance.channelChannels[channel.sid]?.setStreamHandler(object : EventChannel.StreamHandler {
override fun onListen(arguments: Any?, events: EventChannel.EventSink) {
Log.d("TwilioInfo", "Mapper.channelToMap => EventChannel for Channel(${channel.sid}) attached")
TwilioConversationsPlugin.channelListeners[channel.sid] = ChannelListener(events)
channel.addListener(TwilioConversationsPlugin.channelListeners[channel.sid])
pluginInstance.channelListeners[channel.sid] = ChannelListener(pluginInstance, events)
channel.addListener(pluginInstance.channelListeners[channel.sid])
}

override fun onCancel(arguments: Any?) {
Log.d("TwilioInfo", "Mapper.channelToMap => EventChannel for Channel(${channel.sid}) detached")
channel.removeListener(TwilioConversationsPlugin.channelListeners[channel.sid])
TwilioConversationsPlugin.channelListeners.remove(channel.sid)
TwilioConversationsPlugin.channelChannels.remove(channel.sid)
channel.removeListener(pluginInstance.channelListeners[channel.sid])
pluginInstance.channelListeners.remove(channel.sid)
pluginInstance.channelChannels.remove(channel.sid)
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import android.util.Log
import com.twilio.conversations.CallbackListener
import com.twilio.conversations.ConversationsClient
import com.twilio.util.ErrorInfo
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
Expand All @@ -20,27 +21,26 @@ import twilio.flutter.twilio_conversations.methods.MessagesMethods
import twilio.flutter.twilio_conversations.methods.UserMethods
import twilio.flutter.twilio_conversations.methods.UsersMethods

class PluginHandler(private val applicationContext: Context) : MethodCallHandler {

override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: MethodChannel.Result) {
class PluginHandler(private val pluginInstance: TwilioConversationsPlugin, private val applicationContext: Context) : MethodCallHandler {
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.onMethodCall => received ${call.method}")
if (call.method != "cancel" && call.method != "listen") {
when (call.method) {
"debug" -> debug(call, result)
"create" -> create(call, result)
"registerForNotification" -> TwilioConversationsPlugin.instance.registerForNotification(call, result)
"unregisterForNotification" -> TwilioConversationsPlugin.instance.unregisterForNotification(call, result)
"handleReceivedNotification" -> TwilioConversationsPlugin.instance.handleReceivedNotification(call, result)
"registerForNotification" -> pluginInstance.registerForNotification(call, result)
"unregisterForNotification" -> pluginInstance.unregisterForNotification(call, result)
"handleReceivedNotification" -> pluginInstance.handleReceivedNotification(call, result)

"ChatClient#updateToken" -> ChatClientMethods.updateToken(call, result)
"ChatClient#shutdown" -> ChatClientMethods.shutdown(call, result)

"User#unsubscribe" -> UserMethods.unsubscribe(call, result)

"Users#getChannelUserDescriptors" -> UsersMethods.getChannelUserDescriptors(call, result)
"Users#getUserDescriptor" -> UsersMethods.getUserDescriptor(call, result)
"Users#getAndSubscribeUser" -> UsersMethods.getAndSubscribeUser(call, result)

"Channel#join" -> ChannelMethods.join(call, result)
"Channel#leave" -> ChannelMethods.leave(call, result)
"Channel#typing" -> ChannelMethods.typing(call, result)
Expand All @@ -55,27 +55,27 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler
"Channel#setNotificationLevel" -> ChannelMethods.setNotificationLevel(call, result)
"Channel#getUniqueName" -> ChannelMethods.getUniqueName(call, result)
"Channel#setUniqueName" -> ChannelMethods.setUniqueName(call, result)
"Channels#getChannel" -> ChannelsMethods.getChannel(call, result)

"Channels#getChannel" -> ChannelsMethods.getChannel(pluginInstance, call, result)
"Channels#getPublicChannelsList" -> ChannelsMethods.getPublicChannelsList(call, result)
"Channels#getUserChannelsList" -> ChannelsMethods.getUserChannelsList(call, result)
"Channels#createChannel" -> ChannelsMethods.createChannel(call, result)
"Channels#createChannel" -> ChannelsMethods.createChannel(pluginInstance, call, result)

"Member#getUserDescriptor" -> MemberMethods.getUserDescriptor(call, result)
"Member#getAndSubscribeUser" -> MemberMethods.getAndSubscribeUser(call, result)
"Member#setAttributes" -> MemberMethods.setAttributes(call, result)

"Members#getMembersList" -> MembersMethods.getMembersList(call, result)
"Members#getMember" -> MembersMethods.getMember(call, result)
"Members#addByIdentity" -> MembersMethods.addByIdentity(call, result)
"Members#inviteByIdentity" -> MembersMethods.inviteByIdentity(call, result)
"Members#removeByIdentity" -> MembersMethods.removeByIdentity(call, result)

"Message#updateMessageBody" -> MessageMethods.updateMessageBody(call, result)
"Message#setAttributes" -> MessageMethods.setAttributes(call, result)
"Message#getMedia" -> MessageMethods.getMedia(call, result)
"Messages#sendMessage" -> MessagesMethods.sendMessage(call, result)

"Messages#sendMessage" -> MessagesMethods.sendMessage(pluginInstance, call, result)
"Messages#removeMessage" -> MessagesMethods.removeMessage(call, result)
"Messages#getMessagesBefore" -> MessagesMethods.getMessagesBefore(call, result)
"Messages#getMessagesAfter" -> MessagesMethods.getMessagesAfter(call, result)
Expand All @@ -85,7 +85,7 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler
"Messages#advanceLastReadMessageIndexWithResult" -> MessagesMethods.advanceLastReadMessageIndexWithResult(call, result)
"Messages#setAllMessagesReadWithResult" -> MessagesMethods.setAllMessagesReadWithResult(call, result)
"Messages#setNoMessagesReadWithResult" -> MessagesMethods.setNoMessagesReadWithResult(call, result)

else -> result.notImplemented()
}
}
Expand All @@ -99,56 +99,78 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler
if (token == null) {
return result.error("ERROR", "Missing token", null)
}

if (propertiesObj == null) {
return result.error("ERROR", "Missing properties", null)
}

val callRegion = propertiesObj["region"] as String?
val callDeferCA = propertiesObj["deferCA"] as Boolean?


val currentChatClient = TwilioConversationsPlugin.chatClient
val currentChatClientRegion = TwilioConversationsPlugin.chatClientRegion
val currentChatClientDeferCA = TwilioConversationsPlugin.chatClientDeferCA

try {
if (TwilioConversationsPlugin.chatClient == null) {
if (currentChatClient == null) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => making a fresh ChatClient")
} else {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is already set, overriding")
TwilioConversationsPlugin.chatClient = null
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is set to null")
}
val propertiesBuilder = ConversationsClient.Properties.newBuilder()
if (propertiesObj["region"] != null) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.region to '${propertiesObj["region"]}'")
propertiesBuilder.setRegion(propertiesObj["region"] as String)
}

if (propertiesObj["deferCA"] != null) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.setDeferCertificateTrustToPlatform to '${propertiesObj["deferCA"]}'")
propertiesBuilder.setDeferCertificateTrustToPlatform(propertiesObj["deferCA"] as Boolean)
Log.w("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient is already exists.")
if (callRegion != currentChatClientRegion) {
result.error("ERROR", "ChatClient already exists with a different region", null)
return
} else if (callDeferCA != currentChatClientDeferCA) {
result.error("ERROR", "ChatClient already exists with a different deferCA", null)
return
}

TwilioConversationsPlugin.chatListener = ChatListener(propertiesBuilder.createProperties())

ConversationsClient.create(applicationContext, token, TwilioConversationsPlugin.chatListener.properties, object : CallbackListener<ConversationsClient> {
override fun onSuccess(chatClient: ConversationsClient) {
if (TwilioConversationsPlugin.chatClient == null) {
Log.d("Twilio init success", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: myIdentity is '${chatClient.myIdentity}'")
try {
TwilioConversationsPlugin.chatClient = chatClient
val chatClientMap = Mapper.chatClientToMap(chatClient)
result.success(chatClientMap)
} catch (e: Exception) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result")
Log.d("Twilio error", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result: $e : $chatClient : ${Mapper.chatClientToMap(chatClient)}")
result.error("$e", "Failed to map chatClient", null)
}
}
}
}

val propertiesBuilder = ConversationsClient.Properties.newBuilder()
if (callRegion != null) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.region to '${callRegion}'")
propertiesBuilder.setRegion(callRegion)
}

if (callDeferCA != null) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => setting Properties.setDeferCertificateTrustToPlatform to '${callDeferCA}'")
propertiesBuilder.setDeferCertificateTrustToPlatform(callDeferCA)
}

pluginInstance.chatListener = ChatListener(pluginInstance, propertiesBuilder.createProperties())

override fun onError(errorInfo: ErrorInfo) {
try {
with(TwilioConversationsPlugin) { debug("TwilioConversationsPlugin.create => ChatClient.create onError: $errorInfo") }
result.error("${errorInfo.code}", errorInfo.message, errorInfo.status)
} catch (e1: Exception) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create error: failed to send result of onError: $e1")
}
if (currentChatClient != null) {
val chatClientMap = Mapper.chatClientToMap(pluginInstance, currentChatClient)
result.success(chatClientMap)
return
}

ConversationsClient.create(applicationContext, token, pluginInstance.chatListener.properties, object : CallbackListener<ConversationsClient> {
override fun onSuccess(chatClient: ConversationsClient) {
Log.d("Twilio init success", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: myIdentity is '${chatClient.myIdentity}'")
try {
TwilioConversationsPlugin.chatClient = chatClient
TwilioConversationsPlugin.chatClientRegion = callRegion
TwilioConversationsPlugin.chatClientDeferCA = callDeferCA

val chatClientMap = Mapper.chatClientToMap(pluginInstance, chatClient)
result.success(chatClientMap)
} catch (e: Exception) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result")
Log.d("Twilio error", "TwilioConversationsPlugin.create => ChatClient.create onSuccess: failed to give result: $e : $chatClient : ${Mapper.chatClientToMap(pluginInstance, chatClient)}")
result.error("$e", "Failed to map chatClient", null)
}
})
}

override fun onError(errorInfo: ErrorInfo) {
try {
with(pluginInstance) { debug("TwilioConversationsPlugin.create => ChatClient.create onError: $errorInfo") }
result.error("${errorInfo.code}", errorInfo.message, errorInfo.status)
} catch (e1: Exception) {
Log.d("TwilioInfo", "TwilioConversationsPlugin.create => ChatClient.create error: failed to send result of onError: $e1")
}
}
})
} catch (e: Exception) {
result.error("ERROR", e.toString(), e)
}
Expand All @@ -163,7 +185,7 @@ class PluginHandler(private val applicationContext: Context) : MethodCallHandler
}

if (enableNative != null) {
TwilioConversationsPlugin.nativeDebug = enableNative
pluginInstance.nativeDebug = enableNative
result.success(enableNative)
} else {
result.error("MISSING_PARAMS", "Missing 'native' parameter", null)
Expand Down
Loading

0 comments on commit 816afcb

Please sign in to comment.