Migrate to the new graphenej version.

- Migrated the whole app to the new graphenej version, which removes the usage of the Android Service, enabling to aim for a better and simpler architecture.
- Did a good number of modifications to keep the same or better functionality in all parts of the app that use the NetworkService.
This commit is contained in:
Severiano Jaramillo 2019-12-19 16:37:45 -06:00
parent b5411fa7fc
commit 766d42386a
9 changed files with 148 additions and 167 deletions

View file

@ -1,14 +1,9 @@
package cy.agorise.bitsybitshareswallet.activities package cy.agorise.bitsybitshareswallet.activities
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.os.AsyncTask import android.os.AsyncTask
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.IBinder
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import android.widget.Toast import android.widget.Toast
@ -56,7 +51,7 @@ import kotlin.concurrent.thread
* This class manages everything related to keeping the information in the database updated using graphenej's * This class manages everything related to keeping the information in the database updated using graphenej's
* NetworkService, leaving to MainActivity only the Navigation work and some other UI features. * NetworkService, leaving to MainActivity only the Navigation work and some other UI features.
*/ */
abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { abstract class ConnectedActivity : AppCompatActivity() {
companion object { companion object {
private const val TAG = "ConnectedActivity" private const val TAG = "ConnectedActivity"
@ -96,7 +91,7 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
private var missingAssets = ArrayList<Asset>() private var missingAssets = ArrayList<Asset>()
/* Network service connection */ /* Network service connection */
protected var mNetworkService: NetworkService? = null protected var mNetworkService: NetworkService? = NetworkService.getInstance()
// Map used to keep track of request and response id pairs // Map used to keep track of request and response id pairs
private val responseMap = HashMap<Long, Int>() private val responseMap = HashMap<Long, Int>()
@ -110,11 +105,6 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
// to resolve an equivalent BTS value // to resolve an equivalent BTS value
var transfer: Transfer? = null var transfer: Transfer? = null
/**
* Flag used to keep track of the NetworkService binding state
*/
private var mShouldUnbindNetwork: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -227,8 +217,7 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
if (message.error == null) { if (message.error == null) {
if (responseMap.containsKey(message.id)) { if (responseMap.containsKey(message.id)) {
val responseType = responseMap[message.id] when (responseMap[message.id]) {
when (responseType) {
RESPONSE_GET_FULL_ACCOUNTS -> RESPONSE_GET_FULL_ACCOUNTS ->
handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails) handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails)
@ -522,23 +511,9 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
} }
} }
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
val binder = service as NetworkService.LocalBinder
mNetworkService = binder.service
}
override fun onServiceDisconnected(name: ComponentName?) { }
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
val intent = Intent(this, NetworkService::class.java)
if (bindService(intent, this, Context.BIND_AUTO_CREATE)) {
mShouldUnbindNetwork = true
} else {
Log.e(TAG, "Binding to the network service failed.")
}
mHandler.postDelayed(mCheckMissingPaymentsTask, Constants.MISSING_PAYMENT_CHECK_PERIOD) mHandler.postDelayed(mCheckMissingPaymentsTask, Constants.MISSING_PAYMENT_CHECK_PERIOD)
mHandler.postDelayed(verifyConnectionToSuitableNodeTask, NODE_CHECK_DELAY) mHandler.postDelayed(verifyConnectionToSuitableNodeTask, NODE_CHECK_DELAY)
} }
@ -549,12 +524,6 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection {
mConnectedActivityViewModel.updateNodeLatencies(nodes as List<FullNode>) mConnectedActivityViewModel.updateNodeLatencies(nodes as List<FullNode>)
} }
// Unbinding from network service
if (mShouldUnbindNetwork) {
unbindService(this)
mShouldUnbindNetwork = false
mNetworkService = null
}
mHandler.removeCallbacks(mCheckMissingPaymentsTask) mHandler.removeCallbacks(mCheckMissingPaymentsTask)
mHandler.removeCallbacks(mRequestMissingUserAccountsTask) mHandler.removeCallbacks(mRequestMissingUserAccountsTask)
mHandler.removeCallbacks(mRequestMissingAssetsTask) mHandler.removeCallbacks(mRequestMissingAssetsTask)

View file

