diff --git a/briar-android/AndroidManifest.xml b/briar-android/AndroidManifest.xml
index 93f248c9b..44027595b 100644
--- a/briar-android/AndroidManifest.xml
+++ b/briar-android/AndroidManifest.xml
@@ -25,16 +25,20 @@
+
+
+ android:label="@string/add_contact_title" >
diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml
index d60559cb5..e56b8652a 100644
--- a/briar-android/res/values/strings.xml
+++ b/briar-android/res/values/strings.xml
@@ -1,14 +1,14 @@
Briar
- FIXME: Notification title
- FIXME: Notification text
- Welcome to Briar! Add a contact to get started.
- For security reasons you must be face to face with someone to add them as a contact.
- Add a contact
+ Syncing messages
+ Touch to quit.
+ Contacts
Quit
- Add a Contact
- Briar can add contacts via Wi-Fi or Bluetooth. To use Wi-Fi you must both be connected to the same network.
+ Contacts
+ Add a contact
+ Add a Contact
+ Briar can add contacts via Wi-Fi or Bluetooth. For security reasons, you must be face-to-face to add someone as a contact. To use Wi-Fi you must both be connected to the same network.
Wi-Fi is not available on this device
Wi-Fi is OFF
Wi-Fi is DISCONNECTED
@@ -16,7 +16,7 @@
Bluetooth is not available on this device
Bluetooth is OFF
Bluetooth is NOT DISCOVERABLE
- Bluetooth is ON
+ Bluetooth is DISCOVERABLE
Continue
Your invitation code is
Please enter your contact\'s invitation code:
diff --git a/briar-android/src/net/sf/briar/android/BriarService.java b/briar-android/src/net/sf/briar/android/BriarService.java
index ebcd1d04e..06c24e4b7 100644
--- a/briar-android/src/net/sf/briar/android/BriarService.java
+++ b/briar-android/src/net/sf/briar/android/BriarService.java
@@ -1,5 +1,7 @@
package net.sf.briar.android;
+import static android.app.PendingIntent.FLAG_ONE_SHOT;
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@@ -13,6 +15,7 @@ import net.sf.briar.api.db.DatabaseComponent;
import net.sf.briar.api.db.DbException;
import net.sf.briar.api.plugins.PluginManager;
import roboguice.service.RoboService;
+import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
@@ -39,13 +42,20 @@ public class BriarService extends RoboService {
public void onCreate() {
super.onCreate();
if(LOG.isLoggable(INFO)) LOG.info("Created");
+ // Show an ongoing notification that the service is running
NotificationCompat.Builder b = new NotificationCompat.Builder(this);
b.setSmallIcon(R.drawable.notification_icon);
b.setContentTitle(getText(R.string.notification_title));
b.setContentText(getText(R.string.notification_text));
+ // Touch the notification to quit
+ Intent i = new Intent(this, HomeScreenActivity.class);
+ i.addFlags(FLAG_ACTIVITY_CLEAR_TOP);
+ i.putExtra("net.sf.briar.QUIT", true);
+ PendingIntent pi = PendingIntent.getActivity(this, 0, i, FLAG_ONE_SHOT);
+ b.setContentIntent(pi);
b.setOngoing(true);
startForeground(1, b.build());
- if(LOG.isLoggable(INFO)) LOG.info("Running in the foreground");
+ // Start the services in the background thread
new Thread() {
@Override
public void run() {
@@ -69,6 +79,7 @@ public class BriarService extends RoboService {
public void onDestroy() {
super.onDestroy();
if(LOG.isLoggable(INFO)) LOG.info("Destroyed");
+ // Stop the services in a background thread
new Thread() {
@Override
public void run() {
@@ -117,14 +128,14 @@ public class BriarService extends RoboService {
startupLatch.await();
}
- public void shutdown() {
- stopSelf();
- }
-
public void waitForShutdown() throws InterruptedException {
shutdownLatch.await();
}
+ public void shutdown() {
+ stopSelf();
+ }
+
public class BriarBinder extends Binder {
public BriarService getService() {
diff --git a/briar-android/src/net/sf/briar/android/HomeScreenActivity.java b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
new file mode 100644
index 000000000..c6db489c9
--- /dev/null
+++ b/briar-android/src/net/sf/briar/android/HomeScreenActivity.java
@@ -0,0 +1,124 @@
+package net.sf.briar.android;
+
+import static android.view.Gravity.CENTER;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
+import static android.widget.LinearLayout.HORIZONTAL;
+import static android.widget.LinearLayout.VERTICAL;
+import static java.util.logging.Level.INFO;
+
+import java.util.logging.Logger;
+
+import net.sf.briar.R;
+import net.sf.briar.android.BriarService.BriarBinder;
+import net.sf.briar.android.BriarService.BriarServiceConnection;
+import net.sf.briar.android.contact.ContactListActivity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.RelativeLayout.LayoutParams;
+
+public class HomeScreenActivity extends BriarActivity
+implements OnClickListener {
+
+ private static final Logger LOG =
+ Logger.getLogger(HomeScreenActivity.class.getName());
+
+ private final BriarServiceConnection serviceConnection =
+ new BriarServiceConnection();
+
+ Button contactListButton = null, quitButton = null;
+
+ @Override
+ public void onCreate(Bundle state) {
+ super.onCreate(null);
+ if(LOG.isLoggable(INFO)) LOG.info("Created");
+ LinearLayout layout = new LinearLayout(this);
+ layout.setLayoutParams(new LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ layout.setOrientation(VERTICAL);
+ layout.setGravity(CENTER);
+
+ // If this activity was launched from the notification bar, quit
+ if(getIntent().getBooleanExtra("net.sf.briar.QUIT", false)) {
+ ProgressBar spinner = new ProgressBar(this);
+ spinner.setIndeterminate(true);
+ layout.addView(spinner);
+ quit();
+ } else {
+ LinearLayout innerLayout = new LinearLayout(this);
+ innerLayout.setOrientation(HORIZONTAL);
+ innerLayout.setGravity(CENTER);
+
+ contactListButton = new Button(this);
+ LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ contactListButton.setLayoutParams(lp);
+ contactListButton.setText(R.string.contact_list_button);
+ contactListButton.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.social_person, 0, 0, 0);
+ contactListButton.setOnClickListener(this);
+ innerLayout.addView(contactListButton);
+
+ quitButton = new Button(this);
+ quitButton.setLayoutParams(lp);
+ quitButton.setText(R.string.quit_button);
+ quitButton.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.navigation_cancel, 0, 0, 0);
+ quitButton.setOnClickListener(this);
+ innerLayout.addView(quitButton);
+ layout.addView(innerLayout);
+ }
+
+ setContentView(layout);
+
+ // Start the service and bind to it
+ startService(new Intent(BriarService.class.getName()));
+ bindService(new Intent(BriarService.class.getName()),
+ serviceConnection, 0);
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unbindService(serviceConnection);
+ }
+
+ public void onClick(View view) {
+ if(view == contactListButton)
+ startActivity(new Intent(this, ContactListActivity.class));
+ else if(view == quitButton) quit();
+ }
+
+ private void quit() {
+ new Thread() {
+ @Override
+ public void run() {
+ try {
+ // Wait for the service to be bound and started
+ IBinder binder = serviceConnection.waitForBinder();
+ BriarService service = ((BriarBinder) binder).getService();
+ service.waitForStartup();
+ // Shut down the service and wait for it to shut down
+ if(LOG.isLoggable(INFO)) LOG.info("Shutting down service");
+ service.shutdown();
+ service.waitForShutdown();
+ // Finish the activity and kill the JVM
+ runOnUiThread(new Runnable() {
+ public void run() {
+ finish();
+ if(LOG.isLoggable(INFO)) LOG.info("Exiting");
+ System.exit(0);
+ }
+ });
+ } catch(InterruptedException e) {
+ if(LOG.isLoggable(INFO))
+ LOG.info("Interrupted while waiting for service");
+ }
+ }
+ }.start();
+ }
+}
diff --git a/briar-android/src/net/sf/briar/android/helloworld/HelloWorldActivity.java b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
similarity index 67%
rename from briar-android/src/net/sf/briar/android/helloworld/HelloWorldActivity.java
rename to briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
index 281267ae5..ef3b7897a 100644
--- a/briar-android/src/net/sf/briar/android/helloworld/HelloWorldActivity.java
+++ b/briar-android/src/net/sf/briar/android/contact/ContactListActivity.java
@@ -1,10 +1,8 @@
-package net.sf.briar.android.helloworld;
+package net.sf.briar.android.contact;
-import static android.view.Gravity.CENTER;
import static android.view.Gravity.CENTER_HORIZONTAL;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
-import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
@@ -39,15 +37,14 @@ import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout.LayoutParams;
-import android.widget.TextView;
import com.google.inject.Inject;
-public class HelloWorldActivity extends BriarActivity
+public class ContactListActivity extends BriarActivity
implements OnClickListener, DatabaseListener {
private static final Logger LOG =
- Logger.getLogger(HelloWorldActivity.class.getName());
+ Logger.getLogger(ContactListActivity.class.getName());
private final BriarServiceConnection serviceConnection =
new BriarServiceConnection();
@@ -55,7 +52,6 @@ implements OnClickListener, DatabaseListener {
@Inject private DatabaseComponent db;
@Inject @DatabaseExecutor private Executor dbExecutor;
- Button addContact = null, quit = null;
private ArrayAdapter adapter = null;
@Override
@@ -67,36 +63,6 @@ implements OnClickListener, DatabaseListener {
layout.setOrientation(VERTICAL);
layout.setGravity(CENTER_HORIZONTAL);
- TextView welcome = new TextView(this);
- welcome.setPadding(0, 0, 0, 10);
- welcome.setText(R.string.welcome);
- layout.addView(welcome);
-
- TextView faceToFace = new TextView(this);
- faceToFace.setPadding(0, 0, 0, 10);
- faceToFace.setText(R.string.face_to_face);
- layout.addView(faceToFace);
-
- LinearLayout innerLayout = new LinearLayout(this);
- innerLayout.setOrientation(HORIZONTAL);
- innerLayout.setGravity(CENTER);
-
- addContact = new Button(this);
- LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
- addContact.setLayoutParams(lp);
- addContact.setText(R.string.add_contact_button);
- addContact.setCompoundDrawablesWithIntrinsicBounds(
- R.drawable.social_add_person, 0, 0, 0);
- addContact.setOnClickListener(this);
- innerLayout.addView(addContact);
-
- quit = new Button(this);
- quit.setLayoutParams(lp);
- quit.setText(R.string.quit_button);
- quit.setOnClickListener(this);
- innerLayout.addView(quit);
- layout.addView(innerLayout);
-
adapter = new ArrayAdapter(this,
android.R.layout.simple_expandable_list_item_1,
new ArrayList());
@@ -104,17 +70,29 @@ implements OnClickListener, DatabaseListener {
listView.setAdapter(adapter);
layout.addView(listView);
- setContentView(layout);
+ Button addContactButton = new Button(this);
+ LayoutParams lp = new LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
+ addContactButton.setLayoutParams(lp);
+ addContactButton.setText(R.string.add_contact_button);
+ addContactButton.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.social_add_person, 0, 0, 0);
+ addContactButton.setOnClickListener(this);
+ layout.addView(addContactButton);
+ setContentView(layout);
+
// Listen for database events
db.addListener(this);
- // Start the service and bind to it
- startService(new Intent(BriarService.class.getName()));
+ // Bind to the service
bindService(new Intent(BriarService.class.getName()),
serviceConnection, 0);
+ // Load the contact list from the DB
+ reloadContactList();
+
// Add some fake contacts to the database in a background thread
+ // FIXME: Remove this
dbExecutor.execute(new Runnable() {
public void run() {
try {
@@ -137,41 +115,14 @@ implements OnClickListener, DatabaseListener {
});
}
- public void onClick(View view) {
- if(view == addContact)
- startActivity(new Intent(this, AddContactActivity.class));
- else if(view == quit)
- quit();
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ unbindService(serviceConnection);
}
- private void quit() {
- new Thread() {
- @Override
- public void run() {
- try {
- // Wait for the service to be bound and started
- IBinder binder = serviceConnection.waitForBinder();
- BriarService service = ((BriarBinder) binder).getService();
- service.waitForStartup();
- // Shut down the service and wait for it to shut down
- if(LOG.isLoggable(INFO)) LOG.info("Shutting down service");
- service.shutdown();
- service.waitForShutdown();
- // Unbind from the service, finish the activity, and die
- runOnUiThread(new Runnable() {
- public void run() {
- unbindService(serviceConnection);
- finish();
- if(LOG.isLoggable(INFO)) LOG.info("Exiting");
- System.exit(0);
- }
- });
- } catch(InterruptedException e) {
- if(LOG.isLoggable(INFO))
- LOG.info("Interrupted while waiting for service");
- }
- }
- }.start();
+ public void onClick(View view) {
+ startActivity(new Intent(this, AddContactActivity.class));
}
public void eventOccurred(DatabaseEvent e) {