Notification settings. Dev task #76.

This commit is contained in:
akwizgran
2014-03-10 18:00:36 +00:00
parent d151633a60
commit 4560cf17ff
11 changed files with 297 additions and 81 deletions

View File

@@ -11,4 +11,6 @@
<color name="horizontal_border">#CCCCCC</color> <color name="horizontal_border">#CCCCCC</color>
<color name="groups_available_background">#FCCF1C</color> <color name="groups_available_background">#FCCF1C</color>
<color name="no_posts">#AAAAAA</color> <color name="no_posts">#AAAAAA</color>
<color name="settings_title_text">#2D3E50</color>
<color name="settings_title_underline">#2D3E50</color>
</resources> </resources>

View File

@@ -85,6 +85,15 @@
<item quantity="other">%d new forum posts.</item> <item quantity="other">%d new forum posts.</item>
</plurals> </plurals>
<string name="settings_title">Settings</string> <string name="settings_title">Settings</string>
<string name="activate_bluetooth_option">Activate Bluetooth while signed in</string> <string name="bluetooth_setting_title">BLUETOOTH</string>
<string name="activate_bluetooth_explanation">Briar uses Bluetooth to communicate with nearby contacts</string> <string name="bluetooth_setting">Turn on Bluetooth</string>
<string name="bluetooth_setting_enabled">While signed in</string>
<string name="bluetooth_setting_disabled">Only when adding contacts</string>
<string name="notification_settings_title">NOTIFICATIONS</string>
<string name="notify_private_messages_setting">Show alerts for private messages</string>
<string name="notify_group_posts_setting">Show alerts for forum posts</string>
<string name="notify_vibration_setting">Vibrate</string>
<string name="notify_sound_setting">Sound</string>
<string name="notify_sound_setting_enabled">Default ringtone</string>
<string name="notify_sound_setting_disabled">No sound</string>
</resources> </resources>

View File

@@ -60,8 +60,6 @@ public class AndroidModule extends AbstractModule {
protected void configure() { protected void configure() {
bind(AndroidExecutor.class).to(AndroidExecutorImpl.class).in( bind(AndroidExecutor.class).to(AndroidExecutorImpl.class).in(
Singleton.class); Singleton.class);
bind(AndroidNotificationManager.class).to(
AndroidNotificationManagerImpl.class).in(Singleton.class);
bind(ReferenceManager.class).to(ReferenceManagerImpl.class).in( bind(ReferenceManager.class).to(ReferenceManagerImpl.class).in(
Singleton.class); Singleton.class);
bind(UiCallback.class).toInstance(uiCallback); bind(UiCallback.class).toInstance(uiCallback);
@@ -101,4 +99,12 @@ public class AndroidModule extends AbstractModule {
} }
}; };
} }
@Provides @Singleton
AndroidNotificationManager getAndroidNotificationManager(
LifecycleManager lifecycleManager,
AndroidNotificationManagerImpl notificationManager) {
lifecycleManager.register(notificationManager);
return notificationManager;
}
} }

View File

