Fixed initialisation, added message/broadcast sending to service

This commit is contained in:
Christian Basler 2015-10-25 09:50:40 +01:00
parent 725089c604
commit 7fe7ee42fc
6 changed files with 97 additions and 89 deletions

View File

@ -47,14 +47,13 @@ import ch.dissem.apps.abit.listener.ListSelectionListener;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.synchronization.Authenticator;
import ch.dissem.apps.abit.synchronization.BitmessageService;
import ch.dissem.apps.abit.synchronization.SyncService;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.Label;
import ch.dissem.bitmessage.ports.AddressRepository;
import ch.dissem.bitmessage.ports.MessageRepository;
import static ch.dissem.apps.abit.synchronization.BitmessageService.DATA_FIELD_ADDRESS;
import static ch.dissem.apps.abit.synchronization.BitmessageService.DATA_FIELD_IDENTITY;
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_START_NODE;
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_STOP_NODE;
import static ch.dissem.apps.abit.synchronization.StubProvider.AUTHORITY;
@ -419,19 +418,23 @@ public class MessageListActivity extends AppCompatActivity
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case BitmessageService.MSG_CREATE_IDENTITY:
BitmessageAddress identity = (BitmessageAddress) msg.getData().getSerializable(DATA_FIELD_ADDRESS);
IProfile newProfile = new ProfileDrawerItem()
.withName(identity.toString())
.withEmail(identity.getAddress())
.withTag(identity);
if (accountHeader.getProfiles() != null) {
//we know that there are 2 setting elements. set the new profile above them ;)
accountHeader.addProfile(newProfile, accountHeader.getProfiles().size() - 2);
} else {
accountHeader.addProfiles(newProfile);
case BitmessageService.MSG_CREATE_IDENTITY: {
Serializable data = msg.getData().getSerializable(DATA_FIELD_IDENTITY);
if (data instanceof BitmessageAddress) {
BitmessageAddress identity = (BitmessageAddress) data;
IProfile newProfile = new ProfileDrawerItem()
.withName(identity.toString())
.withEmail(identity.getAddress())
.withTag(identity);
if (accountHeader.getProfiles() != null) {
//we know that there are 2 setting elements. set the new profile above them ;)
accountHeader.addProfile(newProfile, accountHeader.getProfiles().size() - 2);
} else {
accountHeader.addProfiles(newProfile);
}
}
break;
}
default:
super.handleMessage(msg);
}

View File