@ -1,11 +1,6 @@
package cy.agorise.bitsybitshareswallet.fragments package cy.agorise.bitsybitshareswallet.fragments
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Bundle import android.os.Bundle
import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.View import android.view.View
import androidx.core.os.ConfigurationCompat import androidx.core.os.ConfigurationCompat
@ -23,17 +18,14 @@ import io.reactivex.disposables.CompositeDisposable
* Base fragment that defines the methods and variables commonly used in all fragments that directly connect and * Base fragment that defines the methods and variables commonly used in all fragments that directly connect and
* talk to the BitShares nodes through graphenej's NetworkService * talk to the BitShares nodes through graphenej's NetworkService
*/ */
abstract class ConnectedFragment : Fragment(), ServiceConnection { abstract class ConnectedFragment : Fragment() {
companion object { companion object {
private const val TAG = "ConnectedFragment" private const val TAG = "ConnectedFragment"
} }
/** Network service connection */ /** Network service connection */
protected var mNetworkService: NetworkService? = null protected var mNetworkService: NetworkService? = NetworkService.getInstance()
/** Flag used to keep track of the NetworkService binding state */
private var mShouldUnbindNetwork: Boolean = false
/** Keeps track of all RxJava disposables, to make sure they are all disposed when the fragment is destroyed */ /** Keeps track of all RxJava disposables, to make sure they are all disposed when the fragment is destroyed */
protected var mDisposables = CompositeDisposable() protected var mDisposables = CompositeDisposable()
@ -66,41 +58,12 @@ abstract class ConnectedFragment : Fragment(), ServiceConnection {
} }
} }
override fun onResume() {
super.onResume()
val intent = Intent(context, NetworkService::class.java)
if (context?.bindService(intent, this, Context.BIND_AUTO_CREATE) == true) {
mShouldUnbindNetwork = true
} else {
Log.e(TAG, "Binding to the network service failed.")
}
}
override fun onPause() {
super.onPause()
// Unbinding from network service
if (mShouldUnbindNetwork) {
context?.unbindService(this)
mShouldUnbindNetwork = false
}
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()
if (!mDisposables.isDisposed) mDisposables.dispose() if (!mDisposables.isDisposed) mDisposables.dispose()
} }
override fun onServiceDisconnected(name: ComponentName?) { }
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
val binder = service as NetworkService.LocalBinder
mNetworkService = binder.service
}
/** /**
* Method to be implemented by all subclasses in order to be notified of JSON-RPC responses. * Method to be implemented by all subclasses in order to be notified of JSON-RPC responses.
* @param response * @param response

View file

@ -1,9 +1,7 @@
package cy.agorise.bitsybitshareswallet.fragments package cy.agorise.bitsybitshareswallet.fragments
import android.content.ComponentName
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.IBinder
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
@ -35,7 +33,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers
import kotlinx.android.synthetic.main.fragment_import_brainkey.* import kotlinx.android.synthetic.main.fragment_import_brainkey.*
import org.bitcoinj.core.ECKey import org.bitcoinj.core.ECKey
import java.text.NumberFormat import java.text.NumberFormat
import java.util.ArrayList import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class ImportBrainkeyFragment : BaseAccountFragment() { class ImportBrainkeyFragment : BaseAccountFragment() {
@ -249,10 +247,10 @@ class ImportBrainkeyFragment : BaseAccountFragment() {
if (Character.isUpperCase(brainKey.toCharArray()[brainKey.length - 1])) { if (Character.isUpperCase(brainKey.toCharArray()[brainKey.length - 1])) {
// If the last character is an uppercase, we assume the whole brainkey // If the last character is an uppercase, we assume the whole brainkey
// was given in capital letters and turn it to lowercase // was given in capital letters and turn it to lowercase
getAccountFromBrainkey(brainKey.toLowerCase()) getAccountFromBrainkey(brainKey.toLowerCase(Locale.ROOT))
} else { } else {
// Otherwise we turn the whole brainkey to capital letters // Otherwise we turn the whole brainkey to capital letters
getAccountFromBrainkey(brainKey.toUpperCase()) getAccountFromBrainkey(brainKey.toUpperCase(Locale.ROOT))
} }
} else { } else {
// If no case switching should take place, we perform the network call with // If no case switching should take place, we perform the network call with
@ -274,6 +272,15 @@ class ImportBrainkeyFragment : BaseAccountFragment() {
keyReferencesRequestId = mNetworkService?.sendMessage(GetKeyReferences(address), GetKeyReferences.REQUIRED_API) keyReferencesRequestId = mNetworkService?.sendMessage(GetKeyReferences(address), GetKeyReferences.REQUIRED_API)
} }
override fun onStart() {
super.onStart()
if (mNetworkService?.isConnected == true)
showConnectedState()
else
showDisconnectedState()
}
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
if (response.id == keyReferencesRequestId) { if (response.id == keyReferencesRequestId) {
handleBrainKeyAccountReferences(response.result) handleBrainKeyAccountReferences(response.result)
@ -289,7 +296,24 @@ class ImportBrainkeyFragment : BaseAccountFragment() {
} }
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) { override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
Log.d(TAG, "handleConnectionStatusUpdate. code: " + connectionStatusUpdate.updateCode) when (connectionStatusUpdate.updateCode) {
ConnectionStatusUpdate.CONNECTED -> {
showConnectedState()
}
ConnectionStatusUpdate.DISCONNECTED -> {
showDisconnectedState()
}
}
}
private fun showConnectedState() {
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_connected, null), null)
}
private fun showDisconnectedState() {
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_disconnected, null), null)
} }
/** /**
@ -385,18 +409,4 @@ class ImportBrainkeyFragment : BaseAccountFragment() {
mHandler.postDelayed(this, Constants.BLOCK_PERIOD) mHandler.postDelayed(this, Constants.BLOCK_PERIOD)
} }
} }
override fun onServiceDisconnected(name: ComponentName?) {
super.onServiceDisconnected(name)
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_disconnected, null), null)
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
super.onServiceConnected(name, service)
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_connected, null), null)
}
} }

View file

@ -3,7 +3,6 @@ package cy.agorise.bitsybitshareswallet.fragments
import android.content.* import android.content.*
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.IBinder
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
@ -190,6 +189,15 @@ class SettingsFragment : ConnectedFragment(), BaseSecurityLockDialog.OnPINPatter
} }
} }
override fun onStart() {
super.onStart()
if (mNetworkService?.isConnected == true)
showConnectedState()
else
showDisconnectedState()
}
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
if (responseMap.containsKey(response.id)) { if (responseMap.containsKey(response.id)) {
when (responseMap[response.id]) { when (responseMap[response.id]) {
@ -201,7 +209,26 @@ class SettingsFragment : ConnectedFragment(), BaseSecurityLockDialog.OnPINPatter
} }
} }
override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) { } override fun handleConnectionStatusUpdate(connectionStatusUpdate: ConnectionStatusUpdate) {
when (connectionStatusUpdate.updateCode) {
ConnectionStatusUpdate.CONNECTED -> {
showConnectedState()
}
ConnectionStatusUpdate.DISCONNECTED -> {
showDisconnectedState()
}
}
}
private fun showConnectedState() {
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_connected, null), null)
}
private fun showDisconnectedState() {
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_disconnected, null), null)
}
/** Handles the result of the [GetDynamicGlobalProperties] api call to obtain the current block number and update /** Handles the result of the [GetDynamicGlobalProperties] api call to obtain the current block number and update
* it in the Nodes Dialog */ * it in the Nodes Dialog */
@ -531,19 +558,5 @@ class SettingsFragment : ConnectedFragment(), BaseSecurityLockDialog.OnPINPatter
activity?.finish() activity?.finish()
activity?.startActivity(intent) activity?.startActivity(intent)
} }
override fun onServiceDisconnected(name: ComponentName?) {
super.onServiceDisconnected(name)
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_disconnected, null), null)
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
super.onServiceConnected(name, service)
tvNetworkStatus.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null,
resources.getDrawable(R.drawable.ic_connected, null), null)
}
} }

