Compare commits

..

3 Commits

Author SHA1 Message Date
akwizgran
84b3670624 Create hidden service via conf file so we can use Tor 0.2.6. 2016-08-27 08:45:01 +01:00
akwizgran
749695187e Disable verification of Tor binaries so we can use old ones. 2016-08-26 23:30:58 +01:00
akwizgran
c4db72abf2 Revert Tor performance improvements for measurement. 2016-08-26 22:22:44 +01:00
837 changed files with 15665 additions and 38051 deletions

View File

@@ -31,42 +31,12 @@
</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>
<JavaCodeStyleSettings>
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
</JavaCodeStyleSettings>
<Objective-C-extensions>
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
<option name="RELEASE_STYLE" value="IVAR" />
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" />
<pair source="c" header="h" />
</extensions>
</Objective-C-extensions>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
</XML>

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

@@ -3,7 +3,6 @@ package org.briarproject;
import net.jodah.concurrentunit.Waiter;
import org.briarproject.api.blogs.Blog;
import org.briarproject.api.blogs.BlogCommentHeader;
import org.briarproject.api.blogs.BlogFactory;
import org.briarproject.api.blogs.BlogManager;
import org.briarproject.api.blogs.BlogPost;
@@ -12,6 +11,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;
@@ -50,17 +50,15 @@ import javax.inject.Inject;
import static junit.framework.Assert.assertFalse;
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
import static org.briarproject.api.blogs.MessageType.COMMENT;
import static org.briarproject.api.blogs.MessageType.POST;
import static org.briarproject.api.blogs.MessageType.WRAPPED_COMMENT;
import static org.briarproject.api.blogs.MessageType.WRAPPED_POST;
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.briarproject.api.sync.ValidationManager.State.VALID;
import static org.junit.Assert.assertArrayEquals;
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;
@@ -91,9 +89,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
private final int TIMEOUT = 15000;
private final String AUTHOR1 = "Author 1";
private final String AUTHOR2 = "Author 2";
private final String CONTENT_TYPE = "text/plain";
private static final Logger LOG =
Logger.getLogger(BlogManagerTest.class.getName());
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
private BlogManagerTestComponent t0, t1;
@@ -173,15 +172,15 @@ public class BlogManagerTest extends BriarIntegrationTest {
defaultInit();
// check that blog0 has no posts
final String body = TestUtils.getRandomString(42);
final byte[] body = TestUtils.getRandomBytes(42);
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog0.getId());
assertEquals(0, headers0.size());
// add a post to blog0
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
.createBlogPost(blog0.getId(), null, clock.currentTimeMillis(),
null, author0, CONTENT_TYPE, body);
blogManager0.addLocalPost(p);
// check that post is now in blog0
@@ -189,7 +188,8 @@ public class BlogManagerTest extends BriarIntegrationTest {
assertEquals(1, headers0.size());
// check that body is there
assertEquals(body, blogManager0.getPostBody(p.getMessage().getId()));
assertArrayEquals(body,
blogManager0.getPostBody(p.getMessage().getId()));
// make sure that blog0 at author1 doesn't have the post yet
Collection<BlogPostHeader> headers1 =
@@ -203,10 +203,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
// make sure post arrived
headers1 = blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// check that body is there
assertEquals(body, blogManager1.getPostBody(p.getMessage().getId()));
assertArrayEquals(body,
blogManager1.getPostBody(p.getMessage().getId()));
stopLifecycles();
}
@@ -217,10 +217,10 @@ public class BlogManagerTest extends BriarIntegrationTest {
defaultInit();
// add a post to blog1
final String body = TestUtils.getRandomString(42);
final byte[] body = TestUtils.getRandomBytes(42);
BlogPost p = blogPostFactory
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
author0, body);
.createBlogPost(blog1.getId(), null, clock.currentTimeMillis(),
null, author0, CONTENT_TYPE, body);
blogManager0.addLocalPost(p);
// check that post is now in blog1
@@ -240,6 +240,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();
@@ -261,262 +287,20 @@ public class BlogManagerTest extends BriarIntegrationTest {
stopLifecycles();
}
@Test
public void testBlogComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 adds a comment to that blog post
String comment = "This is a comment on a blog post!";
blogManager1
.addLocalComment(author1, blog1.getId(), comment,
headers1.iterator().next());
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 2);
// make sure comment and wrapped post arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(1, headers0.size());
assertEquals(COMMENT, headers0.iterator().next().getType());
BlogCommentHeader h = (BlogCommentHeader) headers0.iterator().next();
assertEquals(author0, h.getParent().getAuthor());
// ensure that body can be retrieved from wrapped post
assertEquals(body, blogManager0.getPostBody(h.getParentId()));
// 1 has only their own comment in their blog
headers1 = blogManager1.getPostHeaders(blog1.getId());
assertEquals(1, headers1.size());
stopLifecycles();
}
@Test
public void testBlogCommentOnOwnPost() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// get header of own post
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog0.getId());
assertEquals(1, headers0.size());
BlogPostHeader header = headers0.iterator().next();
// add a comment on own post
String comment = "This is a comment on my own blog post!";
blogManager0
.addLocalComment(author0, blog0.getId(), comment, header);
// sync the post and comment over
sync0To1();
deliveryWaiter.await(TIMEOUT, 2);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(2, headers1.size());
for (BlogPostHeader h : headers1) {
if (h.getType() == POST) {
assertEquals(body, blogManager1.getPostBody(h.getId()));
} else {
assertEquals(comment, ((BlogCommentHeader)h).getComment());
}
}
stopLifecycles();
}
@Test
public void testCommentOnComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 reblogs that blog post
blogManager1
.addLocalComment(author1, blog1.getId(), null,
headers1.iterator().next());
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 2);
// make sure comment and wrapped post arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(1, headers0.size());
// get header of comment
BlogPostHeader cHeader = headers0.iterator().next();
assertEquals(COMMENT, cHeader.getType());
// comment on the comment
String comment = "This is a comment on a reblogged post.";
blogManager0
.addLocalComment(author0, blog0.getId(), comment, cHeader);
// sync comment over
sync0To1();
deliveryWaiter.await(TIMEOUT, 3);
// check that comment arrived
headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(2, headers1.size());
// get header of comment
cHeader = null;
for (BlogPostHeader h : headers1) {
if (h.getType() == COMMENT) {
cHeader = h;
}
}
assertTrue(cHeader != null);
// another comment on the comment
String comment2 = "This is a comment on a comment.";
blogManager1.addLocalComment(author1, blog1.getId(), comment2, cHeader);
// sync comment over
sync1To0();
deliveryWaiter.await(TIMEOUT, 4);
// make sure new comment arrived
headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(2, headers0.size());
boolean satisfied = false;
for (BlogPostHeader h : headers0) {
assertEquals(COMMENT, h.getType());
BlogCommentHeader c = (BlogCommentHeader) h;
if (c.getComment() != null && c.getComment().equals(comment2)) {
assertEquals(author0, c.getParent().getAuthor());
assertEquals(WRAPPED_COMMENT, c.getParent().getType());
assertEquals(comment,
((BlogCommentHeader) c.getParent()).getComment());
assertEquals(WRAPPED_COMMENT,
((BlogCommentHeader) c.getParent()).getParent()
.getType());
assertEquals(WRAPPED_POST,
((BlogCommentHeader) ((BlogCommentHeader) c
.getParent()).getParent()).getParent()
.getType());
satisfied = true;
}
}
assertTrue(satisfied);
stopLifecycles();
}
@Test
public void testCommentOnOwnComment() throws Exception {
startLifecycles();
defaultInit();
// add a post to blog0
final String body = TestUtils.getRandomString(42);
BlogPost p = blogPostFactory
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
author0, body);
blogManager0.addLocalPost(p);
// sync the post over
sync0To1();
deliveryWaiter.await(TIMEOUT, 1);
// make sure post arrived
Collection<BlogPostHeader> headers1 =
blogManager1.getPostHeaders(blog0.getId());
assertEquals(1, headers1.size());
assertEquals(POST, headers1.iterator().next().getType());
// 1 reblogs that blog post with a comment
String comment = "This is a comment on a post.";
blogManager1
.addLocalComment(author1, blog1.getId(), comment,
headers1.iterator().next());
// get comment from own blog
headers1 = blogManager1.getPostHeaders(blog1.getId());
assertEquals(1, headers1.size());
assertEquals(COMMENT, headers1.iterator().next().getType());
BlogCommentHeader ch = (BlogCommentHeader) headers1.iterator().next();
assertEquals(comment, ch.getComment());
comment = "This is a comment on a post with a comment.";
blogManager1.addLocalComment(author1, blog1.getId(), comment, ch);
// sync both comments over (2 comments + 1 wrapped post)
sync1To0();
deliveryWaiter.await(TIMEOUT, 3);
// make sure both comments arrived
Collection<BlogPostHeader> headers0 =
blogManager0.getPostHeaders(blog1.getId());
assertEquals(2, headers0.size());
stopLifecycles();
}
@After
public void tearDown() throws Exception {
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) {
deliveryWaiter.resume();
} else if (event.getState() == INVALID ||
} else if (event.getState() == VALID ||
event.getState() == INVALID ||
event.getState() == PENDING) {
validationWaiter.resume();
}
@@ -526,16 +310,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 +387,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,7 @@ 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.ClientId;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
import org.briarproject.api.sync.ValidationManager.State;
@@ -58,28 +57,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 +84,6 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
@Inject
AuthorFactory authorFactory;
@Inject
ContactGroupFactory contactGroupFactory;
@Inject
BlogPostFactory blogPostFactory;
@Inject
CryptoComponent cryptoComponent;
@@ -144,13 +139,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 +188,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 +233,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();
}
@@ -440,7 +424,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
eventWaiter.await(TIMEOUT, 1);
assertTrue(listener0.responseReceived);
// blog was added successfully and is shared both ways
// blog was added successfully and is shard both ways
assertEquals(3, blogManager1.getBlogs().size());
Collection<Contact> sharedWith =
blogSharingManager0.getSharedWith(blog2.getId());
@@ -527,15 +511,23 @@ 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) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Sharer received message");
ClientId c = event.getClientId();
if ((s == DELIVERED || s == INVALID) &&
c.equals(blogSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Sharer received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(blogManager0.getClientId())) {
LOG.info("TEST: Sharer received blog post");
msgWaiter.resume();
}
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
@@ -550,7 +542,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,26 +558,34 @@ 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);
}
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Invitee received message");
ClientId c = event.getClientId();
if ((s == DELIVERED || s == INVALID) &&
c.equals(blogSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Invitee received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(blogManager0.getClientId())) {
LOG.info("TEST: Invitee received blog post");
msgWaiter.resume();
}
} else if (e instanceof BlogInvitationReceivedEvent) {
@@ -592,7 +593,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 +611,7 @@ public class BlogSharingIntegrationTest extends BriarIntegrationTest {
BlogInvitationResponseReceivedEvent event =
(BlogInvitationResponseReceivedEvent) e;
eventWaiter.assertEquals(contactId01, event.getContactId());
responseReceived = true;
eventWaiter.resume();
}
}
@@ -620,9 +622,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 +641,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 +675,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 +686,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 +704,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,19 @@ 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.briarproject.api.sync.ValidationManager.State.VALID;
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 +76,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 +116,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 +128,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 +151,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 +203,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();
}
@@ -319,7 +298,7 @@ public class ForumManagerTest extends BriarIntegrationTest {
assertEquals(1, forumManager0.getPostHeaders(g).size());
assertEquals(0, forumManager1.getPostHeaders(g).size());
// send the child post to 1
// send posts to 1
sync0To1();
validationWaiter.await(TIMEOUT, 1);
assertEquals(1, forumManager0.getPostHeaders(g).size());
@@ -348,14 +327,14 @@ public class ForumManagerTest extends BriarIntegrationTest {
}
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) {
deliveryWaiter.resume();
} else if (event.getState() == INVALID ||
} else if (event.getState() == VALID ||
event.getState() == INVALID ||
event.getState() == PENDING) {
validationWaiter.resume();
}
@@ -365,15 +344,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 +419,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,8 +36,9 @@ 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.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.SyncSession;
import org.briarproject.api.sync.SyncSessionFactory;
@@ -68,7 +72,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 +424,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 +447,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 +502,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 +517,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 +588,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 +698,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 +715,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 +736,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
startLifecycles();
try {
// initialize
getDefaultIdentities();
addDefaultIdentities();
addDefaultContacts();
addForumForSharer();
@@ -735,7 +744,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 +765,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 +786,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 +825,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 +846,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 +891,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,16 +925,23 @@ 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) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Sharer received message");
ClientId c = event.getClientId();
if ((s == DELIVERED || s == INVALID) &&
c.equals(forumSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Sharer received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(forumManager0.getClientId())) {
LOG.info("TEST: Sharer received forum post");
msgWaiter.resume();
}
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
@@ -937,7 +957,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,27 +972,34 @@ 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);
}
@Override
public void eventOccurred(Event e) {
if (e instanceof MessageStateChangedEvent) {
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
State s = event.getState();
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
LOG.info("TEST: Invitee received message");
ClientId c = event.getClientId();
if ((s == DELIVERED || s == INVALID) &&
c.equals(forumSharingManager0.getClientId()) &&
!event.isLocal()) {
LOG.info("TEST: Invitee received message in group " +
event.getMessage().getGroupId().hashCode());
msgWaiter.resume();
} else if (s == DELIVERED && !event.isLocal() &&
c.equals(forumManager0.getClientId())) {
LOG.info("TEST: Invitee received forum post");
msgWaiter.resume();
}
} else if (e instanceof ForumInvitationReceivedEvent) {
@@ -980,11 +1007,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 +1042,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 +1061,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 +1124,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 +1155,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,5 @@
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 +15,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 +45,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,16 +79,12 @@ interface IntroductionIntegrationTestComponent {
TransportPropertyManager getTransportPropertyManager();
MessageTracker getMessageTracker();
SyncSessionFactory getSyncSessionFactory();
/* the following methods are only needed to manually construct messages */
DatabaseComponent getDatabaseComponent();
ClientHelper getClientHelper();
MessageSender getMessageSender();
IntroductionGroupFactory getIntroductionGroupFactory();

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">
@@ -267,17 +211,6 @@
/>
</activity>
<activity
android:name=".android.blogs.ReblogActivity"
android:label="@string/blogs_reblog_button"
android:parentActivityName=".android.blogs.BlogActivity"
android:windowSoftInputMode="stateHidden">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.blogs.BlogActivity"
/>
</activity>
<activity
android:name=".android.blogs.RssFeedImportActivity"
android:label="@string/blogs_rss_feeds_import"
@@ -299,6 +232,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

@@ -11,6 +11,9 @@ dependencies {
compile project(':briar-api')
compile project(':briar-core')
compile fileTree(dir: 'libs', include: '*.jar')
// This shouldn't be necessary; per section 23.4.4 of the Gradle docs:
// "file dependencies are included in transitive project dependencies within the same build".
compile files('../briar-core/libs/jsocks.jar')
compile "com.android.support:support-v4:$supportVersion"
compile("com.android.support:appcompat-v7:$supportVersion") {
@@ -24,21 +27,16 @@ dependencies {
exclude module: 'support-v4'
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 +51,16 @@ 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 +119,10 @@ android {
warning 'MissingTranslation'
warning 'ImpliedQuantity'
}
dexOptions {
incremental true
}
}
task downloadTorGeoIp(type: Download) {
@@ -191,8 +189,8 @@ project.afterEvaluate {
preBuild.dependsOn {
[
'verifyTorGeoIp',
'verifyTorBinaryArm',
'verifyTorBinaryArmPie',
// 'verifyTorBinaryArm',
// 'verifyTorBinaryArmPie',
'verifyTorBinaryX86',
'verifyTorBinaryX86Pie'
]

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 *;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 175 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -1,5 +0,0 @@
<vector android:alpha="0.54" android:height="24dp"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15.73,3L8.27,3L3,8.27v7.46L8.27,21h7.46L21,15.73L21,8.27L15.73,3zM12,17.3c-0.72,0 -1.3,-0.58 -1.3,-1.3 0,-0.72 0.58,-1.3 1.3,-1.3 0.72,0 1.3,0.58 1.3,1.3 0,0.72 -0.58,1.3 -1.3,1.3zM13,13h-2L11,7h2v6z"/>
</vector>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:radius="@dimen/unread_bubble_size"/>
<solid
android:color="@color/briar_text_primary_inverse"/>
<stroke
android:color="@color/briar_text_primary"
android:width="1dp"/>
</shape>

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

@@ -6,5 +6,5 @@
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z"/>
</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

@@ -4,6 +4,6 @@
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M20,4L4,4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2zM20,8l-8,5 -8,-5L4,6l8,5 8,-5v2z"/>
android:fillColor="#FF000000"
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
</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="16dp"
android:height="16dp"
android:alpha="0.54"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M12,5.9c1.16,0 2.1,0.94 2.1,2.1s-0.94,2.1 -2.1,2.1S9.9,9.16 9.9,8s0.94,-2.1 2.1,-2.1m0,9c2.97,0 6.1,1.46 6.1,2.1v1.1L5.9,18.1L5.9,17c0,-0.64 3.13,-2.1 6.1,-2.1M12,4C9.79,4 8,5.79 8,8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,13c-2.67,0 -8,1.34 -8,4v3h16v-3c0,-2.66 -5.33,-4 -8,-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="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>

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