Moving Bitmessage context into a foreground service (work in progress)
This commit is contained in:
parent
9b1bf6bdb3
commit
f5bf5c8bca
@ -102,6 +102,7 @@
|
|||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
<service android:name=".synchronization.BitmessageService" />
|
||||||
|
|
||||||
<!-- Synchronization -->
|
<!-- Synchronization -->
|
||||||
<provider
|
<provider
|
||||||
|
@ -17,14 +17,13 @@
|
|||||||
package ch.dissem.apps.abit;
|
package ch.dissem.apps.abit;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ListFragment;
|
import android.support.v4.app.ListFragment;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ListView;
|
import android.widget.ListView;
|
||||||
|
|
||||||
import ch.dissem.apps.abit.listener.ListSelectionListener;
|
import ch.dissem.apps.abit.listener.ListSelectionListener;
|
||||||
import ch.dissem.apps.abit.service.Singleton;
|
|
||||||
import ch.dissem.bitmessage.BitmessageContext;
|
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,7 +44,6 @@ public abstract class AbstractItemListFragment<T> extends ListFragment {
|
|||||||
public void onItemSelected(Object plaintext) {
|
public void onItemSelected(Object plaintext) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
protected BitmessageContext bmc;
|
|
||||||
/**
|
/**
|
||||||
* The fragment's current callback object, which is notified of list item
|
* The fragment's current callback object, which is notified of list item
|
||||||
* clicks.
|
* clicks.
|
||||||
@ -59,13 +57,6 @@ public abstract class AbstractItemListFragment<T> extends ListFragment {
|
|||||||
|
|
||||||
abstract void updateList(Label label);
|
abstract void updateList(Label label);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
bmc = Singleton.getBitmessageContext(getActivity());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
@ -89,15 +80,15 @@ public abstract class AbstractItemListFragment<T> extends ListFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Activity activity) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(activity);
|
super.onAttach(context);
|
||||||
|
|
||||||
// Activities containing this fragment must implement its callbacks.
|
// Activities containing this fragment must implement its callbacks.
|
||||||
if (!(activity instanceof ListSelectionListener)) {
|
if (!(context instanceof ListSelectionListener)) {
|
||||||
throw new IllegalStateException("Activity must implement fragment's callbacks.");
|
throw new IllegalStateException("Activity must implement fragment's callbacks.");
|
||||||
}
|
}
|
||||||
|
|
||||||
callbacks = (ListSelectionListener) activity;
|
callbacks = (ListSelectionListener) context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -6,12 +6,15 @@ import android.support.v4.app.Fragment;
|
|||||||
import android.view.*;
|
import android.view.*;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import ch.dissem.apps.abit.service.Singleton;
|
import ch.dissem.apps.abit.service.Singleton;
|
||||||
import ch.dissem.apps.abit.util.Drawables;
|
import ch.dissem.apps.abit.util.Drawables;
|
||||||
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;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||||
|
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||||
|
|
||||||
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
|
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -84,7 +87,7 @@ public class MessageDetailFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (removed) {
|
if (removed) {
|
||||||
Singleton.getBitmessageContext(inflater.getContext()).messages().save(item);
|
Singleton.getMessageRepository(inflater.getContext()).save(item);
|
||||||
}
|
}
|
||||||
return rootView;
|
return rootView;
|
||||||
}
|
}
|
||||||
@ -103,7 +106,7 @@ public class MessageDetailFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem menuItem) {
|
public boolean onOptionsItemSelected(MenuItem menuItem) {
|
||||||
BitmessageContext bmc = Singleton.getBitmessageContext(getActivity());
|
MessageRepository messageRepo = Singleton.getMessageRepository(getContext());
|
||||||
switch (menuItem.getItemId()) {
|
switch (menuItem.getItemId()) {
|
||||||
case R.id.reply:
|
case R.id.reply:
|
||||||
Intent replyIntent = new Intent(getActivity().getApplicationContext(), ComposeMessageActivity.class);
|
Intent replyIntent = new Intent(getActivity().getApplicationContext(), ComposeMessageActivity.class);
|
||||||
@ -113,21 +116,21 @@ public class MessageDetailFragment extends Fragment {
|
|||||||
return true;
|
return true;
|
||||||
case R.id.delete:
|
case R.id.delete:
|
||||||
if (isInTrash(item)) {
|
if (isInTrash(item)) {
|
||||||
bmc.messages().remove(item);
|
messageRepo.remove(item);
|
||||||
} else {
|
} else {
|
||||||
item.getLabels().clear();
|
item.getLabels().clear();
|
||||||
item.addLabels(bmc.messages().getLabels(Label.Type.TRASH));
|
item.addLabels(messageRepo.getLabels(Label.Type.TRASH));
|
||||||
bmc.messages().save(item);
|
messageRepo.save(item);
|
||||||
}
|
}
|
||||||
getActivity().onBackPressed();
|
getActivity().onBackPressed();
|
||||||
return true;
|
return true;
|
||||||
case R.id.mark_unread:
|
case R.id.mark_unread:
|
||||||
item.addLabels(bmc.messages().getLabels(Label.Type.UNREAD));
|
item.addLabels(messageRepo.getLabels(Label.Type.UNREAD));
|
||||||
bmc.messages().save(item);
|
messageRepo.save(item);
|
||||||
return true;
|
return true;
|
||||||
case R.id.archive:
|
case R.id.archive:
|
||||||
item.getLabels().clear();
|
item.getLabels().clear();
|
||||||
bmc.messages().save(item);
|
messageRepo.save(item);
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@ -2,9 +2,17 @@ package ch.dissem.apps.abit;
|
|||||||
|
|
||||||
import android.accounts.Account;
|
import android.accounts.Account;
|
||||||
import android.accounts.AccountManager;
|
import android.accounts.AccountManager;
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
@ -38,12 +46,17 @@ 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.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.BitmessageService;
|
||||||
import ch.dissem.apps.abit.synchronization.SyncService;
|
import ch.dissem.apps.abit.synchronization.SyncService;
|
||||||
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;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
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.MSG_START_NODE;
|
||||||
|
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_STOP_NODE;
|
||||||
import static ch.dissem.apps.abit.synchronization.StubProvider.AUTHORITY;
|
import static ch.dissem.apps.abit.synchronization.StubProvider.AUTHORITY;
|
||||||
|
|
||||||
|
|
||||||
@ -79,15 +92,36 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
*/
|
*/
|
||||||
private boolean twoPane;
|
private boolean twoPane;
|
||||||
|
|
||||||
|
private Messenger messenger = new Messenger(new IncomingHandler());
|
||||||
|
private Messenger service;
|
||||||
|
private boolean bound;
|
||||||
|
private ServiceConnection connection = new ServiceConnection() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
MessageListActivity.this.service = new Messenger(service);
|
||||||
|
MessageListActivity.this.bound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
service = null;
|
||||||
|
bound = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private AccountHeader accountHeader;
|
private AccountHeader accountHeader;
|
||||||
private BitmessageContext bmc;
|
|
||||||
private Label selectedLabel;
|
private Label selectedLabel;
|
||||||
|
|
||||||
|
private MessageRepository messageRepo;
|
||||||
|
private AddressRepository addressRepo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
bmc = Singleton.getBitmessageContext(this);
|
messageRepo = Singleton.getMessageRepository(this);
|
||||||
selectedLabel = bmc.messages().getLabels().get(0);
|
addressRepo = Singleton.getAddressRepository(this);
|
||||||
|
|
||||||
|
selectedLabel = messageRepo.getLabels().get(0);
|
||||||
|
|
||||||
setContentView(R.layout.activity_message_list);
|
setContentView(R.layout.activity_message_list);
|
||||||
|
|
||||||
@ -152,7 +186,7 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
|
|
||||||
private void createDrawer(Toolbar toolbar) {
|
private void createDrawer(Toolbar toolbar) {
|
||||||
final ArrayList<IProfile> profiles = new ArrayList<>();
|
final ArrayList<IProfile> profiles = new ArrayList<>();
|
||||||
for (BitmessageAddress identity : bmc.addresses().getIdentities()) {
|
for (BitmessageAddress identity : addressRepo.getIdentities()) {
|
||||||
LOG.info("Adding identity " + identity.getAddress());
|
LOG.info("Adding identity " + identity.getAddress());
|
||||||
profiles.add(new ProfileDrawerItem()
|
profiles.add(new ProfileDrawerItem()
|
||||||
.withIcon(new Identicon(identity))
|
.withIcon(new Identicon(identity))
|
||||||
@ -183,16 +217,12 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public boolean onProfileChanged(View view, IProfile profile, boolean currentProfile) {
|
public boolean onProfileChanged(View view, IProfile profile, boolean currentProfile) {
|
||||||
if (profile.getIdentifier() == ADD_IDENTITY) {
|
if (profile.getIdentifier() == ADD_IDENTITY) {
|
||||||
BitmessageAddress identity = bmc.createIdentity(false);
|
try {
|
||||||
IProfile newProfile = new ProfileDrawerItem()
|
Message message = Message.obtain(null, BitmessageService.MSG_CREATE_IDENTITY);
|
||||||
.withName(identity.toString())
|
message.replyTo = messenger;
|
||||||
.withEmail(identity.getAddress())
|
service.send(message);
|
||||||
.withTag(identity);
|
} catch (RemoteException e) {
|
||||||
if (accountHeader.getProfiles() != null) {
|
LOG.error(e.getMessage(), e);
|
||||||
//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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// false if it should close the drawer
|
// false if it should close the drawer
|
||||||
@ -202,7 +232,7 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
ArrayList<IDrawerItem> drawerItems = new ArrayList<>();
|
ArrayList<IDrawerItem> drawerItems = new ArrayList<>();
|
||||||
for (Label label : bmc.messages().getLabels()) {
|
for (Label label : messageRepo.getLabels()) {
|
||||||
PrimaryDrawerItem item = new PrimaryDrawerItem().withName(label.toString()).withTag(label);
|
PrimaryDrawerItem item = new PrimaryDrawerItem().withName(label.toString()).withTag(label);
|
||||||
switch (label.getType()) {
|
switch (label.getType()) {
|
||||||
case INBOX:
|
case INBOX:
|
||||||
@ -254,13 +284,21 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(IDrawerItem drawerItem, CompoundButton buttonView, boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
startService(new Intent(MessageListActivity.this, SyncService.class));
|
try {
|
||||||
|
service.send(Message.obtain(null, MSG_START_NODE));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
stopService(new Intent(MessageListActivity.this, SyncService.class));
|
try {
|
||||||
|
service.send(Message.obtain(null, MSG_STOP_NODE));
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.withChecked(SyncService.isRunning())
|
.withChecked(BitmessageService.isRunning())
|
||||||
)
|
)
|
||||||
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
|
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
@ -303,7 +341,7 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
((MessageListFragment) getSupportFragmentManager()
|
((MessageListFragment) getSupportFragmentManager()
|
||||||
.findFragmentById(R.id.item_list)).updateList(selectedLabel);
|
.findFragmentById(R.id.item_list)).updateList(selectedLabel);
|
||||||
} else {
|
} else {
|
||||||
MessageListFragment listFragment = new MessageListFragment(getApplicationContext());
|
MessageListFragment listFragment = new MessageListFragment();
|
||||||
changeList(listFragment);
|
changeList(listFragment);
|
||||||
listFragment.updateList(selectedLabel);
|
listFragment.updateList(selectedLabel);
|
||||||
}
|
}
|
||||||
@ -360,4 +398,41 @@ public class MessageListActivity extends AppCompatActivity
|
|||||||
return selectedLabel;
|
return selectedLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
bindService(new Intent(this, BitmessageService.class), connection, Context.BIND_AUTO_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
if (bound) {
|
||||||
|
unbindService(connection);
|
||||||
|
bound = false;
|
||||||
|
}
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class IncomingHandler extends Handler {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
super.handleMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,11 +44,6 @@ public class MessageListFragment extends AbstractItemListFragment<Plaintext> {
|
|||||||
public MessageListFragment() {
|
public MessageListFragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ValidFragment")
|
|
||||||
public MessageListFragment(Context ctx) {
|
|
||||||
bmc = Singleton.getBitmessageContext(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@ -73,7 +68,7 @@ public class MessageListFragment extends AbstractItemListFragment<Plaintext> {
|
|||||||
getActivity(),
|
getActivity(),
|
||||||
android.R.layout.simple_list_item_activated_1,
|
android.R.layout.simple_list_item_activated_1,
|
||||||
android.R.id.text1,
|
android.R.id.text1,
|
||||||
bmc.messages().findMessages(label)) {
|
Singleton.getMessageRepository(getContext()).findMessages(label)) {
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
if (convertView == null) {
|
if (convertView == null) {
|
||||||
@ -138,7 +133,7 @@ public class MessageListFragment extends AbstractItemListFragment<Plaintext> {
|
|||||||
case R.id.empty_trash:
|
case R.id.empty_trash:
|
||||||
if (currentLabel.getType() != Label.Type.TRASH) return true;
|
if (currentLabel.getType() != Label.Type.TRASH) return true;
|
||||||
|
|
||||||
MessageRepository repo = bmc.messages();
|
MessageRepository repo = Singleton.getMessageRepository(getContext());
|
||||||
for (Plaintext message : repo.findMessages(currentLabel)) {
|
for (Plaintext message : repo.findMessages(currentLabel)) {
|
||||||
repo.remove(message);
|
repo.remove(message);
|
||||||
}
|
}
|
||||||
|
@ -17,19 +17,52 @@
|
|||||||
package ch.dissem.apps.abit;
|
package ch.dissem.apps.abit;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.ServiceConnection;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import ch.dissem.apps.abit.service.Singleton;
|
|
||||||
import ch.dissem.bitmessage.BitmessageContext;
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import ch.dissem.apps.abit.synchronization.BitmessageService;
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
|
|
||||||
|
import static ch.dissem.apps.abit.synchronization.BitmessageService.DATA_FIELD_ADDRESS;
|
||||||
|
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_ADD_CONTACT;
|
||||||
|
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_SUBSCRIBE;
|
||||||
|
import static ch.dissem.apps.abit.synchronization.BitmessageService.MSG_SUBSCRIBE_AND_ADD_CONTACT;
|
||||||
|
|
||||||
public class OpenBitmessageLinkActivity extends AppCompatActivity {
|
public class OpenBitmessageLinkActivity extends AppCompatActivity {
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(OpenBitmessageLinkActivity.class);
|
||||||
|
|
||||||
|
private Messenger service;
|
||||||
|
private boolean bound;
|
||||||
|
private ServiceConnection connection = new ServiceConnection() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
OpenBitmessageLinkActivity.this.service = new Messenger(service);
|
||||||
|
OpenBitmessageLinkActivity.this.bound = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
service = null;
|
||||||
|
bound = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@ -70,14 +103,29 @@ public class OpenBitmessageLinkActivity extends AppCompatActivity {
|
|||||||
ok.setOnClickListener(new View.OnClickListener() {
|
ok.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
BitmessageContext bmc = Singleton.getBitmessageContext(OpenBitmessageLinkActivity.this);
|
|
||||||
BitmessageAddress bmAddress = new BitmessageAddress(address);
|
BitmessageAddress bmAddress = new BitmessageAddress(address);
|
||||||
bmAddress.setAlias(label.getText().toString());
|
bmAddress.setAlias(label.getText().toString());
|
||||||
if (subscribe.isChecked()) {
|
|
||||||
bmc.addSubscribtion(bmAddress);
|
final int what;
|
||||||
}
|
if (subscribe.isChecked() && importContact.isChecked())
|
||||||
if (importContact.isChecked()) {
|
what = MSG_SUBSCRIBE_AND_ADD_CONTACT;
|
||||||
bmc.addContact(bmAddress);
|
else if (subscribe.isChecked())
|
||||||
|
what = MSG_SUBSCRIBE;
|
||||||
|
else if (importContact.isChecked())
|
||||||
|
what = MSG_ADD_CONTACT;
|
||||||
|
else
|
||||||
|
what = 0;
|
||||||
|
|
||||||
|
if (what != 0) {
|
||||||
|
try {
|
||||||
|
Message message = Message.obtain(null, what);
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putSerializable(DATA_FIELD_ADDRESS, bmAddress);
|
||||||
|
message.setData(bundle);
|
||||||
|
service.send(message);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
LOG.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
setResult(Activity.RESULT_OK);
|
setResult(Activity.RESULT_OK);
|
||||||
finish();
|
finish();
|
||||||
@ -110,4 +158,19 @@ public class OpenBitmessageLinkActivity extends AppCompatActivity {
|
|||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
bindService(new Intent(this, BitmessageService.class), connection, Context.BIND_AUTO_CREATE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStop() {
|
||||||
|
if (bound) {
|
||||||
|
unbindService(connection);
|
||||||
|
bound = false;
|
||||||
|
}
|
||||||
|
super.onStop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ import android.widget.CompoundButton;
|
|||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.Switch;
|
import android.widget.Switch;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import ch.dissem.apps.abit.service.Singleton;
|
import ch.dissem.apps.abit.service.Singleton;
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ public class SubscriptionDetailFragment extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
Singleton.getBitmessageContext(getActivity()).addresses().save(item);
|
Singleton.getAddressRepository(getContext()).save(item);
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import ch.dissem.apps.abit.service.Singleton;
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||||
|
|
||||||
@ -32,7 +34,7 @@ import java.util.Comparator;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by chris on 06.09.15.
|
* Fragment that shows a list of all contacts, the ones we subscribed to first.
|
||||||
*/
|
*/
|
||||||
public class SubscriptionListFragment extends AbstractItemListFragment<BitmessageAddress> {
|
public class SubscriptionListFragment extends AbstractItemListFragment<BitmessageAddress> {
|
||||||
@Override
|
@Override
|
||||||
@ -43,7 +45,7 @@ public class SubscriptionListFragment extends AbstractItemListFragment<Bitmessag
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void updateList() {
|
public void updateList() {
|
||||||
List<BitmessageAddress> addresses = bmc.addresses().getContacts();
|
List<BitmessageAddress> addresses = Singleton.getAddressRepository(getContext()).getContacts();
|
||||||
Collections.sort(addresses, new Comparator<BitmessageAddress>() {
|
Collections.sort(addresses, new Comparator<BitmessageAddress>() {
|
||||||
/**
|
/**
|
||||||
* Yields the following order:
|
* Yields the following order:
|
||||||
|
@ -25,9 +25,9 @@ public class NetworkNotification extends AbstractNotification {
|
|||||||
private final BitmessageContext bmc;
|
private final BitmessageContext bmc;
|
||||||
private NotificationCompat.Builder builder;
|
private NotificationCompat.Builder builder;
|
||||||
|
|
||||||
public NetworkNotification(Context ctx) {
|
public NetworkNotification(Context ctx, BitmessageContext bmc) {
|
||||||
super(ctx);
|
super(ctx.getApplicationContext());
|
||||||
bmc = Singleton.getBitmessageContext(ctx);
|
this.bmc = bmc;
|
||||||
builder = new NotificationCompat.Builder(ctx);
|
builder = new NotificationCompat.Builder(ctx);
|
||||||
builder.setSmallIcon(R.drawable.ic_notification_full_node)
|
builder.setSmallIcon(R.drawable.ic_notification_full_node)
|
||||||
.setContentTitle(ctx.getString(R.string.bitmessage_full_node))
|
.setContentTitle(ctx.getString(R.string.bitmessage_full_node))
|
||||||
|
@ -21,6 +21,7 @@ import ch.dissem.bitmessage.entity.Plaintext;
|
|||||||
import static ch.dissem.apps.abit.util.Drawables.toBitmap;
|
import static ch.dissem.apps.abit.util.Drawables.toBitmap;
|
||||||
|
|
||||||
public class NewMessageNotification extends AbstractNotification {
|
public class NewMessageNotification extends AbstractNotification {
|
||||||
|
public static final int NEW_MESSAGE_NOTIFICATION_ID = 1;
|
||||||
private static final StyleSpan SPAN_EMPHASIS = new StyleSpan(Typeface.BOLD);
|
private static final StyleSpan SPAN_EMPHASIS = new StyleSpan(Typeface.BOLD);
|
||||||
|
|
||||||
public NewMessageNotification(Context ctx) {
|
public NewMessageNotification(Context ctx) {
|
||||||
@ -76,6 +77,6 @@ public class NewMessageNotification extends AbstractNotification {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getNotificationId() {
|
protected int getNotificationId() {
|
||||||
return 1;
|
return NEW_MESSAGE_NOTIFICATION_ID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,11 +23,13 @@ import android.database.sqlite.SQLiteConstraintException;
|
|||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
|
||||||
import ch.dissem.apps.abit.R;
|
import ch.dissem.apps.abit.R;
|
||||||
|
import ch.dissem.apps.abit.service.Singleton;
|
||||||
import ch.dissem.bitmessage.InternalContext;
|
import ch.dissem.bitmessage.InternalContext;
|
||||||
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
import ch.dissem.bitmessage.entity.BitmessageAddress;
|
||||||
import ch.dissem.bitmessage.entity.Plaintext;
|
import ch.dissem.bitmessage.entity.Plaintext;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
|
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
|
||||||
import ch.dissem.bitmessage.entity.valueobject.Label;
|
import ch.dissem.bitmessage.entity.valueobject.Label;
|
||||||
|
import ch.dissem.bitmessage.ports.AddressRepository;
|
||||||
import ch.dissem.bitmessage.ports.MessageRepository;
|
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||||
import ch.dissem.bitmessage.utils.Encode;
|
import ch.dissem.bitmessage.utils.Encode;
|
||||||
|
|
||||||
@ -45,7 +47,7 @@ import static ch.dissem.apps.abit.repository.SqlHelper.join;
|
|||||||
/**
|
/**
|
||||||
* {@link MessageRepository} implementation using the Android SQL API.
|
* {@link MessageRepository} implementation using the Android SQL API.
|
||||||
*/
|
*/
|
||||||
public class AndroidMessageRepository implements MessageRepository, InternalContext.ContextHolder {
|
public class AndroidMessageRepository implements MessageRepository {
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AndroidMessageRepository.class);
|
private static final Logger LOG = LoggerFactory.getLogger(AndroidMessageRepository.class);
|
||||||
|
|
||||||
private static final String TABLE_NAME = "Message";
|
private static final String TABLE_NAME = "Message";
|
||||||
@ -71,16 +73,13 @@ public class AndroidMessageRepository implements MessageRepository, InternalCont
|
|||||||
private static final String LBL_COLUMN_ORDER = "ord";
|
private static final String LBL_COLUMN_ORDER = "ord";
|
||||||
private final SqlHelper sql;
|
private final SqlHelper sql;
|
||||||
private final Context ctx;
|
private final Context ctx;
|
||||||
private InternalContext bmc;
|
|
||||||
|
private final AddressRepository addressRepo;
|
||||||
|
|
||||||
public AndroidMessageRepository(SqlHelper sql, Context ctx) {
|
public AndroidMessageRepository(SqlHelper sql, Context ctx) {
|
||||||
this.sql = sql;
|
this.sql = sql;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
}
|
this.addressRepo = Singleton.getAddressRepository(ctx);
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setContext(InternalContext context) {
|
|
||||||
bmc = context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -230,8 +229,8 @@ public class AndroidMessageRepository implements MessageRepository, InternalCont
|
|||||||
long id = c.getLong(c.getColumnIndex(COLUMN_ID));
|
long id = c.getLong(c.getColumnIndex(COLUMN_ID));
|
||||||
builder.id(id);
|
builder.id(id);
|
||||||
builder.IV(new InventoryVector(iv));
|
builder.IV(new InventoryVector(iv));
|
||||||
builder.from(bmc.getAddressRepo().getAddress(c.getString(c.getColumnIndex(COLUMN_SENDER))));
|
builder.from(addressRepo.getAddress(c.getString(c.getColumnIndex(COLUMN_SENDER))));
|
||||||
builder.to(bmc.getAddressRepo().getAddress(c.getString(c.getColumnIndex(COLUMN_RECIPIENT))));
|
builder.to(addressRepo.getAddress(c.getString(c.getColumnIndex(COLUMN_RECIPIENT))));
|
||||||
builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT)));
|
builder.sent(c.getLong(c.getColumnIndex(COLUMN_SENT)));
|
||||||
builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED)));
|
builder.received(c.getLong(c.getColumnIndex(COLUMN_RECEIVED)));
|
||||||
builder.status(Plaintext.Status.valueOf(c.getString(c.getColumnIndex(COLUMN_STATUS))));
|
builder.status(Plaintext.Status.valueOf(c.getString(c.getColumnIndex(COLUMN_STATUS))));
|
||||||
@ -257,12 +256,12 @@ public class AndroidMessageRepository implements MessageRepository, InternalCont
|
|||||||
|
|
||||||
// save from address if necessary
|
// save from address if necessary
|
||||||
if (message.getId() == null) {
|
if (message.getId() == null) {
|
||||||
BitmessageAddress savedAddress = bmc.getAddressRepo().getAddress(message.getFrom().getAddress());
|
BitmessageAddress savedAddress = addressRepo.getAddress(message.getFrom().getAddress());
|
||||||
if (savedAddress == null || savedAddress.getPrivateKey() == null) {
|
if (savedAddress == null || savedAddress.getPrivateKey() == null) {
|
||||||
if (savedAddress != null && savedAddress.getAlias() != null) {
|
if (savedAddress != null && savedAddress.getAlias() != null) {
|
||||||
message.getFrom().setAlias(savedAddress.getAlias());
|
message.getFrom().setAlias(savedAddress.getAlias());
|
||||||
}
|
}
|
||||||
bmc.getAddressRepo().save(message.getFrom());
|
addressRepo.save(message.getFrom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package ch.dissem.apps.abit.service;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import ch.dissem.apps.abit.MessageListActivity;
|
||||||
import ch.dissem.apps.abit.listener.MessageListener;
|
import ch.dissem.apps.abit.listener.MessageListener;
|
||||||
import ch.dissem.apps.abit.repository.AndroidAddressRepository;
|
import ch.dissem.apps.abit.repository.AndroidAddressRepository;
|
||||||
import ch.dissem.apps.abit.repository.AndroidInventory;
|
import ch.dissem.apps.abit.repository.AndroidInventory;
|
||||||
@ -9,35 +10,24 @@ import ch.dissem.apps.abit.repository.AndroidMessageRepository;
|
|||||||
import ch.dissem.apps.abit.repository.SqlHelper;
|
import ch.dissem.apps.abit.repository.SqlHelper;
|
||||||
import ch.dissem.bitmessage.BitmessageContext;
|
import ch.dissem.bitmessage.BitmessageContext;
|
||||||
import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
|
import ch.dissem.bitmessage.networking.DefaultNetworkHandler;
|
||||||
|
import ch.dissem.bitmessage.ports.AddressRepository;
|
||||||
import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
|
import ch.dissem.bitmessage.ports.MemoryNodeRegistry;
|
||||||
|
import ch.dissem.bitmessage.ports.MessageRepository;
|
||||||
|
import ch.dissem.bitmessage.ports.Security;
|
||||||
import ch.dissem.bitmessage.security.sc.SpongySecurity;
|
import ch.dissem.bitmessage.security.sc.SpongySecurity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides singleton objects across the application.
|
* Provides singleton objects across the application.
|
||||||
*/
|
*/
|
||||||
public class Singleton {
|
public class Singleton {
|
||||||
private static BitmessageContext bitmessageContext;
|
private static SqlHelper sqlHelper;
|
||||||
|
private static Security security;
|
||||||
|
private static MessageRepository messageRepository;
|
||||||
private static MessageListener messageListener;
|
private static MessageListener messageListener;
|
||||||
|
private static AddressRepository addressRepository;
|
||||||
|
|
||||||
public static BitmessageContext getBitmessageContext(Context context) {
|
static {
|
||||||
if (bitmessageContext == null) {
|
ch.dissem.bitmessage.utils.Singleton.initialize(new SpongySecurity());
|
||||||
synchronized (Singleton.class) {
|
|
||||||
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) {
|
public static MessageListener getMessageListener(Context ctx) {
|
||||||
@ -50,4 +40,41 @@ public class Singleton {
|
|||||||
}
|
}
|
||||||
return messageListener;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,186 @@
|
|||||||
|
package ch.dissem.apps.abit.synchronization;
|
||||||
|
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 {
|
||||||
|
public static final Logger LOG = LoggerFactory.getLogger(BitmessageService.class);
|
||||||
|
|
||||||
|
public static final int MSG_SYNC = 2;
|
||||||
|
public static final int MSG_CREATE_IDENTITY = 10;
|
||||||
|
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_START_NODE = 100;
|
||||||
|
public static final int MSG_STOP_NODE = 101;
|
||||||
|
|
||||||
|
public static final String DATA_FIELD_ADDRESS = "address";
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
private static volatile boolean running = false;
|
||||||
|
|
||||||
|
private static Messenger messenger;
|
||||||
|
|
||||||
|
public static boolean isRunning() {
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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();
|
||||||
|
notification = new NetworkNotification(this, bmc);
|
||||||
|
messenger = new Messenger(new IncomingHandler());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
return Service.START_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
bmc.shutdown();
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an object that allows the system to invoke
|
||||||
|
* the sync adapter.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return messenger.getBinder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class IncomingHandler extends Handler {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
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);
|
||||||
|
message.setData(bundle);
|
||||||
|
msg.replyTo.send(message);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
LOG.debug(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MSG_SUBSCRIBE:
|
||||||
|
BitmessageAddress address = (BitmessageAddress) msg.getData().getSerializable(DATA_FIELD_ADDRESS);
|
||||||
|
bmc.addSubscribtion(address);
|
||||||
|
break;
|
||||||
|
case MSG_SYNC:
|
||||||
|
LOG.info("Synchronizing Bitmessage");
|
||||||
|
// If the Bitmessage context acts as a full node, synchronization isn't necessary
|
||||||
|
if (bmc.isRunning()) break;
|
||||||
|
|
||||||
|
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(
|
||||||
|
BitmessageService.this);
|
||||||
|
|
||||||
|
String trustedNode = preferences.getString("trusted_node", null);
|
||||||
|
if (trustedNode == null) break;
|
||||||
|
trustedNode = trustedNode.trim();
|
||||||
|
if (trustedNode.isEmpty()) break;
|
||||||
|
|
||||||
|
int port;
|
||||||
|
if (trustedNode.matches("^(?![0-9a-fA-F]*:[0-9a-fA-F]*:).*(:[0-9]+)$")) {
|
||||||
|
int index = trustedNode.lastIndexOf(':');
|
||||||
|
String portString = trustedNode.substring(index + 1);
|
||||||
|
trustedNode = trustedNode.substring(0, index);
|
||||||
|
try {
|
||||||
|
port = Integer.parseInt(portString);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
LOG.error("Invalid port " + portString);
|
||||||
|
// TODO: show error as notification
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
port = 8444;
|
||||||
|
}
|
||||||
|
long timeoutInSeconds = preferences.getInt("sync_timeout", 120);
|
||||||
|
try {
|
||||||
|
LOG.info("Synchronization started");
|
||||||
|
bmc.synchronize(InetAddress.getByName(trustedNode), port, timeoutInSeconds, true);
|
||||||
|
LOG.info("Synchronization finished");
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
LOG.error("Couldn't synchronize", e);
|
||||||
|
// TODO: show error as notification
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case MSG_START_NODE:
|
||||||
|
startService(new Intent(BitmessageService.this, BitmessageService.class));
|
||||||
|
// TODO: warn user, option to restrict to WiFi
|
||||||
|
running = true;
|
||||||
|
startForeground(ONGOING_NOTIFICATION_ID, notification.getNotification());
|
||||||
|
bmc.startup();
|
||||||
|
notification.show();
|
||||||
|
break;
|
||||||
|
case MSG_STOP_NODE:
|
||||||
|
bmc.shutdown();
|
||||||
|
running = false;
|
||||||
|
stopForeground(false);
|
||||||
|
stopService(new Intent(BitmessageService.this, BitmessageService.class));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
super.handleMessage(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,16 +1,12 @@
|
|||||||
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.listener.MessageListener;
|
||||||
import ch.dissem.apps.abit.notification.NetworkNotification;
|
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.AndroidInventory;
|
||||||
import ch.dissem.apps.abit.repository.AndroidMessageRepository;
|
|
||||||
import ch.dissem.apps.abit.repository.SqlHelper;
|
import ch.dissem.apps.abit.repository.SqlHelper;
|
||||||
import ch.dissem.apps.abit.service.Singleton;
|
import ch.dissem.apps.abit.service.Singleton;
|
||||||
import ch.dissem.bitmessage.BitmessageContext;
|
import ch.dissem.bitmessage.BitmessageContext;
|
||||||
@ -26,20 +22,12 @@ import static ch.dissem.apps.abit.notification.NetworkNotification.ONGOING_NOTIF
|
|||||||
* 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.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -50,46 +38,12 @@ 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(ctx, bmc);
|
syncAdapter = new SyncAdapter(this, null); // FIXME
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@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.
|
||||||
|
Loading…
Reference in New Issue
Block a user