View file

@ -0,0 +1,72 @@
package cy.agorise.bitsybitshareswallet.network
import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import android.os.Handler
import cy.agorise.graphenej.api.android.NetworkService
import cy.agorise.graphenej.stats.ExponentialMovingAverage
/**
* Class used to manage the connection status of the NetworkService.
*
*
* The basic idea here is to keep track of the sequence of activity life cycle callbacks so that we
* can infer when the user has left the app and the node connection can be salfely shut down.
*/
class NetworkServiceManager(nodes: List<String>) :
ActivityLifecycleCallbacks {
/**
* Handler instance used to schedule tasks back to the main thread
*/
private val mHandler = Handler()
private var mNetworkService: NetworkService? = null
private val mNodeUrls: Array<String> = nodes.toTypedArray()
/**
* Runnable used to schedule a service disconnection once the app is not visible to the user for
* more than DISCONNECT_DELAY milliseconds.
*/
private val mDisconnectRunnable = Runnable {
if (mNetworkService != null) {
mNetworkService?.stop()
mNetworkService = null
}
}
override fun onActivityCreated(activity: Activity, bundle: Bundle) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity?) {
mHandler.removeCallbacks(mDisconnectRunnable)
if (mNetworkService == null) {
mNetworkService = NetworkService.getInstance()
mNetworkService?.start(mNodeUrls, ExponentialMovingAverage.DEFAULT_ALPHA)
}
}
override fun onActivityPaused(activity: Activity) {
mHandler.postDelayed(
mDisconnectRunnable,
DISCONNECT_DELAY.toLong()
)
}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(
activity: Activity,
bundle: Bundle
) {
}
override fun onActivityDestroyed(activity: Activity) {}
companion object {
/**
* Constant used to specify how long will the app wait for another activity to go through its starting life
* cycle events before running the teardownConnectionTask task.
*
* This is used as a means to detect whether or not the user has left the app.
*/
private const val DISCONNECT_DELAY = 1500
}
}

