Merge branch 'release/1.0-beta20'
This commit is contained in:
		@@ -20,8 +20,8 @@ android {
 | 
			
		||||
        applicationId "ch.dissem.apps.${appName.toLowerCase()}"
 | 
			
		||||
        minSdkVersion 19
 | 
			
		||||
        targetSdkVersion 27
 | 
			
		||||
        versionCode 19
 | 
			
		||||
        versionName "1.0-beta19"
 | 
			
		||||
        versionCode 20
 | 
			
		||||
        versionName "1.0-beta20"
 | 
			
		||||
        multiDexEnabled true
 | 
			
		||||
    }
 | 
			
		||||
    compileOptions {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,8 @@ package ch.dissem.apps.abit.listener
 | 
			
		||||
import android.content.BroadcastReceiver
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import ch.dissem.apps.abit.service.BitmessageService
 | 
			
		||||
import ch.dissem.apps.abit.service.Singleton
 | 
			
		||||
import ch.dissem.apps.abit.util.NetworkUtils
 | 
			
		||||
import ch.dissem.apps.abit.util.Preferences
 | 
			
		||||
import org.jetbrains.anko.connectivityManager
 | 
			
		||||
 | 
			
		||||
@@ -29,7 +29,7 @@ class WifiReceiver : BroadcastReceiver() {
 | 
			
		||||
        if ("android.net.conn.CONNECTIVITY_CHANGE" == intent.action) {
 | 
			
		||||
            val bmc = Singleton.getBitmessageContext(ctx)
 | 
			
		||||
            if (Preferences.isFullNodeActive(ctx) && !bmc.isRunning() && !(Preferences.isWifiOnly(ctx) && ctx.connectivityManager.isActiveNetworkMetered)) {
 | 
			
		||||
                ctx.startService(Intent(ctx, BitmessageService::class.java))
 | 
			
		||||
                NetworkUtils.doStartBitmessageService(ctx)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -17,8 +17,13 @@
 | 
			
		||||
package ch.dissem.apps.abit.notification
 | 
			
		||||
 | 
			
		||||
import android.app.Notification
 | 
			
		||||
import android.app.NotificationChannel
 | 
			
		||||
import android.app.NotificationManager
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.support.annotation.ColorRes
 | 
			
		||||
import android.support.v4.content.ContextCompat
 | 
			
		||||
import ch.dissem.apps.abit.R
 | 
			
		||||
import org.jetbrains.anko.notificationManager
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -46,4 +51,30 @@ abstract class AbstractNotification(ctx: Context) {
 | 
			
		||||
        showing = false
 | 
			
		||||
        manager.cancel(notificationId)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected fun initChannel(channelId: String, @ColorRes color: Int = R.color.colorPrimary) {
 | 
			
		||||
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 | 
			
		||||
            ctx.notificationManager.createNotificationChannel(
 | 
			
		||||
                NotificationChannel(
 | 
			
		||||
                    channelId,
 | 
			
		||||
                    ctx.getText(R.string.app_name),
 | 
			
		||||
                    NotificationManager.IMPORTANCE_LOW
 | 
			
		||||
                ).apply {
 | 
			
		||||
                    lightColor = ContextCompat.getColor(ctx, color)
 | 
			
		||||
                    lockscreenVisibility = Notification.VISIBILITY_PRIVATE
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        internal const val ONGOING_CHANNEL_ID = "abit.ongoing"
 | 
			
		||||
        internal const val MESSAGE_CHANNEL_ID = "abit.message"
 | 
			
		||||
        internal const val ERROR_CHANNEL_ID = "abit.error"
 | 
			
		||||
 | 
			
		||||
        init {
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -30,10 +30,14 @@ import ch.dissem.apps.abit.R
 | 
			
		||||
 */
 | 
			
		||||
class ErrorNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, "abit.error")
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, ERROR_CHANNEL_ID)
 | 
			
		||||
        .setContentTitle(ctx.getString(R.string.app_name))
 | 
			
		||||
        .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        initChannel(ERROR_CHANNEL_ID, R.color.colorPrimaryDark)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun setWarning(@StringRes resId: Int, vararg args: Any): ErrorNotification {
 | 
			
		||||
        builder.setSmallIcon(R.drawable.ic_notification_warning)
 | 
			
		||||
            .setContentText(ctx.getString(resId, *args))
 | 
			
		||||
 
 | 
			
		||||
@@ -34,18 +34,19 @@ import kotlin.concurrent.fixedRateTimer
 | 
			
		||||
 */
 | 
			
		||||
class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, "abit.network")
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, ONGOING_CHANNEL_ID)
 | 
			
		||||
    private var timer: Timer? = null
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        initChannel(ONGOING_CHANNEL_ID, R.color.colorAccent)
 | 
			
		||||
        val showAppIntent = Intent(ctx, MainActivity::class.java)
 | 
			
		||||
        val pendingIntent = PendingIntent.getActivity(ctx, 1, showAppIntent, 0)
 | 
			
		||||
        builder
 | 
			
		||||
                .setSmallIcon(R.drawable.ic_notification_full_node)
 | 
			
		||||
                .setContentTitle(ctx.getString(R.string.bitmessage_full_node))
 | 
			
		||||
                .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
 | 
			
		||||
                .setShowWhen(false)
 | 
			
		||||
                .setContentIntent(pendingIntent)
 | 
			
		||||
            .setSmallIcon(R.drawable.ic_notification_full_node)
 | 
			
		||||
            .setContentTitle(ctx.getString(R.string.bitmessage_full_node))
 | 
			
		||||
            .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
 | 
			
		||||
            .setShowWhen(false)
 | 
			
		||||
            .setContentIntent(pendingIntent)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("StringFormatMatches")
 | 
			
		||||
@@ -63,11 +64,19 @@ class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
                val streamNumber = Integer.parseInt(stream.name.substring("stream ".length))
 | 
			
		||||
                val nodeCount = stream.getProperty("nodes")!!.value as Int?
 | 
			
		||||
                if (nodeCount == 1) {
 | 
			
		||||
                    info.append(ctx.getString(R.string.connection_info_1,
 | 
			
		||||
                            streamNumber))
 | 
			
		||||
                    info.append(
 | 
			
		||||
                        ctx.getString(
 | 
			
		||||
                            R.string.connection_info_1,
 | 
			
		||||
                            streamNumber
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                } else {
 | 
			
		||||
                    info.append(ctx.getString(R.string.connection_info_n,
 | 
			
		||||
                            streamNumber, nodeCount))
 | 
			
		||||
                    info.append(
 | 
			
		||||
                        ctx.getString(
 | 
			
		||||
                            R.string.connection_info_n,
 | 
			
		||||
                            streamNumber, nodeCount
 | 
			
		||||
                        )
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                info.append('\n')
 | 
			
		||||
            }
 | 
			
		||||
@@ -77,14 +86,18 @@ class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
        val intent = Intent(ctx, BitmessageIntentService::class.java)
 | 
			
		||||
        if (running) {
 | 
			
		||||
            intent.putExtra(BitmessageIntentService.EXTRA_SHUTDOWN_NODE, true)
 | 
			
		||||
            builder.addAction(R.drawable.ic_notification_node_stop,
 | 
			
		||||
                    ctx.getString(R.string.full_node_stop),
 | 
			
		||||
                    PendingIntent.getService(ctx, 0, intent, FLAG_UPDATE_CURRENT))
 | 
			
		||||
            builder.addAction(
 | 
			
		||||
                R.drawable.ic_notification_node_stop,
 | 
			
		||||
                ctx.getString(R.string.full_node_stop),
 | 
			
		||||
                PendingIntent.getService(ctx, 0, intent, FLAG_UPDATE_CURRENT)
 | 
			
		||||
            )
 | 
			
		||||
        } else {
 | 
			
		||||
            intent.putExtra(BitmessageIntentService.EXTRA_STARTUP_NODE, true)
 | 
			
		||||
            builder.addAction(R.drawable.ic_notification_node_start,
 | 
			
		||||
                    ctx.getString(R.string.full_node_restart),
 | 
			
		||||
                    PendingIntent.getService(ctx, 1, intent, FLAG_UPDATE_CURRENT))
 | 
			
		||||
            builder.addAction(
 | 
			
		||||
                R.drawable.ic_notification_node_start,
 | 
			
		||||
                ctx.getString(R.string.full_node_restart),
 | 
			
		||||
                PendingIntent.getService(ctx, 1, intent, FLAG_UPDATE_CURRENT)
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
        notification = builder.build()
 | 
			
		||||
        return running
 | 
			
		||||
@@ -116,13 +129,15 @@ class NetworkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
        val intent = Intent(ctx, BitmessageIntentService::class.java)
 | 
			
		||||
        intent.putExtra(BitmessageIntentService.EXTRA_SHUTDOWN_NODE, true)
 | 
			
		||||
        builder.mActions.clear()
 | 
			
		||||
        builder.addAction(R.drawable.ic_notification_node_stop,
 | 
			
		||||
                ctx.getString(R.string.full_node_stop),
 | 
			
		||||
                PendingIntent.getService(ctx, 0, intent, FLAG_UPDATE_CURRENT))
 | 
			
		||||
        builder.addAction(
 | 
			
		||||
            R.drawable.ic_notification_node_stop,
 | 
			
		||||
            ctx.getString(R.string.full_node_stop),
 | 
			
		||||
            PendingIntent.getService(ctx, 0, intent, FLAG_UPDATE_CURRENT)
 | 
			
		||||
        )
 | 
			
		||||
        notification = builder.build()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        val NETWORK_NOTIFICATION_ID = 2
 | 
			
		||||
        const val NETWORK_NOTIFICATION_ID = 2
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -42,36 +42,48 @@ import ch.dissem.apps.abit.util.Drawables.toBitmap
 | 
			
		||||
 | 
			
		||||
class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        initChannel(MESSAGE_CHANNEL_ID, R.color.colorPrimary)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun singleNotification(plaintext: Plaintext): NewMessageNotification {
 | 
			
		||||
        val builder = NotificationCompat.Builder(ctx, CHANNEL_ID)
 | 
			
		||||
        val builder = NotificationCompat.Builder(ctx, MESSAGE_CHANNEL_ID)
 | 
			
		||||
        val bigText = SpannableString(plaintext.subject + "\n" + plaintext.text)
 | 
			
		||||
        plaintext.subject?.let { subject ->
 | 
			
		||||
            bigText.setSpan(SPAN_EMPHASIS, 0, subject.length, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
 | 
			
		||||
        }
 | 
			
		||||
        builder.setSmallIcon(R.drawable.ic_notification_new_message)
 | 
			
		||||
                .setLargeIcon(toBitmap(Identicon(plaintext.from), 192))
 | 
			
		||||
                .setContentTitle(plaintext.from.toString())
 | 
			
		||||
                .setContentText(plaintext.subject)
 | 
			
		||||
                .setStyle(BigTextStyle().bigText(bigText))
 | 
			
		||||
                .setContentInfo("Info")
 | 
			
		||||
            .setLargeIcon(toBitmap(Identicon(plaintext.from), 192))
 | 
			
		||||
            .setContentTitle(plaintext.from.toString())
 | 
			
		||||
            .setContentText(plaintext.subject)
 | 
			
		||||
            .setStyle(BigTextStyle().bigText(bigText))
 | 
			
		||||
            .setContentInfo("Info")
 | 
			
		||||
 | 
			
		||||
        builder.setContentIntent(
 | 
			
		||||
                createActivityIntent(EXTRA_SHOW_MESSAGE, plaintext))
 | 
			
		||||
        builder.addAction(R.drawable.ic_action_reply, ctx.getString(R.string.reply),
 | 
			
		||||
                createActivityIntent(EXTRA_REPLY_TO_MESSAGE, plaintext))
 | 
			
		||||
        builder.addAction(R.drawable.ic_action_delete, ctx.getString(R.string.delete),
 | 
			
		||||
                createServiceIntent(ctx, EXTRA_DELETE_MESSAGE, plaintext))
 | 
			
		||||
            createActivityIntent(EXTRA_SHOW_MESSAGE, plaintext)
 | 
			
		||||
        )
 | 
			
		||||
        builder.addAction(
 | 
			
		||||
            R.drawable.ic_action_reply, ctx.getString(R.string.reply),
 | 
			
		||||
            createActivityIntent(EXTRA_REPLY_TO_MESSAGE, plaintext)
 | 
			
		||||
        )
 | 
			
		||||
        builder.addAction(
 | 
			
		||||
            R.drawable.ic_action_delete, ctx.getString(R.string.delete),
 | 
			
		||||
            createServiceIntent(ctx, EXTRA_DELETE_MESSAGE, plaintext)
 | 
			
		||||
        )
 | 
			
		||||
        notification = builder.build()
 | 
			
		||||
        return this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun createActivityIntent(action: String, message: Plaintext): PendingIntent {
 | 
			
		||||
        val intent = Intent(ctx, MainActivity::class.java)
 | 
			
		||||
        intent.putExtra(action, message)
 | 
			
		||||
        val intent = Intent(ctx, MainActivity::class.java).putExtra(action, message)
 | 
			
		||||
        return PendingIntent.getActivity(ctx, action.hashCode(), intent, FLAG_UPDATE_CURRENT)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private fun createServiceIntent(ctx: Context, action: String, message: Plaintext): PendingIntent {
 | 
			
		||||
    private fun createServiceIntent(
 | 
			
		||||
        ctx: Context,
 | 
			
		||||
        action: String,
 | 
			
		||||
        message: Plaintext
 | 
			
		||||
    ): PendingIntent {
 | 
			
		||||
        val intent = Intent(ctx, BitmessageIntentService::class.java)
 | 
			
		||||
        intent.putExtra(action, message)
 | 
			
		||||
        return PendingIntent.getService(ctx, action.hashCode(), intent, FLAG_UPDATE_CURRENT)
 | 
			
		||||
@@ -82,19 +94,24 @@ class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
     * *                       accessed it will be in a `synchronized(unacknowledged)
 | 
			
		||||
     * *                       {}` block
 | 
			
		||||
     */
 | 
			
		||||
    fun multiNotification(unacknowledged: Collection<Plaintext>, numberOfUnacknowledgedMessages: Int): NewMessageNotification {
 | 
			
		||||
        val builder = NotificationCompat.Builder(ctx, CHANNEL_ID)
 | 
			
		||||
    fun multiNotification(
 | 
			
		||||
        unacknowledged: Collection<Plaintext>,
 | 
			
		||||
        numberOfUnacknowledgedMessages: Int
 | 
			
		||||
    ): NewMessageNotification {
 | 
			
		||||
        val builder = NotificationCompat.Builder(ctx, MESSAGE_CHANNEL_ID)
 | 
			
		||||
        builder.setSmallIcon(R.drawable.ic_notification_new_message)
 | 
			
		||||
                .setContentTitle(ctx.getString(R.string.n_new_messages, numberOfUnacknowledgedMessages))
 | 
			
		||||
                .setContentText(ctx.getString(R.string.app_name))
 | 
			
		||||
            .setContentTitle(ctx.getString(R.string.n_new_messages, numberOfUnacknowledgedMessages))
 | 
			
		||||
            .setContentText(ctx.getString(R.string.app_name))
 | 
			
		||||
 | 
			
		||||
        val inboxStyle = InboxStyle()
 | 
			
		||||
 | 
			
		||||
        synchronized(unacknowledged) {
 | 
			
		||||
            for (msg in unacknowledged) {
 | 
			
		||||
                val sb = SpannableString(msg.from.toString() + " " + msg.subject)
 | 
			
		||||
                sb.setSpan(SPAN_EMPHASIS, 0, msg.from.toString().length, Spannable
 | 
			
		||||
                        .SPAN_INCLUSIVE_EXCLUSIVE)
 | 
			
		||||
                sb.setSpan(
 | 
			
		||||
                    SPAN_EMPHASIS, 0, msg.from.toString().length, Spannable
 | 
			
		||||
                        .SPAN_INCLUSIVE_EXCLUSIVE
 | 
			
		||||
                )
 | 
			
		||||
                inboxStyle.addLine(sb)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -113,6 +130,5 @@ class NewMessageNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
    companion object {
 | 
			
		||||
        private val NEW_MESSAGE_NOTIFICATION_ID = 1
 | 
			
		||||
        private val SPAN_EMPHASIS = StyleSpan(Typeface.BOLD)
 | 
			
		||||
        private val CHANNEL_ID = "abit.message"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@ import kotlin.concurrent.fixedRateTimer
 | 
			
		||||
 */
 | 
			
		||||
class ProofOfWorkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, "abit.pow")
 | 
			
		||||
    private val builder = NotificationCompat.Builder(ctx, ONGOING_CHANNEL_ID)
 | 
			
		||||
        .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
 | 
			
		||||
        .setUsesChronometer(true)
 | 
			
		||||
        .setOngoing(true)
 | 
			
		||||
@@ -46,6 +46,7 @@ class ProofOfWorkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
    private var timer: Timer? = null
 | 
			
		||||
 | 
			
		||||
    init {
 | 
			
		||||
        initChannel(ONGOING_CHANNEL_ID, R.color.colorAccent)
 | 
			
		||||
        update(0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -67,10 +68,6 @@ class ProofOfWorkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
        return this
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val ONGOING_NOTIFICATION_ID = 3
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun start(item: ProofOfWorkService.PowItem) {
 | 
			
		||||
        val expectedPowTimeInMilliseconds = PowStats.getExpectedPowTimeInMilliseconds(ctx, item.targetValue)
 | 
			
		||||
        val delta = (expectedPowTimeInMilliseconds / 3).toInt()
 | 
			
		||||
@@ -101,4 +98,8 @@ class ProofOfWorkNotification(ctx: Context) : AbstractNotification(ctx) {
 | 
			
		||||
            show()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val ONGOING_NOTIFICATION_ID = 3
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,8 @@ import android.net.ConnectivityManager
 | 
			
		||||
import android.os.Handler
 | 
			
		||||
import ch.dissem.apps.abit.notification.NetworkNotification
 | 
			
		||||
import ch.dissem.apps.abit.notification.NetworkNotification.Companion.NETWORK_NOTIFICATION_ID
 | 
			
		||||
import ch.dissem.apps.abit.util.NetworkUtils
 | 
			
		||||
import ch.dissem.apps.abit.util.Preferences
 | 
			
		||||
import ch.dissem.bitmessage.BitmessageContext
 | 
			
		||||
import ch.dissem.bitmessage.utils.Property
 | 
			
		||||
import org.jetbrains.anko.connectivityManager
 | 
			
		||||
@@ -39,9 +41,9 @@ class BitmessageService : Service() {
 | 
			
		||||
    private val bmc: BitmessageContext by lazy { Singleton.getBitmessageContext(this) }
 | 
			
		||||
    private lateinit var notification: NetworkNotification
 | 
			
		||||
 | 
			
		||||
    private val connectivityReceiver: BroadcastReceiver = object: BroadcastReceiver() {
 | 
			
		||||
        override fun onReceive(context: Context?, intent: Intent?) {
 | 
			
		||||
            if (bmc.isRunning() && connectivityManager.isActiveNetworkMetered){
 | 
			
		||||
    private val connectivityReceiver: BroadcastReceiver = object : BroadcastReceiver() {
 | 
			
		||||
        override fun onReceive(context: Context, intent: Intent?) {
 | 
			
		||||
            if (bmc.isRunning() && !Preferences.isConnectionAllowed(this@BitmessageService)) {
 | 
			
		||||
                bmc.shutdown()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -58,7 +60,10 @@ class BitmessageService : Service() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onCreate() {
 | 
			
		||||
        registerReceiver(connectivityReceiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION))
 | 
			
		||||
        registerReceiver(
 | 
			
		||||
            connectivityReceiver,
 | 
			
		||||
            IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
 | 
			
		||||
        )
 | 
			
		||||
        notification = NetworkNotification(this)
 | 
			
		||||
        running = false
 | 
			
		||||
    }
 | 
			
		||||
@@ -85,13 +90,15 @@ class BitmessageService : Service() {
 | 
			
		||||
        notification.showShutdown()
 | 
			
		||||
        cleanupHandler.removeCallbacks(cleanupTask)
 | 
			
		||||
        bmc.cleanup()
 | 
			
		||||
        unregisterReceiver(connectivityReceiver)
 | 
			
		||||
        stopSelf()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    override fun onBind(intent: Intent) = null
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        @Volatile private var running = false
 | 
			
		||||
        @Volatile
 | 
			
		||||
        private var running = false
 | 
			
		||||
 | 
			
		||||
        val isRunning: Boolean
 | 
			
		||||
            get() = running && Singleton.bitmessageContext?.isRunning() == true
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ import android.app.Service
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.os.Binder
 | 
			
		||||
import android.os.IBinder
 | 
			
		||||
import android.support.v4.content.ContextCompat
 | 
			
		||||
import ch.dissem.apps.abit.notification.ProofOfWorkNotification
 | 
			
		||||
import ch.dissem.apps.abit.notification.ProofOfWorkNotification.Companion.ONGOING_NOTIFICATION_ID
 | 
			
		||||
import ch.dissem.apps.abit.util.PowStats
 | 
			
		||||
@@ -44,9 +45,14 @@ class ProofOfWorkService : Service() {
 | 
			
		||||
        private val notification = service.notification
 | 
			
		||||
 | 
			
		||||
        fun process(item: PowItem) = synchronized(queue) {
 | 
			
		||||
            service.startService(Intent(service, ProofOfWorkService::class.java))
 | 
			
		||||
            service.startForeground(ONGOING_NOTIFICATION_ID,
 | 
			
		||||
                notification.notification)
 | 
			
		||||
            ContextCompat.startForegroundService(
 | 
			
		||||
                service,
 | 
			
		||||
                Intent(service, ProofOfWorkService::class.java)
 | 
			
		||||
            )
 | 
			
		||||
            service.startForeground(
 | 
			
		||||
                ONGOING_NOTIFICATION_ID,
 | 
			
		||||
                notification.notification
 | 
			
		||||
            )
 | 
			
		||||
            if (!calculating) {
 | 
			
		||||
                calculating = true
 | 
			
		||||
                service.calculateNonce(item)
 | 
			
		||||
@@ -58,7 +64,11 @@ class ProofOfWorkService : Service() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    data class PowItem(val initialHash: ByteArray, val targetValue: ByteArray, val callback: ProofOfWorkEngine.Callback) {
 | 
			
		||||
    data class PowItem(
 | 
			
		||||
        val initialHash: ByteArray,
 | 
			
		||||
        val targetValue: ByteArray,
 | 
			
		||||
        val callback: ProofOfWorkEngine.Callback
 | 
			
		||||
    ) {
 | 
			
		||||
        override fun equals(other: Any?): Boolean {
 | 
			
		||||
            if (this === other) return true
 | 
			
		||||
            if (javaClass != other?.javaClass) return false
 | 
			
		||||
@@ -81,29 +91,32 @@ class ProofOfWorkService : Service() {
 | 
			
		||||
    private fun calculateNonce(item: PowItem) {
 | 
			
		||||
        notification.start(item)
 | 
			
		||||
        val startTime = System.currentTimeMillis()
 | 
			
		||||
        engine.calculateNonce(item.initialHash, item.targetValue, object : ProofOfWorkEngine.Callback {
 | 
			
		||||
            override fun onNonceCalculated(initialHash: ByteArray, nonce: ByteArray) {
 | 
			
		||||
                notification.finished()
 | 
			
		||||
                val time = System.currentTimeMillis() - startTime
 | 
			
		||||
                PowStats.addPow(this@ProofOfWorkService, time, item.targetValue)
 | 
			
		||||
                try {
 | 
			
		||||
                    item.callback.onNonceCalculated(initialHash, nonce)
 | 
			
		||||
                } finally {
 | 
			
		||||
                    var next: PowItem? = null
 | 
			
		||||
                    synchronized(queue) {
 | 
			
		||||
                        next = queue.poll()
 | 
			
		||||
                        if (next == null) {
 | 
			
		||||
                            calculating = false
 | 
			
		||||
                            stopForeground(true)
 | 
			
		||||
                            stopSelf()
 | 
			
		||||
                        } else {
 | 
			
		||||
                            notification.update(queue.size).show()
 | 
			
		||||
        engine.calculateNonce(
 | 
			
		||||
            item.initialHash,
 | 
			
		||||
            item.targetValue,
 | 
			
		||||
            object : ProofOfWorkEngine.Callback {
 | 
			
		||||
                override fun onNonceCalculated(initialHash: ByteArray, nonce: ByteArray) {
 | 
			
		||||
                    notification.finished()
 | 
			
		||||
                    val time = System.currentTimeMillis() - startTime
 | 
			
		||||
                    PowStats.addPow(this@ProofOfWorkService, time, item.targetValue)
 | 
			
		||||
                    try {
 | 
			
		||||
                        item.callback.onNonceCalculated(initialHash, nonce)
 | 
			
		||||
                    } finally {
 | 
			
		||||
                        var next: PowItem? = null
 | 
			
		||||
                        synchronized(queue) {
 | 
			
		||||
                            next = queue.poll()
 | 
			
		||||
                            if (next == null) {
 | 
			
		||||
                                calculating = false
 | 
			
		||||
                                stopForeground(true)
 | 
			
		||||
                                stopSelf()
 | 
			
		||||
                            } else {
 | 
			
		||||
                                notification.update(queue.size).show()
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        next?.let { calculateNonce(it) }
 | 
			
		||||
                    }
 | 
			
		||||
                    next?.let { calculateNonce(it) }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
            })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import android.app.job.JobService
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.support.annotation.RequiresApi
 | 
			
		||||
import ch.dissem.apps.abit.util.NetworkUtils
 | 
			
		||||
import ch.dissem.apps.abit.util.Preferences
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -19,7 +20,7 @@ class StartupNodeOnWifiService : JobService() {
 | 
			
		||||
    override fun onStartJob(params: JobParameters?): Boolean {
 | 
			
		||||
        val bmc = Singleton.getBitmessageContext(this)
 | 
			
		||||
        if (Preferences.isFullNodeActive(this) && !bmc.isRunning()) {
 | 
			
		||||
            applicationContext.startService(Intent(this, BitmessageService::class.java))
 | 
			
		||||
            NetworkUtils.doStartBitmessageService(applicationContext)
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,7 @@ import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.os.Build
 | 
			
		||||
import android.support.annotation.RequiresApi
 | 
			
		||||
import android.support.v4.content.ContextCompat
 | 
			
		||||
import ch.dissem.apps.abit.MainActivity
 | 
			
		||||
import ch.dissem.apps.abit.dialog.FullNodeDialogActivity
 | 
			
		||||
import ch.dissem.apps.abit.service.BitmessageService
 | 
			
		||||
@@ -23,7 +24,7 @@ object NetworkUtils {
 | 
			
		||||
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
 | 
			
		||||
                    scheduleNodeStart(ctx)
 | 
			
		||||
                } else {
 | 
			
		||||
                    ctx.startService(Intent(ctx, BitmessageService::class.java))
 | 
			
		||||
                    doStartBitmessageService(ctx)
 | 
			
		||||
                    MainActivity.updateNodeSwitch()
 | 
			
		||||
                }
 | 
			
		||||
            } else if (ask) {
 | 
			
		||||
@@ -37,11 +38,15 @@ object NetworkUtils {
 | 
			
		||||
                scheduleNodeStart(ctx)
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            ctx.startService(Intent(ctx, BitmessageService::class.java))
 | 
			
		||||
            doStartBitmessageService(ctx)
 | 
			
		||||
            MainActivity.updateNodeSwitch()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun doStartBitmessageService(ctx: Context) {
 | 
			
		||||
        ContextCompat.startForegroundService(ctx, Intent(ctx, BitmessageService::class.java))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun disableNode(ctx: Context) {
 | 
			
		||||
        Preferences.setFullNodeActive(ctx, false)
 | 
			
		||||
        ctx.stopService(Intent(ctx, BitmessageService::class.java))
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user