Compare commits

..

2 Commits

Author SHA1 Message Date
Santiago Torres
cef4c31e0b FIX: Addresses reviewer comments 2016-09-23 09:21:03 -04:00
Santiago Torres
62527a62c1 WIP: Replace session states in the Engine classes 2016-09-19 22:39:19 -04:00
751 changed files with 14207 additions and 32969 deletions

View File

@@ -31,8 +31,6 @@
</value>
</option>
<option name="RIGHT_MARGIN" value="100" />
<option name="JD_ALIGN_PARAM_COMMENTS" value="false" />
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false" />
<AndroidXmlCodeStyleSettings>
<option name="USE_CUSTOM_SETTINGS" value="true" />
</AndroidXmlCodeStyleSettings>

View File

@@ -13,6 +13,23 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
-------------------------------------------------------------------------
All files under the directories briar-android/src, briar-api/src,
briar-core/src, briar-desktop/src and briar-test/src are licensed
under the Apache License, version 2.0 (the "License"); you may not
use these files except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
-------------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE

View File

@@ -11,6 +11,10 @@ android {
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
}
dexOptions {
incremental true
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7

View File

@@ -12,6 +12,7 @@ import org.briarproject.api.blogs.BlogPostHeader;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
@@ -60,7 +61,7 @@ import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class BlogManagerTest extends BriarIntegrationTest {
public class BlogManagerTest {
private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1;
@@ -93,7 +94,7 @@ public class BlogManagerTest extends BriarIntegrationTest {
private final String AUTHOR2 = "Author 2";
private static final Logger LOG =
Logger.getLogger(BlogManagerTest.class.getName());
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
private BlogManagerTestComponent t0, t1;
@@ -240,6 +241,32 @@ public class BlogManagerTest extends BriarIntegrationTest {
stopLifecycles();
}
@Test
public void testAddAndRemoveBlog() throws Exception {
startLifecycles();
defaultInit();
String name = "Test Blog";
String desc = "Description";
// add blog
Blog blog = blogManager0.addBlog(author0, name, desc);
Collection<Blog> blogs0 = blogManager0.getBlogs();
assertEquals(3, blogs0.size());
assertTrue(blogs0.contains(blog));
assertEquals(2, blogManager0.getBlogs(author0).size());
assertTrue(blogManager0.canBeRemoved(blog.getId()));
// remove blog
blogManager0.removeBlog(blog);
blogs0 = blogManager0.getBlogs();
assertEquals(2, blogs0.size());
assertFalse(blogs0.contains(blog));
assertEquals(1, blogManager0.getBlogs(author0).size());
stopLifecycles();
}
@Test
public void testCanNotRemoveContactsPersonalBlog() throws Exception {
startLifecycles();
@@ -454,7 +481,6 @@ public class BlogManagerTest extends BriarIntegrationTest {
@Test
public void testCommentOnOwnComment() throws Exception {
startLifecycles();
defaultInit();
@@ -526,16 +552,27 @@ public class BlogManagerTest extends BriarIntegrationTest {
}
private void defaultInit() throws DbException {
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
}
private void getDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor();
author1 = identityManager1.getLocalAuthor();
blog0 = blogFactory.createBlog(author0);
blog1 = blogFactory.createBlog(author1);
private void addDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
identityManager0.addLocalAuthor(author0);
blog0 = blogFactory.createPersonalBlog(author0);
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
identityManager1.addLocalAuthor(author1);
blog1 = blogFactory.createPersonalBlog(author1);
}
private void addDefaultContacts() throws DbException {
@@ -592,8 +629,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(AUTHOR1);
lifecycleManager1.startServices(AUTHOR2);
lifecycleManager0.startServices();
lifecycleManager1.startServices();
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
}

View File

@@ -8,12 +8,11 @@ import org.briarproject.api.blogs.BlogInvitationResponse;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPostFactory;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.BlogInvitationReceivedEvent;
@@ -26,7 +25,6 @@ import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.sync.ValidationManager.State;
@@ -58,28 +56,26 @@ import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.blogs.BlogSharingManager.CLIENT_ID;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class BlogSharingIntegrationTest extends BriarIntegrationTest {
public class BlogSharingIntegrationTest extends BriarTestCase {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1;
private BlogManager blogManager0, blogManager1;
private MessageTracker messageTracker0, messageTracker1;
private SyncSessionFactory sync0, sync1, sync2;
private BlogManager blogManager0, blogManager1, blogManager2;
private ContactManager contactManager0, contactManager1, contactManager2;
private Contact contact1, contact2, contact01, contact02;
private ContactId contactId1, contactId01;
private ContactId contactId1, contactId2, contactId01, contactId02;
private IdentityManager identityManager0, identityManager1,
identityManager2;
private LocalAuthor author0, author1, author2;
private Blog blog0, blog1, blog2;
private SharerListener listener0;
private SharerListener listener0, listener2;
private InviteeListener listener1;
@Inject
@@ -87,8 +83,6 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
@Inject
AuthorFactory authorFactory;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
BlogPostFactory blogPostFactory;
@Inject
CryptoComponent cryptoComponent;
@@ -144,13 +138,13 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
contactManager2 = t2.getContactManager();
blogManager0 = t0.getBlogManager();
blogManager1 = t1.getBlogManager();
messageTracker0 = t0.getMessageTracker();
messageTracker1 = t1.getMessageTracker();
blogManager2 = t2.getBlogManager();
blogSharingManager0 = t0.getBlogSharingManager();
blogSharingManager1 = t1.getBlogSharingManager();
blogSharingManager2 = t2.getBlogSharingManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
sync2 = t2.getSyncSessionFactory();
// initialize waiters fresh for each test
eventWaiter = new Waiter();
@@ -193,22 +187,15 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
// invitee has own blog and that of the sharer
assertEquals(2, blogManager1.getBlogs().size());
// get sharing group and assert group message count
GroupId g = contactGroupFactory.createContactGroup(CLIENT_ID, contact1)
.getId();
assertGroupCount(messageTracker0, g, 1, 0);
// sync first request message
sync0To1();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
assertGroupCount(messageTracker1, g, 2, 1);
// sync response back
sync1To0();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
assertGroupCount(messageTracker0, g, 2, 1);
// blog was added successfully
assertEquals(0, blogSharingManager0.getInvitations().size());
@@ -245,10 +232,6 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
// group message count is still correct
assertGroupCount(messageTracker0, g, 2, 1);
assertGroupCount(messageTracker1, g, 2, 1);
stopLifecycles();
}
@@ -527,7 +510,8 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
private class SharerListener implements EventListener {
private volatile boolean responseReceived = false;
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) {
@@ -550,7 +534,8 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
BlogInvitationReceivedEvent event =
(BlogInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
Blog b = event.getShareable();
requestReceived = true;
Blog b = event.getBlog();
try {
Contact c = contactManager0.getContact(contactId1);
blogSharingManager0.respondToInvitation(b, c, true);
@@ -565,16 +550,17 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
private class InviteeListener implements EventListener {
private volatile boolean requestReceived = false;
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private final boolean accept, answer;
private InviteeListener(boolean accept, boolean answer) {
InviteeListener(boolean accept, boolean answer) {
this.accept = accept;
this.answer = answer;
}
private InviteeListener(boolean accept) {
InviteeListener(boolean accept) {
this(accept, true);
}
@@ -592,7 +578,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
(BlogInvitationReceivedEvent) e;
requestReceived = true;
if (!answer) return;
Blog b = event.getShareable();
Blog b = event.getBlog();
try {
eventWaiter.assertEquals(1,
blogSharingManager1.getInvitations().size());
@@ -610,6 +596,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId01, event.getContactId());
responseReceived = true;
eventWaiter.resume();
}
}
@@ -620,9 +607,9 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(INVITEE);
lifecycleManager2.startServices(CONTACT2);
lifecycleManager0.startServices();
lifecycleManager1.startServices();
lifecycleManager2.startServices();
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup();
@@ -639,16 +626,30 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
}
private void defaultInit(boolean accept) throws DbException {
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
getPersonalBlogOfSharer();
listenToEvents(accept);
}
private void getDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor();
author1 = identityManager1.getLocalAuthor();
author2 = identityManager2.getLocalAuthor();
private void addDefaultIdentities() throws DbException {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
author0 = authorFactory.createLocalAuthor(SHARER,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager0.addLocalAuthor(author0);
keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = authorFactory.createLocalAuthor(INVITEE,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager1.addLocalAuthor(author1);
keyPair = cryptoComponent.generateSignatureKeyPair();
author2 = authorFactory.createLocalAuthor(CONTACT2,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager2.addLocalAuthor(author2);
}
private void addDefaultContacts() throws DbException {
@@ -659,7 +660,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
);
contact1 = contactManager0.getContact(contactId1);
// sharer adds second contact
ContactId contactId2 = contactManager0.addContact(author2,
contactId2 = contactManager0.addContact(author2,
author0.getId(), master, clock.currentTimeMillis(), true,
true, true
);
@@ -670,7 +671,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
true, true
);
contact01 = contactManager1.getContact(contactId01);
ContactId contactId02 = contactManager2.addContact(author0,
contactId02 = contactManager2.addContact(author0,
author2.getId(), master, clock.currentTimeMillis(), true,
true, true
);
@@ -688,7 +689,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
t0.getEventBus().addListener(listener0);
listener1 = new InviteeListener(accept);
t1.getEventBus().addListener(listener1);
SharerListener listener2 = new SharerListener();
listener2 = new SharerListener();
t2.getEventBus().addListener(listener2);
}

View File

@@ -2,9 +2,13 @@ package org.briarproject;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogSharingManager;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sync.SyncSessionFactory;
@@ -18,7 +22,6 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -48,8 +51,7 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class,
MessagingModule.class
TransportModule.class
})
interface BlogSharingIntegrationTestComponent {
@@ -83,8 +85,16 @@ interface BlogSharingIntegrationTestComponent {
BlogManager getBlogManager();
MessageTracker getMessageTracker();
SyncSessionFactory getSyncSessionFactory();
/* the following methods are only needed to manually construct messages */
DatabaseComponent getDatabaseComponent();
PrivateGroupFactory getPrivateGroupFactory();
ClientHelper getClientHelper();
MessageQueueManager getMessageQueueManager();
}

View File

@@ -1,30 +0,0 @@
package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.db.DbException;
import org.briarproject.api.sync.GroupId;
import static org.junit.Assert.assertEquals;
public abstract class BriarIntegrationTest extends BriarTestCase {
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount, long latestMsg)
throws DbException {
GroupCount groupCount = tracker.getGroupCount(g);
assertEquals(msgCount, groupCount.getMsgCount());
assertEquals(unreadCount, groupCount.getUnreadCount());
assertEquals(latestMsg, groupCount.getLatestMsgTime());
}
protected static void assertGroupCount(MessageTracker tracker, GroupId g,
long msgCount, long unreadCount) throws DbException {
GroupCount c1 = tracker.getGroupCount(g);
assertEquals(msgCount, c1.getMsgCount());
assertEquals(unreadCount, c1.getUnreadCount());
}
}

View File

@@ -4,11 +4,9 @@ import junit.framework.Assert;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
@@ -36,7 +34,7 @@ import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule;
import org.jetbrains.annotations.Nullable;
import org.briarproject.util.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -55,18 +53,18 @@ import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
import static junit.framework.TestCase.assertFalse;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertTrue;
public class ForumManagerTest extends BriarIntegrationTest {
public class ForumManagerTest {
private LifecycleManager lifecycleManager0, lifecycleManager1;
private SyncSessionFactory sync0, sync1;
private ForumManager forumManager0, forumManager1;
private ContactManager contactManager0, contactManager1;
private MessageTracker messageTracker0, messageTracker1;
private ContactId contactId0,contactId1;
private IdentityManager identityManager0, identityManager1;
private LocalAuthor author0, author1;
@@ -77,8 +75,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
@Inject
AuthorFactory authorFactory;
@Inject
CryptoComponent crypto;
@Inject
ForumPostFactory forumPostFactory;
// objects accessed from background threads need to be volatile
@@ -119,8 +115,6 @@ public class ForumManagerTest extends BriarIntegrationTest {
identityManager1 = t1.getIdentityManager();
contactManager0 = t0.getContactManager();
contactManager1 = t1.getContactManager();
messageTracker0 = t0.getMessageTracker();
messageTracker1 = t1.getMessageTracker();
forumManager0 = t0.getForumManager();
forumManager1 = t1.getForumManager();
forumSharingManager0 = t0.getForumSharingManager();
@@ -133,17 +127,16 @@ public class ForumManagerTest extends BriarIntegrationTest {
deliveryWaiter = new Waiter();
}
private ForumPost createForumPost(GroupId groupId,
@Nullable ForumPost parent, String body, long ms) throws Exception {
return forumPostFactory.createPost(groupId, ms,
private ForumPost createForumPost(GroupId groupId, ForumPost parent,
String body, long ms) throws Exception {
return forumPostFactory.createAnonymousPost(groupId, ms,
parent == null ? null : parent.getMessage().getId(),
author0, body);
"text/plain", StringUtils.toUtf8(body));
}
@Test
public void testForumPost() throws Exception {
startLifecycles();
getDefaultIdentities();
Forum forum = forumManager0.addForum("TestForum");
assertEquals(1, forumManager0.getForums().size());
final long ms1 = clock.currentTimeMillis() - 1000L;
@@ -157,24 +150,15 @@ public class ForumManagerTest extends BriarIntegrationTest {
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
assertEquals(ms2, post2.getMessage().getTimestamp());
forumManager0.addLocalPost(post1);
forumManager0.setReadFlag(forum.getGroup().getId(),
post1.getMessage().getId(), true);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 1, 0,
post1.getMessage().getTimestamp());
forumManager0.setReadFlag(post1.getMessage().getId(), true);
forumManager0.addLocalPost(post2);
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
forumManager0.setReadFlag(forum.getGroup().getId(),
post2.getMessage().getId(), false);
assertGroupCount(messageTracker0, forum.getGroup().getId(), 2, 1,
post2.getMessage().getTimestamp());
forumManager0.setReadFlag(post2.getMessage().getId(), false);
Collection<ForumPostHeader> headers =
forumManager0.getPostHeaders(forum.getGroup().getId());
assertEquals(2, headers.size());
for (ForumPostHeader h : headers) {
final String hBody = forumManager0.getPostBody(h.getId());
final String hBody =
StringUtils.fromUtf8(forumManager0.getPostBody(h.getId()));
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
@@ -218,29 +202,23 @@ public class ForumManagerTest extends BriarIntegrationTest {
forumManager0.addLocalPost(post1);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 1, 0, time);
assertGroupCount(messageTracker1, g, 0, 0, 0);
// send post to 1
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker1, g, 1, 1, time);
// add another forum post
long time2 = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time2);
time = clock.currentTimeMillis();
ForumPost post2 = createForumPost(g, null, "b", time);
forumManager1.addLocalPost(post2);
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 1, 0, time);
assertGroupCount(messageTracker1, g, 2, 1, time2);
// send post to 0
sync1To0();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(2, forumManager1.getPostHeaders(g).size());
assertGroupCount(messageTracker0, g, 2, 1, time2);
stopLifecycles();
}
@@ -365,15 +343,21 @@ public class ForumManagerTest extends BriarIntegrationTest {
}
private void defaultInit() throws DbException {
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
addForum();
listenToEvents();
}
private void getDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor();
author1 = identityManager1.getLocalAuthor();
private void addDefaultIdentities() throws DbException {
author0 = authorFactory.createLocalAuthor(SHARER,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager0.addLocalAuthor(author0);
author1 = authorFactory.createLocalAuthor(INVITEE,
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
TestUtils.getRandomBytes(123));
identityManager1.addLocalAuthor(author1);
}
private void addDefaultContacts() throws DbException {
@@ -434,8 +418,8 @@ public class ForumManagerTest extends BriarIntegrationTest {
// Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(INVITEE);
lifecycleManager0.startServices();
lifecycleManager1.startServices();
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
}

View File

@@ -1,6 +1,5 @@
package org.briarproject;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.forum.ForumManager;
@@ -18,7 +17,6 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -48,8 +46,7 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class,
MessagingModule.class
TransportModule.class
})
interface ForumManagerTestComponent {
@@ -79,8 +76,6 @@ interface ForumManagerTestComponent {
ContactManager getContactManager();
MessageTracker getMessageTracker();
ForumSharingManager getForumSharingManager();
ForumManager getForumManager();

View File

@@ -3,13 +3,16 @@ package org.briarproject;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.Bytes;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.clients.SessionId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.KeyParser;
import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent;
@@ -33,7 +36,7 @@ import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.sharing.SharingInvitationItem;
import org.briarproject.api.sharing.InvitationItem;
import org.briarproject.api.sharing.InvitationMessage;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.SyncSession;
@@ -68,7 +71,6 @@ import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH;
import static org.briarproject.api.forum.ForumSharingManager.CLIENT_ID;
import static org.briarproject.api.sharing.SharingConstants.SHARE_MSG_TYPE_INVITATION;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
@@ -421,11 +423,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
respond = false;
// sync first request message and leave message
deliverMessage(sync0, contactId0, sync1, contactId1, 2,
"Sharer to Invitee");
syncToInvitee();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// wait also for second message to arrive
msgWaiter.await(TIMEOUT, 1);
// ensure that invitee has no forum invitations available
assertEquals(0, forumSharingManager1.getInvitations().size());
assertEquals(0, forumManager1.getForums().size());
@@ -442,11 +446,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
forumManager0.removeForum(forum0);
// sync first request message and leave message
deliverMessage(sync0, contactId0, sync1, contactId1, 2,
"Sharer to Invitee");
syncToInvitee();
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener1.requestReceived);
// wait also for second message to arrive
msgWaiter.await(TIMEOUT, 1);
// ensure that invitee has no forum invitations available
assertEquals(0, forumSharingManager1.getInvitations().size());
assertEquals(1, forumManager1.getForums().size());
@@ -495,8 +501,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1);
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
Group group = groupFactory.createContactGroup(CLIENT_ID, c1);
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis();
BdfList bodyList = BdfList.of(SHARE_MSG_TYPE_INVITATION,
sessionId.getBytes(),
@@ -509,7 +516,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Transaction txn = db.startTransaction(false);
try {
queue.sendMessage(txn, group, time, body, new Metadata());
db.commitTransaction(txn);
txn.setComplete();
} finally {
db.endTransaction(txn);
}
@@ -580,7 +587,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db1 = t1.getDatabaseComponent();
Transaction txn = db1.startTransaction(false);
db1.addGroup(txn, forum0.getGroup());
db1.commitTransaction(txn);
txn.setComplete();
db1.endTransaction(txn);
// send invitation
@@ -690,8 +697,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db = t0.getDatabaseComponent();
MessageQueueManager queue = t0.getMessageQueueManager();
Contact c1 = contactManager0.getContact(contactId1);
ContactGroupFactory groupFactory = t0.getContactGroupFactory();
Group group = groupFactory.createContactGroup(CLIENT_ID, c1);
PrivateGroupFactory groupFactory = t0.getPrivateGroupFactory();
Group group = groupFactory
.createPrivateGroup(forumSharingManager0.getClientId(), c1);
long time = clock.currentTimeMillis();
// construct a new message re-using the old SessionId
@@ -706,7 +714,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Transaction txn = db.startTransaction(false);
try {
queue.sendMessage(txn, group, time, body, new Metadata());
db.commitTransaction(txn);
txn.setComplete();
} finally {
db.endTransaction(txn);
}
@@ -727,7 +735,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
startLifecycles();
try {
// initialize
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
addForumForSharer();
@@ -735,7 +743,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
DatabaseComponent db2 = t2.getDatabaseComponent();
Transaction txn = db2.startTransaction(false);
db2.addGroup(txn, forum0.getGroup());
db2.commitTransaction(txn);
txn.setComplete();
db2.endTransaction(txn);
// add listeners
@@ -756,11 +764,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
forumSharingManager2
.sendInvitation(forum0.getId(), contactId1, null);
// sync second request message
deliverMessage(sync2, contactId2, sync1, contactId1, 1,
deliverMessage(sync2, contactId2, sync1, contactId1,
"Sharer2 to Invitee");
// make sure we now have two invitations to the same forum available
Collection<SharingInvitationItem> forums =
Collection<InvitationItem> forums =
forumSharingManager1.getInvitations();
assertEquals(1, forums.size());
assertEquals(2, forums.iterator().next().getNewSharers().size());
@@ -777,7 +785,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
Contact c2 = contactManager1.getContact(contactId2);
forumSharingManager1.respondToInvitation(forum0, c2, true);
// sync response
deliverMessage(sync1, contactId21, sync2, contactId2, 1,
deliverMessage(sync1, contactId21, sync2, contactId2,
"Invitee to Sharer2");
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener2.responseReceived);
@@ -816,10 +824,12 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// sharer posts into the forum
long time = clock.currentTimeMillis();
String body = TestUtils.getRandomString(42);
byte[] body = TestUtils.getRandomBytes(42);
KeyParser keyParser = cryptoComponent.getSignatureKeyParser();
PrivateKey key = keyParser.parsePrivateKey(author0.getPrivateKey());
ForumPost p = forumPostFactory
.createPost(forum0.getId(), time, null, author0,
body);
.createPseudonymousPost(forum0.getId(), time, null, author0,
"text/plain", body, key);
forumManager0.addLocalPost(p);
// sync forum post
@@ -835,10 +845,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// now invitee creates a post
time = clock.currentTimeMillis();
body = TestUtils.getRandomString(42);
body = TestUtils.getRandomBytes(42);
key = keyParser.parsePrivateKey(author1.getPrivateKey());
p = forumPostFactory
.createPost(forum0.getId(), time, null, author1,
body);
.createPseudonymousPost(forum0.getId(), time, null, author1,
"text/plain", body, key);
forumManager1.addLocalPost(p);
// sync forum post
@@ -879,10 +890,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
// now invitee creates a post
time = clock.currentTimeMillis();
body = TestUtils.getRandomString(42);
body = TestUtils.getRandomBytes(42);
key = keyParser.parsePrivateKey(author1.getPrivateKey());
p = forumPostFactory
.createPost(forum0.getId(), time, null, author1,
body);
.createPseudonymousPost(forum0.getId(), time, null, author1,
"text/plain", body, key);
forumManager1.addLocalPost(p);
// sync forum post
@@ -912,8 +924,8 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
private class SharerListener implements EventListener {
private volatile boolean requestReceived = false;
private volatile boolean responseReceived = false;
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
@Override
public void eventOccurred(Event e) {
@@ -937,7 +949,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
(ForumInvitationReceivedEvent) e;
eventWaiter.assertEquals(contactId1, event.getContactId());
requestReceived = true;
Forum f = event.getShareable();
Forum f = event.getForum();
try {
Contact c = contactManager0.getContact(contactId1);
forumSharingManager0.respondToInvitation(f, c, true);
@@ -952,17 +964,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
private class InviteeListener implements EventListener {
private volatile boolean requestReceived = false;
private volatile boolean responseReceived = false;
volatile boolean requestReceived = false;
volatile boolean responseReceived = false;
private final boolean accept, answer;
private InviteeListener(boolean accept, boolean answer) {
InviteeListener(boolean accept, boolean answer) {
this.accept = accept;
this.answer = answer;
}
private InviteeListener(boolean accept) {
InviteeListener(boolean accept) {
this(accept, true);
}
@@ -980,11 +992,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
(ForumInvitationReceivedEvent) e;
requestReceived = true;
if (!answer) return;
Forum f = event.getShareable();
Forum f = event.getForum();
try {
eventWaiter.assertEquals(1,
forumSharingManager1.getInvitations().size());
SharingInvitationItem invitation =
InvitationItem invitation =
forumSharingManager1.getInvitations().iterator()
.next();
eventWaiter.assertEquals(f, invitation.getShareable());
@@ -1015,9 +1027,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(SHARER);
lifecycleManager1.startServices(INVITEE);
lifecycleManager2.startServices(SHARER2);
lifecycleManager0.startServices();
lifecycleManager1.startServices();
lifecycleManager2.startServices();
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup();
@@ -1034,16 +1046,30 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
}
private void defaultInit(boolean accept) throws DbException {
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
addForumForSharer();
listenToEvents(accept);
}
private void getDefaultIdentities() throws DbException {
author0 = identityManager0.getLocalAuthor();
author1 = identityManager1.getLocalAuthor();
author2 = identityManager2.getLocalAuthor();
private void addDefaultIdentities() throws DbException {
KeyPair keyPair = cryptoComponent.generateSignatureKeyPair();
author0 = authorFactory.createLocalAuthor(SHARER,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager0.addLocalAuthor(author0);
keyPair = cryptoComponent.generateSignatureKeyPair();
author1 = authorFactory.createLocalAuthor(INVITEE,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager1.addLocalAuthor(author1);
keyPair = cryptoComponent.generateSignatureKeyPair();
author2 = authorFactory.createLocalAuthor(SHARER2,
keyPair.getPublic().getEncoded(),
keyPair.getPrivate().getEncoded());
identityManager2.addLocalAuthor(author2);
}
private void addDefaultContacts() throws DbException {
@@ -1083,17 +1109,17 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
}
private void syncToInvitee() throws IOException, TimeoutException {
deliverMessage(sync0, contactId0, sync1, contactId1, 1,
deliverMessage(sync0, contactId0, sync1, contactId1,
"Sharer to Invitee");
}
private void syncToSharer() throws IOException, TimeoutException {
deliverMessage(sync1, contactId1, sync0, contactId0, 1,
deliverMessage(sync1, contactId1, sync0, contactId0,
"Invitee to Sharer");
}
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
SyncSessionFactory toSync, ContactId toId, int num, String debug)
SyncSessionFactory toSync, ContactId toId, String debug)
throws IOException, TimeoutException {
if (debug != null) LOG.info("TEST: Sending message from " + debug);
@@ -1114,7 +1140,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
in.close();
// wait for message to actually arrive
msgWaiter.await(TIMEOUT, num);
msgWaiter.await(TIMEOUT, 1);
}
private void injectEagerSingletons(

View File

@@ -2,7 +2,7 @@ package org.briarproject;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageQueueManager;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.PrivateGroupFactory;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
@@ -21,7 +21,6 @@ import org.briarproject.event.EventModule;
import org.briarproject.forum.ForumModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
@@ -51,8 +50,7 @@ import dagger.Component;
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class,
MessagingModule.class
TransportModule.class
})
interface ForumSharingIntegrationTestComponent {
@@ -92,7 +90,7 @@ interface ForumSharingIntegrationTestComponent {
DatabaseComponent getDatabaseComponent();
ContactGroupFactory getContactGroupFactory();
PrivateGroupFactory getPrivateGroupFactory();
ClientHelper getClientHelper();

View File

@@ -1,10 +1,6 @@
package org.briarproject.introduction;
package org.briarproject;
import org.briarproject.TestDatabaseModule;
import org.briarproject.TestPluginsModule;
import org.briarproject.TestSeedProviderModule;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.MessageTracker;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
@@ -20,8 +16,10 @@ import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.introduction.IntroductionGroupFactory;
import org.briarproject.introduction.IntroductionModule;
import org.briarproject.introduction.MessageSender;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
@@ -48,10 +46,9 @@ import dagger.Component;
SyncModule.class,
SystemModule.class,
DataModule.class,
PropertiesModule.class,
MessagingModule.class
PropertiesModule.class
})
interface IntroductionIntegrationTestComponent {
public interface IntroductionIntegrationTestComponent {
void inject(IntroductionIntegrationTest testCase);
@@ -83,8 +80,6 @@ interface IntroductionIntegrationTestComponent {
TransportPropertyManager getTransportPropertyManager();
MessageTracker getMessageTracker();
SyncSessionFactory getSyncSessionFactory();
/* the following methods are only needed to manually construct messages */

View File

@@ -6,14 +6,14 @@ import org.briarproject.api.crypto.PrivateKey;
import org.briarproject.api.forum.ForumConstants;
import org.briarproject.api.forum.ForumPost;
import org.briarproject.api.forum.ForumPostFactory;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.messaging.MessagingConstants;
import org.briarproject.api.messaging.PrivateMessage;
import org.briarproject.api.messaging.PrivateMessageFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.system.SystemModule;
import org.briarproject.util.StringUtils;
import org.junit.Test;
import javax.inject.Inject;
@@ -48,14 +48,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
// Create a maximum-length private message
GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE;
String body =
StringUtils.fromUtf8(new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH]);
MessageId parent = new MessageId(TestUtils.getRandomId());
String contentType = TestUtils.getRandomString(
MessagingConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_PRIVATE_MESSAGE_BODY_LENGTH];
PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, body);
groupId, timestamp, parent, contentType, body);
// Check the size of the serialised message
int length = message.getMessage().getRaw().length;
assertTrue(
length > UniqueId.LENGTH + 8 + MAX_PRIVATE_MESSAGE_BODY_LENGTH);
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
+ MessagingConstants.MAX_CONTENT_TYPE_LENGTH
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
}
@@ -65,17 +68,17 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
String authorName = TestUtils.getRandomString(
MAX_AUTHOR_NAME_LENGTH);
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
LocalAuthor author = authorFactory
.createLocalAuthor(authorName, authorPublic,
privateKey.getEncoded());
Author author = authorFactory.createAuthor(authorName, authorPublic);
// Create a maximum-length forum post
GroupId groupId = new GroupId(TestUtils.getRandomId());
long timestamp = Long.MAX_VALUE;
MessageId parent = new MessageId(TestUtils.getRandomId());
String body = TestUtils.getRandomString(MAX_FORUM_POST_BODY_LENGTH);
ForumPost post = forumPostFactory.createPost(groupId,
timestamp, parent, author, body);
String contentType = TestUtils.getRandomString(
ForumConstants.MAX_CONTENT_TYPE_LENGTH);
byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH];
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
ForumPost post = forumPostFactory.createPseudonymousPost(groupId,
timestamp, parent, author, contentType, body, privateKey);
// Check the size of the serialised message
int length = post.getMessage().getRaw().length;
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH

View File

@@ -1,838 +0,0 @@
package org.briarproject;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.clients.ClientHelper;
import org.briarproject.api.clients.ContactGroupFactory;
import org.briarproject.api.clients.MessageTracker.GroupCount;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.KeyPair;
import org.briarproject.api.crypto.SecretKey;
import org.briarproject.api.data.BdfList;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Transaction;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageStateChangedEvent;
import org.briarproject.api.identity.AuthorFactory;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.GroupMember;
import org.briarproject.api.privategroup.GroupMessage;
import org.briarproject.api.privategroup.GroupMessageFactory;
import org.briarproject.api.privategroup.GroupMessageHeader;
import org.briarproject.api.privategroup.JoinMessageHeader;
import org.briarproject.api.privategroup.PrivateGroup;
import org.briarproject.api.privategroup.PrivateGroupFactory;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.privategroup.invitation.GroupInvitationFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.system.Clock;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.privategroup.PrivateGroupModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.transport.TransportModule;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.TimeoutException;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.TestUtils.getRandomBytes;
import static org.briarproject.api.identity.Author.Status.VERIFIED;
import static org.briarproject.api.privategroup.Visibility.INVISIBLE;
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_CONTACT;
import static org.briarproject.api.privategroup.Visibility.REVEALED_BY_US;
import static org.briarproject.api.privategroup.Visibility.VISIBLE;
import static org.briarproject.api.privategroup.invitation.GroupInvitationFactory.SIGNING_LABEL_INVITE;
import static org.briarproject.api.sync.Group.Visibility.SHARED;
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
public class PrivateGroupManagerTest extends BriarIntegrationTest {
private LifecycleManager lifecycleManager0, lifecycleManager1,
lifecycleManager2;
private SyncSessionFactory sync0, sync1, sync2;
private PrivateGroupManager groupManager0, groupManager1, groupManager2;
private ContactManager contactManager0, contactManager1, contactManager2;
private ContactId contactId01, contactId02, contactId1, contactId2;
private IdentityManager identityManager0, identityManager1,
identityManager2;
private LocalAuthor author0, author1, author2;
private DatabaseComponent db0, db1, db2;
private PrivateGroup privateGroup0;
private GroupId groupId0;
@Inject
Clock clock;
@Inject
AuthorFactory authorFactory;
@Inject
ClientHelper clientHelper;
@Inject
CryptoComponent crypto;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
PrivateGroupFactory privateGroupFactory;
@Inject
GroupMessageFactory groupMessageFactory;
@Inject
GroupInvitationFactory groupInvitationFactory;
// objects accessed from background threads need to be volatile
private volatile Waiter validationWaiter;
private volatile Waiter deliveryWaiter;
private final File testDir = TestUtils.getTestDirectory();
private final SecretKey master = TestUtils.getSecretKey();
private final int TIMEOUT = 15000;
private final String AUTHOR0 = "Author 0";
private final String AUTHOR1 = "Author 1";
private final String AUTHOR2 = "Author 2";
private static final Logger LOG =
Logger.getLogger(PrivateGroupManagerTest.class.getName());
private PrivateGroupManagerTestComponent t0, t1, t2;
@Rule
public ExpectedException thrown = ExpectedException.none();
@Before
public void setUp() throws Exception {
PrivateGroupManagerTestComponent component =
DaggerPrivateGroupManagerTestComponent.builder().build();
component.inject(this);
assertTrue(testDir.mkdirs());
File t0Dir = new File(testDir, AUTHOR0);
t0 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
injectEagerSingletons(t0);
File t1Dir = new File(testDir, AUTHOR1);
t1 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
injectEagerSingletons(t1);
File t2Dir = new File(testDir, AUTHOR2);
t2 = DaggerPrivateGroupManagerTestComponent.builder()
.testDatabaseModule(new TestDatabaseModule(t2Dir)).build();
injectEagerSingletons(t2);
identityManager0 = t0.getIdentityManager();
identityManager1 = t1.getIdentityManager();
identityManager2 = t2.getIdentityManager();
contactManager0 = t0.getContactManager();
contactManager1 = t1.getContactManager();
contactManager2 = t2.getContactManager();
db0 = t0.getDatabaseComponent();
db1 = t1.getDatabaseComponent();
db2 = t2.getDatabaseComponent();
groupManager0 = t0.getPrivateGroupManager();
groupManager1 = t1.getPrivateGroupManager();
groupManager2 = t2.getPrivateGroupManager();
sync0 = t0.getSyncSessionFactory();
sync1 = t1.getSyncSessionFactory();
sync2 = t2.getSyncSessionFactory();
// initialize waiters fresh for each test
validationWaiter = new Waiter();
deliveryWaiter = new Waiter();
startLifecycles();
}
@Test
public void testSendingMessage() throws Exception {
defaultInit();
// create and add test message
long time = clock.currentTimeMillis();
String body = "This is a test message!";
MessageId previousMsgId =
groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, time, null, author0, body,
previousMsgId);
groupManager0.addLocalMessage(msg);
assertEquals(msg.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// sync test message
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// assert that message arrived as expected
Collection<GroupMessageHeader> headers =
groupManager1.getHeaders(groupId0);
assertEquals(3, headers.size());
GroupMessageHeader header = null;
for (GroupMessageHeader h : headers) {
if (!(h instanceof JoinMessageHeader)) {
header = h;
}
}
assertTrue(header != null);
assertFalse(header.isRead());
assertEquals(author0, header.getAuthor());
assertEquals(time, header.getTimestamp());
assertEquals(VERIFIED, header.getAuthorStatus());
assertEquals(body, groupManager1.getMessageBody(header.getId()));
GroupCount count = groupManager1.getGroupCount(groupId0);
assertEquals(2, count.getUnreadCount());
assertEquals(time, count.getLatestMsgTime());
assertEquals(3, count.getMsgCount());
}
@Test
public void testMessageWithWrongPreviousMsgId() throws Exception {
defaultInit();
// create and add test message with no previousMsgId
@SuppressWarnings("ConstantConditions")
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", null);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with random previousMsgId
MessageId previousMsgId = new MessageId(TestUtils.getRandomId());
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with wrong previousMsgId
previousMsgId = groupManager1.getPreviousMsgId(groupId0);
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(), null,
author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testMessageWithWrongParentMsgId() throws Exception {
defaultInit();
// create and add test message with random parentMsgId
MessageId parentMsgId = new MessageId(TestUtils.getRandomId());
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(),
parentMsgId, author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with wrong parentMsgId
parentMsgId = previousMsgId;
msg = groupMessageFactory
.createGroupMessage(groupId0, clock.currentTimeMillis(),
parentMsgId, author0, "test", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testMessageWithWrongTimestamp() throws Exception {
defaultInit();
// create and add test message with wrong timestamp
MessageId previousMsgId = groupManager0.getPreviousMsgId(groupId0);
GroupMessage msg = groupMessageFactory
.createGroupMessage(groupId0, 42, null, author0, "test",
previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(2, groupManager1.getHeaders(groupId0).size());
// create and add test message with good timestamp
long time = clock.currentTimeMillis();
msg = groupMessageFactory
.createGroupMessage(groupId0, time, null, author0, "test",
previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
assertEquals(3, groupManager1.getHeaders(groupId0).size());
// create and add test message with same timestamp as previous message
previousMsgId = msg.getMessage().getId();
msg = groupMessageFactory
.createGroupMessage(groupId0, time, previousMsgId, author0,
"test2", previousMsgId);
groupManager0.addLocalMessage(msg);
// sync test message
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that message did not arrive
assertEquals(3, groupManager1.getHeaders(groupId0).size());
}
@Test
public void testWrongJoinMessages1() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
// author0 joins privateGroup0 with wrong join message
long joinTime = clock.currentTimeMillis();
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
joinTime, getRandomBytes(12));
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0 with wrong timestamp
joinTime = clock.currentTimeMillis();
long inviteTime = joinTime;
Contact c1 = contactManager0.getContact(contactId1);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// sync join messages
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that 0 never joined the group from 1's perspective
assertEquals(1, groupManager1.getHeaders(groupId0).size());
sync1To0();
validationWaiter.await(TIMEOUT, 1);
// assert that 1 never joined the group from 0's perspective
assertEquals(1, groupManager0.getHeaders(groupId0).size());
}
@Test
public void testWrongJoinMessages2() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
// author0 joins privateGroup0 with wrong member's join message
long joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
BdfList toSign = groupInvitationFactory
.createInviteToken(author0.getId(), author0.getId(),
privateGroup0.getId(), inviteTime);
byte[] creatorSignature = clientHelper
.sign(SIGNING_LABEL_INVITE, toSign, author0.getPrivateKey());
// join message should not include invite time and creator's signature
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0,
inviteTime, creatorSignature);
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0 with wrong signature in join message
joinTime = clock.currentTimeMillis();
inviteTime = joinTime - 1;
// signature uses joiner's key, not creator's key
Contact c1 = contactManager0.getContact(contactId1);
creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author1.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(), SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// sync join messages
sync0To1();
validationWaiter.await(TIMEOUT, 1);
// assert that 0 never joined the group from 1's perspective
assertEquals(1, groupManager1.getHeaders(groupId0).size());
sync1To0();
validationWaiter.await(TIMEOUT, 1);
// assert that 1 never joined the group from 0's perspective
assertEquals(1, groupManager0.getHeaders(groupId0).size());
}
@Test
public void testGetMembers() throws Exception {
defaultInit();
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
assertEquals(2, members0.size());
for (GroupMember m : members0) {
if (m.getAuthor().equals(author0)) {
assertEquals(VISIBLE, m.getVisibility());
} else {
assertEquals(author1, m.getAuthor());
assertEquals(VISIBLE, m.getVisibility());
}
}
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
assertEquals(2, members1.size());
for (GroupMember m : members1) {
if (m.getAuthor().equals(author1)) {
assertEquals(VISIBLE, m.getVisibility());
} else {
assertEquals(author0, m.getAuthor());
assertEquals(VISIBLE, m.getVisibility());
}
}
}
@Test
public void testJoinMessages() throws Exception {
defaultInit();
Collection<GroupMessageHeader> headers0 =
groupManager0.getHeaders(groupId0);
for (GroupMessageHeader h : headers0) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
// all relationships of the creator are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
Collection<GroupMessageHeader> headers1 =
groupManager1.getHeaders(groupId0);
for (GroupMessageHeader h : headers1) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author1))
// we are visible to ourselves
assertEquals(VISIBLE, j.getVisibility());
else
// our relationship to the creator is visible
assertEquals(VISIBLE, j.getVisibility());
}
}
}
@Test
public void testRevealingRelationships() throws Exception {
defaultInit();
// share the group with 2
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId2, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author2 joins privateGroup0
long joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
Contact c2 = contactManager0.getContact(contactId2);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c2, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg2 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author2,
inviteTime, creatorSignature);
Transaction txn2 = db2.startTransaction(false);
groupManager2.addPrivateGroup(txn2, privateGroup0, joinMsg2, false);
// share the group with 0
db2.setGroupVisibility(txn2, contactId01, privateGroup0.getId(),
SHARED);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
// sync join messages
deliverMessage(sync2, contactId2, sync0, contactId02, "2 to 0");
deliveryWaiter.await(TIMEOUT, 1);
deliverMessage(sync0, contactId02, sync2, contactId2, "0 to 2");
deliveryWaiter.await(TIMEOUT, 2);
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// check that everybody sees everybody else as joined
Collection<GroupMember> members0 = groupManager0.getMembers(groupId0);
assertEquals(3, members0.size());
Collection<GroupMember> members1 = groupManager1.getMembers(groupId0);
assertEquals(3, members1.size());
Collection<GroupMember> members2 = groupManager2.getMembers(groupId0);
assertEquals(3, members2.size());
// assert that contact relationship is not revealed initially
for (GroupMember m : members1) {
if (m.getAuthor().equals(author2)) {
assertEquals(INVISIBLE, m.getVisibility());
}
}
for (GroupMember m : members2) {
if (m.getAuthor().equals(author1)) {
assertEquals(INVISIBLE, m.getVisibility());
}
}
// reveal contact relationship
Transaction txn1 = db1.startTransaction(false);
groupManager1
.relationshipRevealed(txn1, groupId0, author2.getId(), false);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
txn2 = db2.startTransaction(false);
groupManager2
.relationshipRevealed(txn2, groupId0, author1.getId(), true);
db2.commitTransaction(txn2);
db2.endTransaction(txn2);
// assert that contact relationship is now revealed properly
members1 = groupManager1.getMembers(groupId0);
for (GroupMember m : members1) {
if (m.getAuthor().equals(author2)) {
assertEquals(REVEALED_BY_US, m.getVisibility());
}
}
members2 = groupManager2.getMembers(groupId0);
for (GroupMember m : members2) {
if (m.getAuthor().equals(author1)) {
assertEquals(REVEALED_BY_CONTACT, m.getVisibility());
}
}
// assert that join messages reflect revealed relationship
Collection<GroupMessageHeader> headers1 =
groupManager1.getHeaders(groupId0);
for (GroupMessageHeader h : headers1) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author2))
// 1 revealed the relationship to 2
assertEquals(REVEALED_BY_US, j.getVisibility());
else
// 1's other relationship (to 1 and creator) are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
Collection<GroupMessageHeader> headers2 =
groupManager2.getHeaders(groupId0);
for (GroupMessageHeader h : headers2) {
if (h instanceof JoinMessageHeader) {
JoinMessageHeader j = (JoinMessageHeader) h;
if (h.getAuthor().equals(author1))
// 2's relationship was revealed by 1
assertEquals(REVEALED_BY_CONTACT, j.getVisibility());
else
// 2's other relationship (to 2 and creator) are visible
assertEquals(VISIBLE, j.getVisibility());
}
}
}
@Test
public void testDissolveGroup() throws Exception {
defaultInit();
// group is not dissolved initially
assertFalse(groupManager1.isDissolved(groupId0));
// creator dissolves group
Transaction txn1 = db1.startTransaction(false);
groupManager1.markGroupDissolved(txn1, groupId0);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
// group is dissolved now
assertTrue(groupManager1.isDissolved(groupId0));
}
@After
public void tearDown() throws Exception {
stopLifecycles();
TestUtils.deleteTestDirectory(testDir);
}
private class Listener implements EventListener {
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
if (!event.isLocal()) {
if (event.getState() == DELIVERED) {
LOG.info("Delivered new message");
deliveryWaiter.resume();
} else if (event.getState() == INVALID ||
event.getState() == PENDING) {
LOG.info("Validated new " + event.getState().name() +
" message");
validationWaiter.resume();
}
}
}
}
}
private void defaultInit() throws Exception {
addDefaultIdentities();
addDefaultContacts();
listenToEvents();
addGroup();
}
private void addDefaultIdentities() throws DbException {
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
author0 = authorFactory
.createLocalAuthor(AUTHOR0, publicKey0, privateKey0);
identityManager0.registerLocalAuthor(author0);
privateGroup0 =
privateGroupFactory.createPrivateGroup("Testgroup", author0);
groupId0 = privateGroup0.getId();
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
author1 = authorFactory
.createLocalAuthor(AUTHOR1, publicKey1, privateKey1);
identityManager1.registerLocalAuthor(author1);
KeyPair keyPair2 = crypto.generateSignatureKeyPair();
byte[] publicKey2 = keyPair2.getPublic().getEncoded();
byte[] privateKey2 = keyPair2.getPrivate().getEncoded();
author2 = authorFactory
.createLocalAuthor(AUTHOR2, publicKey2, privateKey2);
identityManager2.registerLocalAuthor(author2);
}
private void addDefaultContacts() throws DbException {
// creator adds invitee as contact
contactId1 = contactManager0
.addContact(author1, author0.getId(), master,
clock.currentTimeMillis(), true, true, true);
// invitee adds creator back
contactId01 = contactManager1
.addContact(author0, author1.getId(), master,
clock.currentTimeMillis(), true, true, true);
// creator adds invitee as contact
contactId2 = contactManager0
.addContact(author2, author0.getId(), master,
clock.currentTimeMillis(), true, true, true);
// invitee adds creator back
contactId02 = contactManager2
.addContact(author0, author2.getId(), master,
clock.currentTimeMillis(), true, true, true);
}
private void listenToEvents() {
Listener listener0 = new Listener();
t0.getEventBus().addListener(listener0);
Listener listener1 = new Listener();
t1.getEventBus().addListener(listener1);
Listener listener2 = new Listener();
t2.getEventBus().addListener(listener2);
}
private void addGroup() throws Exception {
// author0 joins privateGroup0
long joinTime = clock.currentTimeMillis();
GroupMessage joinMsg0 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author0);
groupManager0.addPrivateGroup(privateGroup0, joinMsg0, true);
assertEquals(joinMsg0.getMessage().getId(),
groupManager0.getPreviousMsgId(groupId0));
// share the group with 1
Transaction txn0 = db0.startTransaction(false);
db0.setGroupVisibility(txn0, contactId1, privateGroup0.getId(), SHARED);
db0.commitTransaction(txn0);
db0.endTransaction(txn0);
// author1 joins privateGroup0
joinTime = clock.currentTimeMillis();
long inviteTime = joinTime - 1;
Contact c1 = contactManager0.getContact(contactId1);
byte[] creatorSignature = groupInvitationFactory
.signInvitation(c1, privateGroup0.getId(), inviteTime,
author0.getPrivateKey());
GroupMessage joinMsg1 = groupMessageFactory
.createJoinMessage(privateGroup0.getId(), joinTime, author1,
inviteTime, creatorSignature);
groupManager1.addPrivateGroup(privateGroup0, joinMsg1, false);
// share the group with 0
Transaction txn1 = db1.startTransaction(false);
db1.setGroupVisibility(txn1, contactId01, privateGroup0.getId(),
SHARED);
db1.commitTransaction(txn1);
db1.endTransaction(txn1);
assertEquals(joinMsg1.getMessage().getId(),
groupManager1.getPreviousMsgId(groupId0));
// sync join messages
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
sync1To0();
deliveryWaiter.await(TIMEOUT, 1);
}
private void sync0To1() throws IOException, TimeoutException {
deliverMessage(sync0, contactId01, sync1, contactId1, "0 to 1");
}
private void sync1To0() throws IOException, TimeoutException {
deliverMessage(sync1, contactId1, sync0, contactId01, "1 to 0");
}
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
SyncSessionFactory toSync, ContactId toId, String debug)
throws IOException, TimeoutException {
if (debug != null) LOG.info("TEST: Sending message from " + debug);
ByteArrayOutputStream out = new ByteArrayOutputStream();
// Create an outgoing sync session
SyncSession sessionFrom =
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
// Write whatever needs to be written
sessionFrom.run();
out.close();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
// Create an incoming sync session
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
// Read whatever needs to be read
sessionTo.run();
in.close();
}
private void startLifecycles() throws InterruptedException {
// Start the lifecycle manager and wait for it to finish
lifecycleManager0 = t0.getLifecycleManager();
lifecycleManager1 = t1.getLifecycleManager();
lifecycleManager2 = t2.getLifecycleManager();
lifecycleManager0.startServices(AUTHOR0);
lifecycleManager1.startServices(AUTHOR1);
lifecycleManager2.startServices(AUTHOR2);
lifecycleManager0.waitForStartup();
lifecycleManager1.waitForStartup();
lifecycleManager2.waitForStartup();
}
private void stopLifecycles() throws InterruptedException {
// Clean up
lifecycleManager0.stopServices();
lifecycleManager1.stopServices();
lifecycleManager2.stopServices();
lifecycleManager0.waitForShutdown();
lifecycleManager1.waitForShutdown();
lifecycleManager2.waitForShutdown();
}
private void injectEagerSingletons(
PrivateGroupManagerTestComponent component) {
component.inject(new LifecycleModule.EagerSingletons());
component.inject(new PrivateGroupModule.EagerSingletons());
component.inject(new CryptoModule.EagerSingletons());
component.inject(new ContactModule.EagerSingletons());
component.inject(new TransportModule.EagerSingletons());
component.inject(new SyncModule.EagerSingletons());
component.inject(new PropertiesModule.EagerSingletons());
}
}

View File

@@ -1,85 +0,0 @@
package org.briarproject;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.identity.IdentityManager;
import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.privategroup.PrivateGroupManager;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.clients.ClientsModule;
import org.briarproject.contact.ContactModule;
import org.briarproject.crypto.CryptoModule;
import org.briarproject.data.DataModule;
import org.briarproject.db.DatabaseModule;
import org.briarproject.event.EventModule;
import org.briarproject.identity.IdentityModule;
import org.briarproject.lifecycle.LifecycleModule;
import org.briarproject.messaging.MessagingModule;
import org.briarproject.privategroup.PrivateGroupModule;
import org.briarproject.privategroup.invitation.GroupInvitationModule;
import org.briarproject.properties.PropertiesModule;
import org.briarproject.sharing.SharingModule;
import org.briarproject.sync.SyncModule;
import org.briarproject.system.SystemModule;
import org.briarproject.transport.TransportModule;
import javax.inject.Singleton;
import dagger.Component;
@Singleton
@Component(modules = {
TestDatabaseModule.class,
TestPluginsModule.class,
TestSeedProviderModule.class,
ClientsModule.class,
ContactModule.class,
CryptoModule.class,
DataModule.class,
DatabaseModule.class,
EventModule.class,
MessagingModule.class,
PrivateGroupModule.class,
GroupInvitationModule.class,
IdentityModule.class,
LifecycleModule.class,
PropertiesModule.class,
SharingModule.class,
SyncModule.class,
SystemModule.class,
TransportModule.class
})
interface PrivateGroupManagerTestComponent {
void inject(PrivateGroupManagerTest testCase);
void inject(ContactModule.EagerSingletons init);
void inject(CryptoModule.EagerSingletons init);
void inject(PrivateGroupModule.EagerSingletons init);
void inject(LifecycleModule.EagerSingletons init);
void inject(PropertiesModule.EagerSingletons init);
void inject(SyncModule.EagerSingletons init);
void inject(TransportModule.EagerSingletons init);
LifecycleManager getLifecycleManager();
EventBus getEventBus();
IdentityManager getIdentityManager();
ContactManager getContactManager();
PrivateGroupManager getPrivateGroupManager();
SyncSessionFactory getSyncSessionFactory();
DatabaseComponent getDatabaseComponent();
}

View File

@@ -43,9 +43,6 @@ import static org.junit.Assert.assertTrue;
public class SimplexMessagingIntegrationTest extends BriarTestCase {
private final static String ALICE = "Alice";
private final static String BOB = "Bob";
private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob");
@@ -72,7 +69,6 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
read(write());
}
private byte[] write() throws Exception {
// Instantiate Alice's services
LifecycleManager lifecycleManager = alice.getLifecycleManager();
@@ -87,23 +83,23 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
SyncSessionFactory syncSessionFactory = alice.getSyncSessionFactory();
// Start the lifecycle manager
lifecycleManager.startServices(null);
lifecycleManager.startServices();
lifecycleManager.waitForStartup();
// Add an identity for Alice
LocalAuthor aliceAuthor = new LocalAuthor(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(aliceAuthor);
identityManager.addLocalAuthor(aliceAuthor);
// Add Bob as a contact
Author bobAuthor = new Author(bobId, BOB,
Author bobAuthor = new Author(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor,
aliceAuthor.getId(), master, timestamp, true, true, true);
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
master, timestamp, true, true, true);
// Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId);
String body = "Hi Bob!";
byte[] body = "Hi Bob!".getBytes("UTF-8");
PrivateMessage message = privateMessageFactory.createPrivateMessage(
groupId, timestamp, body);
groupId, timestamp, null, "text/plain", body);
messagingManager.addLocalMessage(message);
// Get a stream context
StreamContext ctx = keyManager.getStreamContext(contactId,
@@ -140,17 +136,18 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
bob.getMessagingManager();
// Start the lifecyle manager
lifecycleManager.startServices(null);
lifecycleManager.startServices();
lifecycleManager.waitForStartup();
// Add an identity for Bob
LocalAuthor bobAuthor = new LocalAuthor(bobId, BOB,
LocalAuthor bobAuthor = new LocalAuthor(bobId, "Bob",
new byte[MAX_PUBLIC_KEY_LENGTH], new byte[123], timestamp);
identityManager.registerLocalAuthor(bobAuthor);
identityManager.addLocalAuthor(bobAuthor);
// Add Alice as a contact
Author aliceAuthor = new Author(aliceId, ALICE,
Author aliceAuthor = new Author(aliceId, "Alice",
new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor,
bobAuthor.getId(), master, timestamp, false, true, true);
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
master, timestamp, false, true, true);
// Set up an event listener
MessageListener listener = new MessageListener();
bob.getEventBus().addListener(listener);

View File

@@ -74,7 +74,7 @@ public class SyncIntegrationTest extends BriarTestCase {
headerKey = TestUtils.getSecretKey();
streamNumber = 123;
// Create a group
ClientId clientId = new ClientId(TestUtils.getRandomString(5));
ClientId clientId = new ClientId(TestUtils.getRandomId());
byte[] descriptor = new byte[0];
Group group = groupFactory.createGroup(clientId, descriptor);
// Add two messages to the group
@@ -122,7 +122,7 @@ public class SyncIntegrationTest extends BriarTestCase {
// Create the readers
StreamContext ctx = new StreamContext(contactId, transportId, tagKey,
headerKey, streamNumber);
headerKey, 0);
InputStream streamReader = streamReaderFactory.createStreamReader(in,
ctx);
PacketReader packetReader = packetReaderFactory.createPacketReader(

View File

@@ -1,6 +1,6 @@
[main]
host = https://www.transifex.com
lang_map = pt_BR: pt-rBR, fr_FR: fr
lang_map = pt_BR: pt-rBR
[briar.stringsxml-5]
file_filter = res/values-<lang>/strings.xml

View File

@@ -93,7 +93,7 @@
android:label="@string/app_name"
android:theme="@style/BriarThemeNoActionBar.Default"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="stateHidden|adjustResize">
android:windowSoftInputMode="stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
@@ -101,70 +101,7 @@
</activity>
<activity
android:name=".android.privategroup.creation.CreateGroupActivity"
android:label="@string/groups_create_group_title"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="adjustResize">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.privategroup.conversation.GroupActivity"
android:label="@string/app_name"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.privategroup.invitation.GroupInvitationActivity"
android:label="@string/groups_invitations_title"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"/>
</activity>
<activity
android:name=".android.privategroup.memberlist.GroupMemberListActivity"
android:label="@string/groups_member_list"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"
/>
</activity>
<activity
android:name=".android.privategroup.reveal.RevealContactsActivity"
android:label="@string/groups_reveal_contacts"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateAlwaysHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"
/>
</activity>
<activity
android:name=".android.privategroup.creation.GroupInviteActivity"
android:label="@string/groups_invite_members"
android:parentActivityName=".android.privategroup.conversation.GroupActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.privategroup.conversation.GroupActivity"/>
</activity>
<activity
android:name=".android.sharing.ForumInvitationActivity"
android:name=".android.sharing.InvitationsForumActivity"
android:label="@string/forum_invitations_title"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
@@ -174,7 +111,7 @@
</activity>
<activity
android:name=".android.sharing.BlogInvitationActivity"
android:name=".android.sharing.InvitationsBlogActivity"
android:label="@string/blogs_sharing_invitations_title"
android:parentActivityName=".android.contact.ConversationActivity">
<meta-data
@@ -197,8 +134,7 @@
<activity
android:name=".android.forum.ForumActivity"
android:label="@string/app_name"
android:parentActivityName=".android.NavDrawerActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
@@ -208,8 +144,7 @@
<activity
android:name=".android.sharing.ShareForumActivity"
android:label="@string/activity_share_toolbar_header"
android:parentActivityName=".android.forum.ForumActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
android:parentActivityName=".android.forum.ForumActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.forum.ForumActivity"
@@ -219,8 +154,7 @@
<activity
android:name=".android.sharing.ShareBlogActivity"
android:label="@string/activity_share_toolbar_header"
android:parentActivityName=".android.blogs.BlogActivity"
android:windowSoftInputMode="adjustResize|stateHidden">
android:parentActivityName=".android.blogs.BlogActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity"
@@ -228,7 +162,7 @@
</activity>
<activity
android:name=".android.sharing.ForumSharingStatusActivity"
android:name=".android.sharing.SharingStatusForumActivity"
android:label="@string/sharing_status"
android:parentActivityName=".android.forum.ForumActivity">
<meta-data
@@ -238,7 +172,7 @@
</activity>
<activity
android:name=".android.sharing.BlogSharingStatusActivity"
android:name=".android.sharing.SharingStatusBlogActivity"
android:label="@string/sharing_status"
android:parentActivityName=".android.blogs.BlogActivity">
<meta-data
@@ -247,6 +181,16 @@
/>
</activity>
<activity
android:name=".android.blogs.CreateBlogActivity"
android:label="@string/blogs_my_blogs_label"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
</activity>
<activity
android:name=".android.blogs.BlogActivity"
android:parentActivityName=".android.NavDrawerActivity">
@@ -299,6 +243,12 @@
/>
</activity>
<activity
android:name=".android.identity.CreateIdentityActivity"
android:label="@string/new_identity_title"
android:windowSoftInputMode="stateVisible">
</activity>
<activity
android:name=".android.invitation.AddContactActivity"
android:label="@string/add_contact_title"

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
width="24"
height="24"
viewBox="0 0 24 24"
sodipodi:docname="ic_emoji_emoticons.svg">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1021"
id="namedview4"
showgrid="false"
inkscape:zoom="4.6354778"
inkscape:cx="47.926788"
inkscape:cy="24.127496"
inkscape:window-x="1440"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<path
style="fill:#000000;fill-opacity:1"
d="m 15.483903,3.8556996 c -0.661546,0.040406 -0.536253,1.2125273 -0.08054,1.6240791 1.361771,1.4519837 1.747379,3.5080793 1.895646,5.4253553 0.109142,2.216286 -0.0846,4.555699 -1.171466,6.533591 -0.361828,0.731167 -1.339597,1.273078 -1.15283,2.195835 0.287109,1.037426 1.187031,0.242862 1.620751,-0.183708 1.991711,-1.742024 2.867744,-4.428018 2.93133,-7.013492 0.02009,-1.918049 -0.231841,-3.9213035 -1.212735,-5.6044037 -0.664187,-1.0906817 -1.39072,-2.2339438 -2.497355,-2.9193489 -0.127976,-0.045915 -0.238296,-0.06368 -0.332802,-0.057908 z M 5.9118212,7.6583077 A 1.3631614,1.3631614 0 0 0 4.54866,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,10.38463 1.3631614,1.3631614 0 0 0 7.2749824,9.0214691 1.3631614,1.3631614 0 0 0 5.9118212,7.6583077 Z m 3.0731032,3.0012183 0,2.044742 4.7710646,0 0,-2.044742 -4.7710646,0 z m -3.1496485,3.471136 a 1.3631614,1.3631614 0 0 0 -1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,1.363161 1.3631614,1.3631614 0 0 0 1.3631612,-1.363161 1.3631614,1.3631614 0 0 0 -1.3631612,-1.363161 z"
id="path4142"
inkscape:connector-curvature="0" />
</svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 901 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 650 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 547 KiB

View File

@@ -25,20 +25,16 @@ dependencies {
exclude module: 'recyclerview-v7'
}
compile "com.android.support:cardview-v7:$supportVersion"
compile 'com.android.support:support-annotations:23.4.0'
compile('ch.acra:acra:4.8.5') {
exclude module: 'support-v4'
exclude module: 'support-annotations'
}
compile 'info.guardianproject.panic:panic:0.5'
compile 'info.guardianproject.trustedintents:trustedintents:0.2'
compile 'de.hdodenhof:circleimageview:2.1.0'
compile 'de.hdodenhof:circleimageview:2.0.0'
compile 'com.google.zxing:core:3.2.1'
apt 'com.google.dagger:dagger-compiler:2.0.2'
provided 'javax.annotation:jsr250-api:1.0'
compile 'com.jpardogo.materialtabstrip:library:1.1.0'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'uk.co.samuelwall:material-tap-target-prompt:1.3.0'
testCompile 'junit:junit:4.12'
testCompile 'net.jodah:concurrentunit:0.4.2'
@@ -53,20 +49,17 @@ dependencyVerification {
'ch.acra:acra:afd5b28934d5166b55f261c85685ad59e8a4ebe9ca1960906afaa8c76d8dc9eb',
'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
'info.guardianproject.trustedintents:trustedintents:6221456d8821a8d974c2acf86306900237cf6afaaa94a4c9c44e161350f80f3e',
'de.hdodenhof:circleimageview:bcbc588e19e6dcf8c120b1957776bfe229efba5d2fbe5da7156372eeacf65503',
'de.hdodenhof:circleimageview:c76d936395b50705a3f98c9220c22d2599aeb9e609f559f6048975cfc1f686b8',
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
'com.android.support:support-annotations:e91a88dd0c5e99069b7f09d4a46b5e06f1e9c4c72fc0a8e987e25d86af480f01',
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
'com.android.support:recyclerview-v7:44040a888e23e0c93162a3377cfe06751080e3c22d369ab0d4301ef60d63b0fe',
'com.android.support:cardview-v7:4595f1c4a28cfa083b6c0920ad4d49e1c2ca4b8302a955e548f68eb63b74931b',
'com.jpardogo.materialtabstrip:library:24d19232b319f8c73e25793432357919a7ed972186f57a3b2c9093ea74ad8311',
'com.github.bumptech.glide:glide:76ef123957b5fbaebb05fcbe6606dd58c3bc3fcdadb257f99811d0ac9ea9b88b',
'uk.co.samuelwall:material-tap-target-prompt:f67e1caead12a914525b32cbf6da52a96b93ff89573f93cb41102ef3130fb64a',
]
}
@@ -125,6 +118,10 @@ android {
warning 'MissingTranslation'
warning 'ImpliedQuantity'
}
dexOptions {
incremental true
}
}
task downloadTorGeoIp(type: Download) {

View File

@@ -54,18 +54,9 @@
# RSS libraries
-keep class com.rometools.rome.feed.synd.impl.** { *;}
-keep class com.rometools.rome.io.impl.** { *;}
-keep class org.jsoup.safety.Whitelist
-dontnote com.rometools.rome.**
-dontwarn javax.xml.stream.**
-dontwarn org.jaxen.**
-dontwarn java.nio.**
-dontwarn org.codehaus.mojo.animal_sniffer.**
-dontwarn org.slf4j.impl.**
# Emoji
-keep class org.thoughtcrime.securesms.**
-keep class com.astuetz.PagerSlidingTabStrip$OnTabReselectedListener
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M22,3L7,3c-0.69,0 -1.23,0.35 -1.59,0.88L0,12l5.41,8.11c0.36,0.53 0.9,0.89 1.59,0.89h15c1.1,0 2,-0.9 2,-2L24,5c0,-1.1 -0.9,-2 -2,-2zM19,15.59L17.59,17 14,13.41 10.41,17 9,15.59 12.59,12 9,8.41 10.41,7 14,10.59 17.59,7 19,8.41 15.41,12 19,15.59z"/>
</vector>

View File

@@ -1,10 +1,5 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="48dp"
android:height="48dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/>
<vector android:alpha="0.56" android:height="48dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M9.01,14L2,14v2h7.01v3L13,15l-3.99,-4v3zM14.99,13v-3L22,10L22,8h-7.01L14.99,5L11,9l3.99,4z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,0L4,0v2h16L20,0zM4,24h16v-2L4,22v2zM20,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM12,6.75c1.24,0 2.25,1.01 2.25,2.25s-1.01,2.25 -2.25,2.25S9.75,10.24 9.75,9 10.76,6.75 12,6.75zM17,17L7,17v-1.5c0,-1.67 3.33,-2.5 5,-2.5s5,0.83 5,2.5L17,17z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF2D3E50"
android:pathData="M7.5,7.5C9.17,5.87 11.29,4.69 13.37,4.18C15.46,3.67 17.5,3.83 18.6,4C19.71,4.15 19.87,4.31 20.03,5.41C20.18,6.5 20.33,8.55 19.82,10.63C19.31,12.71 18.13,14.83 16.5,16.5C14.83,18.13 12.71,19.31 10.63,19.82C8.55,20.33 6.5,20.18 5.41,20.03C4.31,19.87 4.15,19.71 4,18.6C3.83,17.5 3.67,15.46 4.18,13.37C4.69,11.29 5.87,9.17 7.5,7.5M7.3,15.79L8.21,16.7L9.42,15.5L10.63,16.7L11.54,15.79L10.34,14.58L12,12.91L13.21,14.12L14.12,13.21L12.91,12L14.58,10.34L15.79,11.54L16.7,10.63L15.5,9.42L16.7,8.21L15.79,7.3L14.58,8.5L13.37,7.3L12.46,8.21L13.66,9.42L12,11.09L10.79,9.88L9.88,10.79L11.09,12L9.42,13.66L8.21,12.46L7.3,13.37L8.5,14.58L7.3,15.79Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M18.7,12.4c-0.28,-0.16 -0.57,-0.29 -0.86,-0.4 0.29,-0.11 0.58,-0.24 0.86,-0.4 1.92,-1.11 2.99,-3.12 3,-5.19 -1.79,-1.03 -4.07,-1.11 -6,0 -0.28,0.16 -0.54,0.35 -0.78,0.54 0.05,-0.31 0.08,-0.63 0.08,-0.95 0,-2.22 -1.21,-4.15 -3,-5.19C10.21,1.85 9,3.78 9,6c0,0.32 0.03,0.64 0.08,0.95 -0.24,-0.2 -0.5,-0.39 -0.78,-0.55 -1.92,-1.11 -4.2,-1.03 -6,0 0,2.07 1.07,4.08 3,5.19 0.28,0.16 0.57,0.29 0.86,0.4 -0.29,0.11 -0.58,0.24 -0.86,0.4 -1.92,1.11 -2.99,3.12 -3,5.19 1.79,1.03 4.07,1.11 6,0 0.28,-0.16 0.54,-0.35 0.78,-0.54 -0.05,0.32 -0.08,0.64 -0.08,0.96 0,2.22 1.21,4.15 3,5.19 1.79,-1.04 3,-2.97 3,-5.19 0,-0.32 -0.03,-0.64 -0.08,-0.95 0.24,0.2 0.5,0.38 0.78,0.54 1.92,1.11 4.2,1.03 6,0 -0.01,-2.07 -1.08,-4.08 -3,-5.19zM12,16c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z"/>
</vector>

View File

@@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF2D3E50"
android:pathData="M15.4839,3.8557 C14.8224,3.89611,14.9476,5.06823,15.4034,5.47978
C16.7652,6.93176,17.1508,8.98786,17.299,10.9051
C17.4081,13.1214,17.2144,15.4608,16.1275,17.4387
C15.7657,18.1699,14.7879,18.7118,14.9747,19.6345
C15.2618,20.6719,16.1617,19.8774,16.5955,19.4508
C18.5872,17.7088,19.4632,15.0228,19.5268,12.4373
C19.5469,10.5193,19.295,8.516,18.3141,6.8329
C17.6499,5.74222,16.9234,4.59896,15.8167,3.91355
C15.6887,3.86763,15.5784,3.84987,15.4839,3.85564 Z M5.91182,7.65831
A1.3631614,1.3631614,0,0,0,4.54866,9.02147
A1.3631614,1.3631614,0,0,0,5.91182,10.3846
A1.3631614,1.3631614,0,0,0,7.27498,9.02147
A1.3631614,1.3631614,0,0,0,5.91182,7.65831 Z M8.98492,10.6595 L8.98492,12.7042
L13.756,12.7042 L13.756,10.6595 L8.98494,10.6595 Z M5.83527,14.1306
A1.3631614,1.3631614,0,0,0,4.47211,15.4938
A1.3631614,1.3631614,0,0,0,5.83527,16.857
A1.3631614,1.3631614,0,0,0,7.19843,15.4938
A1.3631614,1.3631614,0,0,0,5.83527,14.1306 Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M14.4,6L14,4H5v17h2v-7h5.6l0.4,2h7V6z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M12,6c1.11,0 2,-0.9 2,-2 0,-0.38 -0.1,-0.73 -0.29,-1.03L12,0l-1.71,2.97c-0.19,0.3 -0.29,0.65 -0.29,1.03 0,1.1 0.9,2 2,2zM16.6,15.99l-1.07,-1.07 -1.08,1.07c-1.3,1.3 -3.58,1.31 -4.89,0l-1.07,-1.07 -1.09,1.07C6.75,16.64 5.88,17 4.96,17c-0.73,0 -1.4,-0.23 -1.96,-0.61L3,21c0,0.55 0.45,1 1,1h16c0.55,0 1,-0.45 1,-1v-4.61c-0.56,0.38 -1.23,0.61 -1.96,0.61 -0.92,0 -1.79,-0.36 -2.44,-1.01zM18,9h-5L13,7h-2v2L6,9c-1.66,0 -3,1.34 -3,3v1.54c0,1.08 0.88,1.96 1.96,1.96 0.52,0 1.02,-0.2 1.38,-0.57l2.14,-2.13 2.13,2.13c0.74,0.74 2.03,0.74 2.77,0l2.14,-2.13 2.13,2.13c0.37,0.37 0.86,0.57 1.38,0.57 1.08,0 1.96,-0.88 1.96,-1.96L20.99,12C21,10.34 19.66,9 18,9z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FF2D3E50"
android:pathData="M5,16L3,5L8.5,12L12,5L15.5,12L21,5L19,16H5M19,19A1,1 0 0,1 18,20H6A1,1 0 0,1 5,19V18H19V19Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M12,7.77L18.39,18H5.61L12,7.77M12,4L2,20h20L12,4z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM15.5,11c0.83,0 1.5,-0.67 1.5,-1.5S16.33,8 15.5,8 14,8.67 14,9.5s0.67,1.5 1.5,1.5zM8.5,11c0.83,0 1.5,-0.67 1.5,-1.5S9.33,8 8.5,8 7,8.67 7,9.5 7.67,11 8.5,11zM12,17.5c2.33,0 4.31,-1.46 5.11,-3.5L6.89,14c0.8,2.04 2.78,3.5 5.11,3.5z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M18.92,6.01C18.72,5.42 18.16,5 17.5,5h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,12v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,13 6.5,13s1.5,0.67 1.5,1.5S7.33,16 6.5,16zM17.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,11l1.5,-4.5h11L19,11L5,11z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M20,5L4,5c-1.1,0 -1.99,0.9 -1.99,2L2,17c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,7c0,-1.1 -0.9,-2 -2,-2zM11,8h2v2h-2L11,8zM11,11h2v2h-2v-2zM8,8h2v2L8,10L8,8zM8,11h2v2L8,13v-2zM7,13L5,13v-2h2v2zM7,10L5,10L5,8h2v2zM16,17L8,17v-2h8v2zM16,13h-2v-2h2v2zM16,10h-2L14,8h2v2zM19,13h-2v-2h2v2zM19,10h-2L17,8h2v2z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF2D3E50"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:alpha="0.53"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,7c2.76,0 5,2.24 5,5 0,0.65 -0.13,1.26 -0.36,1.83l2.92,2.92c1.51,-1.26 2.7,-2.89 3.43,-4.75 -1.73,-4.39 -6,-7.5 -11,-7.5 -1.4,0 -2.74,0.25 -3.98,0.7l2.16,2.16C10.74,7.13 11.35,7 12,7zM2,4.27l2.28,2.28 0.46,0.46C3.08,8.3 1.78,10.02 1,12c1.73,4.39 6,7.5 11,7.5 1.55,0 3.03,-0.3 4.38,-0.84l0.42,0.42L19.73,22 21,20.73 3.27,3 2,4.27zM7.53,9.8l1.55,1.55c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.66 1.34,3 3,3 0.22,0 0.44,-0.03 0.65,-0.08l1.55,1.55c-0.67,0.33 -1.41,0.53 -2.2,0.53 -2.76,0 -5,-2.24 -5,-5 0,-0.79 0.2,-1.53 0.53,-2.2zM11.84,9.02l3.15,3.15 0.02,-0.16c0,-1.66 -1.34,-3 -3,-3l-0.17,0.01z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,4.5C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5zM12,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3 3,-1.34 3,-3 -1.34,-3 -3,-3z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@@ -3,9 +3,9 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".android.contact.ConversationActivity">
<android.support.v7.widget.Toolbar
@@ -24,7 +24,7 @@
<include layout="@layout/contact_avatar_status"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/contactName"
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
android:layout_width="wrap_content"
@@ -38,19 +38,17 @@
</android.support.v7.widget.Toolbar>
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/conversationView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/window_background"/>
android:layout_weight="1"/>
<org.briarproject.android.view.TextInputView
android:id="@+id/text_input_container"
<View style="@style/Divider.Horizontal"/>
<include
layout="@layout/text_input_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/button_bar_background"
android:elevation="@dimen/margin_tiny"
app:hint="@string/message_hint"/>
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:padding="@dimen/margin_activity_horizontal"
tools:context=".android.blogs.CreateBlogActivity">
<android.support.design.widget.TextInputLayout
android:id="@+id/titleLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterOverflowTextAppearance="@style/BriarTextCounter.Overflow">
<android.support.design.widget.TextInputEditText
android:id="@+id/titleInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/blogs_my_blogs_create_hint_title"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/descLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:counterEnabled="true"
app:counterOverflowTextAppearance="@style/BriarTextCounter.Overflow">
<android.support.design.widget.TextInputEditText
android:id="@+id/descInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/blogs_my_blogs_create_hint_desc"/>
</android.support.design.widget.TextInputLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/blogs_my_blogs_create_hint_desc_explanation"/>
<Button
android:id="@+id/createBlogButton"
style="@style/BriarButton"
android:layout_marginTop="@dimen/margin_activity_vertical"
android:enabled="false"
android:text="@string/blogs_my_blogs_create"/>
<ProgressBar
android:id="@+id/createBlogProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_activity_vertical"
android:indeterminate="true"
android:visibility="gone"/>
</LinearLayout>
</ScrollView>

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_activity_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="@string/choose_nickname"
android:textSize="@dimen/text_size_large"/>
<android.support.design.widget.TextInputLayout
android:id="@+id/nicknameInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:errorEnabled="true">
<EditText
android:id="@+id/nicknameEntry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:ems="10"
android:inputType="textPersonName"
android:maxLines="1"/>
</android.support.design.widget.TextInputLayout>
<Button
android:id="@+id/createIdentityButton"
style="@style/BriarButton"
android:layout_gravity="center_horizontal"
android:enabled="false"
android:text="@string/create_identity_button"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:indeterminate="true"
android:visibility="gone"/>
</LinearLayout>

View File

@@ -6,20 +6,16 @@
android:layout_height="match_parent"
android:orientation="vertical">
<org.briarproject.android.view.BriarRecyclerView
android:id="@+id/list"
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/forum_discussion_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:emptyText="@string/no_forum_posts"
app:scrollToEnd="false"/>
<org.briarproject.android.view.TextInputView
android:id="@+id/text_input_container"
<include
layout="@layout/text_input_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/button_bar_background"
android:elevation="@dimen/margin_tiny"
app:hint="@string/forum_new_message_hint"/>
android:layout_height="wrap_content"/>
</LinearLayout>

View File

@@ -3,4 +3,14 @@
android:id="@+id/fragmentContainer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"/>
</FrameLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/invitationsView"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
style="@style/BriarToolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/content_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/window_background"/>
</FrameLayout>
</LinearLayout>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".android.privategroup.reveal.RevealContactsActivity">
<FrameLayout
android:id="@+id/fragmentContainer"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:id="@+id/revealButton"
style="@style/BriarButton"
android:layout_marginEnd="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_small"
android:layout_marginRight="@dimen/margin_small"
android:layout_marginStart="@dimen/margin_small"
android:text="@string/groups_reveal_contacts"/>
</LinearLayout>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
android:id="@+id/shareContainer"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@@ -19,7 +19,7 @@
<View style="@style/Divider.ForumList"/>
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/sharedByView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -36,7 +36,7 @@
<View style="@style/Divider.ForumList"/>
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/sharedWithView"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@@ -1,27 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_small"
tools:context=".android.blogs.WriteBlogPostActivity">
<org.briarproject.android.view.LargeTextInputView
<android.support.design.widget.TextInputLayout
android:id="@+id/titleLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:counterEnabled="true"
app:counterOverflowTextAppearance="@style/BriarTextCounter.Overflow">
<android.support.design.widget.TextInputEditText
android:id="@+id/titleInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/blogs_write_blog_post_title_hint"
android:inputType="textCapWords|textCapSentences|textAutoCorrect"/>
</android.support.design.widget.TextInputLayout>
<EditText
android:id="@+id/bodyInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="bottom"
app:buttonText="@string/blogs_publish_blog_post"
app:hint="@string/blogs_write_blog_post_body_hint"
app:fillHeight="true"/>
android:hint="@string/blogs_write_blog_post_body_hint"
android:inputType="textMultiLine|textLongMessage|textCapSentences|textAutoCorrect">
<requestFocus/>
</EditText>
<Button
android:id="@+id/publishButton"
style="@style/BriarButton"
android:enabled="false"
android:text="@string/blogs_publish_blog_post"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:visibility="invisible"/>
android:visibility="gone"/>
</FrameLayout>
</LinearLayout>

View File

@@ -9,7 +9,7 @@
style="@style/BriarAvatar"
android:layout_width="@dimen/blogs_avatar_normal_size"
android:layout_height="@dimen/blogs_avatar_normal_size"
android:layout_alignTop="@+id/authorName"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/margin_medium"
tools:src="@drawable/ic_launcher"/>
@@ -26,17 +26,18 @@
android:visibility="invisible"
tools:ignore="ContentDescription"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/authorName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/avatar"
android:layout_toEndOf="@+id/avatar"
android:layout_toRightOf="@+id/avatar"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_small"
tools:text="Author Name"/>
<org.briarproject.android.view.TrustIndicatorView
<org.briarproject.android.util.TrustIndicatorView
android:id="@+id/trustIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<merge
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<View
style="@style/Divider.Horizontal"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@color/emoji_pager_background"
android:orientation="horizontal">
<com.astuetz.PagerSlidingTabStrip
android:id="@+id/tabs"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:pstsIndicatorColor="@color/briar_accent"
app:pstsIndicatorHeight="@dimen/emoji_drawer_indicator_height"
app:pstsShouldExpand="true"
app:pstsTabPaddingLeftRight="@dimen/emoji_drawer_left_right_padding"/>
<View
android:layout_width="@dimen/margin_separator"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:background="@color/divider"/>
<org.thoughtcrime.securesms.components.RepeatableImageKey
android:id="@+id/backspace"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@color/emoji_pager_background"
android:paddingLeft="@dimen/margin_medium"
android:paddingRight="@dimen/margin_medium"
android:src="@drawable/ic_backspace_black"/>
</LinearLayout>
<View
style="@style/Divider.Horizontal"/>
<android.support.v4.view.ViewPager
android:id="@+id/emoji_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/window_background"
android:visibility="visible"/>
</merge>

View File

@@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GridView
android:id="@+id/emoji"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:columnWidth="@dimen/emoji_drawer_size"
android:gravity="center"
android:horizontalSpacing="0dp"
android:numColumns="auto_fit"
android:stretchMode="columnWidth"
android:verticalSpacing="0dp"
android:visibility="visible"/>
</FrameLayout>

View File

@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/forum_cell"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal">
<RelativeLayout
@@ -64,6 +63,7 @@
android:visibility="gone"
/>
</RelativeLayout>
<RelativeLayout
@@ -72,63 +72,111 @@
android:layout_marginLeft="@dimen/margin_medium"
android:layout_weight="1">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="@dimen/margin_medium"
android:paddingTop="@dimen/margin_medium"
android:textColor="@color/briar_text_primary"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_medium"
android:textColor="@color/briar_text_primary"
tools:text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."/>
<org.briarproject.android.view.AuthorView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size"
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatar"
android:layout_width="@dimen/forum_avatar_size"
android:layout_height="@dimen/forum_avatar_size"
android:layout_alignLeft="@id/text"
android:layout_below="@id/text"
android:layout_marginRight="@dimen/margin_small"
android:layout_marginTop="@dimen/margin_small"
android:src="@drawable/ic_launcher"
app:civ_border_color="@color/briar_primary"
app:civ_border_width="@dimen/avatar_border_width"
tools:src="@drawable/ic_launcher"
/>
<TextView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/avatar"
android:layout_alignBottom="@+id/avatar"
android:layout_alignTop="@+id/avatar"
android:gravity="center"
app:persona="commenter"/>
android:ellipsize="end"
android:maxLines="1"
android:textSize="@dimen/text_size_tiny"
tools:text="John Smith"/>
<org.briarproject.android.util.TrustIndicatorView
android:id="@+id/trustIndicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/avatar"
android:layout_alignTop="@+id/avatar"
android:scaleType="center"
android:layout_marginLeft="@dimen/margin_small"
android:layout_marginStart="@dimen/margin_small"
android:layout_toRightOf="@+id/author"
tools:src="@drawable/trust_indicator_verified"/>
<TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/avatar"
android:layout_alignTop="@+id/avatar"
android:gravity="center"
android:layout_toRightOf="@+id/trustIndicator"
android:layout_marginLeft="@dimen/margin_small"
android:layout_marginStart="@dimen/margin_small"
android:ellipsize="end"
android:maxLines="1"
android:textSize="@dimen/text_size_tiny"
tools:text="09:09"/>
<ImageView
android:id="@+id/chevron"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@id/text"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_small"
android:clickable="true"
android:src="@drawable/selector_chevron"/>
<TextView
android:id="@+id/btn_reply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/text"
android:layout_marginRight="@dimen/margin_medium"
android:layout_toLeftOf="@id/chevron"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:padding="@dimen/margin_medium"
android:text="@string/btn_reply"
android:textColor="@color/briar_button_positive"
android:textSize="@dimen/text_size_tiny"/>
<TextView
android:id="@+id/replies"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/author"
android:layout_alignTop="@+id/author"
android:layout_toLeftOf="@+id/btn_reply"
android:layout_toRightOf="@+id/author"
android:ellipsize="end"
android:gravity="right|end|center_vertical"
android:layout_alignBaseline="@id/btn_reply"
android:layout_toLeftOf="@id/btn_reply"
android:layout_toRightOf="@+id/date"
android:gravity="right|end"
android:maxLines="1"
android:padding="@dimen/margin_medium"
android:textSize="@dimen/text_size_tiny"
tools:text="2 replies"/>
<TextView
android:id="@+id/btn_reply"
style="@style/BriarButtonFlat.Positive.Tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/author"
android:layout_toLeftOf="@+id/chevron"
android:text="@string/btn_reply"
android:textSize="@dimen/text_size_tiny"/>
<ImageView
android:id="@+id/chevron"
android:layout_width="@dimen/button_size"
android:layout_height="@dimen/button_size"
android:layout_alignBottom="@+id/author"
android:layout_alignParentRight="true"
android:background="?attr/selectableItemBackground"
android:clickable="true"
android:padding="@dimen/margin_medium"
android:scaleType="center"
android:src="@drawable/selector_chevron"/>
<View
android:id="@+id/top_divider"
style="@style/Divider.ForumList"

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/postList"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This is just a placeholder to be replaced by the real My Blogs list -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/num"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:padding="@dimen/margin_activity_horizontal"
android:textSize="128sp"
tools:text="1"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="@dimen/margin_activity_horizontal"
android:text="There is nothing for you to see here.\n\nMove along and come back later."
android:textSize="@dimen/text_size_large"/>
</LinearLayout>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.util.BriarRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/contactList"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_medium">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="bottom"
android:maxLines="1"
android:inputType="text|textCapSentences"
android:hint="@string/groups_create_group_hint"/>
<Button
android:id="@+id/button"
style="@style/BriarButton"
android:enabled="false"
android:text="@string/groups_create_group_button"/>
</LinearLayout>

View File

@@ -5,11 +5,11 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.briarproject.android.view.BriarRecyclerView
<org.briarproject.android.util.BriarRecyclerView
android:id="@+id/forumList"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="org.briarproject.android.view.BriarRecyclerViewBehavior"/>
app:layout_behavior="org.briarproject.android.util.BriarRecyclerViewBehavior"/>
</android.support.design.widget.CoordinatorLayout>

View File

@@ -21,6 +21,7 @@
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_xlarge"
android:adjustViewBounds="true"
android:scaleType="fitCenter"
android:src="@drawable/qr_code_intro"
@@ -41,8 +42,7 @@
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:padding="@dimen/margin_medium"
android:src="@drawable/qr_code_explanation"
android:contentDescription="@string/face_to_face"/>
android:src="@drawable/qr_code_explanation"/>
<TextView
style="@style/BriarTextBody"

View File

@@ -5,17 +5,15 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.briarproject.android.view.CameraView
<org.briarproject.android.util.CameraView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<LinearLayout
android:id="@+id/camera_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="2">
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
@@ -33,9 +31,9 @@
android:visibility="invisible">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
android:layout_height="wrap_content"
android:paddingTop="@dimen/margin_large"/>
<TextView
android:id="@+id/connect_status"
@@ -47,50 +45,23 @@
</LinearLayout>
</FrameLayout>
<FrameLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/white">
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"/>
android:layout_centerInParent="true"
android:paddingTop="@dimen/margin_large"/>
<ImageView
android:id="@+id/qr_code"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:layout_gravity="center"/>
</FrameLayout>
android:scaleType="fitCenter"/>
</RelativeLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/container_progress"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:visibility="invisible">
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/title_progress_bar"
android:layout_centerHorizontal="true"/>
<TextView
android:id="@+id/title_progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center"
android:paddingTop="@dimen/margin_large"
tools:text="@string/waiting_for_contact_to_scan"/>
</RelativeLayout>
</FrameLayout>

View File

@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.view.LargeTextInputView
android:id="@+id/messageView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:buttonText="@string/forum_share_button"
app:fillHeight="true"
app:hint="@string/forum_share_message"/>

View File

@@ -1,47 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<ScrollView
android:id="@+id/scrollView"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:layout_height="wrap_content"
android:background="@color/window_background">
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@color/window_background">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/postLayout"
layout="@layout/list_item_blog_post"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_small"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
</ScrollView>
<org.briarproject.android.view.LargeTextInputView
android:id="@+id/inputText"
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom"
app:buttonText="@string/blogs_reblog_button"
app:maxLines="5"
app:hint="@string/blogs_reblog_comment_hint"/>
android:padding="@dimen/margin_small">
</LinearLayout>
<include
android:id="@+id/postLayout"
layout="@layout/list_item_blog_post"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
<EditText
android:id="@+id/inputText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/postLayout"
android:layout_margin="@dimen/listitem_vertical_margin"
android:gravity="bottom"
android:hint="@string/blogs_reblog_comment_hint"
android:inputType="textShortMessage|textMultiLine|textCapSentences|textAutoCorrect"/>
<Button
android:id="@+id/publishButton"
style="@style/BriarButton"
android:layout_below="@+id/inputText"
android:enabled="false"
android:text="@string/blogs_reblog_button"/>
</RelativeLayout>
</ScrollView>

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/margin_activity_horizontal"
android:orientation="vertical">
<TextView
android:id="@+id/introductionText"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="@dimen/margin_medium"
android:layout_weight="1"
android:gravity="top"
android:textSize="@dimen/text_size_medium"
android:textColor="@color/briar_text_primary"
android:text="@string/forum_share_message"/>
<EditText
android:id="@+id/invitationMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_medium"
android:gravity="bottom"
android:hint="@string/introduction_message_hint"
android:inputType="text|textMultiLine|textCapSentences"/>
<Button
android:id="@+id/shareForumButton"
style="@style/BriarButton"
android:text="@string/forum_share_button"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

View File

@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<org.briarproject.android.view.BriarRecyclerView
android:id="@+id/list"
<org.briarproject.android.util.BriarRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/contactList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:scrollToEnd="false"/>
tools:listitem="@layout/list_item_contact"/>

View File

@@ -1,126 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:fillViewport="true">
<ScrollView
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/margin_activity_horizontal">
<LinearLayout
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_activity_horizontal"
android:orientation="vertical">
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@+id/introductionIcon"
android:gravity="top|center_horizontal"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarContact1"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
tools:src="@drawable/ic_launcher"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/nameContact1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:gravity="center"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_tiny"
tools:text="Contact 1"/>
</LinearLayout>
<ImageView
android:id="@+id/introductionIcon"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_contact_introduction"
tools:ignore="ContentDescription"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@+id/introductionIcon"
android:layout_toRightOf="@+id/introductionIcon"
android:gravity="top|center_horizontal"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarContact2"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:transitionName="avatar"
tools:src="@drawable/ic_launcher"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/nameContact2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:gravity="center"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_tiny"
tools:text="Contact 2"/>
</LinearLayout>
</RelativeLayout>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:visibility="gone"/>
android:layout_toLeftOf="@+id/introductionIcon"
android:gravity="top|center_horizontal"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/introductionText"
android:layout_width="match_parent"
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarContact1"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
tools:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/nameContact1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:gravity="center"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_tiny"
tools:text="Contact 1"/>
</LinearLayout>
<ImageView
android:id="@+id/introductionIcon"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_centerHorizontal="true"
android:src="@drawable/ic_contact_introduction"
tools:ignore="ContentDescription"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_activity_horizontal"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_medium"
tools:text="@string/introduction_message_text"/>
android:layout_toEndOf="@+id/introductionIcon"
android:layout_toRightOf="@+id/introductionIcon"
android:gravity="top|center_horizontal"
android:orientation="vertical">
</LinearLayout>
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarContact2"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_picture_size"
android:layout_height="@dimen/listitem_picture_size"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:transitionName="avatar"
tools:src="@drawable/ic_launcher"/>
</ScrollView>
<TextView
android:id="@+id/nameContact2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_small"
android:gravity="center"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_tiny"
tools:text="Contact 2"/>
<org.briarproject.android.view.LargeTextInputView
android:id="@+id/introductionMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:buttonText="@string/introduction_button"
app:hint="@string/introduction_message_hint"
app:maxLines="5"/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
tools:visibility="gone"/>
<TextView
android:id="@+id/introductionText"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="@dimen/margin_medium"
android:layout_weight="1"
android:gravity="top"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_medium"
tools:text="@string/introduction_message_text"/>
<EditText
android:id="@+id/introductionMessageView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_medium"
android:gravity="bottom"
android:hint="@string/introduction_message_hint"
android:inputType="text|textMultiLine|textCapSentences"
android:textColor="@color/briar_text_primary"
android:textColorHint="@color/briar_text_tertiary"/>
<Button
android:id="@+id/makeIntroductionButton"
style="@style/BriarButton"
android:text="@string/introduction_button"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

View File

@@ -8,7 +8,7 @@
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:background="?attr/selectableItemBackground">
<org.briarproject.android.view.TextAvatarView
<org.briarproject.android.util.TextAvatarView
android:id="@+id/avatarView"
android:layout_width="@dimen/listitem_picture_frame_size"
android:layout_height="@dimen/listitem_picture_frame_size"
@@ -18,7 +18,7 @@
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/margin_medium"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -11,7 +11,7 @@
android:id="@+id/inputDivider"
style="@style/Divider.Horizontal"/>
<org.briarproject.android.view.AuthorView
<org.briarproject.android.util.AuthorView
android:id="@+id/authorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -20,7 +20,7 @@
android:padding="@dimen/listitem_vertical_margin"
app:persona="commenter"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/bodyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -19,7 +19,7 @@
android:layout_height="wrap_content"
android:padding="@dimen/listitem_vertical_margin">
<org.briarproject.android.view.AuthorView
<org.briarproject.android.util.AuthorView
android:id="@+id/rebloggerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -29,7 +29,7 @@
android:layout_toLeftOf="@+id/commentView"
app:persona="reblogger"/>
<org.briarproject.android.view.AuthorView
<org.briarproject.android.util.AuthorView
android:id="@+id/authorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -50,7 +50,7 @@
android:padding="@dimen/margin_small"
android:src="@drawable/ic_repeat"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/bodyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -11,7 +12,8 @@
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:paddingBottom="@dimen/listitem_horizontal_margin"
android:paddingTop="@dimen/listitem_horizontal_margin">
android:paddingTop="@dimen/listitem_horizontal_margin"
>
<FrameLayout
android:id="@+id/avatarFrameView"
@@ -57,7 +59,7 @@
android:layout_toRightOf="@+id/avatarFrameView"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -74,6 +76,15 @@
android:textSize="@dimen/text_size_small"
tools:text="Dec 24"/>
<TextView
android:id="@+id/identityView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/tertiary_text_light"
android:textSize="@dimen/text_size_tiny"
android:visibility="gone"
tools:text="My Identity"/>
</LinearLayout>
<ImageView

View File

@@ -17,7 +17,7 @@
android:layout_marginStart="@dimen/listitem_horizontal_margin"
tools:src="@drawable/ic_launcher"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -8,17 +8,16 @@
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:background="?attr/selectableItemBackground">
<org.briarproject.android.view.TextAvatarView
<org.briarproject.android.util.TextAvatarView
android:id="@+id/avatarView"
android:layout_width="@dimen/listitem_picture_frame_size"
android:layout_height="@dimen/listitem_picture_frame_size"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_horizontal_margin"/>
android:layout_marginRight="@dimen/listitem_horizontal_margin"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/forumNameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -1,107 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:background="?attr/selectableItemBackground">
<org.briarproject.android.view.TextAvatarView
android:id="@+id/avatarView"
android:layout_width="@dimen/listitem_picture_frame_size"
android:layout_height="@dimen/listitem_picture_frame_size"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_horizontal_margin"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="@dimen/listitem_horizontal_margin"
android:layout_toEndOf="@+id/avatarView"
android:layout_toRightOf="@+id/avatarView"
android:maxLines="2"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_medium"
tools:text="This is a name of a Private Group"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/creatorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/nameView"
android:layout_marginBottom="@dimen/margin_small"
android:layout_toEndOf="@+id/avatarView"
android:layout_toRightOf="@+id/avatarView"
android:paddingTop="@dimen/margin_small"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_small"
tools:text="Created by Santa Claus"/>
<TextView
android:id="@+id/messageCountView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/creatorView"
android:layout_marginBottom="@dimen/margin_small"
android:layout_toEndOf="@+id/avatarView"
android:layout_toRightOf="@+id/avatarView"
android:paddingTop="@dimen/margin_small"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_small"
tools:text="1337 messages"
tools:visibility="visible"/>
<TextView
android:id="@+id/dateView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/creatorView"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:paddingTop="@dimen/margin_small"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_small"
tools:text="3 weeks ago, 12:00"
tools:visibility="visible"/>
<TextView
android:id="@+id/statusView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/messageCountView"
android:layout_toEndOf="@+id/avatarView"
android:layout_toRightOf="@+id/avatarView"
android:layout_toLeftOf="@+id/removeButton"
android:paddingTop="@dimen/margin_small"
android:textColor="@color/briar_text_tertiary"
tools:text="@string/groups_group_is_empty"/>
<Button
android:id="@+id/removeButton"
style="@style/BriarButtonFlat.Negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/divider"
android:layout_alignParentRight="true"
android:text="@string/groups_remove"
tools:visibility="gone"/>
<View
android:id="@+id/divider"
style="@style/Divider.ForumList"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/statusView"
android:layout_marginTop="@dimen/listitem_horizontal_margin"/>
</RelativeLayout>

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_medium"
android:baselineAligned="false"
android:orientation="vertical">
<View
android:id="@+id/top_divider"
style="@style/Divider.ForumList"
android:layout_alignParentTop="true"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/top_divider"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_medium"
android:textStyle="italic"
tools:text="@string/groups_member_joined"/>
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/text"
android:layout_below="@+id/text"
android:layout_marginRight="@dimen/margin_small"
tools:ignore="ContentDescription"
tools:src="@drawable/ic_visibility"/>
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_below="@+id/text"
android:layout_toRightOf="@+id/icon"
android:gravity="center_vertical"
android:minHeight="24dp"
android:textColor="@color/briar_text_secondary"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_tiny"
android:textStyle="italic"
tools:text="@string/groups_reveal_visible_revealed_by_contact"/>
<org.briarproject.android.view.AuthorView
android:id="@+id/author"
android:layout_width="wrap_content"
android:layout_height="@dimen/button_size"
android:layout_alignLeft="@+id/text"
android:layout_below="@+id/info"
android:gravity="center"
app:persona="commenter"/>
<Button
android:id="@+id/optionsButton"
style="@style/BriarButtonFlat.Positive.Tiny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_alignTop="@+id/author"
android:layout_toRightOf="@+id/author"
android:gravity="right|center_vertical"
android:text="@string/options"/>
</RelativeLayout>

View File

@@ -1,55 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:paddingTop="@dimen/margin_medium">
<org.briarproject.android.view.AuthorView
android:id="@+id/authorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginBottom="@dimen/margin_small"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
app:persona="list"/>
<ImageView
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/authorView"
android:layout_marginLeft="@dimen/listitem_group_member_indentation"
android:layout_marginRight="@dimen/margin_small"
android:contentDescription="@string/forum_invitation_already_sharing"
android:src="@drawable/ic_visibility"/>
<TextView
android:id="@+id/info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/authorView"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_toRightOf="@+id/icon"
android:gravity="center_vertical"
android:minHeight="24dp"
android:textColor="@color/briar_text_secondary"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_tiny"
android:textStyle="italic"
tools:text="@string/groups_reveal_visible_revealed_by_us"/>
<View
android:id="@+id/divider"
style="@style/Divider.ContactList"
android:layout_below="@+id/info"
android:layout_marginLeft="@dimen/listitem_group_member_indentation"
android:layout_marginTop="@dimen/margin_medium"/>
</RelativeLayout>

View File

@@ -6,8 +6,8 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/msgText"
<TextView
android:id="@+id/msgBody"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
@@ -19,15 +19,15 @@
tools:text="Short message"/>
<RelativeLayout
android:id="@+id/layout"
android:id="@+id/noticeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:background="@drawable/notice_in_bottom">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
<TextView
android:id="@+id/introductionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minWidth="80dp"
@@ -38,11 +38,11 @@
tools:text="@string/introduction_request_received"/>
<TextView
android:id="@+id/time"
android:id="@+id/introductionTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_alignEnd="@+id/introductionText"
android:layout_alignRight="@+id/introductionText"
android:layout_below="@+id/declineButton"
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
android:textColor="@color/private_message_date"
@@ -54,9 +54,9 @@
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignEnd="@+id/text"
android:layout_alignRight="@+id/text"
android:layout_below="@+id/text"
android:layout_alignEnd="@+id/introductionText"
android:layout_alignRight="@+id/introductionText"
android:layout_below="@+id/introductionText"
android:text="@string/accept"/>
<Button
@@ -64,7 +64,7 @@
style="@style/BriarButtonFlat.Negative"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/text"
android:layout_below="@+id/introductionText"
android:layout_marginBottom="-15dp"
android:layout_toLeftOf="@+id/acceptButton"
android:layout_toStartOf="@+id/acceptButton"

View File

@@ -9,7 +9,7 @@
android:background="?attr/selectableItemBackground"
android:paddingTop="@dimen/listitem_horizontal_margin">
<org.briarproject.android.view.TextAvatarView
<org.briarproject.android.util.TextAvatarView
android:id="@+id/avatarView"
android:layout_width="@dimen/listitem_picture_frame_size"
android:layout_height="@dimen/listitem_picture_frame_size"
@@ -18,7 +18,7 @@
android:layout_marginRight="@dimen/listitem_horizontal_margin"
/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/forumNameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -31,7 +31,7 @@
android:textSize="@dimen/text_size_medium"
tools:text="This is a name of a forum that is available"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/sharedByView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/layout"
android:id="@+id/msgLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
@@ -10,8 +10,8 @@
android:background="@drawable/msg_in"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
<TextView
android:id="@+id/msgBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/briar_text_primary"
@@ -20,7 +20,7 @@
tools:text="Short message"/>
<TextView
android:id="@+id/time"
android:id="@+id/msgTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"

View File

@@ -6,8 +6,8 @@
android:layout_height="wrap_content"
android:orientation="vertical">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/msgText"
<TextView
android:id="@+id/msgBody"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
@@ -19,15 +19,15 @@
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
<RelativeLayout
android:id="@+id/layout"
android:id="@+id/noticeLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
android:layout_marginRight="@dimen/message_bubble_margin_tail"
android:background="@drawable/notice_out_bottom">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
<TextView
android:id="@+id/introductionText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@color/briar_text_secondary"
@@ -37,25 +37,25 @@
tools:text="@string/introduction_request_received"/>
<TextView
android:id="@+id/time"
android:id="@+id/introductionTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/text"
android:layout_below="@+id/introductionText"
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
android:textColor="@color/private_message_date"
android:textSize="@dimen/text_size_tiny"
tools:text="Dec 24, 13:37"/>
<ImageView
android:id="@+id/status"
android:id="@+id/introductionStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/time"
android:layout_alignBottom="@+id/introductionTime"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_toEndOf="@+id/time"
android:layout_toRightOf="@+id/time"
android:layout_toEndOf="@+id/introductionTime"
android:layout_toRightOf="@+id/introductionTime"
tools:ignore="ContentDescription"
tools:src="@drawable/message_delivered"/>

View File

@@ -7,7 +7,7 @@
android:orientation="vertical">
<RelativeLayout
android:id="@+id/layout"
android:id="@+id/msgLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
@@ -15,8 +15,8 @@
android:layout_marginRight="@dimen/message_bubble_margin_tail"
android:background="@drawable/msg_out">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/text"
<TextView
android:id="@+id/msgBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/briar_text_primary_inverse"
@@ -25,12 +25,12 @@
tools:text="This is a long long long message that spans over several lines.\n\nIt ends here."/>
<TextView
android:id="@+id/time"
android:id="@+id/msgTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/text"
android:layout_below="@+id/msgBody"
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
android:maxLines="1"
android:textColor="@color/private_message_date_inverse"
@@ -38,13 +38,13 @@
tools:text="Dec 24, 13:37"/>
<ImageView
android:id="@+id/status"
android:id="@+id/msgStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/time"
android:layout_alignBottom="@+id/msgTime"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_toEndOf="@+id/time"
android:layout_toRightOf="@+id/time"
android:layout_toEndOf="@+id/msgTime"
android:layout_toRightOf="@+id/msgTime"
tools:ignore="ContentDescription"
tools:src="@drawable/message_delivered_white"/>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/notice_in"
android:orientation="vertical"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail">
<TextView
android:id="@+id/noticeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_medium"
android:textStyle="italic"
android:textColor="@color/briar_text_secondary"
tools:text="@string/introduction_response_accepted_received"/>
<TextView
android:id="@+id/noticeTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
android:maxLines="1"
android:textColor="@color/private_message_date"
android:textSize="@dimen/text_size_tiny"
tools:text="Dec 24, 13:37"/>
</LinearLayout>

View File

@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right|end"
android:background="@drawable/notice_out"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
android:layout_marginRight="@dimen/message_bubble_margin_tail">
<TextView
android:id="@+id/noticeText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:textSize="@dimen/text_size_medium"
android:textStyle="italic"
android:textColor="@color/briar_text_secondary"
tools:text="@string/introduction_response_accepted_sent"/>
<TextView
android:id="@+id/noticeTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/message_bubble_timestamp_margin"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/noticeText"
android:textColor="@color/private_message_date"
android:textSize="@dimen/text_size_tiny"
tools:text="Dec 24, 13:37"/>
<ImageView
android:id="@+id/noticeStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/noticeTime"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_toEndOf="@+id/noticeTime"
android:layout_toRightOf="@+id/noticeTime"
tools:ignore="ContentDescription"
tools:src="@drawable/message_delivered"/>
</RelativeLayout>
</LinearLayout>

View File

@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/selectableItemBackground"
android:orientation="vertical"
android:padding="@dimen/listitem_horizontal_margin">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/avatarView"
style="@style/BriarAvatar"
android:layout_width="@dimen/listitem_selectable_picture_size"
android:layout_height="@dimen/listitem_selectable_picture_size"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:transitionName="avatar"
tools:src="@drawable/ic_launcher"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/avatarView"
android:textColor="@color/briar_text_primary"
android:textSize="@dimen/text_size_large"
tools:text="Revealable Contact"/>
<ImageView
android:id="@+id/visibilityView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/nameView"
android:layout_marginRight="@dimen/margin_small"
android:layout_toRightOf="@+id/avatarView"
android:src="@drawable/ic_visibility"
tools:ignore="ContentDescription"/>
<TextView
android:id="@+id/infoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/nameView"
android:layout_toLeftOf="@+id/checkBox"
android:layout_toRightOf="@+id/visibilityView"
android:gravity="center_vertical"
android:text="@string/groups_reveal_visible"
android:textColor="@color/briar_text_tertiary"
android:textSize="@dimen/text_size_small"
tools:visibility="visible"/>
<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:clickable="false"/>
</RelativeLayout>
<View style="@style/Divider.ContactList"/>
</LinearLayout>

View File

@@ -9,7 +9,7 @@
android:layout_marginTop="@dimen/listitem_horizontal_margin"
android:background="?attr/selectableItemBackground">
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/titleView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -41,7 +41,7 @@
android:textColor="@color/briar_text_secondary"
android:textSize="@dimen/text_size_small"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/authorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -100,7 +100,7 @@
android:textSize="@dimen/text_size_small"
tools:text="5 min. ago"/>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
<TextView
android:id="@+id/descriptionView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

Some files were not shown because too many files have changed in this diff Show More