View file

@ -1,10 +1,6 @@
package cy.agorise.bitsybitshareswallet.processors package cy.agorise.bitsybitshareswallet.processors
import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.IBinder
import android.preference.PreferenceManager import android.preference.PreferenceManager
import android.util.Log import android.util.Log
import cy.agorise.bitsybitshareswallet.database.entities.Transfer import cy.agorise.bitsybitshareswallet.database.entities.Transfer
@ -29,6 +25,7 @@ import org.bitcoinj.core.DumpedPrivateKey
import org.bitcoinj.core.ECKey import org.bitcoinj.core.ECKey
import java.util.* import java.util.*
import javax.crypto.AEADBadTagException import javax.crypto.AEADBadTagException
import kotlin.math.floor
/** /**
* This class is responsible for loading the local database with all past transfer operations of the * This class is responsible for loading the local database with all past transfer operations of the
@ -66,33 +63,14 @@ class TransfersLoader(private var mContext: Context?) {
private var authorityRepository: AuthorityRepository? = null private var authorityRepository: AuthorityRepository? = null
/* Network service connection */ /* Network service connection */
private var mNetworkService: NetworkService? = null private var mNetworkService: NetworkService? = NetworkService.getInstance()
/* Counter used to keep track of the transfer history batch count */ /* Counter used to keep track of the transfer history batch count */
private var historicalTransferCount = 0 private var historicalTransferCount = 0
/** Flag used to keep track of the NetworkService binding state */
private var mBound: Boolean = false
// Map used to keep track of request and response id pairs // Map used to keep track of request and response id pairs
private val responseMap = HashMap<Long, Int>() private val responseMap = HashMap<Long, Int>()
private val mConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
val binder = service as NetworkService.LocalBinder
mNetworkService = binder.service
mBound = true
// Start the transfers update
startTransfersUpdateProcedure()
}
override fun onServiceDisconnected(name: ComponentName?) {
mBound = false
}
}
init { init {
transferRepository = TransferRepository(mContext!!) transferRepository = TransferRepository(mContext!!)
authorityRepository = AuthorityRepository(mContext!!) authorityRepository = AuthorityRepository(mContext!!)
@ -138,14 +116,8 @@ class TransfersLoader(private var mContext: Context?) {
} }
) )
onStart() // Start the transfers update
} startTransfersUpdateProcedure()
}
private fun onStart() {
// Bind to LocalService
Intent(mContext, NetworkService::class.java).also { intent ->
mContext?.bindService(intent, mConnection, Context.BIND_AUTO_CREATE)
} }
} }
@ -165,7 +137,7 @@ class TransfersLoader(private var mContext: Context?) {
if (transferCount > 0) { if (transferCount > 0) {
// If we already have some transfers in the database, we might want to skip the request // If we already have some transfers in the database, we might want to skip the request
// straight to the last batch // straight to the last batch
historicalTransferCount = Math.floor((transferCount / historicalTransferCount = floor((transferCount /
HISTORICAL_TRANSFER_BATCH_SIZE).toDouble()).toInt() HISTORICAL_TRANSFER_BATCH_SIZE).toDouble()).toInt()
} }
// Retrieving account transactions // Retrieving account transactions
@ -257,10 +229,10 @@ class TransfersLoader(private var mContext: Context?) {
val memo = op.memo val memo = op.memo
if (memo.byteMessage != null) { if (memo.byteMessage != null) {
try { try {
if (memo.destination.equals(myAddress)) { if (memo.destination == myAddress) {
val decryptedMessage = Memo.decryptMessage(memoKey, memo.source, memo.nonce, memo.byteMessage) val decryptedMessage = Memo.decryptMessage(memoKey, memo.source, memo.nonce, memo.byteMessage)
memo.plaintextMessage = decryptedMessage memo.plaintextMessage = decryptedMessage
}else if(memo.source.equals(myAddress)){ }else if(memo.source == myAddress){
val decryptedMessage = Memo.decryptMessage(memoKey, memo.destination, memo.nonce, memo.byteMessage) val decryptedMessage = Memo.decryptMessage(memoKey, memo.destination, memo.nonce, memo.byteMessage)
memo.plaintextMessage = decryptedMessage memo.plaintextMessage = decryptedMessage
} }
@ -271,7 +243,7 @@ class TransfersLoader(private var mContext: Context?) {
Log.e(TAG, "NullPointerException. Msg: " + e.message) Log.e(TAG, "NullPointerException. Msg: " + e.message)
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "Exception while decoding memo. Msg: " + e.message) Log.e(TAG, "Exception while decoding memo. Msg: " + e.message)
Log.e(TAG,"Exception type: " + e) Log.e(TAG, "Exception type: $e")
for(element in e.stackTrace){ for(element in e.stackTrace){
Log.e(TAG, String.format("%s#%s:%d", element.className, element.methodName, element.lineNumber)) Log.e(TAG, String.format("%s#%s:%d", element.className, element.methodName, element.lineNumber))
} }
@ -300,13 +272,6 @@ class TransfersLoader(private var mContext: Context?) {
Log.d(TAG, "Destroying TransfersLoader") Log.d(TAG, "Destroying TransfersLoader")
if (!mDisposables.isDisposed) mDisposables.dispose() if (!mDisposables.isDisposed) mDisposables.dispose()
try {
if (mBound && mNetworkService != null)
mContext?.unbindService(mConnection)
} catch (e: IllegalArgumentException) {
Log.d(TAG, "Avoid crash related to Service not registered: ${e.message}")
}
mBound = false
mContext = null mContext = null
mNetworkService = null mNetworkService = null
} }

View file

@ -50,7 +50,6 @@ class NodeRepository(private val nodeDao: NodeDao) {
suspend fun getFormattedNodes(): Pair<String, Boolean> { suspend fun getFormattedNodes(): Pair<String, Boolean> {
val nodes = nodeDao.getSortedNodes() val nodes = nodeDao.getSortedNodes()
// TODO verify if this is the best way to fire and forget launch a coroutine inside another coroutine
// Launches a job to refresh the list of nodes into the database, without blocking the // Launches a job to refresh the list of nodes into the database, without blocking the
// execution of this function, so that the formatted nodes can be returned immediately // execution of this function, so that the formatted nodes can be returned immediately
// without waiting until the nodes have been updated in the database. // without waiting until the nodes have been updated in the database.

View file

@ -3,9 +3,8 @@ package cy.agorise.bitsybitshareswallet.utils
import android.app.Application import android.app.Application
import com.crashlytics.android.Crashlytics import com.crashlytics.android.Crashlytics
import cy.agorise.bitsybitshareswallet.database.BitsyDatabase import cy.agorise.bitsybitshareswallet.database.BitsyDatabase
import cy.agorise.bitsybitshareswallet.network.NetworkServiceManager
import cy.agorise.bitsybitshareswallet.repositories.NodeRepository import cy.agorise.bitsybitshareswallet.repositories.NodeRepository
import cy.agorise.graphenej.api.ApiAccess
import cy.agorise.graphenej.api.android.NetworkServiceManager
import io.reactivex.plugins.RxJavaPlugins import io.reactivex.plugins.RxJavaPlugins
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@ -46,18 +45,9 @@ class BitsyApplication : Application() {
} }
private suspend fun startNetworkServiceConnection() { private suspend fun startNetworkServiceConnection() {
// Specifying some important information regarding the connection, such as the
// credentials and the requested API accesses
val requestedApis = ApiAccess.API_DATABASE or ApiAccess.API_HISTORY or ApiAccess.API_NETWORK_BROADCAST
val (nodes, autoConnect) = mNodeRepository.getFormattedNodes() val (nodes, autoConnect) = mNodeRepository.getFormattedNodes()
val networkManager = NetworkServiceManager.Builder()
.setUserName("") val networkManager = NetworkServiceManager(nodes.split(","))
.setPassword("")
.setRequestedApis(requestedApis)
.setCustomNodeUrls(nodes)
.setAutoConnect(autoConnect)
.setNodeLatencyVerification(true)
.build(this)
/* /*
* Registering this class as a listener to all activity's callback cycle events, in order to * Registering this class as a listener to all activity's callback cycle events, in order to
* better estimate when the user has left the app and it is safe to disconnect the websocket connection * better estimate when the user has left the app and it is safe to disconnect the websocket connection

@ -1 +1 @@
Subproject commit 1129a92aa3e4d1ceeac6826fcfe154bf909930fe Subproject commit 3d5a57f8961c76fc2cadb327c86374d30c6692b7