@ -23,13 +23,11 @@ import android.database.sqlite.SQLiteConstraintException;
import android.database.sqlite.SQLiteDatabase;
import ch.dissem.apps.abit.R;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.InternalContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext;
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
import ch.dissem.bitmessage.entity.valueobject.Label;
import ch.dissem.bitmessage.ports.AddressRepository;
import ch.dissem.bitmessage.ports.MessageRepository;
import ch.dissem.bitmessage.utils.Encode;
@ -47,7 +45,7 @@ import static ch.dissem.apps.abit.repository.SqlHelper.join;
/**
* {@link MessageRepository} implementation using the Android SQL API.
*/
public class AndroidMessageRepository implements MessageRepository {
public class AndroidMessageRepository implements MessageRepository, InternalContext.ContextHolder {
private static final Logger LOG = LoggerFactory.getLogger(AndroidMessageRepository.class);
private static final String TABLE_NAME = "Message";
@ -73,13 +71,16 @@ public class AndroidMessageRepository implements MessageRepository {
private static final String LBL_COLUMN_ORDER = "ord";
private final SqlHelper sql;
private final Context ctx;
private final AddressRepository addressRepo;
private InternalContext bmc;
public AndroidMessageRepository(SqlHelper sql, Context ctx) {
this.sql = sql;
this.ctx = ctx;
this.addressRepo = Singleton.getAddressRepository(ctx);
}
@Override
public void setContext(InternalContext context) {
bmc = context;
}
@Override
@ -229,8 +230,8 @@ public class AndroidMessageRepository implements MessageRepository {
long id = c.getLong(c.getColumnIndex(COLUMN_ID));
builder.id(id);
builder.IV(new InventoryVector(iv));
builder.from(addressRepo.getAddress(c.getString(c.getColumnIndex(COLUMN_SENDER))));
builder.to(addressRepo.getAddress(c.getString(c.getColumnIndex(COLUMN_RECIPIENT))));
builder.from(bmc.getAddressRepo().getAddress(c.getString(c.getColumnIndex(COLUMN_SENDER))));
builder.to(bmc.getAddressRepo().getAddress(c.getString(c.getColumnIndex(COLUMN_RECIPIENT))));
builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT)));
builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED)));
builder.status(Plaintext.Status.valueOf(c.getString(c.getColumnIndex(COLUMN_STATUS))));
@ -256,12 +257,12 @@ public class AndroidMessageRepository implements MessageRepository {
// save from address if necessary
if (message.getId() == null) {
BitmessageAddress savedAddress = addressRepo.getAddress(message.getFrom().getAddress());
BitmessageAddress savedAddress = bmc.getAddressRepo().getAddress(message.getFrom().getAddress());
if (savedAddress == null || savedAddress.getPrivateKey() == null) {
if (savedAddress != null && savedAddress.getAlias() != null) {
message.getFrom().setAlias(savedAddress.getAlias());
}
addressRepo.save(message.getFrom());
bmc.getAddressRepo().save(message.getFrom());
}
}

View File

@ -2,6 +2,8 @@ package ch.dissem.apps.abit.service;
import android.content.Context;
import java.util.Objects;
import ch.dissem.apps.abit.MessageListActivity;
import ch.dissem.apps.abit.listener.MessageListener;
import ch.dissem.apps.abit.repository.AndroidAddressRepository;
@ -20,14 +22,29 @@ import ch.dissem.bitmessage.security.sc.SpongySecurity;
* Provides singleton objects across the application.
*/
public class Singleton {
private static SqlHelper sqlHelper;
private static Security security;
private static MessageRepository messageRepository;
public static final Object lock = new Object();
private static BitmessageContext bitmessageContext;
private static MessageListener messageListener;
private static AddressRepository addressRepository;
static {
ch.dissem.bitmessage.utils.Singleton.initialize(new SpongySecurity());
public static BitmessageContext getBitmessageContext(Context context) {
if (bitmessageContext == null) {
synchronized (lock) {
if (bitmessageContext == null) {
final Context ctx = context.getApplicationContext();
SqlHelper sqlHelper = new SqlHelper(ctx);
bitmessageContext = new BitmessageContext.Builder()
.security(new SpongySecurity())
.nodeRegistry(new MemoryNodeRegistry())
.inventory(new AndroidInventory(sqlHelper))
.addressRepo(new AndroidAddressRepository(sqlHelper))
.messageRepo(new AndroidMessageRepository(sqlHelper, ctx))
.networkHandler(new DefaultNetworkHandler())
.listener(getMessageListener(ctx))
.build();
}
}
}
return bitmessageContext;
}
public static MessageListener getMessageListener(Context ctx) {
@ -41,40 +58,11 @@ public class Singleton {
return messageListener;
}
public static SqlHelper getSqlHelper(Context ctx) {
if (sqlHelper == null) {
synchronized (Singleton.class) {
if (sqlHelper == null) {
sqlHelper = new SqlHelper(ctx.getApplicationContext());
}
}
}
return sqlHelper;
}
public static MessageRepository getMessageRepository(Context ctx) {
if (messageRepository == null) {
ctx = ctx.getApplicationContext();
getSqlHelper(ctx);
synchronized (Singleton.class) {
if (messageRepository == null) {
messageRepository = new AndroidMessageRepository(sqlHelper, ctx);
}
}
}
return messageRepository;
return getBitmessageContext(ctx).messages();
}
public static AddressRepository getAddressRepository(Context ctx) {
if (addressRepository == null) {
ctx = ctx.getApplicationContext();
getSqlHelper(ctx);
synchronized (Singleton.class) {
if (addressRepository == null) {
addressRepository = new AndroidAddressRepository(sqlHelper);
}
}
}
return addressRepository;
return getBitmessageContext(ctx).addresses();
}
}

View File

@ -14,19 +14,14 @@ import android.preference.PreferenceManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.UnknownHostException;
import ch.dissem.apps.abit.listener.MessageListener;
import ch.dissem.apps.abit.notification.NetworkNotification;
import ch.dissem.apps.abit.repository.AndroidInventory;
import ch.dissem.apps.abit.repository.SqlHelper;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
import ch.dissem.bitmessage.security.sc.SpongySecurity;
import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIFICATION_ID;
@ -43,15 +38,19 @@ public class BitmessageService extends Service {
public static final int MSG_SUBSCRIBE = 20;
public static final int MSG_ADD_CONTACT = 21;
public static final int MSG_SUBSCRIBE_AND_ADD_CONTACT = 23;
public static final int MSG_SEND_MESSAGE = 30;
public static final int MSG_SEND_BROADCAST = 31;
public static final int MSG_START_NODE = 100;
public static final int MSG_STOP_NODE = 101;
public static final String DATA_FIELD_IDENTITY = "identity";
public static final String DATA_FIELD_ADDRESS = "address";
public static final String DATA_FIELD_SUBJECT = "subject";
public static final String DATA_FIELD_MESSAGE = "message";
// Object to use as a thread-safe lock
private static final Object lock = new Object();
private static MessageListener messageListener = null;
private static NetworkNotification notification = null;
private static BitmessageContext bmc = null;
@ -67,17 +66,7 @@ public class BitmessageService extends Service {
public void onCreate() {
synchronized (lock) {
if (bmc == null) {
messageListener = Singleton.getMessageListener(this);
SqlHelper sqlHelper = Singleton.getSqlHelper(this);
bmc = new BitmessageContext.Builder()
.security(new SpongySecurity())
.nodeRegistry(new MemoryNodeRegistry())
.inventory(new AndroidInventory(sqlHelper))
.addressRepo(Singleton.getAddressRepository(this))
.messageRepo(Singleton.getMessageRepository(this))
.networkHandler(new DefaultNetworkHandler())
.listener(messageListener)
.build();
bmc = Singleton.getBitmessageContext(this);
notification = new NetworkNotification(this, bmc);
messenger = new Messenger(new IncomingHandler());
}
@ -108,13 +97,13 @@ public class BitmessageService extends Service {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CREATE_IDENTITY:
case MSG_CREATE_IDENTITY: {
BitmessageAddress identity = bmc.createIdentity(false);
if (msg.replyTo != null) {
try {
Message message = Message.obtain(this, MSG_CREATE_IDENTITY);
Bundle bundle = new Bundle();
bundle.putSerializable(DATA_FIELD_ADDRESS, identity);
bundle.putSerializable(DATA_FIELD_IDENTITY, identity);
message.setData(bundle);
msg.replyTo.send(message);
} catch (RemoteException e) {
@ -122,11 +111,15 @@ public class BitmessageService extends Service {
}
}
break;
case MSG_SUBSCRIBE:
BitmessageAddress address = (BitmessageAddress) msg.getData().getSerializable(DATA_FIELD_ADDRESS);
bmc.addSubscribtion(address);
}
case MSG_SUBSCRIBE: {
Serializable data = msg.getData().getSerializable(DATA_FIELD_ADDRESS);
if (data instanceof BitmessageAddress) {
bmc.addSubscribtion((BitmessageAddress) data);
}
break;
case MSG_SYNC:
}
case MSG_SYNC: {
LOG.info("Synchronizing Bitmessage");
// If the Bitmessage context acts as a full node, synchronization isn't necessary
if (bmc.isRunning()) break;
@ -164,9 +157,32 @@ public class BitmessageService extends Service {
// TODO: show error as notification
}
break;
}
case MSG_SEND_MESSAGE: {
Serializable identity = msg.getData().getSerializable(DATA_FIELD_IDENTITY);
Serializable address = msg.getData().getSerializable(DATA_FIELD_ADDRESS);
if (identity instanceof BitmessageAddress
&& address instanceof BitmessageAddress) {
String subject = msg.getData().getString(DATA_FIELD_SUBJECT);
String message = msg.getData().getString(DATA_FIELD_MESSAGE);
bmc.send((BitmessageAddress) identity, (BitmessageAddress) address,
subject, message);
}
break;
}
case MSG_SEND_BROADCAST: {
Serializable data = msg.getData().getSerializable(DATA_FIELD_IDENTITY);
if (data instanceof BitmessageAddress) {
String subject = msg.getData().getString(DATA_FIELD_SUBJECT);
String message = msg.getData().getString(DATA_FIELD_MESSAGE);
bmc.broadcast((BitmessageAddress) data, subject, message);
}
break;
}
case MSG_START_NODE:
startService(new Intent(BitmessageService.this, BitmessageService.class));
// TODO: warn user, option to restrict to WiFi
// (I'm not quite sure this can be done here, though)
startService(new Intent(BitmessageService.this, BitmessageService.class));
running = true;
startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification());
bmc.startup();

View File

@ -30,9 +30,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
/**
* Set up the sync adapter
*/
public SyncAdapter(Context context, BitmessageContext bitmessageContext) {
super(context, true);
bmc = bitmessageContext;
public SyncAdapter(Context context, boolean autoInitialize) {
super(context, autoInitialize);
bmc = Singleton.getBitmessageContext(context);
}
@Override

View File

@ -39,7 +39,7 @@ public class SyncService extends Service {
*/
synchronized (syncAdapterLock) {
if (syncAdapter == null) {
syncAdapter = new SyncAdapter(this, null); // FIXME
syncAdapter = new SyncAdapter(this, true);
}
}
}