Moving Bitmessage context into a foreground service (work in progress)

This commit is contained in:
Christian Basler 2015-10-21 16:43:13 +02:00
parent f19996f79c
commit 9b1bf6bdb3
6 changed files with 81 additions and 29 deletions

View File

@ -119,8 +119,7 @@
</service> </service>
<service <service
android:name=".synchronization.SyncService" android:name=".synchronization.SyncService"
android:exported="true" android:exported="true">
android:process=":sync">
<intent-filter> <intent-filter>
<action android:name="android.content.SyncAdapter"/> <action android:name="android.content.SyncAdapter"/>
</intent-filter> </intent-filter>

View File

@ -36,9 +36,9 @@ import java.util.ArrayList;
import ch.dissem.apps.abit.listener.ActionBarListener; import ch.dissem.apps.abit.listener.ActionBarListener;
import ch.dissem.apps.abit.listener.ListSelectionListener; import ch.dissem.apps.abit.listener.ListSelectionListener;
import ch.dissem.apps.abit.notification.NetworkNotification;
import ch.dissem.apps.abit.service.Singleton; import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.apps.abit.synchronization.Authenticator; import ch.dissem.apps.abit.synchronization.Authenticator;
import ch.dissem.apps.abit.synchronization.SyncService;
import ch.dissem.bitmessage.BitmessageContext; import ch.dissem.bitmessage.BitmessageContext;
import ch.dissem.bitmessage.entity.BitmessageAddress; import ch.dissem.bitmessage.entity.BitmessageAddress;
import ch.dissem.bitmessage.entity.Plaintext; import ch.dissem.bitmessage.entity.Plaintext;
@ -70,7 +70,7 @@ public class MessageListActivity extends AppCompatActivity
public static final String ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox"; public static final String ACTION_SHOW_INBOX = "ch.dissem.abit.ShowInbox";
private static final Logger LOG = LoggerFactory.getLogger(MessageListActivity.class); private static final Logger LOG = LoggerFactory.getLogger(MessageListActivity.class);
private static final long SYNC_FREQUENCY = 15 * 60; // seconds private static final long SYNC_FREQUENCY = 15;// FIXME * 60; // seconds
private static final int ADD_IDENTITY = 1; private static final int ADD_IDENTITY = 1;
/** /**
@ -253,14 +253,14 @@ public class MessageListActivity extends AppCompatActivity
.withOnCheckedChangeListener(new OnCheckedChangeListener() { .withOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override @Override
public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) { public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) {
// TODO: warn user, option to restrict to WiFi if (isChecked) {
if (isChecked && !bmc.isRunning()) { startService(new Intent(MessageListActivity.this, SyncService.class));
bmc.startup(); } else {
new NetworkNotification(MessageListActivity.this).show(); stopService(new Intent(MessageListActivity.this, SyncService.class));
} else if (bmc.isRunning()) bmc.shutdown(); }
} }
}) })
.withChecked(bmc.isRunning()) .withChecked(SyncService.isRunning())
) )
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() { .withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
@Override @Override

View File

@ -10,7 +10,7 @@ import android.content.Context;
public abstract class AbstractNotification { public abstract class AbstractNotification {
protected final Context ctx; protected final Context ctx;
protected final NotificationManager manager; protected final NotificationManager manager;
public Notification notification; protected Notification notification;
public AbstractNotification(Context ctx) { public AbstractNotification(Context ctx) {

View File

@ -1,6 +1,7 @@
package ch.dissem.apps.abit.notification; package ch.dissem.apps.abit.notification;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -19,6 +20,8 @@ import ch.dissem.bitmessage.utils.Property;
* Shows the network status (as long as the client is connected as a full node) * Shows the network status (as long as the client is connected as a full node)
*/ */
public class NetworkNotification extends AbstractNotification { public class NetworkNotification extends AbstractNotification {
public static final int ONGOING_NOTIFICATION_ID = 2;
private final BitmessageContext bmc; private final BitmessageContext bmc;
private NotificationCompat.Builder builder; private NotificationCompat.Builder builder;
@ -31,6 +34,11 @@ public class NetworkNotification extends AbstractNotification {
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC); .setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
} }
public Notification getNotification() {
update();
return notification;
}
@SuppressLint("StringFormatMatches") @SuppressLint("StringFormatMatches")
private boolean update() { private boolean update() {
boolean running = bmc.isRunning(); boolean running = bmc.isRunning();
@ -82,6 +90,6 @@ public class NetworkNotification extends AbstractNotification {
@Override @Override
protected int getNotificationId() { protected int getNotificationId() {
return 2; return ONGOING_NOTIFICATION_ID;
} }
} }

View File

@ -30,22 +30,9 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter {
/** /**
* Set up the sync adapter * Set up the sync adapter
*/ */
public SyncAdapter(Context context, boolean autoInitialize) { public SyncAdapter(Context context, BitmessageContext bitmessageContext) {
super(context, autoInitialize); super(context, true);
bmc = Singleton.getBitmessageContext(context); bmc = bitmessageContext;
}
/**
* Set up the sync adapter. This form of the
* constructor maintains compatibility with Android 3.0
* and later platform versions
*/
public SyncAdapter(
Context context,
boolean autoInitialize,
boolean allowParallelSyncs) {
super(context, autoInitialize, allowParallelSyncs);
bmc = Singleton.getBitmessageContext(context);
} }
@Override @Override

View File

@ -1,20 +1,44 @@
package ch.dissem.apps.abit.synchronization; package ch.dissem.apps.abit.synchronization;
import android.app.Service; import android.app.Service;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.IBinder; import android.os.IBinder;
import ch.dissem.apps.abit.MessageListActivity;
import ch.dissem.apps.abit.listener.MessageListener;
import ch.dissem.apps.abit.notification.NetworkNotification;
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.SqlHelper;
import ch.dissem.apps.abit.service.Singleton;
import ch.dissem.bitmessage.BitmessageContext;
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;
/** /**
* Define a Service that returns an IBinder for the * Define a Service that returns an IBinder for the
* sync adapter class, allowing the sync adapter framework to call * sync adapter class, allowing the sync adapter framework to call
* onPerformSync(). * onPerformSync().
*/ */
public class SyncService extends Service { public class SyncService extends Service {
private static MessageListener messageListener = null;
private static BitmessageContext bmc = null;
// Storage for an instance of the sync adapter // Storage for an instance of the sync adapter
private static SyncAdapter syncAdapter = null; private static SyncAdapter syncAdapter = null;
// Object to use as a thread-safe lock // Object to use as a thread-safe lock
private static final Object syncAdapterLock = new Object(); private static final Object syncAdapterLock = new Object();
private static volatile boolean running = false;
public static boolean isRunning() {
return running;
}
/* /*
* Instantiate the sync adapter object. * Instantiate the sync adapter object.
*/ */
@ -26,12 +50,46 @@ public class SyncService extends Service {
* Disallow parallel syncs * Disallow parallel syncs
*/ */
synchronized (syncAdapterLock) { synchronized (syncAdapterLock) {
final Context ctx = getApplicationContext();
if (bmc == null) {
// messageListener = new MessageListener(ctx);
// SqlHelper sqlHelper = new SqlHelper(ctx);
// bmc = 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(messageListener)
// .build();
// FIXME: this needs to change once I figured out how to get rid of those singletons
messageListener = Singleton.getMessageListener(ctx);
bmc = Singleton.getBitmessageContext(ctx);
}
if (syncAdapter == null) { if (syncAdapter == null) {
syncAdapter = new SyncAdapter(getApplicationContext(), true); syncAdapter = new SyncAdapter(ctx, bmc);
} }
} }
} }
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO: warn user, option to restrict to WiFi
running = true;
NetworkNotification networkNotification = new NetworkNotification(this);
startForeground(ONGOING_NOTIFICATION_ID, networkNotification.getNotification());
bmc.startup();
networkNotification.show();
return Service.START_STICKY;
}
@Override
public void onDestroy() {
bmc.shutdown();
running = false;
}
/** /**
* Return an object that allows the system to invoke * Return an object that allows the system to invoke
* the sync adapter. * the sync adapter.