From 50a266ffb4e481a1455dd10c3f74e706d8751cf2 Mon Sep 17 00:00:00 2001 From: Severiano Jaramillo Date: Sat, 8 Dec 2018 22:55:28 -0600 Subject: [PATCH] - Move the method to updateBalances from the MainActivity to the ConnectedActivity, so that it can be always trying to update the Balances even if we are not in the MainActivity and also to be able to update the Balances right after we notice there are new transactions for the current BitShares account. - Move the TransfersLoader from MainActivity for the same reason than the updateBalances method described above and fix it so that it no longer needs the activity Lifecycle. --- .../activities/ConnectedActivity.kt | 88 +++++++++++++------ .../activities/MainActivity.kt | 61 +------------ .../processors/TransfersLoader.kt | 14 ++- 3 files changed, 68 insertions(+), 95 deletions(-) diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt index 1fcc958..ebf262a 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt @@ -13,13 +13,17 @@ import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders +import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.processors.TransfersLoader +import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel +import cy.agorise.graphenej.AssetAmount import cy.agorise.graphenej.UserAccount import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.api.android.NetworkService import cy.agorise.graphenej.api.android.RxBus +import cy.agorise.graphenej.api.calls.GetAccountBalances import cy.agorise.graphenej.api.calls.GetAccounts import cy.agorise.graphenej.api.calls.GetFullAccounts import cy.agorise.graphenej.models.AccountProperties @@ -37,6 +41,8 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { private lateinit var mUserAccountViewModel: UserAccountViewModel + private var mBalanceRepository: BalanceRepository? = null + /* Current user account */ protected var mCurrentAccount: UserAccount? = null @@ -65,6 +71,20 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { if (userId != "") mCurrentAccount = UserAccount(userId) + mBalanceRepository = BalanceRepository(this) + + // Configure UserAccountViewModel to show the current account + mUserAccountViewModel = ViewModelProviders.of(this).get(UserAccountViewModel::class.java) + + mUserAccountViewModel.getMissingUserAccountIds().observe(this, Observer>{ userAccountIds -> + if (userAccountIds.isNotEmpty()) { + for (userAccountId in userAccountIds) + missingUserAccounts.add(UserAccount(userAccountId)) + + mHandler.postDelayed(mRequestMissingUserAccountsTask, Constants.NETWORK_SERVICE_RETRY_PERIOD) + } + }) + mDisposable = RxBus.getBusInstance() .asFlowable() .observeOn(AndroidSchedulers.mainThread()) @@ -79,6 +99,8 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails) } else if ((message.result as List<*>)[0] is AccountProperties) { handleAccountProperties(message.result as List) + } else if((message.result as List<*>)[0] is AssetAmount) { + handleBalanceUpdate(message.result as List) } } } else { @@ -92,24 +114,8 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { } } else if (message is ConnectionStatusUpdate) { handleConnectionStatusUpdate(message) - if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) { -// recurrentAccountUpdateId = -1 -// accountOpRequestId = -1 - } } } - - // Configure UserAccountViewModel to show the current account - mUserAccountViewModel = ViewModelProviders.of(this).get(UserAccountViewModel::class.java) - - mUserAccountViewModel.getMissingUserAccountIds().observe(this, Observer>{ userAccountIds -> - if (userAccountIds.isNotEmpty()) { - for (userAccountId in userAccountIds) - missingUserAccounts.add(UserAccount(userAccountId)) - - mHandler.postDelayed(mRequestMissingUserAccountsTask, Constants.NETWORK_SERVICE_RETRY_PERIOD) - } - }) } /** @@ -125,13 +131,16 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { "\nAsk the NetworkService to remove the node from the list and connect to another one.") mNetworkService!!.removeCurrentNodeAndReconnect() } else if (storedOpCount == -1L) { - // Initial case + // Initial case when the app starts storedOpCount = latestOpCount PreferenceManager.getDefaultSharedPreferences(this) .edit().putLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, latestOpCount).apply() + TransfersLoader(this) + updateBalances() } else if (latestOpCount > storedOpCount) { storedOpCount = latestOpCount - TransfersLoader(this, lifecycle) + TransfersLoader(this) + updateBalances() } } @@ -152,6 +161,31 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { missingUserAccounts.clear() } + private fun handleBalanceUpdate(assetAmountList: List) { + Log.d(TAG, "handleBalanceUpdate") + val now = System.currentTimeMillis() / 1000 + val balances = ArrayList() + for (assetAmount in assetAmountList) { + val balance = Balance( + assetAmount.asset.objectId, + assetAmount.amount.toLong(), + now + ) + + balances.add(balance) + } + mBalanceRepository!!.insertAll(balances) + } + + private fun updateBalances() { + if (mNetworkService!!.isConnected) { + mNetworkService!!.sendMessage( + GetAccountBalances(mCurrentAccount, ArrayList()), + GetAccountBalances.REQUIRED_API + ) + } + } + /** * Task used to obtain the missing UserAccounts. */ @@ -171,13 +205,14 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { private val mCheckMissingPaymentsTask = object : Runnable { override fun run() { if (mNetworkService != null && mNetworkService!!.isConnected) { - // Checking that we actually have a user id registered in the shared preferences - val userAccounts = ArrayList() - userAccounts.add(mCurrentAccount!!.objectId) - mNetworkService!!.sendMessage( - GetFullAccounts(userAccounts, false), - GetFullAccounts.REQUIRED_API - ) + if (mCurrentAccount != null) { + val userAccounts = ArrayList() + userAccounts.add(mCurrentAccount!!.objectId) + mNetworkService!!.sendMessage( + GetFullAccounts(userAccounts, false), + GetFullAccounts.REQUIRED_API + ) + } } else { Log.w(TAG, "NetworkService is null or is not connected. mNetworkService: $mNetworkService") } @@ -214,9 +249,6 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { Log.e(TAG, "Binding to the network service failed.") } mHandler.postDelayed(mCheckMissingPaymentsTask, Constants.MISSING_PAYMENT_CHECK_PERIOD) - - storedOpCount = PreferenceManager.getDefaultSharedPreferences(this) - .getLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, -1) } override fun onDestroy() { diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt index 5105309..992308b 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -2,36 +2,22 @@ package cy.agorise.bitsybitshareswallet.activities import android.content.Intent import android.os.Bundle -import android.util.Log import android.view.Menu import android.view.MenuItem -import androidx.collection.LongSparseArray import androidx.fragment.app.Fragment import com.google.android.material.bottomnavigation.BottomNavigationView import cy.agorise.bitsybitshareswallet.R -import cy.agorise.bitsybitshareswallet.database.entities.Balance import cy.agorise.bitsybitshareswallet.fragments.BalancesFragment import cy.agorise.bitsybitshareswallet.fragments.MerchantsFragment import cy.agorise.bitsybitshareswallet.fragments.ReceiveTransactionFragment import cy.agorise.bitsybitshareswallet.fragments.SendTransactionFragment -import cy.agorise.bitsybitshareswallet.processors.TransfersLoader -import cy.agorise.bitsybitshareswallet.repositories.BalanceRepository -import cy.agorise.graphenej.AssetAmount -import cy.agorise.graphenej.RPC -import cy.agorise.graphenej.api.ApiAccess import cy.agorise.graphenej.api.ConnectionStatusUpdate -import cy.agorise.graphenej.api.calls.GetAccountBalances import cy.agorise.graphenej.models.JsonRpcResponse import kotlinx.android.synthetic.main.activity_main.* -import java.util.ArrayList class MainActivity : ConnectedActivity() { private val TAG = this.javaClass.simpleName - private val requestMap = LongSparseArray() - - private var mBalanceRepository: BalanceRepository? = null - private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.navigation_receive -> { @@ -60,8 +46,6 @@ class MainActivity : ConnectedActivity() { navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) navigation.selectedItemId = R.id.navigation_balances - - mBalanceRepository = BalanceRepository(this) } private fun loadFragment(fragment: Fragment) { @@ -88,9 +72,7 @@ class MainActivity : ConnectedActivity() { } override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) { - if (requestMap.get(response.id) == RPC.CALL_GET_ACCOUNT_BALANCES) { - handleBalanceUpdate(response as JsonRpcResponse>) - } + } /** @@ -102,46 +84,7 @@ class MainActivity : ConnectedActivity() { ConnectionStatusUpdate.CONNECTED -> { /* Do nothing for now */ } ConnectionStatusUpdate.DISCONNECTED -> { /* Do nothing for now */ } ConnectionStatusUpdate.AUTHENTICATED -> {}//updateBalances() } - ConnectionStatusUpdate.API_UPDATE -> { - // In certain cases the information about the accounts is not complete, this may not be the best - // solution but at least it works. Feel free to improve it or move it to a better place - //MissingAccountsLoader(this, lifecycle) - - if (connectionStatusUpdate.api == ApiAccess.API_NETWORK_BROADCAST) { - Log.d(TAG, "ConnectionStatusUpdate: API_NETWORK_BROADCAST") - // Instantiating this loader is enough to kick-start the transfers loading procedure - TransfersLoader(this, lifecycle) - - updateBalances() - } - } + ConnectionStatusUpdate.API_UPDATE -> { } } } - - private fun updateBalances() { - if (mNetworkService!!.isConnected) { - val id = mNetworkService!!.sendMessage( - GetAccountBalances(mCurrentAccount, ArrayList()), - GetAccountBalances.REQUIRED_API - ) - requestMap.put(id, RPC.CALL_GET_ACCOUNT_BALANCES) - } - } - - private fun handleBalanceUpdate(response: JsonRpcResponse>) { - Log.d(TAG, "handleBalanceUpdate") - val now = System.currentTimeMillis() / 1000 - val assetBalances = response.result - val balances = ArrayList() - for (assetBalance in assetBalances) { - val balance = Balance( - assetBalance.asset.objectId, - assetBalance.amount.toLong(), - now - ) - - balances.add(balance) - } - mBalanceRepository!!.insertAll(balances) - } } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt index ce8e8c8..be4c5b7 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/processors/TransfersLoader.kt @@ -48,8 +48,7 @@ import javax.crypto.AEADBadTagException * for every transfer, we must first load all historical transfer operations, and then proceed to * handle those missing columns. */ -class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Lifecycle) : LifecycleObserver, - ServiceConnection { +class TransfersLoader(private var mContext: Context?): ServiceConnection { private val TAG = this.javaClass.simpleName @@ -106,7 +105,6 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li } init { - this.mLifeCycle.addObserver(this) transferRepository = TransferRepository(mContext!!) authorityRepository = AuthorityRepository(mContext!!) @@ -152,6 +150,8 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li // If there is no current user, we should not do anything mState = State.CANCELLED } + + onStart() } override fun onServiceDisconnected(name: ComponentName?) { @@ -167,8 +167,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li startTransfersUpdateProcedure() } - @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) - internal fun onStart() { + private fun onStart() { if (mState != State.CANCELLED) { val intent = Intent(mContext, NetworkService::class.java) if (mContext!!.bindService(intent, this, Context.BIND_AUTO_CREATE)) { @@ -219,7 +218,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li // TODO return number of inserted rows // Log.d(TAG, String.format("Inserted count: %d, list size: %d", insertedCount, operationHistoryList.size)) if (/* insertedCount == 0 && */ operationHistoryList.isEmpty()) { - // TODO Terminate process and obtain MissingTimes and MissingEquivalentValues + onDestroy() } else { // If we inserted more than one operation, we cannot yet be sure we've reached the @@ -320,8 +319,7 @@ class TransfersLoader(private var mContext: Context?, private val mLifeCycle: Li return transfers } - @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) - internal fun onDestroy() { + private fun onDestroy() { Log.d(TAG, "Destroying TransfersLoader") if (!mDisposables.isDisposed) mDisposables.dispose() if (mShouldUnbindNetwork) {