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 fb06fb4..1fcc958 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/ConnectedActivity.kt @@ -7,11 +7,13 @@ import android.content.ServiceConnection import android.os.Bundle import android.os.Handler import android.os.IBinder +import android.preference.PreferenceManager import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProviders +import cy.agorise.bitsybitshareswallet.processors.TransfersLoader import cy.agorise.bitsybitshareswallet.utils.Constants import cy.agorise.bitsybitshareswallet.viewmodels.UserAccountViewModel import cy.agorise.graphenej.UserAccount @@ -19,12 +21,13 @@ 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.GetAccounts +import cy.agorise.graphenej.api.calls.GetFullAccounts import cy.agorise.graphenej.models.AccountProperties import cy.agorise.graphenej.models.FullAccountDetails -import cy.agorise.graphenej.models.HistoryOperationDetail import cy.agorise.graphenej.models.JsonRpcResponse import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.Disposable +import java.util.* /** * Class in charge of managing the connection to graphenej's NetworkService @@ -34,6 +37,9 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { private lateinit var mUserAccountViewModel: UserAccountViewModel + /* Current user account */ + protected var mCurrentAccount: UserAccount? = null + private val mHandler = Handler() // Disposable returned at the bus subscription @@ -53,6 +59,12 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + val userId = PreferenceManager.getDefaultSharedPreferences(this) + .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") + if (userId != "") + mCurrentAccount = UserAccount(userId) + mDisposable = RxBus.getBusInstance() .asFlowable() .observeOn(AndroidSchedulers.mainThread()) @@ -63,18 +75,11 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { // Payment detection focused responses if (message.error == null) { if (message.result is List<*> && (message.result as List<*>).size > 0) { - if ((message.result as List<*>)[0] is AccountProperties) { + if ((message.result as List<*>)[0] is FullAccountDetails) { + handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails) + } else if ((message.result as List<*>)[0] is AccountProperties) { handleAccountProperties(message.result as List) } -// if ((message.result as List<*>)[0] is FullAccountDetails) { -// if (message.id == recurrentAccountUpdateId) { -// handleAccountDetails((message.result as List<*>)[0] as FullAccountDetails) -// } else if (message.id == postProcessingAccountUpdateId) { -// handleAccountUpdate((message.result as List<*>)[0] as FullAccountDetails) -// } -// } -// } else if (message.result is HistoryOperationDetail && message.id == accountOpRequestId) { -// handleNewOperations(message.result as HistoryOperationDetail) } } else { // In case of error @@ -90,7 +95,6 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { if (message.updateCode == ConnectionStatusUpdate.DISCONNECTED) { // recurrentAccountUpdateId = -1 // accountOpRequestId = -1 -// isProcessingTx = false } } } @@ -108,6 +112,29 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { }) } + /** + * Method called whenever a response to the 'get_full_accounts' API call has been detected. + * @param accountDetails De-serialized account details object + */ + private fun handleAccountDetails(accountDetails: FullAccountDetails) { + val latestOpCount = accountDetails.statistics.total_ops + Log.d(TAG, "handleAccountDetails. prev count: $storedOpCount, current count: $latestOpCount") + + if (latestOpCount == 0L) { + Log.d(TAG, "The node returned 0 total_ops for current account and may not have installed the history plugin. " + + "\nAsk the NetworkService to remove the node from the list and connect to another one.") + mNetworkService!!.removeCurrentNodeAndReconnect() + } else if (storedOpCount == -1L) { + // Initial case + storedOpCount = latestOpCount + PreferenceManager.getDefaultSharedPreferences(this) + .edit().putLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, latestOpCount).apply() + } else if (latestOpCount > storedOpCount) { + storedOpCount = latestOpCount + TransfersLoader(this, lifecycle) + } + } + private fun handleAccountProperties(accountPropertiesList: List) { val userAccounts = ArrayList() @@ -141,29 +168,22 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { /** * Task used to perform a redundant payment check. */ -// private val mCheckMissingPaymentsTask = object : Runnable { -// override fun run() { -// if (mNetworkService != null && mNetworkService.isConnected()) { -// val userId = PreferenceManager -// .getDefaultSharedPreferences(this@ConnectedActivity) -// .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") -// if (userId != "") { -// // Checking that we actually have a user id registered in the shared preferences -// val userAccounts = ArrayList() -// userAccounts.add(userId) -// recurrentAccountUpdateId = mNetworkService.sendMessage( -// GetFullAccounts(userAccounts, false), -// GetFullAccounts.REQUIRED_API -// ) -// } else { -// Log.w(TAG, "User id is empty") -// } -// } else { -// Log.w(TAG, "NetworkService is null or is not connected. mNetworkService: $mNetworkService") -// } -// mHandler.postDelayed(this, Constants.MISSING_PAYMENT_CHECK_PERIOD) -// } -// } + 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 + ) + } else { + Log.w(TAG, "NetworkService is null or is not connected. mNetworkService: $mNetworkService") + } + mHandler.postDelayed(this, Constants.MISSING_PAYMENT_CHECK_PERIOD) + } + } override fun onServiceConnected(name: ComponentName?, service: IBinder?) { // We've bound to LocalService, cast the IBinder and get LocalService instance @@ -180,7 +200,7 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { unbindService(this) mShouldUnbindNetwork = false } -// mHandler.removeCallbacks(mCheckMissingPaymentsTask) + mHandler.removeCallbacks(mCheckMissingPaymentsTask) mHandler.removeCallbacks(mRequestMissingUserAccountsTask) } @@ -193,10 +213,10 @@ abstract class ConnectedActivity : AppCompatActivity(), ServiceConnection { } 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) -// storedOpCount = PreferenceManager.getDefaultSharedPreferences(this) -// .getLong(Constants.KEY_ACCOUNT_OPERATION_COUNT, -1) + 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 688e972..5105309 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/activities/MainActivity.kt @@ -2,7 +2,6 @@ package cy.agorise.bitsybitshareswallet.activities import android.content.Intent import android.os.Bundle -import android.preference.PreferenceManager import android.util.Log import android.view.Menu import android.view.MenuItem @@ -17,10 +16,8 @@ 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.bitsybitshareswallet.utils.Constants import cy.agorise.graphenej.AssetAmount import cy.agorise.graphenej.RPC -import cy.agorise.graphenej.UserAccount import cy.agorise.graphenej.api.ApiAccess import cy.agorise.graphenej.api.ConnectionStatusUpdate import cy.agorise.graphenej.api.calls.GetAccountBalances @@ -33,9 +30,6 @@ class MainActivity : ConnectedActivity() { private val requestMap = LongSparseArray() - /* Current user account */ - private var mCurrentAccount: UserAccount? = null - private var mBalanceRepository: BalanceRepository? = null private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> @@ -67,11 +61,6 @@ class MainActivity : ConnectedActivity() { navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) navigation.selectedItemId = R.id.navigation_balances - val userId = PreferenceManager.getDefaultSharedPreferences(this) - .getString(Constants.KEY_CURRENT_ACCOUNT_ID, "") - if (userId != "") - mCurrentAccount = UserAccount(userId) - mBalanceRepository = BalanceRepository(this) } diff --git a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt index 2ad4f26..1226d68 100644 --- a/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt +++ b/app/src/main/java/cy/agorise/bitsybitshareswallet/utils/Constants.kt @@ -49,6 +49,11 @@ object Constants { */ const val NETWORK_SERVICE_RETRY_PERIOD: Long = 5000 + /** + * Key used to store the number of operations that the currently selected account had last time we checked + */ + const val KEY_ACCOUNT_OPERATION_COUNT = "key_account_operation_count" + /** Key used to store the night mode setting into the shared preferences */ const val KEY_NIGHT_MODE_ACTIVATED = "key_night_mode_activated" }