@@ -1,12 +1,17 @@
package org.briarproject.android; package org.briarproject.android;
import static android.app.Notification.DEFAULT_ALL; import static android.app.Notification.DEFAULT_LIGHTS;
import static android.app.Notification.DEFAULT_SOUND;
import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
import static android.content.Context.NOTIFICATION_SERVICE; import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
import static java.util.logging.Level.WARNING;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import javax.inject.Inject; import javax.inject.Inject;
@@ -16,21 +21,36 @@ import org.briarproject.android.contact.ConversationActivity;
import org.briarproject.android.groups.GroupActivity; import org.briarproject.android.groups.GroupActivity;
import org.briarproject.android.groups.GroupListActivity; import org.briarproject.android.groups.GroupListActivity;
import org.briarproject.api.ContactId; import org.briarproject.api.ContactId;
import org.briarproject.api.Settings;
import org.briarproject.api.android.AndroidNotificationManager; import org.briarproject.api.android.AndroidNotificationManager;
import org.briarproject.api.android.DatabaseUiExecutor;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.messaging.GroupId; import org.briarproject.api.messaging.GroupId;
import android.app.Application; import android.app.Application;
import android.app.Notification;
import android.app.NotificationManager; import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.app.NotificationCompat; import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder; import android.support.v4.app.TaskStackBuilder;
class AndroidNotificationManagerImpl implements AndroidNotificationManager { class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Service, EventListener {
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
private static final int GROUP_POST_NOTIFICATION_ID = 4; private static final int GROUP_POST_NOTIFICATION_ID = 4;
private static final Logger LOG =
Logger.getLogger(AndroidNotificationManagerImpl.class.getName());
private final DatabaseComponent db;
private final Executor dbUiExecutor;
private final Context appContext; private final Context appContext;
private final Map<ContactId, Integer> contactCounts = private final Map<ContactId, Integer> contactCounts =
new HashMap<ContactId, Integer>(); // Locking: this new HashMap<ContactId, Integer>(); // Locking: this
@@ -39,9 +59,42 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
private int privateTotal = 0, groupTotal = 0; // Locking: this private int privateTotal = 0, groupTotal = 0; // Locking: this
private volatile Settings settings = new Settings();
@Inject @Inject
public AndroidNotificationManagerImpl(Application app) { public AndroidNotificationManagerImpl(DatabaseComponent db,
this.appContext = app.getApplicationContext(); @DatabaseUiExecutor Executor dbExecutor, Application app) {
this.db = db;
this.dbUiExecutor = dbExecutor;
appContext = app.getApplicationContext();
}
public boolean start() {
db.addListener(this);
loadSettings();
return true;
}
private void loadSettings() {
dbUiExecutor.execute(new Runnable() {
public void run() {
try {
settings = db.getSettings();
} catch(DbException e) {
if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
}
public boolean stop() {
db.removeListener(this);
return true;
}
public void eventOccurred(Event e) {
if(e instanceof SettingsUpdatedEvent) loadSettings();
} }
public synchronized void showPrivateMessageNotification(ContactId c) { public synchronized void showPrivateMessageNotification(ContactId c) {
@@ -63,6 +116,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
private void updatePrivateMessageNotification() { private void updatePrivateMessageNotification() {
if(privateTotal == 0) { if(privateTotal == 0) {
clearPrivateMessageNotification(); clearPrivateMessageNotification();
} else if(!settings.getBoolean("notifyPrivateMessages", true)) {
return;
} else { } else {
NotificationCompat.Builder b = NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext); new NotificationCompat.Builder(appContext);
@@ -71,24 +126,24 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
b.setContentText(appContext.getResources().getQuantityString( b.setContentText(appContext.getResources().getQuantityString(
R.plurals.private_message_notification_text, privateTotal, R.plurals.private_message_notification_text, privateTotal,
privateTotal)); privateTotal));
b.setDefaults(DEFAULT_ALL); b.setDefaults(getDefaults());
b.setOnlyAlertOnce(true); b.setOnlyAlertOnce(true);
if(contactCounts.size() == 1) { if(contactCounts.size() == 1) {
Intent i = new Intent(appContext, ConversationActivity.class); Intent i = new Intent(appContext, ConversationActivity.class);
ContactId c = contactCounts.keySet().iterator().next(); ContactId c = contactCounts.keySet().iterator().next();
i.putExtra("briar.CONTACT_ID", c.getInt()); i.putExtra("briar.CONTACT_ID", c.getInt());
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder tsb = TaskStackBuilder.create(appContext); TaskStackBuilder t = TaskStackBuilder.create(appContext);
tsb.addParentStack(ConversationActivity.class); t.addParentStack(ConversationActivity.class);
tsb.addNextIntent(i); t.addNextIntent(i);
b.setContentIntent(tsb.getPendingIntent(0, 0)); b.setContentIntent(t.getPendingIntent(0, FLAG_UPDATE_CURRENT));
} else { } else {
Intent i = new Intent(appContext, ContactListActivity.class); Intent i = new Intent(appContext, ContactListActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder tsb = TaskStackBuilder.create(appContext); TaskStackBuilder t = TaskStackBuilder.create(appContext);
tsb.addParentStack(ContactListActivity.class); t.addParentStack(ContactListActivity.class);
tsb.addNextIntent(i); t.addNextIntent(i);
b.setContentIntent(tsb.getPendingIntent(0, 0)); b.setContentIntent(t.getPendingIntent(0, FLAG_UPDATE_CURRENT));
} }
Object o = appContext.getSystemService(NOTIFICATION_SERVICE); Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
NotificationManager nm = (NotificationManager) o; NotificationManager nm = (NotificationManager) o;
@@ -103,6 +158,15 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
nm.cancel(PRIVATE_MESSAGE_NOTIFICATION_ID); nm.cancel(PRIVATE_MESSAGE_NOTIFICATION_ID);
} }
private int getDefaults() {
int defaults = DEFAULT_LIGHTS;
if(settings.getBoolean("notifySound", true))
defaults |= DEFAULT_SOUND;
if(settings.getBoolean("notifyVibration", true))
defaults |= Notification.DEFAULT_VIBRATE;
return defaults;
}
public synchronized void showGroupPostNotification(GroupId g) { public synchronized void showGroupPostNotification(GroupId g) {
Integer count = groupCounts.get(g); Integer count = groupCounts.get(g);
if(count == null) groupCounts.put(g, 1); if(count == null) groupCounts.put(g, 1);
@@ -122,6 +186,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
private void updateGroupPostNotification() { private void updateGroupPostNotification() {
if(groupTotal == 0) { if(groupTotal == 0) {
clearGroupPostNotification(); clearGroupPostNotification();
} else if(!settings.getBoolean("notifyGroupPosts", true)) {
return;
} else { } else {
NotificationCompat.Builder b = NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext); new NotificationCompat.Builder(appContext);
@@ -130,24 +196,24 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager {
b.setContentText(appContext.getResources().getQuantityString( b.setContentText(appContext.getResources().getQuantityString(
R.plurals.group_post_notification_text, groupTotal, R.plurals.group_post_notification_text, groupTotal,
groupTotal)); groupTotal));
b.setDefaults(DEFAULT_ALL); b.setDefaults(getDefaults());
b.setOnlyAlertOnce(true); b.setOnlyAlertOnce(true);
if(groupCounts.size() == 1) { if(groupCounts.size() == 1) {
Intent i = new Intent(appContext, GroupActivity.class); Intent i = new Intent(appContext, GroupActivity.class);
GroupId g = groupCounts.keySet().iterator().next(); GroupId g = groupCounts.keySet().iterator().next();
i.putExtra("briar.GROUP_ID", g.getBytes()); i.putExtra("briar.GROUP_ID", g.getBytes());
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder tsb = TaskStackBuilder.create(appContext); TaskStackBuilder t = TaskStackBuilder.create(appContext);
tsb.addParentStack(GroupActivity.class); t.addParentStack(GroupActivity.class);
tsb.addNextIntent(i); t.addNextIntent(i);
b.setContentIntent(tsb.getPendingIntent(0, 0)); b.setContentIntent(t.getPendingIntent(0, FLAG_UPDATE_CURRENT));
} else { } else {
Intent i = new Intent(appContext, GroupListActivity.class); Intent i = new Intent(appContext, GroupListActivity.class);
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder tsb = TaskStackBuilder.create(appContext); TaskStackBuilder t = TaskStackBuilder.create(appContext);
tsb.addParentStack(GroupListActivity.class); t.addParentStack(GroupListActivity.class);
tsb.addNextIntent(i); t.addNextIntent(i);
b.setContentIntent(tsb.getPendingIntent(0, 0)); b.setContentIntent(t.getPendingIntent(0, FLAG_UPDATE_CURRENT));
} }
Object o = appContext.getSystemService(NOTIFICATION_SERVICE); Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
NotificationManager nm = (NotificationManager) o; NotificationManager nm = (NotificationManager) o;

View File

@@ -95,9 +95,7 @@ public class PasswordActivity extends RoboActivity {
layout.addView(passwordEntry); layout.addView(passwordEntry);
// Adjusting the padding of buttons and EditTexts has the wrong results // Adjusting the padding of buttons and EditTexts has the wrong results
FixedVerticalSpace space = new FixedVerticalSpace(this); layout.addView(new FixedVerticalSpace(this));
space.setHeight(pad);
layout.addView(space);
continueButton = new Button(this); continueButton = new Button(this);
continueButton.setLayoutParams(WRAP_WRAP); continueButton.setLayoutParams(WRAP_WRAP);

View File

@@ -1,9 +1,11 @@
package org.briarproject.android; package org.briarproject.android;
import static android.graphics.Typeface.DEFAULT_BOLD;
import static android.view.Gravity.CENTER; import static android.view.Gravity.CENTER;
import static android.view.View.GONE; import static android.view.View.GONE;
import static android.view.View.VISIBLE; import static android.view.View.VISIBLE;
import static android.widget.LinearLayout.VERTICAL; import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1; import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
@@ -16,10 +18,14 @@ import org.briarproject.R;
import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar; import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportConfig; import org.briarproject.api.TransportConfig;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.content.Intent; import android.content.Intent;
@@ -33,15 +39,20 @@ import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.TextView; import android.widget.TextView;
public class SettingsActivity extends BriarActivity implements OnClickListener { public class SettingsActivity extends BriarActivity implements EventListener,
OnClickListener {
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SettingsActivity.class.getName()); Logger.getLogger(SettingsActivity.class.getName());
private CheckBox bluetooth = null;
private ScrollView scroll = null; private ScrollView scroll = null;
private TextView enableBluetooth = null, enableBluetoothHint = null;
private CheckBox notifyPrivateMessages = null, notifyGroupPosts = null;
private CheckBox notifyVibration = null;
private TextView notifySound = null, notifySoundHint = null;
private ListLoadingProgressBar progress = null; private ListLoadingProgressBar progress = null;
private ImageButton testingButton = null; private ImageButton testingButton = null;
private boolean bluetoothSetting = true, soundSetting = true;
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@Inject private volatile DatabaseComponent db; @Inject private volatile DatabaseComponent db;
@@ -60,16 +71,87 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
int pad = LayoutUtils.getPadding(this); int pad = LayoutUtils.getPadding(this);
settings.setPadding(pad, pad, pad, pad); settings.setPadding(pad, pad, pad, pad);
bluetooth = new CheckBox(this); TextView bluetoothTitle = new TextView(this);
bluetooth.setLayoutParams(MATCH_WRAP); bluetoothTitle.setPadding(pad, 0, pad, 0);
bluetooth.setTextSize(18); bluetoothTitle.setTypeface(DEFAULT_BOLD);
bluetooth.setText(R.string.activate_bluetooth_option); Resources res = getResources();
bluetooth.setOnClickListener(this); int titleText = res.getColor(R.color.settings_title_text);
settings.addView(bluetooth); bluetoothTitle.setTextColor(titleText);
bluetoothTitle.setText(R.string.bluetooth_setting_title);
settings.addView(bluetoothTitle);
TextView bluetoothHint = new TextView(this); HorizontalBorder underline = new HorizontalBorder(this);
bluetoothHint.setText(R.string.activate_bluetooth_explanation); int titleUnderline = res.getColor(R.color.settings_title_underline);
settings.addView(bluetoothHint); underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
enableBluetooth = new TextView(this);
enableBluetooth.setPadding(pad, pad, pad, 0);
enableBluetooth.setTextSize(18);
enableBluetooth.setText(R.string.bluetooth_setting);
enableBluetooth.setOnClickListener(this);
settings.addView(enableBluetooth);
enableBluetoothHint = new TextView(this);
enableBluetoothHint.setPadding(pad, 0, pad, pad);
enableBluetoothHint.setText(R.string.bluetooth_setting_enabled);
enableBluetoothHint.setOnClickListener(this);
settings.addView(enableBluetoothHint);
TextView notificationsTitle = new TextView(this);
notificationsTitle.setPadding(pad, 0, pad, 0);
notificationsTitle.setTypeface(DEFAULT_BOLD);
notificationsTitle.setTextColor(titleText);
notificationsTitle.setText(R.string.notification_settings_title);
settings.addView(notificationsTitle);
underline = new HorizontalBorder(this);
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
notifyPrivateMessages = new CheckBox(this);
notifyPrivateMessages.setPadding(0, pad, 0, pad);
notifyPrivateMessages.setTextSize(18);
notifyPrivateMessages.setText(R.string.notify_private_messages_setting);
notifyPrivateMessages.setChecked(true);
notifyPrivateMessages.setOnClickListener(this);
settings.addView(notifyPrivateMessages);
settings.addView(new HorizontalBorder(this));
notifyGroupPosts = new CheckBox(this);
notifyGroupPosts.setPadding(0, pad, 0, pad);
notifyGroupPosts.setTextSize(18);
notifyGroupPosts.setText(R.string.notify_group_posts_setting);
notifyGroupPosts.setChecked(true);
notifyGroupPosts.setOnClickListener(this);
settings.addView(notifyGroupPosts);
settings.addView(new HorizontalBorder(this));
notifyVibration = new CheckBox(this);
notifyVibration.setPadding(0, pad, 0, pad);
notifyVibration.setTextSize(18);
notifyVibration.setText(R.string.notify_vibration_setting);
notifyVibration.setOnClickListener(this);
settings.addView(notifyVibration);
settings.addView(new HorizontalBorder(this));
notifySound = new TextView(this);
notifySound.setPadding(pad, pad, pad, 0);
notifySound.setTextSize(18);
notifySound.setText(R.string.notify_sound_setting);
notifySound.setOnClickListener(this);
settings.addView(notifySound);
notifySoundHint = new TextView(this);
notifySoundHint.setPadding(pad, 0, pad, pad);
notifySoundHint.setText(R.string.notify_sound_setting_enabled);
notifySoundHint.setOnClickListener(this);
settings.addView(notifySoundHint);
settings.addView(new HorizontalBorder(this));
scroll.addView(settings); scroll.addView(settings);
scroll.setLayoutParams(MATCH_WRAP_1); scroll.setLayoutParams(MATCH_WRAP_1);
@@ -84,7 +166,6 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
LinearLayout footer = new LinearLayout(this); LinearLayout footer = new LinearLayout(this);
footer.setLayoutParams(MATCH_WRAP); footer.setLayoutParams(MATCH_WRAP);
footer.setGravity(CENTER); footer.setGravity(CENTER);
Resources res = getResources();
footer.setBackgroundColor(res.getColor(R.color.button_bar_background)); footer.setBackgroundColor(res.getColor(R.color.button_bar_background));
testingButton = new ImageButton(this); testingButton = new ImageButton(this);
testingButton.setBackgroundResource(0); testingButton.setBackgroundResource(0);
@@ -99,6 +180,7 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
db.addListener(this);
loadSettings(); loadSettings();
} }
@@ -106,11 +188,14 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
runOnDbThread(new Runnable() { runOnDbThread(new Runnable() {
public void run() { public void run() {
try { try {
boolean activateBluetooth = true; long now = System.currentTimeMillis();
TransportConfig c = db.getConfig(new TransportId("bt")); TransportConfig c = db.getConfig(new TransportId("bt"));
if(c != null && "false".equals(c.get("enable"))) Settings settings = db.getSettings();
activateBluetooth = false; long duration = System.currentTimeMillis() - now;
displaySettings(activateBluetooth); if(LOG.isLoggable(INFO))
LOG.info("Loading settings took " + duration + " ms");
boolean btSetting = c.getBoolean("enable", true);
displaySettings(btSetting, settings);
} catch(DbException e) { } catch(DbException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
@@ -119,37 +204,82 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
}); });
} }
private void displaySettings(final boolean activateBluetooth) { private void displaySettings(final boolean btSetting,
final Settings settings) {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {
scroll.setVisibility(VISIBLE); scroll.setVisibility(VISIBLE);
progress.setVisibility(GONE); progress.setVisibility(GONE);
bluetooth.setChecked(activateBluetooth);
bluetoothSetting = btSetting;
int resId;
if(bluetoothSetting) resId = R.string.bluetooth_setting_enabled;
else resId = R.string.bluetooth_setting_disabled;
enableBluetoothHint.setText(resId);
notifyPrivateMessages.setChecked(settings.getBoolean(
"notifyPrivateMessages", true));
notifyGroupPosts.setChecked(settings.getBoolean(
"notifyGroupPosts", true));
notifyVibration.setChecked(settings.getBoolean(
"notifyVibration", true));
soundSetting = settings.getBoolean("notifySound", true);
if(soundSetting) resId = R.string.notify_sound_setting_enabled;
else resId = R.string.notify_sound_setting_disabled;
notifySoundHint.setText(resId);
} }
}); });
} }
public void onClick(View view) { @Override
if(testingButton == null) return; // Not created yet public void onPause() {
if(view == bluetooth) { super.onPause();
boolean activateBluetooth = bluetooth.isChecked(); db.removeListener(this);
if(!activateBluetooth) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(adapter != null) adapter.disable();
}
storeSettings(activateBluetooth);
} else if(view == testingButton) {
startActivity(new Intent(this, TestingActivity.class));
}
} }
private void storeSettings(final boolean activateBluetooth) { public void onClick(View view) {
if(testingButton == null) return; // Not created yet
if(view == testingButton) {
startActivity(new Intent(this, TestingActivity.class));
return;
}
if(view == enableBluetooth || view == enableBluetoothHint) {
bluetoothSetting = !bluetoothSetting;
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if(adapter != null) {
if(bluetoothSetting) adapter.enable();
else adapter.disable();
}
} else if(view == notifySound || view == notifySoundHint) {
soundSetting = !soundSetting;
}
Settings settings = new Settings();
settings.putBoolean("notifyPrivateMessages",
notifyPrivateMessages.isChecked());
settings.putBoolean("notifyGroupPosts",
notifyGroupPosts.isChecked());
settings.putBoolean("notifyVibration",
notifyVibration.isChecked());
settings.putBoolean("notifySound", soundSetting);
storeSettings(bluetoothSetting, settings);
}
private void storeSettings(final boolean btSetting,
final Settings settings) {
runOnDbThread(new Runnable() { runOnDbThread(new Runnable() {
public void run() { public void run() {
try { try {
TransportConfig c = new TransportConfig(); TransportConfig c = new TransportConfig();
c.put("enable", String.valueOf(activateBluetooth)); c.putBoolean("enable", btSetting);
long now = System.currentTimeMillis();
db.mergeConfig(new TransportId("bt"), c); db.mergeConfig(new TransportId("bt"), c);
db.mergeSettings(settings);
long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO))
LOG.info("Storing settings took " + duration + " ms");
} catch(DbException e) { } catch(DbException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e); LOG.log(WARNING, e.toString(), e);
@@ -157,4 +287,11 @@ public class SettingsActivity extends BriarActivity implements OnClickListener {
} }
}); });
} }
public void eventOccurred(Event e) {
if(e instanceof SettingsUpdatedEvent) {
LOG.info("Settings updated");
loadSettings();
}
}
} }

View File

@@ -234,33 +234,33 @@ public class SetupActivity extends RoboActivity implements OnClickListener {
} }
private void storeEncryptedDatabaseKey(final byte[] encrypted) { private void storeEncryptedDatabaseKey(final byte[] encrypted) {
long start = System.currentTimeMillis(); long now = System.currentTimeMillis();
SharedPreferences prefs = getSharedPreferences("db", MODE_PRIVATE); SharedPreferences prefs = getSharedPreferences("db", MODE_PRIVATE);
Editor editor = prefs.edit(); Editor editor = prefs.edit();
editor.putString("key", StringUtils.toHexString(encrypted)); editor.putString("key", StringUtils.toHexString(encrypted));
editor.commit(); editor.commit();
long duration = System.currentTimeMillis() - start; long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO)) if(LOG.isLoggable(INFO))
LOG.info("Key storage took " + duration + " ms"); LOG.info("Key storage took " + duration + " ms");
} }
private byte[] encryptDatabaseKey(byte[] key, char[] password) { private byte[] encryptDatabaseKey(byte[] key, char[] password) {
long start = System.currentTimeMillis(); long now = System.currentTimeMillis();
byte[] encrypted = crypto.encryptWithPassword(key, password); byte[] encrypted = crypto.encryptWithPassword(key, password);
long duration = System.currentTimeMillis() - start; long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO)) if(LOG.isLoggable(INFO))
LOG.info("Key derivation took " + duration + " ms"); LOG.info("Key derivation took " + duration + " ms");
return encrypted; return encrypted;
} }
private LocalAuthor createLocalAuthor(String nickname) { private LocalAuthor createLocalAuthor(String nickname) {
long start = System.currentTimeMillis(); long now = System.currentTimeMillis();
KeyPair keyPair = crypto.generateSignatureKeyPair(); KeyPair keyPair = crypto.generateSignatureKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded(); byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded(); byte[] privateKey = keyPair.getPrivate().getEncoded();
LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname, LocalAuthor localAuthor = authorFactory.createLocalAuthor(nickname,
publicKey, privateKey); publicKey, privateKey);
long duration = System.currentTimeMillis() - start; long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO)) if(LOG.isLoggable(INFO))
LOG.info("Identity creation took " + duration + " ms"); LOG.info("Identity creation took " + duration + " ms");
return localAuthor; return localAuthor;

View File

@@ -33,7 +33,7 @@ public class SplashScreenActivity extends RoboSplashActivity {
// Default log level - change this to OFF for release builds // Default log level - change this to OFF for release builds
private static final Level DEFAULT_LOG_LEVEL = INFO; private static final Level DEFAULT_LOG_LEVEL = INFO;
private long start = System.currentTimeMillis(); private long now = System.currentTimeMillis();
public SplashScreenActivity() { public SplashScreenActivity() {
Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL); Logger.getLogger("").setLevel(DEFAULT_LOG_LEVEL);
@@ -60,7 +60,7 @@ public class SplashScreenActivity extends RoboSplashActivity {
} }
protected void startNextActivity() { protected void startNextActivity() {
long duration = System.currentTimeMillis() - start; long duration = System.currentTimeMillis() - now;
if(LOG.isLoggable(INFO)) if(LOG.isLoggable(INFO))
LOG.info("Guice startup took " + duration + " ms"); LOG.info("Guice startup took " + duration + " ms");
if(System.currentTimeMillis() >= EXPIRY_DATE) { if(System.currentTimeMillis() >= EXPIRY_DATE) {

View File

@@ -1,6 +1,6 @@
package org.briarproject.android.util; package org.briarproject.android.util;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import android.content.Context; import android.content.Context;
import android.view.View; import android.view.View;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
@@ -9,9 +9,7 @@ public class FixedVerticalSpace extends View {
public FixedVerticalSpace(Context ctx) { public FixedVerticalSpace(Context ctx) {
super(ctx); super(ctx);
} int height = LayoutUtils.getPadding(ctx);
setLayoutParams(new LayoutParams(MATCH_PARENT, height));
public void setHeight(int height) {
setLayoutParams(new LayoutParams(WRAP_CONTENT, height));
} }
} }

View File

@@ -43,11 +43,12 @@ public class AndroidPluginsModule extends AbstractModule {
AndroidExecutor androidExecutor, Application app, AndroidExecutor androidExecutor, Application app,
CryptoComponent crypto, LocationUtils locationUtils, CryptoComponent crypto, LocationUtils locationUtils,
ShutdownManager shutdownManager) { ShutdownManager shutdownManager) {
Context ctx = app.getApplicationContext(); Context appContext = app.getApplicationContext();
DuplexPluginFactory droidtooth = new DroidtoothPluginFactory( DuplexPluginFactory droidtooth = new DroidtoothPluginFactory(
pluginExecutor, androidExecutor, ctx, crypto.getSecureRandom()); pluginExecutor, androidExecutor, appContext,
crypto.getSecureRandom());
DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor, DuplexPluginFactory tor = new TorPluginFactory(pluginExecutor,
ctx, locationUtils, shutdownManager); appContext, locationUtils, shutdownManager);
DuplexPluginFactory lan = new LanTcpPluginFactory(pluginExecutor); DuplexPluginFactory lan = new LanTcpPluginFactory(pluginExecutor);
final Collection<DuplexPluginFactory> factories = final Collection<DuplexPluginFactory> factories =
Arrays.asList(droidtooth, tor, lan); Arrays.asList(droidtooth, tor, lan);

View File

@@ -155,8 +155,7 @@ class DroidtoothPlugin implements DuplexPlugin {
private boolean enableBluetooth() { private boolean enableBluetooth() {
if(adapter.isEnabled()) return true; if(adapter.isEnabled()) return true;
String enable = callback.getConfig().get("enable"); if(!callback.getConfig().getBoolean("enable", true)) {
if("false".equals(enable)) {
if(LOG.isLoggable(INFO)) LOG.info("Not enabling Bluetooth"); if(LOG.isLoggable(INFO)) LOG.info("Not enabling Bluetooth");
return false; return false;
} }
@@ -267,7 +266,7 @@ class DroidtoothPlugin implements DuplexPlugin {
public void poll(Collection<ContactId> connected) { public void poll(Collection<ContactId> connected) {
if(!running) return; if(!running) return;
if(!enableBluetooth()) return; if(!adapter.isEnabled()) return;
// Try to connect to known devices in parallel // Try to connect to known devices in parallel
Map<ContactId, TransportProperties> remote = Map<ContactId, TransportProperties> remote =
callback.getRemoteProperties(); callback.getRemoteProperties();
@@ -349,7 +348,7 @@ class DroidtoothPlugin implements DuplexPlugin {
public DuplexTransportConnection createInvitationConnection(PseudoRandom r, public DuplexTransportConnection createInvitationConnection(PseudoRandom r,
long timeout) { long timeout) {
if(!running) return null; if(!running) return null;
if(!enableBluetooth()) return null; if(!adapter.isEnabled()) return null;
// Use the invitation codes to generate the UUID // Use the invitation codes to generate the UUID
byte[] b = r.nextBytes(UUID_BYTES); byte[] b = r.nextBytes(UUID_BYTES);
UUID uuid = UUID.nameUUIDFromBytes(b); UUID uuid = UUID.nameUUIDFromBytes(b);