Compare commits
218 Commits
384-conver
...
377_replac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cef4c31e0b | ||
|
|
62527a62c1 | ||
|
|
89ab4dd04e | ||
|
|
f3ea731565 | ||
|
|
bf023874f0 | ||
|
|
16ac73d002 | ||
|
|
cc439aa74f | ||
|
|
7a1003178d | ||
|
|
cab667ef6a | ||
|
|
7035d8063c | ||
|
|
2fbbb663a3 | ||
|
|
b4714b5360 | ||
|
|
8a3e5bfb50 | ||
|
|
fd4275733f | ||
|
|
af5b246d7b | ||
|
|
49e9ee2b6d | ||
|
|
1a611d55be | ||
|
|
7c5945de01 | ||
|
|
ccc49df08e | ||
|
|
ac325d4423 | ||
|
|
0a0e1b4280 | ||
|
|
cb64740916 | ||
|
|
73bc86df4a | ||
|
|
307e124ee8 | ||
|
|
60b4c5649a | ||
|
|
e0e46a726e | ||
|
|
668eaf45f6 | ||
|
|
fb9d743d11 | ||
|
|
fc2213c042 | ||
|
|
34f9311f43 | ||
|
|
28fd84b261 | ||
|
|
448bf86379 | ||
|
|
91e529a9e9 | ||
|
|
74f9a0dd73 | ||
|
|
54290bc374 | ||
|
|
3e39ad8a68 | ||
|
|
07445ada41 | ||
|
|
5281d8b468 | ||
|
|
0deac1d1b6 | ||
|
|
387e44d114 | ||
|
|
bb00412187 | ||
|
|
bb0a2a5b32 | ||
|
|
6d7e0aab07 | ||
|
|
da08072409 | ||
|
|
9664aea520 | ||
|
|
636b587b9c | ||
|
|
0afab09fdf | ||
|
|
fe4f71fe0f | ||
|
|
6f0ffa8439 | ||
|
|
69dd399bd2 | ||
|
|
8b7304f4cb | ||
|
|
e023e5d8fc | ||
|
|
042050453a | ||
|
|
1c15e690e1 | ||
|
|
61c05c1dd4 | ||
|
|
d8a9d83caf | ||
|
|
70a44e8a27 | ||
|
|
fc5a7290e3 | ||
|
|
7db0e4472a | ||
|
|
65bdd5558e | ||
|
|
3dd3a18694 | ||
|
|
743fc7dd1f | ||
|
|
eb3da2aac9 | ||
|
|
4518f59a54 | ||
|
|
11c0cb667f | ||
|
|
132a03d0a9 | ||
|
|
c666b0493c | ||
|
|
625276067a | ||
|
|
30f2c192c6 | ||
|
|
55602ed76a | ||
|
|
4ad0df2640 | ||
|
|
d93f59b4ef | ||
|
|
c5f0272621 | ||
|
|
419aa2e97e | ||
|
|
015e45752e | ||
|
|
743053930a | ||
|
|
cc7602e566 | ||
|
|
8b56e082b3 | ||
|
|
b4889fe293 | ||
|
|
ca094620d8 | ||
|
|
83be5c766e | ||
|
|
72fb4e9bc7 | ||
|
|
e10f68b496 | ||
|
|
22e7ec5b27 | ||
|
|
3bccdfa947 | ||
|
|
ef02908082 | ||
|
|
3aa3811d1b | ||
|
|
00240bfa57 | ||
|
|
1f5de42844 | ||
|
|
17f9972a56 | ||
|
|
18dd7d7aa9 | ||
|
|
bc6557e82d | ||
|
|
5f86dd0207 | ||
|
|
659cf85ca1 | ||
|
|
294bc0bdd2 | ||
|
|
be84afc543 | ||
|
|
c6c62cab6c | ||
|
|
d24e18a5d9 | ||
|
|
34a4a3f3c6 | ||
|
|
48e1a65a24 | ||
|
|
28be7d5de3 | ||
|
|
dbdf567d4e | ||
|
|
98337a16ec | ||
|
|
d34afa5f30 | ||
|
|
746fce1b95 | ||
|
|
c3a14d9275 | ||
|
|
e690bcb3cc | ||
|
|
70b311db13 | ||
|
|
caee7fe61b | ||
|
|
84d4bf2205 | ||
|
|
bcf7488afd | ||
|
|
71196e3494 | ||
|
|
9defb099dd | ||
|
|
b3d6e7d12d | ||
|
|
739e8b4511 | ||
|
|
cb9a85eb88 | ||
|
|
7e086d0f4e | ||
|
|
dccc2e6ded | ||
|
|
72906acaee | ||
|
|
6fc7e69849 | ||
|
|
30092550c7 | ||
|
|
b17fbcb135 | ||
|
|
060860bea5 | ||
|
|
f8337d09ae | ||
|
|
4055bbfcd4 | ||
|
|
44d13ef28e | ||
|
|
1ec56fa3ef | ||
|
|
fce104487a | ||
|
|
17db03d40a | ||
|
|
3bbc8dcc4e | ||
|
|
930194accf | ||
|
|
b04bde4f41 | ||
|
|
054a0d467c | ||
|
|
adc85dab7e | ||
|
|
55b7e95d35 | ||
|
|
36d15358a1 | ||
|
|
d15d82ccec | ||
|
|
7be17668c1 | ||
|
|
f8f1c7f0d4 | ||
|
|
dd0d23359b | ||
|
|
1a32458783 | ||
|
|
a4cf91fba5 | ||
|
|
16da3f2cab | ||
|
|
a3b2358164 | ||
|
|
e4f5d8e6e7 | ||
|
|
a69a4028b0 | ||
|
|
a552d1b6a6 | ||
|
|
2f7d188a07 | ||
|
|
4a4366078a | ||
|
|
9a32a13767 | ||
|
|
50d2742cae | ||
|
|
747ed023e4 | ||
|
|
e8c398e996 | ||
|
|
85c9b48196 | ||
|
|
2a2966bd6c | ||
|
|
62c1c3e08d | ||
|
|
6454acdaa5 | ||
|
|
8d1a26ba72 | ||
|
|
e527e30712 | ||
|
|
4af5dbb45b | ||
|
|
7132c88644 | ||
|
|
a452060b41 | ||
|
|
60a381430e | ||
|
|
827fd0aebb | ||
|
|
23eb5acafa | ||
|
|
2170d291a2 | ||
|
|
31cd6e8958 | ||
|
|
a51d2f47af | ||
|
|
0d9cbb2793 | ||
|
|
c17ef86968 | ||
|
|
ff28ae296e | ||
|
|
ce2cb01558 | ||
|
|
d096c1fead | ||
|
|
36dd9c30f8 | ||
|
|
2c993b62c2 | ||
|
|
737f0dac1e | ||
|
|
5a2fd2018f | ||
|
|
15d139afd4 | ||
|
|
2577b2ab2a | ||
|
|
04af39f567 | ||
|
|
64b596d0f9 | ||
|
|
8bbb2184ff | ||
|
|
bca12bb0e5 | ||
|
|
32578e2cab | ||
|
|
0ffbc28792 | ||
|
|
38979ef504 | ||
|
|
5c186db4e4 | ||
|
|
49437522f6 | ||
|
|
6511c13752 | ||
|
|
1bfa1016b4 | ||
|
|
f3d0ffa09f | ||
|
|
d8272d875b | ||
|
|
e782e699fe | ||
|
|
bdb876552d | ||
|
|
e1bdede4f5 | ||
|
|
9ff4758683 | ||
|
|
fa0639d220 | ||
|
|
cf6aa01905 | ||
|
|
3d22d43868 | ||
|
|
bbf12ca0c4 | ||
|
|
04d2ede2e1 | ||
|
|
c47171c06e | ||
|
|
7318aa562e | ||
|
|
ddbac36913 | ||
|
|
c019d8ecf0 | ||
|
|
c12c60d000 | ||
|
|
8504cfa88b | ||
|
|
dd1eed5aa7 | ||
|
|
39d91e026b | ||
|
|
412bf162ce | ||
|
|
d8b5710a42 | ||
|
|
fd7278b488 | ||
|
|
e0d2d09bdd | ||
|
|
761525ad85 | ||
|
|
f7d5c1f63c | ||
|
|
365fbb45ad | ||
|
|
d05237d2c1 | ||
|
|
4c4f4ad2d5 |
6
.idea/codeStyleSettings.xml
generated
@@ -68,6 +68,12 @@
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||
</XML>
|
||||
<codeStyleSettings language="Groovy">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true" />
|
||||
<option name="SMART_TABS" value="true" />
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="RIGHT_MARGIN" value="80" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'witness'
|
||||
apply plugin: 'com.neenbedankt.android-apt'
|
||||
|
||||
android {
|
||||
@@ -7,20 +6,15 @@ android {
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 22
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
minSdkVersion 14
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
||||
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
incremental true
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_7
|
||||
targetCompatibility JavaVersion.VERSION_1_7
|
||||
@@ -28,23 +22,12 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile project(':briar-api')
|
||||
compile project(':briar-core')
|
||||
testCompile project(':briar-api')
|
||||
testCompile project(':briar-core')
|
||||
testCompile 'junit:junit:4.12'
|
||||
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||
compile 'com.android.support:appcompat-v7:23.2.1'
|
||||
testCompile 'com.android.support:appcompat-v7:23.2.1'
|
||||
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
provided 'javax.annotation:jsr250-api:1.0'
|
||||
testCompile project(':briar-tests')
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
verify = [
|
||||
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
||||
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
||||
'com.android.support:animated-vector-drawable:06d1963b85aa917099d7757e6a7b3e4dc06889413dc747f625ae8683606db3a1',
|
||||
'com.android.support:support-vector-drawable:799bafe4c3de812386f0b291f744d5d6876452722dd40189b9ab87dbbf594ea1',
|
||||
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
|
||||
]
|
||||
}
|
||||
|
||||
17
briar-android-tests/proguard-rules.pro
vendored
@@ -1,17 +0,0 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /home/ernir/dev/sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
@@ -3,6 +3,7 @@ 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;
|
||||
@@ -33,7 +34,9 @@ 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;
|
||||
@@ -48,11 +51,13 @@ 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;
|
||||
|
||||
@@ -87,13 +92,15 @@ public class BlogManagerTest {
|
||||
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(ForumSharingIntegrationTest.class.getName());
|
||||
|
||||
private BlogManagerTestComponent t0, t1;
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
BlogManagerTestComponent component =
|
||||
@@ -167,15 +174,15 @@ public class BlogManagerTest {
|
||||
defaultInit();
|
||||
|
||||
// check that blog0 has no posts
|
||||
final byte[] body = TestUtils.getRandomBytes(42);
|
||||
final String body = TestUtils.getRandomString(42);
|
||||
Collection<BlogPostHeader> headers0 =
|
||||
blogManager0.getPostHeaders(blog0.getId());
|
||||
assertEquals(0, headers0.size());
|
||||
|
||||
// add a post to blog0
|
||||
BlogPost p = blogPostFactory
|
||||
.createBlogPost(blog0.getId(), null, clock.currentTimeMillis(),
|
||||
null, author0, CONTENT_TYPE, body);
|
||||
.createBlogPost(blog0.getId(), clock.currentTimeMillis(), null,
|
||||
author0, body);
|
||||
blogManager0.addLocalPost(p);
|
||||
|
||||
// check that post is now in blog0
|
||||
@@ -183,8 +190,7 @@ public class BlogManagerTest {
|
||||
assertEquals(1, headers0.size());
|
||||
|
||||
// check that body is there
|
||||
assertArrayEquals(body,
|
||||
blogManager0.getPostBody(p.getMessage().getId()));
|
||||
assertEquals(body, blogManager0.getPostBody(p.getMessage().getId()));
|
||||
|
||||
// make sure that blog0 at author1 doesn't have the post yet
|
||||
Collection<BlogPostHeader> headers1 =
|
||||
@@ -198,10 +204,10 @@ public class BlogManagerTest {
|
||||
// make sure post arrived
|
||||
headers1 = blogManager1.getPostHeaders(blog0.getId());
|
||||
assertEquals(1, headers1.size());
|
||||
assertEquals(POST, headers1.iterator().next().getType());
|
||||
|
||||
// check that body is there
|
||||
assertArrayEquals(body,
|
||||
blogManager1.getPostBody(p.getMessage().getId()));
|
||||
assertEquals(body, blogManager1.getPostBody(p.getMessage().getId()));
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
@@ -212,10 +218,10 @@ public class BlogManagerTest {
|
||||
defaultInit();
|
||||
|
||||
// add a post to blog1
|
||||
final byte[] body = TestUtils.getRandomBytes(42);
|
||||
final String body = TestUtils.getRandomString(42);
|
||||
BlogPost p = blogPostFactory
|
||||
.createBlogPost(blog1.getId(), null, clock.currentTimeMillis(),
|
||||
null, author0, CONTENT_TYPE, body);
|
||||
.createBlogPost(blog1.getId(), clock.currentTimeMillis(), null,
|
||||
author0, body);
|
||||
blogManager0.addLocalPost(p);
|
||||
|
||||
// check that post is now in blog1
|
||||
@@ -249,6 +255,7 @@ public class BlogManagerTest {
|
||||
assertEquals(3, blogs0.size());
|
||||
assertTrue(blogs0.contains(blog));
|
||||
assertEquals(2, blogManager0.getBlogs(author0).size());
|
||||
assertTrue(blogManager0.canBeRemoved(blog.getId()));
|
||||
|
||||
// remove blog
|
||||
blogManager0.removeBlog(blog);
|
||||
@@ -260,20 +267,282 @@ public class BlogManagerTest {
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanNotRemoveContactsPersonalBlog() throws Exception {
|
||||
startLifecycles();
|
||||
defaultInit();
|
||||
|
||||
assertFalse(blogManager0.canBeRemoved(blog1.getId()));
|
||||
assertFalse(blogManager1.canBeRemoved(blog0.getId()));
|
||||
|
||||
// the following two calls should throw a DbException now
|
||||
thrown.expect(DbException.class);
|
||||
|
||||
blogManager0.removeBlog(blog1);
|
||||
blogManager1.removeBlog(blog0);
|
||||
|
||||
// blogs have not been removed
|
||||
assertEquals(2, blogManager0.getBlogs().size());
|
||||
assertEquals(2, blogManager1.getBlogs().size());
|
||||
|
||||
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() == VALID ||
|
||||
event.getState() == INVALID ||
|
||||
} else if (event.getState() == INVALID ||
|
||||
event.getState() == PENDING) {
|
||||
validationWaiter.resume();
|
||||
}
|
||||
@@ -310,12 +579,12 @@ public class BlogManagerTest {
|
||||
// sharer adds invitee as contact
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
// invitee adds sharer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,744 @@
|
||||
package org.briarproject;
|
||||
|
||||
import net.jodah.concurrentunit.Waiter;
|
||||
|
||||
import org.briarproject.api.blogs.Blog;
|
||||
import org.briarproject.api.blogs.BlogInvitationRequest;
|
||||
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.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;
|
||||
import org.briarproject.api.event.BlogInvitationResponseReceivedEvent;
|
||||
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.sharing.InvitationMessage;
|
||||
import org.briarproject.api.sync.SyncSession;
|
||||
import org.briarproject.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.api.sync.ValidationManager.State;
|
||||
import org.briarproject.api.system.Clock;
|
||||
import org.briarproject.blogs.BlogsModule;
|
||||
import org.briarproject.contact.ContactModule;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
import org.briarproject.lifecycle.LifecycleModule;
|
||||
import org.briarproject.properties.PropertiesModule;
|
||||
import org.briarproject.sharing.SharingModule;
|
||||
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.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
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.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 BriarTestCase {
|
||||
|
||||
private LifecycleManager lifecycleManager0, lifecycleManager1,
|
||||
lifecycleManager2;
|
||||
private SyncSessionFactory sync0, sync1, sync2;
|
||||
private BlogManager blogManager0, blogManager1, blogManager2;
|
||||
private ContactManager contactManager0, contactManager1, contactManager2;
|
||||
private Contact contact1, contact2, contact01, contact02;
|
||||
private ContactId contactId1, contactId2, contactId01, contactId02;
|
||||
private IdentityManager identityManager0, identityManager1,
|
||||
identityManager2;
|
||||
private LocalAuthor author0, author1, author2;
|
||||
private Blog blog0, blog1, blog2;
|
||||
private SharerListener listener0, listener2;
|
||||
private InviteeListener listener1;
|
||||
|
||||
@Inject
|
||||
Clock clock;
|
||||
@Inject
|
||||
AuthorFactory authorFactory;
|
||||
@Inject
|
||||
BlogPostFactory blogPostFactory;
|
||||
@Inject
|
||||
CryptoComponent cryptoComponent;
|
||||
|
||||
// objects accessed from background threads need to be volatile
|
||||
private volatile BlogSharingManager blogSharingManager0;
|
||||
private volatile BlogSharingManager blogSharingManager1;
|
||||
private volatile BlogSharingManager blogSharingManager2;
|
||||
private volatile Waiter eventWaiter;
|
||||
private volatile Waiter msgWaiter;
|
||||
|
||||
private final File testDir = TestUtils.getTestDirectory();
|
||||
private final SecretKey master = TestUtils.getSecretKey();
|
||||
private final int TIMEOUT = 15000;
|
||||
private final String SHARER = "Sharer";
|
||||
private final String INVITEE = "Invitee";
|
||||
private final String CONTACT2 = "Contact2";
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(BlogSharingIntegrationTest.class.getName());
|
||||
|
||||
private BlogSharingIntegrationTestComponent t0, t1, t2;
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
BlogSharingIntegrationTestComponent component =
|
||||
DaggerBlogSharingIntegrationTestComponent.builder().build();
|
||||
component.inject(this);
|
||||
injectEagerSingletons(component);
|
||||
|
||||
assertTrue(testDir.mkdirs());
|
||||
File t0Dir = new File(testDir, SHARER);
|
||||
t0 = DaggerBlogSharingIntegrationTestComponent.builder()
|
||||
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
|
||||
injectEagerSingletons(t0);
|
||||
File t1Dir = new File(testDir, INVITEE);
|
||||
t1 = DaggerBlogSharingIntegrationTestComponent.builder()
|
||||
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
|
||||
injectEagerSingletons(t1);
|
||||
File t2Dir = new File(testDir, CONTACT2);
|
||||
t2 = DaggerBlogSharingIntegrationTestComponent.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();
|
||||
blogManager0 = t0.getBlogManager();
|
||||
blogManager1 = t1.getBlogManager();
|
||||
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();
|
||||
msgWaiter = new Waiter();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersonalBlogCannotBeSharedWithOwner() throws Exception {
|
||||
startLifecycles();
|
||||
defaultInit(true);
|
||||
|
||||
assertFalse(blogSharingManager0.canBeShared(blog1.getId(), contact1));
|
||||
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact2));
|
||||
assertFalse(blogSharingManager1.canBeShared(blog0.getId(), contact01));
|
||||
assertFalse(blogSharingManager2.canBeShared(blog0.getId(), contact02));
|
||||
|
||||
// create invitation
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog1.getId(), contactId1, "Hi!");
|
||||
|
||||
// sync invitation
|
||||
sync0To1();
|
||||
// make sure the invitee ignored the request for their own blog
|
||||
assertFalse(listener1.requestReceived);
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSuccessfulSharing() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee accept all requests
|
||||
defaultInit(true);
|
||||
|
||||
// send invitation
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
||||
|
||||
// invitee has own blog and that of the sharer
|
||||
assertEquals(2, blogManager1.getBlogs().size());
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was added successfully
|
||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
|
||||
// invitee has one invitation message from sharer
|
||||
List<InvitationMessage> list =
|
||||
new ArrayList<>(blogSharingManager1
|
||||
.getInvitationMessages(contactId01));
|
||||
assertEquals(2, list.size());
|
||||
// check other things are alright with the message
|
||||
for (InvitationMessage m : list) {
|
||||
if (m instanceof BlogInvitationRequest) {
|
||||
BlogInvitationRequest invitation =
|
||||
(BlogInvitationRequest) m;
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(blog2.getAuthor().getName(),
|
||||
invitation.getBlogAuthorName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals("Hi!", invitation.getMessage());
|
||||
} else {
|
||||
BlogInvitationResponse response =
|
||||
(BlogInvitationResponse) m;
|
||||
assertEquals(contactId01, response.getContactId());
|
||||
assertTrue(response.wasAccepted());
|
||||
assertTrue(response.isLocal());
|
||||
}
|
||||
}
|
||||
// sharer has own invitation message and response
|
||||
assertEquals(2,
|
||||
blogSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
// blog can not be shared again
|
||||
assertFalse(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
||||
assertFalse(blogSharingManager1.canBeShared(blog2.getId(), contact01));
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclinedSharing() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee deny all requests
|
||||
defaultInit(false);
|
||||
|
||||
// send invitation
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, null);
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was not added
|
||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
||||
assertEquals(2, blogManager1.getBlogs().size());
|
||||
// blog is no longer available to invitee who declined
|
||||
assertEquals(0, blogSharingManager1.getInvitations().size());
|
||||
|
||||
// invitee has one invitation message from sharer and one response
|
||||
List<InvitationMessage> list =
|
||||
new ArrayList<>(blogSharingManager1
|
||||
.getInvitationMessages(contactId01));
|
||||
assertEquals(2, list.size());
|
||||
// check things are alright with the message
|
||||
for (InvitationMessage m : list) {
|
||||
if (m instanceof BlogInvitationRequest) {
|
||||
BlogInvitationRequest invitation =
|
||||
(BlogInvitationRequest) m;
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(blog2.getAuthor().getName(),
|
||||
invitation.getBlogAuthorName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals(null, invitation.getMessage());
|
||||
} else {
|
||||
BlogInvitationResponse response =
|
||||
(BlogInvitationResponse) m;
|
||||
assertEquals(contactId01, response.getContactId());
|
||||
assertFalse(response.wasAccepted());
|
||||
assertTrue(response.isLocal());
|
||||
}
|
||||
}
|
||||
// sharer has own invitation message and response
|
||||
assertEquals(2,
|
||||
blogSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
// blog can be shared again
|
||||
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInviteeLeavesAfterFinished() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee accept all requests
|
||||
defaultInit(true);
|
||||
|
||||
// send invitation
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was added successfully
|
||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
assertTrue(blogManager1.getBlogs().contains(blog2));
|
||||
|
||||
// sharer shares blog with invitee
|
||||
assertTrue(blogSharingManager0.getSharedWith(blog2.getId())
|
||||
.contains(contact1));
|
||||
// invitee gets blog shared by sharer
|
||||
assertTrue(blogSharingManager1.getSharedBy(blog2.getId())
|
||||
.contains(contact01));
|
||||
|
||||
// invitee un-subscribes from blog
|
||||
blogManager1.removeBlog(blog2);
|
||||
|
||||
// send leave message to sharer
|
||||
sync1To0();
|
||||
|
||||
// blog is gone
|
||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
||||
assertEquals(2, blogManager1.getBlogs().size());
|
||||
|
||||
// sharer no longer shares blog with invitee
|
||||
assertFalse(blogSharingManager0.getSharedWith(blog2.getId())
|
||||
.contains(contact1));
|
||||
// invitee no longer gets blog shared by sharer
|
||||
assertFalse(blogSharingManager1.getSharedBy(blog2.getId())
|
||||
.contains(contact01));
|
||||
// blog can be shared again
|
||||
assertTrue(blogSharingManager0.canBeShared(blog2.getId(), contact1));
|
||||
assertTrue(blogSharingManager1.canBeShared(blog2.getId(), contact01));
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvitationForExistingBlog() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee accept all requests
|
||||
defaultInit(true);
|
||||
|
||||
// 1 and 2 are adding each other
|
||||
contactManager1.addContact(author2,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contactManager2.addContact(author1,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
|
||||
// sharer sends invitation for 2's blog to 1
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// make sure blog2 is shared by 0
|
||||
Collection<Contact> contacts =
|
||||
blogSharingManager1.getSharedBy(blog2.getId());
|
||||
assertEquals(1, contacts.size());
|
||||
assertTrue(contacts.contains(contact01));
|
||||
|
||||
// make sure 1 knows that they have blog2 already
|
||||
Collection<InvitationMessage> messages =
|
||||
blogSharingManager1.getInvitationMessages(contactId01);
|
||||
assertEquals(2, messages.size());
|
||||
assertEquals(blog2, blogManager1.getBlog(blog2.getId()));
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was not added, because it was there already
|
||||
assertEquals(0, blogSharingManager0.getInvitations().size());
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemovingSharedBlog() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee accept all requests
|
||||
defaultInit(true);
|
||||
|
||||
// send invitation
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was added successfully and is shared both ways
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
Collection<Contact> sharedWith =
|
||||
blogSharingManager0.getSharedWith(blog2.getId());
|
||||
assertEquals(1, sharedWith.size());
|
||||
assertEquals(contact1, sharedWith.iterator().next());
|
||||
Collection<Contact> sharedBy =
|
||||
blogSharingManager1.getSharedBy(blog2.getId());
|
||||
assertEquals(1, sharedBy.size());
|
||||
assertEquals(contact01, sharedBy.iterator().next());
|
||||
|
||||
// shared blog can be removed
|
||||
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
|
||||
|
||||
// invitee removes blog again
|
||||
blogManager1.removeBlog(blog2);
|
||||
|
||||
// sync LEAVE message
|
||||
sync1To0();
|
||||
|
||||
// sharer does not share this blog anymore with invitee
|
||||
sharedWith =
|
||||
blogSharingManager0.getSharedWith(blog2.getId());
|
||||
assertEquals(0, sharedWith.size());
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSharedBlogBecomesPermanent() throws Exception {
|
||||
startLifecycles();
|
||||
|
||||
// initialize and let invitee accept all requests
|
||||
defaultInit(true);
|
||||
|
||||
// invitee only sees two blogs
|
||||
assertEquals(2, blogManager1.getBlogs().size());
|
||||
|
||||
// sharer sends invitation for 2's blog to 1
|
||||
blogSharingManager0
|
||||
.sendInvitation(blog2.getId(), contactId1, "Hi!");
|
||||
|
||||
// sync first request message
|
||||
sync0To1();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// make sure blog2 is shared by 0
|
||||
Collection<Contact> contacts =
|
||||
blogSharingManager1.getSharedBy(blog2.getId());
|
||||
assertEquals(1, contacts.size());
|
||||
assertTrue(contacts.contains(contact01));
|
||||
|
||||
// sync response back
|
||||
sync1To0();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// blog was added and can be removed
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
assertTrue(blogManager1.canBeRemoved(blog2.getId()));
|
||||
|
||||
// 1 and 2 are adding each other
|
||||
contactManager1.addContact(author2,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contactManager2.addContact(author1,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
assertEquals(3, blogManager1.getBlogs().size());
|
||||
|
||||
// now blog can not be removed anymore
|
||||
assertFalse(blogManager1.canBeRemoved(blog2.getId()));
|
||||
|
||||
stopLifecycles();
|
||||
}
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown() throws InterruptedException {
|
||||
TestUtils.deleteTestDirectory(testDir);
|
||||
}
|
||||
|
||||
private class SharerListener implements EventListener {
|
||||
|
||||
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");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
||||
BlogInvitationResponseReceivedEvent event =
|
||||
(BlogInvitationResponseReceivedEvent) e;
|
||||
eventWaiter.assertEquals(contactId1, event.getContactId());
|
||||
responseReceived = true;
|
||||
eventWaiter.resume();
|
||||
}
|
||||
// this is only needed for tests where a blog is re-shared
|
||||
else if (e instanceof BlogInvitationReceivedEvent) {
|
||||
BlogInvitationReceivedEvent event =
|
||||
(BlogInvitationReceivedEvent) e;
|
||||
eventWaiter.assertEquals(contactId1, event.getContactId());
|
||||
requestReceived = true;
|
||||
Blog b = event.getBlog();
|
||||
try {
|
||||
Contact c = contactManager0.getContact(contactId1);
|
||||
blogSharingManager0.respondToInvitation(b, c, true);
|
||||
} catch (DbException ex) {
|
||||
eventWaiter.rethrow(ex);
|
||||
} finally {
|
||||
eventWaiter.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InviteeListener implements EventListener {
|
||||
|
||||
volatile boolean requestReceived = false;
|
||||
volatile boolean responseReceived = false;
|
||||
|
||||
private final boolean accept, answer;
|
||||
|
||||
InviteeListener(boolean accept, boolean answer) {
|
||||
this.accept = accept;
|
||||
this.answer = answer;
|
||||
}
|
||||
|
||||
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");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof BlogInvitationReceivedEvent) {
|
||||
BlogInvitationReceivedEvent event =
|
||||
(BlogInvitationReceivedEvent) e;
|
||||
requestReceived = true;
|
||||
if (!answer) return;
|
||||
Blog b = event.getBlog();
|
||||
try {
|
||||
eventWaiter.assertEquals(1,
|
||||
blogSharingManager1.getInvitations().size());
|
||||
Contact c =
|
||||
contactManager1.getContact(event.getContactId());
|
||||
blogSharingManager1.respondToInvitation(b, c, accept);
|
||||
} catch (DbException ex) {
|
||||
eventWaiter.rethrow(ex);
|
||||
} finally {
|
||||
eventWaiter.resume();
|
||||
}
|
||||
}
|
||||
// this is only needed for tests where a blog is re-shared
|
||||
else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
||||
BlogInvitationResponseReceivedEvent event =
|
||||
(BlogInvitationResponseReceivedEvent) e;
|
||||
eventWaiter.assertEquals(contactId01, event.getContactId());
|
||||
responseReceived = true;
|
||||
eventWaiter.resume();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
lifecycleManager1.startServices();
|
||||
lifecycleManager2.startServices();
|
||||
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 defaultInit(boolean accept) throws DbException {
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
getPersonalBlogOfSharer();
|
||||
listenToEvents(accept);
|
||||
}
|
||||
|
||||
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 {
|
||||
// sharer adds invitee as contact
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contact1 = contactManager0.getContact(contactId1);
|
||||
// sharer adds second contact
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contact2 = contactManager0.getContact(contactId2);
|
||||
// contacts add sharer back
|
||||
contactId01 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contact01 = contactManager1.getContact(contactId01);
|
||||
contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contact02 = contactManager2.getContact(contactId02);
|
||||
}
|
||||
|
||||
private void getPersonalBlogOfSharer() throws DbException {
|
||||
blog0 = blogManager0.getPersonalBlog(author0);
|
||||
blog1 = blogManager0.getPersonalBlog(author1);
|
||||
blog2 = blogManager0.getPersonalBlog(author2);
|
||||
}
|
||||
|
||||
private void listenToEvents(boolean accept) {
|
||||
listener0 = new SharerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
listener1 = new InviteeListener(accept);
|
||||
t1.getEventBus().addListener(listener1);
|
||||
listener2 = new SharerListener();
|
||||
t2.getEventBus().addListener(listener2);
|
||||
}
|
||||
|
||||
private void sync0To1() throws IOException, TimeoutException {
|
||||
deliverMessage(sync0, contactId01, sync1, contactId1,
|
||||
"Sharer to Invitee");
|
||||
}
|
||||
|
||||
private void sync1To0() throws IOException, TimeoutException {
|
||||
deliverMessage(sync1, contactId1, sync0, contactId01,
|
||||
"Invitee to Sharer");
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// wait for message to actually arrive
|
||||
msgWaiter.await(TIMEOUT, 1);
|
||||
}
|
||||
|
||||
private void injectEagerSingletons(
|
||||
BlogSharingIntegrationTestComponent component) {
|
||||
|
||||
component.inject(new LifecycleModule.EagerSingletons());
|
||||
component.inject(new BlogsModule.EagerSingletons());
|
||||
component.inject(new CryptoModule.EagerSingletons());
|
||||
component.inject(new ContactModule.EagerSingletons());
|
||||
component.inject(new TransportModule.EagerSingletons());
|
||||
component.inject(new SharingModule.EagerSingletons());
|
||||
component.inject(new SyncModule.EagerSingletons());
|
||||
component.inject(new PropertiesModule.EagerSingletons());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.briarproject;
|
||||
|
||||
import org.briarproject.api.blogs.BlogManager;
|
||||
import org.briarproject.api.blogs.BlogSharingManager;
|
||||
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;
|
||||
import org.briarproject.blogs.BlogsModule;
|
||||
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.forum.ForumModule;
|
||||
import org.briarproject.identity.IdentityModule;
|
||||
import org.briarproject.lifecycle.LifecycleModule;
|
||||
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,
|
||||
BlogsModule.class,
|
||||
ForumModule.class,
|
||||
IdentityModule.class,
|
||||
LifecycleModule.class,
|
||||
PropertiesModule.class,
|
||||
SharingModule.class,
|
||||
SyncModule.class,
|
||||
SystemModule.class,
|
||||
TransportModule.class
|
||||
})
|
||||
interface BlogSharingIntegrationTestComponent {
|
||||
|
||||
void inject(BlogSharingIntegrationTest testCase);
|
||||
|
||||
void inject(ContactModule.EagerSingletons init);
|
||||
|
||||
void inject(CryptoModule.EagerSingletons init);
|
||||
|
||||
void inject(BlogsModule.EagerSingletons init);
|
||||
|
||||
void inject(LifecycleModule.EagerSingletons init);
|
||||
|
||||
void inject(PropertiesModule.EagerSingletons init);
|
||||
|
||||
void inject(SharingModule.EagerSingletons init);
|
||||
|
||||
void inject(SyncModule.EagerSingletons init);
|
||||
|
||||
void inject(TransportModule.EagerSingletons init);
|
||||
|
||||
LifecycleManager getLifecycleManager();
|
||||
|
||||
EventBus getEventBus();
|
||||
|
||||
IdentityManager getIdentityManager();
|
||||
|
||||
ContactManager getContactManager();
|
||||
|
||||
BlogSharingManager getBlogSharingManager();
|
||||
|
||||
BlogManager getBlogManager();
|
||||
|
||||
SyncSessionFactory getSyncSessionFactory();
|
||||
|
||||
/* the following methods are only needed to manually construct messages */
|
||||
|
||||
DatabaseComponent getDatabaseComponent();
|
||||
|
||||
PrivateGroupFactory getPrivateGroupFactory();
|
||||
|
||||
ClientHelper getClientHelper();
|
||||
|
||||
MessageQueueManager getMessageQueueManager();
|
||||
|
||||
}
|
||||
@@ -57,7 +57,6 @@ import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGT
|
||||
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 {
|
||||
@@ -298,7 +297,7 @@ public class ForumManagerTest {
|
||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
||||
|
||||
// send posts to 1
|
||||
// send the child post to 1
|
||||
sync0To1();
|
||||
validationWaiter.await(TIMEOUT, 1);
|
||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
||||
@@ -327,14 +326,14 @@ public class ForumManagerTest {
|
||||
}
|
||||
|
||||
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() == VALID ||
|
||||
event.getState() == INVALID ||
|
||||
} else if (event.getState() == INVALID ||
|
||||
event.getState() == PENDING) {
|
||||
validationWaiter.resume();
|
||||
}
|
||||
@@ -365,12 +364,12 @@ public class ForumManagerTest {
|
||||
// sharer adds invitee as contact
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
// invitee adds sharer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.blogs.BlogsModule;
|
||||
import org.briarproject.clients.ClientsModule;
|
||||
import org.briarproject.contact.ContactModule;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
@@ -38,6 +39,7 @@ import dagger.Component;
|
||||
DatabaseModule.class,
|
||||
EventModule.class,
|
||||
ForumModule.class,
|
||||
BlogsModule.class,
|
||||
IdentityModule.class,
|
||||
LifecycleModule.class,
|
||||
PropertiesModule.class,
|
||||
@@ -46,7 +48,7 @@ import dagger.Component;
|
||||
SystemModule.class,
|
||||
TransportModule.class
|
||||
})
|
||||
public interface ForumManagerTestComponent {
|
||||
interface ForumManagerTestComponent {
|
||||
|
||||
void inject(ForumManagerTest testCase);
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ import org.briarproject.api.event.ForumInvitationReceivedEvent;
|
||||
import org.briarproject.api.event.ForumInvitationResponseReceivedEvent;
|
||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
||||
import org.briarproject.api.forum.Forum;
|
||||
import org.briarproject.api.forum.ForumInvitationMessage;
|
||||
import org.briarproject.api.forum.ForumInvitationRequest;
|
||||
import org.briarproject.api.forum.ForumInvitationResponse;
|
||||
import org.briarproject.api.forum.ForumManager;
|
||||
import org.briarproject.api.forum.ForumPost;
|
||||
import org.briarproject.api.forum.ForumPostFactory;
|
||||
@@ -35,7 +36,8 @@ 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.sync.ClientId;
|
||||
import org.briarproject.api.sharing.InvitationItem;
|
||||
import org.briarproject.api.sharing.InvitationMessage;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.SyncSession;
|
||||
import org.briarproject.api.sync.SyncSessionFactory;
|
||||
@@ -111,6 +113,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
private final String SHARER = "Sharer";
|
||||
private final String INVITEE = "Invitee";
|
||||
private final String SHARER2 = "Sharer2";
|
||||
private boolean respond = true;
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
|
||||
@@ -183,22 +186,33 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// forum was added successfully
|
||||
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
assertEquals(1, forumManager1.getForums().size());
|
||||
|
||||
// invitee has one invitation message from sharer
|
||||
List<ForumInvitationMessage> list =
|
||||
List<InvitationMessage> list =
|
||||
new ArrayList<>(forumSharingManager1
|
||||
.getInvitationMessages(contactId0));
|
||||
assertEquals(1, list.size());
|
||||
assertEquals(2, list.size());
|
||||
// check other things are alright with the forum message
|
||||
ForumInvitationMessage invitation = list.get(0);
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(forum0.getName(), invitation.getForumName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals("Hi!", invitation.getMessage());
|
||||
// sharer has own invitation message
|
||||
assertEquals(1,
|
||||
for (InvitationMessage m : list) {
|
||||
if (m instanceof ForumInvitationRequest) {
|
||||
ForumInvitationRequest invitation =
|
||||
(ForumInvitationRequest) m;
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(forum0.getName(), invitation.getForumName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals("Hi!", invitation.getMessage());
|
||||
} else {
|
||||
ForumInvitationResponse response =
|
||||
(ForumInvitationResponse) m;
|
||||
assertEquals(contactId0, response.getContactId());
|
||||
assertTrue(response.wasAccepted());
|
||||
assertTrue(response.isLocal());
|
||||
}
|
||||
}
|
||||
// sharer has own invitation message and response
|
||||
assertEquals(2,
|
||||
forumSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
// forum can not be shared again
|
||||
@@ -233,24 +247,35 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// forum was not added
|
||||
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
assertEquals(0, forumManager1.getForums().size());
|
||||
// forum is no longer available to invitee who declined
|
||||
assertEquals(0, forumSharingManager1.getInvited().size());
|
||||
assertEquals(0, forumSharingManager1.getInvitations().size());
|
||||
|
||||
// invitee has one invitation message from sharer
|
||||
List<ForumInvitationMessage> list =
|
||||
// invitee has one invitation message from sharer and one response
|
||||
List<InvitationMessage> list =
|
||||
new ArrayList<>(forumSharingManager1
|
||||
.getInvitationMessages(contactId0));
|
||||
assertEquals(1, list.size());
|
||||
// check other things are alright with the forum message
|
||||
ForumInvitationMessage invitation = list.get(0);
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(forum0.getName(), invitation.getForumName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals(null, invitation.getMessage());
|
||||
// sharer has own invitation message
|
||||
assertEquals(1,
|
||||
assertEquals(2, list.size());
|
||||
// check things are alright with the forum message
|
||||
for (InvitationMessage m : list) {
|
||||
if (m instanceof ForumInvitationRequest) {
|
||||
ForumInvitationRequest invitation =
|
||||
(ForumInvitationRequest) m;
|
||||
assertFalse(invitation.isAvailable());
|
||||
assertEquals(forum0.getName(), invitation.getForumName());
|
||||
assertEquals(contactId1, invitation.getContactId());
|
||||
assertEquals(null, invitation.getMessage());
|
||||
} else {
|
||||
ForumInvitationResponse response =
|
||||
(ForumInvitationResponse) m;
|
||||
assertEquals(contactId0, response.getContactId());
|
||||
assertFalse(response.wasAccepted());
|
||||
assertTrue(response.isLocal());
|
||||
}
|
||||
}
|
||||
// sharer has own invitation message and response
|
||||
assertEquals(2,
|
||||
forumSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
// forum can be shared again
|
||||
@@ -283,7 +308,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// forum was added successfully
|
||||
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
assertEquals(1, forumManager1.getForums().size());
|
||||
assertTrue(forumManager1.getForums().contains(forum0));
|
||||
|
||||
@@ -303,7 +328,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
syncToSharer();
|
||||
|
||||
// forum is gone
|
||||
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
assertEquals(0, forumManager1.getForums().size());
|
||||
|
||||
// sharer no longer shares forum with invitee
|
||||
@@ -343,7 +368,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
// forum was added successfully
|
||||
assertEquals(0, forumSharingManager0.getInvited().size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
assertEquals(1, forumManager1.getForums().size());
|
||||
assertTrue(forumManager1.getForums().contains(forum0));
|
||||
|
||||
@@ -384,7 +409,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
public void testSharerLeavesBeforeResponse() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// initialize and let invitee accept all requests
|
||||
// initialize except event listeners
|
||||
defaultInit(true);
|
||||
|
||||
// send invitation
|
||||
@@ -394,17 +419,43 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
// sharer un-subscribes from forum
|
||||
forumManager0.removeForum(forum0);
|
||||
|
||||
// from here on expect the response to fail with an AssertionError,
|
||||
// because there is in fact no invited forum available anymore
|
||||
thrown.expect(AssertionError.class);
|
||||
// prevent invitee response before syncing messages
|
||||
respond = false;
|
||||
|
||||
// sync first request message and leave message
|
||||
syncToInvitee();
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.requestReceived);
|
||||
|
||||
// invitee has no forums available
|
||||
assertEquals(0, forumSharingManager1.getInvited().size());
|
||||
// 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());
|
||||
|
||||
// Try again, this time allow the response
|
||||
addForumForSharer();
|
||||
respond = true;
|
||||
|
||||
// send invitation
|
||||
forumSharingManager0
|
||||
.sendInvitation(forum0.getId(), contactId1, null);
|
||||
|
||||
// sharer un-subscribes from forum
|
||||
forumManager0.removeForum(forum0);
|
||||
|
||||
// sync first request message and leave message
|
||||
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());
|
||||
} finally {
|
||||
stopLifecycles();
|
||||
}
|
||||
@@ -438,12 +489,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
listener1.requestReceived = false;
|
||||
|
||||
// get SessionId from invitation
|
||||
List<ForumInvitationMessage> list = new ArrayList<>(
|
||||
List<InvitationMessage> list = new ArrayList<>(
|
||||
forumSharingManager1
|
||||
.getInvitationMessages(contactId0));
|
||||
assertEquals(1, list.size());
|
||||
ForumInvitationMessage msg = list.get(0);
|
||||
assertEquals(2, list.size());
|
||||
InvitationMessage msg = list.get(0);
|
||||
SessionId sessionId = msg.getSessionId();
|
||||
assertEquals(sessionId, list.get(1).getSessionId());
|
||||
|
||||
// get all sorts of stuff needed to send a message
|
||||
DatabaseComponent db = t0.getDatabaseComponent();
|
||||
@@ -501,6 +553,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
|
||||
// forum was added successfully
|
||||
assertEquals(1, forumManager1.getForums().size());
|
||||
assertEquals(2,
|
||||
forumSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
|
||||
// invitee now shares same forum back
|
||||
forumSharingManager1.sendInvitation(forum0.getId(),
|
||||
@@ -512,9 +567,10 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
|
||||
// make sure that no new request was received
|
||||
assertFalse(listener0.requestReceived);
|
||||
assertEquals(1,
|
||||
assertEquals(2,
|
||||
forumSharingManager0.getInvitationMessages(contactId1)
|
||||
.size());
|
||||
assertEquals(0, forumSharingManager0.getInvitations().size());
|
||||
} finally {
|
||||
stopLifecycles();
|
||||
}
|
||||
@@ -566,9 +622,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener0.responseReceived);
|
||||
|
||||
assertEquals(1, forumSharingManager0
|
||||
assertEquals(2, forumSharingManager0
|
||||
.getInvitationMessages(contactId1).size());
|
||||
assertEquals(2, forumSharingManager1
|
||||
assertEquals(3, forumSharingManager1
|
||||
.getInvitationMessages(contactId0).size());
|
||||
} else {
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
@@ -579,9 +635,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
assertTrue(listener1.responseReceived);
|
||||
|
||||
assertEquals(2, forumSharingManager0
|
||||
assertEquals(3, forumSharingManager0
|
||||
.getInvitationMessages(contactId1).size());
|
||||
assertEquals(1, forumSharingManager1
|
||||
assertEquals(2, forumSharingManager1
|
||||
.getInvitationMessages(contactId0).size());
|
||||
}
|
||||
} finally {
|
||||
@@ -616,12 +672,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
forumSharingManager0.getSharedWith(forum0.getId()).size());
|
||||
|
||||
// remember SessionId from invitation
|
||||
List<ForumInvitationMessage> list = new ArrayList<>(
|
||||
List<InvitationMessage> list = new ArrayList<>(
|
||||
forumSharingManager1
|
||||
.getInvitationMessages(contactId0));
|
||||
assertEquals(1, list.size());
|
||||
ForumInvitationMessage msg = list.get(0);
|
||||
assertEquals(2, list.size());
|
||||
InvitationMessage msg = list.get(0);
|
||||
SessionId sessionId = msg.getSessionId();
|
||||
assertEquals(sessionId, list.get(1).getSessionId());
|
||||
|
||||
// contacts now remove each other
|
||||
contactManager0.removeContact(contactId1);
|
||||
@@ -711,8 +768,11 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
"Sharer2 to Invitee");
|
||||
|
||||
// make sure we now have two invitations to the same forum available
|
||||
Collection<Forum> forums = forumSharingManager1.getInvited();
|
||||
Collection<InvitationItem> forums =
|
||||
forumSharingManager1.getInvitations();
|
||||
assertEquals(1, forums.size());
|
||||
assertEquals(2, forums.iterator().next().getNewSharers().size());
|
||||
assertEquals(forum0, forums.iterator().next().getShareable());
|
||||
assertEquals(2,
|
||||
forumSharingManager1.getSharedBy(forum0.getId()).size());
|
||||
|
||||
@@ -867,20 +927,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
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();
|
||||
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");
|
||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
||||
LOG.info("TEST: Sharer received message");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
|
||||
@@ -925,20 +978,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
this(accept, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof MessageStateChangedEvent) {
|
||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||
State s = event.getState();
|
||||
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");
|
||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
||||
LOG.info("TEST: Invitee received message");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof ForumInvitationReceivedEvent) {
|
||||
@@ -949,10 +995,16 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
Forum f = event.getForum();
|
||||
try {
|
||||
eventWaiter.assertEquals(1,
|
||||
forumSharingManager1.getInvited().size());
|
||||
forumSharingManager1.getInvitations().size());
|
||||
InvitationItem invitation =
|
||||
forumSharingManager1.getInvitations().iterator()
|
||||
.next();
|
||||
eventWaiter.assertEquals(f, invitation.getShareable());
|
||||
if (respond) {
|
||||
Contact c =
|
||||
contactManager1.getContact(event.getContactId());
|
||||
forumSharingManager1.respondToInvitation(f, c, accept);
|
||||
}
|
||||
} catch (DbException ex) {
|
||||
eventWaiter.rethrow(ex);
|
||||
} finally {
|
||||
@@ -1024,21 +1076,21 @@ public class ForumSharingIntegrationTest extends BriarTestCase {
|
||||
// sharer adds invitee as contact
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
// second sharer does the same
|
||||
contactId21 = contactManager2.addContact(author1,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
// invitee adds sharers back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
contactId2 = contactManager1.addContact(author2,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.briarproject.api.forum.ForumSharingManager;
|
||||
import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.sync.SyncSessionFactory;
|
||||
import org.briarproject.blogs.BlogsModule;
|
||||
import org.briarproject.clients.ClientsModule;
|
||||
import org.briarproject.contact.ContactModule;
|
||||
import org.briarproject.crypto.CryptoModule;
|
||||
@@ -42,6 +43,7 @@ import dagger.Component;
|
||||
DatabaseModule.class,
|
||||
EventModule.class,
|
||||
ForumModule.class,
|
||||
BlogsModule.class,
|
||||
IdentityModule.class,
|
||||
LifecycleModule.class,
|
||||
PropertiesModule.class,
|
||||
@@ -50,7 +52,7 @@ import dagger.Component;
|
||||
SystemModule.class,
|
||||
TransportModule.class
|
||||
})
|
||||
public interface ForumSharingIntegrationTestComponent {
|
||||
interface ForumSharingIntegrationTestComponent {
|
||||
|
||||
void inject(ForumSharingIntegrationTest testCase);
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
package org.briarproject;
|
||||
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import net.jodah.concurrentunit.Waiter;
|
||||
|
||||
import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
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.SecretKey;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfEntry;
|
||||
@@ -23,18 +29,18 @@ 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.introduction.IntroducerProtocolState;
|
||||
import org.briarproject.api.introduction.IntroductionManager;
|
||||
import org.briarproject.api.introduction.IntroductionMessage;
|
||||
import org.briarproject.api.introduction.IntroductionRequest;
|
||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||
import org.briarproject.api.properties.TransportProperties;
|
||||
import org.briarproject.api.properties.TransportPropertyManager;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
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.sync.ValidationManager;
|
||||
import org.briarproject.api.sync.ValidationManager.State;
|
||||
import org.briarproject.api.system.Clock;
|
||||
import org.briarproject.contact.ContactModule;
|
||||
@@ -56,6 +62,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -66,13 +73,17 @@ import javax.inject.Inject;
|
||||
|
||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
||||
import static org.briarproject.TestPluginsModule.TRANSPORT_ID;
|
||||
import static org.briarproject.api.clients.MessageQueueManager.QUEUE_STATE_KEY;
|
||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.GROUP_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.NAME;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.PUBLIC_KEY;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.SESSION_ID;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.STATE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TRANSPORT;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_REQUEST;
|
||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE_RESPONSE;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
@@ -81,17 +92,23 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
|
||||
LifecycleManager lifecycleManager0, lifecycleManager1, lifecycleManager2;
|
||||
SyncSessionFactory sync0, sync1, sync2;
|
||||
ContactManager contactManager0, contactManager1, contactManager2;
|
||||
ContactId contactId0, contactId1, contactId2;
|
||||
IdentityManager identityManager0, identityManager1, identityManager2;
|
||||
LocalAuthor author0, author1, author2;
|
||||
private LifecycleManager lifecycleManager0, lifecycleManager1,
|
||||
lifecycleManager2;
|
||||
private SyncSessionFactory sync0, sync1, sync2;
|
||||
private ContactManager contactManager0, contactManager1, contactManager2;
|
||||
private ContactId contactId0, contactId1, contactId2;
|
||||
private IdentityManager identityManager0, identityManager1,
|
||||
identityManager2;
|
||||
private LocalAuthor author0, author1, author2;
|
||||
|
||||
@Inject
|
||||
Clock clock;
|
||||
@Inject
|
||||
CryptoComponent crypto;
|
||||
@Inject
|
||||
AuthorFactory authorFactory;
|
||||
@Inject
|
||||
IntroductionGroupFactory introductionGroupFactory;
|
||||
|
||||
// objects accessed from background threads need to be volatile
|
||||
private volatile IntroductionManager introductionManager0;
|
||||
@@ -155,32 +172,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroductionSession() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -238,6 +236,18 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
assertTrue(contactManager2
|
||||
.contactExists(author1.getId(), author2.getId()));
|
||||
|
||||
// make sure that introduced contacts are not verified
|
||||
for (Contact c : contactManager1.getActiveContacts()) {
|
||||
if (c.getAuthor().equals(author2)) {
|
||||
assertFalse(c.isVerified());
|
||||
}
|
||||
}
|
||||
for (Contact c : contactManager2.getActiveContacts()) {
|
||||
if (c.getAuthor().equals(author1)) {
|
||||
assertFalse(c.isVerified());
|
||||
}
|
||||
}
|
||||
|
||||
assertDefaultUiMessages();
|
||||
} finally {
|
||||
stopLifecycles();
|
||||
@@ -248,29 +258,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroductionSessionFirstDecline() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -306,7 +300,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
assertTrue(listener0.response2Received);
|
||||
|
||||
// sync first forwarded response
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2);
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
|
||||
|
||||
// note how the introducer does not forward the second response,
|
||||
// because after the first decline the protocol finished
|
||||
@@ -341,29 +335,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroductionSessionSecondDecline() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||
master, clock.currentTimeMillis(), false, true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -429,29 +407,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroductionSessionDelayedFirstDecline() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||
master, clock.currentTimeMillis(), false, true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -508,21 +470,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroductionToSameContact() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducee as contact
|
||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||
master, clock.currentTimeMillis(), true, true
|
||||
);
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -573,21 +527,21 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
// Add introducees' authors as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = null;
|
||||
ContactId contactId01 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), false,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
ContactId contactId02 = contactManager1.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||
true
|
||||
true, true
|
||||
);
|
||||
|
||||
// listen to events
|
||||
@@ -658,32 +612,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testSessionIdReuse() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -755,32 +690,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroducerRemovedCleanup() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -841,32 +757,13 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
public void testIntroduceesRemovedCleanup() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
// Add Identities
|
||||
// Add Identities And Contacts
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
|
||||
// Add Transport Properties
|
||||
addTransportProperties();
|
||||
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
@@ -937,7 +834,133 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO add a test for faking responses when #256 is implemented
|
||||
@Test
|
||||
public void testModifiedResponse() throws Exception {
|
||||
startLifecycles();
|
||||
try {
|
||||
addDefaultIdentities();
|
||||
addDefaultContacts();
|
||||
addTransportProperties();
|
||||
|
||||
// listen to events
|
||||
IntroducerListener listener0 = new IntroducerListener();
|
||||
t0.getEventBus().addListener(listener0);
|
||||
IntroduceeListener listener1 = new IntroduceeListener(1, true);
|
||||
t1.getEventBus().addListener(listener1);
|
||||
IntroduceeListener listener2 = new IntroduceeListener(2, true);
|
||||
t2.getEventBus().addListener(listener2);
|
||||
|
||||
// make introduction
|
||||
long time = clock.currentTimeMillis();
|
||||
Contact introducee1 = contactManager0.getContact(contactId1);
|
||||
Contact introducee2 = contactManager0.getContact(contactId2);
|
||||
introductionManager0
|
||||
.makeIntroduction(introducee1, introducee2, "Hi!", time);
|
||||
|
||||
// sync request messages
|
||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
|
||||
eventWaiter.await(TIMEOUT, 2);
|
||||
|
||||
// sync first response
|
||||
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
|
||||
// get response to be forwarded
|
||||
MessageId responseId = null;
|
||||
BdfDictionary response = null;
|
||||
Group g2 = introductionGroupFactory
|
||||
.createIntroductionGroup(introducee2);
|
||||
ClientHelper clientHelper0 = t0.getClientHelper();
|
||||
Map<MessageId, BdfDictionary> map =
|
||||
clientHelper0.getMessageMetadataAsDictionary(g2.getId());
|
||||
for (Map.Entry<MessageId, BdfDictionary> entry : map.entrySet()) {
|
||||
if (entry.getValue().getLong(TYPE) == TYPE_RESPONSE) {
|
||||
responseId = entry.getKey();
|
||||
response = entry.getValue();
|
||||
}
|
||||
}
|
||||
assertTrue(responseId != null && response != null);
|
||||
|
||||
// adapt outgoing message queue to removed message
|
||||
decreaseOutgoingMessageCounter(clientHelper0, g2.getId(), 1);
|
||||
|
||||
// modify response by changing transport properties
|
||||
BdfDictionary tp = response.getDictionary(TRANSPORT);
|
||||
tp.put("fakeId", BdfDictionary.of(new BdfEntry("fake", "fake")));
|
||||
response.put(TRANSPORT, tp);
|
||||
|
||||
// replace original response with modified one
|
||||
MessageSender sender0 = t0.getMessageSender();
|
||||
DatabaseComponent db0 = t0.getDatabaseComponent();
|
||||
Transaction txn = db0.startTransaction(false);
|
||||
try {
|
||||
db0.deleteMessage(txn, responseId);
|
||||
sender0.sendMessage(txn, response);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db0.endTransaction(txn);
|
||||
}
|
||||
|
||||
// sync second response
|
||||
deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0");
|
||||
eventWaiter.await(TIMEOUT, 1);
|
||||
|
||||
// sync forwarded responses to introducees
|
||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
|
||||
|
||||
// sync first ACK and its forward
|
||||
deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0");
|
||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
||||
|
||||
// sync second ACK and forward it
|
||||
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
|
||||
|
||||
// introducee2 should have detected the fake now
|
||||
// and deleted introducee1 again
|
||||
Collection<Contact> contacts2;
|
||||
DatabaseComponent db2 = t2.getDatabaseComponent();
|
||||
txn = db2.startTransaction(true);
|
||||
try {
|
||||
contacts2 = db2.getContacts(txn);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db2.endTransaction(txn);
|
||||
}
|
||||
assertEquals(1, contacts2.size());
|
||||
|
||||
// sync abort message to introducer
|
||||
deliverMessage(sync2, contactId2, sync0, contactId0, "2 to 0");
|
||||
|
||||
// ensure introducer got the abort
|
||||
SessionId sessionId = new SessionId(response.getRaw(SESSION_ID));
|
||||
BdfDictionary state =
|
||||
clientHelper0.getMessageMetadataAsDictionary(sessionId);
|
||||
assertEquals(IntroducerProtocolState.ERROR.getValue(),
|
||||
state.getLong(STATE).intValue());
|
||||
|
||||
// sync abort messages to introducees
|
||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
||||
deliverMessage(sync0, contactId0, sync2, contactId2, "0 to 2");
|
||||
|
||||
// although aborted, introducee1 keeps the contact,
|
||||
// so introducer can not make contacts disappear by sending abort
|
||||
Collection<Contact> contacts1;
|
||||
DatabaseComponent db1 = t1.getDatabaseComponent();
|
||||
txn = db1.startTransaction(true);
|
||||
try {
|
||||
contacts1 = db1.getContacts(txn);
|
||||
txn.setComplete();
|
||||
} finally {
|
||||
db1.endTransaction(txn);
|
||||
}
|
||||
assertEquals(2, contacts1.size());
|
||||
} finally {
|
||||
stopLifecycles();
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws InterruptedException {
|
||||
@@ -980,20 +1003,48 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
private void addDefaultIdentities() throws DbException {
|
||||
author0 = authorFactory.createLocalAuthor(INTRODUCER,
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
TestUtils.getRandomBytes(123));
|
||||
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
|
||||
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
|
||||
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
|
||||
author0 = authorFactory
|
||||
.createLocalAuthor(INTRODUCER, publicKey0, privateKey0);
|
||||
identityManager0.addLocalAuthor(author0);
|
||||
author1 = authorFactory.createLocalAuthor(INTRODUCEE1,
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
TestUtils.getRandomBytes(123));
|
||||
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
|
||||
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
|
||||
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
|
||||
author1 = authorFactory
|
||||
.createLocalAuthor(INTRODUCEE1, publicKey1, privateKey1);
|
||||
identityManager1.addLocalAuthor(author1);
|
||||
author2 = authorFactory.createLocalAuthor(INTRODUCEE2,
|
||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
||||
TestUtils.getRandomBytes(123));
|
||||
KeyPair keyPair2 = crypto.generateSignatureKeyPair();
|
||||
byte[] publicKey2 = keyPair2.getPublic().getEncoded();
|
||||
byte[] privateKey2 = keyPair2.getPrivate().getEncoded();
|
||||
author2 = authorFactory
|
||||
.createLocalAuthor(INTRODUCEE2, publicKey2, privateKey2);
|
||||
identityManager2.addLocalAuthor(author2);
|
||||
}
|
||||
|
||||
private void addDefaultContacts() throws DbException {
|
||||
// Add introducees as contacts
|
||||
contactId1 = contactManager0.addContact(author1,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
contactId2 = contactManager0.addContact(author2,
|
||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
// Add introducer back
|
||||
contactId0 = contactManager1.addContact(author0,
|
||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
ContactId contactId02 = contactManager2.addContact(author0,
|
||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||
true, true
|
||||
);
|
||||
assertTrue(contactId0.equals(contactId02));
|
||||
}
|
||||
|
||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
||||
SyncSessionFactory toSync, ContactId toId)
|
||||
throws IOException, TimeoutException {
|
||||
@@ -1001,7 +1052,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
|
||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
||||
SyncSessionFactory toSync, ContactId toId, String debug)
|
||||
SyncSessionFactory toSync, ContactId toId, @Nullable String debug)
|
||||
throws IOException, TimeoutException {
|
||||
|
||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
||||
@@ -1038,14 +1089,14 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
|
||||
private class IntroduceeListener implements EventListener {
|
||||
|
||||
public volatile boolean requestReceived = false;
|
||||
public volatile boolean succeeded = false;
|
||||
public volatile boolean aborted = false;
|
||||
private volatile boolean requestReceived = false;
|
||||
private volatile boolean succeeded = false;
|
||||
private volatile boolean aborted = false;
|
||||
|
||||
private final int introducee;
|
||||
private final boolean accept;
|
||||
|
||||
IntroduceeListener(int introducee, boolean accept) {
|
||||
private IntroduceeListener(int introducee, boolean accept) {
|
||||
this.introducee = introducee;
|
||||
this.accept = accept;
|
||||
}
|
||||
@@ -1055,13 +1106,9 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
if (e instanceof MessageStateChangedEvent) {
|
||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||
State s = event.getState();
|
||||
ClientId c = event.getClientId();
|
||||
if ((s == DELIVERED || s == INVALID) &&
|
||||
c.equals(introductionManager0.getClientId()) &&
|
||||
!event.isLocal()) {
|
||||
if ((s == DELIVERED || s == INVALID) && !event.isLocal()) {
|
||||
LOG.info("TEST: Introducee" + introducee +
|
||||
" received message in group " +
|
||||
event.getMessage().getGroupId().hashCode());
|
||||
" received message");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
||||
@@ -1095,6 +1142,7 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
}
|
||||
} catch (DbException | IOException exception) {
|
||||
msgWaiter.rethrow(exception);
|
||||
eventWaiter.rethrow(exception);
|
||||
} finally {
|
||||
eventWaiter.resume();
|
||||
@@ -1114,19 +1162,16 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
|
||||
private class IntroducerListener implements EventListener {
|
||||
|
||||
public volatile boolean response1Received = false;
|
||||
public volatile boolean response2Received = false;
|
||||
public volatile boolean aborted = false;
|
||||
private volatile boolean response1Received = false;
|
||||
private volatile boolean response2Received = false;
|
||||
private volatile boolean aborted = false;
|
||||
|
||||
@Override
|
||||
public void eventOccurred(Event e) {
|
||||
if (e instanceof MessageStateChangedEvent) {
|
||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
||||
if (event.getState() == DELIVERED && event.getClientId()
|
||||
.equals(introductionManager0.getClientId()) &&
|
||||
!event.isLocal()) {
|
||||
LOG.info("TEST: Introducer received message in group " +
|
||||
event.getMessage().getGroupId().hashCode());
|
||||
if (event.getState() == DELIVERED && !event.isLocal()) {
|
||||
LOG.info("TEST: Introducer received message");
|
||||
msgWaiter.resume();
|
||||
}
|
||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||
@@ -1148,6 +1193,16 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
private void decreaseOutgoingMessageCounter(ClientHelper clientHelper,
|
||||
GroupId g, int num) throws FormatException, DbException {
|
||||
BdfDictionary gD = clientHelper.getGroupMetadataAsDictionary(g);
|
||||
LOG.warning(gD.toString());
|
||||
BdfDictionary queue = gD.getDictionary(QUEUE_STATE_KEY);
|
||||
queue.put("nextOut", queue.getLong("nextOut") - num);
|
||||
gD.put(QUEUE_STATE_KEY, queue);
|
||||
clientHelper.mergeGroupMetadata(g, gD);
|
||||
}
|
||||
|
||||
private void injectEagerSingletons(
|
||||
IntroductionIntegrationTestComponent component) {
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.briarproject;
|
||||
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.contact.ContactManager;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.event.EventBus;
|
||||
@@ -85,6 +86,8 @@ public interface IntroductionIntegrationTestComponent {
|
||||
|
||||
DatabaseComponent getDatabaseComponent();
|
||||
|
||||
ClientHelper getClientHelper();
|
||||
|
||||
MessageSender getMessageSender();
|
||||
|
||||
IntroductionGroupFactory getIntroductionGroupFactory();
|
||||
|
||||
@@ -93,7 +93,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
Author bobAuthor = new Author(bobId, "Bob",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
||||
master, timestamp, true, true);
|
||||
master, timestamp, true, true, true);
|
||||
|
||||
// Send Bob a message
|
||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||
@@ -146,7 +146,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
||||
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
||||
master, timestamp, false, true);
|
||||
master, timestamp, false, true, true);
|
||||
|
||||
// Set up an event listener
|
||||
MessageListener listener = new MessageListener();
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
android:versionName="0.12">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="9"
|
||||
|
||||
android:minSdkVersion="14"
|
||||
android:targetSdkVersion="22"
|
||||
tools:overrideLibrary="android.support.v14.preference"
|
||||
/>
|
||||
@@ -51,7 +50,9 @@
|
||||
android:finishOnTaskLaunch="true"
|
||||
android:label="@string/crash_report_title"
|
||||
android:launchMode="singleInstance"
|
||||
android:process=":briar_error_handler">
|
||||
android:process=":briar_error_handler"
|
||||
android:theme="@style/BriarThemeNoActionBar.Default"
|
||||
android:windowSoftInputMode="stateHidden">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
@@ -100,7 +101,7 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.forum.ForumInvitationsActivity"
|
||||
android:name=".android.sharing.InvitationsForumActivity"
|
||||
android:label="@string/forum_invitations_title"
|
||||
android:parentActivityName=".android.NavDrawerActivity">
|
||||
<meta-data
|
||||
@@ -109,6 +110,16 @@
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.sharing.InvitationsBlogActivity"
|
||||
android:label="@string/blogs_sharing_invitations_title"
|
||||
android:parentActivityName=".android.contact.ConversationActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.contact.ConversationActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.forum.CreateForumActivity"
|
||||
android:label="@string/create_forum_title"
|
||||
@@ -131,8 +142,8 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.forum.ShareForumActivity"
|
||||
android:label="@string/forums_share_toolbar_header"
|
||||
android:name=".android.sharing.ShareForumActivity"
|
||||
android:label="@string/activity_share_toolbar_header"
|
||||
android:parentActivityName=".android.forum.ForumActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@@ -141,8 +152,18 @@
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.forum.ForumSharingStatusActivity"
|
||||
android:label="@string/forum_sharing_status"
|
||||
android:name=".android.sharing.ShareBlogActivity"
|
||||
android:label="@string/activity_share_toolbar_header"
|
||||
android:parentActivityName=".android.blogs.BlogActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.blogs.BlogActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.sharing.SharingStatusForumActivity"
|
||||
android:label="@string/sharing_status"
|
||||
android:parentActivityName=".android.forum.ForumActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
@@ -150,6 +171,78 @@
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.sharing.SharingStatusBlogActivity"
|
||||
android:label="@string/sharing_status"
|
||||
android:parentActivityName=".android.blogs.BlogActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.blogs.BlogActivity"
|
||||
/>
|
||||
</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">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.NavDrawerActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.blogs.WriteBlogPostActivity"
|
||||
android:label="@string/blogs_write_blog_post"
|
||||
android:parentActivityName=".android.blogs.BlogActivity"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.blogs.BlogActivity"
|
||||
/>
|
||||
</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"
|
||||
android:parentActivityName=".android.NavDrawerActivity"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.NavDrawerActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.blogs.RssFeedManageActivity"
|
||||
android:label="@string/blogs_rss_feeds_manage"
|
||||
android:parentActivityName=".android.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".android.NavDrawerActivity"
|
||||
/>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".android.identity.CreateIdentityActivity"
|
||||
android:label="@string/new_identity_title"
|
||||
@@ -194,7 +287,7 @@
|
||||
|
||||
<activity
|
||||
android:name=".android.SettingsActivity"
|
||||
android:label="@string/settings_title"
|
||||
android:label="@string/settings_button"
|
||||
android:parentActivityName=".android.NavDrawerActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
|
||||
@@ -11,25 +11,20 @@ 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") {
|
||||
exclude module: 'support-v4'
|
||||
}
|
||||
compile("com.android.support:preference-v7:$supportVersion") {
|
||||
exclude module: 'support-v4'
|
||||
}
|
||||
|
||||
compile("com.android.support:preference-v14:$supportVersion") {
|
||||
exclude module: 'support-v4'
|
||||
exclude module: 'preference-v7'
|
||||
exclude module: 'recyclerview-v7'
|
||||
}
|
||||
compile("com.android.support:design:$supportVersion") {
|
||||
exclude module: 'support-v4'
|
||||
exclude module: 'recyclerview-v7'
|
||||
}
|
||||
compile "com.android.support:cardview-v7:$supportVersion"
|
||||
compile('ch.acra:acra:4.8.5') {
|
||||
exclude module: 'support-v4'
|
||||
exclude module: 'support-annotations'
|
||||
@@ -47,11 +42,6 @@ dependencies {
|
||||
testCompile project(path: ':briar-tests')
|
||||
testCompile 'org.robolectric:robolectric:3.0'
|
||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
||||
|
||||
androidTestCompile 'org.robolectric:robolectric:3.0'
|
||||
androidTestCompile 'org.mockito:mockito-core:1.10.19'
|
||||
androidTestApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||
androidTestCompile 'junit:junit:4.12'
|
||||
}
|
||||
|
||||
dependencyVerification {
|
||||
@@ -63,13 +53,13 @@ dependencyVerification {
|
||||
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
||||
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
||||
'com.android.support:preference-v7:775101bd07bd052e455761c5c5d9523d7ad59f2f320e3e8cbde241fd6b1d6025',
|
||||
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
|
||||
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
|
||||
'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',
|
||||
]
|
||||
}
|
||||
|
||||
@@ -77,6 +67,10 @@ android {
|
||||
compileSdkVersion 23
|
||||
buildToolsVersion "23.0.3"
|
||||
|
||||
defaultConfig {
|
||||
resValue "string", "app_package", "org.briarproject"
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
@@ -100,24 +94,16 @@ android {
|
||||
unitTests.returnDefaultValues = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Move the build types to build-types/<type>
|
||||
// For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
|
||||
// This moves them out of them default location under src/<type>/... which would
|
||||
// conflict with src/ being used by the main source set.
|
||||
// Adding new build types or product flavors should be accompanied
|
||||
// by a similar customization.
|
||||
debug.setRoot('build-types/debug')
|
||||
release.setRoot('build-types/release')
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
shrinkResources false
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
}
|
||||
release {
|
||||
shrinkResources true
|
||||
minifyEnabled true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||
}
|
||||
@@ -129,8 +115,10 @@ android {
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
warning 'MissingTranslation'
|
||||
warning 'ImpliedQuantity'
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
incremental true
|
||||
}
|
||||
|
||||
@@ -4,17 +4,16 @@
|
||||
-dontobfuscate
|
||||
-verbose
|
||||
-useuniqueclassmembernames
|
||||
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||
# For comfortability in case we do obfuscate
|
||||
# -renamesourcefileattribute SourceFile
|
||||
-keepattributes SourceFile,LineNumberTable,*Annotation*,Signature, InnerClasses, EnclosingMethod
|
||||
-keepattributes SourceFile, LineNumberTable, *Annotation*, Signature, InnerClasses, EnclosingMethod
|
||||
|
||||
-keep public class * extends android.app.Activity
|
||||
-keep public class * extends android.app.Application
|
||||
-keep public class * extends android.app.Service
|
||||
-keep public class * extends android.content.BroadcastReceiver
|
||||
-keep public class * extends android.content.ContentProvider
|
||||
-keep public class com.android.vending.licensing.ILicensingService
|
||||
-keepclasseswithmembers class * { native <methods>; }
|
||||
-keepclasseswithmembers class * {
|
||||
public <init> (android.content.Context, android.util.AttributeSet);
|
||||
@@ -32,31 +31,32 @@
|
||||
-keepclassmembers class * extends android.app.Activity {
|
||||
public void *(android.view.View);
|
||||
}
|
||||
-keepclassmembers class * {
|
||||
@com.google.inject.Inject <init>(...);
|
||||
@com.google.inject.Inject <fields>;
|
||||
}
|
||||
# Just in case Roboguice events are used
|
||||
-keepclassmembers class * {
|
||||
void *(**On*Event);
|
||||
}
|
||||
|
||||
-keep class org.h2.** { *; }
|
||||
-keep class org.briarproject.** { *; }
|
||||
-keep class com.google.inject.** { *; }
|
||||
-keep class javax.inject.** { *; }
|
||||
-keep class javax.annotation.** { *; }
|
||||
-keep class roboguice.** { *; }
|
||||
-keep class dagger.** { *; }
|
||||
-keep class com.google.** { *; }
|
||||
-keep class com.google.zxing.Result
|
||||
|
||||
-dontwarn org.h2.**
|
||||
-dontnote org.h2.**
|
||||
-dontwarn net.sf.cglib.**
|
||||
-dontwarn org.briarproject.plugins.tcp.**
|
||||
-dontwarn roboguice.**
|
||||
-dontnote org.briarproject.crypto.**
|
||||
-dontnote org.spongycastle.crypto.parsers.ECIESPublicKeyParser
|
||||
-dontwarn net.sourceforge.jsocks.**
|
||||
-dontnote android.support.**
|
||||
-dontnote dagger.**
|
||||
-dontwarn dagger.**
|
||||
-dontwarn com.google.common.**
|
||||
-dontnote com.google.common.**
|
||||
-dontwarn com.google.common.**
|
||||
|
||||
# RSS libraries
|
||||
-keep class com.rometools.rome.feed.synd.impl.** { *;}
|
||||
-keep class com.rometools.rome.io.impl.** { *;}
|
||||
-dontnote com.rometools.rome.**
|
||||
-dontwarn javax.xml.stream.**
|
||||
-dontwarn org.jaxen.**
|
||||
-dontwarn java.nio.**
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.**
|
||||
-dontwarn org.slf4j.impl.**
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 366 B |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
briar-android/res/drawable-hdpi/msg_in_top.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 2.1 KiB |
BIN
briar-android/res/drawable-hdpi/msg_out_top.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
briar-android/res/drawable-hdpi/notice_in_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 2.0 KiB |
BIN
briar-android/res/drawable-hdpi/notice_out_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 210 B |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 175 B |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 1.9 KiB |
BIN
briar-android/res/drawable-mdpi/msg_in_top.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1014 B |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
briar-android/res/drawable-mdpi/msg_out_top.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-mdpi/notice_in_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-mdpi/notice_out_bottom.9.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
@@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
A FAB does not work, because even with fabSize="mini" it will be too big due to shadow drawing
|
||||
on lower API levels
|
||||
-->
|
||||
<ripple
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/briar_primary_dark">
|
||||
|
||||
<item>
|
||||
<shape android:shape="oval">
|
||||
<solid android:color="@color/briar_primary"/>
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</ripple>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
briar-android/res/drawable-xhdpi/msg_in_top.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
briar-android/res/drawable-xhdpi/msg_out_top.9.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
briar-android/res/drawable-xhdpi/notice_in_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 2.3 KiB |
BIN
briar-android/res/drawable-xhdpi/notice_out_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
briar-android/res/drawable-xxhdpi/msg_in_top.9.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 3.1 KiB |
BIN
briar-android/res/drawable-xxhdpi/msg_out_top.9.png
Normal file
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 3.0 KiB |
BIN
briar-android/res/drawable-xxhdpi/notice_in_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 2.9 KiB |
BIN
briar-android/res/drawable-xxhdpi/notice_out_bottom.9.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
10
briar-android/res/drawable/action_delete_black.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:alpha="0.56"
|
||||
android:viewportHeight="24.0"
|
||||
android:viewportWidth="24.0">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
||||
</vector>
|
||||
5
briar-android/res/drawable/alerts_and_states_error.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<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>
|
||||
13
briar-android/res/drawable/border_explanation.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid
|
||||
android:color="@android:color/transparent"/>
|
||||
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/briar_text_primary"/>
|
||||
|
||||
</shape>
|
||||
17
briar-android/res/drawable/bubble_white.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<vector android:height="24dp" android:viewportHeight="48.0"
|
||||
android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="48.0"
|
||||
android:viewportWidth="48.0">
|
||||
<path
|
||||
android:fillColor="#06b9ff"
|
||||
android:pathData="M9.1,19.3l14.9,11.8l14.9,-11.8l-1.9,-2.4l-13,10.4l-13,-10.4z"/>
|
||||
</vector>
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
<vector android:height="24dp" android:viewportHeight="48.0"
|
||||
android:viewportWidth="48.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportHeight="48.0"
|
||||
android:viewportWidth="48.0">
|
||||
<path
|
||||
android:fillColor="#06b9ff"
|
||||
android:pathData="M38.9,28.7l-14.9,-11.8l-14.9,11.8l1.9,2.4l13,-10.4l13,10.4z"/>
|
||||
</vector>
|
||||
|
||||
10
briar-android/res/drawable/ic_our_identity_black.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<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>
|
||||
10
briar-android/res/drawable/ic_repeat.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<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="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||
</vector>
|
||||
@@ -4,6 +4,6 @@
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
|
||||
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"/>
|
||||
</vector>
|
||||
10
briar-android/res/drawable/navigation_accept.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<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="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||
</vector>
|
||||
28
briar-android/res/drawable/qr_code_explanation.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="400dp"
|
||||
android:height="100dp"
|
||||
android:viewportHeight="49.5"
|
||||
android:viewportWidth="194.8">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M30.1 16.5l-9 0 0 -5c0 -2.4 -2 -4.4 -4.4 -4.4L4.4 7.1C2 7.1 0 9.1 0 11.5l0 24.2c0 2.4 2 4.4 4.4 4.4l9 0 0 5c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.3 -4.4zm-27.4 16.1l0 -20.9 15.8 0 0 20.9 -15.8 0zm10.7 4.6l-5.8 0 0 -1.5 5.8 0 0 1.5zm13.5 9.4l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -1.9 0.5 0c2.4 0 4.4 -2 4.4 -4.4l0 -14.6 10.8 0 0 20.9z"/>
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M101.2 16.5l-8.3 0 0 -4.4c0 -1.4 -1.2 -2.6 -2.6 -2.6l-3.9 0 -2.1 -2.5 -6.9 0 -2.2 2.5 -3.8 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 13.3c0 1.4 1.2 2.6 2.6 2.6l13.1 0 0 17.2c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.3c0.2 -2.4 -1.8 -4.4 -4.3 -4.4zm-26.4 2.4c0 -3.3 2.7 -6 6 -6 3.3 0 6 2.7 6 6 0 3.3 -2.7 6 -6 6 -3.3 0 -6 -2.7 -6 -6zm23.2 27.7l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.1 3.1 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.2 10.1 0 0 20.9z"/>
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M84.600003 18.9a3.8 3.8 0 0 1 -3.8 3.8 3.8 3.8 0 0 1 -3.8 -3.8 3.8 3.8 0 0 1 3.8 -3.8 3.8 3.8 0 0 1 3.8 3.8z"/>
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M175.3 16.5l-9.8 0 0 -5.7c0 -1.4 -1.2 -2.6 -2.6 -2.6l-19.3 0c-1.4 0 -2.6 1.2 -2.6 2.6l0 14.4c0 1.4 1.2 2.6 2.6 2.6l15.1 0 0 17.3c0 2.4 2 4.4 4.4 4.4l12.2 0c2.4 0 4.4 -2 4.4 -4.4l0 -24.2c0.1 -2.4 -1.9 -4.4 -4.4 -4.4zm-12.4 -5.9l-9.6 6 -9.6 -6 19.2 0zm-19.4 14.8l0 -12.3 9.8 6.1 9.8 -6.1 0 12.3 -19.6 0zm28.6 21.2l-5.8 0 0 -1.5 5.8 0 0 1.5zm5 -4.6l-15.8 0 0 -14.2 1.6 0c1.4 0 2.6 -1.2 2.6 -2.6l0 -4.1 11.6 0 0 20.9z"/>
|
||||
<path
|
||||
android:fillColor="#ff0000"
|
||||
android:pathData="M101.4 17.8l2 2 7.4 -7.3 7.3 7.3 2.1 -2 -7.4 -7.4 7.4 -7.3 -2.1 -2.1 -7.3 7.4 -7.4 -7.4 -2 2.1 7.3 7.3z"/>
|
||||
<path
|
||||
android:fillColor="#ff0000"
|
||||
android:pathData="M176 17.8l2.1 2 7.3 -7.3 7.4 7.3 2 -2 -7.3 -7.4 7.3 -7.3 -2 -2.1 -7.4 7.4 -7.3 -7.4 -2.1 2.1 7.3 7.3z"/>
|
||||
<path
|
||||
android:fillColor="#08b124"
|
||||
android:pathData="M35.8 18.8l0 0L52.5 2.1 50.5 0 35.6 14.8 28.5 7.7l-2.1 2.1 9.2 9.1z"/>
|
||||
</vector>
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_selected="true" android:drawable="@drawable/chevron48dp_down"/>
|
||||
<item android:drawable="@drawable/chevron48dp_down" android:state_selected="true"/>
|
||||
<item android:drawable="@drawable/chevron48dp_up"/>
|
||||
</selector>
|
||||
@@ -1,5 +0,0 @@
|
||||
<vector android:alpha="0.56" 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="M2.01,21L23,12 2.01,3 2,10l15,2 -15,2z"/>
|
||||
</vector>
|
||||
@@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
|
||||
</vector>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="40dp"
|
||||
android:height="15dp"
|
||||
android:width="31dp"
|
||||
android:height="12dp"
|
||||
android:viewportHeight="20"
|
||||
android:viewportWidth="49">
|
||||
<path
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="40dp"
|
||||
android:height="15dp"
|
||||
android:width="31dp"
|
||||
android:height="12dp"
|
||||
android:viewportHeight="20"
|
||||
android:viewportWidth="49">
|
||||
<path
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="40dp"
|
||||
android:height="15dp"
|
||||
android:width="31dp"
|
||||
android:height="12dp"
|
||||
android:viewportHeight="20"
|
||||
android:viewportWidth="49">
|
||||
<path
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="40dp"
|
||||
android:height="15dp"
|
||||
android:width="31dp"
|
||||
android:height="12dp"
|
||||
android:viewportHeight="20"
|
||||
android:viewportWidth="49">
|
||||
<path
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="@dimen/margin_activity_vertical"
|
||||
android:paddingEnd="@dimen/margin_activity_horizontal"
|
||||
android:paddingLeft="@dimen/margin_activity_horizontal"
|
||||
android:paddingRight="@dimen/margin_activity_horizontal"
|
||||
android:paddingStart="@dimen/margin_activity_horizontal"
|
||||
android:paddingTop="@dimen/margin_activity_vertical">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginEnd="@dimen/margin_medium"
|
||||
android:layout_marginRight="@dimen/margin_medium"
|
||||
android:layout_weight="1"
|
||||
android:adjustViewBounds="true"
|
||||
android:paddingBottom="@dimen/margin_activity_vertical"
|
||||
android:paddingEnd="@dimen/margin_activity_horizontal"
|
||||
android:paddingLeft="@dimen/margin_activity_horizontal"
|
||||
android:paddingRight="@dimen/margin_activity_horizontal"
|
||||
android:paddingStart="@dimen/margin_activity_horizontal"
|
||||
android:paddingTop="@dimen/margin_activity_vertical"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/qr_code_intro"/>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1">
|
||||
@@ -31,32 +31,37 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/margin_activity_vertical"
|
||||
android:paddingEnd="@dimen/margin_activity_horizontal"
|
||||
android:paddingLeft="@dimen/margin_activity_horizontal"
|
||||
android:paddingRight="@dimen/margin_activity_horizontal"
|
||||
android:paddingStart="@dimen/margin_activity_horizontal"
|
||||
android:paddingTop="@dimen/margin_activity_vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourNicknameView"
|
||||
style="@style/BriarTextBody"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/your_nickname"
|
||||
android:visibility="gone"/>
|
||||
android:background="@drawable/border_explanation"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/margin_large">
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_medium"
|
||||
android:background="@drawable/spinner_border"
|
||||
android:spinnerMode="dropdown"
|
||||
android:visibility="gone"/>
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:padding="@dimen/margin_medium"
|
||||
android:src="@drawable/qr_code_explanation"
|
||||
tools:ignore="ContentDescription"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/faceToFaceView"
|
||||
style="@style/BriarTextBody"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_medium"
|
||||
android:text="@string/face_to_face"/>
|
||||
<TextView
|
||||
style="@style/BriarTextBody"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_medium"
|
||||
android:text="@string/face_to_face"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/continueButton"
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/yourNicknameView"
|
||||
style="@style/BriarTextBody"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
@@ -46,12 +45,11 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_medium"
|
||||
android:background="@drawable/spinner_border"
|
||||
android:background="@drawable/border_spinner"
|
||||
android:spinnerMode="dropdown"
|
||||
android:visibility="gone"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/faceToFaceView"
|
||||
style="@style/BriarTextBody"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
69
briar-android/res/layout/activity_create_blog.xml
Normal file
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/margin_activity_horizontal"
|
||||
tools:context=".android.blogs.CreateBlogActivity">
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/titleLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:counterEnabled="true"
|
||||
app:counterOverflowTextAppearance="@style/BriarTextCounter.Overflow">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/titleInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/blogs_my_blogs_create_hint_title"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:id="@+id/descLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:counterEnabled="true"
|
||||
app:counterOverflowTextAppearance="@style/BriarTextCounter.Overflow">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/descInput"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/blogs_my_blogs_create_hint_desc"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/blogs_my_blogs_create_hint_desc_explanation"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/createBlogButton"
|
||||
style="@style/BriarButton"
|
||||
android:layout_marginTop="@dimen/margin_activity_vertical"
|
||||
android:enabled="false"
|
||||
android:text="@string/blogs_my_blogs_create"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/createBlogProgressBar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/margin_activity_vertical"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||