146 lines
6.0 KiB
Kotlin
146 lines
6.0 KiB
Kotlin
/*
|
|
* Copyright 2016 Christian Basler
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package ch.dissem.apps.abit.service
|
|
|
|
import android.content.Context
|
|
import android.widget.Toast
|
|
import ch.dissem.apps.abit.MainActivity
|
|
import ch.dissem.apps.abit.R
|
|
import ch.dissem.apps.abit.adapter.AndroidCryptography
|
|
import ch.dissem.apps.abit.adapter.SwitchingProofOfWorkEngine
|
|
import ch.dissem.apps.abit.listener.MessageListener
|
|
import ch.dissem.apps.abit.pow.ServerPowEngine
|
|
import ch.dissem.apps.abit.repository.*
|
|
import ch.dissem.apps.abit.util.Constants
|
|
import ch.dissem.bitmessage.BitmessageContext
|
|
import ch.dissem.bitmessage.entity.BitmessageAddress
|
|
import ch.dissem.bitmessage.entity.payload.Pubkey
|
|
import ch.dissem.bitmessage.networking.nio.NioNetworkHandler
|
|
import ch.dissem.bitmessage.ports.DefaultLabeler
|
|
import ch.dissem.bitmessage.utils.ConversationService
|
|
import ch.dissem.bitmessage.utils.TTL
|
|
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
|
import org.jetbrains.anko.doAsync
|
|
import org.jetbrains.anko.uiThread
|
|
|
|
/**
|
|
* Provides singleton objects across the application.
|
|
*/
|
|
object Singleton {
|
|
val labeler = DefaultLabeler()
|
|
var bitmessageContext: BitmessageContext? = null
|
|
private set
|
|
private var conversationService: ConversationService? = null
|
|
private var messageListener: MessageListener? = null
|
|
private var identity: BitmessageAddress? = null
|
|
private var powRepo: AndroidProofOfWorkRepository? = null
|
|
private var creatingIdentity: Boolean = false
|
|
|
|
fun getBitmessageContext(context: Context): BitmessageContext =
|
|
init({ bitmessageContext }, { bitmessageContext = it }) {
|
|
val ctx = context.applicationContext
|
|
val sqlHelper = SqlHelper(ctx)
|
|
val powRepo = AndroidProofOfWorkRepository(sqlHelper)
|
|
this.powRepo = powRepo
|
|
TTL.pubkey = 2 * DAY
|
|
BitmessageContext.Builder()
|
|
.proofOfWorkEngine(SwitchingProofOfWorkEngine(
|
|
ctx, Constants.PREFERENCE_SERVER_POW,
|
|
ServerPowEngine(ctx),
|
|
ServicePowEngine(ctx)
|
|
))
|
|
.cryptography(AndroidCryptography())
|
|
.nodeRegistry(AndroidNodeRegistry(sqlHelper))
|
|
.inventory(AndroidInventory(sqlHelper))
|
|
.addressRepo(AndroidAddressRepository(sqlHelper))
|
|
.messageRepo(AndroidMessageRepository(sqlHelper, ctx))
|
|
.powRepo(powRepo)
|
|
.networkHandler(NioNetworkHandler())
|
|
.listener(getMessageListener(ctx))
|
|
.labeler(labeler)
|
|
.doNotSendPubkeyOnIdentityCreation()
|
|
.build()
|
|
}
|
|
|
|
fun getMessageListener(ctx: Context) = init({ messageListener }, { messageListener = it }) { MessageListener(ctx) }
|
|
|
|
fun getMessageRepository(ctx: Context) = getBitmessageContext(ctx).messages as AndroidMessageRepository
|
|
|
|
fun getAddressRepository(ctx: Context) = getBitmessageContext(ctx).addresses as AndroidAddressRepository
|
|
|
|
fun getProofOfWorkRepository(ctx: Context) = powRepo ?: getBitmessageContext(ctx).internals.proofOfWorkRepository
|
|
|
|
fun getIdentity(ctx: Context): BitmessageAddress? =
|
|
init<BitmessageAddress?>(ctx, { identity }, { identity = it }) { bmc ->
|
|
val identities = bmc.addresses.getIdentities()
|
|
if (identities.isNotEmpty()) {
|
|
identities[0]
|
|
} else {
|
|
if (!creatingIdentity) {
|
|
creatingIdentity = true
|
|
doAsync {
|
|
val identity = bmc.createIdentity(false,
|
|
Pubkey.Feature.DOES_ACK)
|
|
identity.alias = ctx.getString(R.string.alias_default_identity)
|
|
bmc.addresses.save(identity)
|
|
|
|
uiThread {
|
|
Singleton.identity = identity
|
|
Toast.makeText(ctx,
|
|
R.string.toast_identity_created,
|
|
Toast.LENGTH_SHORT).show()
|
|
val mainActivity = MainActivity.getInstance()
|
|
mainActivity?.addIdentityEntry(identity)
|
|
}
|
|
}
|
|
}
|
|
null
|
|
}
|
|
}
|
|
|
|
fun setIdentity(identity: BitmessageAddress) {
|
|
if (identity.privateKey == null)
|
|
throw IllegalArgumentException("Identity expected, but no private key available")
|
|
Singleton.identity = identity
|
|
}
|
|
|
|
fun getConversationService(ctx: Context) = init(ctx, { conversationService }, { conversationService = it }) { ConversationService(it.messages) }
|
|
|
|
private inline fun <T> init(crossinline getter: () -> T?, crossinline setter: (T) -> Unit, crossinline creator: () -> T): T =
|
|
getter() ?: {
|
|
synchronized(Singleton) {
|
|
getter() ?: {
|
|
val v = creator()
|
|
setter(v)
|
|
v
|
|
}.invoke()
|
|
}
|
|
}.invoke()
|
|
|
|
private inline fun <T> init(ctx: Context, crossinline getter: () -> T?, crossinline setter: (T) -> Unit, crossinline creator: (BitmessageContext) -> T): T =
|
|
getter() ?: {
|
|
val bmc = getBitmessageContext(ctx)
|
|
synchronized(Singleton) {
|
|
getter() ?: {
|
|
val v = creator(bmc)
|
|
setter(v)
|
|
v
|
|
}.invoke()
|
|
}
|
|
}.invoke()
|
|
}
|