diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index c7aa5a7d6..f7362082d 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -13,7 +13,7 @@
Connected
Last connected <br /> %1$s
Add a Contact
- Your identity:
+ Your nickname:
Wi-Fi is NOT AVAILABLE
Wi-Fi is OFF
Wi-Fi is DISCONNECTED
@@ -37,7 +37,6 @@
Codes do not match
This could mean that someone is trying to interfere with your connection.
Contact added
- Please enter a nickname for this contact:
Done
Messages
From: %1$s
@@ -49,13 +48,13 @@
Groups
New Post
Blogs
- New identity\u2026
+ New nickname\u2026
Create an Identity
- Choose your nickname:
+ Choose your nickname:
Create
You don\'t have any contacts. Add a contact now?
- Add a contact
+ Add
Cancel
You aren\'t subscribed to any groups. Create a group now?
- Create a group
+ You don\'t have any blogs. Create a blog now?
diff --git a/briar-android/src/net/sf/briar/android/AndroidModule.java b/briar-android/src/net/sf/briar/android/AndroidModule.java
index 3be4882c8..f97e6276e 100644
--- a/briar-android/src/net/sf/briar/android/AndroidModule.java
+++ b/briar-android/src/net/sf/briar/android/AndroidModule.java
@@ -20,7 +20,8 @@ public class AndroidModule extends AbstractModule {
Singleton.class);
bind(ReferenceManager.class).to(ReferenceManagerImpl.class).in(
Singleton.class);
- // Use a single thread so DB accesses from the UI don't overlap
+ // Use a single thread so DB accesses from the UI don't overlap, with
+ // an unbounded queue so submissions don't block
bind(Executor.class).annotatedWith(DatabaseUiExecutor.class).toInstance(
Executors.newSingleThreadExecutor());
}
diff --git a/briar-android/src/net/sf/briar/android/HomeScreenActivity.java b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
index 8aeb80902..2b0c7d6ca 100644
--- a/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
+++ b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
@@ -6,6 +6,7 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_MATCH;
+import java.lang.Thread.UncaughtExceptionHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -70,6 +71,17 @@ public class HomeScreenActivity extends BriarActivity {
// The activity was launched from the splash screen
showButtons();
}
+ // Ensure uncaught exceptions thrown on worker threads kill the JVM
+ final UncaughtExceptionHandler handler =
+ Thread.getDefaultUncaughtExceptionHandler();
+ UncaughtExceptionHandler die = new UncaughtExceptionHandler() {
+ public void uncaughtException(Thread thread, Throwable throwable) {
+ handler.uncaughtException(thread, throwable);
+ if(LOG.isLoggable(INFO)) LOG.info("Exiting");
+ System.exit(0);
+ }
+ };
+ Thread.setDefaultUncaughtExceptionHandler(die);
// Start the service and bind to it
startService(new Intent(BriarService.class.getName()));
bindService(new Intent(BriarService.class.getName()),
@@ -120,7 +132,11 @@ public class HomeScreenActivity extends BriarActivity {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
db.addLocalAuthor(a);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Storing author took " + duration + " ms");
runOnUiThread(new Runnable() {
public void run() {
showButtons();
diff --git a/briar-android/src/net/sf/briar/android/SetupActivity.java b/briar-android/src/net/sf/briar/android/SetupActivity.java
index b4dfda23c..0ece0cad4 100644
--- a/briar-android/src/net/sf/briar/android/SetupActivity.java
+++ b/briar-android/src/net/sf/briar/android/SetupActivity.java
@@ -1,6 +1,8 @@
package net.sf.briar.android;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.View.GONE;
@@ -67,6 +69,8 @@ implements OnEditorActionListener, OnClickListener {
nicknameEntry.setTextSize(18);
nicknameEntry.setMaxLines(1);
nicknameEntry.setPadding(10, 10, 10, 10);
+ int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_WORDS;
+ nicknameEntry.setInputType(inputType);
nicknameEntry.setOnEditorActionListener(this);
layout.addView(nicknameEntry);
diff --git a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
index 1c1af5c8e..b205c5a20 100644
--- a/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
+++ b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
@@ -54,6 +54,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
@Inject private ConnectionRegistry connectionRegistry;
private ContactListAdapter adapter = null;
+ private ListView list = null;
// Fields that are accessed from background threads must be volatile
@Inject private volatile DatabaseComponent db;
@@ -68,7 +69,7 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
layout.setGravity(CENTER_HORIZONTAL);
adapter = new ContactListAdapter(this);
- ListView list = new ListView(this);
+ list = new ListView(this);
// Give me all the width and all the unused height
list.setLayoutParams(MATCH_WRAP_1);
list.setAdapter(adapter);
@@ -110,13 +111,12 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
- // Wait for the service to be bound and started
serviceConnection.waitForStartup();
- // Load the contacts from the database
+ long now = System.currentTimeMillis();
Collection contacts = db.getContacts();
+ long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
- LOG.info("Loaded " + contacts.size() + " contacts");
- // Display the contacts in the UI
+ LOG.info("Load took " + duration + " ms");
displayContacts(contacts);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
@@ -181,6 +181,8 @@ implements OnClickListener, DatabaseListener, ConnectionListener {
ContactListItem item = adapter.getItem(i);
if(item.getContactId().equals(c)) {
item.setConnected(connected);
+ // FIXME: Item is not redrawn
+ list.invalidate();
return;
}
}
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
index c576e748f..893442a6a 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupActivity.java
@@ -113,16 +113,13 @@ OnClickListener, OnItemClickListener {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
- // Wait for the service to be bound and started
serviceConnection.waitForStartup();
- // Load the headers from the database
long now = System.currentTimeMillis();
Collection headers =
db.getMessageHeaders(groupId);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Load took " + duration + " ms");
- // Display the headers in the UI
displayHeaders(headers);
} catch(NoSuchSubscriptionException e) {
if(LOG.isLoggable(INFO)) LOG.info("Subscription removed");
diff --git a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
index f13fce4f6..6759acba8 100644
--- a/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/GroupListActivity.java
@@ -129,19 +129,16 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
- // Wait for the service to be bound and started
serviceConnection.waitForStartup();
- // Load the subscribed groups from the DB
long now = System.currentTimeMillis();
+ if(restricted) noGroups = db.getLocalGroups().isEmpty();
for(Group g : db.getSubscriptions()) {
// Filter out restricted/unrestricted groups
if(g.isRestricted() != restricted) continue;
- noGroups = false;
+ if(!restricted) noGroups = false;
try {
- // Load the headers from the database
Collection headers =
db.getMessageHeaders(g.getId());
- // Display the headers in the UI
displayHeaders(g, headers);
} catch(NoSuchSubscriptionException e) {
if(LOG.isLoggable(INFO))
@@ -222,6 +219,7 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
if(noGroups) {
NoGroupsDialog dialog = new NoGroupsDialog();
dialog.setListener(this);
+ dialog.setRestricted(restricted);
dialog.show(getSupportFragmentManager(), "NoGroupsDialog");
} else {
Intent i = new Intent(this, WriteGroupMessageActivity.class);
@@ -242,9 +240,9 @@ implements OnClickListener, DatabaseListener, NoGroupsDialog.Listener {
if(LOG.isLoggable(INFO)) LOG.info("Message expired, reloading");
loadHeaders();
} else if(e instanceof SubscriptionRemovedEvent) {
- // Reload the group, expecting NoSuchSubscriptionException
Group g = ((SubscriptionRemovedEvent) e).getGroup();
if(g.isRestricted() == restricted) {
+ // Reload the group, expecting NoSuchSubscriptionException
if(LOG.isLoggable(INFO)) LOG.info("Group removed, reloading");
loadHeaders(g);
}
diff --git a/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java b/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java
index 59cd5c270..e5aab93e1 100644
--- a/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java
+++ b/briar-android/src/net/sf/briar/android/groups/NoGroupsDialog.java
@@ -10,16 +10,21 @@ import android.support.v4.app.DialogFragment;
public class NoGroupsDialog extends DialogFragment {
private Listener listener = null;
+ private boolean restricted = false;
void setListener(Listener listener) {
this.listener = listener;
}
+ void setRestricted(boolean restricted) {
+ this.restricted = restricted;
+ }
+
@Override
public Dialog onCreateDialog(Bundle state) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- builder.setMessage(R.string.no_groups);
- builder.setPositiveButton(R.string.create_group_button,
+ builder.setMessage(restricted ? R.string.no_blogs : R.string.no_groups);
+ builder.setPositiveButton(R.string.create_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
listener.createGroupButtonClicked();
diff --git a/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java b/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java
index 145dcf670..001f1ccc3 100644
--- a/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/ReadGroupMessageActivity.java
@@ -236,7 +236,11 @@ implements OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
db.setReadFlag(messageId, read);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Setting flag took " + duration + " ms");
setReadInUi(read);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
@@ -265,7 +269,11 @@ implements OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
byte[] body = db.getMessageBody(messageId);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading message took " + duration + " ms");
final String text = new String(body, "UTF-8");
runOnUiThread(new Runnable() {
public void run() {
@@ -331,7 +339,11 @@ implements OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
db.setRating(authorId, r);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Setting rating took " + duration + " ms");
setRatingInUi(r);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
diff --git a/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java b/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
index 976bbb84b..0f1f6648d 100644
--- a/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/groups/WriteGroupMessageActivity.java
@@ -1,5 +1,7 @@
package net.sf.briar.android.groups;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
import static android.view.Gravity.CENTER_VERTICAL;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
@@ -137,6 +139,8 @@ implements OnItemSelectedListener, OnClickListener {
content = new EditText(this);
content.setPadding(10, 10, 10, 10);
+ int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_SENTENCES;
+ content.setInputType(inputType);
if(state != null && bundleEncrypter.decrypt(state)) {
Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
if(p != null) content.onRestoreInstanceState(p);
@@ -162,7 +166,12 @@ implements OnItemSelectedListener, OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
- displayLocalAuthors(db.getLocalAuthors());
+ long now = System.currentTimeMillis();
+ Collection localAuthors = db.getLocalAuthors();
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading authors took " + duration + " ms");
+ displayLocalAuthors(localAuthors);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
@@ -191,12 +200,16 @@ implements OnItemSelectedListener, OnClickListener {
try {
serviceConnection.waitForStartup();
List groups = new ArrayList();
+ long now = System.currentTimeMillis();
if(restricted) {
groups.addAll(db.getLocalGroups());
} else {
for(Group g : db.getSubscriptions())
if(!g.isRestricted()) groups.add(g);
}
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading groups took " + duration + " ms");
groups = Collections.unmodifiableList(groups);
displayGroups(groups);
} catch(DbException e) {
@@ -281,7 +294,11 @@ implements OnItemSelectedListener, OnClickListener {
// FIXME: Anonymous/pseudonymous, restricted/unrestricted
Message m = messageFactory.createAnonymousMessage(parentId,
group, "text/plain", body);
+ long now = System.currentTimeMillis();
db.addLocalGroupMessage(m);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Storing message took " + duration + " ms");
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
diff --git a/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java b/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
index fb08874a1..e5cd400a4 100644
--- a/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
+++ b/briar-android/src/net/sf/briar/android/identity/CreateIdentityActivity.java
@@ -1,11 +1,14 @@
package net.sf.briar.android.identity;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_FLAG_CAP_WORDS;
import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.view.inputmethod.InputMethodManager.HIDE_IMPLICIT_ONLY;
import static android.widget.LinearLayout.VERTICAL;
+import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_MATCH;
import static net.sf.briar.android.widgets.CommonLayoutParams.WRAP_WRAP;
@@ -80,6 +83,8 @@ implements OnEditorActionListener, OnClickListener {
nicknameEntry.setTextSize(18);
nicknameEntry.setMaxLines(1);
nicknameEntry.setPadding(10, 10, 10, 10);
+ int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_WORDS;
+ nicknameEntry.setInputType(inputType);
nicknameEntry.setOnEditorActionListener(this);
layout.addView(nicknameEntry);
@@ -141,7 +146,11 @@ implements OnEditorActionListener, OnClickListener {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
+ long now = System.currentTimeMillis();
db.addLocalAuthor(a);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Storing author took " + duration + " ms");
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
diff --git a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
index 9a5ed666e..07cd6e9da 100644
--- a/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
+++ b/briar-android/src/net/sf/briar/android/invitation/AddContactActivity.java
@@ -1,5 +1,6 @@
package net.sf.briar.android.invitation;
+import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import java.util.Collection;
@@ -186,12 +187,17 @@ implements InvitationListener {
setView(view);
}
- void loadLocalAuthorList(final LocalAuthorSpinnerAdapter adapter) {
+ void loadLocalAuthors(final LocalAuthorSpinnerAdapter adapter) {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
serviceConnection.waitForStartup();
- displayLocalAuthorList(adapter, db.getLocalAuthors());
+ long now = System.currentTimeMillis();
+ Collection localAuthors = db.getLocalAuthors();
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading authors took " + duration + " ms");
+ displayLocalAuthors(adapter, localAuthors);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
@@ -203,7 +209,7 @@ implements InvitationListener {
});
}
- private void displayLocalAuthorList(final LocalAuthorSpinnerAdapter adapter,
+ private void displayLocalAuthors(final LocalAuthorSpinnerAdapter adapter,
final Collection localAuthors) {
runOnUiThread(new Runnable() {
public void run() {
@@ -218,6 +224,10 @@ implements InvitationListener {
this.localAuthorId = localAuthorId;
}
+ AuthorId getLocalAuthorId() {
+ return localAuthorId;
+ }
+
void setNetworkName(String networkName) {
this.networkName = networkName;
}
@@ -347,6 +357,7 @@ implements InvitationListener {
}
public void connectionFailed() {
+ // FIXME: Do this on the UI thread
referenceManager.removeReference(handle, InvitationTask.class);
}
@@ -355,14 +366,17 @@ implements InvitationListener {
}
public void remoteConfirmationFailed() {
+ // FIXME: Do this on the UI thread
referenceManager.removeReference(handle, InvitationTask.class);
}
public void pseudonymExchangeSucceeded(String remoteName) {
+ // FIXME: Do this on the UI thread
referenceManager.removeReference(handle, InvitationTask.class);
}
public void pseudonymExchangeFailed() {
+ // FIXME: Do this on the UI thread
referenceManager.removeReference(handle, InvitationTask.class);
}
}
diff --git a/briar-android/src/net/sf/briar/android/invitation/ConnectionFailedView.java b/briar-android/src/net/sf/briar/android/invitation/ConnectionFailedView.java
index 5ae9e9fd1..9eb401636 100644
--- a/briar-android/src/net/sf/briar/android/invitation/ConnectionFailedView.java
+++ b/briar-android/src/net/sf/briar/android/invitation/ConnectionFailedView.java
@@ -57,26 +57,33 @@ implements WifiStateListener, BluetoothStateListener, OnClickListener {
tryAgainButton.setLayoutParams(WRAP_WRAP);
tryAgainButton.setText(R.string.try_again_button);
tryAgainButton.setOnClickListener(this);
- enabledOrDisableTryAgainButton();
+ enableOrDisableTryAgainButton();
addView(tryAgainButton);
}
- public void wifiStateChanged(String networkName) {
- container.setNetworkName(networkName);
- enabledOrDisableTryAgainButton();
+ public void wifiStateChanged(final String networkName) {
+ container.runOnUiThread(new Runnable() {
+ public void run() {
+ container.setNetworkName(networkName);
+ enableOrDisableTryAgainButton();
+ }
+ });
}
- public void bluetoothStateChanged(boolean enabled) {
- container.setUseBluetooth(enabled);
- enabledOrDisableTryAgainButton();
+ public void bluetoothStateChanged(final boolean enabled) {
+ container.runOnUiThread(new Runnable() {
+ public void run() {
+ container.setUseBluetooth(enabled);
+ enableOrDisableTryAgainButton();
+ }
+ });
}
- private void enabledOrDisableTryAgainButton() {
+ private void enableOrDisableTryAgainButton() {
if(tryAgainButton == null) return; // Activity not created yet
boolean useBluetooth = container.getUseBluetooth();
String networkName = container.getNetworkName();
- if(useBluetooth || networkName != null) tryAgainButton.setEnabled(true);
- else tryAgainButton.setEnabled(false);
+ tryAgainButton.setEnabled(useBluetooth || networkName != null);
}
public void onClick(View view) {
diff --git a/briar-android/src/net/sf/briar/android/invitation/ConnectionView.java b/briar-android/src/net/sf/briar/android/invitation/ConnectionView.java
index 9daf3287f..11b22c02a 100644
--- a/briar-android/src/net/sf/briar/android/invitation/ConnectionView.java
+++ b/briar-android/src/net/sf/briar/android/invitation/ConnectionView.java
@@ -32,6 +32,7 @@ public class ConnectionView extends AddContactView {
code.setText(String.format("%06d", localCode));
addView(code);
+ // FIXME: These spinners don't appear when trying again after a failure
String networkName = container.getNetworkName();
if(networkName != null) {
LinearLayout innerLayout = new LinearLayout(ctx);
diff --git a/briar-android/src/net/sf/briar/android/invitation/NetworkSetupView.java b/briar-android/src/net/sf/briar/android/invitation/NetworkSetupView.java
index 47ed08604..2a150f0a0 100644
--- a/briar-android/src/net/sf/briar/android/invitation/NetworkSetupView.java
+++ b/briar-android/src/net/sf/briar/android/invitation/NetworkSetupView.java
@@ -5,10 +5,8 @@ import static net.sf.briar.android.widgets.CommonLayoutParams.MATCH_WRAP;
import static net.sf.briar.android.widgets.CommonLayoutParams.WRAP_WRAP;
import net.sf.briar.R;
import net.sf.briar.android.LocalAuthorSpinnerAdapter;
-import net.sf.briar.android.identity.CreateIdentityActivity;
-import net.sf.briar.api.LocalAuthor;
+import net.sf.briar.api.AuthorId;
import android.content.Context;
-import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
@@ -39,17 +37,17 @@ OnClickListener {
innerLayout.setOrientation(HORIZONTAL);
innerLayout.setGravity(CENTER);
- TextView yourIdentity = new TextView(ctx);
- yourIdentity.setTextSize(18);
- yourIdentity.setPadding(10, 10, 10, 10);
- yourIdentity.setText(R.string.your_identity);
- innerLayout.addView(yourIdentity);
+ TextView yourNickname = new TextView(ctx);
+ yourNickname.setTextSize(18);
+ yourNickname.setPadding(10, 10, 10, 10);
+ yourNickname.setText(R.string.your_nickname);
+ innerLayout.addView(yourNickname);
adapter = new LocalAuthorSpinnerAdapter(ctx);
spinner = new Spinner(ctx);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);
- container.loadLocalAuthorList(adapter);
+ container.loadLocalAuthors(adapter);
innerLayout.addView(spinner);
addView(innerLayout);
@@ -89,21 +87,17 @@ OnClickListener {
private void enableOrDisableContinueButton() {
if(continueButton == null) return; // Activity not created yet
+ AuthorId localAuthorId = container.getLocalAuthorId();
boolean useBluetooth = container.getUseBluetooth();
String networkName = container.getNetworkName();
- if(useBluetooth || networkName != null) continueButton.setEnabled(true);
- else continueButton.setEnabled(false);
+ continueButton.setEnabled(localAuthorId != null &&
+ (useBluetooth || networkName != null));
}
public void onItemSelected(AdapterView> parent, View view, int position,
long id) {
- LocalAuthor item = adapter.getItem(position);
- if(item == null) {
- Intent i = new Intent(container, CreateIdentityActivity.class);
- container.startActivity(i);
- } else {
- container.setLocalAuthorId(item.getId());
- }
+ container.setLocalAuthorId(adapter.getItem(position).getId());
+ enableOrDisableContinueButton();
}
public void onNothingSelected(AdapterView> parent) {
diff --git a/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java b/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java
index d04aa9e84..21162f2a6 100644
--- a/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java
+++ b/briar-android/src/net/sf/briar/android/messages/NoContactsDialog.java
@@ -19,7 +19,7 @@ public class NoContactsDialog extends DialogFragment {
public Dialog onCreateDialog(Bundle state) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setMessage(R.string.no_contacts);
- builder.setPositiveButton(R.string.add_contact_button,
+ builder.setPositiveButton(R.string.add_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
listener.addContactButtonClicked();
diff --git a/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
index ef48f2814..9a4ba4eec 100644
--- a/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/ReadPrivateMessageActivity.java
@@ -189,7 +189,11 @@ implements OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
db.setReadFlag(messageId, read);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Setting flag took " + duration + " ms");
setReadInUi(read);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
@@ -218,7 +222,11 @@ implements OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
byte[] body = db.getMessageBody(messageId);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading message took " + duration + " ms");
final String text = new String(body, "UTF-8");
runOnUiThread(new Runnable() {
public void run() {
diff --git a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
index f3d714e07..db08956fb 100644
--- a/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
+++ b/briar-android/src/net/sf/briar/android/messages/WritePrivateMessageActivity.java
@@ -1,5 +1,7 @@
package net.sf.briar.android.messages;
+import static android.text.InputType.TYPE_CLASS_TEXT;
+import static android.text.InputType.TYPE_TEXT_FLAG_CAP_SENTENCES;
import static android.view.Gravity.CENTER_VERTICAL;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
@@ -125,6 +127,8 @@ implements OnItemSelectedListener, OnClickListener {
content = new EditText(this);
content.setPadding(10, 10, 10, 10);
+ int inputType = TYPE_CLASS_TEXT | TYPE_TEXT_FLAG_CAP_SENTENCES;
+ content.setInputType(inputType);
if(state != null && bundleEncrypter.decrypt(state)) {
Parcelable p = state.getParcelable("net.sf.briar.CONTENT");
if(p != null) content.onRestoreInstanceState(p);
@@ -149,7 +153,12 @@ implements OnItemSelectedListener, OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
- displayContacts(db.getContacts());
+ long now = System.currentTimeMillis();
+ Collection contacts = db.getContacts();
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading contacts took " + duration + " ms");
+ displayContacts(contacts);
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
@@ -200,12 +209,12 @@ implements OnItemSelectedListener, OnClickListener {
public void run() {
try {
serviceConnection.waitForStartup();
+ long now = System.currentTimeMillis();
localAuthor = db.getLocalAuthor(a);
- runOnUiThread(new Runnable() {
- public void run() {
- sendButton.setEnabled(true);
- }
- });
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Loading author took " + duration + " ms");
+ displayLocalAuthor();
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
@@ -217,6 +226,16 @@ implements OnItemSelectedListener, OnClickListener {
});
}
+ private void displayLocalAuthor() {
+ runOnUiThread(new Runnable() {
+ public void run() {
+ String format = getResources().getString(R.string.format_from);
+ from.setText(String.format(format, localAuthor.getName()));
+ sendButton.setEnabled(true);
+ }
+ });
+ }
+
public void onNothingSelected(AdapterView> parent) {
contactId = null;
sendButton.setEnabled(false);
@@ -242,7 +261,11 @@ implements OnItemSelectedListener, OnClickListener {
serviceConnection.waitForStartup();
Message m = messageFactory.createPrivateMessage(parentId,
"text/plain", body);
+ long now = System.currentTimeMillis();
db.addLocalPrivateMessage(m, contactId);
+ long duration = System.currentTimeMillis() - now;
+ if(LOG.isLoggable(INFO))
+ LOG.info("Storing message took " + duration + " ms");
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);