Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix bch module crashes #89

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ android {

defaultConfig {
minSdkVersion 19
targetSdkVersion 25
versionCode 300905
versionName "3.0.9.5"
targetSdkVersion 26
versionCode 300907
versionName "3.0.9.7"
multiDexEnabled true
}

Expand Down Expand Up @@ -140,8 +140,8 @@ dependencies {
implementation project(includePrefix +':modulespvcontract')
implementation project(includePrefix +':wallet-android-modularization-tools:modularization-lib')
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.madgag.spongycastle:core:1.58.0.0'
implementation 'com.google.protobuf:protobuf-java:3.4.0'
implementation(guavaArtifact) {
Expand Down
9 changes: 1 addition & 8 deletions src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<uses-permission android:name="com.mycelium.wallet.BROADCAST_SIGNED_TRANSACTION"/>
<uses-permission android:name="com.mycelium.wallet.RECEIVE_ADDRESSES"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".SpvModuleApplication"
android:allowBackup="false"
Expand All @@ -35,13 +36,5 @@
android:name=".providers.TransactionContentProvider"
android:exported="true"
android:authorities="${applicationId}.providers.TransactionContentProvider" />

<receiver android:name=".PackageRemovedReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_REPLACED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
</manifest>
2 changes: 1 addition & 1 deletion src/main/java/com/mycelium/spvmodule/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ interface Constants {

val MEMORY_CLASS_LOWEND = 48

val NOTIFICATION_ID_CONNECTED = 3
val NOTIFICATION_ID_CONNECTED = 2133
val NOTIFICATION_ID_COINS_RECEIVED = 1
val NOTIFICATION_ID_INACTIVITY = 2

Expand Down
13 changes: 13 additions & 0 deletions src/main/java/com/mycelium/spvmodule/PackageRemovedReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.mycelium.spvmodule
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri

class PackageRemovedReceiver : BroadcastReceiver() {
Expand All @@ -22,4 +23,16 @@ class PackageRemovedReceiver : BroadcastReceiver() {
}
}
}

companion object {
fun register(context: Context) {
val filter = IntentFilter().apply {
addAction(Intent.ACTION_PACKAGE_ADDED)
addAction(Intent.ACTION_PACKAGE_REPLACED)
addAction(Intent.ACTION_PACKAGE_REMOVED)
addDataScheme("package")
}
context.registerReceiver(PackageRemovedReceiver(), filter)
}
}
}
10 changes: 9 additions & 1 deletion src/main/java/com/mycelium/spvmodule/SpvMessageReceiver.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ package com.mycelium.spvmodule

import android.content.Context
import android.content.Intent
import android.os.Build
import android.util.Log
import com.mycelium.modularizationtools.ModuleMessageReceiver
import com.mycelium.spvmodule.SpvModuleApplication.Companion.getMbwModulePackage
import org.bitcoinj.utils.ContextPropagatingThreadFactory
import java.lang.IllegalStateException
import java.util.concurrent.Executors

class SpvMessageReceiver(private val context: Context) : ModuleMessageReceiver {
override fun getIcon() = R.drawable.ic_launcher

@Synchronized
override fun onMessage(callingPackageName: String, intent: Intent) {
//Wait until the application is initialized
Expand Down Expand Up @@ -64,7 +68,11 @@ class SpvMessageReceiver(private val context: Context) : ModuleMessageReceiver {
ContextPropagatingThreadFactory("SpvMessageReceiverThreadFactory"))
executorService.execute {
Log.d(LOG_TAG, "Starting Service $clone with action ${clone.action}")
context.startService(clone)
try {
context.startService(clone)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "", e) // often throw after update mbw application with exception "process is bad"
}
}
}

Expand Down
17 changes: 15 additions & 2 deletions src/main/java/com/mycelium/spvmodule/SpvModuleApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.os.Build
import android.os.StrictMode
import android.preference.PreferenceManager
import android.support.multidex.MultiDexApplication
Expand All @@ -20,6 +21,7 @@ import org.bitcoinj.crypto.LinuxSecureRandom
import org.bitcoinj.utils.Threading
import org.bitcoinj.wallet.SendRequest
import org.bitcoinj.wallet.Wallet
import java.lang.IllegalStateException

class SpvModuleApplication : MultiDexApplication(), ModuleMessageReceiver {
var configuration: Configuration? = null
Expand All @@ -34,6 +36,8 @@ class SpvModuleApplication : MultiDexApplication(), ModuleMessageReceiver {

override fun onMessage(callingPackageName: String, intent: Intent) = spvMessageReceiver.onMessage(callingPackageName, intent)

override fun getIcon() = spvMessageReceiver.getIcon()

override fun attachBaseContext(base: Context?) {
INSTANCE = if (INSTANCE != null && INSTANCE !== this) {
throw Error("Application was instantiated more than once?")
Expand All @@ -57,6 +61,7 @@ class SpvModuleApplication : MultiDexApplication(), ModuleMessageReceiver {
Threading.throwOnLockCycles()
enableStrictMode()
propagate(Constants.CONTEXT)
PackageRemovedReceiver.register(this)

Log.i(LOG_TAG, "=== starting app using configuration: ${if (BuildConfig.IS_TESTNET) "test" else "prod"}, ${Constants.NETWORK_PARAMETERS.id}")
super.onCreate()
Expand All @@ -82,7 +87,11 @@ class SpvModuleApplication : MultiDexApplication(), ModuleMessageReceiver {
SpvService::class.java)

val serviceIntent = Intent(this, Bip44AccountIdleService::class.java)
startService(serviceIntent)
try {
startService(serviceIntent)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "", e) // often throw after update mbw application with exception "process is bad"
}
}

fun stopBlockchainService() {
Expand Down Expand Up @@ -147,7 +156,11 @@ class SpvModuleApplication : MultiDexApplication(), ModuleMessageReceiver {
serviceIntent.putExtra(IntentContract.RESET_BLOCKCHAIN_STATE, true)
}
Log.d(LOG_TAG, "restartBip44AccountIdleService, startAsync")
startService(serviceIntent)
try {
startService(serviceIntent)
} catch (e: IllegalStateException) {
Log.e(LOG_TAG, "", e) // often throw after update mbw application with exception "process is bad"
}
Log.d(LOG_TAG, "restartBip44AccountIdleService, DONE")
}
}
Expand Down
31 changes: 29 additions & 2 deletions src/main/java/com/mycelium/spvmodule/SpvService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,12 @@

package com.mycelium.spvmodule

import android.app.IntentService
import android.app.NotificationManager
import android.app.*
import android.content.*
import android.content.Context
import android.graphics.Color
import android.os.Build
import android.support.v4.app.NotificationCompat
import android.util.Log
import org.bitcoinj.core.*
import org.bitcoinj.core.Context.propagate
Expand All @@ -34,6 +37,30 @@ class SpvService : IntentService("SpvService") {
private var accountIndex: Int = -1
private var unrelatedAccountGuid: String = ""

override fun onCreate() {
super.onCreate()
if (Build.VERSION.SDK_INT >= 26) {
val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val CHANNEL_ID = "spv service"
val channel = NotificationChannel(CHANNEL_ID, "SPV Service",
NotificationManager.IMPORTANCE_LOW)
channel.enableVibration(false)
service.createNotificationChannel(channel)

val notification = NotificationCompat.Builder(applicationContext, CHANNEL_ID)
.setSmallIcon(com.mycelium.spvmodule.R.drawable.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_MIN)
.setVibrate(null)
.setSound(null)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setContentTitle("Title title")
.setContentText("Text text")
.build()

startForeground(51554, notification)
}
}

override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
intentsQueue.offer(intent)
return super.onStartCommand(intent, flags, startId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.mycelium.spvmodule.guava

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.SharedPreferences
import android.net.ConnectivityManager
import android.os.Build
import android.os.IBinder
import android.os.Looper
import android.os.PowerManager
import android.support.v4.app.NotificationCompat
import android.util.Log
import android.widget.Toast
import com.google.common.base.Optional
Expand Down Expand Up @@ -99,7 +103,6 @@ class Bip44AccountIdleService : Service() {
initializeWalletsAccounts()
initializePeergroup()
checkImpediments()
notificationManager = Bip44NotificationManager(this)
runOneIteration()

synchronized (initializingMonitor) {
Expand All @@ -109,6 +112,11 @@ class Bip44AccountIdleService : Service() {
return START_REDELIVER_INTENT
}

override fun onCreate() {
super.onCreate()
notificationManager = Bip44NotificationManager(this)
}

override fun onDestroy() {
Log.d(LOG_TAG, "shutDown")
ready = false
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
package com.mycelium.spvmodule.guava

import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.*
import android.os.Build
import android.support.v4.app.NotificationCompat
import android.support.v4.content.LocalBroadcastManager
import android.text.format.DateUtils
import com.mycelium.spvmodule.*
import java.util.*
import java.util.concurrent.TimeUnit
import kotlin.concurrent.timerTask

class Bip44NotificationManager(private val bip44IdleServiceInstance: Bip44AccountIdleService?) {
private val spvModuleApplication = SpvModuleApplication.getApplication()
Expand All @@ -23,6 +24,7 @@ class Bip44NotificationManager(private val bip44IdleServiceInstance: Bip44Accoun
private var notification: Notification? = null

private val localBroadcastManager = LocalBroadcastManager.getInstance(spvModuleApplication)
private var changedTask: TimerTask? = null

init {
localBroadcastManager.registerReceiver(chainStateBroadcastReceiver, IntentFilter(SpvService.ACTION_BLOCKCHAIN_STATE))
Expand All @@ -38,19 +40,30 @@ class Bip44NotificationManager(private val bip44IdleServiceInstance: Bip44Accoun
localBroadcastManager.unregisterReceiver(peerCountBroadcastReceiver)
}

// prevent notification "updates" that don't update anything
private var oldNotificationBasics = ""
// prevent notification updates faster than NOTIFICATION_THROTTLE_MS
private val NOTIFICATION_THROTTLE_MS = TimeUnit.SECONDS.toMillis(20)
private fun changed() {
val now = System.currentTimeMillis()
if (changedTask?.scheduledExecutionTime() ?: 0 > now) {
// will execute changeThrottled in the future anyway
return
}
changedTask = timerTask { changedThrottled() }
Timer().schedule(changedTask, NOTIFICATION_THROTTLE_MS)
}
private fun changedThrottled() {
val connectivityNotificationEnabled = configuration.connectivityNotificationEnabled

//We need to check fo 100 to prevent not partial sync on first run.
//We need to check for 100 to prevent not partial sync on first run.
if (Bip44DownloadProgressTracker.getSyncProgress() == 100F) {
this.bip44IdleServiceInstance?.stopForeground(false)
if (!connectivityNotificationEnabled) {
notificationManager.cancel(Constants.NOTIFICATION_ID_CONNECTED)
return
}
}

val downloadPercentDone = if (blockchainState != null) {
blockchainState!!.chainDownloadPercentDone
} else {
Expand All @@ -67,7 +80,17 @@ class Bip44NotificationManager(private val bip44IdleServiceInstance: Bip44Accoun
}

private fun buildNotification(): Notification? {
return Notification.Builder(spvModuleApplication).apply {
val CHANNEL_ID = "idle service"

if (Build.VERSION.SDK_INT >= 26) {
val service = bip44IdleServiceInstance?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(CHANNEL_ID, "Message Receiver",
NotificationManager.IMPORTANCE_LOW)
channel.enableVibration(false)

service.createNotificationChannel(channel)
}
return NotificationCompat.Builder(spvModuleApplication, CHANNEL_ID).apply {
setSmallIcon(R.drawable.stat_sys_peers, if (peerCount > 4) 4 else peerCount)
setContentTitle(spvModuleApplication.getString(R.string.app_name))
var contentText = spvModuleApplication.resources.getQuantityString(R.plurals.notification_peers_connected_msg, peerCount, peerCount)
Expand All @@ -88,7 +111,7 @@ class Bip44NotificationManager(private val bip44IdleServiceInstance: Bip44Accoun
contentText += " " + spvModuleApplication.getString(R.string.notification_chain_status_impediment, impedimentsString)
}
}
setStyle(Notification.BigTextStyle().bigText(contentText))
setStyle(NotificationCompat.BigTextStyle().bigText(contentText))
setContentText(contentText)

setContentIntent(PendingIntent.getActivity(spvModuleApplication, 0,
Expand Down