mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 20:59:54 +01:00
Compare commits
76 Commits
screenshot
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
39478a7914 | ||
|
|
112e71a9cb | ||
|
|
5650bef310 | ||
|
|
2a87171c49 | ||
|
|
15cb5409e7 | ||
|
|
fd07dc006d | ||
|
|
cc87c4e37d | ||
|
|
4a10e876f6 | ||
|
|
fad0057c4a | ||
|
|
5aabfcea9a | ||
|
|
f7d928c774 | ||
|
|
bd983d9796 | ||
|
|
de8d1b7d96 | ||
|
|
9155f62d0b | ||
|
|
86684e228a | ||
|
|
9615eff649 | ||
|
|
9381d46f51 | ||
|
|
e4a3a1ad40 | ||
|
|
905dc2a662 | ||
|
|
c2b7f85b8e | ||
|
|
ae81eb3737 | ||
|
|
60d949c342 | ||
|
|
1c90e64894 | ||
|
|
f0e2d5281f | ||
|
|
c7522dae1f | ||
|
|
097d14b9a1 | ||
|
|
0491c3cace | ||
|
|
cbae13feca | ||
|
|
b7c8859c82 | ||
|
|
2e120f752c | ||
|
|
031eac54c5 | ||
|
|
2c2596afdd | ||
|
|
d1be14effe | ||
|
|
b56e7ab07d | ||
|
|
089e9589ed | ||
|
|
660ba16a14 | ||
|
|
b101c4b636 | ||
|
|
fdfddd2667 | ||
|
|
296546544f | ||
|
|
ad579a6ba3 | ||
|
|
90e82357ba | ||
|
|
b3b40753d8 | ||
|
|
e60df3cece | ||
|
|
da3cb95151 | ||
|
|
c27885072f | ||
|
|
6557d564c9 | ||
|
|
53edcaf3e9 | ||
|
|
5122c961b4 | ||
|
|
f83b9244d4 | ||
|
|
81292967e0 | ||
|
|
b72f6b4fc3 | ||
|
|
488be49c93 | ||
|
|
90db45817a | ||
|
|
81863b9db6 | ||
|
|
da069adb57 | ||
|
|
46425b09fa | ||
|
|
41e1a436c9 | ||
|
|
989394d18b | ||
|
|
b6b3f9c292 | ||
|
|
a52547f73b | ||
|
|
24f823a3ce | ||
|
|
7d479063a9 | ||
|
|
2309e73216 | ||
|
|
4b325f797b | ||
|
|
9be83c3cc7 | ||
|
|
86f650503b | ||
|
|
d430b4fd2d | ||
|
|
fcf7cf72ea | ||
|
|
b78dfea95f | ||
|
|
183fe08565 | ||
|
|
7e32697696 | ||
|
|
29758b174a | ||
|
|
61e18f104e | ||
|
|
ffeca8817f | ||
|
|
59fae2fa3c | ||
|
|
2d9345c018 |
@@ -9,8 +9,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 14
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 10101
|
versionCode 10102
|
||||||
versionName "1.1.1"
|
versionName "1.1.2"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.briarproject.bramble.api;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
public interface Nameable {
|
||||||
|
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package org.briarproject.bramble.api;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An exception that indicates an unrecoverable version mismatch.
|
|
||||||
*/
|
|
||||||
public class UnsupportedVersionException extends IOException {
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.bramble.api.identity;
|
package org.briarproject.bramble.api.identity;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Nameable;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ import static org.briarproject.bramble.api.identity.AuthorConstants.MAX_PUBLIC_K
|
|||||||
*/
|
*/
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class Author {
|
public class Author implements Nameable {
|
||||||
|
|
||||||
public enum Status {
|
public enum Status {
|
||||||
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
|
NONE, ANONYMOUS, UNKNOWN, UNVERIFIED, VERIFIED, OURSELVES
|
||||||
|
|||||||
@@ -3,7 +3,13 @@ package org.briarproject.bramble.api.keyagreement;
|
|||||||
public interface KeyAgreementConstants {
|
public interface KeyAgreementConstants {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The current version of the BQP protocol. Version number 89 is reserved.
|
* The version of the BQP protocol used in beta releases. This version
|
||||||
|
* number is reserved.
|
||||||
|
*/
|
||||||
|
byte BETA_PROTOCOL_VERSION = 89;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current version of the BQP protocol.
|
||||||
*/
|
*/
|
||||||
byte PROTOCOL_VERSION = 4;
|
byte PROTOCOL_VERSION = 4;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.briarproject.bramble.api.keyagreement;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thrown when a QR code that has been scanned uses a protocol version that is
|
||||||
|
* not supported.
|
||||||
|
*/
|
||||||
|
public class UnsupportedVersionException extends IOException {
|
||||||
|
|
||||||
|
private final boolean tooOld;
|
||||||
|
|
||||||
|
public UnsupportedVersionException(boolean tooOld) {
|
||||||
|
this.tooOld = tooOld;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isTooOld() {
|
||||||
|
return tooOld;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -159,7 +159,8 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
@Override
|
@Override
|
||||||
public boolean createAccount(String name, String password) {
|
public boolean createAccount(String name, String password) {
|
||||||
synchronized (stateChangeLock) {
|
synchronized (stateChangeLock) {
|
||||||
// TODO don't allow creating another account if one already exists
|
if (hasDatabaseKey())
|
||||||
|
throw new AssertionError("Already have a database key");
|
||||||
LocalAuthor localAuthor = identityManager.createLocalAuthor(name);
|
LocalAuthor localAuthor = identityManager.createLocalAuthor(name);
|
||||||
identityManager.registerLocalAuthor(localAuthor);
|
identityManager.registerLocalAuthor(localAuthor);
|
||||||
SecretKey key = crypto.generateSecretKey();
|
SecretKey key = crypto.generateSecretKey();
|
||||||
@@ -182,6 +183,7 @@ class AccountManagerImpl implements AccountManager {
|
|||||||
LOG.info("Deleting account");
|
LOG.info("Deleting account");
|
||||||
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
|
||||||
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
|
||||||
|
databaseKey = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
package org.briarproject.bramble.keyagreement;
|
package org.briarproject.bramble.keyagreement;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.data.BdfReader;
|
import org.briarproject.bramble.api.data.BdfReader;
|
||||||
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||||
import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
|
import org.briarproject.bramble.api.keyagreement.TransportDescriptor;
|
||||||
|
import org.briarproject.bramble.api.keyagreement.UnsupportedVersionException;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
import org.briarproject.bramble.api.plugin.BluetoothConstants;
|
||||||
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
import org.briarproject.bramble.api.plugin.LanTcpConstants;
|
||||||
@@ -21,6 +21,7 @@ import java.util.List;
|
|||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TRANSPORT_ID_BLUETOOTH;
|
||||||
@@ -43,8 +44,11 @@ class PayloadParserImpl implements PayloadParser {
|
|||||||
// First byte: the protocol version
|
// First byte: the protocol version
|
||||||
int protocolVersion = in.read();
|
int protocolVersion = in.read();
|
||||||
if (protocolVersion == -1) throw new FormatException();
|
if (protocolVersion == -1) throw new FormatException();
|
||||||
if (protocolVersion != PROTOCOL_VERSION)
|
if (protocolVersion != PROTOCOL_VERSION) {
|
||||||
throw new UnsupportedVersionException();
|
boolean tooOld = protocolVersion < PROTOCOL_VERSION ||
|
||||||
|
protocolVersion == BETA_PROTOCOL_VERSION;
|
||||||
|
throw new UnsupportedVersionException(tooOld);
|
||||||
|
}
|
||||||
// The rest of the payload is a BDF list with one or more elements
|
// The rest of the payload is a BDF list with one or more elements
|
||||||
BdfReader r = bdfReaderFactory.createReader(in);
|
BdfReader r = bdfReaderFactory.createReader(in);
|
||||||
BdfList payload = r.readList();
|
BdfList payload = r.readList();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Bridge 131.252.210.150:8081 0E858AC201BF0F3FA3C462F64844CBFFC7297A42
|
|||||||
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
|
Bridge 67.205.189.122:8443 12D64D5D44E20169585E7378580C0D33A872AD98
|
||||||
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
|
Bridge 45.32.148.146:8443 0CE016FB2462D8BF179AE71F7D702D09DEAC3F1D
|
||||||
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
|
Bridge 148.251.90.59:7510 019F727CA6DCA6CA5C90B55E477B7D87981E75BC
|
||||||
Bridge 195.91.239.8:9001 BA83F62551545655BBEBBFF353A45438D73FD45A
|
|
||||||
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
|
Bridge 45.55.1.74:8443 6F18FEFBB0CAECD5ABA755312FCCB34FC11A7AB8
|
||||||
Bridge 97.107.131.168:65341 DCDA8A5F1E2C50A6756A58462E5CF4B6B2DFDE26
|
Bridge 85.229.131.78:444 50E433CCC5FEC11CC34CB4D92033561E065EA106
|
||||||
Bridge 85.229.131.78:444 50E433CCC5FEC11CC34CB4D92033561E065EA106
|
Bridge 178.62.62.193:8443 391B1F9B6A28A1C5FAE1872283985F975E5DB029
|
||||||
|
Bridge 45.76.29.92:8443 ECF1DD51A46FDEF2C50CED992EEEAE8DED18DA0C
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
package org.briarproject.bramble.keyagreement;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.Bytes;
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
|
import org.briarproject.bramble.api.data.BdfReader;
|
||||||
|
import org.briarproject.bramble.api.data.BdfReaderFactory;
|
||||||
|
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||||
|
import org.briarproject.bramble.api.keyagreement.UnsupportedVersionException;
|
||||||
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
|
import org.jmock.Expectations;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
|
||||||
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.BETA_PROTOCOL_VERSION;
|
||||||
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.COMMIT_LENGTH;
|
||||||
|
import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.PROTOCOL_VERSION;
|
||||||
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
public class PayloadParserImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
|
private final BdfReaderFactory bdfReaderFactory =
|
||||||
|
context.mock(BdfReaderFactory.class);
|
||||||
|
private final BdfReader bdfReader = context.mock(BdfReader.class);
|
||||||
|
|
||||||
|
private final PayloadParserImpl payloadParser =
|
||||||
|
new PayloadParserImpl(bdfReaderFactory);
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testThrowsFormatExceptionIfPayloadIsEmpty() throws Exception {
|
||||||
|
payloadParser.parse(new byte[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThrowsUnsupportedVersionExceptionForOldVersion()
|
||||||
|
throws Exception {
|
||||||
|
try {
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION - 1});
|
||||||
|
fail();
|
||||||
|
} catch (UnsupportedVersionException e) {
|
||||||
|
assertTrue(e.isTooOld());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThrowsUnsupportedVersionExceptionForBetaVersion()
|
||||||
|
throws Exception {
|
||||||
|
try {
|
||||||
|
payloadParser.parse(new byte[] {BETA_PROTOCOL_VERSION});
|
||||||
|
fail();
|
||||||
|
} catch (UnsupportedVersionException e) {
|
||||||
|
assertTrue(e.isTooOld());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testThrowsUnsupportedVersionExceptionForNewVersion()
|
||||||
|
throws Exception {
|
||||||
|
try {
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION + 1});
|
||||||
|
fail();
|
||||||
|
} catch (UnsupportedVersionException e) {
|
||||||
|
assertFalse(e.isTooOld());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testThrowsFormatExceptionForEmptyList() throws Exception {
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(bdfReaderFactory).createReader(
|
||||||
|
with(any(ByteArrayInputStream.class)));
|
||||||
|
will(returnValue(bdfReader));
|
||||||
|
oneOf(bdfReader).readList();
|
||||||
|
will(returnValue(new BdfList()));
|
||||||
|
}});
|
||||||
|
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testThrowsFormatExceptionForDataAfterList()
|
||||||
|
throws Exception {
|
||||||
|
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(bdfReaderFactory).createReader(
|
||||||
|
with(any(ByteArrayInputStream.class)));
|
||||||
|
will(returnValue(bdfReader));
|
||||||
|
oneOf(bdfReader).readList();
|
||||||
|
will(returnValue(BdfList.of(new Bytes(commitment))));
|
||||||
|
oneOf(bdfReader).eof();
|
||||||
|
will(returnValue(false));
|
||||||
|
}});
|
||||||
|
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testThrowsFormatExceptionForShortCommitment()
|
||||||
|
throws Exception {
|
||||||
|
byte[] commitment = getRandomBytes(COMMIT_LENGTH - 1);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(bdfReaderFactory).createReader(
|
||||||
|
with(any(ByteArrayInputStream.class)));
|
||||||
|
will(returnValue(bdfReader));
|
||||||
|
oneOf(bdfReader).readList();
|
||||||
|
will(returnValue(BdfList.of(new Bytes(commitment))));
|
||||||
|
oneOf(bdfReader).eof();
|
||||||
|
will(returnValue(true));
|
||||||
|
}});
|
||||||
|
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = FormatException.class)
|
||||||
|
public void testThrowsFormatExceptionForLongCommitment()
|
||||||
|
throws Exception {
|
||||||
|
byte[] commitment = getRandomBytes(COMMIT_LENGTH + 1);
|
||||||
|
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(bdfReaderFactory).createReader(
|
||||||
|
with(any(ByteArrayInputStream.class)));
|
||||||
|
will(returnValue(bdfReader));
|
||||||
|
oneOf(bdfReader).readList();
|
||||||
|
will(returnValue(BdfList.of(new Bytes(commitment))));
|
||||||
|
oneOf(bdfReader).eof();
|
||||||
|
will(returnValue(true));
|
||||||
|
}});
|
||||||
|
|
||||||
|
payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAcceptsPayloadWithNoDescriptors() throws Exception {
|
||||||
|
byte[] commitment = getRandomBytes(COMMIT_LENGTH);
|
||||||
|
context.checking(new Expectations() {{
|
||||||
|
oneOf(bdfReaderFactory).createReader(
|
||||||
|
with(any(ByteArrayInputStream.class)));
|
||||||
|
will(returnValue(bdfReader));
|
||||||
|
oneOf(bdfReader).readList();
|
||||||
|
will(returnValue(BdfList.of(new Bytes(commitment))));
|
||||||
|
oneOf(bdfReader).eof();
|
||||||
|
will(returnValue(true));
|
||||||
|
}});
|
||||||
|
|
||||||
|
Payload p = payloadParser.parse(new byte[] {PROTOCOL_VERSION});
|
||||||
|
assertArrayEquals(commitment, p.getCommitment());
|
||||||
|
assertTrue(p.getTransportDescriptors().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,9 +10,13 @@ import org.briarproject.bramble.api.system.ResourceProvider;
|
|||||||
import org.briarproject.bramble.test.BrambleJavaIntegrationTestComponent;
|
import org.briarproject.bramble.test.BrambleJavaIntegrationTestComponent;
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.test.DaggerBrambleJavaIntegrationTestComponent;
|
import org.briarproject.bramble.test.DaggerBrambleJavaIntegrationTestComponent;
|
||||||
import org.junit.AfterClass;
|
import org.briarproject.bramble.util.OsUtils;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.junit.runners.Parameterized;
|
||||||
|
import org.junit.runners.Parameterized.Parameters;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -29,13 +33,20 @@ import static org.briarproject.bramble.test.TestUtils.deleteTestDirectory;
|
|||||||
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
import static org.briarproject.bramble.test.TestUtils.getTestDirectory;
|
||||||
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
import static org.briarproject.bramble.test.TestUtils.isOptionalTestEnabled;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.junit.Assume.assumeTrue;
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
@RunWith(Parameterized.class)
|
||||||
public class BridgeTest extends BrambleTestCase {
|
public class BridgeTest extends BrambleTestCase {
|
||||||
|
|
||||||
private final static long TIMEOUT = SECONDS.toMillis(23);
|
@Parameters
|
||||||
|
public static Iterable<String> data() {
|
||||||
|
BrambleJavaIntegrationTestComponent component =
|
||||||
|
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
||||||
|
return component.getCircumventionProvider().getBridges();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static long TIMEOUT = SECONDS.toMillis(30);
|
||||||
|
|
||||||
private final static Logger LOG =
|
private final static Logger LOG =
|
||||||
Logger.getLogger(BridgeTest.class.getName());
|
Logger.getLogger(BridgeTest.class.getName());
|
||||||
@@ -53,17 +64,23 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
@Inject
|
@Inject
|
||||||
Clock clock;
|
Clock clock;
|
||||||
|
|
||||||
private List<String> bridges;
|
private final File torDir = getTestDirectory();
|
||||||
private LinuxTorPluginFactory factory;
|
private final String bridge;
|
||||||
private final static File torDir = getTestDirectory();
|
|
||||||
|
|
||||||
private volatile String currentBridge = null;
|
private LinuxTorPluginFactory factory;
|
||||||
|
|
||||||
|
public BridgeTest(String bridge) {
|
||||||
|
this.bridge = bridge;
|
||||||
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
// Skip this test unless it's explicitly enabled in the environment
|
// Skip this test unless it's explicitly enabled in the environment
|
||||||
assumeTrue(isOptionalTestEnabled(BridgeTest.class));
|
assumeTrue(isOptionalTestEnabled(BridgeTest.class));
|
||||||
|
|
||||||
|
// TODO: Remove this assumption when the plugin supports other platforms
|
||||||
|
assumeTrue(OsUtils.isLinux());
|
||||||
|
|
||||||
BrambleJavaIntegrationTestComponent component =
|
BrambleJavaIntegrationTestComponent component =
|
||||||
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
DaggerBrambleJavaIntegrationTestComponent.builder().build();
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -72,7 +89,6 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
LocationUtils locationUtils = () -> "US";
|
LocationUtils locationUtils = () -> "US";
|
||||||
SocketFactory torSocketFactory = SocketFactory.getDefault();
|
SocketFactory torSocketFactory = SocketFactory.getDefault();
|
||||||
|
|
||||||
bridges = circumventionProvider.getBridges();
|
|
||||||
CircumventionProvider bridgeProvider = new CircumventionProvider() {
|
CircumventionProvider bridgeProvider = new CircumventionProvider() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isTorProbablyBlocked(String countryCode) {
|
public boolean isTorProbablyBlocked(String countryCode) {
|
||||||
@@ -86,7 +102,7 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getBridges() {
|
public List<String> getBridges() {
|
||||||
return singletonList(currentBridge);
|
return singletonList(bridge);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
factory = new LinuxTorPluginFactory(ioExecutor, networkManager,
|
factory = new LinuxTorPluginFactory(ioExecutor, networkManager,
|
||||||
@@ -94,25 +110,18 @@ public class BridgeTest extends BrambleTestCase {
|
|||||||
resourceProvider, bridgeProvider, clock, torDir);
|
resourceProvider, bridgeProvider, clock, torDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@After
|
||||||
public static void tearDown() {
|
public void tearDown() {
|
||||||
deleteTestDirectory(torDir);
|
deleteTestDirectory(torDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBridges() throws Exception {
|
public void testBridges() throws Exception {
|
||||||
assertTrue(bridges.size() > 0);
|
|
||||||
|
|
||||||
for (String bridge : bridges) testBridge(bridge);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testBridge(String bridge) throws Exception {
|
|
||||||
DuplexPlugin duplexPlugin =
|
DuplexPlugin duplexPlugin =
|
||||||
factory.createPlugin(new TorPluginCallBack());
|
factory.createPlugin(new TorPluginCallBack());
|
||||||
assertNotNull(duplexPlugin);
|
assertNotNull(duplexPlugin);
|
||||||
LinuxTorPlugin plugin = (LinuxTorPlugin) duplexPlugin;
|
LinuxTorPlugin plugin = (LinuxTorPlugin) duplexPlugin;
|
||||||
|
|
||||||
currentBridge = bridge;
|
|
||||||
LOG.warning("Testing " + bridge);
|
LOG.warning("Testing " + bridge);
|
||||||
try {
|
try {
|
||||||
plugin.start();
|
plugin.start();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import org.briarproject.bramble.BrambleJavaModule;
|
|||||||
import org.briarproject.bramble.event.EventModule;
|
import org.briarproject.bramble.event.EventModule;
|
||||||
import org.briarproject.bramble.plugin.PluginModule;
|
import org.briarproject.bramble.plugin.PluginModule;
|
||||||
import org.briarproject.bramble.plugin.tor.BridgeTest;
|
import org.briarproject.bramble.plugin.tor.BridgeTest;
|
||||||
|
import org.briarproject.bramble.plugin.tor.CircumventionProvider;
|
||||||
import org.briarproject.bramble.system.SystemModule;
|
import org.briarproject.bramble.system.SystemModule;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -22,4 +23,5 @@ public interface BrambleJavaIntegrationTestComponent {
|
|||||||
|
|
||||||
void inject(BridgeTest init);
|
void inject(BridgeTest init);
|
||||||
|
|
||||||
|
CircumventionProvider getCircumventionProvider();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,65 +2,6 @@ apply plugin: 'com.android.application'
|
|||||||
apply plugin: 'witness'
|
apply plugin: 'witness'
|
||||||
apply from: 'witness.gradle'
|
apply from: 'witness.gradle'
|
||||||
|
|
||||||
dependencies {
|
|
||||||
implementation project(path: ':briar-core', configuration: 'default')
|
|
||||||
implementation project(path: ':bramble-core', configuration: 'default')
|
|
||||||
implementation project(':bramble-android')
|
|
||||||
|
|
||||||
def supportVersion = '27.1.1'
|
|
||||||
implementation "com.android.support:support-v4:$supportVersion"
|
|
||||||
implementation("com.android.support:appcompat-v7:$supportVersion") {
|
|
||||||
exclude module: 'support-v4'
|
|
||||||
}
|
|
||||||
implementation("com.android.support:preference-v14:$supportVersion") {
|
|
||||||
exclude module: 'support-v4'
|
|
||||||
}
|
|
||||||
implementation("com.android.support:design:$supportVersion") {
|
|
||||||
exclude module: 'support-v4'
|
|
||||||
exclude module: 'recyclerview-v7'
|
|
||||||
}
|
|
||||||
implementation "com.android.support:cardview-v7:$supportVersion"
|
|
||||||
implementation "com.android.support:support-annotations:$supportVersion"
|
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
|
|
||||||
|
|
||||||
implementation('ch.acra:acra:4.9.1') {
|
|
||||||
exclude module: 'support-v4'
|
|
||||||
exclude module: 'support-annotations'
|
|
||||||
}
|
|
||||||
implementation 'info.guardianproject.panic:panic:0.5'
|
|
||||||
implementation 'info.guardianproject.trustedintents:trustedintents:0.2'
|
|
||||||
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
|
||||||
implementation 'com.google.zxing:core:3.3.0'
|
|
||||||
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.8.0'
|
|
||||||
implementation 'com.vanniktech:emoji-google:0.5.1'
|
|
||||||
|
|
||||||
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
|
|
||||||
|
|
||||||
compileOnly 'javax.annotation:jsr250-api:1.0'
|
|
||||||
|
|
||||||
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
|
||||||
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
|
||||||
testImplementation 'org.robolectric:robolectric:3.8'
|
|
||||||
testImplementation 'org.robolectric:shadows-support-v4:3.3.2'
|
|
||||||
testImplementation 'org.mockito:mockito-core:2.13.0'
|
|
||||||
testImplementation 'junit:junit:4.12'
|
|
||||||
testImplementation "org.jmock:jmock:2.8.2"
|
|
||||||
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
|
||||||
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
|
||||||
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
|
||||||
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
|
||||||
|
|
||||||
def espressoVersion = '3.0.2'
|
|
||||||
androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion"
|
|
||||||
androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion"
|
|
||||||
androidTestImplementation "com.android.support.test.espresso:espresso-intents:$espressoVersion"
|
|
||||||
androidTestImplementation "tools.fastlane:screengrab:1.1.0"
|
|
||||||
androidTestImplementation "com.android.support.test.uiautomator:uiautomator-v18:2.1.3"
|
|
||||||
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2"
|
|
||||||
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
|
|
||||||
androidTestImplementation 'junit:junit:4.12'
|
|
||||||
}
|
|
||||||
|
|
||||||
def getStdout = { command, defaultValue ->
|
def getStdout = { command, defaultValue ->
|
||||||
def stdout = new ByteArrayOutputStream()
|
def stdout = new ByteArrayOutputStream()
|
||||||
try {
|
try {
|
||||||
@@ -81,15 +22,15 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 15
|
minSdkVersion 15
|
||||||
targetSdkVersion 26
|
targetSdkVersion 26
|
||||||
versionCode 10101
|
versionCode 10102
|
||||||
versionName "1.1.1"
|
versionName "1.1.2"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
buildConfigField "String", "GitHash",
|
buildConfigField "String", "GitHash",
|
||||||
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
|
||||||
def now = (long) (System.currentTimeMillis() / 1000)
|
def now = (long) (System.currentTimeMillis() / 1000)
|
||||||
buildConfigField "Long", "BuildTimestamp",
|
buildConfigField "Long", "BuildTimestamp",
|
||||||
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
|
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
|
||||||
testInstrumentationRunner 'org.briarproject.briar.android.test.BriarTestRunner'
|
testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner'
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -144,6 +85,65 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(path: ':briar-core', configuration: 'default')
|
||||||
|
implementation project(path: ':bramble-core', configuration: 'default')
|
||||||
|
implementation project(':bramble-android')
|
||||||
|
|
||||||
|
def supportVersion = '27.1.1'
|
||||||
|
implementation "com.android.support:support-v4:$supportVersion"
|
||||||
|
implementation("com.android.support:appcompat-v7:$supportVersion") {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
}
|
||||||
|
implementation("com.android.support:preference-v14:$supportVersion") {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
}
|
||||||
|
implementation("com.android.support:design:$supportVersion") {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
exclude module: 'recyclerview-v7'
|
||||||
|
}
|
||||||
|
implementation "com.android.support:cardview-v7:$supportVersion"
|
||||||
|
implementation "com.android.support:support-annotations:$supportVersion"
|
||||||
|
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||||
|
|
||||||
|
implementation('ch.acra:acra:4.9.1') {
|
||||||
|
exclude module: 'support-v4'
|
||||||
|
exclude module: 'support-annotations'
|
||||||
|
}
|
||||||
|
implementation 'info.guardianproject.panic:panic:0.5'
|
||||||
|
implementation 'info.guardianproject.trustedintents:trustedintents:0.2'
|
||||||
|
implementation 'de.hdodenhof:circleimageview:2.2.0'
|
||||||
|
implementation 'com.google.zxing:core:3.3.0'
|
||||||
|
implementation 'uk.co.samuelwall:material-tap-target-prompt:2.8.0'
|
||||||
|
implementation 'com.vanniktech:emoji-google:0.5.1'
|
||||||
|
|
||||||
|
annotationProcessor 'com.google.dagger:dagger-compiler:2.0.2'
|
||||||
|
|
||||||
|
compileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
|
|
||||||
|
testImplementation project(path: ':bramble-api', configuration: 'testOutput')
|
||||||
|
testImplementation project(path: ':bramble-core', configuration: 'testOutput')
|
||||||
|
testImplementation 'org.robolectric:robolectric:3.8'
|
||||||
|
testImplementation 'org.robolectric:shadows-support-v4:3.3.2'
|
||||||
|
testImplementation 'org.mockito:mockito-core:2.13.0'
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
testImplementation "org.jmock:jmock:2.8.2"
|
||||||
|
testImplementation "org.jmock:jmock-junit4:2.8.2"
|
||||||
|
testImplementation "org.jmock:jmock-legacy:2.8.2"
|
||||||
|
testImplementation "org.hamcrest:hamcrest-library:1.3"
|
||||||
|
testImplementation "org.hamcrest:hamcrest-core:1.3"
|
||||||
|
|
||||||
|
def espressoVersion = '3.0.2'
|
||||||
|
androidTestImplementation "com.android.support.test.espresso:espresso-core:$espressoVersion"
|
||||||
|
androidTestImplementation "com.android.support.test.espresso:espresso-contrib:$espressoVersion"
|
||||||
|
androidTestImplementation "com.android.support.test.espresso:espresso-intents:$espressoVersion"
|
||||||
|
androidTestAnnotationProcessor "com.google.dagger:dagger-compiler:2.0.2"
|
||||||
|
androidTestCompileOnly 'javax.annotation:jsr250-api:1.0'
|
||||||
|
androidTestImplementation 'junit:junit:4.12'
|
||||||
|
androidTestScreenshotImplementation "tools.fastlane:screengrab:1.2.0"
|
||||||
|
androidTestScreenshotImplementation "com.android.support.test.uiautomator:uiautomator-v18:2.1.3"
|
||||||
|
}
|
||||||
|
|
||||||
task verifyTranslations {
|
task verifyTranslations {
|
||||||
doLast {
|
doLast {
|
||||||
def file = project.file("src/main/res/values/arrays.xml")
|
def file = project.file("src/main/res/values/arrays.xml")
|
||||||
@@ -153,8 +153,9 @@ task verifyTranslations {
|
|||||||
lc.children().each { value -> translations.add(value.text()) }
|
lc.children().each { value -> translations.add(value.text()) }
|
||||||
|
|
||||||
def folders = ["default", "en-US"]
|
def folders = ["default", "en-US"]
|
||||||
|
def exceptions = ["values-night", "values-v21", "values-ldrtl"]
|
||||||
project.file("src/main/res").eachDir { dir ->
|
project.file("src/main/res").eachDir { dir ->
|
||||||
if (dir.name.startsWith("values-") && !dir.name.endsWith("night") && !dir.name.endsWith("v21")) {
|
if (dir.name.startsWith("values-") && !exceptions.contains(dir.name)) {
|
||||||
folders.add(dir.name.substring(7).replace("-r", "-"))
|
folders.add(dir.name.substring(7).replace("-r", "-"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
app_package_name "org.briarproject.briar.android.screenshot.debug"
|
app_package_name "org.briarproject.briar.android.screenshot.debug"
|
||||||
locales ['en-US']
|
locales ['en-US']
|
||||||
use_tests_in_classes([
|
|
||||||
'org.briarproject.briar.android.login.SetupActivityScreenshotTest',
|
|
||||||
'org.briarproject.briar.android.settings.SettingsActivityScreenshotTest',
|
|
||||||
])
|
|
||||||
app_apk_path "build/outputs/apk/screenshot/debug/briar-android-screenshot-debug.apk"
|
app_apk_path "build/outputs/apk/screenshot/debug/briar-android-screenshot-debug.apk"
|
||||||
tests_apk_path "build/outputs/apk/androidTest/screenshot/debug/briar-android-screenshot-debug-androidTest.apk"
|
tests_apk_path "build/outputs/apk/androidTest/screenshot/debug/briar-android-screenshot-debug-androidTest.apk"
|
||||||
test_instrumentation_runner "org.briarproject.briar.android.test.BriarTestRunner"
|
test_instrumentation_runner "org.briarproject.briar.android.BriarTestRunner"
|
||||||
|
reinstall_app = true
|
||||||
|
exit_on_test_failure = true
|
||||||
@@ -4,4 +4,8 @@ adb shell am broadcast -a com.android.systemui.demo -e command enter
|
|||||||
adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false
|
adb shell am broadcast -a com.android.systemui.demo -e command notifications -e visible false
|
||||||
adb shell am broadcast -a com.android.systemui.demo -e command battery -e level 100
|
adb shell am broadcast -a com.android.systemui.demo -e command battery -e level 100
|
||||||
adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi show
|
adb shell am broadcast -a com.android.systemui.demo -e command network -e wifi show
|
||||||
adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 1337
|
adb shell am broadcast -a com.android.systemui.demo -e command clock -e hhmm 1337
|
||||||
|
|
||||||
|
# workaround for Android Pie hidden API Espresso bug
|
||||||
|
adb shell settings put global hidden_api_policy_pre_p_apps 1
|
||||||
|
adb shell settings put global hidden_api_policy_p_apps 1
|
||||||
|
|||||||
@@ -12,4 +12,4 @@
|
|||||||
-keep class junit.** { *; }
|
-keep class junit.** { *; }
|
||||||
-dontwarn junit.**
|
-dontwarn junit.**
|
||||||
|
|
||||||
-dontwarn org.briarproject.briar.android.BriarTestComponentApplication
|
-dontwarn org.briarproject.briar.android.**
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package org.briarproject.briar.android.test;
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.test.runner.AndroidJUnitRunner;
|
import android.support.test.runner.AndroidJUnitRunner;
|
||||||
|
|
||||||
import org.briarproject.briar.android.BriarTestComponentApplication;
|
|
||||||
|
|
||||||
public class BriarTestRunner extends AndroidJUnitRunner {
|
public class BriarTestRunner extends AndroidJUnitRunner {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -13,8 +11,8 @@ public class BriarTestRunner extends AndroidJUnitRunner {
|
|||||||
Context context)
|
Context context)
|
||||||
throws InstantiationException, IllegalAccessException,
|
throws InstantiationException, IllegalAccessException,
|
||||||
ClassNotFoundException {
|
ClassNotFoundException {
|
||||||
return super.newApplication(cl, BriarTestComponentApplication.class.getName(),
|
return super.newApplication(cl,
|
||||||
context);
|
BriarTestComponentApplication.class.getName(), context);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.test.espresso.intent.rule.IntentsTestRule;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.account.AccountManager;
|
||||||
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.support.test.InstrumentationRegistry.getTargetContext;
|
||||||
|
|
||||||
|
@SuppressWarnings("WeakerAccess")
|
||||||
|
public abstract class UiTest {
|
||||||
|
|
||||||
|
protected final String USERNAME =
|
||||||
|
getTargetContext().getString(R.string.screenshot_alice);
|
||||||
|
protected static final String PASSWORD = "123456";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected AccountManager accountManager;
|
||||||
|
@Inject
|
||||||
|
protected LifecycleManager lifecycleManager;
|
||||||
|
|
||||||
|
public UiTest() {
|
||||||
|
BriarTestComponentApplication app =
|
||||||
|
(BriarTestComponentApplication) getTargetContext()
|
||||||
|
.getApplicationContext();
|
||||||
|
inject((BriarUiTestComponent) app.getApplicationComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void inject(BriarUiTestComponent component);
|
||||||
|
|
||||||
|
@NotNullByDefault
|
||||||
|
protected class CleanAccountTestRule<A extends Activity>
|
||||||
|
extends IntentsTestRule<A> {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private final Runnable runnable;
|
||||||
|
|
||||||
|
public CleanAccountTestRule(Class<A> activityClass) {
|
||||||
|
super(activityClass);
|
||||||
|
this.runnable = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this if you need to run code before launching the activity.
|
||||||
|
* Note: You need to use {@link #launchActivity(Intent)} yourself
|
||||||
|
* to start the activity.
|
||||||
|
*/
|
||||||
|
public CleanAccountTestRule(Class<A> activityClass, Runnable runnable) {
|
||||||
|
super(activityClass, false, false);
|
||||||
|
this.runnable = runnable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeActivityLaunched() {
|
||||||
|
super.beforeActivityLaunched();
|
||||||
|
accountManager.deleteAccount();
|
||||||
|
accountManager.createAccount(USERNAME, PASSWORD);
|
||||||
|
if (runnable != null) {
|
||||||
|
Intent serviceIntent =
|
||||||
|
new Intent(getTargetContext(), BriarService.class);
|
||||||
|
getTargetContext().startService(serviceIntent);
|
||||||
|
try {
|
||||||
|
lifecycleManager.waitForStartup();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
runnable.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.test;
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.support.test.espresso.PerformException;
|
import android.support.test.espresso.PerformException;
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
package org.briarproject.briar.android.test;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.support.test.espresso.intent.rule.IntentsTestRule;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.account.AccountManager;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.briar.android.BriarTestComponentApplication;
|
|
||||||
import org.briarproject.briar.android.BriarUiTestComponent;
|
|
||||||
import org.junit.ClassRule;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import tools.fastlane.screengrab.Screengrab;
|
|
||||||
import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy;
|
|
||||||
import tools.fastlane.screengrab.locale.LocaleTestRule;
|
|
||||||
|
|
||||||
import static android.support.test.InstrumentationRegistry.getTargetContext;
|
|
||||||
import static tools.fastlane.screengrab.Screengrab.setDefaultScreenshotStrategy;
|
|
||||||
|
|
||||||
public abstract class ScreenshotTest {
|
|
||||||
|
|
||||||
@ClassRule
|
|
||||||
public static final LocaleTestRule localeTestRule = new LocaleTestRule();
|
|
||||||
|
|
||||||
protected static final String USERNAME = "Alice";
|
|
||||||
protected static final String PASSWORD = "123456";
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
protected AccountManager accountManager;
|
|
||||||
@Inject
|
|
||||||
protected LifecycleManager lifecycleManager;
|
|
||||||
|
|
||||||
public ScreenshotTest() {
|
|
||||||
super();
|
|
||||||
setDefaultScreenshotStrategy(new UiAutomatorScreenshotStrategy());
|
|
||||||
BriarTestComponentApplication app =
|
|
||||||
(BriarTestComponentApplication) getTargetContext()
|
|
||||||
.getApplicationContext();
|
|
||||||
inject((BriarUiTestComponent) app.getApplicationComponent());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void inject(BriarUiTestComponent component);
|
|
||||||
|
|
||||||
protected void screenshot(String name) {
|
|
||||||
try {
|
|
||||||
Screengrab.screenshot(name);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
if (!e.getMessage().equals("Unable to capture screenshot."))
|
|
||||||
throw e;
|
|
||||||
// The tests should still pass when run from AndroidStudio
|
|
||||||
// without manually granting permissions like fastlane does.
|
|
||||||
Log.w("Screengrab", "Permission to write screenshot is missing.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class CleanAccountTestRule<A extends Activity>
|
|
||||||
extends IntentsTestRule<A> {
|
|
||||||
|
|
||||||
public CleanAccountTestRule(Class<A> activityClass) {
|
|
||||||
super(activityClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void beforeActivityLaunched() {
|
|
||||||
super.beforeActivityLaunched();
|
|
||||||
accountManager.deleteAccount();
|
|
||||||
accountManager.createAccount(USERNAME, PASSWORD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.BrambleAndroidModule;
|
||||||
|
import org.briarproject.bramble.BrambleCoreModule;
|
||||||
|
import org.briarproject.bramble.account.BriarAccountModule;
|
||||||
|
import org.briarproject.briar.BriarCoreModule;
|
||||||
|
import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Component;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Component(modules = {
|
||||||
|
AppModule.class,
|
||||||
|
BriarCoreModule.class,
|
||||||
|
BrambleAndroidModule.class,
|
||||||
|
BriarAccountModule.class,
|
||||||
|
BrambleCoreModule.class
|
||||||
|
})
|
||||||
|
public interface BriarUiTestComponent extends AndroidComponent {
|
||||||
|
|
||||||
|
void inject(NavDrawerActivityTest test);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,8 +6,8 @@ import android.view.Gravity;
|
|||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarUiTestComponent;
|
import org.briarproject.briar.android.BriarUiTestComponent;
|
||||||
|
import org.briarproject.briar.android.UiTest;
|
||||||
import org.briarproject.briar.android.settings.SettingsActivity;
|
import org.briarproject.briar.android.settings.SettingsActivity;
|
||||||
import org.briarproject.briar.android.test.ScreenshotTest;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -23,7 +23,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
|||||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class NavDrawerActivityTest extends ScreenshotTest {
|
public class NavDrawerActivityTest extends UiTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public CleanAccountTestRule<NavDrawerActivity> testRule =
|
public CleanAccountTestRule<NavDrawerActivity> testRule =
|
||||||
@@ -4,8 +4,7 @@ import org.briarproject.bramble.BrambleAndroidModule;
|
|||||||
import org.briarproject.bramble.BrambleCoreModule;
|
import org.briarproject.bramble.BrambleCoreModule;
|
||||||
import org.briarproject.bramble.account.BriarAccountModule;
|
import org.briarproject.bramble.account.BriarAccountModule;
|
||||||
import org.briarproject.briar.BriarCoreModule;
|
import org.briarproject.briar.BriarCoreModule;
|
||||||
import org.briarproject.briar.android.login.SetupActivityScreenshotTest;
|
import org.briarproject.briar.android.contact.ConversationActivityScreenshotTest;
|
||||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest;
|
|
||||||
import org.briarproject.briar.android.settings.SettingsActivityScreenshotTest;
|
import org.briarproject.briar.android.settings.SettingsActivityScreenshotTest;
|
||||||
|
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
@@ -22,8 +21,9 @@ import dagger.Component;
|
|||||||
})
|
})
|
||||||
public interface BriarUiTestComponent extends AndroidComponent {
|
public interface BriarUiTestComponent extends AndroidComponent {
|
||||||
|
|
||||||
void inject(SetupActivityScreenshotTest test);
|
void inject(SetupDataTest test);
|
||||||
void inject(NavDrawerActivityTest test);
|
|
||||||
|
void inject(ConversationActivityScreenshotTest test);
|
||||||
void inject(SettingsActivityScreenshotTest test);
|
void inject(SettingsActivityScreenshotTest test);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.plugin.ConnectionRegistry;
|
||||||
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
|
import org.briarproject.briar.api.test.TestDataCreator;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import tools.fastlane.screengrab.FalconScreenshotStrategy;
|
||||||
|
import tools.fastlane.screengrab.Screengrab;
|
||||||
|
import tools.fastlane.screengrab.locale.LocaleTestRule;
|
||||||
|
|
||||||
|
public abstract class ScreenshotTest extends UiTest {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static final LocaleTestRule localeTestRule = new LocaleTestRule();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
protected TestDataCreator testDataCreator;
|
||||||
|
@Inject
|
||||||
|
protected ConnectionRegistry connectionRegistry;
|
||||||
|
@Inject
|
||||||
|
protected Clock clock;
|
||||||
|
|
||||||
|
protected void screenshot(String name, Activity activity) {
|
||||||
|
try {
|
||||||
|
Screengrab.screenshot(name, new FalconScreenshotStrategy(activity));
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
if (!e.getMessage().equals("Unable to capture screenshot."))
|
||||||
|
throw e;
|
||||||
|
// The tests should still pass when run from AndroidStudio
|
||||||
|
// without manually granting permissions like fastlane does.
|
||||||
|
Log.w("Screengrab", "Permission to write screenshot is missing.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected long getMinutesAgo(int minutes) {
|
||||||
|
return clock.currentTimeMillis() - minutes * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package org.briarproject.briar.android.login;
|
package org.briarproject.briar.android;
|
||||||
|
|
||||||
import android.support.test.espresso.intent.rule.IntentsTestRule;
|
import android.support.test.espresso.intent.rule.IntentsTestRule;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
@@ -6,9 +6,12 @@ import android.support.test.uiautomator.UiDevice;
|
|||||||
import android.support.test.uiautomator.UiObject;
|
import android.support.test.uiautomator.UiObject;
|
||||||
import android.support.test.uiautomator.UiSelector;
|
import android.support.test.uiautomator.UiSelector;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.FormatException;
|
||||||
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarUiTestComponent;
|
import org.briarproject.briar.android.login.OpenDatabaseActivity;
|
||||||
import org.briarproject.briar.android.test.ScreenshotTest;
|
import org.briarproject.briar.android.login.SetupActivity;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -26,14 +29,14 @@ import static android.support.test.espresso.matcher.ViewMatchers.isRoot;
|
|||||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
import static android.support.test.runner.lifecycle.Stage.PAUSED;
|
import static android.support.test.runner.lifecycle.Stage.PAUSED;
|
||||||
import static junit.framework.Assert.assertTrue;
|
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
|
||||||
import static org.briarproject.briar.android.test.ViewActions.waitForActivity;
|
import static org.briarproject.briar.android.ViewActions.waitForActivity;
|
||||||
import static org.briarproject.briar.android.test.ViewActions.waitUntilMatches;
|
import static org.briarproject.briar.android.ViewActions.waitUntilMatches;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
|
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class SetupActivityScreenshotTest extends ScreenshotTest {
|
public class SetupDataTest extends ScreenshotTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public IntentsTestRule<SetupActivity> testRule =
|
public IntentsTestRule<SetupActivity> testRule =
|
||||||
@@ -61,7 +64,7 @@ public class SetupActivityScreenshotTest extends ScreenshotTest {
|
|||||||
onView(withId(R.id.nickname_entry))
|
onView(withId(R.id.nickname_entry))
|
||||||
.perform(waitUntilMatches(withText(USERNAME)));
|
.perform(waitUntilMatches(withText(USERNAME)));
|
||||||
|
|
||||||
screenshot("manual_create_account");
|
screenshot("manual_create_account", testRule.getActivity());
|
||||||
|
|
||||||
onView(withId(R.id.next))
|
onView(withId(R.id.next))
|
||||||
.check(matches(isDisplayed()))
|
.check(matches(isDisplayed()))
|
||||||
@@ -94,13 +97,54 @@ public class SetupActivityScreenshotTest extends ScreenshotTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// wait for OpenDatabaseActivity to show up
|
// wait for OpenDatabaseActivity to show up
|
||||||
onView(withId(R.id.progress))
|
|
||||||
.check(matches(isDisplayed()));
|
|
||||||
onView(isRoot())
|
onView(isRoot())
|
||||||
.perform(waitForActivity(testRule.getActivity(), PAUSED));
|
.perform(waitForActivity(testRule.getActivity(), PAUSED));
|
||||||
intended(hasComponent(OpenDatabaseActivity.class.getName()));
|
intended(hasComponent(OpenDatabaseActivity.class.getName()));
|
||||||
|
|
||||||
assertTrue(accountManager.hasDatabaseKey());
|
assertTrue(accountManager.hasDatabaseKey());
|
||||||
|
|
||||||
|
lifecycleManager.waitForStartup();
|
||||||
|
createTestData();
|
||||||
|
|
||||||
|
// close expiry warning
|
||||||
|
onView(withId(R.id.expiryWarning))
|
||||||
|
.perform(waitUntilMatches(isDisplayed()));
|
||||||
|
onView(withId(R.id.expiryWarningClose))
|
||||||
|
.check(matches(isDisplayed()));
|
||||||
|
onView(withId(R.id.expiryWarningClose))
|
||||||
|
.perform(click());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTestData() {
|
||||||
|
try {
|
||||||
|
createTestDataExceptions();
|
||||||
|
} catch (DbException | FormatException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createTestDataExceptions()
|
||||||
|
throws DbException, FormatException {
|
||||||
|
String bobName =
|
||||||
|
getTargetContext().getString(R.string.screenshot_bob);
|
||||||
|
Contact bob = testDataCreator.addContact(bobName);
|
||||||
|
|
||||||
|
String bobHi = getTargetContext()
|
||||||
|
.getString(R.string.screenshot_message_1);
|
||||||
|
long bobTime = getMinutesAgo(2);
|
||||||
|
testDataCreator.addPrivateMessage(bob, bobHi, bobTime, true);
|
||||||
|
|
||||||
|
String aliceHi = getTargetContext()
|
||||||
|
.getString(R.string.screenshot_message_2);
|
||||||
|
long aliceTime = getMinutesAgo(1);
|
||||||
|
testDataCreator.addPrivateMessage(bob, aliceHi, aliceTime, false);
|
||||||
|
|
||||||
|
String bobHi2 = getTargetContext()
|
||||||
|
.getString(R.string.screenshot_message_3);
|
||||||
|
long bobTime2 = getMinutesAgo(0);
|
||||||
|
testDataCreator.addPrivateMessage(bob, bobHi2, bobTime2, true);
|
||||||
|
|
||||||
|
connectionRegistry.registerConnection(bob.getId(), ID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.support.test.rule.ActivityTestRule;
|
||||||
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.BriarUiTestComponent;
|
||||||
|
import org.briarproject.briar.android.ScreenshotTest;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static android.support.test.InstrumentationRegistry.getInstrumentation;
|
||||||
|
import static android.support.test.espresso.Espresso.onView;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
|
import static org.briarproject.briar.android.ViewActions.waitUntilMatches;
|
||||||
|
import static org.briarproject.briar.android.contact.ConversationActivity.CONTACT_ID;
|
||||||
|
import static org.hamcrest.Matchers.allOf;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ConversationActivityScreenshotTest extends ScreenshotTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ActivityTestRule<ConversationActivity> testRule =
|
||||||
|
new ActivityTestRule<>(ConversationActivity.class, false, false);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void inject(BriarUiTestComponent component) {
|
||||||
|
component.inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void messaging() throws Exception {
|
||||||
|
Context targetContext = getInstrumentation().getTargetContext();
|
||||||
|
Intent intent = new Intent(targetContext, ConversationActivity.class);
|
||||||
|
intent.putExtra(CONTACT_ID, 1);
|
||||||
|
testRule.launchActivity(intent);
|
||||||
|
|
||||||
|
onView(withId(R.id.conversationView))
|
||||||
|
.perform(waitUntilMatches(allOf(
|
||||||
|
withText(R.string.screenshot_message_3),
|
||||||
|
isCompletelyDisplayed())
|
||||||
|
));
|
||||||
|
|
||||||
|
screenshot("manual_messaging", testRule.getActivity());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,14 +2,15 @@ package org.briarproject.briar.android.settings;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.test.espresso.contrib.DrawerActions;
|
import android.support.test.espresso.contrib.DrawerActions;
|
||||||
|
import android.support.test.rule.ActivityTestRule;
|
||||||
import android.support.test.runner.AndroidJUnit4;
|
import android.support.test.runner.AndroidJUnit4;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.BriarUiTestComponent;
|
import org.briarproject.briar.android.BriarUiTestComponent;
|
||||||
|
import org.briarproject.briar.android.ScreenshotTest;
|
||||||
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
|
||||||
import org.briarproject.briar.android.test.ScreenshotTest;
|
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
@@ -26,15 +27,15 @@ import static android.support.test.espresso.matcher.ViewMatchers.withChild;
|
|||||||
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
|
import static android.support.test.espresso.matcher.ViewMatchers.withClassName;
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
import static android.support.test.espresso.matcher.ViewMatchers.withId;
|
||||||
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
import static android.support.test.espresso.matcher.ViewMatchers.withText;
|
||||||
import static org.briarproject.briar.android.test.ViewActions.waitUntilMatches;
|
import static org.briarproject.briar.android.ViewActions.waitUntilMatches;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public CleanAccountTestRule<SettingsActivity> testRule =
|
public ActivityTestRule<SettingsActivity> testRule =
|
||||||
new CleanAccountTestRule<>(SettingsActivity.class);
|
new ActivityTestRule<>(SettingsActivity.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void inject(BriarUiTestComponent component) {
|
protected void inject(BriarUiTestComponent component) {
|
||||||
@@ -46,7 +47,7 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
|||||||
onView(withText(R.string.settings_button))
|
onView(withText(R.string.settings_button))
|
||||||
.check(matches(isDisplayed()));
|
.check(matches(isDisplayed()));
|
||||||
|
|
||||||
screenshot("manual_dark_theme_settings");
|
screenshot("manual_dark_theme_settings", testRule.getActivity());
|
||||||
|
|
||||||
// switch to dark theme
|
// switch to dark theme
|
||||||
onView(withText(R.string.pref_theme_title))
|
onView(withText(R.string.pref_theme_title))
|
||||||
@@ -56,10 +57,20 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
|||||||
.check(matches(isDisplayed()))
|
.check(matches(isDisplayed()))
|
||||||
.perform(click());
|
.perform(click());
|
||||||
|
|
||||||
// open nav drawer and remove expiry warning
|
openNavDrawer();
|
||||||
openNavDrawer(true);
|
|
||||||
|
|
||||||
screenshot("manual_dark_theme_nav_drawer");
|
screenshot("manual_dark_theme_nav_drawer", testRule.getActivity());
|
||||||
|
|
||||||
|
// switch to back to light theme
|
||||||
|
onView(withText(R.string.settings_button))
|
||||||
|
.check(matches(isDisplayed()))
|
||||||
|
.perform(click());
|
||||||
|
onView(withText(R.string.pref_theme_title))
|
||||||
|
.check(matches(isDisplayed()))
|
||||||
|
.perform(click());
|
||||||
|
onView(withText(R.string.pref_theme_light))
|
||||||
|
.check(matches(isDisplayed()))
|
||||||
|
.perform(click());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -83,12 +94,11 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
|||||||
.check(matches(isDisplayed()))
|
.check(matches(isDisplayed()))
|
||||||
.check(matches(isEnabled()));
|
.check(matches(isEnabled()));
|
||||||
|
|
||||||
screenshot("manual_app_lock");
|
screenshot("manual_app_lock", testRule.getActivity());
|
||||||
|
|
||||||
// no more expiry warning to remove, because sharedprefs cached?
|
openNavDrawer();
|
||||||
openNavDrawer(false);
|
|
||||||
|
|
||||||
screenshot("manual_app_lock_nav_drawer");
|
screenshot("manual_app_lock_nav_drawer", testRule.getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -104,23 +114,15 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
|
|||||||
.check(matches(isDisplayed()))
|
.check(matches(isDisplayed()))
|
||||||
.perform(waitUntilMatches(isEnabled()));
|
.perform(waitUntilMatches(isEnabled()));
|
||||||
|
|
||||||
screenshot("manual_tor_settings");
|
screenshot("manual_tor_settings", testRule.getActivity());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openNavDrawer(boolean expiry) {
|
private void openNavDrawer() {
|
||||||
// start main activity
|
// start main activity
|
||||||
Intent i =
|
Intent i =
|
||||||
new Intent(testRule.getActivity(), NavDrawerActivity.class);
|
new Intent(testRule.getActivity(), NavDrawerActivity.class);
|
||||||
testRule.getActivity().startActivity(i);
|
testRule.getActivity().startActivity(i);
|
||||||
|
|
||||||
// close expiry warning
|
|
||||||
if (expiry) {
|
|
||||||
onView(withId(R.id.expiryWarningClose))
|
|
||||||
.check(matches(isDisplayed()));
|
|
||||||
onView(withId(R.id.expiryWarningClose))
|
|
||||||
.perform(click());
|
|
||||||
}
|
|
||||||
|
|
||||||
// open navigation drawer
|
// open navigation drawer
|
||||||
onView(withId(R.id.drawer_layout))
|
onView(withId(R.id.drawer_layout))
|
||||||
.check(matches(isClosed(Gravity.START)))
|
.check(matches(isClosed(Gravity.START)))
|
||||||
@@ -13,9 +13,10 @@
|
|||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
||||||
|
<uses-permission android:name="android.permission.USE_FINGERPRINT"/>
|
||||||
<uses-permission android:name="android.permission.VIBRATE" />
|
<uses-permission android:name="android.permission.VIBRATE" />
|
||||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
|
|
||||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
|
||||||
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
android:icon="@mipmap/ic_launcher_round"
|
android:icon="@mipmap/ic_launcher_round"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:logo="@mipmap/ic_launcher_round"
|
android:logo="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
android:theme="@style/BriarTheme">
|
android:theme="@style/BriarTheme">
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
|
|||||||
@@ -41,13 +41,9 @@ import org.briarproject.briar.android.util.BriarNotificationBuilder;
|
|||||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||||
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
||||||
import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent;
|
import org.briarproject.briar.api.forum.event.ForumPostReceivedEvent;
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
|
import org.briarproject.briar.api.introduction.event.IntroductionSucceededEvent;
|
||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent;
|
import org.briarproject.briar.api.privategroup.event.GroupMessageAddedEvent;
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
@@ -235,19 +231,6 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
} else if (e instanceof BlogPostAddedEvent) {
|
} else if (e instanceof BlogPostAddedEvent) {
|
||||||
BlogPostAddedEvent b = (BlogPostAddedEvent) e;
|
BlogPostAddedEvent b = (BlogPostAddedEvent) e;
|
||||||
showBlogPostNotification(b.getGroupId());
|
showBlogPostNotification(b.getGroupId());
|
||||||
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
|
||||||
ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId();
|
|
||||||
showContactNotification(c);
|
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
|
||||||
ContactId c =
|
|
||||||
((IntroductionResponseReceivedEvent) e).getContactId();
|
|
||||||
showContactNotification(c);
|
|
||||||
} else if (e instanceof InvitationRequestReceivedEvent) {
|
|
||||||
ContactId c = ((InvitationRequestReceivedEvent) e).getContactId();
|
|
||||||
showContactNotification(c);
|
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
|
||||||
ContactId c = ((InvitationResponseReceivedEvent) e).getContactId();
|
|
||||||
showContactNotification(c);
|
|
||||||
} else if (e instanceof IntroductionSucceededEvent) {
|
} else if (e instanceof IntroductionSucceededEvent) {
|
||||||
showIntroductionNotification();
|
showIntroductionNotification();
|
||||||
}
|
}
|
||||||
@@ -327,9 +310,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
R.plurals.private_message_notification_text, contactTotal,
|
R.plurals.private_message_notification_text, contactTotal,
|
||||||
contactTotal));
|
contactTotal));
|
||||||
b.setNumber(contactTotal);
|
b.setNumber(contactTotal);
|
||||||
boolean showOnLockScreen =
|
b.setNotificationCategory(CATEGORY_MESSAGE);
|
||||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
|
||||||
b.setLockscreenVisibility(CATEGORY_MESSAGE, showOnLockScreen);
|
|
||||||
if (mayAlertAgain) setAlertProperties(b);
|
if (mayAlertAgain) setAlertProperties(b);
|
||||||
setDeleteIntent(b, CONTACT_URI);
|
setDeleteIntent(b, CONTACT_URI);
|
||||||
Set<ContactId> contacts = contactCounts.keySet();
|
Set<ContactId> contacts = contactCounts.keySet();
|
||||||
@@ -431,9 +412,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
R.plurals.group_message_notification_text, groupTotal,
|
R.plurals.group_message_notification_text, groupTotal,
|
||||||
groupTotal));
|
groupTotal));
|
||||||
b.setNumber(groupTotal);
|
b.setNumber(groupTotal);
|
||||||
boolean showOnLockScreen =
|
b.setNotificationCategory(CATEGORY_SOCIAL);
|
||||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
|
||||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
|
||||||
if (mayAlertAgain) setAlertProperties(b);
|
if (mayAlertAgain) setAlertProperties(b);
|
||||||
setDeleteIntent(b, GROUP_URI);
|
setDeleteIntent(b, GROUP_URI);
|
||||||
Set<GroupId> groups = groupCounts.keySet();
|
Set<GroupId> groups = groupCounts.keySet();
|
||||||
@@ -504,9 +483,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
R.plurals.forum_post_notification_text, forumTotal,
|
R.plurals.forum_post_notification_text, forumTotal,
|
||||||
forumTotal));
|
forumTotal));
|
||||||
b.setNumber(forumTotal);
|
b.setNumber(forumTotal);
|
||||||
boolean showOnLockScreen =
|
b.setNotificationCategory(CATEGORY_SOCIAL);
|
||||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
|
||||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
|
||||||
if (mayAlertAgain) setAlertProperties(b);
|
if (mayAlertAgain) setAlertProperties(b);
|
||||||
setDeleteIntent(b, FORUM_URI);
|
setDeleteIntent(b, FORUM_URI);
|
||||||
Set<GroupId> forums = forumCounts.keySet();
|
Set<GroupId> forums = forumCounts.keySet();
|
||||||
@@ -575,9 +552,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
R.plurals.blog_post_notification_text, blogTotal,
|
R.plurals.blog_post_notification_text, blogTotal,
|
||||||
blogTotal));
|
blogTotal));
|
||||||
b.setNumber(blogTotal);
|
b.setNumber(blogTotal);
|
||||||
boolean showOnLockScreen =
|
b.setNotificationCategory(CATEGORY_SOCIAL);
|
||||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
|
||||||
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
|
|
||||||
if (mayAlertAgain) setAlertProperties(b);
|
if (mayAlertAgain) setAlertProperties(b);
|
||||||
setDeleteIntent(b, BLOG_URI);
|
setDeleteIntent(b, BLOG_URI);
|
||||||
// Touching the notification shows the combined blog feed
|
// Touching the notification shows the combined blog feed
|
||||||
@@ -618,9 +593,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
|||||||
b.setContentText(appContext.getResources().getQuantityString(
|
b.setContentText(appContext.getResources().getQuantityString(
|
||||||
R.plurals.introduction_notification_text, introductionTotal,
|
R.plurals.introduction_notification_text, introductionTotal,
|
||||||
introductionTotal));
|
introductionTotal));
|
||||||
boolean showOnLockScreen =
|
b.setNotificationCategory(CATEGORY_MESSAGE);
|
||||||
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
|
|
||||||
b.setLockscreenVisibility(CATEGORY_MESSAGE, showOnLockScreen);
|
|
||||||
setAlertProperties(b);
|
setAlertProperties(b);
|
||||||
setDeleteIntent(b, INTRODUCTION_URI);
|
setDeleteIntent(b, INTRODUCTION_URI);
|
||||||
// Touching the notification shows the contact list
|
// Touching the notification shows the contact list
|
||||||
|
|||||||
@@ -101,6 +101,8 @@ public class LockManagerImpl implements LockManager, Service, EventListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopService() {
|
public void stopService() {
|
||||||
|
timeoutMinutes = timeoutNever;
|
||||||
|
if (alarmSet) alarmManager.cancel(lockIntent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
|
|||||||
@@ -21,11 +21,11 @@ import org.briarproject.briar.android.controller.ActivityLifecycleController;
|
|||||||
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
|
import org.briarproject.briar.android.controller.handler.ResultExceptionHandler;
|
||||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||||
import org.briarproject.briar.api.blog.Blog;
|
import org.briarproject.briar.api.blog.Blog;
|
||||||
|
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||||
import org.briarproject.briar.api.blog.BlogManager;
|
import org.briarproject.briar.api.blog.BlogManager;
|
||||||
import org.briarproject.briar.api.blog.BlogSharingManager;
|
import org.briarproject.briar.api.blog.BlogSharingManager;
|
||||||
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
import org.briarproject.briar.api.blog.event.BlogInvitationResponseReceivedEvent;
|
||||||
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
import org.briarproject.briar.api.blog.event.BlogPostAddedEvent;
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
import org.briarproject.briar.api.sharing.event.ContactLeftShareableEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -107,7 +107,7 @@ class BlogControllerImpl extends BaseControllerImpl
|
|||||||
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
} else if (e instanceof BlogInvitationResponseReceivedEvent) {
|
||||||
BlogInvitationResponseReceivedEvent b =
|
BlogInvitationResponseReceivedEvent b =
|
||||||
(BlogInvitationResponseReceivedEvent) e;
|
(BlogInvitationResponseReceivedEvent) e;
|
||||||
InvitationResponse r = b.getResponse();
|
BlogInvitationResponse r = b.getMessageHeader();
|
||||||
if (r.getShareableId().equals(groupId) && r.wasAccepted()) {
|
if (r.getShareableId().equals(groupId) && r.wasAccepted()) {
|
||||||
LOG.info("Blog invitation accepted");
|
LOG.info("Blog invitation accepted");
|
||||||
onBlogInvitationAccepted(b.getContactId());
|
onBlogInvitationAccepted(b.getContactId());
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.briar.android.contact;
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.ActivityCompat;
|
import android.support.v4.app.ActivityCompat;
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
@@ -36,19 +35,10 @@ import org.briarproject.briar.android.fragment.BaseFragment;
|
|||||||
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
|
import org.briarproject.briar.android.keyagreement.ContactExchangeActivity;
|
||||||
import org.briarproject.briar.android.view.BriarRecyclerView;
|
import org.briarproject.briar.android.view.BriarRecyclerView;
|
||||||
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
import org.briarproject.briar.api.android.AndroidNotificationManager;
|
||||||
import org.briarproject.briar.api.client.BaseMessageHeader;
|
|
||||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
|
||||||
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.messaging.ConversationManager;
|
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.briar.api.sharing.InvitationRequest;
|
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -57,6 +47,7 @@ import java.util.logging.Logger;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
|
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
|
||||||
import static android.support.v4.view.ViewCompat.getTransitionName;
|
import static android.support.v4.view.ViewCompat.getTransitionName;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
@@ -122,7 +113,7 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
ContactId contactId = item.getContact().getId();
|
ContactId contactId = item.getContact().getId();
|
||||||
i.putExtra(CONTACT_ID, contactId.getInt());
|
i.putExtra(CONTACT_ID, contactId.getInt());
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= 23) {
|
if (SDK_INT >= 23) {
|
||||||
ContactListItemViewHolder holder =
|
ContactListItemViewHolder holder =
|
||||||
(ContactListItemViewHolder) list
|
(ContactListItemViewHolder) list
|
||||||
.getRecyclerView()
|
.getRecyclerView()
|
||||||
@@ -256,41 +247,16 @@ public class ContactListFragment extends BaseFragment implements EventListener {
|
|||||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||||
PrivateMessageHeader h = p.getMessageHeader();
|
PrivateMessageHeader h = p.getMessageHeader();
|
||||||
updateItem(p.getContactId(), h);
|
updateItem(p.getContactId(), h);
|
||||||
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
|
||||||
LOG.info("Introduction request received, updating item");
|
|
||||||
IntroductionRequestReceivedEvent m =
|
|
||||||
(IntroductionRequestReceivedEvent) e;
|
|
||||||
IntroductionRequest ir = m.getIntroductionRequest();
|
|
||||||
updateItem(m.getContactId(), ir);
|
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
|
||||||
LOG.info("Introduction response received, updating item");
|
|
||||||
IntroductionResponseReceivedEvent m =
|
|
||||||
(IntroductionResponseReceivedEvent) e;
|
|
||||||
IntroductionResponse ir = m.getIntroductionResponse();
|
|
||||||
updateItem(m.getContactId(), ir);
|
|
||||||
} else if (e instanceof InvitationRequestReceivedEvent) {
|
|
||||||
LOG.info("Invitation Request received, update item");
|
|
||||||
InvitationRequestReceivedEvent m =
|
|
||||||
(InvitationRequestReceivedEvent) e;
|
|
||||||
InvitationRequest ir = m.getRequest();
|
|
||||||
updateItem(m.getContactId(), ir);
|
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
|
||||||
LOG.info("Invitation response received, updating item");
|
|
||||||
InvitationResponseReceivedEvent m =
|
|
||||||
(InvitationResponseReceivedEvent) e;
|
|
||||||
InvitationResponse ir = m.getResponse();
|
|
||||||
updateItem(m.getContactId(), ir);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateItem(ContactId c, BaseMessageHeader h) {
|
private void updateItem(ContactId c, PrivateMessageHeader h) {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
adapter.incrementRevision();
|
adapter.incrementRevision();
|
||||||
int position = adapter.findItemPosition(c);
|
int position = adapter.findItemPosition(c);
|
||||||
ContactListItem item = adapter.getItemAt(position);
|
ContactListItem item = adapter.getItemAt(position);
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
ConversationItem i = ConversationItem.from(getContext(), h);
|
item.addMessage(h);
|
||||||
item.addMessage(i);
|
|
||||||
adapter.updateItemAt(position, item);
|
adapter.updateItemAt(position, item);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.briar.android.contact;
|
|||||||
import org.briarproject.bramble.api.contact.Contact;
|
import org.briarproject.bramble.api.contact.Contact;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
|
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
@@ -22,11 +23,10 @@ public class ContactListItem extends ContactItem {
|
|||||||
this.timestamp = count.getLatestMsgTime();
|
this.timestamp = count.getLatestMsgTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
void addMessage(ConversationItem message) {
|
void addMessage(PrivateMessageHeader h) {
|
||||||
empty = false;
|
empty = false;
|
||||||
if (message.getTime() > timestamp) timestamp = message.getTime();
|
if (h.getTimestamp() > timestamp) timestamp = h.getTimestamp();
|
||||||
if (!message.isRead())
|
if (!h.isRead()) unread++;
|
||||||
unread++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isEmpty() {
|
boolean isEmpty() {
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package org.briarproject.briar.android.contact;
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
|
import android.arch.lifecycle.Observer;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
@@ -50,6 +53,7 @@ import org.briarproject.briar.android.activity.ActivityComponent;
|
|||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.blog.BlogActivity;
|
import org.briarproject.briar.android.blog.BlogActivity;
|
||||||
import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener;
|
import org.briarproject.briar.android.contact.ConversationAdapter.ConversationListener;
|
||||||
|
import org.briarproject.briar.android.contact.ConversationVisitor.BodyCache;
|
||||||
import org.briarproject.briar.android.forum.ForumActivity;
|
import org.briarproject.briar.android.forum.ForumActivity;
|
||||||
import org.briarproject.briar.android.introduction.IntroductionActivity;
|
import org.briarproject.briar.android.introduction.IntroductionActivity;
|
||||||
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
|
||||||
@@ -62,24 +66,15 @@ import org.briarproject.briar.api.client.ProtocolStateException;
|
|||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
import org.briarproject.briar.api.forum.ForumSharingManager;
|
import org.briarproject.briar.api.forum.ForumSharingManager;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionManager;
|
import org.briarproject.briar.api.introduction.IntroductionManager;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionMessage;
|
import org.briarproject.briar.api.messaging.ConversationManager;
|
||||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
|
||||||
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.introduction.event.IntroductionResponseReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.messaging.MessagingManager;
|
import org.briarproject.briar.api.messaging.MessagingManager;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessage;
|
import org.briarproject.briar.api.messaging.PrivateMessage;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
import org.briarproject.briar.api.messaging.PrivateMessageFactory;
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationManager;
|
||||||
import org.briarproject.briar.api.sharing.InvitationMessage;
|
|
||||||
import org.briarproject.briar.api.sharing.InvitationRequest;
|
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationRequestReceivedEvent;
|
|
||||||
import org.briarproject.briar.api.sharing.event.InvitationResponseReceivedEvent;
|
|
||||||
import org.thoughtcrime.securesms.components.util.FutureTaskListener;
|
|
||||||
import org.thoughtcrime.securesms.components.util.ListenableFutureTask;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -87,13 +82,10 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import de.hdodenhof.circleimageview.CircleImageView;
|
import de.hdodenhof.circleimageview.CircleImageView;
|
||||||
@@ -120,7 +112,8 @@ import static uk.co.samuelwall.materialtaptargetprompt.MaterialTapTargetPrompt.S
|
|||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class ConversationActivity extends BriarActivity
|
public class ConversationActivity extends BriarActivity
|
||||||
implements EventListener, ConversationListener, TextInputListener {
|
implements EventListener, ConversationListener, TextInputListener,
|
||||||
|
BodyCache {
|
||||||
|
|
||||||
public static final String CONTACT_ID = "briar.CONTACT_ID";
|
public static final String CONTACT_ID = "briar.CONTACT_ID";
|
||||||
|
|
||||||
@@ -138,7 +131,9 @@ public class ConversationActivity extends BriarActivity
|
|||||||
Executor cryptoExecutor;
|
Executor cryptoExecutor;
|
||||||
|
|
||||||
private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
|
private final Map<MessageId, String> bodyCache = new ConcurrentHashMap<>();
|
||||||
|
private final MutableLiveData<String> contactName = new MutableLiveData<>();
|
||||||
|
|
||||||
|
private ConversationVisitor visitor;
|
||||||
private ConversationAdapter adapter;
|
private ConversationAdapter adapter;
|
||||||
private Toolbar toolbar;
|
private Toolbar toolbar;
|
||||||
private CircleImageView toolbarAvatar;
|
private CircleImageView toolbarAvatar;
|
||||||
@@ -147,24 +142,14 @@ public class ConversationActivity extends BriarActivity
|
|||||||
private BriarRecyclerView list;
|
private BriarRecyclerView list;
|
||||||
private TextInputView textInputView;
|
private TextInputView textInputView;
|
||||||
|
|
||||||
private final ListenableFutureTask<String> contactNameTask =
|
|
||||||
new ListenableFutureTask<>(new Callable<String>() {
|
|
||||||
@Override
|
|
||||||
public String call() throws Exception {
|
|
||||||
Contact c = contactManager.getContact(contactId);
|
|
||||||
contactName = c.getAuthor().getName();
|
|
||||||
return c.getAuthor().getName();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
private final AtomicBoolean contactNameTaskStarted =
|
|
||||||
new AtomicBoolean(false);
|
|
||||||
|
|
||||||
// Fields that are accessed from background threads must be volatile
|
// Fields that are accessed from background threads must be volatile
|
||||||
@Inject
|
@Inject
|
||||||
volatile ContactManager contactManager;
|
volatile ContactManager contactManager;
|
||||||
@Inject
|
@Inject
|
||||||
volatile MessagingManager messagingManager;
|
volatile MessagingManager messagingManager;
|
||||||
@Inject
|
@Inject
|
||||||
|
volatile ConversationManager conversationManager;
|
||||||
|
@Inject
|
||||||
volatile EventBus eventBus;
|
volatile EventBus eventBus;
|
||||||
@Inject
|
@Inject
|
||||||
volatile SettingsManager settingsManager;
|
volatile SettingsManager settingsManager;
|
||||||
@@ -181,8 +166,6 @@ public class ConversationActivity extends BriarActivity
|
|||||||
|
|
||||||
private volatile ContactId contactId;
|
private volatile ContactId contactId;
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile String contactName;
|
|
||||||
@Nullable
|
|
||||||
private volatile AuthorId contactAuthorId;
|
private volatile AuthorId contactAuthorId;
|
||||||
@Nullable
|
@Nullable
|
||||||
private volatile GroupId messagingGroupId;
|
private volatile GroupId messagingGroupId;
|
||||||
@@ -211,6 +194,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
setTransitionName(toolbarAvatar, getAvatarTransitionName(contactId));
|
setTransitionName(toolbarAvatar, getAvatarTransitionName(contactId));
|
||||||
setTransitionName(toolbarStatus, getBulbTransitionName(contactId));
|
setTransitionName(toolbarStatus, getBulbTransitionName(contactId));
|
||||||
|
|
||||||
|
visitor = new ConversationVisitor(this, this, contactName);
|
||||||
adapter = new ConversationAdapter(this, this);
|
adapter = new ConversationAdapter(this, this);
|
||||||
list = findViewById(R.id.conversationView);
|
list = findViewById(R.id.conversationView);
|
||||||
list.setLayoutManager(new LinearLayoutManager(this));
|
list.setLayoutManager(new LinearLayoutManager(this));
|
||||||
@@ -294,9 +278,9 @@ public class ConversationActivity extends BriarActivity
|
|||||||
runOnDbThread(() -> {
|
runOnDbThread(() -> {
|
||||||
try {
|
try {
|
||||||
long start = now();
|
long start = now();
|
||||||
if (contactName == null || contactAuthorId == null) {
|
if (contactAuthorId == null) {
|
||||||
Contact contact = contactManager.getContact(contactId);
|
Contact contact = contactManager.getContact(contactId);
|
||||||
contactName = contact.getAuthor().getName();
|
contactName.postValue(contact.getAuthor().getName());
|
||||||
contactAuthorId = contact.getAuthor().getId();
|
contactAuthorId = contact.getAuthor().getId();
|
||||||
}
|
}
|
||||||
logDuration(LOG, "Loading contact", start);
|
logDuration(LOG, "Loading contact", start);
|
||||||
@@ -310,12 +294,13 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// contactAuthorId and contactName are expected to be set
|
||||||
private void displayContactDetails() {
|
private void displayContactDetails() {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
toolbarAvatar.setImageDrawable(
|
toolbarAvatar.setImageDrawable(
|
||||||
new IdenticonDrawable(contactAuthorId.getBytes()));
|
new IdenticonDrawable(contactAuthorId.getBytes()));
|
||||||
toolbarTitle.setText(contactName);
|
toolbarTitle.setText(contactName.getValue());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,23 +328,9 @@ public class ConversationActivity extends BriarActivity
|
|||||||
try {
|
try {
|
||||||
long start = now();
|
long start = now();
|
||||||
Collection<PrivateMessageHeader> headers =
|
Collection<PrivateMessageHeader> headers =
|
||||||
messagingManager.getMessageHeaders(contactId);
|
conversationManager.getMessageHeaders(contactId);
|
||||||
Collection<IntroductionMessage> introductions =
|
|
||||||
introductionManager.getIntroductionMessages(contactId);
|
|
||||||
Collection<InvitationMessage> forumInvitations =
|
|
||||||
forumSharingManager.getInvitationMessages(contactId);
|
|
||||||
Collection<InvitationMessage> blogInvitations =
|
|
||||||
blogSharingManager.getInvitationMessages(contactId);
|
|
||||||
Collection<InvitationMessage> groupInvitations =
|
|
||||||
groupInvitationManager.getInvitationMessages(contactId);
|
|
||||||
List<InvitationMessage> invitations = new ArrayList<>(
|
|
||||||
forumInvitations.size() + blogInvitations.size() +
|
|
||||||
groupInvitations.size());
|
|
||||||
invitations.addAll(forumInvitations);
|
|
||||||
invitations.addAll(blogInvitations);
|
|
||||||
invitations.addAll(groupInvitations);
|
|
||||||
logDuration(LOG, "Loading messages", start);
|
logDuration(LOG, "Loading messages", start);
|
||||||
displayMessages(revision, headers, introductions, invitations);
|
displayMessages(revision, headers);
|
||||||
} catch (NoSuchContactException e) {
|
} catch (NoSuchContactException e) {
|
||||||
finishOnUiThread();
|
finishOnUiThread();
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -369,15 +340,12 @@ public class ConversationActivity extends BriarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void displayMessages(int revision,
|
private void displayMessages(int revision,
|
||||||
Collection<PrivateMessageHeader> headers,
|
Collection<PrivateMessageHeader> headers) {
|
||||||
Collection<IntroductionMessage> introductions,
|
|
||||||
Collection<InvitationMessage> invitations) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
if (revision == adapter.getRevision()) {
|
if (revision == adapter.getRevision()) {
|
||||||
adapter.incrementRevision();
|
adapter.incrementRevision();
|
||||||
textInputView.setSendButtonEnabled(true);
|
textInputView.setSendButtonEnabled(true);
|
||||||
List<ConversationItem> items = createItems(headers,
|
List<ConversationItem> items = createItems(headers);
|
||||||
introductions, invitations);
|
|
||||||
adapter.addAll(items);
|
adapter.addAll(items);
|
||||||
list.showData();
|
list.showData();
|
||||||
// Scroll to the bottom
|
// Scroll to the bottom
|
||||||
@@ -396,41 +364,9 @@ public class ConversationActivity extends BriarActivity
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
private List<ConversationItem> createItems(
|
private List<ConversationItem> createItems(
|
||||||
Collection<PrivateMessageHeader> headers,
|
Collection<PrivateMessageHeader> headers) {
|
||||||
Collection<IntroductionMessage> introductions,
|
List<ConversationItem> items = new ArrayList<>(headers.size());
|
||||||
Collection<InvitationMessage> invitations) {
|
for (PrivateMessageHeader h : headers) items.add(h.accept(visitor));
|
||||||
int size =
|
|
||||||
headers.size() + introductions.size() + invitations.size();
|
|
||||||
List<ConversationItem> items = new ArrayList<>(size);
|
|
||||||
for (PrivateMessageHeader h : headers) {
|
|
||||||
ConversationItem item = ConversationItem.from(h);
|
|
||||||
String body = bodyCache.get(h.getId());
|
|
||||||
if (body == null) loadMessageBody(h.getId());
|
|
||||||
else item.setBody(body);
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
for (IntroductionMessage m : introductions) {
|
|
||||||
ConversationItem item;
|
|
||||||
if (m instanceof IntroductionRequest) {
|
|
||||||
IntroductionRequest i = (IntroductionRequest) m;
|
|
||||||
item = ConversationItem.from(this, contactName, i);
|
|
||||||
} else {
|
|
||||||
IntroductionResponse i = (IntroductionResponse) m;
|
|
||||||
item = ConversationItem.from(this, contactName, i);
|
|
||||||
}
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
for (InvitationMessage i : invitations) {
|
|
||||||
ConversationItem item;
|
|
||||||
if (i instanceof InvitationRequest) {
|
|
||||||
InvitationRequest r = (InvitationRequest) i;
|
|
||||||
item = ConversationItem.from(this, contactName, r);
|
|
||||||
} else {
|
|
||||||
InvitationResponse r = (InvitationResponse) i;
|
|
||||||
item = ConversationItem.from(this, contactName, r);
|
|
||||||
}
|
|
||||||
items.add(item);
|
|
||||||
}
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,9 +412,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||||
if (p.getContactId().equals(contactId)) {
|
if (p.getContactId().equals(contactId)) {
|
||||||
LOG.info("Message received, adding");
|
LOG.info("Message received, adding");
|
||||||
PrivateMessageHeader h = p.getMessageHeader();
|
onNewPrivateMessage(p.getMessageHeader());
|
||||||
addConversationItem(ConversationItem.from(h));
|
|
||||||
loadMessageBody(h.getId());
|
|
||||||
}
|
}
|
||||||
} else if (e instanceof MessagesSentEvent) {
|
} else if (e instanceof MessagesSentEvent) {
|
||||||
MessagesSentEvent m = (MessagesSentEvent) e;
|
MessagesSentEvent m = (MessagesSentEvent) e;
|
||||||
@@ -504,38 +438,6 @@ public class ConversationActivity extends BriarActivity
|
|||||||
LOG.info("Contact disconnected");
|
LOG.info("Contact disconnected");
|
||||||
displayContactOnlineStatus();
|
displayContactOnlineStatus();
|
||||||
}
|
}
|
||||||
} else if (e instanceof IntroductionRequestReceivedEvent) {
|
|
||||||
IntroductionRequestReceivedEvent event =
|
|
||||||
(IntroductionRequestReceivedEvent) e;
|
|
||||||
if (event.getContactId().equals(contactId)) {
|
|
||||||
LOG.info("Introduction request received, adding...");
|
|
||||||
IntroductionRequest ir = event.getIntroductionRequest();
|
|
||||||
handleIntroductionRequest(ir);
|
|
||||||
}
|
|
||||||
} else if (e instanceof IntroductionResponseReceivedEvent) {
|
|
||||||
IntroductionResponseReceivedEvent event =
|
|
||||||
(IntroductionResponseReceivedEvent) e;
|
|
||||||
if (event.getContactId().equals(contactId)) {
|
|
||||||
LOG.info("Introduction response received, adding...");
|
|
||||||
IntroductionResponse ir = event.getIntroductionResponse();
|
|
||||||
handleIntroductionResponse(ir);
|
|
||||||
}
|
|
||||||
} else if (e instanceof InvitationRequestReceivedEvent) {
|
|
||||||
InvitationRequestReceivedEvent event =
|
|
||||||
(InvitationRequestReceivedEvent) e;
|
|
||||||
if (event.getContactId().equals(contactId)) {
|
|
||||||
LOG.info("Invitation received, adding...");
|
|
||||||
InvitationRequest ir = event.getRequest();
|
|
||||||
handleInvitationRequest(ir);
|
|
||||||
}
|
|
||||||
} else if (e instanceof InvitationResponseReceivedEvent) {
|
|
||||||
InvitationResponseReceivedEvent event =
|
|
||||||
(InvitationResponseReceivedEvent) e;
|
|
||||||
if (event.getContactId().equals(contactId)) {
|
|
||||||
LOG.info("Invitation response received, adding...");
|
|
||||||
InvitationResponse ir = event.getResponse();
|
|
||||||
handleInvitationResponse(ir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,84 +450,33 @@ public class ConversationActivity extends BriarActivity
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleIntroductionRequest(IntroductionRequest m) {
|
private void onNewPrivateMessage(PrivateMessageHeader h) {
|
||||||
getContactNameTask().addListener(new FutureTaskListener<String>() {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
@Override
|
if (h instanceof PrivateRequest || h instanceof PrivateResponse) {
|
||||||
public void onSuccess(String contactName) {
|
String cName = contactName.getValue();
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
if (cName == null) {
|
||||||
ConversationItem item = ConversationItem
|
// Wait for the contact name to be loaded
|
||||||
.from(ConversationActivity.this, contactName, m);
|
contactName.observe(this, new Observer<String>() {
|
||||||
addConversationItem(item);
|
@Override
|
||||||
});
|
public void onChanged(@Nullable String cName) {
|
||||||
}
|
if (cName != null) {
|
||||||
|
addConversationItem(h.accept(visitor));
|
||||||
@Override
|
contactName.removeObserver(this);
|
||||||
public void onFailure(Throwable exception) {
|
}
|
||||||
runOnUiThreadUnlessDestroyed(
|
}
|
||||||
() -> handleDbException((DbException) exception));
|
});
|
||||||
|
} else {
|
||||||
|
addConversationItem(h.accept(visitor));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addConversationItem(h.accept(visitor));
|
||||||
|
loadMessageBody(h.getId());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleIntroductionResponse(IntroductionResponse m) {
|
private void markMessages(Collection<MessageId> messageIds, boolean sent,
|
||||||
getContactNameTask().addListener(new FutureTaskListener<String>() {
|
boolean seen) {
|
||||||
@Override
|
|
||||||
public void onSuccess(String contactName) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
|
||||||
ConversationItem item = ConversationItem
|
|
||||||
.from(ConversationActivity.this, contactName, m);
|
|
||||||
addConversationItem(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable exception) {
|
|
||||||
runOnUiThreadUnlessDestroyed(
|
|
||||||
() -> handleDbException((DbException) exception));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleInvitationRequest(InvitationRequest m) {
|
|
||||||
getContactNameTask().addListener(new FutureTaskListener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(String contactName) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
|
||||||
ConversationItem item = ConversationItem
|
|
||||||
.from(ConversationActivity.this, contactName, m);
|
|
||||||
addConversationItem(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable exception) {
|
|
||||||
runOnUiThreadUnlessDestroyed(
|
|
||||||
() -> handleDbException((DbException) exception));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handleInvitationResponse(InvitationResponse m) {
|
|
||||||
getContactNameTask().addListener(new FutureTaskListener<String>() {
|
|
||||||
@Override
|
|
||||||
public void onSuccess(String contactName) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
|
||||||
ConversationItem item = ConversationItem
|
|
||||||
.from(ConversationActivity.this, contactName, m);
|
|
||||||
addConversationItem(item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(Throwable exception) {
|
|
||||||
runOnUiThreadUnlessDestroyed(
|
|
||||||
() -> handleDbException((DbException) exception));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void markMessages(Collection<MessageId> messageIds,
|
|
||||||
boolean sent, boolean seen) {
|
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
adapter.incrementRevision();
|
adapter.incrementRevision();
|
||||||
Set<MessageId> messages = new HashSet<>(messageIds);
|
Set<MessageId> messages = new HashSet<>(messageIds);
|
||||||
@@ -678,7 +529,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
//noinspection ConstantConditions init in loadGroupId()
|
//noinspection ConstantConditions init in loadGroupId()
|
||||||
storeMessage(privateMessageFactory.createPrivateMessage(
|
storeMessage(privateMessageFactory.createPrivateMessage(
|
||||||
messagingGroupId, timestamp, body), body);
|
messagingGroupId, timestamp, body), body);
|
||||||
} catch (FormatException e) {throw new RuntimeException(e);
|
} catch (FormatException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -693,10 +545,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
PrivateMessageHeader h = new PrivateMessageHeader(
|
PrivateMessageHeader h = new PrivateMessageHeader(
|
||||||
message.getId(), message.getGroupId(),
|
message.getId(), message.getGroupId(),
|
||||||
message.getTimestamp(), true, false, false, false);
|
message.getTimestamp(), true, false, false, false);
|
||||||
ConversationItem item = ConversationItem.from(h);
|
|
||||||
item.setBody(body);
|
|
||||||
bodyCache.put(message.getId(), body);
|
bodyCache.put(message.getId(), body);
|
||||||
addConversationItem(item);
|
addConversationItem(h.accept(visitor));
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
}
|
}
|
||||||
@@ -823,7 +673,7 @@ public class ConversationActivity extends BriarActivity
|
|||||||
@UiThread
|
@UiThread
|
||||||
@Override
|
@Override
|
||||||
public void respondToRequest(ConversationRequestItem item, boolean accept) {
|
public void respondToRequest(ConversationRequestItem item, boolean accept) {
|
||||||
item.setAnswered(true);
|
item.setAnswered();
|
||||||
int position = adapter.findItemPosition(item);
|
int position = adapter.findItemPosition(item);
|
||||||
if (position != INVALID_POSITION) {
|
if (position != INVALID_POSITION) {
|
||||||
adapter.notifyItemChanged(position, item);
|
adapter.notifyItemChanged(position, item);
|
||||||
@@ -909,10 +759,11 @@ public class ConversationActivity extends BriarActivity
|
|||||||
groupInvitationManager.respondToInvitation(contactId, id, accept);
|
groupInvitationManager.respondToInvitation(contactId, id, accept);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ListenableFutureTask<String> getContactNameTask() {
|
@Nullable
|
||||||
if (!contactNameTaskStarted.getAndSet(true))
|
@Override
|
||||||
runOnDbThread(contactNameTask);
|
public String getBody(MessageId m) {
|
||||||
return contactNameTask;
|
String body = bodyCache.get(m);
|
||||||
|
if (body == null) loadMessageBody(m);
|
||||||
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +1,20 @@
|
|||||||
package org.briarproject.briar.android.contact;
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
import android.support.annotation.StringRes;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.R;
|
|
||||||
import org.briarproject.briar.android.contact.ConversationRequestItem.RequestType;
|
|
||||||
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
|
||||||
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
|
||||||
import org.briarproject.briar.api.client.BaseMessageHeader;
|
|
||||||
import org.briarproject.briar.api.forum.ForumInvitationRequest;
|
|
||||||
import org.briarproject.briar.api.forum.ForumInvitationResponse;
|
|
||||||
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
|
||||||
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
|
||||||
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
|
||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
|
|
||||||
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
|
|
||||||
import org.briarproject.briar.api.sharing.InvitationRequest;
|
|
||||||
import org.briarproject.briar.api.sharing.InvitationResponse;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.BLOG;
|
|
||||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM;
|
|
||||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP;
|
|
||||||
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
abstract class ConversationItem {
|
abstract class ConversationItem {
|
||||||
|
|
||||||
protected @Nullable String body;
|
@Nullable
|
||||||
|
protected String body;
|
||||||
private final MessageId id;
|
private final MessageId id;
|
||||||
private final GroupId groupId;
|
private final GroupId groupId;
|
||||||
private final long time;
|
private final long time;
|
||||||
@@ -78,216 +58,4 @@ abstract class ConversationItem {
|
|||||||
|
|
||||||
@LayoutRes
|
@LayoutRes
|
||||||
abstract public int getLayout();
|
abstract public int getLayout();
|
||||||
|
|
||||||
static ConversationItem from(PrivateMessageHeader h) {
|
|
||||||
if (h.isLocal()) {
|
|
||||||
return new ConversationMessageOutItem(h);
|
|
||||||
} else {
|
|
||||||
return new ConversationMessageInItem(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ConversationItem from(Context ctx, String contactName,
|
|
||||||
IntroductionRequest ir) {
|
|
||||||
if (ir.isLocal()) {
|
|
||||||
String text = ctx.getString(R.string.introduction_request_sent,
|
|
||||||
contactName, ir.getName());
|
|
||||||
return new ConversationNoticeOutItem(ir.getMessageId(),
|
|
||||||
ir.getGroupId(), text, ir.getMessage(), ir.getTimestamp(),
|
|
||||||
ir.isSent(), ir.isSeen());
|
|
||||||
} else {
|
|
||||||
String text;
|
|
||||||
if (ir.wasAnswered()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_request_answered_received,
|
|
||||||
contactName, ir.getName());
|
|
||||||
} else if (ir.contactExists()){
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_request_exists_received,
|
|
||||||
contactName, ir.getName());
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(R.string.introduction_request_received,
|
|
||||||
contactName, ir.getName());
|
|
||||||
}
|
|
||||||
return new ConversationRequestItem(ir.getMessageId(),
|
|
||||||
ir.getGroupId(), INTRODUCTION, ir.getSessionId(), text,
|
|
||||||
ir.getMessage(), ir.getTimestamp(), ir.isRead(), null,
|
|
||||||
ir.wasAnswered(), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ConversationItem from(Context ctx, String contactName,
|
|
||||||
IntroductionResponse ir) {
|
|
||||||
if (ir.isLocal()) {
|
|
||||||
String text;
|
|
||||||
if (ir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_response_accepted_sent,
|
|
||||||
ir.getName());
|
|
||||||
text += "\n\n" + ctx.getString(
|
|
||||||
R.string.introduction_response_accepted_sent_info,
|
|
||||||
ir.getName());
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_response_declined_sent,
|
|
||||||
ir.getName());
|
|
||||||
}
|
|
||||||
return new ConversationNoticeOutItem(ir.getMessageId(),
|
|
||||||
ir.getGroupId(), text, null, ir.getTimestamp(), ir.isSent(),
|
|
||||||
ir.isSeen());
|
|
||||||
} else {
|
|
||||||
String text;
|
|
||||||
if (ir.wasAccepted()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_response_accepted_received,
|
|
||||||
contactName, ir.getName());
|
|
||||||
} else {
|
|
||||||
if (ir.isIntroducer()) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_response_declined_received,
|
|
||||||
contactName, ir.getName());
|
|
||||||
} else {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.introduction_response_declined_received_by_introducee,
|
|
||||||
contactName, ir.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ConversationNoticeInItem(ir.getMessageId(),
|
|
||||||
ir.getGroupId(), text, null, ir.getTimestamp(),
|
|
||||||
ir.isRead());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ConversationItem from(Context ctx, String contactName,
|
|
||||||
InvitationRequest ir) {
|
|
||||||
if (ir.isLocal()) {
|
|
||||||
String text;
|
|
||||||
if (ir instanceof ForumInvitationRequest) {
|
|
||||||
text = ctx.getString(R.string.forum_invitation_sent,
|
|
||||||
((ForumInvitationRequest) ir).getForumName(),
|
|
||||||
contactName);
|
|
||||||
} else if (ir instanceof BlogInvitationRequest) {
|
|
||||||
text = ctx.getString(R.string.blogs_sharing_invitation_sent,
|
|
||||||
((BlogInvitationRequest) ir).getBlogAuthorName(),
|
|
||||||
contactName);
|
|
||||||
} else if (ir instanceof GroupInvitationRequest) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.groups_invitations_invitation_sent,
|
|
||||||
contactName, ir.getShareable().getName());
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown InvitationRequest");
|
|
||||||
}
|
|
||||||
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
|
|
||||||
text, ir.getMessage(), ir.getTimestamp(), ir.isSent(),
|
|
||||||
ir.isSeen());
|
|
||||||
} else {
|
|
||||||
String text;
|
|
||||||
RequestType type;
|
|
||||||
if (ir instanceof ForumInvitationRequest) {
|
|
||||||
text = ctx.getString(R.string.forum_invitation_received,
|
|
||||||
contactName,
|
|
||||||
((ForumInvitationRequest) ir).getForumName());
|
|
||||||
type = FORUM;
|
|
||||||
} else if (ir instanceof BlogInvitationRequest) {
|
|
||||||
text = ctx.getString(R.string.blogs_sharing_invitation_received,
|
|
||||||
contactName,
|
|
||||||
((BlogInvitationRequest) ir).getBlogAuthorName());
|
|
||||||
type = BLOG;
|
|
||||||
} else if (ir instanceof GroupInvitationRequest) {
|
|
||||||
text = ctx.getString(
|
|
||||||
R.string.groups_invitations_invitation_received,
|
|
||||||
contactName, ir.getShareable().getName());
|
|
||||||
type = GROUP;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown InvitationRequest");
|
|
||||||
}
|
|
||||||
return new ConversationRequestItem(ir.getId(),
|
|
||||||
ir.getGroupId(), type, ir.getSessionId(), text,
|
|
||||||
ir.getMessage(), ir.getTimestamp(), ir.isRead(),
|
|
||||||
ir.getShareable().getId(), !ir.isAvailable(),
|
|
||||||
ir.canBeOpened());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ConversationItem from(Context ctx, String contactName,
|
|
||||||
InvitationResponse ir) {
|
|
||||||
@StringRes int res;
|
|
||||||
if (ir.isLocal()) {
|
|
||||||
if (ir.wasAccepted()) {
|
|
||||||
if (ir instanceof ForumInvitationResponse) {
|
|
||||||
res = R.string.forum_invitation_response_accepted_sent;
|
|
||||||
} else if (ir instanceof BlogInvitationResponse) {
|
|
||||||
res = R.string.blogs_sharing_response_accepted_sent;
|
|
||||||
} else if (ir instanceof GroupInvitationResponse) {
|
|
||||||
res = R.string.groups_invitations_response_accepted_sent;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unknown InvitationResponse");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ir instanceof ForumInvitationResponse) {
|
|
||||||
res = R.string.forum_invitation_response_declined_sent;
|
|
||||||
} else if (ir instanceof BlogInvitationResponse) {
|
|
||||||
res = R.string.blogs_sharing_response_declined_sent;
|
|
||||||
} else if (ir instanceof GroupInvitationResponse) {
|
|
||||||
res = R.string.groups_invitations_response_declined_sent;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unknown InvitationResponse");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String text = ctx.getString(res, contactName);
|
|
||||||
return new ConversationNoticeOutItem(ir.getId(), ir.getGroupId(),
|
|
||||||
text, null, ir.getTimestamp(), ir.isSent(), ir.isSeen());
|
|
||||||
} else {
|
|
||||||
if (ir.wasAccepted()) {
|
|
||||||
if (ir instanceof ForumInvitationResponse) {
|
|
||||||
res = R.string.forum_invitation_response_accepted_received;
|
|
||||||
} else if (ir instanceof BlogInvitationResponse) {
|
|
||||||
res = R.string.blogs_sharing_response_accepted_received;
|
|
||||||
} else if (ir instanceof GroupInvitationResponse) {
|
|
||||||
res = R.string.groups_invitations_response_accepted_received;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unknown InvitationResponse");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (ir instanceof ForumInvitationResponse) {
|
|
||||||
res = R.string.forum_invitation_response_declined_received;
|
|
||||||
} else if (ir instanceof BlogInvitationResponse) {
|
|
||||||
res = R.string.blogs_sharing_response_declined_received;
|
|
||||||
} else if (ir instanceof GroupInvitationResponse) {
|
|
||||||
res = R.string.groups_invitations_response_declined_received;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unknown InvitationResponse");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String text = ctx.getString(res, contactName);
|
|
||||||
return new ConversationNoticeInItem(ir.getId(), ir.getGroupId(),
|
|
||||||
text, null, ir.getTimestamp(), ir.isRead());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This method should not be used to display the resulting ConversationItem
|
|
||||||
* in the UI, but only to update list information based on the
|
|
||||||
* BaseMessageHeader.
|
|
||||||
**/
|
|
||||||
static ConversationItem from(Context ctx, BaseMessageHeader h) {
|
|
||||||
if (h instanceof PrivateMessageHeader) {
|
|
||||||
return from((PrivateMessageHeader) h);
|
|
||||||
} else if(h instanceof IntroductionRequest) {
|
|
||||||
return from(ctx, "", (IntroductionRequest) h);
|
|
||||||
} else if(h instanceof IntroductionResponse) {
|
|
||||||
return from(ctx, "", (IntroductionResponse) h);
|
|
||||||
} else if(h instanceof InvitationRequest) {
|
|
||||||
return from(ctx, "", (InvitationRequest) h);
|
|
||||||
} else if(h instanceof InvitationResponse) {
|
|
||||||
return from(ctx, "", (InvitationResponse) h);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unknown message header");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
@@ -17,13 +18,17 @@ class ConversationNoticeInItem extends ConversationItem {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final String msgText;
|
private final String msgText;
|
||||||
|
|
||||||
ConversationNoticeInItem(MessageId id, GroupId groupId,
|
ConversationNoticeInItem(MessageId id, GroupId groupId, String text,
|
||||||
String text, @Nullable String msgText, long time,
|
@Nullable String msgText, long time, boolean read) {
|
||||||
boolean read) {
|
|
||||||
super(id, groupId, text, time, read);
|
super(id, groupId, text, time, read);
|
||||||
this.msgText = msgText;
|
this.msgText = msgText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConversationNoticeInItem(String text, PrivateResponse r) {
|
||||||
|
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isRead());
|
||||||
|
this.msgText = null;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
String getMsgText() {
|
String getMsgText() {
|
||||||
return msgText;
|
return msgText;
|
||||||
@@ -39,5 +44,4 @@ class ConversationNoticeInItem extends ConversationItem {
|
|||||||
public int getLayout() {
|
public int getLayout() {
|
||||||
return R.layout.list_item_conversation_notice_in;
|
return R.layout.list_item_conversation_notice_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package org.briarproject.briar.android.contact;
|
|||||||
import android.support.annotation.LayoutRes;
|
import android.support.annotation.LayoutRes;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateResponse;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
@@ -17,11 +17,16 @@ class ConversationNoticeOutItem extends ConversationOutItem {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private final String msgText;
|
private final String msgText;
|
||||||
|
|
||||||
ConversationNoticeOutItem(MessageId id, GroupId groupId,
|
ConversationNoticeOutItem(String text, PrivateRequest r) {
|
||||||
String text, @Nullable String msgText, long time,
|
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
|
||||||
boolean sent, boolean seen) {
|
r.isSeen());
|
||||||
super(id, groupId, text, time, sent, seen);
|
this.msgText = r.getMessage();
|
||||||
this.msgText = msgText;
|
}
|
||||||
|
|
||||||
|
ConversationNoticeOutItem(String text, PrivateResponse r) {
|
||||||
|
super(r.getId(), r.getGroupId(), text, r.getTimestamp(), r.isSent(),
|
||||||
|
r.isSeen());
|
||||||
|
this.msgText = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -34,5 +39,4 @@ class ConversationNoticeOutItem extends ConversationOutItem {
|
|||||||
public int getLayout() {
|
public int getLayout() {
|
||||||
return R.layout.list_item_conversation_notice_out;
|
return R.layout.list_item_conversation_notice_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import android.support.annotation.LayoutRes;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.api.client.SessionId;
|
import org.briarproject.briar.api.client.SessionId;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateRequest;
|
||||||
|
import org.briarproject.briar.api.sharing.InvitationRequest;
|
||||||
|
import org.briarproject.briar.api.sharing.Shareable;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
@@ -15,7 +17,7 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class ConversationRequestItem extends ConversationNoticeInItem {
|
class ConversationRequestItem extends ConversationNoticeInItem {
|
||||||
|
|
||||||
enum RequestType { INTRODUCTION, FORUM, BLOG, GROUP }
|
enum RequestType {INTRODUCTION, FORUM, BLOG, GROUP}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final GroupId requestedGroupId;
|
private final GroupId requestedGroupId;
|
||||||
@@ -24,17 +26,19 @@ class ConversationRequestItem extends ConversationNoticeInItem {
|
|||||||
private final boolean canBeOpened;
|
private final boolean canBeOpened;
|
||||||
private boolean answered;
|
private boolean answered;
|
||||||
|
|
||||||
ConversationRequestItem(MessageId id, GroupId groupId,
|
ConversationRequestItem(String text, RequestType type, PrivateRequest r) {
|
||||||
RequestType requestType, SessionId sessionId, String text,
|
super(r.getId(), r.getGroupId(), text, r.getMessage(),
|
||||||
@Nullable String msgText, long time, boolean read,
|
r.getTimestamp(), r.isRead());
|
||||||
@Nullable GroupId requestedGroupId, boolean answered,
|
this.requestType = type;
|
||||||
boolean canBeOpened) {
|
this.sessionId = r.getSessionId();
|
||||||
super(id, groupId, text, msgText, time, read);
|
this.answered = r.wasAnswered();
|
||||||
this.requestType = requestType;
|
if (r instanceof InvitationRequest) {
|
||||||
this.sessionId = sessionId;
|
this.requestedGroupId = ((Shareable) r.getNameable()).getId();
|
||||||
this.requestedGroupId = requestedGroupId;
|
this.canBeOpened = ((InvitationRequest) r).canBeOpened();
|
||||||
this.answered = answered;
|
} else {
|
||||||
this.canBeOpened = canBeOpened;
|
this.requestedGroupId = null;
|
||||||
|
this.canBeOpened = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestType getRequestType() {
|
RequestType getRequestType() {
|
||||||
@@ -54,8 +58,8 @@ class ConversationRequestItem extends ConversationNoticeInItem {
|
|||||||
return answered;
|
return answered;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAnswered(boolean answered) {
|
void setAnswered() {
|
||||||
this.answered = answered;
|
this.answered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canBeOpened() {
|
public boolean canBeOpened() {
|
||||||
@@ -67,5 +71,4 @@ class ConversationRequestItem extends ConversationNoticeInItem {
|
|||||||
public int getLayout() {
|
public int getLayout() {
|
||||||
return R.layout.list_item_conversation_request;
|
return R.layout.list_item_conversation_request;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
package org.briarproject.briar.android.contact;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.LiveData;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.api.blog.BlogInvitationRequest;
|
||||||
|
import org.briarproject.briar.api.blog.BlogInvitationResponse;
|
||||||
|
import org.briarproject.briar.api.forum.ForumInvitationRequest;
|
||||||
|
import org.briarproject.briar.api.forum.ForumInvitationResponse;
|
||||||
|
import org.briarproject.briar.api.introduction.IntroductionRequest;
|
||||||
|
import org.briarproject.briar.api.introduction.IntroductionResponse;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
||||||
|
import org.briarproject.briar.api.messaging.PrivateMessageVisitor;
|
||||||
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationRequest;
|
||||||
|
import org.briarproject.briar.api.privategroup.invitation.GroupInvitationResponse;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.BLOG;
|
||||||
|
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.FORUM;
|
||||||
|
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.GROUP;
|
||||||
|
import static org.briarproject.briar.android.contact.ConversationRequestItem.RequestType.INTRODUCTION;
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConversationVisitor implements PrivateMessageVisitor<ConversationItem> {
|
||||||
|
|
||||||
|
private final Context ctx;
|
||||||
|
private final BodyCache bodyCache;
|
||||||
|
private final LiveData<String> contactName;
|
||||||
|
|
||||||
|
ConversationVisitor(Context ctx, BodyCache bodyCache,
|
||||||
|
LiveData<String> contactName) {
|
||||||
|
this.ctx = ctx;
|
||||||
|
this.bodyCache = bodyCache;
|
||||||
|
this.contactName = contactName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitPrivateMessageHeader(PrivateMessageHeader h) {
|
||||||
|
ConversationItem item;
|
||||||
|
if (h.isLocal()) item = new ConversationMessageOutItem(h);
|
||||||
|
else item = new ConversationMessageInItem(h);
|
||||||
|
String body = bodyCache.getBody(h.getId());
|
||||||
|
if (body != null) item.setBody(body);
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitBlogInvitationRequest(
|
||||||
|
BlogInvitationRequest r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text = ctx.getString(R.string.blogs_sharing_invitation_sent,
|
||||||
|
r.getName(), contactName.getValue());
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text = ctx.getString(
|
||||||
|
R.string.blogs_sharing_invitation_received,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationRequestItem(text, BLOG, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitBlogInvitationResponse(
|
||||||
|
BlogInvitationResponse r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.blogs_sharing_response_accepted_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.blogs_sharing_response_declined_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.blogs_sharing_response_accepted_received,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.blogs_sharing_response_declined_received,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeInItem(text, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitForumInvitationRequest(
|
||||||
|
ForumInvitationRequest r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text = ctx.getString(R.string.forum_invitation_sent,
|
||||||
|
r.getName(), contactName.getValue());
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text = ctx.getString(
|
||||||
|
R.string.forum_invitation_received,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationRequestItem(text, FORUM, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitForumInvitationResponse(
|
||||||
|
ForumInvitationResponse r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.forum_invitation_response_accepted_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.forum_invitation_response_declined_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.forum_invitation_response_accepted_received,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.forum_invitation_response_declined_received,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeInItem(text, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitGroupInvitationRequest(
|
||||||
|
GroupInvitationRequest r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text = ctx.getString(
|
||||||
|
R.string.groups_invitations_invitation_sent,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text = ctx.getString(
|
||||||
|
R.string.groups_invitations_invitation_received,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationRequestItem(text, GROUP, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitGroupInvitationResponse(
|
||||||
|
GroupInvitationResponse r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.groups_invitations_response_accepted_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.groups_invitations_response_declined_sent,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.groups_invitations_response_accepted_received,
|
||||||
|
contactName.getValue());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.groups_invitations_response_declined_received,
|
||||||
|
contactName.getValue());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeInItem(text, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitIntroductionRequest(IntroductionRequest r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text = ctx.getString(R.string.introduction_request_sent,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text = ctx.getString(R.string.introduction_request_received,
|
||||||
|
contactName.getValue(), r.getName());
|
||||||
|
return new ConversationRequestItem(text, INTRODUCTION, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConversationItem visitIntroductionResponse(IntroductionResponse r) {
|
||||||
|
if (r.isLocal()) {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
String introducee = r.getIntroducedAuthor().getName();
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_response_accepted_sent,
|
||||||
|
introducee)
|
||||||
|
+ "\n\n" + ctx.getString(
|
||||||
|
R.string.introduction_response_accepted_sent_info,
|
||||||
|
introducee);
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_response_declined_sent,
|
||||||
|
r.getIntroducedAuthor().getName());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeOutItem(text, r);
|
||||||
|
} else {
|
||||||
|
String text;
|
||||||
|
if (r.wasAccepted()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_response_accepted_received,
|
||||||
|
contactName.getValue(),
|
||||||
|
r.getIntroducedAuthor().getName());
|
||||||
|
} else if (r.isIntroducer()) {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_response_declined_received,
|
||||||
|
contactName.getValue(),
|
||||||
|
r.getIntroducedAuthor().getName());
|
||||||
|
} else {
|
||||||
|
text = ctx.getString(
|
||||||
|
R.string.introduction_response_declined_received_by_introducee,
|
||||||
|
contactName.getValue(),
|
||||||
|
r.getIntroducedAuthor().getName());
|
||||||
|
}
|
||||||
|
return new ConversationNoticeInItem(text, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BodyCache {
|
||||||
|
@Nullable
|
||||||
|
String getBody(MessageId m);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,11 +84,10 @@ class ForumControllerImpl extends
|
|||||||
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
|
} else if (e instanceof ForumInvitationResponseReceivedEvent) {
|
||||||
ForumInvitationResponseReceivedEvent f =
|
ForumInvitationResponseReceivedEvent f =
|
||||||
(ForumInvitationResponseReceivedEvent) e;
|
(ForumInvitationResponseReceivedEvent) e;
|
||||||
ForumInvitationResponse r =
|
ForumInvitationResponse r = f.getMessageHeader();
|
||||||
(ForumInvitationResponse) f.getResponse();
|
|
||||||
if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) {
|
if (r.getShareableId().equals(getGroupId()) && r.wasAccepted()) {
|
||||||
LOG.info("Forum invitation was accepted");
|
LOG.info("Forum invitation was accepted");
|
||||||
onForumInvitationAccepted(r.getContactId());
|
onForumInvitationAccepted(f.getContactId());
|
||||||
}
|
}
|
||||||
} else if (e instanceof ContactLeftShareableEvent) {
|
} else if (e instanceof ContactLeftShareableEvent) {
|
||||||
ContactLeftShareableEvent c = (ContactLeftShareableEvent) e;
|
ContactLeftShareableEvent c = (ContactLeftShareableEvent) e;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.introduction;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.ActionBar;
|
import android.support.v7.app.ActionBar;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -82,8 +83,8 @@ public class IntroductionMessageFragment extends BaseFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
|
||||||
// change toolbar text
|
// change toolbar text
|
||||||
ActionBar actionBar = introductionActivity.getSupportActionBar();
|
ActionBar actionBar = introductionActivity.getSupportActionBar();
|
||||||
@@ -182,7 +183,7 @@ public class IntroductionMessageFragment extends BaseFragment
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSendClick(String text) {
|
public void onSendClick(@NonNull String text) {
|
||||||
// disable button to prevent accidental double invitations
|
// disable button to prevent accidental double invitations
|
||||||
ui.message.setSendButtonEnabled(false);
|
ui.message.setSendButtonEnabled(false);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.google.zxing.Result;
|
import com.google.zxing.Result;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.UnsupportedVersionException;
|
|
||||||
import org.briarproject.bramble.api.event.Event;
|
import org.briarproject.bramble.api.event.Event;
|
||||||
import org.briarproject.bramble.api.event.EventBus;
|
import org.briarproject.bramble.api.event.EventBus;
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
|
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
|
||||||
@@ -23,6 +22,7 @@ import org.briarproject.bramble.api.keyagreement.KeyAgreementTask;
|
|||||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||||
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
import org.briarproject.bramble.api.keyagreement.PayloadEncoder;
|
||||||
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
import org.briarproject.bramble.api.keyagreement.PayloadParser;
|
||||||
|
import org.briarproject.bramble.api.keyagreement.UnsupportedVersionException;
|
||||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementAbortedEvent;
|
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementAbortedEvent;
|
||||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFailedEvent;
|
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFailedEvent;
|
||||||
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent;
|
import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent;
|
||||||
@@ -244,8 +244,14 @@ public class KeyAgreementFragment extends BaseEventFragment
|
|||||||
task.connectAndRunProtocol(remotePayload);
|
task.connectAndRunProtocol(remotePayload);
|
||||||
} catch (UnsupportedVersionException e) {
|
} catch (UnsupportedVersionException e) {
|
||||||
reset();
|
reset();
|
||||||
String msg = getString(R.string.qr_code_unsupported,
|
String msg;
|
||||||
getString(R.string.app_name));
|
if (e.isTooOld()) {
|
||||||
|
msg = getString(R.string.qr_code_too_old,
|
||||||
|
getString(R.string.app_name));
|
||||||
|
} else {
|
||||||
|
msg = getString(R.string.qr_code_too_new,
|
||||||
|
getString(R.string.app_name));
|
||||||
|
}
|
||||||
showNextFragment(ContactExchangeErrorFragment.newInstance(msg));
|
showNextFragment(ContactExchangeErrorFragment.newInstance(msg));
|
||||||
} catch (CameraException e) {
|
} catch (CameraException e) {
|
||||||
logCameraExceptionAndFinish(e);
|
logCameraExceptionAndFinish(e);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import android.graphics.drawable.ClipDrawable;
|
|||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.graphics.drawable.LayerDrawable;
|
import android.graphics.drawable.LayerDrawable;
|
||||||
import android.graphics.drawable.ShapeDrawable;
|
import android.graphics.drawable.ShapeDrawable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ import static android.graphics.Paint.Style.FILL;
|
|||||||
import static android.graphics.Paint.Style.STROKE;
|
import static android.graphics.Paint.Style.STROKE;
|
||||||
import static android.graphics.drawable.ClipDrawable.HORIZONTAL;
|
import static android.graphics.drawable.ClipDrawable.HORIZONTAL;
|
||||||
import static android.view.Gravity.LEFT;
|
import static android.view.Gravity.LEFT;
|
||||||
|
import static android.view.Gravity.START;
|
||||||
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
|
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_STRONG;
|
||||||
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
|
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
|
||||||
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
|
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.STRONG;
|
||||||
@@ -35,11 +37,11 @@ public class StrengthMeter extends ProgressBar {
|
|||||||
this(context, null);
|
this(context, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public StrengthMeter(Context context, AttributeSet attrs) {
|
public StrengthMeter(Context context, @Nullable AttributeSet attrs) {
|
||||||
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
|
super(context, attrs, android.R.attr.progressBarStyleHorizontal);
|
||||||
bar = new ShapeDrawable();
|
bar = new ShapeDrawable();
|
||||||
bar.getPaint().setColor(RED);
|
bar.getPaint().setColor(RED);
|
||||||
ClipDrawable clip = new ClipDrawable(bar, LEFT, HORIZONTAL);
|
ClipDrawable clip = new ClipDrawable(bar, LEFT & START, HORIZONTAL);
|
||||||
ShapeDrawable background = new ShapeDrawable();
|
ShapeDrawable background = new ShapeDrawable();
|
||||||
Paint p = background.getPaint();
|
Paint p = background.getPaint();
|
||||||
p.setStyle(FILL);
|
p.setStyle(FILL);
|
||||||
@@ -50,6 +52,7 @@ public class StrengthMeter extends ProgressBar {
|
|||||||
Drawable[] layers = new Drawable[] { clip, background };
|
Drawable[] layers = new Drawable[] { clip, background };
|
||||||
setProgressDrawable(new LayerDrawable(layers));
|
setProgressDrawable(new LayerDrawable(layers));
|
||||||
setIndeterminate(false);
|
setIndeterminate(false);
|
||||||
|
if (isInEditMode()) setStrength(STRONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package org.briarproject.briar.android.panic;
|
||||||
|
|
||||||
|
import info.guardianproject.trustedintents.ApkSignaturePin;
|
||||||
|
|
||||||
|
// needs to be public, because TrustedIntents will instantiate
|
||||||
|
public final class FDroidSignaturePin extends ApkSignaturePin {
|
||||||
|
|
||||||
|
public FDroidSignaturePin() {
|
||||||
|
this.fingerprints = new String[] {
|
||||||
|
"927f7e38b6acbecd84e02dace33efa9a7a2f0979750f28f585688ee38b3a4e28"};
|
||||||
|
this.certificates = new byte[][] {
|
||||||
|
{48, -126, 3, 95, 48, -126, 2, 71, -96, 3, 2, 1, 2, 2, 4, 28,
|
||||||
|
-30, 107, -102, 48, 13, 6, 9, 42, -122, 72, -122, -9,
|
||||||
|
13, 1, 1, 11, 5, 0, 48, 96, 49, 11, 48, 9, 6, 3, 85, 4,
|
||||||
|
6, 19, 2, 85, 75, 49, 12, 48, 10, 6, 3, 85, 4, 8, 19, 3,
|
||||||
|
79, 82, 71, 49, 12, 48, 10, 6, 3, 85, 4, 7, 19, 3, 79,
|
||||||
|
82, 71, 49, 19, 48, 17, 6, 3, 85, 4, 10, 19, 10, 102,
|
||||||
|
100, 114, 111, 105, 100, 46, 111, 114, 103, 49, 15, 48,
|
||||||
|
13, 6, 3, 85, 4, 11, 19, 6, 70, 68, 114, 111, 105, 100,
|
||||||
|
49, 15, 48, 13, 6, 3, 85, 4, 3, 19, 6, 70, 68, 114, 111,
|
||||||
|
105, 100, 48, 30, 23, 13, 49, 55, 49, 50, 48, 55, 49,
|
||||||
|
55, 51, 48, 52, 50, 90, 23, 13, 52, 53, 48, 52, 50, 52,
|
||||||
|
49, 55, 51, 48, 52, 50, 90, 48, 96, 49, 11, 48, 9, 6, 3,
|
||||||
|
85, 4, 6, 19, 2, 85, 75, 49, 12, 48, 10, 6, 3, 85, 4, 8,
|
||||||
|
19, 3, 79, 82, 71, 49, 12, 48, 10, 6, 3, 85, 4, 7, 19,
|
||||||
|
3, 79, 82, 71, 49, 19, 48, 17, 6, 3, 85, 4, 10, 19, 10,
|
||||||
|
102, 100, 114, 111, 105, 100, 46, 111, 114, 103, 49, 15,
|
||||||
|
48, 13, 6, 3, 85, 4, 11, 19, 6, 70, 68, 114, 111, 105,
|
||||||
|
100, 49, 15, 48, 13, 6, 3, 85, 4, 3, 19, 6, 70, 68, 114,
|
||||||
|
111, 105, 100, 48, -126, 1, 34, 48, 13, 6, 9, 42, -122,
|
||||||
|
72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -126, 1, 15, 0, 48,
|
||||||
|
-126, 1, 10, 2, -126, 1, 1, 0, -107, -115, -106, 1, -26,
|
||||||
|
72, -105, -99, 62, 3, -55, 34, 99, -112, -68, -20, -115,
|
||||||
|
31, 34, 118, -50, 12, -32, -59, 74, -58, -37, -87, 21,
|
||||||
|
105, 36, -82, 13, -51, 66, 4, 55, -111, 13, -46, -7,
|
||||||
|
-69, -15, 36, 118, -7, 101, -86, 123, -83, -103, 110,
|
||||||
|
116, -54, 112, 46, 12, 96, -76, -48, -70, -33, -81, 52,
|
||||||
|
59, 73, 107, -126, -72, -25, 32, 93, 29, -20, 5, -41,
|
||||||
|
-27, 123, -9, 104, -31, -59, -1, -83, -93, 99, 85, -116,
|
||||||
|
-62, -55, 18, -63, 6, -51, -110, 33, 9, 7, -49, 102,
|
||||||
|
-20, -122, -124, -68, 93, -102, 31, 48, 86, 96, -99,
|
||||||
|
105, -52, 95, 12, 57, 99, 12, -24, 70, 40, -99, -20,
|
||||||
|
-21, -85, -70, -105, 95, 117, -31, 126, -126, -39, 46,
|
||||||
|
-62, 59, -23, -74, 108, -12, -56, -40, -96, 79, -37,
|
||||||
|
-82, 1, 99, -104, 48, -60, 92, 14, 109, 127, -22, 31,
|
||||||
|
115, -27, 108, 9, 92, 118, -45, 103, 117, 57, -50, -82,
|
||||||
|
114, -113, 68, -82, 87, 96, 111, 72, 65, -63, 12, 31,
|
||||||
|
-34, -31, -55, -101, 101, 101, 59, 73, -119, -122, 82,
|
||||||
|
28, 47, -108, -85, 59, 46, 89, -93, -1, 9, -11, -51, 63,
|
||||||
|
-44, 109, -76, -103, -26, -49, -80, 6, 52, -27, 73,
|
||||||
|
-104, 40, 2, -101, -124, 60, -52, -105, -70, -24, -62,
|
||||||
|
88, 38, 53, -99, -92, 31, 119, 26, 79, 60, -124, 25,
|
||||||
|
-115, -89, -115, -109, 0, 6, 122, -78, 116, 82, 3, 39,
|
||||||
|
-67, 45, -43, 17, -39, 2, 3, 1, 0, 1, -93, 33, 48, 31,
|
||||||
|
48, 29, 6, 3, 85, 29, 14, 4, 22, 4, 20, 63, 109, -42,
|
||||||
|
-109, 25, 22, 7, -37, -22, -41, -38, 58, -56, 2, -68,
|
||||||
|
-38, -22, 65, -28, -60, 48, 13, 6, 9, 42, -122, 72,
|
||||||
|
-122, -9, 13, 1, 1, 11, 5, 0, 3, -126, 1, 1, 0, 94, 17,
|
||||||
|
31, 36, 85, -11, 85, 44, 19, -80, -20, -92, -118, 93,
|
||||||
|
40, 45, 96, 31, -3, -37, -110, -96, 102, 81, 61, -74,
|
||||||
|
-125, -117, -112, 58, -47, 17, 78, -18, 111, -116, 26,
|
||||||
|
-91, 73, 100, 84, -99, 21, 87, 73, -106, 108, -51, -125,
|
||||||
|
-21, 119, -88, -78, 2, 82, -109, -64, -9, -86, -112,
|
||||||
|
-115, 66, -86, 46, 71, 107, -65, 96, -102, 47, 35, -45,
|
||||||
|
-126, 33, 34, 121, -25, -85, -121, -56, -42, 22, -1,
|
||||||
|
-95, -86, 81, 100, -70, 113, 104, -73, 22, -19, 79, -19,
|
||||||
|
52, 62, 42, 76, -112, 94, -34, 42, -57, -75, -90, -58,
|
||||||
|
118, 127, -106, -39, 108, -56, -79, 103, -33, 22, 3, 47,
|
||||||
|
103, -76, -81, 53, -22, -44, -26, -102, 63, -99, 39, 38,
|
||||||
|
-108, 75, 33, 10, 25, -110, -125, -115, 114, -69, 73,
|
||||||
|
-112, 36, 74, 77, -82, -44, 29, -123, -8, -117, 71,
|
||||||
|
-105, 15, -109, 51, 22, 4, 80, 1, 43, 118, 121, -113,
|
||||||
|
-70, 83, -56, 82, -110, 4, -63, 16, -57, 126, -70, 81,
|
||||||
|
73, 61, 2, -61, 24, -14, -10, 4, -21, 90, 24, 66, 41,
|
||||||
|
-57, -60, -113, -18, -54, -1, 103, -75, 32, -64, 67,
|
||||||
|
103, 109, -79, -12, -113, -27, 114, 89, 116, 115, -13,
|
||||||
|
-123, -70, 61, -41, -46, -118, 29, -105, -97, -75, 39,
|
||||||
|
-51, 60, 88, 125, 55, -46, -95, 52, 57, 52, -115, 80,
|
||||||
|
44, 109, 119, -116, -62, -77, -74, -88, 41, 57, -65,
|
||||||
|
-71, -115, -67, 23, 66, -21, 56, 51, -91, 109}};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,13 +31,12 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
public static final String KEY_LOCK = "pref_key_lock";
|
public static final String KEY_LOCK = "pref_key_lock";
|
||||||
public static final String KEY_PANIC_APP = "pref_key_panic_app";
|
public static final String KEY_PANIC_APP = "pref_key_panic_app";
|
||||||
public static final String KEY_PURGE = "pref_key_purge";
|
public static final String KEY_PURGE = "pref_key_purge";
|
||||||
public static final String KEY_UNINSTALL = "pref_key_uninstall";
|
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(PanicPreferencesFragment.class.getName());
|
Logger.getLogger(PanicPreferencesFragment.class.getName());
|
||||||
|
|
||||||
private PackageManager pm;
|
private PackageManager pm;
|
||||||
private SwitchPreference lockPref, purgePref, uninstallPref;
|
private SwitchPreference lockPref, purgePref;
|
||||||
private ListPreference panicAppPref;
|
private ListPreference panicAppPref;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,7 +48,6 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
lockPref = (SwitchPreference) findPreference(KEY_LOCK);
|
lockPref = (SwitchPreference) findPreference(KEY_LOCK);
|
||||||
panicAppPref = (ListPreference) findPreference(KEY_PANIC_APP);
|
panicAppPref = (ListPreference) findPreference(KEY_PANIC_APP);
|
||||||
purgePref = (SwitchPreference) findPreference(KEY_PURGE);
|
purgePref = (SwitchPreference) findPreference(KEY_PURGE);
|
||||||
uninstallPref = (SwitchPreference) findPreference(KEY_UNINSTALL);
|
|
||||||
|
|
||||||
// check for connect/disconnect intents from panic trigger apps
|
// check for connect/disconnect intents from panic trigger apps
|
||||||
if (PanicResponder.checkForDisconnectIntent(getActivity())) {
|
if (PanicResponder.checkForDisconnectIntent(getActivity())) {
|
||||||
@@ -97,16 +95,11 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
showPanicApp(packageName);
|
showPanicApp(packageName);
|
||||||
|
|
||||||
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
|
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
|
||||||
lockPref.setEnabled(false);
|
|
||||||
purgePref.setChecked(false);
|
purgePref.setChecked(false);
|
||||||
purgePref.setEnabled(false);
|
purgePref.setEnabled(false);
|
||||||
uninstallPref.setChecked(false);
|
|
||||||
uninstallPref.setEnabled(false);
|
|
||||||
getActivity().setResult(Activity.RESULT_CANCELED);
|
getActivity().setResult(Activity.RESULT_CANCELED);
|
||||||
} else {
|
} else {
|
||||||
lockPref.setEnabled(true);
|
|
||||||
purgePref.setEnabled(true);
|
purgePref.setEnabled(true);
|
||||||
uninstallPref.setEnabled(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -145,27 +138,15 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
@Override
|
@Override
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||||
String key) {
|
String key) {
|
||||||
if (key.equals(KEY_PURGE)) {
|
// enable locking if purging gets enabled
|
||||||
// enable locking if purging gets enabled
|
if (key.equals(KEY_PURGE) &&
|
||||||
if (sharedPreferences.getBoolean(KEY_PURGE, false)) {
|
sharedPreferences.getBoolean(KEY_PURGE, false)) {
|
||||||
lockPref.setChecked(true);
|
|
||||||
}
|
|
||||||
// disable uninstall if purging gets disabled
|
|
||||||
else {
|
|
||||||
uninstallPref.setChecked(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// enable purging and locking if uninstall gets enabled
|
|
||||||
if (key.equals(KEY_UNINSTALL) &&
|
|
||||||
sharedPreferences.getBoolean(KEY_UNINSTALL, false)) {
|
|
||||||
lockPref.setChecked(true);
|
lockPref.setChecked(true);
|
||||||
purgePref.setChecked(true);
|
|
||||||
}
|
}
|
||||||
// disable purging and uninstalling if locking gets disabled
|
// disable purging if locking gets disabled
|
||||||
if (key.equals(KEY_LOCK) &&
|
if (key.equals(KEY_LOCK) &&
|
||||||
!sharedPreferences.getBoolean(KEY_LOCK, true)) {
|
!sharedPreferences.getBoolean(KEY_LOCK, true)) {
|
||||||
purgePref.setChecked(false);
|
purgePref.setChecked(false);
|
||||||
uninstallPref.setChecked(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,10 +160,8 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
panicAppPref.setIcon(
|
panicAppPref.setIcon(
|
||||||
android.R.drawable.ic_menu_close_clear_cancel);
|
android.R.drawable.ic_menu_close_clear_cancel);
|
||||||
|
|
||||||
// disable panic actions
|
// disable destructive panic actions
|
||||||
lockPref.setEnabled(false);
|
|
||||||
purgePref.setEnabled(false);
|
purgePref.setEnabled(false);
|
||||||
uninstallPref.setEnabled(false);
|
|
||||||
} else {
|
} else {
|
||||||
// display connected panic app
|
// display connected panic app
|
||||||
try {
|
try {
|
||||||
@@ -192,10 +171,8 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
|
|||||||
panicAppPref.setIcon(
|
panicAppPref.setIcon(
|
||||||
pm.getApplicationIcon(triggerPackageName));
|
pm.getApplicationIcon(triggerPackageName));
|
||||||
|
|
||||||
// enable panic actions
|
// enable destructive panic actions
|
||||||
lockPref.setEnabled(true);
|
|
||||||
purgePref.setEnabled(true);
|
purgePref.setEnabled(true);
|
||||||
uninstallPref.setEnabled(true);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
// revert back to no app, just to be safe
|
// revert back to no app, just to be safe
|
||||||
PanicResponder.setTriggerPackageName(getActivity(),
|
PanicResponder.setTriggerPackageName(getActivity(),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.panic;
|
|||||||
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v7.preference.PreferenceManager;
|
import android.support.v7.preference.PreferenceManager;
|
||||||
@@ -11,7 +10,6 @@ import org.briarproject.bramble.api.account.AccountManager;
|
|||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.iilab.IilabEngineeringRSA2048Pin;
|
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -22,10 +20,8 @@ import info.guardianproject.panic.Panic;
|
|||||||
import info.guardianproject.panic.PanicResponder;
|
import info.guardianproject.panic.PanicResponder;
|
||||||
import info.guardianproject.trustedintents.TrustedIntents;
|
import info.guardianproject.trustedintents.TrustedIntents;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_DELETE;
|
|
||||||
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_LOCK;
|
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_LOCK;
|
||||||
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_PURGE;
|
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_PURGE;
|
||||||
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_UNINSTALL;
|
|
||||||
|
|
||||||
public class PanicResponderActivity extends BriarActivity {
|
public class PanicResponderActivity extends BriarActivity {
|
||||||
|
|
||||||
@@ -44,8 +40,8 @@ public class PanicResponderActivity extends BriarActivity {
|
|||||||
TrustedIntents trustedIntents = TrustedIntents.get(this);
|
TrustedIntents trustedIntents = TrustedIntents.get(this);
|
||||||
// Guardian Project Ripple
|
// Guardian Project Ripple
|
||||||
trustedIntents.addTrustedSigner(GuardianProjectRSA4096.class);
|
trustedIntents.addTrustedSigner(GuardianProjectRSA4096.class);
|
||||||
// Amnesty International's Panic Button, made by iilab.org
|
// F-Droid
|
||||||
trustedIntents.addTrustedSigner(IilabEngineeringRSA2048Pin.class);
|
trustedIntents.addTrustedSigner(FDroidSignaturePin.class);
|
||||||
|
|
||||||
Intent intent = trustedIntents.getIntentFromTrustedSender(this);
|
Intent intent = trustedIntents.getIntentFromTrustedSender(this);
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
@@ -60,23 +56,16 @@ public class PanicResponderActivity extends BriarActivity {
|
|||||||
LOG.info("Panic Trigger came from connected app");
|
LOG.info("Panic Trigger came from connected app");
|
||||||
|
|
||||||
// Performing panic responses
|
// Performing panic responses
|
||||||
if (sharedPref.getBoolean(KEY_UNINSTALL, false)) {
|
if (sharedPref.getBoolean(KEY_PURGE, false)) {
|
||||||
LOG.info("Purging all data...");
|
LOG.info("Purging all data...");
|
||||||
deleteAllData();
|
deleteAllData();
|
||||||
|
|
||||||
LOG.info("Uninstalling...");
|
|
||||||
Intent uninstall = new Intent(ACTION_DELETE);
|
|
||||||
uninstall.setData(
|
|
||||||
Uri.parse("package:" + getPackageName()));
|
|
||||||
startActivity(uninstall);
|
|
||||||
} else if (sharedPref.getBoolean(KEY_PURGE, false)) {
|
|
||||||
LOG.info("Purging all data...");
|
|
||||||
deleteAllData();
|
|
||||||
} else if (sharedPref.getBoolean(KEY_LOCK, true)) {
|
|
||||||
LOG.info("Signing out...");
|
|
||||||
signOut(true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// non-destructive actions are allowed by non-connected trusted apps
|
||||||
|
if (sharedPref.getBoolean(KEY_LOCK, true)) {
|
||||||
|
LOG.info("Signing out...");
|
||||||
|
signOut(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,10 @@ class GroupControllerImpl extends
|
|||||||
} else if (e instanceof GroupInvitationResponseReceivedEvent) {
|
} else if (e instanceof GroupInvitationResponseReceivedEvent) {
|
||||||
GroupInvitationResponseReceivedEvent g =
|
GroupInvitationResponseReceivedEvent g =
|
||||||
(GroupInvitationResponseReceivedEvent) e;
|
(GroupInvitationResponseReceivedEvent) e;
|
||||||
GroupInvitationResponse r =
|
GroupInvitationResponse r = g.getMessageHeader();
|
||||||
(GroupInvitationResponse) g.getResponse();
|
|
||||||
if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
|
if (getGroupId().equals(r.getShareableId()) && r.wasAccepted()) {
|
||||||
listener.runOnUiThreadUnlessDestroyed(
|
listener.runOnUiThreadUnlessDestroyed(
|
||||||
() -> listener.onInvitationAccepted(r.getContactId()));
|
() -> listener.onInvitationAccepted(g.getContactId()));
|
||||||
}
|
}
|
||||||
} else if (e instanceof GroupDissolvedEvent) {
|
} else if (e instanceof GroupDissolvedEvent) {
|
||||||
GroupDissolvedEvent g = (GroupDissolvedEvent) e;
|
GroupDissolvedEvent g = (GroupDissolvedEvent) e;
|
||||||
|
|||||||
@@ -292,8 +292,7 @@ public class DevReportActivity extends BaseCrashReportDialog
|
|||||||
cb.setChecked(required || !excluded);
|
cb.setChecked(required || !excluded);
|
||||||
cb.setEnabled(!required);
|
cb.setEnabled(!required);
|
||||||
cb.setOnCheckedChangeListener(DevReportActivity.this);
|
cb.setOnCheckedChangeListener(DevReportActivity.this);
|
||||||
TextView title = v.findViewById(R.id.title);
|
cb.setText(field.toString());
|
||||||
title.setText(field.toString());
|
|
||||||
TextView content = v.findViewById(R.id.content);
|
TextView content = v.findViewById(R.id.content);
|
||||||
content.setText(value);
|
content.setText(value);
|
||||||
report.addView(v);
|
report.addView(v);
|
||||||
|
|||||||
@@ -89,7 +89,6 @@ import static org.briarproject.briar.api.android.AndroidNotificationManager.GROU
|
|||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_BLOG;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_BLOG;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_FORUM;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_FORUM;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_GROUP;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_GROUP;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_LOCK_SCREEN;
|
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_PRIVATE;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_PRIVATE;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_RINGTONE_NAME;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_RINGTONE_NAME;
|
||||||
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_RINGTONE_URI;
|
import static org.briarproject.briar.api.android.AndroidNotificationManager.PREF_NOTIFY_RINGTONE_URI;
|
||||||
@@ -127,7 +126,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
private SwitchPreference notifyForumPosts;
|
private SwitchPreference notifyForumPosts;
|
||||||
private SwitchPreference notifyBlogPosts;
|
private SwitchPreference notifyBlogPosts;
|
||||||
private SwitchPreference notifyVibration;
|
private SwitchPreference notifyVibration;
|
||||||
private SwitchPreference notifyLockscreen;
|
|
||||||
|
|
||||||
private Preference notifySound;
|
private Preference notifySound;
|
||||||
|
|
||||||
@@ -179,8 +177,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
"pref_key_notify_blog_posts");
|
"pref_key_notify_blog_posts");
|
||||||
notifyVibration = (SwitchPreference) findPreference(
|
notifyVibration = (SwitchPreference) findPreference(
|
||||||
"pref_key_notify_vibration");
|
"pref_key_notify_vibration");
|
||||||
notifyLockscreen = (SwitchPreference) findPreference(
|
|
||||||
"pref_key_notify_lock_screen");
|
|
||||||
notifySound = findPreference("pref_key_notify_sound");
|
notifySound = findPreference("pref_key_notify_sound");
|
||||||
|
|
||||||
language.setOnPreferenceChangeListener(this);
|
language.setOnPreferenceChangeListener(this);
|
||||||
@@ -207,10 +203,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
torMobile.setOnPreferenceChangeListener(this);
|
torMobile.setOnPreferenceChangeListener(this);
|
||||||
screenLock.setOnPreferenceChangeListener(this);
|
screenLock.setOnPreferenceChangeListener(this);
|
||||||
screenLockTimeout.setOnPreferenceChangeListener(this);
|
screenLockTimeout.setOnPreferenceChangeListener(this);
|
||||||
if (SDK_INT >= 21) {
|
|
||||||
notifyLockscreen.setVisible(true);
|
|
||||||
notifyLockscreen.setOnPreferenceChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
findPreference("pref_key_send_feedback").setOnPreferenceClickListener(
|
findPreference("pref_key_send_feedback").setOnPreferenceClickListener(
|
||||||
preference -> {
|
preference -> {
|
||||||
@@ -380,8 +372,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
notifyForumPosts.setOnPreferenceChangeListener(this);
|
notifyForumPosts.setOnPreferenceChangeListener(this);
|
||||||
notifyBlogPosts.setOnPreferenceChangeListener(this);
|
notifyBlogPosts.setOnPreferenceChangeListener(this);
|
||||||
notifyVibration.setOnPreferenceChangeListener(this);
|
notifyVibration.setOnPreferenceChangeListener(this);
|
||||||
notifyLockscreen.setChecked(settings.getBoolean(
|
|
||||||
PREF_NOTIFY_LOCK_SCREEN, false));
|
|
||||||
notifySound.setOnPreferenceClickListener(
|
notifySound.setOnPreferenceClickListener(
|
||||||
pref -> onNotificationSoundClicked());
|
pref -> onNotificationSoundClicked());
|
||||||
String text;
|
String text;
|
||||||
@@ -409,7 +399,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
setupNotificationPreference(notifyBlogPosts, BLOG_CHANNEL_ID,
|
setupNotificationPreference(notifyBlogPosts, BLOG_CHANNEL_ID,
|
||||||
R.string.notify_blog_posts_setting_summary_26);
|
R.string.notify_blog_posts_setting_summary_26);
|
||||||
notifyVibration.setVisible(false);
|
notifyVibration.setVisible(false);
|
||||||
notifyLockscreen.setVisible(false);
|
|
||||||
notifySound.setVisible(false);
|
notifySound.setVisible(false);
|
||||||
}
|
}
|
||||||
setSettingsEnabled(true);
|
setSettingsEnabled(true);
|
||||||
@@ -432,7 +421,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
notifyForumPosts.setEnabled(enabled);
|
notifyForumPosts.setEnabled(enabled);
|
||||||
notifyBlogPosts.setEnabled(enabled);
|
notifyBlogPosts.setEnabled(enabled);
|
||||||
notifyVibration.setEnabled(enabled);
|
notifyVibration.setEnabled(enabled);
|
||||||
notifyLockscreen.setEnabled(enabled);
|
|
||||||
notifySound.setEnabled(enabled);
|
notifySound.setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,10 +541,6 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
|||||||
Settings s = new Settings();
|
Settings s = new Settings();
|
||||||
s.putBoolean(PREF_NOTIFY_VIBRATION, (Boolean) newValue);
|
s.putBoolean(PREF_NOTIFY_VIBRATION, (Boolean) newValue);
|
||||||
storeSettings(s);
|
storeSettings(s);
|
||||||
} else if (preference == notifyLockscreen) {
|
|
||||||
Settings s = new Settings();
|
|
||||||
s.putBoolean(PREF_NOTIFY_LOCK_SCREEN, (Boolean) newValue);
|
|
||||||
storeSettings(s);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.android.sharing;
|
package org.briarproject.briar.android.sharing;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -26,7 +27,7 @@ public abstract class InvitationAdapter<I extends InvitationItem, VH extends Inv
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(VH ui, int position) {
|
public void onBindViewHolder(@NonNull VH ui, int position) {
|
||||||
I item = getItemAt(position);
|
I item = getItemAt(position);
|
||||||
if (item == null) return;
|
if (item == null) return;
|
||||||
ui.onBind(item, listener);
|
ui.onBind(item, listener);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.android.threaded;
|
package org.briarproject.briar.android.threaded;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
@@ -36,8 +37,9 @@ public class ThreadItemAdapter<I extends ThreadItem>
|
|||||||
this.layoutManager = layoutManager;
|
this.layoutManager = layoutManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public BaseThreadItemViewHolder<I> onCreateViewHolder(
|
public BaseThreadItemViewHolder<I> onCreateViewHolder(@NonNull
|
||||||
ViewGroup parent, int viewType) {
|
ViewGroup parent, int viewType) {
|
||||||
View v = LayoutInflater.from(parent.getContext())
|
View v = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_item_thread, parent, false);
|
.inflate(R.layout.list_item_thread, parent, false);
|
||||||
@@ -45,7 +47,8 @@ public class ThreadItemAdapter<I extends ThreadItem>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(BaseThreadItemViewHolder<I> ui, int position) {
|
public void onBindViewHolder(@NonNull BaseThreadItemViewHolder<I> ui,
|
||||||
|
int position) {
|
||||||
I item = items.get(position);
|
I item = items.get(position);
|
||||||
ui.bind(item, listener);
|
ui.bind(item, listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package org.briarproject.briar.android.util;
|
package org.briarproject.briar.android.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
|
||||||
import android.support.annotation.ColorRes;
|
import android.support.annotation.ColorRes;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE;
|
import static android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE;
|
||||||
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
|
|
||||||
|
|
||||||
|
|
||||||
public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
||||||
@@ -22,6 +21,7 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
|||||||
|
|
||||||
setLights(ContextCompat.getColor(context, R.color.briar_green_light),
|
setLights(ContextCompat.getColor(context, R.color.briar_green_light),
|
||||||
750, 500);
|
750, 500);
|
||||||
|
if (SDK_INT >= 21) setVisibility(VISIBILITY_PRIVATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BriarNotificationBuilder setColorRes(@ColorRes int res) {
|
public BriarNotificationBuilder setColorRes(@ColorRes int res) {
|
||||||
@@ -29,13 +29,8 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BriarNotificationBuilder setLockscreenVisibility(String category,
|
public BriarNotificationBuilder setNotificationCategory(String category) {
|
||||||
boolean show) {
|
if (SDK_INT >= 21) setCategory(category);
|
||||||
if (Build.VERSION.SDK_INT >= 21) {
|
|
||||||
setCategory(category);
|
|
||||||
if (show) setVisibility(VISIBILITY_PRIVATE);
|
|
||||||
else setVisibility(VISIBILITY_SECRET);
|
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
|
|||||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||||
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
||||||
import static android.view.KeyEvent.ACTION_DOWN;
|
import static android.view.KeyEvent.ACTION_DOWN;
|
||||||
import static android.view.KeyEvent.ACTION_UP;
|
|
||||||
import static android.view.KeyEvent.KEYCODE_ENTER;
|
import static android.view.KeyEvent.KEYCODE_ENTER;
|
||||||
import static android.view.inputmethod.EditorInfo.IME_NULL;
|
import static android.view.inputmethod.EditorInfo.IME_NULL;
|
||||||
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
||||||
@@ -157,7 +156,7 @@ public class UiUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the runnable when clicking the link in the textView's text.
|
* Executes the runnable when clicking the link in the textView's text.
|
||||||
*
|
* <p>
|
||||||
* Attention: This assumes that there's only <b>one</b> link in the text.
|
* Attention: This assumes that there's only <b>one</b> link in the text.
|
||||||
*/
|
*/
|
||||||
public static void onSingleLinkClick(TextView textView, Runnable runnable) {
|
public static void onSingleLinkClick(TextView textView, Runnable runnable) {
|
||||||
|
|||||||
@@ -5,11 +5,10 @@ import android.content.res.TypedArray;
|
|||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.support.annotation.DimenRes;
|
import android.support.annotation.DimenRes;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
import android.support.constraint.ConstraintLayout;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.RelativeLayout;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
import org.briarproject.bramble.api.identity.Author;
|
||||||
@@ -30,7 +29,7 @@ import static org.briarproject.bramble.api.identity.Author.Status.OURSELVES;
|
|||||||
import static org.briarproject.briar.android.util.UiUtils.resolveAttribute;
|
import static org.briarproject.briar.android.util.UiUtils.resolveAttribute;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public class AuthorView extends RelativeLayout {
|
public class AuthorView extends ConstraintLayout {
|
||||||
|
|
||||||
public static final int NORMAL = 0;
|
public static final int NORMAL = 0;
|
||||||
public static final int REBLOGGER = 1;
|
public static final int REBLOGGER = 1;
|
||||||
@@ -133,32 +132,24 @@ public class AuthorView extends RelativeLayout {
|
|||||||
date.setVisibility(VISIBLE);
|
date.setVisibility(VISIBLE);
|
||||||
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
||||||
setTextSize(authorName, R.dimen.text_size_small);
|
setTextSize(authorName, R.dimen.text_size_small);
|
||||||
setCenterVertical(authorName, false);
|
|
||||||
setCenterVertical(trustIndicator, false);
|
|
||||||
break;
|
break;
|
||||||
case REBLOGGER:
|
case REBLOGGER:
|
||||||
avatarIcon.setVisibility(VISIBLE);
|
avatarIcon.setVisibility(VISIBLE);
|
||||||
date.setVisibility(VISIBLE);
|
date.setVisibility(VISIBLE);
|
||||||
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
||||||
setTextSize(authorName, R.dimen.text_size_small);
|
setTextSize(authorName, R.dimen.text_size_small);
|
||||||
setCenterVertical(authorName, false);
|
|
||||||
setCenterVertical(trustIndicator, false);
|
|
||||||
break;
|
break;
|
||||||
case COMMENTER:
|
case COMMENTER:
|
||||||
avatarIcon.setVisibility(INVISIBLE);
|
avatarIcon.setVisibility(INVISIBLE);
|
||||||
date.setVisibility(VISIBLE);
|
date.setVisibility(VISIBLE);
|
||||||
setAvatarSize(R.dimen.blogs_avatar_comment_size);
|
setAvatarSize(R.dimen.blogs_avatar_comment_size);
|
||||||
setTextSize(authorName, R.dimen.text_size_tiny);
|
setTextSize(authorName, R.dimen.text_size_tiny);
|
||||||
setCenterVertical(authorName, false);
|
|
||||||
setCenterVertical(trustIndicator, false);
|
|
||||||
break;
|
break;
|
||||||
case LIST:
|
case LIST:
|
||||||
avatarIcon.setVisibility(INVISIBLE);
|
avatarIcon.setVisibility(INVISIBLE);
|
||||||
date.setVisibility(GONE);
|
date.setVisibility(GONE);
|
||||||
setAvatarSize(R.dimen.listitem_picture_size_small);
|
setAvatarSize(R.dimen.listitem_picture_size_small);
|
||||||
setTextSize(authorName, R.dimen.text_size_medium);
|
setTextSize(authorName, R.dimen.text_size_medium);
|
||||||
setCenterVertical(authorName, true);
|
|
||||||
setCenterVertical(trustIndicator, true);
|
|
||||||
break;
|
break;
|
||||||
case RSS_FEED:
|
case RSS_FEED:
|
||||||
avatarIcon.setVisibility(INVISIBLE);
|
avatarIcon.setVisibility(INVISIBLE);
|
||||||
@@ -166,8 +157,6 @@ public class AuthorView extends RelativeLayout {
|
|||||||
avatar.setImageResource(R.drawable.ic_rss_feed);
|
avatar.setImageResource(R.drawable.ic_rss_feed);
|
||||||
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
setAvatarSize(R.dimen.blogs_avatar_normal_size);
|
||||||
setTextSize(authorName, R.dimen.text_size_small);
|
setTextSize(authorName, R.dimen.text_size_small);
|
||||||
setCenterVertical(authorName, false);
|
|
||||||
setCenterVertical(trustIndicator, false);
|
|
||||||
break;
|
break;
|
||||||
case RSS_FEED_REBLOGGED:
|
case RSS_FEED_REBLOGGED:
|
||||||
avatarIcon.setVisibility(INVISIBLE);
|
avatarIcon.setVisibility(INVISIBLE);
|
||||||
@@ -175,8 +164,6 @@ public class AuthorView extends RelativeLayout {
|
|||||||
avatar.setImageResource(R.drawable.ic_rss_feed);
|
avatar.setImageResource(R.drawable.ic_rss_feed);
|
||||||
setAvatarSize(R.dimen.blogs_avatar_comment_size);
|
setAvatarSize(R.dimen.blogs_avatar_comment_size);
|
||||||
setTextSize(authorName, R.dimen.text_size_tiny);
|
setTextSize(authorName, R.dimen.text_size_tiny);
|
||||||
setCenterVertical(authorName, false);
|
|
||||||
setCenterVertical(trustIndicator, false);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,10 +181,4 @@ public class AuthorView extends RelativeLayout {
|
|||||||
v.setTextSize(COMPLEX_UNIT_PX, textSize);
|
v.setTextSize(COMPLEX_UNIT_PX, textSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setCenterVertical(View v, boolean center) {
|
|
||||||
LayoutParams params = (LayoutParams) v.getLayoutParams();
|
|
||||||
params.addRule(CENTER_VERTICAL, center ? RelativeLayout.TRUE : 0);
|
|
||||||
v.setLayoutParams(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ public class QrCodeView extends FrameLayout {
|
|||||||
private boolean fullscreen = false;
|
private boolean fullscreen = false;
|
||||||
private FullscreenListener listener;
|
private FullscreenListener listener;
|
||||||
|
|
||||||
public QrCodeView(@NonNull Context context,
|
public QrCodeView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
@Nullable AttributeSet attrs) {
|
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
LayoutInflater inflater = (LayoutInflater) context
|
LayoutInflater inflater = (LayoutInflater) context
|
||||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package org.briarproject.briar.android.view;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.v7.widget.AppCompatTextView;
|
import android.support.v7.widget.AppCompatTextView;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
@@ -11,13 +10,11 @@ import android.view.LayoutInflater;
|
|||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.identity.Author;
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import de.hdodenhof.circleimageview.CircleImageView;
|
import de.hdodenhof.circleimageview.CircleImageView;
|
||||||
import im.delight.android.identicons.IdenticonDrawable;
|
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public class TextAvatarView extends FrameLayout {
|
public class TextAvatarView extends FrameLayout {
|
||||||
@@ -35,7 +32,6 @@ public class TextAvatarView extends FrameLayout {
|
|||||||
character = findViewById(R.id.textAvatarView);
|
character = findViewById(R.id.textAvatarView);
|
||||||
background = findViewById(R.id.avatarBackground);
|
background = findViewById(R.id.avatarBackground);
|
||||||
badge = findViewById(R.id.unreadCountView);
|
badge = findViewById(R.id.unreadCountView);
|
||||||
badge.setVisibility(INVISIBLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextAvatarView(Context context) {
|
public TextAvatarView(Context context) {
|
||||||
@@ -72,10 +68,4 @@ public class TextAvatarView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthorAvatar(Author author) {
|
|
||||||
Drawable drawable = new IdenticonDrawable(author.getId().getBytes());
|
|
||||||
background.setImageDrawable(drawable);
|
|
||||||
character.setVisibility(GONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,11 @@ public class TextInputView extends KeyboardAwareLinearLayout {
|
|||||||
public TextInputView(Context context, @Nullable AttributeSet attrs,
|
public TextInputView(Context context, @Nullable AttributeSet attrs,
|
||||||
int defStyleAttr) {
|
int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
BriarApplication app =
|
if (!isInEditMode()) {
|
||||||
(BriarApplication) context.getApplicationContext();
|
BriarApplication app =
|
||||||
app.getApplicationComponent().inject(this);
|
(BriarApplication) context.getApplicationContext();
|
||||||
|
app.getApplicationComponent().inject(this);
|
||||||
|
}
|
||||||
setOrientation(VERTICAL);
|
setOrientation(VERTICAL);
|
||||||
setLayoutTransition(new LayoutTransition());
|
setLayoutTransition(new LayoutTransition());
|
||||||
inflateLayout(context);
|
inflateLayout(context);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ public class UnreadMessageButton extends FrameLayout {
|
|||||||
setDirection(direction);
|
setDirection(direction);
|
||||||
attributes.recycle();
|
attributes.recycle();
|
||||||
|
|
||||||
setUnreadCount(0);
|
if (!isInEditMode()) setUnreadCount(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setDirection(int direction) {
|
private void setDirection(int direction) {
|
||||||
@@ -64,11 +64,11 @@ public class UnreadMessageButton extends FrameLayout {
|
|||||||
|
|
||||||
public void setUnreadCount(int count) {
|
public void setUnreadCount(int count) {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
setVisibility(INVISIBLE);
|
fab.hide();
|
||||||
|
unread.setVisibility(INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
// FIXME: Use animations when upgrading to support library 24.2.0
|
fab.show();
|
||||||
// https://code.google.com/p/android/issues/detail?id=216469
|
unread.setVisibility(VISIBLE);
|
||||||
setVisibility(VISIBLE);
|
|
||||||
unread.setText(String.valueOf(count));
|
unread.setText(String.valueOf(count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.Intent;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.DialogFragment;
|
import android.support.v4.app.DialogFragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -42,8 +43,8 @@ public class LinkDialogFragment extends DialogFragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
Bundle savedInstanceState) {
|
ViewGroup container, Bundle savedInstanceState) {
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_link_dialog, container,
|
View v = inflater.inflate(R.layout.fragment_link_dialog, container,
|
||||||
false);
|
false);
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ public interface AndroidNotificationManager {
|
|||||||
String PREF_NOTIFY_RINGTONE_NAME = "notifyRingtoneName";
|
String PREF_NOTIFY_RINGTONE_NAME = "notifyRingtoneName";
|
||||||
String PREF_NOTIFY_RINGTONE_URI = "notifyRingtoneUri";
|
String PREF_NOTIFY_RINGTONE_URI = "notifyRingtoneUri";
|
||||||
String PREF_NOTIFY_VIBRATION = "notifyVibration";
|
String PREF_NOTIFY_VIBRATION = "notifyVibration";
|
||||||
String PREF_NOTIFY_LOCK_SCREEN = "notifyLockScreen";
|
|
||||||
|
|
||||||
// Notification IDs
|
// Notification IDs
|
||||||
int ONGOING_NOTIFICATION_ID = 1;
|
int ONGOING_NOTIFICATION_ID = 1;
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (C) 2014 Open Whisper Systems
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.thoughtcrime.securesms.components.util;
|
|
||||||
|
|
||||||
public interface FutureTaskListener<V> {
|
|
||||||
void onSuccess(V result);
|
|
||||||
|
|
||||||
void onFailure(Throwable error);
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2014 Open Whisper Systems
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.thoughtcrime.securesms.components.util;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.Callable;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
import java.util.concurrent.FutureTask;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class ListenableFutureTask<V> extends FutureTask<V> {
|
|
||||||
|
|
||||||
private final List<FutureTaskListener<V>> listeners = new LinkedList<>();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private final Object identifier;
|
|
||||||
|
|
||||||
public ListenableFutureTask(Callable<V> callable) {
|
|
||||||
this(callable, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ListenableFutureTask(Callable<V> callable,
|
|
||||||
@Nullable Object identifier) {
|
|
||||||
super(callable);
|
|
||||||
this.identifier = identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ListenableFutureTask(V result) {
|
|
||||||
this(result, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private ListenableFutureTask(V result, @Nullable Object identifier) {
|
|
||||||
super(() -> result);
|
|
||||||
this.identifier = identifier;
|
|
||||||
this.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void addListener(FutureTaskListener<V> listener) {
|
|
||||||
if (this.isDone()) {
|
|
||||||
callback(listener);
|
|
||||||
} else {
|
|
||||||
this.listeners.add(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void removeListener(FutureTaskListener<V> listener) {
|
|
||||||
this.listeners.remove(listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected synchronized void done() {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void callback() {
|
|
||||||
for (FutureTaskListener<V> listener : listeners) {
|
|
||||||
callback(listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void callback(FutureTaskListener<V> listener) {
|
|
||||||
if (listener != null) {
|
|
||||||
try {
|
|
||||||
listener.onSuccess(get());
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
} catch (ExecutionException e) {
|
|
||||||
listener.onFailure(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object other) {
|
|
||||||
if (other != null && other instanceof ListenableFutureTask &&
|
|
||||||
this.identifier != null) {
|
|
||||||
return identifier.equals(other);
|
|
||||||
} else {
|
|
||||||
return super.equals(other);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
if (identifier != null) return identifier.hashCode();
|
|
||||||
else return super.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="oval">
|
android:shape="oval">
|
||||||
|
|
||||||
<solid android:color="@color/window_background"/>
|
<solid android:color="@color/thread_item_background"/>
|
||||||
|
|
||||||
<stroke
|
<stroke
|
||||||
android:width="2dp"
|
android:width="@dimen/forum_nested_line_width"
|
||||||
android:color="@color/thread_indicator"/>
|
android:color="@color/thread_indicator"/>
|
||||||
</shape>
|
</shape>
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="16dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="16dp"
|
android:width="16dp"
|
||||||
android:viewportHeight="24.0"
|
android:height="16dp"
|
||||||
android:viewportWidth="24.0">
|
android:viewportHeight="24.0"
|
||||||
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zm4.24,-1.41L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/>
|
android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zm4.24,-1.41L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/>
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<vector android:height="16dp"
|
<vector
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="16dp"
|
||||||
<path android:fillColor="#FFFFFFFF" android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zm4.24,-1.41L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/>
|
android:height="16dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:viewportWidth="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M18,7l-1.41,-1.41 -6.34,6.34 1.41,1.41L18,7zm4.24,-1.41L11.66,16.17 7.48,12l-1.41,1.41L11.66,19l12,-12 -1.42,-1.41zM0.41,13.41L6,19l1.41,-1.41L1.83,12 0.41,13.41z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="16dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="16dp"
|
android:width="16dp"
|
||||||
android:viewportHeight="24.0"
|
android:height="16dp"
|
||||||
android:viewportWidth="24.0">
|
android:viewportHeight="24.0"
|
||||||
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FF000000"
|
android:fillColor="#FF000000"
|
||||||
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<vector android:height="16dp"
|
<vector
|
||||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="16dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:width="16dp"
|
||||||
<path android:fillColor="#FFFFFFFF" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
android:height="16dp"
|
||||||
|
android:viewportHeight="24.0"
|
||||||
|
android:viewportWidth="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFFFF"
|
||||||
|
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
||||||
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_small"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_inner"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_big"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_outer"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_bottom"
|
android:bottom="@dimen/message_bubble_padding_bottom"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="0dp"
|
android:bottomLeftRadius="0dp"
|
||||||
android:bottomRightRadius="0dp"
|
android:bottomRightRadius="0dp"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_small"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_inner"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_big"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_outer"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_top"
|
android:bottom="@dimen/message_bubble_padding_top"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
||||||
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_big"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_outer"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_small"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_inner"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_bottom"
|
android:bottom="@dimen/message_bubble_padding_bottom"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="0dp"
|
android:bottomLeftRadius="0dp"
|
||||||
android:bottomRightRadius="0dp"
|
android:bottomRightRadius="0dp"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_big"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_outer"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_small"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_inner"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_top"
|
android:bottom="@dimen/message_bubble_padding_top"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
||||||
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_small"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_inner"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_big"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_outer"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_bottom"
|
android:bottom="@dimen/message_bubble_padding_bottom"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<corners
|
<corners
|
||||||
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
android:bottomLeftRadius="@dimen/message_bubble_radius_big"
|
||||||
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
android:bottomRightRadius="@dimen/message_bubble_radius_big"
|
||||||
android:topLeftRadius="@dimen/message_bubble_radius_big"
|
android:topLeftRadius="@dimen/message_bubble_radius_top_outer"
|
||||||
android:topRightRadius="@dimen/message_bubble_radius_small"/>
|
android:topRightRadius="@dimen/message_bubble_radius_top_inner"/>
|
||||||
<padding
|
<padding
|
||||||
android:bottom="@dimen/message_bubble_padding_bottom"
|
android:bottom="@dimen/message_bubble_padding_bottom"
|
||||||
android:left="@dimen/message_bubble_padding_sides"
|
android:left="@dimen/message_bubble_padding_sides"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="400dp"
|
android:width="400dp"
|
||||||
android:height="100dp"
|
android:height="100dp"
|
||||||
|
android:autoMirrored="true"
|
||||||
android:viewportHeight="49.5"
|
android:viewportHeight="49.5"
|
||||||
android:viewportWidth="194.8">
|
android:viewportWidth="194.8">
|
||||||
<path
|
<path
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
|
android:autoMirrored="true"
|
||||||
android:viewportHeight="24.0"
|
android:viewportHeight="24.0"
|
||||||
android:viewportWidth="24.0">
|
android:viewportWidth="24.0">
|
||||||
<path
|
<path
|
||||||
|
|||||||
@@ -26,7 +26,8 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="@id/explanationText"
|
app:layout_constraintBottom_toBottomOf="@id/explanationText"
|
||||||
app:layout_constraintEnd_toStartOf="@id/explanationText"
|
app:layout_constraintEnd_toStartOf="@id/explanationText"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:ignore="ContentDescription"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/explanationImage"
|
android:id="@+id/explanationImage"
|
||||||
@@ -34,8 +35,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
android:paddingLeft="@dimen/margin_large"
|
android:paddingEnd="@dimen/margin_large"
|
||||||
android:paddingRight="@dimen/margin_large"
|
android:paddingStart="@dimen/margin_large"
|
||||||
android:paddingTop="@dimen/margin_large"
|
android:paddingTop="@dimen/margin_large"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/qr_code_explanation"
|
android:src="@drawable/qr_code_explanation"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".android.login.ChangePasswordActivity">
|
tools:context=".android.login.ChangePasswordActivity">
|
||||||
|
|
||||||
<RelativeLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
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"
|
||||||
@@ -22,9 +22,11 @@
|
|||||||
android:id="@+id/current_password_entry_wrapper"
|
android:id="@+id/current_password_entry_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
app:hintEnabled="false"
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:passwordToggleEnabled="true">
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@@ -40,10 +42,11 @@
|
|||||||
android:id="@+id/new_password_entry_wrapper"
|
android:id="@+id/new_password_entry_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/current_password_entry_wrapper"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
app:hintEnabled="false"
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/current_password_entry_wrapper"
|
||||||
app:passwordToggleEnabled="true">
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@@ -59,10 +62,11 @@
|
|||||||
android:id="@+id/new_password_confirm_wrapper"
|
android:id="@+id/new_password_confirm_wrapper"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/new_password_entry_wrapper"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
app:hintEnabled="false"
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/new_password_entry_wrapper"
|
||||||
app:passwordToggleEnabled="true">
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@@ -79,30 +83,33 @@
|
|||||||
android:id="@+id/strength_meter"
|
android:id="@+id/strength_meter"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/new_password_confirm_wrapper"
|
android:visibility="invisible"
|
||||||
android:layout_centerHorizontal="true"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
android:visibility="invisible"/>
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/new_password_confirm_wrapper"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/change_password"
|
android:id="@+id/change_password"
|
||||||
style="@style/BriarButton"
|
style="@style/BriarButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/strength_meter"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/change_password"
|
android:text="@string/change_password"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/strength_meter"
|
||||||
tools:enabled="true"/>
|
tools:enabled="true"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progress_wheel"
|
android:id="@+id/progress_wheel"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignTop="@id/change_password"
|
android:visibility="invisible"
|
||||||
android:layout_centerHorizontal="true"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
android:visibility="invisible"/>
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/change_password"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@@ -20,20 +20,23 @@
|
|||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<include layout="@layout/contact_avatar_status"/>
|
<include layout="@layout/contact_avatar_status"/>
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
android:id="@+id/contactName"
|
android:id="@+id/contactName"
|
||||||
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
|
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title.Inverse"
|
||||||
android:textColor="@color/action_bar_text"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginLeft="@dimen/margin_medium"
|
android:layout_marginLeft="@dimen/margin_medium"
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
tools:text="Contact Name"/>
|
android:maxLines="1"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:textColor="@color/action_bar_text"
|
||||||
|
tools:text="Contact Name of someone who chose a long name"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -1,186 +1,224 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<LinearLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/report_form"
|
android:id="@+id/report_form"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
|
||||||
android:visibility="visible"
|
android:visibility="visible"
|
||||||
tools:context=".android.reporting.DevReportActivity">
|
tools:context=".android.reporting.DevReportActivity"
|
||||||
|
tools:visibility="invisible">
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
<include
|
||||||
|
android:id="@+id/appBar"
|
||||||
|
layout="@layout/toolbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/user_comment_layout"
|
||||||
android:layout_height="match_parent"
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/margin_large"
|
android:layout_marginEnd="@dimen/margin_large"
|
||||||
android:layout_marginLeft="@dimen/margin_large"
|
android:layout_marginLeft="@dimen/margin_large"
|
||||||
android:layout_marginRight="@dimen/margin_large"
|
android:layout_marginRight="@dimen/margin_large"
|
||||||
android:layout_marginStart="@dimen/margin_large">
|
android:layout_marginStart="@dimen/margin_large"
|
||||||
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appBar">
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputEditText
|
||||||
android:id="@+id/user_comment_layout"
|
android:id="@+id/user_comment"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputEditText
|
|
||||||
android:id="@+id/user_comment"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:inputType="textMultiLine|textCapSentences"
|
|
||||||
tools:hint="@string/describe_crash"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
|
||||||
android:id="@+id/user_email_layout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/user_comment_layout"
|
android:inputType="textMultiLine|textCapSentences"
|
||||||
android:layout_marginTop="@dimen/margin_small">
|
android:maxLines="5"
|
||||||
|
tools:hint="@string/describe_crash"/>
|
||||||
|
|
||||||
<android.support.design.widget.TextInputEditText
|
</android.support.design.widget.TextInputLayout>
|
||||||
android:id="@+id/user_email"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:hint="@string/optional_contact_email"
|
|
||||||
android:inputType="textEmailAddress"
|
|
||||||
android:maxLines="1"/>
|
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/user_email_layout"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/margin_large"
|
||||||
|
android:layout_marginLeft="@dimen/margin_large"
|
||||||
|
android:layout_marginRight="@dimen/margin_large"
|
||||||
|
android:layout_marginStart="@dimen/margin_large"
|
||||||
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/user_comment_layout">
|
||||||
|
|
||||||
<CheckBox
|
<android.support.design.widget.TextInputEditText
|
||||||
android:id="@+id/include_debug_report"
|
android:id="@+id/user_email"
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_below="@+id/user_email_layout"
|
|
||||||
android:layout_marginTop="@dimen/margin_small"
|
|
||||||
android:layout_toLeftOf="@+id/chevron"
|
|
||||||
android:checked="false"
|
|
||||||
android:text="@string/include_debug_report_crash"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/chevron"
|
|
||||||
style="@style/BriarButtonFlat.Positive"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_alignTop="@+id/include_debug_report"
|
|
||||||
android:text="@string/show"/>
|
|
||||||
|
|
||||||
<ScrollView
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/include_debug_report"
|
android:hint="@string/optional_contact_email"
|
||||||
android:layout_marginTop="@dimen/margin_small">
|
android:inputType="textEmailAddress"
|
||||||
|
android:maxLines="1"/>
|
||||||
|
|
||||||
<LinearLayout
|
</android.support.design.widget.TextInputLayout>
|
||||||
android:id="@+id/report_content"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingBottom="@dimen/listitem_height_one_line_avatar"
|
|
||||||
android:paddingEnd="@dimen/margin_large"
|
|
||||||
android:paddingLeft="@dimen/margin_large"
|
|
||||||
android:paddingRight="@dimen/margin_large"
|
|
||||||
android:paddingStart="@dimen/margin_large"
|
|
||||||
android:paddingTop="@dimen/margin_small"
|
|
||||||
android:visibility="gone"/>
|
|
||||||
|
|
||||||
</ScrollView>
|
<CheckBox
|
||||||
|
android:id="@+id/include_debug_report"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/margin_large"
|
||||||
|
android:layout_marginStart="@dimen/margin_large"
|
||||||
|
android:checked="false"
|
||||||
|
android:text="@string/include_debug_report_crash"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/chevron"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/chevron"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/chevron"/>
|
||||||
|
|
||||||
<ProgressBar
|
<Button
|
||||||
android:id="@+id/progress_wheel"
|
android:id="@+id/chevron"
|
||||||
style="?android:attr/progressBarStyleLarge"
|
style="@style/BriarButtonFlat.Positive"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/show"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/user_email_layout"/>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:id="@+id/report_scroll"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/include_debug_report">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/report_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:gravity="center_horizontal"
|
||||||
android:layout_below="@+id/include_debug_report"
|
android:orientation="vertical"
|
||||||
android:layout_centerHorizontal="true"
|
android:paddingBottom="@dimen/listitem_height_one_line_avatar"
|
||||||
android:indeterminate="true"
|
android:paddingEnd="@dimen/margin_large"
|
||||||
android:visibility="gone"/>
|
android:paddingStart="@dimen/margin_large"
|
||||||
|
android:paddingTop="@dimen/margin_small"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</ScrollView>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<RelativeLayout
|
<ProgressBar
|
||||||
|
android:id="@+id/progress_wheel"
|
||||||
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:indeterminate="true"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/include_debug_report"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/request_report"
|
android:id="@+id/request_report"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:clickable="true"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="@dimen/margin_large"
|
android:padding="@dimen/margin_large"
|
||||||
android:visibility="invisible">
|
android:visibility="invisible"
|
||||||
|
tools:visibility="visible">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/crashed"
|
android:id="@+id/crashed"
|
||||||
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_large"
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/briar_crashed"
|
android:text="@string/briar_crashed"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_large"/>
|
android:textSize="@dimen/text_size_large"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/fault"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
|
tools:layout_editor_absoluteY="8dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/fault"
|
android:id="@+id/fault"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/crashed"
|
|
||||||
android:layout_marginTop="@dimen/margin_large"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/not_your_fault"
|
android:text="@string/not_your_fault"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_large"/>
|
android:textSize="@dimen/text_size_large"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/pleaseSend"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/crashed"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/pleaseSend"
|
android:id="@+id/pleaseSend"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/fault"
|
|
||||||
android:layout_marginTop="@dimen/margin_large"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/please_send_report"
|
android:text="@string/please_send_report"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_large"/>
|
android:textSize="@dimen/text_size_large"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/encrypted"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/fault"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/encrypted"
|
android:id="@+id/encrypted"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/pleaseSend"
|
|
||||||
android:layout_marginBottom="@dimen/margin_large"
|
|
||||||
android:layout_marginTop="@dimen/margin_large"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/report_is_encrypted"
|
android:text="@string/report_is_encrypted"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_large"/>
|
android:textSize="@dimen/text_size_large"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/acceptButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/pleaseSend"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/declineButton"
|
android:id="@+id/declineButton"
|
||||||
style="@style/BriarButtonFlat.Negative"
|
style="@style/BriarButtonFlat.Negative"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
android:text="@string/close"
|
||||||
android:layout_below="@+id/encrypted"
|
app:layout_constraintBottom_toBottomOf="@+id/acceptButton"
|
||||||
android:text="@string/close"/>
|
app:layout_constraintEnd_toStartOf="@+id/acceptButton"
|
||||||
|
app:layout_constraintHorizontal_weight="1"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/acceptButton"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/acceptButton"
|
android:id="@+id/acceptButton"
|
||||||
style="@style/BriarButtonFlat.Positive"
|
style="@style/BriarButtonFlat.Positive"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:layout_below="@+id/encrypted"
|
android:text="@string/send_report"
|
||||||
android:text="@string/send_report"/>
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_weight="1"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/declineButton"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/encrypted"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
@@ -2,57 +2,75 @@
|
|||||||
<android.support.v4.widget.DrawerLayout
|
<android.support.v4.widget.DrawerLayout
|
||||||
android:id="@+id/drawer_layout"
|
android:id="@+id/drawer_layout"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".android.navdrawer.NavDrawerActivity">
|
tools:context=".android.navdrawer.NavDrawerActivity">
|
||||||
|
|
||||||
<!-- The first child(root) is the content view -->
|
<!-- The first child(root) is the content view -->
|
||||||
<LinearLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
|
android:id="@+id/constraintLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<include layout="@layout/toolbar"/>
|
<include
|
||||||
|
android:id="@+id/appBar"
|
||||||
|
layout="@layout/toolbar"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<RelativeLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/expiryWarning"
|
android:id="@+id/expiryWarning"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/briar_warning_background"
|
android:background="@color/briar_warning_background"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="@dimen/margin_medium"
|
android:padding="@dimen/margin_medium"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/appBar"
|
||||||
tools:visibility="visible">
|
tools:visibility="visible">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/expiryWarningText"
|
android:id="@+id/expiryWarningText"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_toLeftOf="@+id/expiryWarningClose"
|
|
||||||
android:text="@plurals/expiry_warning"
|
android:text="@plurals/expiry_warning"
|
||||||
android:textColor="@color/briar_text_primary_inverse"
|
android:textColor="@color/briar_text_primary_inverse"
|
||||||
android:textSize="@dimen/text_size_small"/>
|
android:textSize="@dimen/text_size_small"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/expiryWarningClose"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/expiryWarningClose"
|
android:id="@+id/expiryWarningClose"
|
||||||
android:layout_width="24dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="0dp"
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_centerInParent="true"
|
|
||||||
android:contentDescription="@string/close"
|
android:contentDescription="@string/close"
|
||||||
android:scaleType="center"
|
android:scaleType="center"
|
||||||
android:src="@drawable/ic_close"
|
android:src="@drawable/ic_close"
|
||||||
android:tint="@color/briar_text_tertiary_inverse"/>
|
android:tint="@color/briar_text_tertiary_inverse"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/fragmentContainer"
|
android:id="@+id/fragmentContainer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/expiryWarning"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
<!-- The second child is the menu -->
|
<!-- The second child is the menu -->
|
||||||
<include
|
<include
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="8dp"
|
android:layout_margin="8dp"
|
||||||
|
android:gravity="center"
|
||||||
android:paddingLeft="@dimen/margin_large"
|
android:paddingLeft="@dimen/margin_large"
|
||||||
android:paddingRight="@dimen/margin_large"
|
android:paddingRight="@dimen/margin_large"
|
||||||
android:text="@string/startup_open_database"
|
android:text="@string/startup_open_database"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|||||||
@@ -5,24 +5,20 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<RelativeLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:padding="@dimen/margin_activity_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">
|
|
||||||
|
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
android:id="@+id/password_layout"
|
android:id="@+id/password_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
app:errorEnabled="true"
|
app:errorEnabled="true"
|
||||||
app:hintEnabled="false"
|
app:hintEnabled="false"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:passwordToggleEnabled="true">
|
app:passwordToggleEnabled="true">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
@@ -40,31 +36,36 @@
|
|||||||
style="@style/BriarButton"
|
style="@style/BriarButton"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/password_layout"
|
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:onClick="onSignInClick"
|
android:onClick="onSignInClick"
|
||||||
android:text="@string/sign_in_button"/>
|
android:text="@string/sign_in_button"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/password_layout"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progress_wheel"
|
android:id="@+id/progress_wheel"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignTop="@id/btn_sign_in"
|
android:visibility="invisible"
|
||||||
android:layout_centerHorizontal="true"
|
app:layout_constraintBottom_toBottomOf="@+id/btn_sign_in"
|
||||||
android:visibility="invisible"/>
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/btn_sign_in"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/btn_sign_in"
|
|
||||||
android:layout_centerHorizontal="true"
|
|
||||||
android:layout_marginTop="@dimen/margin_large"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
android:onClick="onForgottenPasswordClick"
|
android:onClick="onForgottenPasswordClick"
|
||||||
android:text="@string/forgotten_password"
|
android:text="@string/forgotten_password"
|
||||||
android:textColor="?android:attr/textColorLink"/>
|
android:textColor="?android:attr/textColorLink"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/btn_sign_in"/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="@dimen/margin_small"
|
android:padding="@dimen/margin_medium"
|
||||||
tools:context=".android.blog.RssFeedImportActivity">
|
tools:context=".android.blog.RssFeedImportActivity">
|
||||||
|
|
||||||
<android.support.v7.widget.CardView
|
<android.support.v7.widget.CardView
|
||||||
@@ -35,7 +35,8 @@
|
|||||||
android:id="@+id/importButton"
|
android:id="@+id/importButton"
|
||||||
style="@style/BriarButton"
|
style="@style/BriarButton"
|
||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/blogs_rss_feeds_import_button"/>
|
android:text="@string/blogs_rss_feeds_import_button"
|
||||||
|
tools:enabled="true"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:visibility="gone"/>
|
android:visibility="gone"
|
||||||
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
|||||||
@@ -1,178 +1,179 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<ScrollView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent"
|
||||||
|
android:fillViewport="true"
|
||||||
|
android:padding="@dimen/margin_medium"
|
||||||
|
tools:ignore="HardcodedText">
|
||||||
|
|
||||||
<ScrollView
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content">
|
||||||
android:padding="8dp"
|
|
||||||
tools:ignore="HardcodedText">
|
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<TextView
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
android:id="@+id/textViewContacts"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="@dimen/margin_medium"
|
||||||
|
android:text="Number of contacts"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<TextView
|
<SeekBar
|
||||||
android:id="@+id/textViewContacts"
|
android:id="@+id/seekBarContacts"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_medium"
|
android:max="49"
|
||||||
android:text="Number of contacts"
|
android:progress="20"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintEnd_toStartOf="@+id/textViewContactsSb"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewContacts"/>
|
||||||
|
|
||||||
<SeekBar
|
<TextView
|
||||||
android:id="@+id/seekBarContacts"
|
android:id="@+id/textViewContactsSb"
|
||||||
android:layout_width="0dp"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:max="49"
|
android:ems="2"
|
||||||
android:progress="20"
|
android:text="20"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/textViewContactsSb"
|
app:layout_constraintBottom_toBottomOf="@+id/seekBarContacts"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textViewContacts"/>
|
app:layout_constraintTop_toBottomOf="@+id/textViewContacts"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewContactsSb"
|
android:id="@+id/textViewMessages"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="2"
|
android:layout_margin="@dimen/margin_medium"
|
||||||
android:text="20"
|
android:text="Number of messages per contact"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/seekBarContacts"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintTop_toBottomOf="@+id/seekBarContacts"/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/seekBarMessages"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="50"
|
||||||
|
android:paddingTop="5dp"
|
||||||
|
android:progress="20"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/textViewMessagesSb"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewMessages"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewMessages"
|
android:id="@+id/textViewMessagesSb"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_medium"
|
android:ems="2"
|
||||||
android:text="Number of messages per contact"
|
android:text="20"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintBottom_toBottomOf="@+id/seekBarMessages"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/seekBarContacts"/>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewMessages"/>
|
||||||
|
|
||||||
<SeekBar
|
<TextView
|
||||||
android:id="@+id/seekBarMessages"
|
android:id="@+id/textViewBlogPosts"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:max="50"
|
android:layout_margin="@dimen/margin_medium"
|
||||||
android:paddingTop="5dp"
|
android:text="Number of blog posts"
|
||||||
android:progress="15"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/textViewMessagesSb"
|
app:layout_constraintTop_toBottomOf="@+id/seekBarMessages"/>
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textViewMessages"/>
|
|
||||||
|
|
||||||
<TextView
|
<SeekBar
|
||||||
android:id="@+id/textViewMessagesSb"
|
android:id="@+id/seekBarBlogPosts"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="2"
|
android:max="50"
|
||||||
android:text="20"
|
android:paddingTop="5dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/seekBarMessages"
|
android:progress="20"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toStartOf="@+id/TextViewBlogPostsSb"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewBlogPosts"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewBlogPosts"
|
android:id="@+id/TextViewBlogPostsSb"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_medium"
|
android:ems="2"
|
||||||
android:text="Number of blog posts"
|
android:text="20"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintBottom_toBottomOf="@+id/seekBarBlogPosts"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/seekBarMessages"/>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewBlogPosts"/>
|
||||||
|
|
||||||
<SeekBar
|
<TextView
|
||||||
android:id="@+id/seekBarBlogPosts"
|
android:id="@+id/textViewForums"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:max="50"
|
android:layout_margin="@dimen/margin_medium"
|
||||||
android:paddingTop="5dp"
|
android:text="Number of forums"
|
||||||
android:progress="30"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/TextViewBlogPostsSb"
|
app:layout_constraintTop_toBottomOf="@+id/seekBarBlogPosts"/>
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textViewBlogPosts"/>
|
|
||||||
|
|
||||||
<TextView
|
<SeekBar
|
||||||
android:id="@+id/TextViewBlogPostsSb"
|
android:id="@+id/seekBarForums"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="2"
|
android:max="50"
|
||||||
android:text="20"
|
android:paddingTop="5dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/seekBarBlogPosts"
|
android:progress="5"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toStartOf="@+id/TextViewForumsSb"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewForums"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewForums"
|
android:id="@+id/TextViewForumsSb"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_medium"
|
android:ems="2"
|
||||||
android:text="Number of forums"
|
android:text="5"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintBottom_toBottomOf="@+id/seekBarForums"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/seekBarBlogPosts"/>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewForums"/>
|
||||||
|
|
||||||
<SeekBar
|
<TextView
|
||||||
android:id="@+id/seekBarForums"
|
android:id="@+id/textViewForumMessages"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:max="10"
|
android:layout_margin="@dimen/margin_medium"
|
||||||
android:paddingTop="5dp"
|
android:text="Number of forum messages"
|
||||||
android:progress="3"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/TextViewForumsSb"
|
app:layout_constraintTop_toBottomOf="@+id/seekBarForums"/>
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textViewForums"/>
|
|
||||||
|
|
||||||
<TextView
|
<SeekBar
|
||||||
android:id="@+id/TextViewForumsSb"
|
android:id="@+id/seekBarForumMessages"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:ems="2"
|
android:max="50"
|
||||||
android:text="20"
|
android:paddingTop="5dp"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/seekBarForums"
|
android:progress="20"
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
app:layout_constraintEnd_toStartOf="@+id/TextViewForumMessagesSb"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewForumMessages"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/textViewForumMessages"
|
android:id="@+id/TextViewForumMessagesSb"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_medium"
|
android:ems="2"
|
||||||
android:text="Number of forum messages"
|
android:text="20"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintBottom_toBottomOf="@+id/seekBarForumMessages"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/seekBarForums"/>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/textViewForumMessages"/>
|
||||||
|
|
||||||
<SeekBar
|
<Button
|
||||||
android:id="@+id/seekBarForumMessages"
|
android:id="@+id/buttonCreateTestData"
|
||||||
android:layout_width="0dp"
|
style="@style/BriarButton"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:max="50"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="5dp"
|
android:layout_margin="10dp"
|
||||||
android:progress="30"
|
android:text="Create test data"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/TextViewForumMessagesSb"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/textViewForumMessages"/>
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/seekBarForumMessages"
|
||||||
|
app:layout_constraintVertical_bias="1.0"/>
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
<TextView
|
</ScrollView>
|
||||||
android:id="@+id/TextViewForumMessagesSb"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:ems="2"
|
|
||||||
android:text="20"
|
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/seekBarForumMessages"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/buttonCreateTestData"
|
|
||||||
style="@style/BriarButton"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="10dp"
|
|
||||||
android:text="Create test data"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/seekBarForumMessages"/>
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
</ScrollView>
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
|||||||
@@ -26,14 +26,14 @@
|
|||||||
android:id="@+id/upButton"
|
android:id="@+id/upButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top|right"
|
android:layout_gravity="top|right|end"
|
||||||
app:direction="up"/>
|
app:direction="up"/>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.UnreadMessageButton
|
<org.briarproject.briar.android.view.UnreadMessageButton
|
||||||
android:id="@+id/downButton"
|
android:id="@+id/downButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom|right"
|
android:layout_gravity="bottom|right|end"
|
||||||
app:direction="down"/>
|
app:direction="down"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="bottom"
|
android:gravity="bottom"
|
||||||
app:buttonText="@string/blogs_publish_blog_post"
|
app:buttonText="@string/blogs_publish_blog_post"
|
||||||
app:hint="@string/blogs_write_blog_post_body_hint"
|
app:fillHeight="true"
|
||||||
app:fillHeight="true"/>
|
app:hint="@string/blogs_write_blog_post_body_hint"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge
|
<merge
|
||||||
|
android:id="@+id/merge"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:layout_height="wrap_content"
|
||||||
|
tools:layout_width="match_parent"
|
||||||
|
tools:parentTag="android.support.constraint.ConstraintLayout"
|
||||||
tools:showIn="@layout/list_item_blog_post">
|
tools:showIn="@layout/list_item_blog_post">
|
||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
@@ -9,54 +14,64 @@
|
|||||||
style="@style/BriarAvatar"
|
style="@style/BriarAvatar"
|
||||||
android:layout_width="@dimen/blogs_avatar_normal_size"
|
android:layout_width="@dimen/blogs_avatar_normal_size"
|
||||||
android:layout_height="@dimen/blogs_avatar_normal_size"
|
android:layout_height="@dimen/blogs_avatar_normal_size"
|
||||||
android:layout_alignTop="@+id/authorName"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
android:layout_marginRight="@dimen/margin_medium"
|
app:layout_constraintEnd_toStartOf="@+id/authorName"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintHorizontal_chainStyle="packed"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@mipmap/ic_launcher_round"/>
|
tools:src="@mipmap/ic_launcher_round"/>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/avatarIcon"
|
android:id="@+id/avatarIcon"
|
||||||
android:layout_width="@dimen/blogs_avatar_icon_size"
|
android:layout_width="@dimen/blogs_avatar_icon_size"
|
||||||
android:layout_height="@dimen/blogs_avatar_icon_size"
|
android:layout_height="@dimen/blogs_avatar_icon_size"
|
||||||
android:layout_alignBottom="@+id/avatar"
|
|
||||||
android:layout_alignRight="@+id/avatar"
|
|
||||||
android:background="@drawable/bubble_white"
|
android:background="@drawable/bubble_white"
|
||||||
|
android:contentDescription="@string/blogs_reblog_button"
|
||||||
android:padding="2dp"
|
android:padding="2dp"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
android:src="@drawable/ic_repeat"
|
android:src="@drawable/ic_repeat"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
tools:ignore="ContentDescription"/>
|
app:layout_constraintBottom_toBottomOf="@+id/avatar"
|
||||||
|
app:layout_constraintEnd_toEndOf="@+id/avatar"/>
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
android:id="@+id/authorName"
|
android:id="@+id/authorName"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_toEndOf="@+id/avatar"
|
android:layout_marginEnd="@dimen/margin_medium"
|
||||||
android:layout_toRightOf="@+id/avatar"
|
android:layout_marginLeft="@dimen/margin_medium"
|
||||||
|
android:layout_marginRight="@dimen/margin_medium"
|
||||||
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
tools:text="Author Name"/>
|
app:layout_constrainedWidth="true"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/trustIndicator"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/avatar"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Author View that can have a long name"/>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.TrustIndicatorView
|
<org.briarproject.briar.android.view.TrustIndicatorView
|
||||||
android:id="@+id/trustIndicator"
|
android:id="@+id/trustIndicator"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBottom="@+id/authorName"
|
app:layout_constraintBottom_toBottomOf="@+id/authorName"
|
||||||
android:layout_alignTop="@+id/authorName"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_marginLeft="@dimen/margin_small"
|
app:layout_constraintStart_toEndOf="@+id/authorName"
|
||||||
android:layout_toRightOf="@id/authorName"
|
app:layout_constraintTop_toTopOf="@+id/authorName"
|
||||||
android:scaleType="center"
|
app:layout_goneMarginEnd="0dp"
|
||||||
|
app:layout_goneMarginStart="0dp"
|
||||||
tools:src="@drawable/trust_indicator_verified"/>
|
tools:src="@drawable/trust_indicator_verified"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/dateView"
|
android:id="@+id/dateView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/authorName"
|
|
||||||
android:layout_toEndOf="@+id/avatar"
|
|
||||||
android:layout_toRightOf="@+id/avatar"
|
|
||||||
android:gravity="bottom"
|
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_tiny"
|
android:textSize="@dimen/text_size_tiny"
|
||||||
tools:text="yesterday"/>
|
app:layout_constraintStart_toStartOf="@+id/authorName"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/authorName"
|
||||||
|
tools:text="yesterday"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</merge>
|
</merge>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/relativeLayout"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@@ -62,8 +61,6 @@
|
|||||||
android:textSize="@dimen/text_size_large"
|
android:textSize="@dimen/text_size_large"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/emptyAction"
|
app:layout_constraintBottom_toTopOf="@+id/emptyAction"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/emptyImage"
|
app:layout_constraintTop_toBottomOf="@+id/emptyImage"
|
||||||
tools:text="@string/no_contacts"/>
|
tools:text="@string/no_contacts"/>
|
||||||
@@ -79,8 +76,6 @@
|
|||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/emptyText"
|
app:layout_constraintTop_toBottomOf="@+id/emptyText"
|
||||||
tools:text="@string/no_contacts_action"/>
|
tools:text="@string/no_contacts_action"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginLeft="@dimen/margin_activity_horizontal"
|
android:layout_marginLeft="@dimen/margin_activity_horizontal"
|
||||||
|
android:layout_marginStart="@dimen/margin_activity_horizontal"
|
||||||
android:layout_marginTop="@dimen/margin_activity_vertical"
|
android:layout_marginTop="@dimen/margin_activity_vertical"
|
||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:text="@string/don_t_ask_again"/>
|
android:text="@string/don_t_ask_again"/>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
android:id="@+id/contactStatus"
|
android:id="@+id/contactStatus"
|
||||||
android:layout_width="15dp"
|
android:layout_width="15dp"
|
||||||
android:layout_height="15dp"
|
android:layout_height="15dp"
|
||||||
android:layout_gravity="bottom|right"
|
android:layout_gravity="bottom|end|right"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
tools:ignore="ContentDescription"
|
tools:ignore="ContentDescription"
|
||||||
tools:src="@drawable/contact_online"/>
|
tools:src="@drawable/contact_online"/>
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_height="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:layout_width="match_parent"
|
||||||
android:padding="@dimen/margin_large">
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/margin_large">
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -13,7 +15,8 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/screen_filter_message"
|
android:id="@+id/screen_filter_message"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/screen_filter_body"/>
|
||||||
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
||||||
@@ -21,8 +24,8 @@
|
|||||||
android:id="@+id/screen_filter_checkbox"
|
android:id="@+id/screen_filter_checkbox"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0"
|
|
||||||
android:layout_marginTop="@dimen/margin_large"
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
|
android:layout_weight="0"
|
||||||
android:text="@string/screen_filter_allow"/>
|
android:text="@string/screen_filter_allow"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:descendantFocusability="beforeDescendants"
|
android:descendantFocusability="beforeDescendants"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
android:id="@+id/postLayout"
|
android:id="@+id/postLayout"
|
||||||
style="@style/BriarCard"
|
style="@style/BriarCard"
|
||||||
layout="@layout/list_item_blog_post"
|
layout="@layout/list_item_blog_post"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:src="@drawable/alerts_and_states_error"
|
android:src="@drawable/alerts_and_states_error"
|
||||||
@@ -25,6 +27,8 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="8dp"
|
android:layout_marginEnd="8dp"
|
||||||
|
android:layout_marginLeft="8dp"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:text="@string/sorry"
|
android:text="@string/sorry"
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:paddingTop="@dimen/margin_large"
|
android:paddingTop="@dimen/margin_large"
|
||||||
tools:text="Connection failed"/>
|
tools:text="@string/waiting_for_contact_to_scan"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.QrCodeView
|
<org.briarproject.briar.android.view.QrCodeView
|
||||||
@@ -47,6 +47,9 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:background="@android:color/white"/>
|
android:background="@android:color/white"
|
||||||
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@@ -47,27 +48,28 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="@dimen/button_size">
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/cancelButton"
|
android:id="@+id/cancelButton"
|
||||||
style="@style/BriarButtonFlat.Positive"
|
style="@style/BriarButtonFlat.Positive"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0.5"
|
android:text="@string/cancel"
|
||||||
android:text="@string/cancel"/>
|
app:layout_constraintEnd_toStartOf="@+id/openButton"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/openButton"
|
android:id="@+id/openButton"
|
||||||
style="@style/BriarButtonFlat.Negative"
|
style="@style/BriarButtonFlat.Negative"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="0.5"
|
android:text="@string/link_warning_open_link"
|
||||||
android:text="@string/link_warning_open_link"/>
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/cancelButton"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -10,19 +10,13 @@
|
|||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingBottom="@dimen/margin_activity_vertical"
|
android:padding="@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">
|
|
||||||
|
|
||||||
<org.briarproject.briar.android.login.DozeView
|
<org.briarproject.briar.android.login.DozeView
|
||||||
android:id="@+id/dozeView"
|
android:id="@+id/dozeView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"/>
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
@@ -30,8 +24,8 @@
|
|||||||
android:id="@+id/huaweiView"
|
android:id="@+id/huaweiView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/dozeView"/>
|
app:layout_constraintTop_toBottomOf="@+id/dozeView"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@@ -42,8 +36,8 @@
|
|||||||
android:enabled="false"
|
android:enabled="false"
|
||||||
android:text="@string/create_account_button"
|
android:text="@string/create_account_button"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/huaweiView"
|
app:layout_constraintTop_toBottomOf="@+id/huaweiView"
|
||||||
app:layout_constraintVertical_bias="1.0"
|
app:layout_constraintVertical_bias="1.0"
|
||||||
tools:enabled="true"/>
|
tools:enabled="true"/>
|
||||||
@@ -55,8 +49,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:visibility="invisible"
|
android:visibility="invisible"
|
||||||
app:layout_constraintBottom_toBottomOf="@+id/next"
|
app:layout_constraintBottom_toBottomOf="@+id/next"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/next"/>
|
app:layout_constraintTop_toTopOf="@+id/next"/>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|||||||
@@ -7,113 +7,125 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<LinearLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content">
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<LinearLayout
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/avatarContact1"
|
||||||
|
style="@style/BriarAvatar"
|
||||||
|
android:layout_width="42dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_activity_horizontal"
|
android:layout_margin="@dimen/margin_large"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/introductionIcon"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:src="@mipmap/ic_launcher_round"/>
|
||||||
|
|
||||||
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
|
android:id="@+id/nameContact1"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="@dimen/margin_large"
|
||||||
|
android:layout_marginLeft="@dimen/margin_large"
|
||||||
|
android:layout_marginRight="@dimen/margin_large"
|
||||||
|
android:layout_marginStart="@dimen/margin_large"
|
||||||
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:orientation="horizontal">
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/introductionIcon"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/avatarContact1"
|
||||||
|
tools:text="Contact 1"/>
|
||||||
|
|
||||||
<LinearLayout
|
<android.support.v7.widget.AppCompatImageView
|
||||||
android:layout_width="wrap_content"
|
android:id="@+id/introductionIcon"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:gravity="top|center_horizontal"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:layout_margin="@dimen/margin_large"
|
||||||
|
android:src="@drawable/ic_contact_introduction"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/barrier"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/avatarContact2"
|
||||||
|
app:tint="?attr/colorControlNormal"
|
||||||
|
tools:ignore="ContentDescription"/>
|
||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
<de.hdodenhof.circleimageview.CircleImageView
|
||||||
android:id="@+id/avatarContact1"
|
android:id="@+id/avatarContact2"
|
||||||
style="@style/BriarAvatar"
|
style="@style/BriarAvatar"
|
||||||
android:layout_width="@dimen/listitem_picture_size"
|
android:layout_width="42dp"
|
||||||
android:layout_height="@dimen/listitem_picture_size"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
android:layout_margin="@dimen/margin_large"
|
||||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
android:layout_marginRight="@dimen/listitem_horizontal_margin"
|
app:layout_constraintStart_toEndOf="@+id/introductionIcon"
|
||||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
tools:src="@mipmap/ic_launcher_round"/>
|
tools:src="@mipmap/ic_launcher_round"/>
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
android:id="@+id/nameContact1"
|
android:id="@+id/nameContact2"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/margin_small"
|
android:layout_marginEnd="@dimen/margin_large"
|
||||||
android:gravity="center"
|
android:layout_marginLeft="@dimen/margin_large"
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
android:layout_marginRight="@dimen/margin_large"
|
||||||
android:textSize="@dimen/text_size_small"
|
android:layout_marginStart="@dimen/margin_large"
|
||||||
tools:text="Contact 1"/>
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textColor="?android:attr/textColorPrimary"
|
||||||
|
android:textSize="@dimen/text_size_small"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/introductionIcon"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/avatarContact2"
|
||||||
|
tools:text="Contact 2 can have quite a long name"/>
|
||||||
|
|
||||||
</LinearLayout>
|
<android.support.constraint.Barrier
|
||||||
|
android:id="@+id/barrier"
|
||||||
<android.support.v7.widget.AppCompatImageView
|
android:layout_width="wrap_content"
|
||||||
android:id="@+id/introductionIcon"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="@dimen/listitem_picture_size"
|
app:barrierDirection="bottom"
|
||||||
android:layout_height="@dimen/listitem_picture_size"
|
app:constraint_referenced_ids="nameContact1,nameContact2"/>
|
||||||
android:src="@drawable/ic_contact_introduction"
|
|
||||||
app:tint="?attr/colorControlNormal"
|
|
||||||
tools:ignore="ContentDescription"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="top|center_horizontal"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<de.hdodenhof.circleimageview.CircleImageView
|
|
||||||
android:id="@+id/avatarContact2"
|
|
||||||
style="@style/BriarAvatar"
|
|
||||||
android:layout_width="@dimen/listitem_picture_size"
|
|
||||||
android:layout_height="@dimen/listitem_picture_size"
|
|
||||||
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
|
|
||||||
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
|
|
||||||
android:layout_marginRight="@dimen/listitem_horizontal_margin"
|
|
||||||
android:layout_marginStart="@dimen/listitem_horizontal_margin"
|
|
||||||
tools:src="@mipmap/ic_launcher_round"/>
|
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
|
||||||
android:id="@+id/nameContact2"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/margin_small"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textColor="?android:attr/textColorPrimary"
|
|
||||||
android:textSize="@dimen/text_size_small"
|
|
||||||
tools:text="Contact 2"/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/progressBar"
|
android:id="@+id/progressBar"
|
||||||
style="?android:attr/progressBarStyleLarge"
|
style="?android:attr/progressBarStyleLarge"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center"
|
android:layout_margin="@dimen/margin_large"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/introductionNotPossibleView"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/barrier"
|
||||||
tools:visibility="gone"/>
|
tools:visibility="gone"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/introductionNotPossibleView"
|
android:id="@+id/introductionNotPossibleView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/margin_activity_horizontal"
|
android:layout_margin="@dimen/margin_large"
|
||||||
android:text="@string/introduction_not_possible"
|
android:text="@string/introduction_not_possible"
|
||||||
android:textSize="@dimen/text_size_large"
|
android:textSize="@dimen/text_size_large"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/progressBar"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.LargeTextInputView
|
<org.briarproject.briar.android.view.LargeTextInputView
|
||||||
android:id="@+id/introductionMessageView"
|
android:id="@+id/introductionMessageView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="@dimen/margin_large"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
app:buttonText="@string/introduction_button"
|
app:buttonText="@string/introduction_button"
|
||||||
app:hint="@string/introduction_message_hint"
|
app:hint="@string/introduction_message_hint"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/introductionNotPossibleView"
|
||||||
app:maxLines="5"
|
app:maxLines="5"
|
||||||
tools:visibility="visible"/>
|
tools:visibility="visible"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
@@ -9,27 +9,32 @@
|
|||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/inputDivider"
|
android:id="@+id/inputDivider"
|
||||||
style="@style/Divider.Horizontal"/>
|
style="@style/Divider.Horizontal"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"/>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.AuthorView
|
<org.briarproject.briar.android.view.AuthorView
|
||||||
android:id="@+id/authorView"
|
android:id="@+id/authorView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentLeft="true"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:padding="@dimen/listitem_vertical_margin"
|
android:padding="@dimen/listitem_vertical_margin"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:persona="commenter"/>
|
app:persona="commenter"/>
|
||||||
|
|
||||||
<com.vanniktech.emoji.EmojiTextView
|
<com.vanniktech.emoji.EmojiTextView
|
||||||
android:id="@+id/bodyView"
|
android:id="@+id/bodyView"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/authorView"
|
|
||||||
android:paddingBottom="@dimen/listitem_vertical_margin"
|
android:paddingBottom="@dimen/listitem_vertical_margin"
|
||||||
android:paddingLeft="@dimen/listitem_vertical_margin"
|
android:paddingEnd="@dimen/listitem_vertical_margin"
|
||||||
android:paddingRight="@dimen/listitem_vertical_margin"
|
android:paddingStart="@dimen/listitem_vertical_margin"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="?android:attr/textColorSecondary"
|
||||||
android:textSize="@dimen/text_size_small"
|
android:textSize="@dimen/text_size_small"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/authorView"
|
||||||
tools:text="This is a comment that appears below a blog post. Usually, it is expected to be rather short. Not much longer than this one."/>
|
tools:text="This is a comment that appears below a blog post. Usually, it is expected to be rather short. Not much longer than this one."/>
|
||||||
|
|
||||||
</RelativeLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user