Compare commits
1 Commits
115-tor-pe
...
beta-2016-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62eda5cd91 |
34
.idea/codeStyleSettings.xml
generated
@@ -37,15 +37,37 @@
|
|||||||
<JavaCodeStyleSettings>
|
<JavaCodeStyleSettings>
|
||||||
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
|
<option name="ANNOTATION_PARAMETER_WRAP" value="1" />
|
||||||
</JavaCodeStyleSettings>
|
</JavaCodeStyleSettings>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<option name="GENERATE_INSTANCE_VARIABLES_FOR_PROPERTIES" value="ASK" />
|
||||||
|
<option name="RELEASE_STYLE" value="IVAR" />
|
||||||
|
<option name="TYPE_QUALIFIERS_PLACEMENT" value="BEFORE" />
|
||||||
|
<file>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||||
|
</file>
|
||||||
|
<class>
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||||
|
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||||
|
</class>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cpp" header="h" />
|
||||||
|
<pair source="c" header="h" />
|
||||||
|
</extensions>
|
||||||
|
</Objective-C-extensions>
|
||||||
<XML>
|
<XML>
|
||||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
|
||||||
</XML>
|
</XML>
|
||||||
<codeStyleSettings language="Groovy">
|
|
||||||
<indentOptions>
|
|
||||||
<option name="USE_TAB_CHARACTER" value="true" />
|
|
||||||
<option name="SMART_TABS" value="true" />
|
|
||||||
</indentOptions>
|
|
||||||
</codeStyleSettings>
|
|
||||||
<codeStyleSettings language="JAVA">
|
<codeStyleSettings language="JAVA">
|
||||||
<option name="RIGHT_MARGIN" value="80" />
|
<option name="RIGHT_MARGIN" value="80" />
|
||||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
|
apply plugin: 'witness'
|
||||||
apply plugin: 'com.neenbedankt.android-apt'
|
apply plugin: 'com.neenbedankt.android-apt'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven { url 'http://repo1.maven.org/maven2' }
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.3"
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 9
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
targetSdkVersion 22
|
||||||
consumerProguardFiles getDefaultProguardFile('proguard-android.txt'), '../briar-android/proguard-rules.txt'
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
}
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dexOptions {
|
dexOptions {
|
||||||
incremental true
|
incremental true
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_7
|
sourceCompatibility JavaVersion.VERSION_1_7
|
||||||
targetCompatibility JavaVersion.VERSION_1_7
|
targetCompatibility JavaVersion.VERSION_1_7
|
||||||
@@ -22,12 +32,23 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
testCompile project(':briar-api')
|
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
testCompile project(':briar-core')
|
compile project(':briar-api')
|
||||||
|
compile project(':briar-core')
|
||||||
testCompile 'junit:junit:4.12'
|
testCompile 'junit:junit:4.12'
|
||||||
testCompile 'net.jodah:concurrentunit:0.4.2'
|
testCompile 'net.jodah:concurrentunit:0.4.2'
|
||||||
testCompile 'com.android.support:appcompat-v7:23.2.1'
|
compile 'com.android.support:appcompat-v7:23.2.1'
|
||||||
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
testApt 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
provided 'javax.annotation:jsr250-api:1.0'
|
provided 'javax.annotation:jsr250-api:1.0'
|
||||||
testCompile project(':briar-tests')
|
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
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# 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 *;
|
||||||
|
#}
|
||||||
@@ -1,414 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.Blog;
|
|
||||||
import org.briarproject.api.blogs.BlogFactory;
|
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
|
||||||
import org.briarproject.api.blogs.BlogPost;
|
|
||||||
import org.briarproject.api.blogs.BlogPostFactory;
|
|
||||||
import org.briarproject.api.blogs.BlogPostHeader;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
|
||||||
import org.briarproject.api.crypto.KeyPair;
|
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.event.Event;
|
|
||||||
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.sync.SyncSession;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
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.sync.SyncModule;
|
|
||||||
import org.briarproject.transport.TransportModule;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Rule;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.rules.ExpectedException;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertFalse;
|
|
||||||
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.briarproject.api.sync.ValidationManager.State.PENDING;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class BlogManagerTest {
|
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
|
||||||
private SyncSessionFactory sync0, sync1;
|
|
||||||
private BlogManager blogManager0, blogManager1;
|
|
||||||
private ContactManager contactManager0, contactManager1;
|
|
||||||
private ContactId contactId0,contactId1;
|
|
||||||
private IdentityManager identityManager0, identityManager1;
|
|
||||||
private LocalAuthor author0, author1;
|
|
||||||
private Blog blog0, blog1;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Clock clock;
|
|
||||||
@Inject
|
|
||||||
AuthorFactory authorFactory;
|
|
||||||
@Inject
|
|
||||||
CryptoComponent crypto;
|
|
||||||
@Inject
|
|
||||||
BlogFactory blogFactory;
|
|
||||||
@Inject
|
|
||||||
BlogPostFactory blogPostFactory;
|
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
|
||||||
private volatile Waiter validationWaiter;
|
|
||||||
private volatile Waiter deliveryWaiter;
|
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
|
||||||
private final SecretKey master = TestUtils.getSecretKey();
|
|
||||||
private final int TIMEOUT = 15000;
|
|
||||||
private final String 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 =
|
|
||||||
DaggerBlogManagerTestComponent.builder().build();
|
|
||||||
component.inject(this);
|
|
||||||
injectEagerSingletons(component);
|
|
||||||
|
|
||||||
assertTrue(testDir.mkdirs());
|
|
||||||
File t0Dir = new File(testDir, AUTHOR1);
|
|
||||||
t0 = DaggerBlogManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
|
|
||||||
injectEagerSingletons(t0);
|
|
||||||
File t1Dir = new File(testDir, AUTHOR2);
|
|
||||||
t1 = DaggerBlogManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
|
|
||||||
injectEagerSingletons(t1);
|
|
||||||
|
|
||||||
identityManager0 = t0.getIdentityManager();
|
|
||||||
identityManager1 = t1.getIdentityManager();
|
|
||||||
contactManager0 = t0.getContactManager();
|
|
||||||
contactManager1 = t1.getContactManager();
|
|
||||||
blogManager0 = t0.getBlogManager();
|
|
||||||
blogManager1 = t1.getBlogManager();
|
|
||||||
sync0 = t0.getSyncSessionFactory();
|
|
||||||
sync1 = t1.getSyncSessionFactory();
|
|
||||||
|
|
||||||
// initialize waiters fresh for each test
|
|
||||||
validationWaiter = new Waiter();
|
|
||||||
deliveryWaiter = new Waiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testPersonalBlogInitialisation() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
Collection<Blog> blogs0 = blogManager0.getBlogs();
|
|
||||||
assertEquals(2, blogs0.size());
|
|
||||||
Iterator<Blog> i0 = blogs0.iterator();
|
|
||||||
assertEquals(author0, i0.next().getAuthor());
|
|
||||||
assertEquals(author1, i0.next().getAuthor());
|
|
||||||
|
|
||||||
Collection<Blog> blogs1 = blogManager1.getBlogs();
|
|
||||||
assertEquals(2, blogs1.size());
|
|
||||||
Iterator<Blog> i1 = blogs1.iterator();
|
|
||||||
assertEquals(author1, i1.next().getAuthor());
|
|
||||||
assertEquals(author0, i1.next().getAuthor());
|
|
||||||
|
|
||||||
assertEquals(blog0, blogManager0.getPersonalBlog(author0));
|
|
||||||
assertEquals(blog0, blogManager1.getPersonalBlog(author0));
|
|
||||||
assertEquals(blog1, blogManager0.getPersonalBlog(author1));
|
|
||||||
assertEquals(blog1, blogManager1.getPersonalBlog(author1));
|
|
||||||
|
|
||||||
assertEquals(blog0, blogManager0.getBlog(blog0.getId()));
|
|
||||||
assertEquals(blog0, blogManager1.getBlog(blog0.getId()));
|
|
||||||
assertEquals(blog1, blogManager0.getBlog(blog1.getId()));
|
|
||||||
assertEquals(blog1, blogManager1.getBlog(blog1.getId()));
|
|
||||||
|
|
||||||
assertEquals(1, blogManager0.getBlogs(author0).size());
|
|
||||||
assertEquals(1, blogManager1.getBlogs(author0).size());
|
|
||||||
assertEquals(1, blogManager0.getBlogs(author1).size());
|
|
||||||
assertEquals(1, blogManager1.getBlogs(author1).size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlogPost() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// check that blog0 has no posts
|
|
||||||
final byte[] body = TestUtils.getRandomBytes(42);
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(0, headers0.size());
|
|
||||||
|
|
||||||
// add a post to blog0
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog0.getId(), null, clock.currentTimeMillis(),
|
|
||||||
null, author0, CONTENT_TYPE, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// check that post is now in blog0
|
|
||||||
headers0 = blogManager0.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers0.size());
|
|
||||||
|
|
||||||
// check that body is there
|
|
||||||
assertArrayEquals(body,
|
|
||||||
blogManager0.getPostBody(p.getMessage().getId()));
|
|
||||||
|
|
||||||
// make sure that blog0 at author1 doesn't have the post yet
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(0, headers1.size());
|
|
||||||
|
|
||||||
// sync the post over
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// make sure post arrived
|
|
||||||
headers1 = blogManager1.getPostHeaders(blog0.getId());
|
|
||||||
assertEquals(1, headers1.size());
|
|
||||||
|
|
||||||
// check that body is there
|
|
||||||
assertArrayEquals(body,
|
|
||||||
blogManager1.getPostBody(p.getMessage().getId()));
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testBlogPostInWrongBlog() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// add a post to blog1
|
|
||||||
final byte[] body = TestUtils.getRandomBytes(42);
|
|
||||||
BlogPost p = blogPostFactory
|
|
||||||
.createBlogPost(blog1.getId(), null, clock.currentTimeMillis(),
|
|
||||||
null, author0, CONTENT_TYPE, body);
|
|
||||||
blogManager0.addLocalPost(p);
|
|
||||||
|
|
||||||
// check that post is now in blog1
|
|
||||||
Collection<BlogPostHeader> headers0 =
|
|
||||||
blogManager0.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(1, headers0.size());
|
|
||||||
|
|
||||||
// sync the post over
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// make sure post did not arrive, because of wrong signature
|
|
||||||
Collection<BlogPostHeader> headers1 =
|
|
||||||
blogManager1.getPostHeaders(blog1.getId());
|
|
||||||
assertEquals(0, headers1.size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAddAndRemoveBlog() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
String name = "Test Blog";
|
|
||||||
String desc = "Description";
|
|
||||||
|
|
||||||
// add blog
|
|
||||||
Blog blog = blogManager0.addBlog(author0, name, desc);
|
|
||||||
Collection<Blog> blogs0 = blogManager0.getBlogs();
|
|
||||||
assertEquals(3, blogs0.size());
|
|
||||||
assertTrue(blogs0.contains(blog));
|
|
||||||
assertEquals(2, blogManager0.getBlogs(author0).size());
|
|
||||||
assertTrue(blogManager0.canBeRemoved(blog.getId()));
|
|
||||||
|
|
||||||
// remove blog
|
|
||||||
blogManager0.removeBlog(blog);
|
|
||||||
blogs0 = blogManager0.getBlogs();
|
|
||||||
assertEquals(2, blogs0.size());
|
|
||||||
assertFalse(blogs0.contains(blog));
|
|
||||||
assertEquals(1, blogManager0.getBlogs(author0).size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCanNotRemoveContactsPersonalBlog() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Listener implements EventListener {
|
|
||||||
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 ||
|
|
||||||
event.getState() == PENDING) {
|
|
||||||
validationWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defaultInit() throws DbException {
|
|
||||||
addDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
listenToEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultIdentities() throws DbException {
|
|
||||||
KeyPair keyPair0 = crypto.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey0 = keyPair0.getPublic().getEncoded();
|
|
||||||
byte[] privateKey0 = keyPair0.getPrivate().getEncoded();
|
|
||||||
author0 = authorFactory
|
|
||||||
.createLocalAuthor(AUTHOR1, publicKey0, privateKey0);
|
|
||||||
identityManager0.addLocalAuthor(author0);
|
|
||||||
blog0 = blogFactory.createPersonalBlog(author0);
|
|
||||||
|
|
||||||
KeyPair keyPair1 = crypto.generateSignatureKeyPair();
|
|
||||||
byte[] publicKey1 = keyPair1.getPublic().getEncoded();
|
|
||||||
byte[] privateKey1 = keyPair1.getPrivate().getEncoded();
|
|
||||||
author1 = authorFactory
|
|
||||||
.createLocalAuthor(AUTHOR2, publicKey1, privateKey1);
|
|
||||||
identityManager1.addLocalAuthor(author1);
|
|
||||||
blog1 = blogFactory.createPersonalBlog(author1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
|
||||||
// sharer adds invitee as contact
|
|
||||||
contactId1 = contactManager0.addContact(author1,
|
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
// invitee adds sharer back
|
|
||||||
contactId0 = contactManager1.addContact(author0,
|
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listenToEvents() {
|
|
||||||
Listener listener0 = new Listener();
|
|
||||||
t0.getEventBus().addListener(listener0);
|
|
||||||
Listener listener1 = new Listener();
|
|
||||||
t1.getEventBus().addListener(listener1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync0To1() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync1To0() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
|
||||||
SyncSessionFactory toSync, ContactId toId, String debug)
|
|
||||||
throws IOException, TimeoutException {
|
|
||||||
|
|
||||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
// Create an outgoing sync session
|
|
||||||
SyncSession sessionFrom =
|
|
||||||
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
|
||||||
// Write whatever needs to be written
|
|
||||||
sessionFrom.run();
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
|
||||||
// Create an incoming sync session
|
|
||||||
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
|
|
||||||
// Read whatever needs to be read
|
|
||||||
sessionTo.run();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startLifecycles() throws InterruptedException {
|
|
||||||
// Start the lifecycle manager and wait for it to finish
|
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
|
||||||
lifecycleManager0.startServices();
|
|
||||||
lifecycleManager1.startServices();
|
|
||||||
lifecycleManager0.waitForStartup();
|
|
||||||
lifecycleManager1.waitForStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopLifecycles() throws InterruptedException {
|
|
||||||
// Clean up
|
|
||||||
lifecycleManager0.stopServices();
|
|
||||||
lifecycleManager1.stopServices();
|
|
||||||
lifecycleManager0.waitForShutdown();
|
|
||||||
lifecycleManager1.waitForShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectEagerSingletons(BlogManagerTestComponent 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 SyncModule.EagerSingletons());
|
|
||||||
component.inject(new PropertiesModule.EagerSingletons());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import org.briarproject.api.blogs.BlogManager;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.event.EventBus;
|
|
||||||
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.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,
|
|
||||||
IdentityModule.class,
|
|
||||||
LifecycleModule.class,
|
|
||||||
PropertiesModule.class,
|
|
||||||
SharingModule.class,
|
|
||||||
SyncModule.class,
|
|
||||||
SystemModule.class,
|
|
||||||
TransportModule.class
|
|
||||||
})
|
|
||||||
interface BlogManagerTestComponent {
|
|
||||||
|
|
||||||
void inject(BlogManagerTest 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(SyncModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(TransportModule.EagerSingletons init);
|
|
||||||
|
|
||||||
LifecycleManager getLifecycleManager();
|
|
||||||
|
|
||||||
EventBus getEventBus();
|
|
||||||
|
|
||||||
IdentityManager getIdentityManager();
|
|
||||||
|
|
||||||
ContactManager getContactManager();
|
|
||||||
|
|
||||||
BlogManager getBlogManager();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,759 +0,0 @@
|
|||||||
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.ClientId;
|
|
||||||
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 shard 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;
|
|
||||||
|
|
||||||
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(blogSharingManager0.getClientId()) &&
|
|
||||||
!event.isLocal()) {
|
|
||||||
LOG.info("TEST: Sharer received message in group " +
|
|
||||||
event.getMessage().getGroupId().hashCode());
|
|
||||||
msgWaiter.resume();
|
|
||||||
} else if (s == DELIVERED && !event.isLocal() &&
|
|
||||||
c.equals(blogManager0.getClientId())) {
|
|
||||||
LOG.info("TEST: Sharer received blog post");
|
|
||||||
msgWaiter.resume();
|
|
||||||
}
|
|
||||||
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
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(blogSharingManager0.getClientId()) &&
|
|
||||||
!event.isLocal()) {
|
|
||||||
LOG.info("TEST: Invitee received message in group " +
|
|
||||||
event.getMessage().getGroupId().hashCode());
|
|
||||||
msgWaiter.resume();
|
|
||||||
} else if (s == DELIVERED && !event.isLocal() &&
|
|
||||||
c.equals(blogManager0.getClientId())) {
|
|
||||||
LOG.info("TEST: Invitee received blog post");
|
|
||||||
msgWaiter.resume();
|
|
||||||
}
|
|
||||||
} else if (e instanceof BlogInvitationReceivedEvent) {
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
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();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,447 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import junit.framework.Assert;
|
|
||||||
|
|
||||||
import net.jodah.concurrentunit.Waiter;
|
|
||||||
|
|
||||||
import org.briarproject.api.contact.Contact;
|
|
||||||
import org.briarproject.api.contact.ContactId;
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.event.Event;
|
|
||||||
import org.briarproject.api.event.EventListener;
|
|
||||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
|
||||||
import org.briarproject.api.forum.Forum;
|
|
||||||
import org.briarproject.api.forum.ForumManager;
|
|
||||||
import org.briarproject.api.forum.ForumPost;
|
|
||||||
import org.briarproject.api.forum.ForumPostFactory;
|
|
||||||
import org.briarproject.api.forum.ForumPostHeader;
|
|
||||||
import org.briarproject.api.forum.ForumSharingManager;
|
|
||||||
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.GroupId;
|
|
||||||
import org.briarproject.api.sync.SyncSession;
|
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
|
||||||
import org.briarproject.api.system.Clock;
|
|
||||||
import org.briarproject.contact.ContactModule;
|
|
||||||
import org.briarproject.crypto.CryptoModule;
|
|
||||||
import org.briarproject.forum.ForumModule;
|
|
||||||
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.briarproject.util.StringUtils;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.concurrent.TimeoutException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import static junit.framework.Assert.assertEquals;
|
|
||||||
import static junit.framework.Assert.assertNull;
|
|
||||||
import static junit.framework.TestCase.assertFalse;
|
|
||||||
import static org.briarproject.TestPluginsModule.MAX_LATENCY;
|
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.DELIVERED;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.INVALID;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.PENDING;
|
|
||||||
import static org.briarproject.api.sync.ValidationManager.State.VALID;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class ForumManagerTest {
|
|
||||||
|
|
||||||
private LifecycleManager lifecycleManager0, lifecycleManager1;
|
|
||||||
private SyncSessionFactory sync0, sync1;
|
|
||||||
private ForumManager forumManager0, forumManager1;
|
|
||||||
private ContactManager contactManager0, contactManager1;
|
|
||||||
private ContactId contactId0,contactId1;
|
|
||||||
private IdentityManager identityManager0, identityManager1;
|
|
||||||
private LocalAuthor author0, author1;
|
|
||||||
private Forum forum0;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
Clock clock;
|
|
||||||
@Inject
|
|
||||||
AuthorFactory authorFactory;
|
|
||||||
@Inject
|
|
||||||
ForumPostFactory forumPostFactory;
|
|
||||||
|
|
||||||
// objects accessed from background threads need to be volatile
|
|
||||||
private volatile ForumSharingManager forumSharingManager0;
|
|
||||||
private volatile ForumSharingManager forumSharingManager1;
|
|
||||||
private volatile Waiter validationWaiter;
|
|
||||||
private volatile Waiter deliveryWaiter;
|
|
||||||
|
|
||||||
private final File testDir = TestUtils.getTestDirectory();
|
|
||||||
private final SecretKey master = TestUtils.getSecretKey();
|
|
||||||
private final int TIMEOUT = 15000;
|
|
||||||
private final String SHARER = "Sharer";
|
|
||||||
private final String INVITEE = "Invitee";
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
|
||||||
Logger.getLogger(ForumSharingIntegrationTest.class.getName());
|
|
||||||
|
|
||||||
private ForumManagerTestComponent t0, t1;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
ForumManagerTestComponent component =
|
|
||||||
DaggerForumManagerTestComponent.builder().build();
|
|
||||||
component.inject(this);
|
|
||||||
injectEagerSingletons(component);
|
|
||||||
|
|
||||||
assertTrue(testDir.mkdirs());
|
|
||||||
File t0Dir = new File(testDir, SHARER);
|
|
||||||
t0 = DaggerForumManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t0Dir)).build();
|
|
||||||
injectEagerSingletons(t0);
|
|
||||||
File t1Dir = new File(testDir, INVITEE);
|
|
||||||
t1 = DaggerForumManagerTestComponent.builder()
|
|
||||||
.testDatabaseModule(new TestDatabaseModule(t1Dir)).build();
|
|
||||||
injectEagerSingletons(t1);
|
|
||||||
|
|
||||||
identityManager0 = t0.getIdentityManager();
|
|
||||||
identityManager1 = t1.getIdentityManager();
|
|
||||||
contactManager0 = t0.getContactManager();
|
|
||||||
contactManager1 = t1.getContactManager();
|
|
||||||
forumManager0 = t0.getForumManager();
|
|
||||||
forumManager1 = t1.getForumManager();
|
|
||||||
forumSharingManager0 = t0.getForumSharingManager();
|
|
||||||
forumSharingManager1 = t1.getForumSharingManager();
|
|
||||||
sync0 = t0.getSyncSessionFactory();
|
|
||||||
sync1 = t1.getSyncSessionFactory();
|
|
||||||
|
|
||||||
// initialize waiters fresh for each test
|
|
||||||
validationWaiter = new Waiter();
|
|
||||||
deliveryWaiter = new Waiter();
|
|
||||||
}
|
|
||||||
|
|
||||||
private ForumPost createForumPost(GroupId groupId, ForumPost parent,
|
|
||||||
String body, long ms) throws Exception {
|
|
||||||
return forumPostFactory.createAnonymousPost(groupId, ms,
|
|
||||||
parent == null ? null : parent.getMessage().getId(),
|
|
||||||
"text/plain", StringUtils.toUtf8(body));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForumPost() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
Forum forum = forumManager0.addForum("TestForum");
|
|
||||||
assertEquals(1, forumManager0.getForums().size());
|
|
||||||
final long ms1 = clock.currentTimeMillis() - 1000L;
|
|
||||||
final String body1 = "some forum text";
|
|
||||||
final long ms2 = clock.currentTimeMillis();
|
|
||||||
final String body2 = "some other forum text";
|
|
||||||
ForumPost post1 =
|
|
||||||
createForumPost(forum.getGroup().getId(), null, body1, ms1);
|
|
||||||
assertEquals(ms1, post1.getMessage().getTimestamp());
|
|
||||||
ForumPost post2 =
|
|
||||||
createForumPost(forum.getGroup().getId(), post1, body2, ms2);
|
|
||||||
assertEquals(ms2, post2.getMessage().getTimestamp());
|
|
||||||
forumManager0.addLocalPost(post1);
|
|
||||||
forumManager0.setReadFlag(post1.getMessage().getId(), true);
|
|
||||||
forumManager0.addLocalPost(post2);
|
|
||||||
forumManager0.setReadFlag(post2.getMessage().getId(), false);
|
|
||||||
Collection<ForumPostHeader> headers =
|
|
||||||
forumManager0.getPostHeaders(forum.getGroup().getId());
|
|
||||||
assertEquals(2, headers.size());
|
|
||||||
for (ForumPostHeader h : headers) {
|
|
||||||
final String hBody =
|
|
||||||
StringUtils.fromUtf8(forumManager0.getPostBody(h.getId()));
|
|
||||||
|
|
||||||
boolean isPost1 = h.getId().equals(post1.getMessage().getId());
|
|
||||||
boolean isPost2 = h.getId().equals(post2.getMessage().getId());
|
|
||||||
Assert.assertTrue(isPost1 || isPost2);
|
|
||||||
if (isPost1) {
|
|
||||||
assertEquals(h.getTimestamp(), ms1);
|
|
||||||
assertEquals(body1, hBody);
|
|
||||||
assertNull(h.getParentId());
|
|
||||||
assertTrue(h.isRead());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
assertEquals(h.getTimestamp(), ms2);
|
|
||||||
assertEquals(body2, hBody);
|
|
||||||
assertEquals(h.getParentId(), post2.getParent());
|
|
||||||
assertFalse(h.isRead());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
forumManager0.removeForum(forum);
|
|
||||||
assertEquals(0, forumManager0.getForums().size());
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForumPostDelivery() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// share forum
|
|
||||||
GroupId g = forum0.getId();
|
|
||||||
forumSharingManager0.sendInvitation(g, contactId1, null);
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
Contact c0 = contactManager1.getContact(contactId0);
|
|
||||||
forumSharingManager1.respondToInvitation(forum0, c0, true);
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// add one forum post
|
|
||||||
long time = clock.currentTimeMillis();
|
|
||||||
ForumPost post1 = createForumPost(g, null, "a", time);
|
|
||||||
forumManager0.addLocalPost(post1);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// send post to 1
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(1, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// add another forum post
|
|
||||||
time = clock.currentTimeMillis();
|
|
||||||
ForumPost post2 = createForumPost(g, null, "b", time);
|
|
||||||
forumManager1.addLocalPost(post2);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// send post to 0
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForumPostDeliveredAfterParent() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// share forum
|
|
||||||
GroupId g = forum0.getId();
|
|
||||||
forumSharingManager0.sendInvitation(g, contactId1, null);
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
Contact c0 = contactManager1.getContact(contactId0);
|
|
||||||
forumSharingManager1.respondToInvitation(forum0, c0, true);
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// add one forum post without the parent
|
|
||||||
long time = clock.currentTimeMillis();
|
|
||||||
ForumPost post1 = createForumPost(g, null, "a", time);
|
|
||||||
ForumPost post2 = createForumPost(g, post1, "a", time);
|
|
||||||
forumManager0.addLocalPost(post2);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// send post to 1 without waiting for message delivery
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// now add the parent post as well
|
|
||||||
forumManager0.addLocalPost(post1);
|
|
||||||
assertEquals(2, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// and send it over to 1 and wait for a second message to be delivered
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 2);
|
|
||||||
assertEquals(2, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForumPostWithParentInOtherGroup() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
defaultInit();
|
|
||||||
|
|
||||||
// share forum
|
|
||||||
GroupId g = forum0.getId();
|
|
||||||
forumSharingManager0.sendInvitation(g, contactId1, null);
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
Contact c0 = contactManager1.getContact(contactId0);
|
|
||||||
forumSharingManager1.respondToInvitation(forum0, c0, true);
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// share a second forum
|
|
||||||
Forum forum1 = forumManager0.addForum("Test Forum1");
|
|
||||||
GroupId g1 = forum1.getId();
|
|
||||||
forumSharingManager0.sendInvitation(g1, contactId1, null);
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
forumSharingManager1.respondToInvitation(forum1, c0, true);
|
|
||||||
sync1To0();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
|
|
||||||
// add one forum post with a parent in another forum
|
|
||||||
long time = clock.currentTimeMillis();
|
|
||||||
ForumPost post1 = createForumPost(g1, null, "a", time);
|
|
||||||
ForumPost post = createForumPost(g, post1, "b", time);
|
|
||||||
forumManager0.addLocalPost(post);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// send posts to 1
|
|
||||||
sync0To1();
|
|
||||||
validationWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
|
|
||||||
// now also add the parent post which is in another group
|
|
||||||
forumManager0.addLocalPost(post1);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g1).size());
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g1).size());
|
|
||||||
|
|
||||||
// send posts to 1
|
|
||||||
sync0To1();
|
|
||||||
deliveryWaiter.await(TIMEOUT, 1);
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g).size());
|
|
||||||
assertEquals(1, forumManager0.getPostHeaders(g1).size());
|
|
||||||
// the next line is critical, makes sure post doesn't show up
|
|
||||||
assertEquals(0, forumManager1.getPostHeaders(g).size());
|
|
||||||
assertEquals(1, forumManager1.getPostHeaders(g1).size());
|
|
||||||
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws Exception {
|
|
||||||
TestUtils.deleteTestDirectory(testDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Listener implements EventListener {
|
|
||||||
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 ||
|
|
||||||
event.getState() == PENDING) {
|
|
||||||
validationWaiter.resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void defaultInit() throws DbException {
|
|
||||||
addDefaultIdentities();
|
|
||||||
addDefaultContacts();
|
|
||||||
addForum();
|
|
||||||
listenToEvents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultIdentities() throws DbException {
|
|
||||||
author0 = authorFactory.createLocalAuthor(SHARER,
|
|
||||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
|
||||||
TestUtils.getRandomBytes(123));
|
|
||||||
identityManager0.addLocalAuthor(author0);
|
|
||||||
author1 = authorFactory.createLocalAuthor(INVITEE,
|
|
||||||
TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH),
|
|
||||||
TestUtils.getRandomBytes(123));
|
|
||||||
identityManager1.addLocalAuthor(author1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addDefaultContacts() throws DbException {
|
|
||||||
// sharer adds invitee as contact
|
|
||||||
contactId1 = contactManager0.addContact(author1,
|
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
// invitee adds sharer back
|
|
||||||
contactId0 = contactManager1.addContact(author0,
|
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
|
||||||
true, true
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addForum() throws DbException {
|
|
||||||
forum0 = forumManager0.addForum("Test Forum");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void listenToEvents() {
|
|
||||||
Listener listener0 = new Listener();
|
|
||||||
t0.getEventBus().addListener(listener0);
|
|
||||||
Listener listener1 = new Listener();
|
|
||||||
t1.getEventBus().addListener(listener1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync0To1() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sync1To0() throws IOException, TimeoutException {
|
|
||||||
deliverMessage(sync1, contactId1, sync0, contactId0, "1 to 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deliverMessage(SyncSessionFactory fromSync, ContactId fromId,
|
|
||||||
SyncSessionFactory toSync, ContactId toId, String debug)
|
|
||||||
throws IOException, TimeoutException {
|
|
||||||
|
|
||||||
if (debug != null) LOG.info("TEST: Sending message from " + debug);
|
|
||||||
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
// Create an outgoing sync session
|
|
||||||
SyncSession sessionFrom =
|
|
||||||
fromSync.createSimplexOutgoingSession(toId, MAX_LATENCY, out);
|
|
||||||
// Write whatever needs to be written
|
|
||||||
sessionFrom.run();
|
|
||||||
out.close();
|
|
||||||
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
|
||||||
// Create an incoming sync session
|
|
||||||
SyncSession sessionTo = toSync.createIncomingSession(fromId, in);
|
|
||||||
// Read whatever needs to be read
|
|
||||||
sessionTo.run();
|
|
||||||
in.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startLifecycles() throws InterruptedException {
|
|
||||||
// Start the lifecycle manager and wait for it to finish
|
|
||||||
lifecycleManager0 = t0.getLifecycleManager();
|
|
||||||
lifecycleManager1 = t1.getLifecycleManager();
|
|
||||||
lifecycleManager0.startServices();
|
|
||||||
lifecycleManager1.startServices();
|
|
||||||
lifecycleManager0.waitForStartup();
|
|
||||||
lifecycleManager1.waitForStartup();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void stopLifecycles() throws InterruptedException {
|
|
||||||
// Clean up
|
|
||||||
lifecycleManager0.stopServices();
|
|
||||||
lifecycleManager1.stopServices();
|
|
||||||
lifecycleManager0.waitForShutdown();
|
|
||||||
lifecycleManager1.waitForShutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void injectEagerSingletons(ForumManagerTestComponent component) {
|
|
||||||
component.inject(new LifecycleModule.EagerSingletons());
|
|
||||||
component.inject(new ForumModule.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());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
import org.briarproject.api.contact.ContactManager;
|
|
||||||
import org.briarproject.api.event.EventBus;
|
|
||||||
import org.briarproject.api.forum.ForumManager;
|
|
||||||
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;
|
|
||||||
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,
|
|
||||||
ForumModule.class,
|
|
||||||
BlogsModule.class,
|
|
||||||
IdentityModule.class,
|
|
||||||
LifecycleModule.class,
|
|
||||||
PropertiesModule.class,
|
|
||||||
SharingModule.class,
|
|
||||||
SyncModule.class,
|
|
||||||
SystemModule.class,
|
|
||||||
TransportModule.class
|
|
||||||
})
|
|
||||||
interface ForumManagerTestComponent {
|
|
||||||
|
|
||||||
void inject(ForumManagerTest testCase);
|
|
||||||
|
|
||||||
void inject(ContactModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(CryptoModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(ForumModule.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();
|
|
||||||
|
|
||||||
ForumSharingManager getForumSharingManager();
|
|
||||||
|
|
||||||
ForumManager getForumManager();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
package org.briarproject;
|
|
||||||
|
|
||||||
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.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;
|
|
||||||
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,
|
|
||||||
ForumModule.class,
|
|
||||||
BlogsModule.class,
|
|
||||||
IdentityModule.class,
|
|
||||||
LifecycleModule.class,
|
|
||||||
PropertiesModule.class,
|
|
||||||
SharingModule.class,
|
|
||||||
SyncModule.class,
|
|
||||||
SystemModule.class,
|
|
||||||
TransportModule.class
|
|
||||||
})
|
|
||||||
interface ForumSharingIntegrationTestComponent {
|
|
||||||
|
|
||||||
void inject(ForumSharingIntegrationTest testCase);
|
|
||||||
|
|
||||||
void inject(ContactModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(CryptoModule.EagerSingletons init);
|
|
||||||
|
|
||||||
void inject(ForumModule.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();
|
|
||||||
|
|
||||||
ForumSharingManager getForumSharingManager();
|
|
||||||
|
|
||||||
ForumManager getForumManager();
|
|
||||||
|
|
||||||
SyncSessionFactory getSyncSessionFactory();
|
|
||||||
|
|
||||||
/* the following methods are only needed to manually construct messages */
|
|
||||||
|
|
||||||
DatabaseComponent getDatabaseComponent();
|
|
||||||
|
|
||||||
PrivateGroupFactory getPrivateGroupFactory();
|
|
||||||
|
|
||||||
ClientHelper getClientHelper();
|
|
||||||
|
|
||||||
MessageQueueManager getMessageQueueManager();
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -19,7 +19,7 @@ import org.briarproject.api.event.IntroductionAbortedEvent;
|
|||||||
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
||||||
import org.briarproject.api.event.IntroductionSucceededEvent;
|
import org.briarproject.api.event.IntroductionSucceededEvent;
|
||||||
import org.briarproject.api.event.MessageStateChangedEvent;
|
import org.briarproject.api.event.MessageValidatedEvent;
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
import org.briarproject.api.identity.AuthorFactory;
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
@@ -29,13 +29,10 @@ import org.briarproject.api.introduction.IntroductionRequest;
|
|||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.properties.TransportProperties;
|
import org.briarproject.api.properties.TransportProperties;
|
||||||
import org.briarproject.api.properties.TransportPropertyManager;
|
import org.briarproject.api.properties.TransportPropertyManager;
|
||||||
import org.briarproject.api.sync.ClientId;
|
|
||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.sync.SyncSession;
|
import org.briarproject.api.sync.SyncSession;
|
||||||
import org.briarproject.api.sync.SyncSessionFactory;
|
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.api.system.Clock;
|
||||||
import org.briarproject.contact.ContactModule;
|
import org.briarproject.contact.ContactModule;
|
||||||
import org.briarproject.crypto.CryptoModule;
|
import org.briarproject.crypto.CryptoModule;
|
||||||
@@ -73,8 +70,6 @@ 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.SESSION_ID;
|
||||||
import static org.briarproject.api.introduction.IntroductionConstants.TYPE;
|
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_REQUEST;
|
||||||
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.assertEquals;
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -164,20 +159,20 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2,
|
contactId2 = contactManager0.addContact(author2,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -238,18 +233,6 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
assertTrue(contactManager2
|
assertTrue(contactManager2
|
||||||
.contactExists(author1.getId(), author2.getId()));
|
.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();
|
assertDefaultUiMessages();
|
||||||
} finally {
|
} finally {
|
||||||
stopLifecycles();
|
stopLifecycles();
|
||||||
@@ -268,18 +251,18 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -361,18 +344,18 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||||
master, clock.currentTimeMillis(), false, true, true
|
master, clock.currentTimeMillis(), false, true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -449,18 +432,18 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
contactId2 = contactManager0.addContact(author2, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||||
master, clock.currentTimeMillis(), false, true, true
|
master, clock.currentTimeMillis(), false, true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -528,11 +511,11 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
// Add introducee as contact
|
// Add introducee as contact
|
||||||
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
contactId1 = contactManager0.addContact(author1, author0.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
contactId0 = contactManager1.addContact(author0, author1.getId(),
|
||||||
master, clock.currentTimeMillis(), true, true, true
|
master, clock.currentTimeMillis(), true, true
|
||||||
);
|
);
|
||||||
|
|
||||||
// listen to events
|
// listen to events
|
||||||
@@ -585,21 +568,21 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
// Add introducees' authors as contacts
|
// Add introducees' authors as contacts
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2,
|
contactId2 = contactManager0.addContact(author2,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = null;
|
contactId0 = null;
|
||||||
ContactId contactId01 = contactManager1.addContact(author0,
|
ContactId contactId01 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), false,
|
author1.getId(), master, clock.currentTimeMillis(), false,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager1.addContact(author0,
|
ContactId contactId02 = contactManager1.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), false,
|
author2.getId(), master, clock.currentTimeMillis(), false,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
// listen to events
|
// listen to events
|
||||||
@@ -679,20 +662,20 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2,
|
contactId2 = contactManager0.addContact(author2,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -776,20 +759,20 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
// Add introducees as contacts
|
// Add introducees as contacts
|
||||||
contactId1 = contactManager0.addContact(author1,
|
contactId1 = contactManager0.addContact(author1,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
contactId2 = contactManager0.addContact(author2,
|
contactId2 = contactManager0.addContact(author2,
|
||||||
author0.getId(), master, clock.currentTimeMillis(), true,
|
author0.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
// Add introducer back
|
// Add introducer back
|
||||||
contactId0 = contactManager1.addContact(author0,
|
contactId0 = contactManager1.addContact(author0,
|
||||||
author1.getId(), master, clock.currentTimeMillis(), true,
|
author1.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
ContactId contactId02 = contactManager2.addContact(author0,
|
ContactId contactId02 = contactManager2.addContact(author0,
|
||||||
author2.getId(), master, clock.currentTimeMillis(), true,
|
author2.getId(), master, clock.currentTimeMillis(), true,
|
||||||
true, true
|
true
|
||||||
);
|
);
|
||||||
assertTrue(contactId0.equals(contactId02));
|
assertTrue(contactId0.equals(contactId02));
|
||||||
|
|
||||||
@@ -849,106 +832,6 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIntroduceesRemovedCleanup() throws Exception {
|
|
||||||
startLifecycles();
|
|
||||||
try {
|
|
||||||
// Add Identities
|
|
||||||
addDefaultIdentities();
|
|
||||||
|
|
||||||
// Add Transport Properties
|
|
||||||
addTransportProperties();
|
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
// 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 first request message
|
|
||||||
deliverMessage(sync0, contactId0, sync1, contactId1, "0 to 1");
|
|
||||||
eventWaiter.await(TIMEOUT, 1);
|
|
||||||
assertTrue(listener1.requestReceived);
|
|
||||||
|
|
||||||
// get database and local group for introducee
|
|
||||||
DatabaseComponent db0 = t0.getDatabaseComponent();
|
|
||||||
IntroductionGroupFactory groupFactory0 =
|
|
||||||
t0.getIntroductionGroupFactory();
|
|
||||||
Group group1 = groupFactory0.createLocalGroup();
|
|
||||||
|
|
||||||
// get local session state messages
|
|
||||||
Map<MessageId, Metadata> map;
|
|
||||||
Transaction txn = db0.startTransaction(false);
|
|
||||||
try {
|
|
||||||
map = db0.getMessageMetadata(txn, group1.getId());
|
|
||||||
txn.setComplete();
|
|
||||||
} finally {
|
|
||||||
db0.endTransaction(txn);
|
|
||||||
}
|
|
||||||
// check that we have one session state
|
|
||||||
assertEquals(1, map.size());
|
|
||||||
|
|
||||||
// introducer removes introducee1
|
|
||||||
contactManager0.removeContact(contactId1);
|
|
||||||
|
|
||||||
// get local session state messages again
|
|
||||||
txn = db0.startTransaction(false);
|
|
||||||
try {
|
|
||||||
map = db0.getMessageMetadata(txn, group1.getId());
|
|
||||||
txn.setComplete();
|
|
||||||
} finally {
|
|
||||||
db0.endTransaction(txn);
|
|
||||||
}
|
|
||||||
// make sure local state is still there
|
|
||||||
assertEquals(1, map.size());
|
|
||||||
|
|
||||||
// introducer removes other introducee
|
|
||||||
contactManager0.removeContact(contactId2);
|
|
||||||
|
|
||||||
// get local session state messages again
|
|
||||||
txn = db0.startTransaction(false);
|
|
||||||
try {
|
|
||||||
map = db0.getMessageMetadata(txn, group1.getId());
|
|
||||||
txn.setComplete();
|
|
||||||
} finally {
|
|
||||||
db0.endTransaction(txn);
|
|
||||||
}
|
|
||||||
// make sure local state is gone now
|
|
||||||
assertEquals(0, map.size());
|
|
||||||
} finally {
|
|
||||||
stopLifecycles();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO add a test for faking responses when #256 is implemented
|
// TODO add a test for faking responses when #256 is implemented
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@@ -1064,16 +947,15 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageValidatedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageValidatedEvent event = (MessageValidatedEvent) e;
|
||||||
State s = event.getState();
|
if (event.getClientId()
|
||||||
ClientId c = event.getClientId();
|
.equals(introductionManager0.getClientId()) &&
|
||||||
if ((s == DELIVERED || s == INVALID) &&
|
|
||||||
c.equals(introductionManager0.getClientId()) &&
|
|
||||||
!event.isLocal()) {
|
!event.isLocal()) {
|
||||||
LOG.info("TEST: Introducee" + introducee +
|
LOG.info("TEST: Introducee" + introducee +
|
||||||
" received message in group " +
|
" received message in group " +
|
||||||
event.getMessage().getGroupId().hashCode());
|
((MessageValidatedEvent) e).getMessage()
|
||||||
|
.getGroupId().hashCode());
|
||||||
msgWaiter.resume();
|
msgWaiter.resume();
|
||||||
}
|
}
|
||||||
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
||||||
@@ -1132,13 +1014,14 @@ public class IntroductionIntegrationTest extends BriarTestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof MessageStateChangedEvent) {
|
if (e instanceof MessageValidatedEvent) {
|
||||||
MessageStateChangedEvent event = (MessageStateChangedEvent) e;
|
MessageValidatedEvent event = (MessageValidatedEvent) e;
|
||||||
if (event.getState() == DELIVERED && event.getClientId()
|
if (event.getClientId()
|
||||||
.equals(introductionManager0.getClientId()) &&
|
.equals(introductionManager0.getClientId()) &&
|
||||||
!event.isLocal()) {
|
!event.isLocal()) {
|
||||||
LOG.info("TEST: Introducer received message in group " +
|
LOG.info("TEST: Introducer received message in group " +
|
||||||
event.getMessage().getGroupId().hashCode());
|
((MessageValidatedEvent) e).getMessage()
|
||||||
|
.getGroupId().hashCode());
|
||||||
msgWaiter.resume();
|
msgWaiter.resume();
|
||||||
}
|
}
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
||||||
|
|||||||
@@ -2,11 +2,6 @@ package org.briarproject;
|
|||||||
|
|
||||||
import org.briarproject.api.UniqueId;
|
import org.briarproject.api.UniqueId;
|
||||||
import org.briarproject.api.crypto.CryptoComponent;
|
import org.briarproject.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.api.crypto.PrivateKey;
|
|
||||||
import org.briarproject.api.forum.ForumConstants;
|
|
||||||
import org.briarproject.api.forum.ForumPost;
|
|
||||||
import org.briarproject.api.forum.ForumPostFactory;
|
|
||||||
import org.briarproject.api.identity.Author;
|
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
import org.briarproject.api.identity.AuthorFactory;
|
||||||
import org.briarproject.api.messaging.MessagingConstants;
|
import org.briarproject.api.messaging.MessagingConstants;
|
||||||
import org.briarproject.api.messaging.PrivateMessage;
|
import org.briarproject.api.messaging.PrivateMessage;
|
||||||
@@ -18,9 +13,6 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
|
||||||
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
import static org.briarproject.api.messaging.MessagingConstants.MAX_PRIVATE_MESSAGE_BODY_LENGTH;
|
||||||
import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
import static org.briarproject.api.sync.SyncConstants.MAX_PACKET_PAYLOAD_LENGTH;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
@@ -33,8 +25,6 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
AuthorFactory authorFactory;
|
AuthorFactory authorFactory;
|
||||||
@Inject
|
@Inject
|
||||||
PrivateMessageFactory privateMessageFactory;
|
PrivateMessageFactory privateMessageFactory;
|
||||||
@Inject
|
|
||||||
ForumPostFactory forumPostFactory;
|
|
||||||
|
|
||||||
public MessageSizeIntegrationTest() throws Exception {
|
public MessageSizeIntegrationTest() throws Exception {
|
||||||
MessageSizeIntegrationTestComponent component =
|
MessageSizeIntegrationTestComponent component =
|
||||||
@@ -61,30 +51,4 @@ public class MessageSizeIntegrationTest extends BriarTestCase {
|
|||||||
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
+ MAX_PRIVATE_MESSAGE_BODY_LENGTH);
|
||||||
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testForumPostFitsIntoPacket() throws Exception {
|
|
||||||
// Create a maximum-length author
|
|
||||||
String authorName = TestUtils.getRandomString(
|
|
||||||
MAX_AUTHOR_NAME_LENGTH);
|
|
||||||
byte[] authorPublic = new byte[MAX_PUBLIC_KEY_LENGTH];
|
|
||||||
Author author = authorFactory.createAuthor(authorName, authorPublic);
|
|
||||||
// Create a maximum-length forum post
|
|
||||||
GroupId groupId = new GroupId(TestUtils.getRandomId());
|
|
||||||
long timestamp = Long.MAX_VALUE;
|
|
||||||
MessageId parent = new MessageId(TestUtils.getRandomId());
|
|
||||||
String contentType = TestUtils.getRandomString(
|
|
||||||
ForumConstants.MAX_CONTENT_TYPE_LENGTH);
|
|
||||||
byte[] body = new byte[MAX_FORUM_POST_BODY_LENGTH];
|
|
||||||
PrivateKey privateKey = crypto.generateSignatureKeyPair().getPrivate();
|
|
||||||
ForumPost post = forumPostFactory.createPseudonymousPost(groupId,
|
|
||||||
timestamp, parent, author, contentType, body, privateKey);
|
|
||||||
// Check the size of the serialised message
|
|
||||||
int length = post.getMessage().getRaw().length;
|
|
||||||
assertTrue(length > UniqueId.LENGTH + 8 + UniqueId.LENGTH
|
|
||||||
+ MAX_AUTHOR_NAME_LENGTH + MAX_PUBLIC_KEY_LENGTH
|
|
||||||
+ ForumConstants.MAX_CONTENT_TYPE_LENGTH
|
|
||||||
+ MAX_FORUM_POST_BODY_LENGTH);
|
|
||||||
assertTrue(length <= MAX_PACKET_PAYLOAD_LENGTH);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import org.briarproject.crypto.CryptoModule;
|
|||||||
import org.briarproject.data.DataModule;
|
import org.briarproject.data.DataModule;
|
||||||
import org.briarproject.db.DatabaseModule;
|
import org.briarproject.db.DatabaseModule;
|
||||||
import org.briarproject.event.EventModule;
|
import org.briarproject.event.EventModule;
|
||||||
import org.briarproject.forum.ForumModule;
|
|
||||||
import org.briarproject.identity.IdentityModule;
|
import org.briarproject.identity.IdentityModule;
|
||||||
import org.briarproject.messaging.MessagingModule;
|
import org.briarproject.messaging.MessagingModule;
|
||||||
import org.briarproject.sync.SyncModule;
|
import org.briarproject.sync.SyncModule;
|
||||||
@@ -25,7 +24,6 @@ import dagger.Component;
|
|||||||
DataModule.class,
|
DataModule.class,
|
||||||
DatabaseModule.class,
|
DatabaseModule.class,
|
||||||
EventModule.class,
|
EventModule.class,
|
||||||
ForumModule.class,
|
|
||||||
IdentityModule.class,
|
IdentityModule.class,
|
||||||
MessagingModule.class,
|
MessagingModule.class,
|
||||||
SyncModule.class,
|
SyncModule.class,
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
Author bobAuthor = new Author(bobId, "Bob",
|
Author bobAuthor = new Author(bobId, "Bob",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
ContactId contactId = contactManager.addContact(bobAuthor, aliceId,
|
||||||
master, timestamp, true, true, true);
|
master, timestamp, true, true);
|
||||||
|
|
||||||
// Send Bob a message
|
// Send Bob a message
|
||||||
GroupId groupId = messagingManager.getConversationId(contactId);
|
GroupId groupId = messagingManager.getConversationId(contactId);
|
||||||
@@ -146,7 +146,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
|
|||||||
Author aliceAuthor = new Author(aliceId, "Alice",
|
Author aliceAuthor = new Author(aliceId, "Alice",
|
||||||
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
new byte[MAX_PUBLIC_KEY_LENGTH]);
|
||||||
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
ContactId contactId = contactManager.addContact(aliceAuthor, bobId,
|
||||||
master, timestamp, false, true, true);
|
master, timestamp, false, true);
|
||||||
|
|
||||||
// Set up an event listener
|
// Set up an event listener
|
||||||
MessageListener listener = new MessageListener();
|
MessageListener listener = new MessageListener();
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import java.util.Collection;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
|
||||||
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
|
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
@@ -75,7 +76,7 @@ public class SyncIntegrationTest extends BriarTestCase {
|
|||||||
streamNumber = 123;
|
streamNumber = 123;
|
||||||
// Create a group
|
// Create a group
|
||||||
ClientId clientId = new ClientId(TestUtils.getRandomId());
|
ClientId clientId = new ClientId(TestUtils.getRandomId());
|
||||||
byte[] descriptor = new byte[0];
|
byte[] descriptor = new byte[MAX_GROUP_DESCRIPTOR_LENGTH];
|
||||||
Group group = groupFactory.createGroup(clientId, descriptor);
|
Group group = groupFactory.createGroup(clientId, descriptor);
|
||||||
// Add two messages to the group
|
// Add two messages to the group
|
||||||
long timestamp = System.currentTimeMillis();
|
long timestamp = System.currentTimeMillis();
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
[main]
|
|
||||||
host = https://www.transifex.com
|
|
||||||
lang_map = pt_BR: pt-rBR
|
|
||||||
|
|
||||||
[briar.stringsxml-5]
|
|
||||||
file_filter = res/values-<lang>/strings.xml
|
|
||||||
source_file = res/values/strings.xml
|
|
||||||
source_lang = en
|
|
||||||
type = ANDROID
|
|
||||||
minimum_perc = 25
|
|
||||||
|
|
||||||
@@ -7,7 +7,8 @@
|
|||||||
android:versionName="0.12">
|
android:versionName="0.12">
|
||||||
|
|
||||||
<uses-sdk
|
<uses-sdk
|
||||||
android:minSdkVersion="14"
|
android:minSdkVersion="9"
|
||||||
|
|
||||||
android:targetSdkVersion="22"
|
android:targetSdkVersion="22"
|
||||||
tools:overrideLibrary="android.support.v14.preference"
|
tools:overrideLibrary="android.support.v14.preference"
|
||||||
/>
|
/>
|
||||||
@@ -50,9 +51,7 @@
|
|||||||
android:finishOnTaskLaunch="true"
|
android:finishOnTaskLaunch="true"
|
||||||
android:label="@string/crash_report_title"
|
android:label="@string/crash_report_title"
|
||||||
android:launchMode="singleInstance"
|
android:launchMode="singleInstance"
|
||||||
android:process=":briar_error_handler"
|
android:process=":briar_error_handler">
|
||||||
android:theme="@style/BriarThemeNoActionBar.Default"
|
|
||||||
android:windowSoftInputMode="stateHidden">
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -68,8 +67,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.SetupActivity"
|
android:name=".android.SetupActivity"
|
||||||
android:label="@string/setup_title"
|
android:label="@string/setup_title">
|
||||||
android:windowSoftInputMode="adjustResize">
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
@@ -100,138 +98,6 @@
|
|||||||
/>
|
/>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.sharing.InvitationsForumActivity"
|
|
||||||
android:label="@string/forum_invitations_title"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</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"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity"
|
|
||||||
android:windowSoftInputMode="stateVisible">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.forum.ForumActivity"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.NavDrawerActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
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"
|
|
||||||
android:value=".android.forum.ForumActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
|
||||||
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"
|
|
||||||
android:value=".android.forum.ForumActivity"
|
|
||||||
/>
|
|
||||||
</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.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
|
<activity
|
||||||
android:name=".android.identity.CreateIdentityActivity"
|
android:name=".android.identity.CreateIdentityActivity"
|
||||||
android:label="@string/new_identity_title"
|
android:label="@string/new_identity_title"
|
||||||
@@ -276,7 +142,7 @@
|
|||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.SettingsActivity"
|
android:name=".android.SettingsActivity"
|
||||||
android:label="@string/settings_button"
|
android:label="@string/settings_title"
|
||||||
android:parentActivityName=".android.NavDrawerActivity">
|
android:parentActivityName=".android.NavDrawerActivity">
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
android:name="android.support.PARENT_ACTIVITY"
|
||||||
@@ -288,16 +154,6 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".android.ChangePasswordActivity"
|
|
||||||
android:label="@string/change_password"
|
|
||||||
android:parentActivityName=".android.SettingsActivity">
|
|
||||||
<meta-data
|
|
||||||
android:name="android.support.PARENT_ACTIVITY"
|
|
||||||
android:value=".android.SettingsActivity"
|
|
||||||
/>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".android.panic.PanicPreferencesActivity"
|
android:name=".android.panic.PanicPreferencesActivity"
|
||||||
android:label="@string/panic_setting">
|
android:label="@string/panic_setting">
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="49"
|
|
||||||
height="20"
|
|
||||||
viewBox="0 0 49.000004 20"
|
|
||||||
id="svg2"
|
|
||||||
version="1.1"
|
|
||||||
inkscape:version="0.91 r13725"
|
|
||||||
sodipodi:docname="trust-indicator.svg">
|
|
||||||
<defs
|
|
||||||
id="defs4" />
|
|
||||||
<sodipodi:namedview
|
|
||||||
id="base"
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1.0"
|
|
||||||
inkscape:pageopacity="0.0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:zoom="15.839192"
|
|
||||||
inkscape:cx="19.828141"
|
|
||||||
inkscape:cy="4.1791031"
|
|
||||||
inkscape:document-units="px"
|
|
||||||
inkscape:current-layer="layer1"
|
|
||||||
showgrid="false"
|
|
||||||
units="px"
|
|
||||||
fit-margin-top="0"
|
|
||||||
fit-margin-left="0"
|
|
||||||
fit-margin-right="0"
|
|
||||||
fit-margin-bottom="0"
|
|
||||||
inkscape:window-width="1920"
|
|
||||||
inkscape:window-height="993"
|
|
||||||
inkscape:window-x="1440"
|
|
||||||
inkscape:window-y="0"
|
|
||||||
inkscape:window-maximized="1" />
|
|
||||||
<metadata
|
|
||||||
id="metadata7">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
inkscape:label="Layer 1"
|
|
||||||
inkscape:groupmode="layer"
|
|
||||||
id="layer1"
|
|
||||||
transform="translate(-216.17711,-507.04154)">
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;letter-spacing:0px;word-spacing:0px;fill:#b7b7b7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="text4136"
|
|
||||||
transform="matrix(1,0,0,0.90497738,-18.96574,55.694085)">
|
|
||||||
<path
|
|
||||||
d="m 250.64285,514.07648 0,-2.275 -2.55,0 0,-3.8 2.55,0 0,-2.275 -2.55,0 0,-4.225 -2.375,0 0,4.225 -3.15,0 0,-4.225 -2.375,0 0,4.225 -2.55,0 0,2.275 2.55,0 0,3.8 -2.55,0 0,2.275 2.55,0 0,4 2.375,0 0,-4 3.15,0 0,4 2.375,0 0,-4 2.55,0 z m -4.925,-2.275 -3.15,0 0,-3.8 3.15,0 0,3.8 z"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#b7b7b7;fill-opacity:1"
|
|
||||||
id="path4745"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
transform="matrix(1,0,0,0.90497738,-3.4657389,55.694085)"
|
|
||||||
id="g4755"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;letter-spacing:0px;word-spacing:0px;fill:#b7b7b7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1">
|
|
||||||
<path
|
|
||||||
inkscape:connector-curvature="0"
|
|
||||||
id="path4757"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#b7b7b7;fill-opacity:1"
|
|
||||||
d="m 250.64285,514.07648 0,-2.275 -2.55,0 0,-3.8 2.55,0 0,-2.275 -2.55,0 0,-4.225 -2.375,0 0,4.225 -3.15,0 0,-4.225 -2.375,0 0,4.225 -2.55,0 0,2.275 2.55,0 0,3.8 -2.55,0 0,2.275 2.55,0 0,4 2.375,0 0,-4 3.15,0 0,4 2.375,0 0,-4 2.55,0 z m -4.925,-2.275 -3.15,0 0,-3.8 3.15,0 0,3.8 z" />
|
|
||||||
</g>
|
|
||||||
<g
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:25px;line-height:125%;font-family:FreeSans;-inkscape-font-specification:FreeSans;letter-spacing:0px;word-spacing:0px;fill:#b7b7b7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
|
||||||
id="g4139"
|
|
||||||
transform="matrix(1,0,0,0.90497738,12.034262,55.694085)">
|
|
||||||
<path
|
|
||||||
d="m 250.64285,514.07648 0,-2.275 -2.55,0 0,-3.8 2.55,0 0,-2.275 -2.55,0 0,-4.225 -2.375,0 0,4.225 -3.15,0 0,-4.225 -2.375,0 0,4.225 -2.55,0 0,2.275 2.55,0 0,3.8 -2.55,0 0,2.275 2.55,0 0,4 2.375,0 0,-4 3.15,0 0,4 2.375,0 0,-4 2.55,0 z m -4.925,-2.275 -3.15,0 0,-3.8 3.15,0 0,3.8 z"
|
|
||||||
style="font-style:normal;font-variant:normal;font-weight:600;font-stretch:normal;font-family:Titillium;-inkscape-font-specification:'Titillium Semi-Bold';fill:#b7b7b7;fill-opacity:1"
|
|
||||||
id="path4141"
|
|
||||||
inkscape:connector-curvature="0" />
|
|
||||||
</g>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 4.6 KiB |
@@ -6,6 +6,11 @@ apply plugin: 'witness'
|
|||||||
apply plugin: 'com.neenbedankt.android-apt'
|
apply plugin: 'com.neenbedankt.android-apt'
|
||||||
apply plugin: 'de.undercouch.download'
|
apply plugin: 'de.undercouch.download'
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
def supportVersion = '23.2.1'
|
def supportVersion = '23.2.1'
|
||||||
compile project(':briar-api')
|
compile project(':briar-api')
|
||||||
@@ -14,14 +19,17 @@ dependencies {
|
|||||||
// This shouldn't be necessary; per section 23.4.4 of the Gradle docs:
|
// 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".
|
// "file dependencies are included in transitive project dependencies within the same build".
|
||||||
compile files('../briar-core/libs/jsocks.jar')
|
compile files('../briar-core/libs/jsocks.jar')
|
||||||
|
|
||||||
compile "com.android.support:support-v4:$supportVersion"
|
compile "com.android.support:support-v4:$supportVersion"
|
||||||
compile("com.android.support:appcompat-v7:$supportVersion") {
|
compile("com.android.support:appcompat-v7:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
}
|
}
|
||||||
|
compile("com.android.support:preference-v7:$supportVersion") {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
}
|
||||||
compile("com.android.support:preference-v14:$supportVersion") {
|
compile("com.android.support:preference-v14:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
|
exclude module: 'preference-v7'
|
||||||
|
exclude module: 'recyclerview-v7'
|
||||||
}
|
}
|
||||||
compile("com.android.support:design:$supportVersion") {
|
compile("com.android.support:design:$supportVersion") {
|
||||||
exclude module: 'support-v4'
|
exclude module: 'support-v4'
|
||||||
@@ -44,6 +52,11 @@ dependencies {
|
|||||||
testCompile project(path: ':briar-tests')
|
testCompile project(path: ':briar-tests')
|
||||||
testCompile 'org.robolectric:robolectric:3.0'
|
testCompile 'org.robolectric:robolectric:3.0'
|
||||||
testCompile 'org.mockito:mockito-core:1.10.19'
|
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 {
|
dependencyVerification {
|
||||||
@@ -55,6 +68,7 @@ dependencyVerification {
|
|||||||
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||||
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
'com.android.support:support-v4:81ce890f26d35c75ad17d0f998a7e3230330c3b41e0b629566bc744bee89e448',
|
||||||
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
'com.android.support:appcompat-v7:00f9d93acacd6731f309724054bf51492814b4b2869f16d7d5c0038dcb8c9a0d',
|
||||||
|
'com.android.support:preference-v7:775101bd07bd052e455761c5c5d9523d7ad59f2f320e3e8cbde241fd6b1d6025',
|
||||||
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
|
'com.android.support:preference-v14:44881bb46094e86d0bc2426f205419674a5b4eb514b44b5a4659b5de29f71eb7',
|
||||||
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
|
'com.android.support:design:003e0c0bea0a6891f8b2bc43f20ae7af2a49a17363e5bb10df5ee0bae12fa686',
|
||||||
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
|
'com.android.support:support-annotations:786ab0d060774fb95cfdaf4878771e14b85733b1af9d72a4aae762dc7c1dff9f',
|
||||||
@@ -68,10 +82,6 @@ android {
|
|||||||
compileSdkVersion 23
|
compileSdkVersion 23
|
||||||
buildToolsVersion "23.0.3"
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
resValue "string", "app_package", "org.briarproject"
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
main {
|
main {
|
||||||
manifest.srcFile 'AndroidManifest.xml'
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
@@ -95,16 +105,24 @@ android {
|
|||||||
unitTests.returnDefaultValues = true
|
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 {
|
buildTypes {
|
||||||
debug {
|
debug {
|
||||||
shrinkResources false
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
}
|
}
|
||||||
release {
|
release {
|
||||||
shrinkResources true
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
|
||||||
}
|
}
|
||||||
@@ -116,10 +134,8 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
warning 'MissingTranslation'
|
abortOnError false
|
||||||
warning 'ImpliedQuantity'
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dexOptions {
|
dexOptions {
|
||||||
incremental true
|
incremental true
|
||||||
}
|
}
|
||||||
@@ -189,8 +205,8 @@ project.afterEvaluate {
|
|||||||
preBuild.dependsOn {
|
preBuild.dependsOn {
|
||||||
[
|
[
|
||||||
'verifyTorGeoIp',
|
'verifyTorGeoIp',
|
||||||
// 'verifyTorBinaryArm',
|
'verifyTorBinaryArm',
|
||||||
// 'verifyTorBinaryArmPie',
|
'verifyTorBinaryArmPie',
|
||||||
'verifyTorBinaryX86',
|
'verifyTorBinaryX86',
|
||||||
'verifyTorBinaryX86Pie'
|
'verifyTorBinaryX86Pie'
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -4,16 +4,17 @@
|
|||||||
-dontobfuscate
|
-dontobfuscate
|
||||||
-verbose
|
-verbose
|
||||||
-useuniqueclassmembernames
|
-useuniqueclassmembernames
|
||||||
#-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
|
||||||
# For comfortability in case we do obfuscate
|
# For comfortability in case we do obfuscate
|
||||||
# -renamesourcefileattribute SourceFile
|
# -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.Activity
|
||||||
-keep public class * extends android.app.Application
|
-keep public class * extends android.app.Application
|
||||||
-keep public class * extends android.app.Service
|
-keep public class * extends android.app.Service
|
||||||
-keep public class * extends android.content.BroadcastReceiver
|
-keep public class * extends android.content.BroadcastReceiver
|
||||||
-keep public class * extends android.content.ContentProvider
|
-keep public class * extends android.content.ContentProvider
|
||||||
|
-keep public class com.android.vending.licensing.ILicensingService
|
||||||
-keepclasseswithmembers class * { native <methods>; }
|
-keepclasseswithmembers class * { native <methods>; }
|
||||||
-keepclasseswithmembers class * {
|
-keepclasseswithmembers class * {
|
||||||
public <init> (android.content.Context, android.util.AttributeSet);
|
public <init> (android.content.Context, android.util.AttributeSet);
|
||||||
@@ -31,32 +32,31 @@
|
|||||||
-keepclassmembers class * extends android.app.Activity {
|
-keepclassmembers class * extends android.app.Activity {
|
||||||
public void *(android.view.View);
|
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.h2.** { *; }
|
||||||
-keep class org.briarproject.** { *; }
|
-keep class org.briarproject.** { *; }
|
||||||
|
-keep class com.google.inject.** { *; }
|
||||||
-keep class javax.inject.** { *; }
|
-keep class javax.inject.** { *; }
|
||||||
|
-keep class javax.annotation.** { *; }
|
||||||
|
-keep class roboguice.** { *; }
|
||||||
-keep class dagger.** { *; }
|
-keep class dagger.** { *; }
|
||||||
-keep class com.google.zxing.Result
|
-keep class com.google.** { *; }
|
||||||
|
|
||||||
-dontwarn org.h2.**
|
-dontwarn org.h2.**
|
||||||
-dontnote org.h2.**
|
-dontnote org.h2.**
|
||||||
-dontwarn net.sf.cglib.**
|
-dontwarn net.sf.cglib.**
|
||||||
-dontwarn org.briarproject.plugins.tcp.**
|
-dontwarn org.briarproject.plugins.tcp.**
|
||||||
-dontnote org.briarproject.crypto.**
|
-dontwarn roboguice.**
|
||||||
-dontnote org.spongycastle.crypto.parsers.ECIESPublicKeyParser
|
|
||||||
-dontwarn net.sourceforge.jsocks.**
|
-dontwarn net.sourceforge.jsocks.**
|
||||||
-dontnote android.support.**
|
-dontnote android.support.**
|
||||||
-dontnote dagger.**
|
-dontnote dagger.**
|
||||||
-dontwarn dagger.**
|
-dontwarn dagger.**
|
||||||
-dontnote com.google.common.**
|
|
||||||
-dontwarn 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.**
|
|
||||||
|
|||||||
BIN
briar-android/res/drawable-hdpi/action_about.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-hdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/content_new_email.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/device_access_accounts.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-hdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 975 B |
BIN
briar-android/res/drawable-hdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 1009 B |
BIN
briar-android/res/drawable-hdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-hdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
BIN
briar-android/res/drawable-hdpi/social_chat.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-hdpi/social_person.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
briar-android/res/drawable-hdpi/social_reply_all.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
briar-android/res/drawable-mdpi/action_about.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-mdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/content_new_email.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-mdpi/device_access_accounts.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-mdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 362 B |
BIN
briar-android/res/drawable-mdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 708 B |
BIN
briar-android/res/drawable-mdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 713 B |
BIN
briar-android/res/drawable-mdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 531 B |
BIN
briar-android/res/drawable-mdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 1014 B |
BIN
briar-android/res/drawable-mdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
briar-android/res/drawable-mdpi/social_chat.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-android/res/drawable-mdpi/social_person.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-mdpi/social_reply_all.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
16
briar-android/res/drawable-v21/round_button.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?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>
|
||||||
BIN
briar-android/res/drawable-xhdpi/action_about.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
BIN
briar-android/res/drawable-xhdpi/action_settings.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
briar-android/res/drawable-xhdpi/content_attachment.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/content_new_email.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/device_access_accounts.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_anonymous.png
Normal file
|
After Width: | Height: | Size: 853 B |
BIN
briar-android/res/drawable-xhdpi/identity_unknown.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_unverified.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
briar-android/res/drawable-xhdpi/identity_verified.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
briar-android/res/drawable-xhdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_next_item.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_previous_item.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
briar-android/res/drawable-xhdpi/navigation_refresh.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
briar-android/res/drawable-xhdpi/social_chat.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
briar-android/res/drawable-xhdpi/social_person.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
briar-android/res/drawable-xhdpi/social_reply_all.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
briar-android/res/drawable-xxhdpi/msg_in_unread.9.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
@@ -1,10 +0,0 @@
|
|||||||
<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>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M13,12h7v1.5h-7zM13,9.5h7L20,11h-7zM13,14.5h7L20,16h-7zM21,4L3,4c-1.1,0 -2,0.9 -2,2v13c0,1.1 0.9,2 2,2h18c1.1,0 2,-0.9 2,-2L23,6c0,-1.1 -0.9,-2 -2,-2zM21,19h-9L12,6h9v13z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<?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>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
|
|
||||||
<corners
|
|
||||||
android:radius="@dimen/unread_bubble_size"/>
|
|
||||||
|
|
||||||
<padding
|
|
||||||
android:left="@dimen/unread_bubble_padding_horizontal"
|
|
||||||
android:right="@dimen/unread_bubble_padding_horizontal"
|
|
||||||
android:bottom="1px"/>
|
|
||||||
|
|
||||||
<solid
|
|
||||||
android:color="@color/briar_primary"/>
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:color="@color/briar_text_primary_inverse"
|
|
||||||
android:width="@dimen/avatar_border_width"/>
|
|
||||||
|
|
||||||
</shape>
|
|
||||||
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:shape="rectangle">
|
|
||||||
|
|
||||||
<corners
|
|
||||||
android:radius="@dimen/unread_bubble_size"/>
|
|
||||||
|
|
||||||
<padding
|
|
||||||
android:left="@dimen/unread_bubble_padding_horizontal"
|
|
||||||
android:right="@dimen/unread_bubble_padding_horizontal"/>
|
|
||||||
|
|
||||||
<solid
|
|
||||||
android:color="@color/briar_gold"/>
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:color="@color/briar_primary"
|
|
||||||
android:width="@dimen/avatar_border_width"/>
|
|
||||||
|
|
||||||
</shape>
|
|
||||||
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<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,9 +0,0 @@
|
|||||||
<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>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFFFF"
|
|
||||||
android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM6,9h12v2L6,11L6,9zM14,14L6,14v-2h8v2zM18,8L6,8L6,6h12v2z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M21,6h-2v9L6,15v2c0,0.55 0.45,1 1,1h11l4,4L22,7c0,-0.55 -0.45,-1 -1,-1zM17,12L17,3c0,-0.55 -0.45,-1 -1,-1L3,2c-0.55,0 -1,0.45 -1,1v14l4,-4h10c0.55,0 1,-0.45 1,-1z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M7,7h10v3l4,-4 -4,-4v3L5,5v6h2L7,7zM17,17L7,17v-3l-4,4 4,4v-3h12v-6h-2v4z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:alpha="0.54"
|
|
||||||
android:viewportHeight="24.0"
|
|
||||||
android:viewportWidth="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M13,8.2l-1,-1 -4,4 -4,-4 -1,1 4,4 -4,4 1,1 4,-4 4,4 1,-1 -4,-4 4,-4zM19,1H9c-1.1,0 -2,0.9 -2,2v3h2V4h10v16H9v-2H7v3c0,1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2V3c0,-1.1 -0.9,-2 -2,-2z"/>
|
|
||||||
</vector>
|
|
||||||
9
briar-android/res/drawable/ic_warning_black_24dp.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<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>
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval">
|
|
||||||
|
|
||||||
<solid android:color="@color/window_background"/>
|
|
||||||
|
|
||||||
<stroke
|
|
||||||
android:width="2dp"
|
|
||||||
android:color="@color/forum_discussion_nested_line"/>
|
|
||||||
</shape>
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
<?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>
|
|
||||||
13
briar-android/res/drawable/round_button.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?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
|
||||||
|
-->
|
||||||
|
<selector
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<solid android:color="@color/briar_primary"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item android:drawable="@drawable/chevron48dp_down" android:state_selected="true"/>
|
|
||||||
<item android:drawable="@drawable/chevron48dp_up"/>
|
|
||||||
</selector>
|
|
||||||
5
briar-android/res/drawable/social_send_now.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<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,6 +1,6 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="38dp"
|
android:width="24dp"
|
||||||
android:height="38dp"
|
android:height="24dp"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
|
|||||||
9
briar-android/res/drawable/social_share.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<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,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="31dp"
|
|
||||||
android:height="12dp"
|
|
||||||
android:viewportHeight="20"
|
|
||||||
android:viewportWidth="49">
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
|
||||||
L5.05014,2.49959 L5.05014,6.32312 L2.50016,6.32312 L2.50016,8.38194
|
|
||||||
L5.05014,8.38194 L5.05014,11.8208 L2.50016,11.8208 L2.50016,13.8797
|
|
||||||
L5.05014,13.8797 L5.05014,17.4996 L7.42514,17.4996 L7.42514,13.8797
|
|
||||||
L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|
||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
|
||||||
L20.5501,2.49959 L20.5501,6.32312 L18.0002,6.32312 L18.0002,8.38194
|
|
||||||
L20.5501,8.38194 L20.5501,11.8208 L18.0002,11.8208 L18.0002,13.8797
|
|
||||||
L20.5501,13.8797 L20.5501,17.4996 L22.9251,17.4996 L22.9251,13.8797
|
|
||||||
L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|
||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
|
||||||
L36.0501,2.49959 L36.0501,6.32312 L33.5002,6.32312 L33.5002,8.38194
|
|
||||||
L36.0501,8.38194 L36.0501,11.8208 L33.5002,11.8208 L33.5002,13.8797
|
|
||||||
L36.0501,13.8797 L36.0501,17.4996 L38.4251,17.4996 L38.4251,13.8797
|
|
||||||
L41.5752,13.8797 L41.5752,17.4996 L43.9502,17.4996 L43.9502,13.8797
|
|
||||||
L46.5002,13.8797 Z M41.5752,11.8208 L38.4251,11.8208 L38.4251,8.38194
|
|
||||||
L41.5752,8.38194 L41.5752,11.8208 Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="31dp"
|
|
||||||
android:height="12dp"
|
|
||||||
android:viewportHeight="20"
|
|
||||||
android:viewportWidth="49">
|
|
||||||
<path
|
|
||||||
android:fillColor="#c34032"
|
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
|
||||||
L5.05014,2.49959 L5.05014,6.32312 L2.50016,6.32312 L2.50016,8.38194
|
|
||||||
L5.05014,8.38194 L5.05014,11.8208 L2.50016,11.8208 L2.50016,13.8797
|
|
||||||
L5.05014,13.8797 L5.05014,17.4996 L7.42514,17.4996 L7.42514,13.8797
|
|
||||||
L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|
||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
|
||||||
L20.5501,2.49959 L20.5501,6.32312 L18.0002,6.32312 L18.0002,8.38194
|
|
||||||
L20.5501,8.38194 L20.5501,11.8208 L18.0002,11.8208 L18.0002,13.8797
|
|
||||||
L20.5501,13.8797 L20.5501,17.4996 L22.9251,17.4996 L22.9251,13.8797
|
|
||||||
L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|
||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
|
||||||
L36.0501,2.49959 L36.0501,6.32312 L33.5002,6.32312 L33.5002,8.38194
|
|
||||||
L36.0501,8.38194 L36.0501,11.8208 L33.5002,11.8208 L33.5002,13.8797
|
|
||||||
L36.0501,13.8797 L36.0501,17.4996 L38.4251,17.4996 L38.4251,13.8797
|
|
||||||
L41.5752,13.8797 L41.5752,17.4996 L43.9502,17.4996 L43.9502,13.8797
|
|
||||||
L46.5002,13.8797 Z M41.5752,11.8208 L38.4251,11.8208 L38.4251,8.38194
|
|
||||||
L41.5752,8.38194 L41.5752,11.8208 Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="31dp"
|
|
||||||
android:height="12dp"
|
|
||||||
android:viewportHeight="20"
|
|
||||||
android:viewportWidth="49">
|
|
||||||
<path
|
|
||||||
android:fillColor="#fcd53a"
|
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
|
||||||
L5.05014,2.49959 L5.05014,6.32312 L2.50016,6.32312 L2.50016,8.38194
|
|
||||||
L5.05014,8.38194 L5.05014,11.8208 L2.50016,11.8208 L2.50016,13.8797
|
|
||||||
L5.05014,13.8797 L5.05014,17.4996 L7.42514,17.4996 L7.42514,13.8797
|
|
||||||
L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|
||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#fcd53a"
|
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
|
||||||
L20.5501,2.49959 L20.5501,6.32312 L18.0002,6.32312 L18.0002,8.38194
|
|
||||||
L20.5501,8.38194 L20.5501,11.8208 L18.0002,11.8208 L18.0002,13.8797
|
|
||||||
L20.5501,13.8797 L20.5501,17.4996 L22.9251,17.4996 L22.9251,13.8797
|
|
||||||
L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|
||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#b7b7b7"
|
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
|
||||||
L36.0501,2.49959 L36.0501,6.32312 L33.5002,6.32312 L33.5002,8.38194
|
|
||||||
L36.0501,8.38194 L36.0501,11.8208 L33.5002,11.8208 L33.5002,13.8797
|
|
||||||
L36.0501,13.8797 L36.0501,17.4996 L38.4251,17.4996 L38.4251,13.8797
|
|
||||||
L41.5752,13.8797 L41.5752,17.4996 L43.9502,17.4996 L43.9502,13.8797
|
|
||||||
L46.5002,13.8797 Z M41.5752,11.8208 L38.4251,11.8208 L38.4251,8.38194
|
|
||||||
L41.5752,8.38194 L41.5752,11.8208 Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="31dp"
|
|
||||||
android:height="12dp"
|
|
||||||
android:viewportHeight="20"
|
|
||||||
android:viewportWidth="49">
|
|
||||||
<path
|
|
||||||
android:fillColor="#7fac49"
|
|
||||||
android:pathData="M15.5002,13.8797 L15.5002,11.8208 L12.9502,11.8208 L12.9502,8.38194
|
|
||||||
L15.5002,8.38194 L15.5002,6.32312 L12.9502,6.32312 L12.9502,2.49959
|
|
||||||
L10.5752,2.49959 L10.5752,6.32312 L7.42514,6.32312 L7.42514,2.49959
|
|
||||||
L5.05014,2.49959 L5.05014,6.32312 L2.50016,6.32312 L2.50016,8.38194
|
|
||||||
L5.05014,8.38194 L5.05014,11.8208 L2.50016,11.8208 L2.50016,13.8797
|
|
||||||
L5.05014,13.8797 L5.05014,17.4996 L7.42514,17.4996 L7.42514,13.8797
|
|
||||||
L10.5752,13.8797 L10.5752,17.4996 L12.9502,17.4996 L12.9502,13.8797
|
|
||||||
L15.5002,13.8797 Z M10.5752,11.8208 L7.42514,11.8208 L7.42514,8.38194
|
|
||||||
L10.5752,8.38194 L10.5752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#7fac49"
|
|
||||||
android:pathData="M31.0002,13.8797 L31.0002,11.8208 L28.4502,11.8208 L28.4502,8.38194
|
|
||||||
L31.0002,8.38194 L31.0002,6.32312 L28.4502,6.32312 L28.4502,2.49959
|
|
||||||
L26.0752,2.49959 L26.0752,6.32312 L22.9251,6.32312 L22.9251,2.49959
|
|
||||||
L20.5501,2.49959 L20.5501,6.32312 L18.0002,6.32312 L18.0002,8.38194
|
|
||||||
L20.5501,8.38194 L20.5501,11.8208 L18.0002,11.8208 L18.0002,13.8797
|
|
||||||
L20.5501,13.8797 L20.5501,17.4996 L22.9251,17.4996 L22.9251,13.8797
|
|
||||||
L26.0752,13.8797 L26.0752,17.4996 L28.4502,17.4996 L28.4502,13.8797
|
|
||||||
L31.0002,13.8797 Z M26.0752,11.8208 L22.9251,11.8208 L22.9251,8.38194
|
|
||||||
L26.0752,8.38194 L26.0752,11.8208 Z"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#7fac49"
|
|
||||||
android:pathData="M46.5002,13.8797 L46.5002,11.8208 L43.9502,11.8208 L43.9502,8.38194
|
|
||||||
L46.5002,8.38194 L46.5002,6.32312 L43.9502,6.32312 L43.9502,2.49959
|
|
||||||
L41.5752,2.49959 L41.5752,6.32312 L38.4251,6.32312 L38.4251,2.49959
|
|
||||||
L36.0501,2.49959 L36.0501,6.32312 L33.5002,6.32312 L33.5002,8.38194
|
|
||||||
L36.0501,8.38194 L36.0501,11.8208 L33.5002,11.8208 L33.5002,13.8797
|
|
||||||
L36.0501,13.8797 L36.0501,17.4996 L38.4251,17.4996 L38.4251,13.8797
|
|
||||||
L41.5752,13.8797 L41.5752,17.4996 L43.9502,17.4996 L43.9502,13.8797
|
|
||||||
L46.5002,13.8797 Z M41.5752,11.8208 L38.4251,11.8208 L38.4251,8.38194
|
|
||||||
L41.5752,8.38194 L41.5752,11.8208 Z"/>
|
|
||||||
</vector>
|
|
||||||
@@ -3,21 +3,23 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal">
|
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">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/imageView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_vertical"
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="@dimen/margin_medium"
|
||||||
|
android:layout_marginRight="@dimen/margin_medium"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="true"
|
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:scaleType="fitCenter"
|
||||||
android:src="@drawable/qr_code_intro"/>
|
android:src="@drawable/qr_code_intro"/>
|
||||||
|
|
||||||
@@ -29,52 +31,30 @@
|
|||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
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
|
<TextView
|
||||||
|
android:id="@+id/yourNicknameView"
|
||||||
style="@style/BriarTextBody"
|
style="@style/BriarTextBody"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/your_nickname"
|
android:text="@string/your_nickname"/>
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/spinner"
|
android:id="@+id/spinner"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:background="@drawable/border_spinner"
|
android:background="@drawable/spinner_border"
|
||||||
android:spinnerMode="dropdown"
|
android:spinnerMode="dropdown"/>
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
|
android:id="@+id/faceToFaceView"
|
||||||
|
style="@style/BriarTextBody"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@drawable/border_explanation"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:orientation="vertical"
|
android:text="@string/face_to_face"/>
|
||||||
android:padding="@dimen/margin_large">
|
|
||||||
|
|
||||||
<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"/>
|
|
||||||
|
|
||||||
<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
|
<Button
|
||||||
android:id="@+id/continueButton"
|
android:id="@+id/continueButton"
|
||||||
|
|||||||
@@ -34,22 +34,22 @@
|
|||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/yourNicknameView"
|
||||||
style="@style/BriarTextBody"
|
style="@style/BriarTextBody"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/your_nickname"
|
android:text="@string/your_nickname"/>
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/spinner"
|
android:id="@+id/spinner"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:background="@drawable/border_spinner"
|
android:background="@drawable/spinner_border"
|
||||||
android:spinnerMode="dropdown"
|
android:spinnerMode="dropdown"/>
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/faceToFaceView"
|
||||||
style="@style/BriarTextBody"
|
style="@style/BriarTextBody"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|||||||