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) {