mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
20 Commits
beta-0.16.
...
beta-0.16.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
078534889e | ||
|
|
e92713006a | ||
|
|
18f43f3bc1 | ||
|
|
a4118b40e1 | ||
|
|
de29fbc324 | ||
|
|
3197dcf9b5 | ||
|
|
35aad409fd | ||
|
|
08ce6a7331 | ||
|
|
33a0099065 | ||
|
|
34d20fafda | ||
|
|
aafddcd0f0 | ||
|
|
0d6983b4ef | ||
|
|
69bfb72171 | ||
|
|
1aa33ec9b2 | ||
|
|
6702df1e22 | ||
|
|
c1748c9a86 | ||
|
|
9df624c62a | ||
|
|
0ee6197d7f | ||
|
|
b03a7dce3e | ||
|
|
6c59d7dd5f |
@@ -12,8 +12,8 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
versionCode 14
|
||||
versionName "0.14"
|
||||
versionCode 1609
|
||||
versionName "0.16.9"
|
||||
consumerProguardFiles 'proguard-rules.txt'
|
||||
}
|
||||
|
||||
|
||||
@@ -78,15 +78,19 @@ android {
|
||||
defaultConfig {
|
||||
minSdkVersion 14
|
||||
targetSdkVersion 22
|
||||
versionCode 1606
|
||||
versionName "0.16.6"
|
||||
versionCode 1609
|
||||
versionName "0.16.9"
|
||||
applicationId "org.briarproject.briar.beta"
|
||||
resValue "string", "app_package", "org.briarproject.briar.beta"
|
||||
resValue "string", "app_name", "Briar Beta"
|
||||
buildConfigField "String", "GitHash", "\"${getGitHash()}\""
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
applicationIdSuffix ".debug"
|
||||
resValue "string", "app_package", "org.briarproject.briar.beta.debug"
|
||||
resValue "string", "app_name", "Briar Debug"
|
||||
shrinkResources false
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
|
||||
@@ -5,11 +5,8 @@ import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import org.briarproject.bramble.api.contact.ContactId;
|
||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||
@@ -25,12 +22,14 @@ import org.briarproject.bramble.api.settings.SettingsManager;
|
||||
import org.briarproject.bramble.api.settings.event.SettingsUpdatedEvent;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.util.StringUtils;
|
||||
import org.briarproject.briar.R;
|
||||
import org.briarproject.briar.android.contact.ConversationActivity;
|
||||
import org.briarproject.briar.android.forum.ForumActivity;
|
||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
||||
import org.briarproject.briar.android.util.BriarNotificationBuilder;
|
||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
||||
import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent;
|
||||
@@ -48,6 +47,7 @@ import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@@ -61,8 +61,6 @@ import static android.content.Context.NOTIFICATION_SERVICE;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
|
||||
import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
|
||||
import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
|
||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE;
|
||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
import static org.briarproject.briar.android.activity.BriarActivity.GROUP_ID;
|
||||
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
|
||||
@@ -95,6 +93,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
private static final String BLOG_URI =
|
||||
"content://org.briarproject.briar/blog";
|
||||
|
||||
private static final long SOUND_DELAY = TimeUnit.SECONDS.toMillis(2);
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(AndroidNotificationManagerImpl.class.getName());
|
||||
|
||||
@@ -102,6 +102,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
private final SettingsManager settingsManager;
|
||||
private final AndroidExecutor androidExecutor;
|
||||
private final Context appContext;
|
||||
private final Clock clock;
|
||||
private final AtomicBoolean used = new AtomicBoolean(false);
|
||||
|
||||
// The following must only be accessed on the main UI thread
|
||||
@@ -117,16 +118,18 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
private boolean blockContacts = false, blockGroups = false;
|
||||
private boolean blockForums = false, blockBlogs = false;
|
||||
private boolean blockIntroductions = false;
|
||||
private long lastSound = 0;
|
||||
|
||||
private volatile Settings settings = new Settings();
|
||||
|
||||
@Inject
|
||||
AndroidNotificationManagerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
SettingsManager settingsManager, AndroidExecutor androidExecutor,
|
||||
Application app) {
|
||||
Application app, Clock clock) {
|
||||
this.dbExecutor = dbExecutor;
|
||||
this.settingsManager = settingsManager;
|
||||
this.androidExecutor = androidExecutor;
|
||||
this.clock = clock;
|
||||
appContext = app.getApplicationContext();
|
||||
}
|
||||
|
||||
@@ -288,22 +291,19 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
if (contactTotal == 0) {
|
||||
clearContactNotification();
|
||||
} else if (settings.getBoolean(PREF_NOTIFY_PRIVATE, true)) {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
BriarNotificationBuilder b =
|
||||
new BriarNotificationBuilder(appContext);
|
||||
b.setSmallIcon(R.drawable.notification_private_message);
|
||||
b.setColor(ContextCompat.getColor(appContext,
|
||||
R.color.briar_primary));
|
||||
b.setColorRes(R.color.briar_primary);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getResources().getQuantityString(
|
||||
R.plurals.private_message_notification_text, contactTotal,
|
||||
contactTotal));
|
||||
boolean sound = settings.getBoolean(PREF_NOTIFY_SOUND, true);
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (sound && !StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
b.setNumber(contactTotal);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
b.setLockscreenVisibility(CATEGORY_MESSAGE, showOnLockScreen);
|
||||
playSound(b);
|
||||
if (contactCounts.size() == 1) {
|
||||
// Touching the notification shows the relevant conversation
|
||||
Intent i = new Intent(appContext, ConversationActivity.class);
|
||||
@@ -326,21 +326,27 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_MESSAGE);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
if (showOnLockScreen)
|
||||
b.setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(PRIVATE_MESSAGE_NOTIFICATION_ID, b.build());
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void playSound(BriarNotificationBuilder b) {
|
||||
boolean sound = settings.getBoolean(PREF_NOTIFY_SOUND, true);
|
||||
if (!sound) return;
|
||||
|
||||
long currentTime = clock.currentTimeMillis();
|
||||
if (currentTime - lastSound > SOUND_DELAY) {
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
lastSound = clock.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private int getDefaults() {
|
||||
int defaults = DEFAULT_LIGHTS;
|
||||
@@ -387,21 +393,19 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
if (groupTotal == 0) {
|
||||
clearGroupMessageNotification();
|
||||
} else if (settings.getBoolean(PREF_NOTIFY_GROUP, true)) {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
BriarNotificationBuilder b =
|
||||
new BriarNotificationBuilder(appContext);
|
||||
b.setSmallIcon(R.drawable.notification_private_group);
|
||||
b.setColor(ContextCompat.getColor(appContext,
|
||||
R.color.briar_primary));
|
||||
b.setColorRes(R.color.briar_primary);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getResources().getQuantityString(
|
||||
R.plurals.group_message_notification_text, groupTotal,
|
||||
groupTotal));
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
b.setNumber(groupTotal);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
||||
playSound(b);
|
||||
if (groupCounts.size() == 1) {
|
||||
// Touching the notification shows the relevant group
|
||||
Intent i = new Intent(appContext, GroupActivity.class);
|
||||
@@ -425,15 +429,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_SOCIAL);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
if (showOnLockScreen)
|
||||
b.setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(GROUP_MESSAGE_NOTIFICATION_ID, b.build());
|
||||
@@ -474,21 +469,19 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
if (forumTotal == 0) {
|
||||
clearForumPostNotification();
|
||||
} else if (settings.getBoolean(PREF_NOTIFY_FORUM, true)) {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
BriarNotificationBuilder b =
|
||||
new BriarNotificationBuilder(appContext);
|
||||
b.setSmallIcon(R.drawable.notification_forum);
|
||||
b.setColor(ContextCompat.getColor(appContext,
|
||||
R.color.briar_primary));
|
||||
b.setColorRes(R.color.briar_primary);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getResources().getQuantityString(
|
||||
R.plurals.forum_post_notification_text, forumTotal,
|
||||
forumTotal));
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
b.setNumber(forumTotal);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
||||
playSound(b);
|
||||
if (forumCounts.size() == 1) {
|
||||
// Touching the notification shows the relevant forum
|
||||
Intent i = new Intent(appContext, ForumActivity.class);
|
||||
@@ -512,15 +505,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_SOCIAL);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
if (showOnLockScreen)
|
||||
b.setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(FORUM_POST_NOTIFICATION_ID, b.build());
|
||||
@@ -561,21 +545,19 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
if (blogTotal == 0) {
|
||||
clearBlogPostNotification();
|
||||
} else if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
BriarNotificationBuilder b =
|
||||
new BriarNotificationBuilder(appContext);
|
||||
b.setSmallIcon(R.drawable.notification_blog);
|
||||
b.setColor(ContextCompat.getColor(appContext,
|
||||
R.color.briar_primary));
|
||||
b.setColorRes(R.color.briar_primary);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getResources().getQuantityString(
|
||||
R.plurals.blog_post_notification_text, blogTotal,
|
||||
blogTotal));
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
b.setNumber(blogTotal);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
||||
playSound(b);
|
||||
// Touching the notification shows the combined blog feed
|
||||
Intent i = new Intent(appContext, NavDrawerActivity.class);
|
||||
i.putExtra(INTENT_BLOGS, true);
|
||||
@@ -585,15 +567,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
t.addParentStack(NavDrawerActivity.class);
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_SOCIAL);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
if (showOnLockScreen)
|
||||
b.setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(BLOG_POST_NOTIFICATION_ID, b.build());
|
||||
@@ -623,20 +597,17 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
@UiThread
|
||||
private void updateIntroductionNotification() {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
BriarNotificationBuilder b = new BriarNotificationBuilder(appContext);
|
||||
b.setSmallIcon(R.drawable.notification_introduction);
|
||||
b.setColor(ContextCompat.getColor(appContext, R.color.briar_primary));
|
||||
b.setColorRes(R.color.briar_primary);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getResources().getQuantityString(
|
||||
R.plurals.introduction_notification_text, introductionTotal,
|
||||
introductionTotal));
|
||||
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
b.setLockscreenVisibility(CATEGORY_MESSAGE, showOnLockScreen);
|
||||
playSound(b);
|
||||
// Touching the notification shows the contact list
|
||||
Intent i = new Intent(appContext, NavDrawerActivity.class);
|
||||
i.putExtra(INTENT_CONTACTS, true);
|
||||
@@ -646,15 +617,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
t.addParentStack(NavDrawerActivity.class);
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
b.setCategory(CATEGORY_MESSAGE);
|
||||
boolean showOnLockScreen =
|
||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
||||
if (showOnLockScreen)
|
||||
b.setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
b.setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(INTRODUCTION_SUCCESS_NOTIFICATION_ID, b.build());
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.briarproject.briar.android.keyagreement;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class CameraException extends IOException {
|
||||
|
||||
CameraException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
CameraException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import android.hardware.Camera.CameraInfo;
|
||||
import android.hardware.Camera.Parameters;
|
||||
import android.hardware.Camera.Size;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.Surface;
|
||||
@@ -43,6 +44,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(CameraView.class.getName());
|
||||
|
||||
@Nullable
|
||||
private Camera camera = null;
|
||||
private PreviewConsumer previewConsumer = null;
|
||||
private Surface surface = null;
|
||||
@@ -82,14 +84,14 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void start() {
|
||||
public void start() throws CameraException {
|
||||
LOG.info("Opening camera");
|
||||
try {
|
||||
LOG.info("Opening camera");
|
||||
camera = Camera.open();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error opening camera", e);
|
||||
return;
|
||||
throw new CameraException(e);
|
||||
}
|
||||
if (camera == null) throw new CameraException("No back-facing camera");
|
||||
setDisplayOrientation(0);
|
||||
// Use barcode scene mode if it's available
|
||||
Parameters params = camera.getParameters();
|
||||
@@ -113,60 +115,81 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void stop() {
|
||||
public void stop() throws CameraException {
|
||||
if (camera == null) return;
|
||||
stopPreview();
|
||||
LOG.info("Releasing camera");
|
||||
try {
|
||||
LOG.info("Releasing camera");
|
||||
camera.release();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error releasing camera", e);
|
||||
throw new CameraException(e);
|
||||
}
|
||||
camera = null;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void startPreview(SurfaceHolder holder) {
|
||||
private void startPreview(SurfaceHolder holder) throws CameraException {
|
||||
LOG.info("Starting preview");
|
||||
if (camera == null) throw new CameraException("Camera is null");
|
||||
try {
|
||||
camera.setPreviewDisplay(holder);
|
||||
camera.startPreview();
|
||||
previewStarted = true;
|
||||
startConsumer();
|
||||
} catch (IOException | RuntimeException e) {
|
||||
LOG.log(WARNING, "Error starting camera preview", e);
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void stopPreview() {
|
||||
private void stopPreview() throws CameraException {
|
||||
LOG.info("Stopping preview");
|
||||
if (camera == null) throw new CameraException("Camera is null");
|
||||
try {
|
||||
stopConsumer();
|
||||
camera.stopPreview();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error stopping camera preview", e);
|
||||
throw new CameraException(e);
|
||||
}
|
||||
previewStarted = false;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void startConsumer() {
|
||||
if (autoFocus) camera.autoFocus(this);
|
||||
private void startConsumer() throws CameraException {
|
||||
if (camera == null) throw new CameraException("Camera is null");
|
||||
if (autoFocus) {
|
||||
try {
|
||||
camera.autoFocus(this);
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
previewConsumer.start(camera);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void stopConsumer() {
|
||||
if (autoFocus) camera.cancelAutoFocus();
|
||||
private void stopConsumer() throws CameraException {
|
||||
if (camera == null) throw new CameraException("Camera is null");
|
||||
if (autoFocus) {
|
||||
try {
|
||||
camera.cancelAutoFocus();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
previewConsumer.stop();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void setDisplayOrientation(int rotationDegrees) {
|
||||
private void setDisplayOrientation(int rotationDegrees)
|
||||
throws CameraException {
|
||||
int orientation;
|
||||
CameraInfo info = new CameraInfo();
|
||||
Camera.getCameraInfo(0, info);
|
||||
try {
|
||||
Camera.getCameraInfo(0, info);
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
if (info.facing == CAMERA_FACING_FRONT) {
|
||||
orientation = (info.orientation + rotationDegrees) % 360;
|
||||
orientation = (360 - orientation) % 360;
|
||||
@@ -175,49 +198,70 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
if (LOG.isLoggable(INFO))
|
||||
LOG.info("Display orientation " + orientation + " degrees");
|
||||
if (camera == null) throw new CameraException("Camera is null");
|
||||
try {
|
||||
camera.setDisplayOrientation(orientation);
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error setting display orientation", e);
|
||||
throw new CameraException(e);
|
||||
}
|
||||
displayOrientation = orientation;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private Parameters setSceneMode(Camera camera, Parameters params) {
|
||||
private Parameters setSceneMode(Camera camera, Parameters params)
|
||||
throws CameraException {
|
||||
List<String> sceneModes = params.getSupportedSceneModes();
|
||||
if (sceneModes == null) return params;
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Scene modes: " + sceneModes);
|
||||
if (sceneModes.contains(SCENE_MODE_BARCODE)) {
|
||||
params.setSceneMode(SCENE_MODE_BARCODE);
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
try {
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private Parameters disableFlash(Camera camera, Parameters params) {
|
||||
private Parameters disableFlash(Camera camera, Parameters params)
|
||||
throws CameraException {
|
||||
params.setFlashMode(FLASH_MODE_OFF);
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
try {
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private Parameters disableSceneMode(Camera camera, Parameters params) {
|
||||
private Parameters disableSceneMode(Camera camera, Parameters params)
|
||||
throws CameraException {
|
||||
params.setSceneMode(SCENE_MODE_AUTO);
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
try {
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private Parameters setBestParameters(Camera camera, Parameters params) {
|
||||
private Parameters setBestParameters(Camera camera, Parameters params)
|
||||
throws CameraException {
|
||||
setVideoStabilisation(params);
|
||||
setFocusMode(params);
|
||||
params.setFlashMode(FLASH_MODE_OFF);
|
||||
setPreviewSize(params);
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
try {
|
||||
camera.setParameters(params);
|
||||
return camera.getParameters();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -286,9 +330,15 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void logCameraParameters() {
|
||||
private void logCameraParameters() throws CameraException {
|
||||
if (camera == null) throw new AssertionError();
|
||||
if (LOG.isLoggable(INFO)) {
|
||||
Parameters params = camera.getParameters();
|
||||
Parameters params;
|
||||
try {
|
||||
params = camera.getParameters();
|
||||
} catch (RuntimeException e) {
|
||||
throw new CameraException(e);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= 15) {
|
||||
LOG.info("Video stabilisation enabled: "
|
||||
+ params.getVideoStabilization());
|
||||
@@ -306,13 +356,18 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
surfaceCreatedUi(holder);
|
||||
try {
|
||||
surfaceCreatedUi(holder);
|
||||
} catch (CameraException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void surfaceCreatedUi(SurfaceHolder holder) {
|
||||
private void surfaceCreatedUi(SurfaceHolder holder) throws CameraException {
|
||||
LOG.info("Surface created");
|
||||
if (surface != null && surface != holder.getSurface()) {
|
||||
LOG.info("Releasing old surface");
|
||||
@@ -329,13 +384,19 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
surfaceChangedUi(holder, w, h);
|
||||
try {
|
||||
surfaceChangedUi(holder, w, h);
|
||||
} catch (CameraException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void surfaceChangedUi(SurfaceHolder holder, int w, int h) {
|
||||
private void surfaceChangedUi(SurfaceHolder holder, int w, int h)
|
||||
throws CameraException {
|
||||
if (LOG.isLoggable(INFO)) LOG.info("Surface changed: " + w + "x" + h);
|
||||
if (surface != null && surface != holder.getSurface()) {
|
||||
LOG.info("Releasing old surface");
|
||||
@@ -352,7 +413,7 @@ public class CameraView extends SurfaceView implements SurfaceHolder.Callback,
|
||||
camera.setParameters(params);
|
||||
logCameraParameters();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error setting preview size", e);
|
||||
throw new CameraException(e);
|
||||
}
|
||||
startPreview(holder);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@MethodsNotNullByDefault
|
||||
@@ -60,8 +61,12 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
@Override
|
||||
public void onPreviewFrame(byte[] data, Camera camera) {
|
||||
if (camera == this.camera) {
|
||||
Size size = camera.getParameters().getPreviewSize();
|
||||
new DecoderTask(data, size.width, size.height).execute();
|
||||
try {
|
||||
Size size = camera.getParameters().getPreviewSize();
|
||||
new DecoderTask(data, size.width, size.height).execute();
|
||||
} catch (RuntimeException e) {
|
||||
LOG.log(WARNING, "Error getting camera parameters.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +75,7 @@ class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
|
||||
private final byte[] data;
|
||||
private final int width, height;
|
||||
|
||||
DecoderTask(byte[] data, int width, int height) {
|
||||
private DecoderTask(byte[] data, int width, int height) {
|
||||
this.data = data;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
@@ -56,6 +56,7 @@ import static android.view.View.INVISIBLE;
|
||||
import static android.view.View.VISIBLE;
|
||||
import static android.widget.Toast.LENGTH_LONG;
|
||||
import static java.util.logging.Level.INFO;
|
||||
import static java.util.logging.Level.WARNING;
|
||||
|
||||
@MethodsNotNullByDefault
|
||||
@ParametersNotNullByDefault
|
||||
@@ -143,6 +144,12 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
|
||||
try {
|
||||
cameraView.start();
|
||||
} catch (CameraException e) {
|
||||
logCameraExceptionAndFinish(e);
|
||||
}
|
||||
|
||||
// Listen for changes to the Bluetooth state
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_STATE_CHANGED);
|
||||
@@ -162,7 +169,6 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
} else {
|
||||
startListening();
|
||||
}
|
||||
cameraView.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -170,7 +176,19 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
super.onStop();
|
||||
stopListening();
|
||||
if (receiver != null) getActivity().unregisterReceiver(receiver);
|
||||
cameraView.stop();
|
||||
try {
|
||||
cameraView.stop();
|
||||
} catch (CameraException e) {
|
||||
logCameraExceptionAndFinish(e);
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void logCameraExceptionAndFinish(CameraException e) {
|
||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||
Toast.makeText(getActivity(), R.string.camera_error,
|
||||
LENGTH_LONG).show();
|
||||
finish();
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -218,7 +236,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
||||
statusView.setVisibility(VISIBLE);
|
||||
status.setText(R.string.connecting_to_device);
|
||||
task.connectAndRunProtocol(remotePayload);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException | IllegalArgumentException e) {
|
||||
// TODO show failure
|
||||
Toast.makeText(getActivity(), R.string.qr_code_invalid,
|
||||
LENGTH_LONG).show();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package org.briarproject.briar.android.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorRes;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v7.app.NotificationCompat;
|
||||
|
||||
import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
|
||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE;
|
||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
|
||||
|
||||
|
||||
public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
||||
|
||||
public BriarNotificationBuilder(Context context) {
|
||||
super(context);
|
||||
setAutoCancel(true);
|
||||
}
|
||||
|
||||
public BriarNotificationBuilder setColorRes(@ColorRes int res) {
|
||||
setColor(ContextCompat.getColor(mContext, res));
|
||||
return this;
|
||||
}
|
||||
|
||||
public BriarNotificationBuilder setLockscreenVisibility(String category,
|
||||
boolean show) {
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
setCategory(category);
|
||||
if (show)
|
||||
setVisibility(VISIBILITY_PRIVATE);
|
||||
else
|
||||
setVisibility(VISIBILITY_SECRET);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -122,7 +122,7 @@
|
||||
<string name="introduction_activity_title">Seleccionar contacto</string>
|
||||
<string name="introduction_message_title">Presentar a dos contactos</string>
|
||||
<string name="introduction_message_hint">Añade un mensaje (opcional)</string>
|
||||
<string name="introduction_button">Presentarle a</string>
|
||||
<string name="introduction_button">Presentar contactos</string>
|
||||
<string name="introduction_sent">Tu presentación se ha mandado.</string>
|
||||
<string name="introduction_error">Ocurrió un error realizando la presentación.</string>
|
||||
<string name="introduction_response_error">Error al responder a la presentación</string>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string translatable="false" name="app_name">Briar Beta</string>
|
||||
|
||||
<!-- Setup -->
|
||||
<string name="setup_title">Briar Setup</string>
|
||||
@@ -121,6 +120,7 @@
|
||||
<string name="contact_already_exists">Contact %s already exists</string>
|
||||
<string name="contact_exchange_failed">Contact exchange failed</string>
|
||||
<string name="qr_code_invalid">The QR code is invalid</string>
|
||||
<string name="camera_error">Camera error</string>
|
||||
<string name="connecting_to_device">Connecting to device\u2026</string>
|
||||
<string name="authenticating_with_device">Authenticating with device\u2026</string>
|
||||
<string name="connection_aborted_local">Connection aborted by us! This could mean that someone is trying to interfere with your connection</string>
|
||||
|
||||
@@ -291,8 +291,12 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
|
||||
* This method is called periodically from a background service.
|
||||
* It fetches all available feeds and posts new entries to the respective
|
||||
* blog.
|
||||
*
|
||||
* We can not do this within one database {@link Transaction},
|
||||
* because fetching can take a long time
|
||||
* and we can not block the database that long.
|
||||
*/
|
||||
private void fetchFeeds() {
|
||||
void fetchFeeds() {
|
||||
LOG.info("Updating RSS feeds...");
|
||||
|
||||
// Get current feeds
|
||||
@@ -313,12 +317,15 @@ class FeedManagerImpl implements FeedManager, Client, EventListener,
|
||||
} catch (FeedException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
newFeeds.add(feed);
|
||||
} catch (IOException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
newFeeds.add(feed);
|
||||
} catch (DbException e) {
|
||||
if (LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
newFeeds.add(feed);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package org.briarproject.briar.feed;
|
||||
|
||||
import org.briarproject.bramble.api.client.ClientHelper;
|
||||
import org.briarproject.bramble.api.client.ContactGroupFactory;
|
||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||
import org.briarproject.bramble.api.data.BdfEntry;
|
||||
import org.briarproject.bramble.api.data.BdfList;
|
||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||
import org.briarproject.bramble.api.db.Transaction;
|
||||
import org.briarproject.bramble.api.identity.AuthorId;
|
||||
import org.briarproject.bramble.api.identity.LocalAuthor;
|
||||
import org.briarproject.bramble.api.sync.Group;
|
||||
import org.briarproject.bramble.api.sync.GroupId;
|
||||
import org.briarproject.bramble.api.system.Clock;
|
||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||
import org.briarproject.bramble.test.ImmediateExecutor;
|
||||
import org.briarproject.briar.api.blog.Blog;
|
||||
import org.briarproject.briar.api.blog.BlogManager;
|
||||
import org.briarproject.briar.api.blog.BlogPostFactory;
|
||||
import org.briarproject.briar.api.feed.Feed;
|
||||
import org.jmock.Expectations;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
import okhttp3.Dns;
|
||||
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||
import static org.briarproject.bramble.test.TestUtils.getRandomId;
|
||||
import static org.briarproject.briar.api.feed.FeedConstants.KEY_FEEDS;
|
||||
import static org.briarproject.briar.api.feed.FeedManager.CLIENT_ID;
|
||||
|
||||
public class FeedManagerImplTest extends BrambleMockTestCase {
|
||||
|
||||
private final ScheduledExecutorService scheduler =
|
||||
context.mock(ScheduledExecutorService.class);
|
||||
private final Executor ioExecutor = new ImmediateExecutor();
|
||||
private final DatabaseComponent db = context.mock(DatabaseComponent.class);
|
||||
private final ContactGroupFactory contactGroupFactory =
|
||||
context.mock(ContactGroupFactory.class);
|
||||
private final ClientHelper clientHelper = context.mock(ClientHelper.class);
|
||||
private final BlogManager blogManager = context.mock(BlogManager.class);
|
||||
private final BlogPostFactory blogPostFactory =
|
||||
context.mock(BlogPostFactory.class);
|
||||
private final FeedFactory feedFactory = context.mock(FeedFactory.class);
|
||||
private final Clock clock = context.mock(Clock.class);
|
||||
private final Dns noDnsLookups = context.mock(Dns.class);
|
||||
|
||||
private final GroupId localGroupId = new GroupId(getRandomId());
|
||||
private final Group localGroup =
|
||||
new Group(localGroupId, CLIENT_ID, getRandomBytes(42));
|
||||
private final GroupId blogGroupId = new GroupId(getRandomId());
|
||||
private final Group blogGroup =
|
||||
new Group(blogGroupId, BlogManager.CLIENT_ID, getRandomBytes(42));
|
||||
private final AuthorId authorId = new AuthorId(getRandomId());
|
||||
private final LocalAuthor localAuthor =
|
||||
new LocalAuthor(authorId, "author", getRandomBytes(2),
|
||||
getRandomBytes(2), 0);
|
||||
private final Blog blog = new Blog(blogGroup, localAuthor, true);
|
||||
private final Feed feed =
|
||||
new Feed("http://example.org", blog, localAuthor, 0);
|
||||
private final BdfDictionary feedDict = new BdfDictionary();
|
||||
|
||||
private final FeedManagerImpl feedManager =
|
||||
new FeedManagerImpl(scheduler, ioExecutor, db, contactGroupFactory,
|
||||
clientHelper, blogManager, blogPostFactory, feedFactory,
|
||||
SocketFactory.getDefault(), clock, noDnsLookups);
|
||||
|
||||
@Test
|
||||
public void testEmptyFetchFeed() throws Exception {
|
||||
BdfList feedList = new BdfList();
|
||||
expectGetFeeds(feedList);
|
||||
expectStoreFeed(feedList);
|
||||
feedManager.fetchFeeds();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFetchFeedIoException() throws Exception {
|
||||
final BdfDictionary feedDict= new BdfDictionary();
|
||||
BdfList feedList = BdfList.of(feedDict);
|
||||
|
||||
expectGetFeeds(feedList);
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(noDnsLookups).lookup("example.org");
|
||||
will(throwException(new UnknownHostException()));
|
||||
}});
|
||||
expectStoreFeed(feedList);
|
||||
|
||||
feedManager.fetchFeeds();
|
||||
}
|
||||
|
||||
private void expectGetLocalGroup() {
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(contactGroupFactory).createLocalGroup(CLIENT_ID);
|
||||
will(returnValue(localGroup));
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectGetFeeds(final BdfList feedList) throws Exception {
|
||||
final Transaction txn = new Transaction(null, true);
|
||||
final BdfDictionary feedsDict =
|
||||
BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
|
||||
expectGetLocalGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(db).startTransaction(true);
|
||||
will(returnValue(txn));
|
||||
oneOf(clientHelper).getGroupMetadataAsDictionary(txn, localGroupId);
|
||||
will(returnValue(feedsDict));
|
||||
if (feedList.size() == 1) {
|
||||
oneOf(feedFactory).createFeed(feedDict);
|
||||
will(returnValue(feed));
|
||||
}
|
||||
oneOf(db).commitTransaction(txn);
|
||||
oneOf(db).endTransaction(txn);
|
||||
}});
|
||||
}
|
||||
|
||||
private void expectStoreFeed(final BdfList feedList) throws Exception {
|
||||
final BdfDictionary feedDict =
|
||||
BdfDictionary.of(new BdfEntry(KEY_FEEDS, feedList));
|
||||
expectGetLocalGroup();
|
||||
context.checking(new Expectations() {{
|
||||
oneOf(clientHelper).mergeGroupMetadata(localGroupId, feedDict);
|
||||
if (feedList.size() == 1) {
|
||||
oneOf(feedFactory).feedToBdfDictionary(feed);
|
||||
will(returnValue(feedList.getDictionary(0)));
|
||||
}
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user