Some Bugfixes and some Kotlin that helped fixing the bugs
This commit is contained in:
@ -1,106 +0,0 @@
|
||||
/*
|
||||
* 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.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import ch.dissem.apps.abit.notification.NetworkNotification;
|
||||
import ch.dissem.bitmessage.BitmessageContext;
|
||||
import ch.dissem.bitmessage.utils.Property;
|
||||
|
||||
import static ch.dissem.apps.abit.notification.NetworkNotification.NETWORK_NOTIFICATION_ID;
|
||||
|
||||
/**
|
||||
* Define a Service that returns an IBinder for the
|
||||
* sync adapter class, allowing the sync adapter framework to call
|
||||
* onPerformSync().
|
||||
*/
|
||||
public class BitmessageService extends Service {
|
||||
private static BitmessageContext bmc = null;
|
||||
private static volatile boolean running = false;
|
||||
|
||||
private NetworkNotification notification = null;
|
||||
|
||||
private final Handler cleanupHandler = new Handler();
|
||||
private final Runnable cleanupTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
bmc.cleanup();
|
||||
if (isRunning()) {
|
||||
cleanupHandler.postDelayed(this, 24 * 60 * 60 * 1000L);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static boolean isRunning() {
|
||||
return running && bmc.isRunning();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
if (bmc == null) {
|
||||
bmc = Singleton.getBitmessageContext(this);
|
||||
}
|
||||
notification = new NetworkNotification(this);
|
||||
running = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
if (!isRunning()) {
|
||||
running = true;
|
||||
notification.connecting();
|
||||
startForeground(NETWORK_NOTIFICATION_ID, notification.getNotification());
|
||||
if (!bmc.isRunning()) {
|
||||
bmc.startup();
|
||||
}
|
||||
notification.show();
|
||||
cleanupHandler.postDelayed(cleanupTask, 24 * 60 * 60 * 1000L);
|
||||
}
|
||||
return Service.START_STICKY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (bmc.isRunning()) {
|
||||
bmc.shutdown();
|
||||
}
|
||||
running = false;
|
||||
notification.showShutdown();
|
||||
cleanupHandler.removeCallbacks(cleanupTask);
|
||||
bmc.cleanup();
|
||||
stopSelf();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Property getStatus() {
|
||||
if (bmc != null) {
|
||||
return bmc.status();
|
||||
} else {
|
||||
return new Property("bitmessage context");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.app.Service
|
||||
import android.content.Intent
|
||||
import android.os.Handler
|
||||
import ch.dissem.apps.abit.notification.NetworkNotification
|
||||
import ch.dissem.apps.abit.notification.NetworkNotification.NETWORK_NOTIFICATION_ID
|
||||
import ch.dissem.bitmessage.BitmessageContext
|
||||
import ch.dissem.bitmessage.utils.Property
|
||||
|
||||
/**
|
||||
* Define a Service that returns an IBinder for the
|
||||
* sync adapter class, allowing the sync adapter framework to call
|
||||
* onPerformSync().
|
||||
*/
|
||||
class BitmessageService : Service() {
|
||||
|
||||
private val bmc: BitmessageContext by lazy { Singleton.getBitmessageContext(this) }
|
||||
private lateinit var notification: NetworkNotification
|
||||
|
||||
private val cleanupHandler = Handler()
|
||||
private val cleanupTask = object : Runnable {
|
||||
override fun run() {
|
||||
bmc.cleanup()
|
||||
if (isRunning) {
|
||||
cleanupHandler.postDelayed(this, 24 * 60 * 60 * 1000L) // once a day
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
notification = NetworkNotification(this)
|
||||
running = false
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
if (!isRunning) {
|
||||
running = true
|
||||
notification.connecting()
|
||||
startForeground(NETWORK_NOTIFICATION_ID, notification.notification)
|
||||
if (!bmc.isRunning()) {
|
||||
bmc.startup()
|
||||
}
|
||||
notification.show()
|
||||
cleanupHandler.postDelayed(cleanupTask, 24 * 60 * 60 * 1000L)
|
||||
}
|
||||
return Service.START_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
if (bmc.isRunning()) {
|
||||
bmc.shutdown()
|
||||
}
|
||||
running = false
|
||||
notification.showShutdown()
|
||||
cleanupHandler.removeCallbacks(cleanupTask)
|
||||
bmc.cleanup()
|
||||
stopSelf()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent) = null
|
||||
|
||||
companion object {
|
||||
@Volatile private var running = false
|
||||
|
||||
@JvmStatic
|
||||
val isRunning: Boolean
|
||||
get() = running && Singleton.bitmessageContext?.isRunning() ?: false
|
||||
|
||||
@JvmStatic
|
||||
val status: Property
|
||||
get() = Singleton.bitmessageContext?.status() ?: Property("bitmessage context")
|
||||
}
|
||||
}
|
@ -1,177 +0,0 @@
|
||||
/*
|
||||
* 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.os.AsyncTask;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.AndroidAddressRepository;
|
||||
import ch.dissem.apps.abit.repository.AndroidInventory;
|
||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository;
|
||||
import ch.dissem.apps.abit.repository.AndroidNodeRegistry;
|
||||
import ch.dissem.apps.abit.repository.AndroidProofOfWorkRepository;
|
||||
import ch.dissem.apps.abit.repository.SqlHelper;
|
||||
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.AddressRepository;
|
||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||
import ch.dissem.bitmessage.ports.ProofOfWorkRepository;
|
||||
import ch.dissem.bitmessage.utils.ConversationService;
|
||||
import ch.dissem.bitmessage.utils.TTL;
|
||||
|
||||
import static ch.dissem.bitmessage.utils.UnixTime.DAY;
|
||||
|
||||
/**
|
||||
* Provides singleton objects across the application.
|
||||
*/
|
||||
public class Singleton {
|
||||
private static BitmessageContext bitmessageContext;
|
||||
private static ConversationService conversationService;
|
||||
private static MessageListener messageListener;
|
||||
private static BitmessageAddress identity;
|
||||
private static AndroidProofOfWorkRepository powRepo;
|
||||
private static boolean creatingIdentity;
|
||||
|
||||
public static BitmessageContext getBitmessageContext(Context context) {
|
||||
if (bitmessageContext == null) {
|
||||
synchronized (Singleton.class) {
|
||||
if (bitmessageContext == null) {
|
||||
final Context ctx = context.getApplicationContext();
|
||||
SqlHelper sqlHelper = new SqlHelper(ctx);
|
||||
powRepo = new AndroidProofOfWorkRepository(sqlHelper);
|
||||
TTL.pubkey(2 * DAY);
|
||||
bitmessageContext = new BitmessageContext.Builder()
|
||||
.proofOfWorkEngine(new SwitchingProofOfWorkEngine(
|
||||
ctx, Constants.PREFERENCE_SERVER_POW,
|
||||
new ServerPowEngine(ctx),
|
||||
new ServicePowEngine(ctx)
|
||||
))
|
||||
.cryptography(new AndroidCryptography())
|
||||
.nodeRegistry(new AndroidNodeRegistry(sqlHelper))
|
||||
.inventory(new AndroidInventory(sqlHelper))
|
||||
.addressRepo(new AndroidAddressRepository(sqlHelper))
|
||||
.messageRepo(new AndroidMessageRepository(sqlHelper, ctx))
|
||||
.powRepo(powRepo)
|
||||
.networkHandler(new NioNetworkHandler())
|
||||
.listener(getMessageListener(ctx))
|
||||
.doNotSendPubkeyOnIdentityCreation()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitmessageContext;
|
||||
}
|
||||
|
||||
public static MessageListener getMessageListener(Context ctx) {
|
||||
if (messageListener == null) {
|
||||
synchronized (Singleton.class) {
|
||||
if (messageListener == null) {
|
||||
messageListener = new MessageListener(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageListener;
|
||||
}
|
||||
|
||||
public static AndroidMessageRepository getMessageRepository(Context ctx) {
|
||||
return (AndroidMessageRepository) getBitmessageContext(ctx).messages();
|
||||
}
|
||||
|
||||
public static AndroidAddressRepository getAddressRepository(Context ctx) {
|
||||
return (AndroidAddressRepository) getBitmessageContext(ctx).addresses();
|
||||
}
|
||||
|
||||
public static ProofOfWorkRepository getProofOfWorkRepository(Context ctx) {
|
||||
if (powRepo == null) getBitmessageContext(ctx);
|
||||
return powRepo;
|
||||
}
|
||||
|
||||
public static BitmessageAddress getIdentity(final Context ctx) {
|
||||
if (identity == null) {
|
||||
final BitmessageContext bmc = getBitmessageContext(ctx);
|
||||
synchronized (Singleton.class) {
|
||||
if (identity == null) {
|
||||
List<BitmessageAddress> identities = bmc.addresses()
|
||||
.getIdentities();
|
||||
if (identities.size() > 0) {
|
||||
identity = identities.get(0);
|
||||
} else {
|
||||
if (!creatingIdentity) {
|
||||
creatingIdentity = true;
|
||||
new AsyncTask<Void, Void, BitmessageAddress>() {
|
||||
@Override
|
||||
protected BitmessageAddress doInBackground(Void... args) {
|
||||
BitmessageAddress identity = bmc.createIdentity(false,
|
||||
Pubkey.Feature.DOES_ACK);
|
||||
identity.setAlias(
|
||||
ctx.getString(R.string.alias_default_identity)
|
||||
);
|
||||
bmc.addresses().save(identity);
|
||||
return identity;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(BitmessageAddress identity) {
|
||||
Singleton.identity = identity;
|
||||
Toast.makeText(ctx,
|
||||
R.string.toast_identity_created,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
MainActivity mainActivity = MainActivity.getInstance();
|
||||
if (mainActivity != null) {
|
||||
mainActivity.addIdentityEntry(identity);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return identity;
|
||||
}
|
||||
|
||||
public static void setIdentity(BitmessageAddress identity) {
|
||||
if (identity.getPrivateKey() == null)
|
||||
throw new IllegalArgumentException("Identity expected, but no private key available");
|
||||
Singleton.identity = identity;
|
||||
}
|
||||
|
||||
public static ConversationService getConversationService(Context ctx) {
|
||||
if (conversationService == null) {
|
||||
final BitmessageContext bmc = getBitmessageContext(ctx);
|
||||
synchronized (Singleton.class) {
|
||||
if (conversationService == null) {
|
||||
conversationService = new ConversationService(bmc.messages());
|
||||
}
|
||||
}
|
||||
}
|
||||
return conversationService;
|
||||
}
|
||||
}
|
168
app/src/main/java/ch/dissem/apps/abit/service/Singleton.kt
Normal file
168
app/src/main/java/ch/dissem/apps/abit/service/Singleton.kt
Normal file
@ -0,0 +1,168 @@
|
||||
/*
|
||||
* 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.os.AsyncTask
|
||||
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.ProofOfWorkRepository
|
||||
import ch.dissem.bitmessage.utils.ConversationService
|
||||
import ch.dissem.bitmessage.utils.TTL
|
||||
import ch.dissem.bitmessage.utils.UnixTime.DAY
|
||||
|
||||
/**
|
||||
* Provides singleton objects across the application.
|
||||
*/
|
||||
object Singleton {
|
||||
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
|
||||
|
||||
@JvmStatic
|
||||
fun getBitmessageContext(context: Context): BitmessageContext {
|
||||
if (bitmessageContext == null) {
|
||||
synchronized(Singleton::class.java) {
|
||||
if (bitmessageContext == null) {
|
||||
val ctx = context.applicationContext
|
||||
val sqlHelper = SqlHelper(ctx)
|
||||
powRepo = AndroidProofOfWorkRepository(sqlHelper)
|
||||
TTL.pubkey = 2 * DAY
|
||||
bitmessageContext = 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))
|
||||
.doNotSendPubkeyOnIdentityCreation()
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitmessageContext!!
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMessageListener(ctx: Context): MessageListener {
|
||||
if (messageListener == null) {
|
||||
synchronized(Singleton::class.java) {
|
||||
if (messageListener == null) {
|
||||
messageListener = MessageListener(ctx)
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageListener!!
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getMessageRepository(ctx: Context): AndroidMessageRepository {
|
||||
return getBitmessageContext(ctx).messages as AndroidMessageRepository
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getAddressRepository(ctx: Context): AndroidAddressRepository {
|
||||
return getBitmessageContext(ctx).addresses as AndroidAddressRepository
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getProofOfWorkRepository(ctx: Context): ProofOfWorkRepository {
|
||||
if (powRepo == null) getBitmessageContext(ctx)
|
||||
return powRepo!!
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getIdentity(ctx: Context): BitmessageAddress? {
|
||||
if (identity == null) {
|
||||
val bmc = getBitmessageContext(ctx)
|
||||
synchronized(Singleton::class) {
|
||||
if (identity == null) {
|
||||
val identities = bmc.addresses.getIdentities()
|
||||
if (identities.isNotEmpty()) {
|
||||
identity = identities[0]
|
||||
} else {
|
||||
if (!creatingIdentity) {
|
||||
creatingIdentity = true
|
||||
object : AsyncTask<Void, Void, BitmessageAddress>() {
|
||||
override fun doInBackground(vararg args: Void): BitmessageAddress {
|
||||
val identity = bmc.createIdentity(false,
|
||||
Pubkey.Feature.DOES_ACK)
|
||||
identity.alias = ctx.getString(R.string.alias_default_identity)
|
||||
bmc.addresses.save(identity)
|
||||
return identity
|
||||
}
|
||||
|
||||
override fun onPostExecute(identity: BitmessageAddress) {
|
||||
Singleton.identity = identity
|
||||
Toast.makeText(ctx,
|
||||
R.string.toast_identity_created,
|
||||
Toast.LENGTH_SHORT).show()
|
||||
val mainActivity = MainActivity.getInstance()
|
||||
mainActivity?.addIdentityEntry(identity)
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return identity
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setIdentity(identity: BitmessageAddress) {
|
||||
if (identity.privateKey == null)
|
||||
throw IllegalArgumentException("Identity expected, but no private key available")
|
||||
Singleton.identity = identity
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getConversationService(ctx: Context): ConversationService {
|
||||
if (conversationService == null) {
|
||||
val bmc = getBitmessageContext(ctx)
|
||||
synchronized(Singleton::class.java) {
|
||||
if (conversationService == null) {
|
||||
conversationService = ConversationService(bmc.messages)
|
||||
}
|
||||
}
|
||||
}
|
||||
return conversationService!!
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user