Skip to content

Commit

Permalink
Use HTTP API for sending and reading MeshMS, ensure I/O is only done …
Browse files Browse the repository at this point in the history
…on background threads
  • Loading branch information
lakeman committed Jun 25, 2014
1 parent 8cc696f commit 8c71c34
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 82 deletions.
13 changes: 13 additions & 0 deletions src/org/servalproject/ServalBatPhoneApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.preference.PreferenceManager;
Expand Down Expand Up @@ -104,6 +105,8 @@ public class ServalBatPhoneApplication extends Application {
public Control controlService = null;
public MeshMS meshMS;
public ServalD server;
private Handler backgroundHandler;
private HandlerThread backgroundThread;

public static String version="Unknown";
public static long lastModified;
Expand Down Expand Up @@ -175,6 +178,11 @@ public void mainIdentityUpdated(Identity identity){
public boolean getReady() {
if (Looper.myLooper() == null)
Looper.prepare();

backgroundThread = new HandlerThread("Background");
backgroundThread.start();
backgroundHandler = new Handler(backgroundThread.getLooper());

ChipsetDetection detection = ChipsetDetection.getDetection();

String chipset = settings.getString("chipset", "Automatic");
Expand Down Expand Up @@ -584,6 +592,11 @@ public boolean isMainThread() {
return this.getMainLooper().getThread().equals(Thread.currentThread());
}

public void runOnBackgroundThread(Runnable r){
backgroundHandler.removeCallbacks(r);
backgroundHandler.post(r);
}

private Toast toast = null;

// Display Toast-Message
Expand Down
42 changes: 33 additions & 9 deletions src/org/servalproject/messages/MessagesListActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.Typeface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
Expand All @@ -45,6 +46,8 @@
import org.servalproject.servaldna.meshms.MeshMSConversationList;
import org.servalproject.ui.SimpleAdapter;

import java.util.List;

/**
* main activity to display the list of messages
*/
Expand All @@ -60,9 +63,8 @@ public class MessagesListActivity extends ListActivity implements
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MeshMS.NEW_MESSAGES)) {
if (intent.getAction().equals(MeshMS.NEW_MESSAGES))
populateList();
}
}

};
Expand All @@ -83,13 +85,35 @@ protected void onCreate(Bundle savedInstanceState) {
* get the required data and populate the cursor
*/
private void populateList() {
try {
MeshMSConversationList conversations = app.server.getRestfulClient().meshmsListConversations(identity.subscriberId);
this.adapter.setItems(conversations.toList());
setListAdapter(adapter);
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}
if (!app.isMainThread())
runOnUiThread(new Runnable() {
@Override
public void run() {
populateList();
}
});

new AsyncTask<Void, Void, List<MeshMSConversation>>() {
@Override
protected void onPostExecute(List<MeshMSConversation> meshMSConversations) {
if (meshMSConversations!=null) {
adapter.setItems(meshMSConversations);
setListAdapter(adapter);
}
}

@Override
protected List<MeshMSConversation> doInBackground(Void... voids) {
try{
MeshMSConversationList conversations = app.server.getRestfulClient().meshmsListConversations(identity.subscriberId);
return conversations.toList();
} catch (Exception e) {
app.displayToastMessage(e.getMessage());
Log.e(TAG, e.getMessage(), e);
}
return null;
}
}.execute();
}

/*
Expand Down
107 changes: 68 additions & 39 deletions src/org/servalproject/messages/ShowConversationActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
Expand All @@ -40,14 +41,14 @@
import org.servalproject.servald.Identity;
import org.servalproject.servald.Peer;
import org.servalproject.servald.PeerListService;
import org.servalproject.servaldna.ServalDCommand;
import org.servalproject.servaldna.SubscriberId;
import org.servalproject.servaldna.meshms.MeshMSMessage;
import org.servalproject.servaldna.meshms.MeshMSMessageList;
import org.servalproject.ui.SimpleAdapter;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
* activity to show a conversation thread
Expand Down Expand Up @@ -170,20 +171,30 @@ protected void onCreate(Bundle savedInstanceState) {

private void sendMessage() {
// send the message
try {
CharSequence messageText = message.getText();
if (messageText==null || "".equals(messageText.toString()))
return;
ServalDCommand.sendMessage(identity.subscriberId, recipient.sid, messageText.toString());

message.setText("");
populateList();
new AsyncTask<String, Void, Boolean>(){
@Override
protected void onPostExecute(Boolean ret) {
if (ret) {
message.setText("");
populateList();
}
}

} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
ServalBatPhoneApplication.context.displayToastMessage(e
.getMessage());
}
@Override
protected Boolean doInBackground(String... args) {
try {
app.server.getRestfulClient().meshmsSendMessage(identity.subscriberId, recipient.sid, args[0]);
return true;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
app.displayToastMessage(e.getMessage());
}
return false;
}
}.execute(messageText.toString());
}

/*
Expand All @@ -200,36 +211,49 @@ public void run() {
});
return;
}
try{
MeshMSMessageList results = app.server.getRestfulClient().meshmsListMessages(identity.subscriberId, recipient.sid);
MeshMSMessage item;
LinkedList<Object> listItems = new LinkedList<Object>();
boolean firstRead=true, firstDelivered=true;
while((item = results.nextMessage())!=null){
switch(item.type){
case MESSAGE_SENT:
if (item.isDelivered && firstDelivered){
listItems.addFirst(getString(R.string.meshms_delivered));
firstDelivered=false;
}
break;
case MESSAGE_RECEIVED:
if (item.isRead && firstRead){
listItems.addFirst(getString(R.string.meshms_read));
firstRead=false;
new AsyncTask<Void, Void, List<Object>>(){
@Override
protected void onPostExecute(List<Object> listItems) {
if (listItems!=null) {
adapter.setItems(listItems);
setListAdapter(adapter);
}
}

@Override
protected List<Object> doInBackground(Void... voids) {
try{
MeshMSMessageList results = app.server.getRestfulClient().meshmsListMessages(identity.subscriberId, recipient.sid);
MeshMSMessage item;
LinkedList<Object> listItems = new LinkedList<Object>();
boolean firstRead=true, firstDelivered=true;
while((item = results.nextMessage())!=null){
switch(item.type){
case MESSAGE_SENT:
if (item.isDelivered && firstDelivered){
listItems.addFirst(getString(R.string.meshms_delivered));
firstDelivered=false;
}
break;
case MESSAGE_RECEIVED:
if (item.isRead && firstRead){
listItems.addFirst(getString(R.string.meshms_read));
firstRead=false;
}
break;
default:
continue;
}
break;
default:
continue;
listItems.addFirst(item);
}
return new ArrayList<Object>(listItems);
}catch(Exception e) {
Log.e(TAG, e.getMessage(), e);
app.displayToastMessage(e.getMessage());
}
listItems.addFirst(item);
return null;
}
adapter.setItems(new ArrayList<Object>(listItems));
setListAdapter(adapter);
}catch(Exception e){
Log.e(TAG, e.getMessage(), e);
app.displayToastMessage(e.getMessage());
}
}.execute();
}

/*
Expand All @@ -241,7 +265,12 @@ public void run() {
public void onPause() {
PeerListService.removeListener(this);
this.unregisterReceiver(receiver);
app.meshMS.markRead(recipient.sid);
app.runOnBackgroundThread(new Runnable() {
@Override
public void run() {
app.meshMS.markRead(recipient.sid);
}
});
super.onPause();
}

Expand Down
35 changes: 20 additions & 15 deletions src/org/servalproject/rhizome/MeshMS.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
import org.servalproject.messages.ShowConversationActivity;
import org.servalproject.servald.Identity;
import org.servalproject.servald.ServalD;
import org.servalproject.servaldna.ServalDCommand;
import org.servalproject.servaldna.ServalDFailureException;
import org.servalproject.servaldna.SubscriberId;
import org.servalproject.servaldna.meshms.MeshMSConversation;
import org.servalproject.servaldna.meshms.MeshMSConversationList;
Expand All @@ -40,8 +38,9 @@ public void bundleArrived(RhizomeManifest_MeshMS meshms){

public void markRead(SubscriberId recipient){
try {
ServalDCommand.readMessage(identity.subscriberId, recipient);
} catch (ServalDFailureException e) {
app.server.getRestfulClient().meshmsMarkAllMessagesRead(identity.subscriberId, recipient);
} catch (Exception e) {
app.displayToastMessage(e.getMessage());
Log.e(TAG, e.getMessage(), e);
}
cancelNotification();
Expand All @@ -63,23 +62,29 @@ public void initialiseNotification() {
MeshMSConversation conv;
while ((conv = conversations.nextConversation()) != null) {
// detect when the number of incoming messages has changed
if (conv.lastMessageOffset > 0)
messageHash = (messageHash << 25) ^ (messageHash >>> 7) ^ conv.theirSid.hashCode() ^
(int) ((conv.lastMessageOffset & 0xFFFFFFFF) ^ ((conv.lastMessageOffset >> 32) & 0xFFFFFFFF));
if (!conv.isRead) {
// remember the recipient, if it is the only recipient with unread messages
if (unread) {
recipient = null;
} else {
recipient = conv.theirSid;
}
unread = true;
if (conv.isRead)
continue;

messageHash =
conv.theirSid.hashCode() ^
(int) conv.lastMessageOffset ^
(int) (conv.lastMessageOffset >> 32);

Log.v(TAG, conv.theirSid.abbreviation()+", lastOffset = "+conv.lastMessageOffset+", hash = "+messageHash+", read = "+conv.isRead);

// remember the recipient, if it is the only recipient with unread messages
if (unread) {
recipient = null;
} else {
recipient = conv.theirSid;
}
unread = true;
}
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
}

Log.v(TAG, "unread = "+unread+", hash = "+messageHash+", lastHash = "+lastMessageHash);
if (!unread){
cancelNotification();
return;
Expand Down
15 changes: 2 additions & 13 deletions src/org/servalproject/rhizome/Rhizome.java
Original file line number Diff line number Diff line change
Expand Up @@ -322,18 +322,6 @@ public static boolean safeDelete(File f) {
return false;
}

/** Invoked by the servald monitor thread whenever a new bundle has been added to the Rhizome
* store. That monitor thread must remain highly responsive for the sake of voice call
* performance, so the significant work that rhizome needs to do is done in a separate thread
* that is started here.
*
* @author Andrew Bettison <andrew@servalproject.com>
* @throws RhizomeManifestParseException
*/
public static void notifyIncomingBundle(RhizomeManifest manifest) {
new Thread(new ExamineBundle(manifest)).start();
}

/** Invoked in a thread whenever a new bundle appears in the rhizome store.
*/
private static class ExamineBundle implements Runnable {
Expand Down Expand Up @@ -449,7 +437,8 @@ public int message(String cmd, Iterator<String> args, InputStream in, int dataBy
} else {
manifest = readManifest(bid);
}
notifyIncomingBundle(manifest);

ServalBatPhoneApplication.context.runOnBackgroundThread(new ExamineBundle(manifest));
} catch (Exception e) {
Log.v(TAG, e.getMessage(), e);
}
Expand Down
2 changes: 1 addition & 1 deletion src/org/servalproject/rhizome/RhizomeManifest_File.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public void setName(String name) {

@Override
public String getDisplayName() {
if (mName != null)
if (mName != null && !"".equals(mName))
return mName;
return super.getDisplayName();
}
Expand Down
Loading

0 comments on commit 8c71c34

Please sign in to comment.