Show whether identities are anonymous, unknown, or verified.
Dev task #52. Known but unverified identities are also supported, but currently unused. These will be used in future for contacts who've been introduced but not verified face to face.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
briar-android/res/drawable-hdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
briar-android/res/drawable-hdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 1009 B |
|
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 682 B |
|
Before Width: | Height: | Size: 605 B After Width: | Height: | Size: 484 B |
BIN
briar-android/res/drawable-mdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 362 B |
BIN
briar-android/res/drawable-mdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 708 B |
BIN
briar-android/res/drawable-mdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 713 B |
BIN
briar-android/res/drawable-mdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 531 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
briar-android/res/drawable-xhdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
@@ -4,7 +4,6 @@
|
|||||||
<color name="content_background">#FFFFFF</color>
|
<color name="content_background">#FFFFFF</color>
|
||||||
<color name="unread_background">#FFFFFF</color>
|
<color name="unread_background">#FFFFFF</color>
|
||||||
<color name="horizontal_border">#CCCCCC</color>
|
<color name="horizontal_border">#CCCCCC</color>
|
||||||
<color name="anonymous_author">#AAAAAA</color>
|
|
||||||
<color name="no_posts">#AAAAAA</color>
|
<color name="no_posts">#AAAAAA</color>
|
||||||
<color name="no_messages">#AAAAAA</color>
|
<color name="no_messages">#AAAAAA</color>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -3,10 +3,12 @@ package org.briarproject.android.contact;
|
|||||||
import static android.widget.LinearLayout.HORIZONTAL;
|
import static android.widget.LinearLayout.HORIZONTAL;
|
||||||
import static java.text.DateFormat.SHORT;
|
import static java.text.DateFormat.SHORT;
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||||
|
import static org.briarproject.api.Author.Status.VERIFIED;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.util.AuthorView;
|
||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.android.util.LayoutUtils;
|
||||||
import org.briarproject.api.db.MessageHeader;
|
import org.briarproject.api.db.MessageHeader;
|
||||||
|
|
||||||
@@ -41,14 +43,10 @@ class ConversationAdapter extends ArrayAdapter<ConversationItem> {
|
|||||||
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextView name = new TextView(ctx);
|
AuthorView authorView = new AuthorView(ctx);
|
||||||
// Give me all the unused width
|
authorView.setLayoutParams(WRAP_WRAP_1);
|
||||||
name.setLayoutParams(WRAP_WRAP_1);
|
authorView.init(header.getAuthor().getName(), VERIFIED);
|
||||||
name.setTextSize(18);
|
layout.addView(authorView);
|
||||||
name.setMaxLines(1);
|
|
||||||
name.setPadding(pad, pad, pad, pad);
|
|
||||||
name.setText(header.getAuthor().getName());
|
|
||||||
layout.addView(name);
|
|
||||||
|
|
||||||
TextView date = new TextView(ctx);
|
TextView date = new TextView(ctx);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ 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;
|
||||||
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
||||||
|
import static org.briarproject.api.Author.Status.VERIFIED;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
@@ -18,8 +19,9 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.util.HorizontalBorder;
|
import org.briarproject.android.util.AuthorView;
|
||||||
import org.briarproject.android.util.ElasticHorizontalSpace;
|
import org.briarproject.android.util.ElasticHorizontalSpace;
|
||||||
|
import org.briarproject.android.util.HorizontalBorder;
|
||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.android.util.LayoutUtils;
|
||||||
import org.briarproject.api.AuthorId;
|
import org.briarproject.api.AuthorId;
|
||||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||||
@@ -116,16 +118,12 @@ implements OnClickListener {
|
|||||||
header.setOrientation(HORIZONTAL);
|
header.setOrientation(HORIZONTAL);
|
||||||
header.setGravity(CENTER_VERTICAL);
|
header.setGravity(CENTER_VERTICAL);
|
||||||
|
|
||||||
int pad = LayoutUtils.getPadding(this);
|
AuthorView author = new AuthorView(this);
|
||||||
|
author.setLayoutParams(WRAP_WRAP_1);
|
||||||
|
author.init(authorName, VERIFIED);
|
||||||
|
header.addView(author);
|
||||||
|
|
||||||
TextView name = new TextView(this);
|
int pad = LayoutUtils.getPadding(this);
|
||||||
// Give me all the unused width
|
|
||||||
name.setLayoutParams(WRAP_WRAP_1);
|
|
||||||
name.setTextSize(18);
|
|
||||||
name.setMaxLines(1);
|
|
||||||
name.setPadding(pad, pad, pad, pad);
|
|
||||||
name.setText(authorName);
|
|
||||||
header.addView(name);
|
|
||||||
|
|
||||||
TextView date = new TextView(this);
|
TextView date = new TextView(this);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ OnClickListener, OnItemClickListener {
|
|||||||
i.putExtra("briar.AUTHOR_ID", author.getId().getBytes());
|
i.putExtra("briar.AUTHOR_ID", author.getId().getBytes());
|
||||||
i.putExtra("briar.AUTHOR_NAME", author.getName());
|
i.putExtra("briar.AUTHOR_NAME", author.getName());
|
||||||
}
|
}
|
||||||
|
i.putExtra("briar.AUTHOR_STATUS", item.getAuthorStatus().name());
|
||||||
i.putExtra("briar.CONTENT_TYPE", item.getContentType());
|
i.putExtra("briar.CONTENT_TYPE", item.getContentType());
|
||||||
i.putExtra("briar.TIMESTAMP", item.getTimestamp());
|
i.putExtra("briar.TIMESTAMP", item.getTimestamp());
|
||||||
startActivityForResult(i, position);
|
startActivityForResult(i, position);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP_1;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.android.util.AuthorView;
|
||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.android.util.LayoutUtils;
|
||||||
import org.briarproject.api.Author;
|
import org.briarproject.api.Author;
|
||||||
import org.briarproject.api.db.MessageHeader;
|
import org.briarproject.api.db.MessageHeader;
|
||||||
@@ -32,34 +33,27 @@ class GroupAdapter extends ArrayAdapter<MessageHeader> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
MessageHeader item = getItem(position);
|
MessageHeader header = getItem(position);
|
||||||
Context ctx = getContext();
|
Context ctx = getContext();
|
||||||
Resources res = ctx.getResources();
|
|
||||||
|
|
||||||
LinearLayout layout = new LinearLayout(ctx);
|
LinearLayout layout = new LinearLayout(ctx);
|
||||||
layout.setOrientation(HORIZONTAL);
|
layout.setOrientation(HORIZONTAL);
|
||||||
if(!item.isRead())
|
if(!header.isRead()) {
|
||||||
|
Resources res = ctx.getResources();
|
||||||
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
layout.setBackgroundColor(res.getColor(R.color.unread_background));
|
||||||
|
|
||||||
TextView name = new TextView(ctx);
|
|
||||||
// Give me all the unused width
|
|
||||||
name.setLayoutParams(WRAP_WRAP_1);
|
|
||||||
name.setTextSize(18);
|
|
||||||
name.setMaxLines(1);
|
|
||||||
name.setPadding(pad, pad, pad, pad);
|
|
||||||
Author author = item.getAuthor();
|
|
||||||
if(author == null) {
|
|
||||||
name.setTextColor(res.getColor(R.color.anonymous_author));
|
|
||||||
name.setText(R.string.anonymous);
|
|
||||||
} else {
|
|
||||||
name.setText(author.getName());
|
|
||||||
}
|
}
|
||||||
layout.addView(name);
|
|
||||||
|
AuthorView authorView = new AuthorView(ctx);
|
||||||
|
authorView.setLayoutParams(WRAP_WRAP_1);
|
||||||
|
Author author = header.getAuthor();
|
||||||
|
if(author == null) authorView.init(null, header.getAuthorStatus());
|
||||||
|
else authorView.init(author.getName(), header.getAuthorStatus());
|
||||||
|
layout.addView(authorView);
|
||||||
|
|
||||||
TextView date = new TextView(ctx);
|
TextView date = new TextView(ctx);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
date.setPadding(pad, pad, pad, pad);
|
date.setPadding(0, pad, pad, pad);
|
||||||
long then = item.getTimestamp(), now = System.currentTimeMillis();
|
long then = header.getTimestamp(), now = System.currentTimeMillis();
|
||||||
date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
|
date.setText(DateUtils.formatSameDayTime(then, now, SHORT, SHORT));
|
||||||
layout.addView(date);
|
layout.addView(date);
|
||||||
|
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.briarproject.R;
|
import org.briarproject.R;
|
||||||
import org.briarproject.android.util.HorizontalBorder;
|
import org.briarproject.android.util.AuthorView;
|
||||||
import org.briarproject.android.util.ElasticHorizontalSpace;
|
import org.briarproject.android.util.ElasticHorizontalSpace;
|
||||||
|
import org.briarproject.android.util.HorizontalBorder;
|
||||||
import org.briarproject.android.util.LayoutUtils;
|
import org.briarproject.android.util.LayoutUtils;
|
||||||
|
import org.briarproject.api.Author;
|
||||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||||
import org.briarproject.api.db.DatabaseComponent;
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -83,6 +85,9 @@ implements OnClickListener {
|
|||||||
timestamp = i.getLongExtra("briar.TIMESTAMP", -1);
|
timestamp = i.getLongExtra("briar.TIMESTAMP", -1);
|
||||||
if(timestamp == -1) throw new IllegalStateException();
|
if(timestamp == -1) throw new IllegalStateException();
|
||||||
String authorName = i.getStringExtra("briar.AUTHOR_NAME");
|
String authorName = i.getStringExtra("briar.AUTHOR_NAME");
|
||||||
|
String s = i.getStringExtra("briar.AUTHOR_STATUS");
|
||||||
|
if(s == null) throw new IllegalStateException();
|
||||||
|
Author.Status authorStatus = Author.Status.valueOf(s);
|
||||||
|
|
||||||
if(state == null) {
|
if(state == null) {
|
||||||
read = false;
|
read = false;
|
||||||
@@ -109,21 +114,12 @@ implements OnClickListener {
|
|||||||
header.setOrientation(HORIZONTAL);
|
header.setOrientation(HORIZONTAL);
|
||||||
header.setGravity(CENTER_VERTICAL);
|
header.setGravity(CENTER_VERTICAL);
|
||||||
|
|
||||||
int pad = LayoutUtils.getPadding(this);
|
AuthorView author = new AuthorView(this);
|
||||||
|
author.setLayoutParams(WRAP_WRAP_1);
|
||||||
|
author.init(authorName, authorStatus);
|
||||||
|
header.addView(author);
|
||||||
|
|
||||||
TextView name = new TextView(this);
|
int pad = LayoutUtils.getPadding(this);
|
||||||
// Give me all the unused width
|
|
||||||
name.setLayoutParams(WRAP_WRAP_1);
|
|
||||||
name.setTextSize(18);
|
|
||||||
name.setMaxLines(1);
|
|
||||||
name.setPadding(pad, pad, pad, pad);
|
|
||||||
if(authorName == null) {
|
|
||||||
name.setTextColor(res.getColor(R.color.anonymous_author));
|
|
||||||
name.setText(R.string.anonymous);
|
|
||||||
} else {
|
|
||||||
name.setText(authorName);
|
|
||||||
}
|
|
||||||
header.addView(name);
|
|
||||||
|
|
||||||
TextView date = new TextView(this);
|
TextView date = new TextView(this);
|
||||||
date.setTextSize(14);
|
date.setTextSize(14);
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package org.briarproject.android.util;
|
||||||
|
|
||||||
|
import org.briarproject.R;
|
||||||
|
import org.briarproject.api.Author;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class AuthorView extends LinearLayout {
|
||||||
|
|
||||||
|
public AuthorView(Context ctx) {
|
||||||
|
super(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(String name, Author.Status status) {
|
||||||
|
Context ctx = getContext();
|
||||||
|
int pad = LayoutUtils.getPadding(ctx);
|
||||||
|
setOrientation(VERTICAL);
|
||||||
|
TextView nameView = new TextView(ctx);
|
||||||
|
// Give me all the unused width
|
||||||
|
nameView.setTextSize(18);
|
||||||
|
nameView.setMaxLines(1);
|
||||||
|
nameView.setPadding(pad, pad, pad, pad);
|
||||||
|
if(name == null) nameView.setText(R.string.anonymous);
|
||||||
|
else nameView.setText(name);
|
||||||
|
addView(nameView);
|
||||||
|
LinearLayout statusLayout = new LinearLayout(ctx);
|
||||||
|
statusLayout.setOrientation(HORIZONTAL);
|
||||||
|
ImageView statusView = new ImageView(ctx);
|
||||||
|
statusView.setPadding(pad, 0, pad, pad);
|
||||||
|
switch(status) {
|
||||||
|
case ANONYMOUS:
|
||||||
|
statusView.setImageResource(R.drawable.identity_anonymous);
|
||||||
|
break;
|
||||||
|
case UNKNOWN:
|
||||||
|
statusView.setImageResource(R.drawable.identity_unknown);
|
||||||
|
break;
|
||||||
|
case UNVERIFIED:
|
||||||
|
statusView.setImageResource(R.drawable.identity_unverified);
|
||||||
|
break;
|
||||||
|
case VERIFIED:
|
||||||
|
statusView.setImageResource(R.drawable.identity_verified);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
statusLayout.addView(statusView);
|
||||||
|
statusLayout.addView(new ElasticHorizontalSpace(ctx));
|
||||||
|
addView(statusLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import java.io.UnsupportedEncodingException;
|
|||||||
/** A pseudonym for a user. */
|
/** A pseudonym for a user. */
|
||||||
public class Author {
|
public class Author {
|
||||||
|
|
||||||
|
public enum Status { ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED };
|
||||||
|
|
||||||
private final AuthorId id;
|
private final AuthorId id;
|
||||||
private final String name;
|
private final String name;
|
||||||
private final byte[] publicKey;
|
private final byte[] publicKey;
|
||||||
|
|||||||
@@ -9,16 +9,19 @@ public class MessageHeader {
|
|||||||
private final MessageId id, parent;
|
private final MessageId id, parent;
|
||||||
private final GroupId groupId;
|
private final GroupId groupId;
|
||||||
private final Author author;
|
private final Author author;
|
||||||
|
private final Author.Status authorStatus;
|
||||||
private final String contentType;
|
private final String contentType;
|
||||||
private final long timestamp;
|
private final long timestamp;
|
||||||
private final boolean read;
|
private final boolean read;
|
||||||
|
|
||||||
public MessageHeader(MessageId id, MessageId parent, GroupId groupId,
|
public MessageHeader(MessageId id, MessageId parent, GroupId groupId,
|
||||||
Author author, String contentType, long timestamp, boolean read) {
|
Author author, Author.Status authorStatus, String contentType,
|
||||||
|
long timestamp, boolean read) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.groupId = groupId;
|
this.groupId = groupId;
|
||||||
this.author = author;
|
this.author = author;
|
||||||
|
this.authorStatus = authorStatus;
|
||||||
this.contentType = contentType;
|
this.contentType = contentType;
|
||||||
this.timestamp = timestamp;
|
this.timestamp = timestamp;
|
||||||
this.read = read;
|
this.read = read;
|
||||||
@@ -51,6 +54,11 @@ public class MessageHeader {
|
|||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the status of the message's author. */
|
||||||
|
public Author.Status getAuthorStatus() {
|
||||||
|
return authorStatus;
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the message's content type. */
|
/** Returns the message's content type. */
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return contentType;
|
return contentType;
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import static java.sql.Types.BINARY;
|
|||||||
import static java.sql.Types.VARCHAR;
|
import static java.sql.Types.VARCHAR;
|
||||||
import static java.util.logging.Level.INFO;
|
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.api.Author.Status.ANONYMOUS;
|
||||||
|
import static org.briarproject.api.Author.Status.UNKNOWN;
|
||||||
|
import static org.briarproject.api.Author.Status.VERIFIED;
|
||||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_SUBSCRIPTIONS;
|
import static org.briarproject.api.messaging.MessagingConstants.MAX_SUBSCRIPTIONS;
|
||||||
import static org.briarproject.api.messaging.MessagingConstants.RETENTION_GRANULARITY;
|
import static org.briarproject.api.messaging.MessagingConstants.RETENTION_GRANULARITY;
|
||||||
import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
|
import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
|
||||||
@@ -1525,10 +1528,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
boolean read = rs.getBoolean(7);
|
boolean read = rs.getBoolean(7);
|
||||||
if(incoming) {
|
if(incoming) {
|
||||||
headers.add(new MessageHeader(id, parent, groupId,
|
headers.add(new MessageHeader(id, parent, groupId,
|
||||||
remoteAuthor, contentType, timestamp, read));
|
remoteAuthor, VERIFIED, contentType, timestamp,
|
||||||
|
read));
|
||||||
} else {
|
} else {
|
||||||
headers.add(new MessageHeader(id, parent, groupId,
|
headers.add(new MessageHeader(id, parent, groupId,
|
||||||
localAuthor, contentType, timestamp, read));
|
localAuthor, VERIFIED, contentType, timestamp,
|
||||||
|
read));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
@@ -1701,9 +1706,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
String sql = "SELECT messageId, parentId, authorId, authorName,"
|
String sql = "SELECT messageId, parentId, m.authorId, authorName,"
|
||||||
+ " authorKey, contentType, timestamp, read"
|
+ " authorKey, contentType, timestamp, read,"
|
||||||
+ " FROM messages"
|
+ " la.authorId IS NOT NULL, c.authorId IS NOT NULL"
|
||||||
|
+ " FROM messages AS m"
|
||||||
|
+ " LEFT OUTER JOIN localAuthors AS la"
|
||||||
|
+ " ON m.authorId = la.authorId"
|
||||||
|
+ " LEFT OUTER JOIN contacts AS c"
|
||||||
|
+ " ON m.authorId = c.authorId"
|
||||||
+ " WHERE groupId = ?";
|
+ " WHERE groupId = ?";
|
||||||
ps = txn.prepareStatement(sql);
|
ps = txn.prepareStatement(sql);
|
||||||
ps.setBytes(1, g.getBytes());
|
ps.setBytes(1, g.getBytes());
|
||||||
@@ -1726,8 +1736,14 @@ abstract class JdbcDatabase implements Database<Connection> {
|
|||||||
String contentType = rs.getString(6);
|
String contentType = rs.getString(6);
|
||||||
long timestamp = rs.getLong(7);
|
long timestamp = rs.getLong(7);
|
||||||
boolean read = rs.getBoolean(8);
|
boolean read = rs.getBoolean(8);
|
||||||
|
boolean isSelf = rs.getBoolean(9);
|
||||||
|
boolean isContact = rs.getBoolean(10);
|
||||||
|
Author.Status authorStatus;
|
||||||
|
if(author == null) authorStatus = ANONYMOUS;
|
||||||
|
else if(isSelf || isContact) authorStatus = VERIFIED;
|
||||||
|
else authorStatus = UNKNOWN;
|
||||||
headers.add(new MessageHeader(id, parent, g, author,
|
headers.add(new MessageHeader(id, parent, g, author,
|
||||||
contentType, timestamp, read));
|
authorStatus, contentType, timestamp, read));
|
||||||
}
|
}
|
||||||
rs.close();
|
rs.close();
|
||||||
ps.close();
|
ps.close();
|
||||||
|
|||||||
@@ -41,7 +41,6 @@ import org.briarproject.api.messaging.MessageId;
|
|||||||
import org.briarproject.api.transport.Endpoint;
|
import org.briarproject.api.transport.Endpoint;
|
||||||
import org.briarproject.api.transport.TemporarySecret;
|
import org.briarproject.api.transport.TemporarySecret;
|
||||||
import org.briarproject.system.SystemClock;
|
import org.briarproject.system.SystemClock;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -898,42 +897,26 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
// Mark one of the messages read
|
// Mark one of the messages read
|
||||||
db.setReadFlag(txn, messageId, true);
|
db.setReadFlag(txn, messageId, true);
|
||||||
|
|
||||||
// Retrieve the message headers
|
// Retrieve the message headers (order is undefined)
|
||||||
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
|
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
|
||||||
Iterator<MessageHeader> it = headers.iterator();
|
assertEquals(2, headers.size());
|
||||||
boolean messageFound = false, message1Found = false;
|
boolean firstFound = false, secondFound = false;
|
||||||
// First header (order is undefined)
|
for(MessageHeader header : headers) {
|
||||||
assertTrue(it.hasNext());
|
if(messageId.equals(header.getId())) {
|
||||||
MessageHeader header = it.next();
|
assertHeadersMatch(message, header);
|
||||||
if(messageId.equals(header.getId())) {
|
assertTrue(header.isRead());
|
||||||
assertHeadersMatch(message, header);
|
firstFound = true;
|
||||||
assertTrue(header.isRead());
|
} else if(messageId1.equals(header.getId())) {
|
||||||
messageFound = true;
|
assertHeadersMatch(message1, header);
|
||||||
} else if(messageId1.equals(header.getId())) {
|
assertFalse(header.isRead());
|
||||||
assertHeadersMatch(message1, header);
|
secondFound = true;
|
||||||
assertFalse(header.isRead());
|
} else {
|
||||||
message1Found = true;
|
fail();
|
||||||
} else {
|
}
|
||||||
fail();
|
|
||||||
}
|
}
|
||||||
// Second header
|
// Both the headers should have been retrieved
|
||||||
assertTrue(it.hasNext());
|
assertTrue(firstFound);
|
||||||
header = it.next();
|
assertTrue(secondFound);
|
||||||
if(messageId.equals(header.getId())) {
|
|
||||||
assertHeadersMatch(message, header);
|
|
||||||
assertTrue(header.isRead());
|
|
||||||
messageFound = true;
|
|
||||||
} else if(messageId1.equals(header.getId())) {
|
|
||||||
assertHeadersMatch(message1, header);
|
|
||||||
assertFalse(header.isRead());
|
|
||||||
message1Found = true;
|
|
||||||
} else {
|
|
||||||
fail();
|
|
||||||
}
|
|
||||||
// No more headers
|
|
||||||
assertFalse(it.hasNext());
|
|
||||||
assertTrue(messageFound);
|
|
||||||
assertTrue(message1Found);
|
|
||||||
|
|
||||||
db.commitTransaction(txn);
|
db.commitTransaction(txn);
|
||||||
db.close();
|
db.close();
|
||||||
@@ -950,6 +933,62 @@ public class H2DatabaseTest extends BriarTestCase {
|
|||||||
assertEquals(m.getTimestamp(), h.getTimestamp());
|
assertEquals(m.getTimestamp(), h.getTimestamp());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAuthorStatus() throws Exception {
|
||||||
|
Database<Connection> db = open(false);
|
||||||
|
Connection txn = db.startTransaction();
|
||||||
|
|
||||||
|
// Add a contact and subscribe to a group
|
||||||
|
db.addLocalAuthor(txn, localAuthor);
|
||||||
|
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
|
||||||
|
db.addGroup(txn, group);
|
||||||
|
|
||||||
|
// Store a message from the contact - status VERIFIED
|
||||||
|
db.addMessage(txn, message, false);
|
||||||
|
AuthorId authorId1 = new AuthorId(TestUtils.getRandomId());
|
||||||
|
// Store a message from an unknown author - status UNKNOWN
|
||||||
|
Author author1 = new Author(authorId1, "Bob",
|
||||||
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
|
MessageId messageId1 = new MessageId(TestUtils.getRandomId());
|
||||||
|
Message message1 = new TestMessage(messageId1, null, group, author1,
|
||||||
|
contentType, subject, timestamp, raw);
|
||||||
|
db.addMessage(txn, message1, false);
|
||||||
|
// Store an anonymous message - status ANONYMOUS
|
||||||
|
MessageId messageId2 = new MessageId(TestUtils.getRandomId());
|
||||||
|
Message message2 = new TestMessage(messageId2, null, group, null,
|
||||||
|
contentType, subject, timestamp, raw);
|
||||||
|
db.addMessage(txn, message2, false);
|
||||||
|
|
||||||
|
// Retrieve the message headers (order is undefined)
|
||||||
|
Collection<MessageHeader> headers = db.getMessageHeaders(txn, groupId);
|
||||||
|
assertEquals(3, headers.size());
|
||||||
|
boolean firstFound = false, secondFound = false, thirdFound = false;
|
||||||
|
for(MessageHeader header : headers) {
|
||||||
|
if(messageId.equals(header.getId())) {
|
||||||
|
assertHeadersMatch(message, header);
|
||||||
|
assertEquals(Author.Status.VERIFIED, header.getAuthorStatus());
|
||||||
|
firstFound = true;
|
||||||
|
} else if(messageId1.equals(header.getId())) {
|
||||||
|
assertHeadersMatch(message1, header);
|
||||||
|
assertEquals(Author.Status.UNKNOWN, header.getAuthorStatus());
|
||||||
|
secondFound = true;
|
||||||
|
} else if(messageId2.equals(header.getId())) {
|
||||||
|
assertHeadersMatch(message2, header);
|
||||||
|
assertEquals(Author.Status.ANONYMOUS, header.getAuthorStatus());
|
||||||
|
thirdFound = true;
|
||||||
|
} else {
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All of the headers should have been retrieved
|
||||||
|
assertTrue(firstFound);
|
||||||
|
assertTrue(secondFound);
|
||||||
|
assertTrue(thirdFound);
|
||||||
|
|
||||||
|
db.commitTransaction(txn);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadFlag() throws Exception {
|
public void testReadFlag() throws Exception {
|
||||||
Database<Connection> db = open(false);
|
Database<Connection> db = open(false);
|
||||||
|
|||||||