Some Bugfixes and some Kotlin that helped fixing the bugs

This commit is contained in:
2017-07-28 07:39:57 +02:00
parent e064012551
commit 898c49802b
19 changed files with 961 additions and 1048 deletions

View File

@ -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");
}
}
}

View File

@ -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")
}
}

View File

@ -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;
}
}

View 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!!
}
}