Compare commits

..

19 Commits

Author SHA1 Message Date
akwizgran
39478a7914 Bump version numbers for 1.1.2 release. 2018-10-01 14:58:45 +01:00
akwizgran
112e71a9cb Bump version numbers for 1.0.2 release. 2018-10-01 14:56:08 +01:00
akwizgran
5650bef310 Update translations. 2018-10-01 14:56:08 +01:00
akwizgran
2a87171c49 Merge branch 'manual-screenshots' into 'master'
Create Screenshot of Conversation for Manual

Closes #1377

See merge request briar/briar!910
2018-10-01 13:41:05 +00:00
akwizgran
15cb5409e7 Merge branch '1352-panic-ripple-fdroid' into 'master'
Fix Panic Button bugs

Closes #1109 and #1352

See merge request briar/briar!937
2018-09-28 09:57:18 +00:00
akwizgran
fd07dc006d Update comment. 2018-09-28 09:55:47 +01:00
akwizgran
cc87c4e37d Merge branch '1391-start-end-api15' into 'master'
RTL language layout fixes

Closes #1391

See merge request briar/briar!938
2018-09-28 08:45:17 +00:00
akwizgran
4a10e876f6 Merge branch '1389-notice-shadows' into 'master'
Fix notice shadows

Closes #1389

See merge request briar/briar!939
2018-09-28 08:43:06 +00:00
Torsten Grote
fad0057c4a Fix notice shadows 2018-09-27 20:32:13 -03:00
Torsten Grote
5aabfcea9a Unmirror checkboxes in RTL layouts 2018-09-27 19:09:08 -03:00
Torsten Grote
f7d928c774 Fix start/end margins for API 15
Fixes #1391
2018-09-27 19:07:13 -03:00
Torsten Grote
bd983d9796 Remove non-functional uninstall panic action
Fixes #1109
2018-09-27 18:37:57 -03:00
Torsten Grote
de8d1b7d96 Allow sign out by trusted non-paired panic apps 2018-09-27 18:25:31 -03:00
Torsten Grote
9155f62d0b Remove Amnesty International's key and add F-Droid Ripple key instead
Fixes #1352
2018-09-27 18:17:14 -03:00
Torsten Grote
c2b7f85b8e Remove code from TestDataCreator that breaks encapsulation 2018-09-24 12:37:11 -03:00
Torsten Grote
ae81eb3737 Throw AssertionError when creating an account while a database key is in memory 2018-09-24 12:37:11 -03:00
Torsten Grote
60d949c342 Refactor tests so that all test data is created in the first test 2018-09-24 12:37:11 -03:00
Torsten Grote
1c90e64894 Split up UI and Screenshot tests
Closes #1377
2018-09-24 12:37:06 -03:00
Torsten Grote
f0e2d5281f Create Screenshot of Conversation for Manual 2018-09-24 12:34:26 -03:00
124 changed files with 739 additions and 2556 deletions

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-android" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-android" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-api" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-api" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-api" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-core" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in bramble-java" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-java" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea -Djava.library.path=libs" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/bramble-java" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-android" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-android" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-android" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="All tests in briar-core" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="briar-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/briar-core" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="H2 Performance Test" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -1,5 +1,6 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="HyperSQL Performance Test" type="AndroidJUnit" factoryName="Android JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="bramble-core" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
@@ -10,10 +11,12 @@
<option name="VM_PARAMETERS" value="-ea" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<patterns />
<method />
</configuration>

View File

@@ -9,8 +9,8 @@ android {
defaultConfig {
minSdkVersion 14
targetSdkVersion 26
versionCode 10101
versionName "1.1.1"
versionCode 10102
versionName "1.1.2"
consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

View File

@@ -153,15 +153,4 @@ public class StringUtils {
return new String(c);
}
public static String getRandomBase32String(int length) {
char[] c = new char[length];
for (int i = 0; i < length; i++) {
int character = random.nextInt(32);
if (character < 26) c[i] = (char) ('A' + character);
else c[i] = (char) ('2' + (character - 26));
}
return new String(c);
}
}

View File

@@ -159,7 +159,8 @@ class AccountManagerImpl implements AccountManager {
@Override
public boolean createAccount(String name, String password) {
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);
identityManager.registerLocalAuthor(localAuthor);
SecretKey key = crypto.generateSecretKey();
@@ -182,6 +183,7 @@ class AccountManagerImpl implements AccountManager {
LOG.info("Deleting account");
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseKeyDirectory());
IoUtils.deleteFileOrDir(databaseConfig.getDatabaseDirectory());
databaseKey = null;
}
}

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
style="width:24px;height:24px"
viewBox="0 0 24 24"
version="1.1"
id="svg4"
sodipodi:docname="ic_link_down.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview6"
showgrid="false"
inkscape:zoom="13.906433"
inkscape:cx="5.1490538"
inkscape:cy="22.945407"
inkscape:window-x="1440"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
fill="#000000"
d="M16,6H13V7.9H16C18.26,7.9 20.1,9.73 20.1,12A4.1,4.1 0 0,1 16,16.1H13V18H16A6,6 0 0,0 22,12C22,8.68 19.31,6 16,6M3.9,12C3.9,9.73 5.74,7.9 8,7.9H11V6H8A6,6 0 0,0 2,12A6,6 0 0,0 8,18H11V16.1H8C5.74,16.1 3.9,14.26 3.9,12M8,13H16V11H8V13Z"
id="path2" />
<path
id="path884"
d="m 21.659779,17.473157 h -2.295918 v 3.061224 H 17.51182 l 3.000001,3 2.999999,-3 h -1.852041 z"
inkscape:connector-curvature="0"
style="fill:#000000;stroke-width:0.38265303" />
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
style="width:24px;height:24px"
viewBox="0 0 24 24"
version="1.1"
id="svg4"
sodipodi:docname="ic_link_up.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)">
<metadata
id="metadata10">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs8" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1020"
id="namedview6"
showgrid="false"
inkscape:zoom="13.906433"
inkscape:cx="5.1490538"
inkscape:cy="22.945407"
inkscape:window-x="1440"
inkscape:window-y="24"
inkscape:window-maximized="0"
inkscape:current-layer="svg4" />
<path
fill="#000000"
d="M16,6H13V7.9H16C18.26,7.9 20.1,9.73 20.1,12A4.1,4.1 0 0,1 16,16.1H13V18H16A6,6 0 0,0 22,12C22,8.68 19.31,6 16,6M3.9,12C3.9,9.73 5.74,7.9 8,7.9H11V6H8A6,6 0 0,0 2,12A6,6 0 0,0 8,18H11V16.1H8C5.74,16.1 3.9,14.26 3.9,12M8,13H16V11H8V13Z"
id="path2" />
<path
id="path884"
d="M 21.659779,23.534381 H 19.363861 V 20.473157 H 17.51182 l 3.000001,-3 2.999999,3 h -1.852041 z"
inkscape:connector-curvature="0"
style="fill:#000000;stroke-width:0.38265303" />
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@@ -2,73 +2,6 @@ apply plugin: 'com.android.application'
apply plugin: 'witness'
apply from: 'witness.gradle'
// prototype
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation project(path: ':briar-core', configuration: 'default')
implementation project(path: ':bramble-core', configuration: 'default')
implementation project(':bramble-android')
def supportVersion = '28.0.0'
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'
// prototype
implementation "com.github.kobakei:MaterialFabSpeedDial:1.2.0"
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 stdout = new ByteArrayOutputStream()
try {
@@ -89,15 +22,15 @@ android {
defaultConfig {
minSdkVersion 15
targetSdkVersion 26
versionCode 10101
versionName "1.1.1"
versionCode 10102
versionName "1.1.2"
applicationId "org.briarproject.briar.android"
buildConfigField "String", "GitHash",
"\"${getStdout(['git', 'rev-parse', '--short=7', 'HEAD'], 'No commit hash')}\""
def now = (long) (System.currentTimeMillis() / 1000)
buildConfigField "Long", "BuildTimestamp",
"${getStdout(['git', 'log', '-n', '1', '--format=%ct'], now)}000L"
testInstrumentationRunner 'org.briarproject.briar.android.test.BriarTestRunner'
testInstrumentationRunner 'org.briarproject.briar.android.BriarTestRunner'
}
buildTypes {
@@ -152,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 {
doLast {
def file = project.file("src/main/res/values/arrays.xml")

View File

@@ -1,9 +1,7 @@
app_package_name "org.briarproject.briar.android.screenshot.debug"
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"
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

View File

@@ -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 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 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

View File

@@ -12,4 +12,4 @@
-keep class junit.** { *; }
-dontwarn junit.**
-dontwarn org.briarproject.briar.android.BriarTestComponentApplication
-dontwarn org.briarproject.briar.android.**

View File

@@ -1,11 +1,9 @@
package org.briarproject.briar.android.test;
package org.briarproject.briar.android;
import android.app.Application;
import android.content.Context;
import android.support.test.runner.AndroidJUnitRunner;
import org.briarproject.briar.android.BriarTestComponentApplication;
public class BriarTestRunner extends AndroidJUnitRunner {
@Override
@@ -13,8 +11,8 @@ public class BriarTestRunner extends AndroidJUnitRunner {
Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return super.newApplication(cl, BriarTestComponentApplication.class.getName(),
context);
return super.newApplication(cl,
BriarTestComponentApplication.class.getName(), context);
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -1,4 +1,4 @@
package org.briarproject.briar.android.test;
package org.briarproject.briar.android;
import android.app.Activity;
import android.support.test.espresso.PerformException;

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -6,8 +6,8 @@ import android.view.Gravity;
import org.briarproject.briar.R;
import org.briarproject.briar.android.BriarUiTestComponent;
import org.briarproject.briar.android.UiTest;
import org.briarproject.briar.android.settings.SettingsActivity;
import org.briarproject.briar.android.test.ScreenshotTest;
import org.junit.Rule;
import org.junit.Test;
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;
@RunWith(AndroidJUnit4.class)
public class NavDrawerActivityTest extends ScreenshotTest {
public class NavDrawerActivityTest extends UiTest {
@Rule
public CleanAccountTestRule<NavDrawerActivity> testRule =

View File

@@ -4,8 +4,7 @@ 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.login.SetupActivityScreenshotTest;
import org.briarproject.briar.android.navdrawer.NavDrawerActivityTest;
import org.briarproject.briar.android.contact.ConversationActivityScreenshotTest;
import org.briarproject.briar.android.settings.SettingsActivityScreenshotTest;
import javax.inject.Singleton;
@@ -22,8 +21,9 @@ import dagger.Component;
})
public interface BriarUiTestComponent extends AndroidComponent {
void inject(SetupActivityScreenshotTest test);
void inject(NavDrawerActivityTest test);
void inject(SetupDataTest test);
void inject(ConversationActivityScreenshotTest test);
void inject(SettingsActivityScreenshotTest test);
}

View File

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

View File

@@ -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.runner.AndroidJUnit4;
@@ -6,9 +6,12 @@ import android.support.test.uiautomator.UiDevice;
import android.support.test.uiautomator.UiObject;
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.android.BriarUiTestComponent;
import org.briarproject.briar.android.test.ScreenshotTest;
import org.briarproject.briar.android.login.OpenDatabaseActivity;
import org.briarproject.briar.android.login.SetupActivity;
import org.junit.Rule;
import org.junit.Test;
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.withText;
import static android.support.test.runner.lifecycle.Stage.PAUSED;
import static junit.framework.Assert.assertTrue;
import static org.briarproject.briar.android.test.ViewActions.waitForActivity;
import static org.briarproject.briar.android.test.ViewActions.waitUntilMatches;
import static org.briarproject.bramble.api.plugin.LanTcpConstants.ID;
import static org.briarproject.briar.android.ViewActions.waitForActivity;
import static org.briarproject.briar.android.ViewActions.waitUntilMatches;
import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
import static org.junit.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
public class SetupActivityScreenshotTest extends ScreenshotTest {
public class SetupDataTest extends ScreenshotTest {
@Rule
public IntentsTestRule<SetupActivity> testRule =
@@ -61,7 +64,7 @@ public class SetupActivityScreenshotTest extends ScreenshotTest {
onView(withId(R.id.nickname_entry))
.perform(waitUntilMatches(withText(USERNAME)));
screenshot("manual_create_account");
screenshot("manual_create_account", testRule.getActivity());
onView(withId(R.id.next))
.check(matches(isDisplayed()))
@@ -94,13 +97,54 @@ public class SetupActivityScreenshotTest extends ScreenshotTest {
}
// wait for OpenDatabaseActivity to show up
onView(withId(R.id.progress))
.check(matches(isDisplayed()));
onView(isRoot())
.perform(waitForActivity(testRule.getActivity(), PAUSED));
intended(hasComponent(OpenDatabaseActivity.class.getName()));
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);
}
}

View File

@@ -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());
}
}

View File

@@ -2,14 +2,15 @@ package org.briarproject.briar.android.settings;
import android.content.Intent;
import android.support.test.espresso.contrib.DrawerActions;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.support.v7.widget.RecyclerView;
import android.view.Gravity;
import org.briarproject.briar.R;
import org.briarproject.briar.android.BriarUiTestComponent;
import org.briarproject.briar.android.ScreenshotTest;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import org.briarproject.briar.android.test.ScreenshotTest;
import org.junit.Rule;
import org.junit.Test;
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.withId;
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;
@RunWith(AndroidJUnit4.class)
public class SettingsActivityScreenshotTest extends ScreenshotTest {
@Rule
public CleanAccountTestRule<SettingsActivity> testRule =
new CleanAccountTestRule<>(SettingsActivity.class);
public ActivityTestRule<SettingsActivity> testRule =
new ActivityTestRule<>(SettingsActivity.class);
@Override
protected void inject(BriarUiTestComponent component) {
@@ -46,7 +47,7 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
onView(withText(R.string.settings_button))
.check(matches(isDisplayed()));
screenshot("manual_dark_theme_settings");
screenshot("manual_dark_theme_settings", testRule.getActivity());
// switch to dark theme
onView(withText(R.string.pref_theme_title))
@@ -56,10 +57,20 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
.check(matches(isDisplayed()))
.perform(click());
// open nav drawer and remove expiry warning
openNavDrawer(true);
openNavDrawer();
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
@@ -83,12 +94,11 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
.check(matches(isDisplayed()))
.check(matches(isEnabled()));
screenshot("manual_app_lock");
screenshot("manual_app_lock", testRule.getActivity());
// no more expiry warning to remove, because sharedprefs cached?
openNavDrawer(false);
openNavDrawer();
screenshot("manual_app_lock_nav_drawer");
screenshot("manual_app_lock_nav_drawer", testRule.getActivity());
}
@Test
@@ -104,23 +114,15 @@ public class SettingsActivityScreenshotTest extends ScreenshotTest {
.check(matches(isDisplayed()))
.perform(waitUntilMatches(isEnabled()));
screenshot("manual_tor_settings");
screenshot("manual_tor_settings", testRule.getActivity());
}
private void openNavDrawer(boolean expiry) {
private void openNavDrawer() {
// start main activity
Intent i =
new Intent(testRule.getActivity(), NavDrawerActivity.class);
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
onView(withId(R.id.drawer_layout))
.check(matches(isClosed(Gravity.START)))

View File

@@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="org.briarproject.briar"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
@@ -28,8 +27,7 @@
android:label="@string/app_name"
android:logo="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/BriarTheme"
tools:ignore="GoogleAppIndexingWarning">
android:theme="@style/BriarTheme">
<receiver
android:name="org.briarproject.briar.android.login.SignInReminderReceiver"
@@ -413,34 +411,5 @@
android:launchMode="singleTask"
android:theme="@style/BriarTheme.NoActionBar"/>
<!-- Prototype -->
<activity
android:name=".android.contact.ContactInviteOutputActivity"
android:theme="@style/BriarTheme"
android:label="@string/send_link_title"/>
<activity
android:name=".android.contact.ContactInviteInputActivity"
android:theme="@style/BriarTheme"
android:label="@string/open_link_title"
android:windowSoftInputMode="stateHidden|adjustResize">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="briar"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
<activity
android:name=".android.contact.PendingRequestsActivity"
android:label="@string/pending_contact_requests"
android:theme="@style/BriarTheme"/>
</application>
</manifest>

View File

@@ -15,17 +15,9 @@ import org.briarproject.briar.android.blog.ReblogFragment;
import org.briarproject.briar.android.blog.RssFeedImportActivity;
import org.briarproject.briar.android.blog.RssFeedManageActivity;
import org.briarproject.briar.android.blog.WriteBlogPostActivity;
import org.briarproject.briar.android.contact.ContactAliasInputFragment;
import org.briarproject.briar.android.contact.ContactInviteInputActivity;
import org.briarproject.briar.android.contact.ContactInviteOutputActivity;
import org.briarproject.briar.android.contact.ContactLinkInputFragment;
import org.briarproject.briar.android.contact.ContactLinkOutputFragment;
import org.briarproject.briar.android.contact.ContactListFragment;
import org.briarproject.briar.android.contact.ContactModule;
import org.briarproject.briar.android.contact.ContactQrCodeInputFragment;
import org.briarproject.briar.android.contact.ContactQrCodeOutputFragment;
import org.briarproject.briar.android.contact.ConversationActivity;
import org.briarproject.briar.android.contact.PendingRequestsActivity;
import org.briarproject.briar.android.forum.CreateForumActivity;
import org.briarproject.briar.android.forum.ForumActivity;
import org.briarproject.briar.android.forum.ForumListFragment;
@@ -175,15 +167,6 @@ public interface ActivityComponent {
void inject(UnlockActivity activity);
void inject(ContactInviteOutputActivity activity);
void inject(ContactInviteInputActivity activity);
void inject(PendingRequestsActivity activity);
void inject(ContactLinkOutputFragment activity);
void inject(ContactQrCodeOutputFragment activity);
void inject(ContactLinkInputFragment activity);
void inject(ContactQrCodeInputFragment activity);
void inject(ContactAliasInputFragment activity);
// Fragments
void inject(AuthorNameFragment fragment);

View File

@@ -1,116 +0,0 @@
package org.briarproject.briar.android.contact;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v4.graphics.drawable.DrawableCompat;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.navdrawer.NavDrawerActivity;
import javax.annotation.Nullable;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.Build.VERSION.SDK_INT;
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
@NotNullByDefault
public class ContactAliasInputFragment extends BaseFragment
implements TextWatcher {
private EditText contactNameInput;
private Button addButton;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
getActivity().setTitle("Enter Contact Name");
View v = inflater.inflate(R.layout.fragment_contact_alias_input,
container, false);
contactNameInput = v.findViewById(R.id.contactNameInput);
contactNameInput.addTextChangedListener(this);
addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked());
return v;
}
public static final String TAG = ContactAliasInputFragment.class.getName();
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
updateAddButtonState();
}
@Override
public void afterTextChanged(Editable s) {
}
private boolean isBriarLink(CharSequence s) {
return getActivity() != null &&
((ContactInviteInputActivity) getActivity()).isBriarLink(s);
}
private void updateAddButtonState() {
addButton.setEnabled(contactNameInput.getText().length() > 0);
}
private void onAddButtonClicked() {
if (getActivity() == null || getContext() == null) return;;
((ContactInviteInputActivity) getActivity())
.addFakeRequest(contactNameInput.getText().toString());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.BriarDialogTheme_Neutral);
builder.setTitle("Contact requested");
builder.setMessage(getString(R.string.add_contact_link_question));
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
Intent intent = new Intent(getContext(), NavDrawerActivity.class);
intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
});
builder.setNegativeButton(R.string.no, (dialog, which) -> {
startActivity(
new Intent(getContext(), ContactInviteOutputActivity.class));
finish();
});
builder.show();
}
}

View File

@@ -1,158 +0,0 @@
package org.briarproject.briar.android.contact;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.util.Log;
import android.view.MenuItem;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.system.Clock;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import org.briarproject.briar.api.messaging.MessagingManager;
import java.util.Random;
import javax.annotation.Nullable;
import javax.inject.Inject;
import static android.app.AlarmManager.ELAPSED_REALTIME;
import static android.content.Intent.ACTION_SEND;
import static android.content.Intent.ACTION_VIEW;
import static android.content.Intent.EXTRA_TEXT;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.os.SystemClock.elapsedRealtime;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
public class ContactInviteInputActivity extends BriarActivity implements
BaseFragmentListener {
@Inject
LifecycleManager lifecycleManager;
@Inject
MessagingManager messagingManager;
@Inject
Clock clock;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_fragment_container);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
Intent i = getIntent();
if (i != null) {
String action = i.getAction();
if (ACTION_SEND.equals(action) || ACTION_VIEW.equals(action)) {
String text = i.getStringExtra(EXTRA_TEXT);
if (text != null) {
showInitialFragment(
ContactLinkInputFragment.newInstance(text));
return;
}
String uri = i.getDataString();
if (uri != null) {
showInitialFragment(
ContactLinkInputFragment.newInstance(uri));
return;
}
} else if ("addContact".equals(action)) {
removeFakeRequest(i.getStringExtra("name"),
i.getLongExtra("timestamp", 0));
setIntent(null);
finish();
}
}
if (state == null) {
showInitialFragment(ContactLinkInputFragment.newInstance(null));
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
boolean isBriarLink(CharSequence s) {
String link = s.toString().trim();
return link.matches("^(briar://)?[A-Z2-7]{64}$");
}
void showLink(@Nullable String link) {
showInitialFragment(ContactLinkInputFragment.newInstance(link));
}
void showCode() {
showNextFragment(new ContactQrCodeInputFragment());
}
void showAlias() {
showNextFragment(new ContactAliasInputFragment());
}
void addFakeRequest(String name) {
long timestamp = clock.currentTimeMillis();
try {
messagingManager.addNewPendingContact(name, timestamp);
} catch (DbException e) {
e.printStackTrace();
}
AlarmManager alarmManager =
(AlarmManager) requireNonNull(getSystemService(ALARM_SERVICE));
long m = MINUTES.toMillis(1);
long fromNow = (long) (-m * Math.log(new Random().nextDouble()));
long triggerAt = elapsedRealtime() + fromNow;
Intent i = new Intent(this, ContactInviteInputActivity.class);
i.setAction("addContact");
i.setFlags(FLAG_ACTIVITY_NEW_TASK);
i.putExtra("name", name);
i.putExtra("timestamp", timestamp);
PendingIntent pendingIntent = PendingIntent
.getActivity(this, (int) timestamp / 1000, i, 0);
alarmManager.set(ELAPSED_REALTIME, triggerAt, pendingIntent);
Log.e("TEST", "Setting Alarm in " + MILLISECONDS.toSeconds(fromNow) +
" seconds");
Log.e("TEST", "with contact: " + name);
}
private void removeFakeRequest(String name, long timestamp) {
if (lifecycleManager.getLifecycleState() != RUNNING) {
Log.e("TEST", "Lifecycle not started, not adding contact " + name);
return;
}
Log.e("TEST", "Adding Contact " + name);
try {
messagingManager.removePendingContact(name, timestamp);
} catch (DbException e) {
e.printStackTrace();
}
}
}

View File

@@ -1,57 +0,0 @@
package org.briarproject.briar.android.contact;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.MenuItem;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
import javax.annotation.Nullable;
public class ContactInviteOutputActivity extends BriarActivity implements
BaseFragmentListener {
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(R.layout.activity_fragment_container);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
if (state == null) {
showInitialFragment(new ContactLinkOutputFragment());
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
void showLink() {
showInitialFragment(new ContactLinkOutputFragment());
}
void showCode() {
showNextFragment(new ContactQrCodeOutputFragment());
}
}

View File

@@ -1,178 +0,0 @@
package org.briarproject.briar.android.contact;
import android.content.ClipboardManager;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import javax.annotation.Nullable;
import static android.content.ClipDescription.MIMETYPE_TEXT_PLAIN;
import static android.content.Context.CLIPBOARD_SERVICE;
import static android.os.Build.VERSION.SDK_INT;
import static android.support.v4.graphics.drawable.DrawableCompat.setTint;
import static android.support.v4.graphics.drawable.DrawableCompat.wrap;
import static java.util.Objects.requireNonNull;
import static org.briarproject.briar.android.util.UiUtils.resolveColorAttribute;
@NotNullByDefault
public class ContactLinkInputFragment extends BaseFragment
implements TextWatcher {
private ClipboardManager clipboard;
private EditText linkInput;
private Button pasteButton;
private EditText contactNameInput;
private Button addButton;
static BaseFragment newInstance(@Nullable String link) {
BaseFragment f = new ContactLinkInputFragment();
Bundle bundle = new Bundle();
bundle.putString("link", link);
f.setArguments(bundle);
return f;
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
getActivity().setTitle(R.string.open_link_title);
View v = inflater.inflate(R.layout.fragment_contact_link_input,
container, false);
clipboard = (ClipboardManager) requireNonNull(
getContext().getSystemService(CLIPBOARD_SERVICE));
int color = resolveColorAttribute(getContext(), R.attr.colorControlNormal);
linkInput = v.findViewById(R.id.linkInput);
linkInput.addTextChangedListener(this);
if (SDK_INT < 23) {
Drawable drawable = wrap(linkInput.getCompoundDrawables()[0]);
setTint(drawable, color);
linkInput.setCompoundDrawables(drawable, null, null, null);
}
pasteButton = v.findViewById(R.id.pasteButton);
pasteButton.setOnClickListener(view -> linkInput
.setText(clipboard.getPrimaryClip().getItemAt(0).getText()));
contactNameInput = v.findViewById(R.id.contactNameInput);
contactNameInput.addTextChangedListener(this);
if (SDK_INT < 23) {
Drawable drawable =
wrap(contactNameInput.getCompoundDrawables()[0]);
setTint(drawable, color);
contactNameInput.setCompoundDrawables(drawable, null, null, null);
}
addButton = v.findViewById(R.id.addButton);
addButton.setOnClickListener(view -> onAddButtonClicked());
Button scanCodeButton = v.findViewById(R.id.scanCodeButton);
scanCodeButton.setOnClickListener(view ->
((ContactInviteInputActivity) getActivity()).showCode());
linkInput.setText(getArguments().getString("link"));
return v;
}
public static final String TAG = ContactLinkInputFragment.class.getName();
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
}
@Override
public void onResume() {
super.onResume();
if (hasLinkInClipboard()) pasteButton.setEnabled(true);
else pasteButton.setEnabled(false);
}
private boolean hasLinkInClipboard() {
return clipboard.hasPrimaryClip() &&
clipboard.getPrimaryClip().getDescription()
.hasMimeType(MIMETYPE_TEXT_PLAIN) &&
clipboard.getPrimaryClip().getItemCount() > 0;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (isBriarLink(linkInput.getText()) && getActivity() != null) {
updateAddButtonState();
// linkInput.setText(null);
// ((ContactInviteInputActivity) getActivity()).showAlias();
}
}
@Override
public void afterTextChanged(Editable s) {
}
private boolean isBriarLink(CharSequence s) {
return getActivity() != null &&
((ContactInviteInputActivity) getActivity()).isBriarLink(s);
}
private void updateAddButtonState() {
addButton.setEnabled(isBriarLink(linkInput.getText()) &&
contactNameInput.getText().length() > 0);
}
private void onAddButtonClicked() {
if (getActivity() == null || getContext() == null) return;
((ContactInviteInputActivity) getActivity())
.addFakeRequest(contactNameInput.getText().toString());
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(),
R.style.BriarDialogTheme_Neutral);
builder.setTitle("Contact requested");
builder.setMessage(getString(R.string.add_contact_link_question));
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
Intent intent = new Intent(getContext(), PendingRequestsActivity.class);
// intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
});
builder.setNegativeButton(R.string.no, (dialog, which) -> {
startActivity(
new Intent(getContext(),
ContactInviteOutputActivity.class));
finish();
});
builder.show();
}
}

View File

@@ -1,86 +0,0 @@
package org.briarproject.briar.android.contact;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import javax.annotation.Nullable;
import static android.content.Context.CLIPBOARD_SERVICE;
import static android.content.Intent.ACTION_SEND;
import static android.content.Intent.EXTRA_TEXT;
import static android.widget.Toast.LENGTH_SHORT;
import static org.briarproject.bramble.util.StringUtils.getRandomBase32String;
@NotNullByDefault
public class ContactLinkOutputFragment extends BaseFragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
getActivity().setTitle(R.string.send_link_title);
View v = inflater.inflate(R.layout.fragment_contact_link_output,
container, false);
String link = "briar://" + getRandomBase32String(64);
TextView linkView = v.findViewById(R.id.linkView);
linkView.setText(link);
ClipboardManager clipboard = (ClipboardManager)
getContext().getSystemService(CLIPBOARD_SERVICE);
if (clipboard == null) throw new AssertionError();
ClipData clip = ClipData.newPlainText(
getString(R.string.link_clip_label), link);
Button copyButton = v.findViewById(R.id.copyButton);
copyButton.setOnClickListener(view -> {
clipboard.setPrimaryClip(clip);
Toast.makeText(getContext(), R.string.link_copied_toast,
LENGTH_SHORT).show();
});
Button shareButton = v.findViewById(R.id.shareButton);
shareButton.setOnClickListener(view -> {
Intent i = new Intent(ACTION_SEND);
i.putExtra(EXTRA_TEXT, link);
i.setType("text/plain");
startActivity(i);
});
Button showCodeButton = v.findViewById(R.id.showCodeButton);
showCodeButton.setOnClickListener(
view -> ((ContactInviteOutputActivity) getActivity()).showCode());
return v;
}
public static final String TAG = ContactLinkOutputFragment.class.getName();
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
}
}

View File

@@ -2,11 +2,8 @@ package org.briarproject.briar.android.contact;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.ActivityOptionsCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.util.Pair;
import android.support.v7.widget.LinearLayoutManager;
import android.view.LayoutInflater;
@@ -15,12 +12,10 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactId;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
import org.briarproject.bramble.api.contact.event.ContactRemovedEvent;
import org.briarproject.bramble.api.contact.event.ContactStatusChangedEvent;
import org.briarproject.bramble.api.db.DbException;
@@ -42,24 +37,17 @@ import org.briarproject.briar.android.view.BriarRecyclerView;
import org.briarproject.briar.api.android.AndroidNotificationManager;
import org.briarproject.briar.api.client.MessageTracker.GroupCount;
import org.briarproject.briar.api.messaging.ConversationManager;
import org.briarproject.briar.api.messaging.MessagingManager;
import org.briarproject.briar.api.messaging.MessagingManager.PendingContact;
import org.briarproject.briar.api.messaging.PrivateMessageHeader;
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.inject.Inject;
import io.github.kobakei.materialfabspeeddial.FabSpeedDial;
import io.github.kobakei.materialfabspeeddial.FabSpeedDial.OnMenuItemClickListener;
import static android.os.Build.VERSION.SDK_INT;
import static android.support.design.widget.Snackbar.LENGTH_INDEFINITE;
import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAnimation;
import static android.support.v4.view.ViewCompat.getTransitionName;
import static java.util.logging.Level.WARNING;
@@ -70,8 +58,7 @@ import static org.briarproject.briar.android.contact.ConversationActivity.CONTAC
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class ContactListFragment extends BaseFragment implements EventListener,
OnMenuItemClickListener {
public class ContactListFragment extends BaseFragment implements EventListener {
public static final String TAG = ContactListFragment.class.getName();
private static final Logger LOG = Logger.getLogger(TAG);
@@ -83,13 +70,8 @@ public class ContactListFragment extends BaseFragment implements EventListener,
@Inject
AndroidNotificationManager notificationManager;
// TODO remove
@Inject
MessagingManager messagingManager;
private ContactListAdapter adapter;
private BriarRecyclerView list;
private Snackbar snackbar;
// Fields that are accessed from background threads must be volatile
@Inject
@@ -122,12 +104,7 @@ public class ContactListFragment extends BaseFragment implements EventListener,
getActivity().setTitle(R.string.contact_list_button);
View contentView =
inflater.inflate(R.layout.fragment_contact_list, container,
false);
FabSpeedDial speedDialView = contentView.findViewById(R.id.speedDial);
speedDialView.addOnMenuItemClickListener(this);
View contentView = inflater.inflate(R.layout.list, container, false);
OnContactClickListener<ContactListItem> onContactClickListener =
(view, item) -> {
@@ -166,20 +143,12 @@ public class ContactListFragment extends BaseFragment implements EventListener,
list.setEmptyText(getString(R.string.no_contacts));
list.setEmptyAction(getString(R.string.no_contacts_action));
snackbar = Snackbar.make(contentView,
R.string.pending_contact_requests_snackbar, LENGTH_INDEFINITE);
snackbar.getView().setBackgroundResource(R.color.briar_primary);
snackbar.setAction(R.string.show, v -> startActivity(
new Intent(getContext(), PendingRequestsActivity.class)));
snackbar.setActionTextColor(ContextCompat
.getColor(getContext(), R.color.briar_button_text_positive));
return contentView;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// inflater.inflate(R.menu.contact_list_actions, menu);
inflater.inflate(R.menu.contact_list_actions, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@@ -197,28 +166,6 @@ public class ContactListFragment extends BaseFragment implements EventListener,
}
}
@Override
public void onMenuItemClick(FloatingActionButton fab, TextView v,
int itemId) {
switch (itemId) {
case R.id.action_add_contact:
Intent intent =
new Intent(getContext(), ContactExchangeActivity.class);
startActivity(intent);
return;
case R.id.action_open_link:
startActivity(new Intent(getContext(),
ContactInviteInputActivity.class));
return;
case R.id.action_send_link:
startActivity(new Intent(getContext(),
ContactInviteOutputActivity.class));
return;
default:
return;
}
}
@Override
public void onStart() {
super.onStart();
@@ -227,26 +174,6 @@ public class ContactListFragment extends BaseFragment implements EventListener,
notificationManager.clearAllIntroductionNotifications();
loadContacts();
list.startPeriodicUpdate();
// TODO remove
checkForPendingContacts();
}
// TODO remove
private void checkForPendingContacts() {
listener.runOnDbThread(() -> {
try {
Collection<PendingContact> contacts =
messagingManager.getPendingContacts();
if (contacts.isEmpty()) {
runOnUiThreadUnlessDestroyed(() -> snackbar.dismiss());
} else {
runOnUiThreadUnlessDestroyed(() -> snackbar.show());
}
} catch (DbException e) {
e.printStackTrace();
}
});
}
@Override
@@ -321,11 +248,6 @@ public class ContactListFragment extends BaseFragment implements EventListener,
PrivateMessageHeader h = p.getMessageHeader();
updateItem(p.getContactId(), h);
}
// TODO remove
else if (e instanceof ContactAddedEvent) {
checkForPendingContacts();
}
}
private void updateItem(ContactId c, PrivateMessageHeader h) {

View File

@@ -1,181 +0,0 @@
package org.briarproject.briar.android.contact;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.google.zxing.Result;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.keyagreement.CameraException;
import org.briarproject.briar.android.keyagreement.CameraView;
import org.briarproject.briar.android.keyagreement.QrCodeDecoder;
import org.briarproject.briar.android.util.UiUtils;
import javax.annotation.Nullable;
import static android.Manifest.permission.CAMERA;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.widget.Toast.LENGTH_LONG;
import static android.widget.Toast.LENGTH_SHORT;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA;
@NotNullByDefault
public class ContactQrCodeInputFragment extends BaseFragment
implements QrCodeDecoder.ResultCallback {
private CameraView cameraView;
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
getActivity().setRequestedOrientation(SCREEN_ORIENTATION_NOSENSOR);
cameraView.setPreviewConsumer(new QrCodeDecoder(this));
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
getActivity().setTitle("Scan QR Code");
View v = inflater.inflate(R.layout.fragment_contact_qr_code_input,
container, false);
cameraView = v.findViewById(R.id.camera_view);
// Button enterLinkButton = v.findViewById(R.id.enterLinkButton);
// enterLinkButton.setOnClickListener(view ->
// ((ContactInviteInputActivity) getActivity()).showLink());
return v;
}
public static final String TAG = ContactQrCodeInputFragment.class.getName();
@Override
public void onStart() {
super.onStart();
if (checkPermissions()) {
startCamera();
}
}
@Override
public void onStop() {
super.onStop();
try {
cameraView.stop();
} catch (CameraException e) {
e.printStackTrace();
}
}
private void startCamera() {
try {
cameraView.start();
} catch (CameraException e) {
e.printStackTrace();
Toast.makeText(getContext(), "Camera Error", LENGTH_SHORT)
.show();
}
}
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
}
private boolean checkPermissions() {
if (ActivityCompat.checkSelfPermission(getContext(), CAMERA) !=
PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(CAMERA)) {
DialogInterface.OnClickListener continueListener =
(dialog, which) -> requestPermission();
AlertDialog.Builder
builder = new AlertDialog.Builder(getContext(), R.style.BriarDialogTheme);
builder.setTitle(R.string.permission_camera_title);
builder.setMessage(R.string.permission_camera_request_body);
builder.setNeutralButton(R.string.continue_button,
continueListener);
builder.show();
} else {
requestPermission();
}
return false;
} else {
return true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_PERMISSION_CAMERA) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 &&
grantResults[0] == PERMISSION_GRANTED) {
startCamera();
} else {
if (!shouldShowRequestPermissionRationale(CAMERA)) {
// The user has permanently denied the request
AlertDialog.Builder
builder = new AlertDialog.Builder(getContext(),
R.style.BriarDialogTheme);
builder.setTitle(R.string.permission_camera_title);
builder.setMessage(R.string.permission_camera_denied_body);
builder.setPositiveButton(R.string.ok,
UiUtils.getGoToSettingsListener(getContext()));
builder.setNegativeButton(R.string.cancel,
(dialog, which) -> showLink(null));
builder.show();
} else {
Toast.makeText(getContext(),
R.string.permission_camera_denied_toast,
LENGTH_LONG).show();
showLink(null);
}
}
}
}
private void requestPermission() {
requestPermissions(new String[] {CAMERA}, REQUEST_PERMISSION_CAMERA);
}
private void showLink(@Nullable String link) {
if (getActivity() != null)
((ContactInviteInputActivity) getActivity()).showLink(link);
}
@Override
public void handleResult(Result result) {
Log.e("TEST", result.toString());
if (getActivity() != null &&
((ContactInviteInputActivity) getActivity())
.isBriarLink(result.getText())) {
showLink(result.getText());
}
}
}

View File

@@ -1,73 +0,0 @@
package org.briarproject.briar.android.contact;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.view.QrCodeView;
import javax.annotation.Nullable;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static org.briarproject.bramble.util.StringUtils.getRandomBase32String;
import static org.briarproject.briar.android.keyagreement.QrCodeUtils.createQrCode;
@NotNullByDefault
public class ContactQrCodeOutputFragment extends BaseFragment
implements QrCodeView.FullscreenListener {
private View linkIntro;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
getActivity().setTitle("Show my QR Code");
View v = inflater.inflate(R.layout.fragment_contact_qr_code_output,
container, false);
linkIntro = v.findViewById(R.id.linkIntro);
String link = "briar://" + getRandomBase32String(64);
DisplayMetrics dm = getResources().getDisplayMetrics();
Bitmap qrCode = createQrCode(dm, link);
QrCodeView qrCodeView = v.findViewById(R.id.qrCodeView);
qrCodeView.setQrCode(qrCode);
qrCodeView.setFullscreenListener(this);
Button showLinkButton = v.findViewById(R.id.showLinkButton);
showLinkButton.setOnClickListener(
view -> ((ContactInviteOutputActivity) getActivity()).showLink());
return v;
}
public static final String TAG = ContactQrCodeOutputFragment.class.getName();
@Override
public String getUniqueTag() {
return TAG;
}
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
}
@Override
public void setFullscreen(boolean fullscreen) {
linkIntro.setVisibility(fullscreen ? GONE : VISIBLE);
}
}

View File

@@ -1,122 +0,0 @@
package org.briarproject.briar.android.contact;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.LinearLayoutManager;
import android.view.MenuItem;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.contact.ContactManager;
import org.briarproject.bramble.api.contact.event.ContactAddedEvent;
import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.event.Event;
import org.briarproject.bramble.api.event.EventBus;
import org.briarproject.bramble.api.event.EventListener;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import org.briarproject.briar.android.view.BriarRecyclerView;
import org.briarproject.briar.api.messaging.MessagingManager;
import org.briarproject.briar.api.messaging.MessagingManager.PendingContact;
import java.util.Collection;
import javax.annotation.Nullable;
import javax.inject.Inject;
public class PendingRequestsActivity extends BriarActivity
implements EventListener {
@Inject
MessagingManager messagingManager;
@Inject
ContactManager contactManager;
@Inject
EventBus eventBus;
private PendingRequestsAdapter adapter;
private BriarRecyclerView list;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
}
@Override
public void onCreate(@Nullable Bundle state) {
super.onCreate(state);
setContentView(R.layout.list);
ActionBar ab = getSupportActionBar();
if (ab != null) {
ab.setDisplayHomeAsUpEnabled(true);
}
adapter = new PendingRequestsAdapter(this, PendingContact.class);
list = findViewById(R.id.list);
list.setLayoutManager(new LinearLayoutManager(this));
list.setAdapter(adapter);
}
@Override
public void onStart() {
super.onStart();
eventBus.addListener(this);
runOnDbThread(() -> {
try {
Collection<PendingContact> contacts =
messagingManager.getPendingContacts();
addPendingContacts(contacts);
} catch (DbException e) {
e.printStackTrace();
}
});
}
@Override
protected void onStop() {
super.onStop();
adapter.clear();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void eventOccurred(Event e) {
if (e instanceof ContactAddedEvent) {
runOnDbThread(() -> {
try {
Contact contact = contactManager
.getContact(((ContactAddedEvent) e).getContactId());
runOnUiThreadUnlessDestroyed(() -> {
adapter.remove(contact);
if (adapter.isEmpty()) finish();
});
} catch (DbException e1) {
e1.printStackTrace();
}
});
}
}
private void addPendingContacts(Collection<PendingContact> contacts) {
runOnUiThreadUnlessDestroyed(() -> {
if (contacts.isEmpty()) {
list.showData();
} else {
adapter.addAll(contacts);
}
});
}
}

View File

@@ -1,67 +0,0 @@
package org.briarproject.briar.android.contact;
import android.content.Context;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.briarproject.bramble.api.contact.Contact;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.util.BriarAdapter;
import org.briarproject.briar.api.messaging.MessagingManager.PendingContact;
@NotNullByDefault
public class PendingRequestsAdapter extends
BriarAdapter<PendingContact, PendingRequestsViewHolder> {
public PendingRequestsAdapter(Context ctx, Class<PendingContact> c) {
super(ctx, c);
}
@NonNull
@Override
public PendingRequestsViewHolder onCreateViewHolder(
ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.list_item_pending_contact, viewGroup, false);
return new PendingRequestsViewHolder(v);
}
@Override
public void onBindViewHolder(
PendingRequestsViewHolder pendingRequestsViewHolder, int i) {
pendingRequestsViewHolder.bind(items.get(i));
}
@Override
public int compare(PendingContact item1, PendingContact item2) {
return (int) (item1.getTimestamp() - item2.getTimestamp());
}
@Override
public boolean areContentsTheSame(PendingContact item1,
PendingContact item2) {
return item1.getName().equals(item2.getName()) &&
item1.getTimestamp() == item2.getTimestamp();
}
@Override
public boolean areItemsTheSame(PendingContact item1,
PendingContact item2) {
return item1.getName().equals(item2.getName()) &&
item1.getTimestamp() == item2.getTimestamp();
}
// TODO remove
public void remove(Contact contact) {
for (int i = 0; i < items.size(); i++) {
if (items.get(i).getName().equals(contact.getAuthor().getName())) {
items.removeItemAt(i);
return;
}
}
}
}

View File

@@ -1,36 +0,0 @@
package org.briarproject.briar.android.contact;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.view.View;
import android.widget.TextView;
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
import org.briarproject.briar.R;
import org.briarproject.briar.android.view.TextAvatarView;
import org.briarproject.briar.api.messaging.MessagingManager.PendingContact;
import static org.briarproject.bramble.util.StringUtils.toUtf8;
import static org.briarproject.briar.android.util.UiUtils.formatDate;
@NotNullByDefault
public class PendingRequestsViewHolder extends ViewHolder {
private final TextAvatarView avatar;
private final TextView name;
private final TextView time;
public PendingRequestsViewHolder(View v) {
super(v);
avatar = v.findViewById(R.id.avatar);
name = v.findViewById(R.id.name);
time = v.findViewById(R.id.time);
}
public void bind(PendingContact item) {
avatar.setText(item.getName());
avatar.setBackgroundBytes(toUtf8(item.getName() + item.getTimestamp()));
name.setText(item.getName());
time.setText(formatDate(time.getContext(), item.getTimestamp()));
}
}

View File

@@ -2,7 +2,7 @@ package org.briarproject.briar.android.keyagreement;
import java.io.IOException;
public class CameraException extends IOException {
class CameraException extends IOException {
CameraException(String message) {
super(message);

View File

@@ -7,7 +7,7 @@ import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
@SuppressWarnings("deprecation")
@NotNullByDefault
public interface PreviewConsumer {
interface PreviewConsumer {
@UiThread
void start(Camera camera, int cameraIndex);

View File

@@ -29,7 +29,7 @@ import static java.util.logging.Level.WARNING;
@SuppressWarnings("deprecation")
@MethodsNotNullByDefault
@ParametersNotNullByDefault
public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
private static final Logger LOG =
Logger.getLogger(QrCodeDecoder.class.getName());
@@ -40,7 +40,7 @@ public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
private Camera camera = null;
private int cameraIndex = 0;
public QrCodeDecoder(ResultCallback callback) {
QrCodeDecoder(ResultCallback callback) {
this.callback = callback;
}
@@ -141,7 +141,7 @@ public class QrCodeDecoder implements PreviewConsumer, PreviewCallback {
}
@NotNullByDefault
public interface ResultCallback {
interface ResultCallback {
void handleResult(Result result);
}

View File

@@ -21,13 +21,13 @@ import static java.util.logging.Level.WARNING;
import static org.briarproject.bramble.util.LogUtils.logException;
@NotNullByDefault
public class QrCodeUtils {
class QrCodeUtils {
private static final Logger LOG =
Logger.getLogger(QrCodeUtils.class.getName());
@Nullable
public static Bitmap createQrCode(DisplayMetrics dm, String input) {
static Bitmap createQrCode(DisplayMetrics dm, String input) {
int smallestDimen = Math.min(dm.widthPixels, dm.heightPixels);
try {
// Generate QR code

View File

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

View File

@@ -31,13 +31,12 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
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_PURGE = "pref_key_purge";
public static final String KEY_UNINSTALL = "pref_key_uninstall";
private static final Logger LOG =
Logger.getLogger(PanicPreferencesFragment.class.getName());
private PackageManager pm;
private SwitchPreference lockPref, purgePref, uninstallPref;
private SwitchPreference lockPref, purgePref;
private ListPreference panicAppPref;
@Override
@@ -49,7 +48,6 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
lockPref = (SwitchPreference) findPreference(KEY_LOCK);
panicAppPref = (ListPreference) findPreference(KEY_PANIC_APP);
purgePref = (SwitchPreference) findPreference(KEY_PURGE);
uninstallPref = (SwitchPreference) findPreference(KEY_UNINSTALL);
// check for connect/disconnect intents from panic trigger apps
if (PanicResponder.checkForDisconnectIntent(getActivity())) {
@@ -97,16 +95,11 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
showPanicApp(packageName);
if (packageName.equals(Panic.PACKAGE_NAME_NONE)) {
lockPref.setEnabled(false);
purgePref.setChecked(false);
purgePref.setEnabled(false);
uninstallPref.setChecked(false);
uninstallPref.setEnabled(false);
getActivity().setResult(Activity.RESULT_CANCELED);
} else {
lockPref.setEnabled(true);
purgePref.setEnabled(true);
uninstallPref.setEnabled(true);
}
return true;
@@ -145,27 +138,15 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
if (key.equals(KEY_PURGE)) {
// enable locking if purging gets enabled
if (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)) {
// enable locking if purging gets enabled
if (key.equals(KEY_PURGE) &&
sharedPreferences.getBoolean(KEY_PURGE, false)) {
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) &&
!sharedPreferences.getBoolean(KEY_LOCK, true)) {
purgePref.setChecked(false);
uninstallPref.setChecked(false);
}
}
@@ -179,10 +160,8 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
panicAppPref.setIcon(
android.R.drawable.ic_menu_close_clear_cancel);
// disable panic actions
lockPref.setEnabled(false);
// disable destructive panic actions
purgePref.setEnabled(false);
uninstallPref.setEnabled(false);
} else {
// display connected panic app
try {
@@ -192,10 +171,8 @@ public class PanicPreferencesFragment extends PreferenceFragmentCompat
panicAppPref.setIcon(
pm.getApplicationIcon(triggerPackageName));
// enable panic actions
lockPref.setEnabled(true);
// enable destructive panic actions
purgePref.setEnabled(true);
uninstallPref.setEnabled(true);
} catch (PackageManager.NameNotFoundException e) {
// revert back to no app, just to be safe
PanicResponder.setTriggerPackageName(getActivity(),

View File

@@ -2,7 +2,6 @@ package org.briarproject.briar.android.panic;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
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.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity;
import org.iilab.IilabEngineeringRSA2048Pin;
import java.util.logging.Logger;
@@ -22,10 +20,8 @@ import info.guardianproject.panic.Panic;
import info.guardianproject.panic.PanicResponder;
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_PURGE;
import static org.briarproject.briar.android.panic.PanicPreferencesFragment.KEY_UNINSTALL;
public class PanicResponderActivity extends BriarActivity {
@@ -44,8 +40,8 @@ public class PanicResponderActivity extends BriarActivity {
TrustedIntents trustedIntents = TrustedIntents.get(this);
// Guardian Project Ripple
trustedIntents.addTrustedSigner(GuardianProjectRSA4096.class);
// Amnesty International's Panic Button, made by iilab.org
trustedIntents.addTrustedSigner(IilabEngineeringRSA2048Pin.class);
// F-Droid
trustedIntents.addTrustedSigner(FDroidSignaturePin.class);
Intent intent = trustedIntents.getIntentFromTrustedSender(this);
if (intent != null) {
@@ -60,23 +56,16 @@ public class PanicResponderActivity extends BriarActivity {
LOG.info("Panic Trigger came from connected app");
// Performing panic responses
if (sharedPref.getBoolean(KEY_UNINSTALL, false)) {
if (sharedPref.getBoolean(KEY_PURGE, false)) {
LOG.info("Purging all data...");
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);
}
}
}

View File

@@ -39,9 +39,6 @@ public class QrCodeView extends FrameLayout {
listener.setFullscreen(fullscreen);
}
);
// TODO remove
fullscreenButton.setVisibility(INVISIBLE);
}
@UiThread

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M12,11c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM18,13c0,-3.31 -2.69,-6 -6,-6s-6,2.69 -6,6c0,2.22 1.21,4.15 3,5.19l1,-1.74c-1.19,-0.7 -2,-1.97 -2,-3.45 0,-2.21 1.79,-4 4,-4s4,1.79 4,4c0,1.48 -0.81,2.75 -2,3.45l1,1.74c1.79,-1.04 3,-2.97 3,-5.19zM12,3C6.48,3 2,7.48 2,13c0,3.7 2.01,6.92 4.99,8.65l1,-1.73C5.61,18.53 4,15.96 4,13c0,-4.42 3.58,-8 8,-8s8,3.58 8,8c0,2.96 -1.61,5.53 -4,6.92l1,1.73c2.99,-1.73 5,-4.95 5,-8.65 0,-5.52 -4.48,-10 -10,-10z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#2A93C6"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM19,5L8,5c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h11c1.1,0 2,-0.9 2,-2L21,7c0,-1.1 -0.9,-2 -2,-2zM19,21L8,21L8,7h11v14z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#2A93C6"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FF000000"
android:pathData="M19,2h-4.18C14.4,0.84 13.3,0 12,0c-1.3,0 -2.4,0.84 -2.82,2L5,2c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,4c0,-1.1 -0.9,-2 -2,-2zM12,2c0.55,0 1,0.45 1,1s-0.45,1 -1,1 -1,-0.45 -1,-1 0.45,-1 1,-1zM19,20L5,20L5,4h2v3h10L17,4h2v16z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M3.9,12c0,-1.71 1.39,-3.1 3.1,-3.1h4L11,7L7,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5h4v-1.9L7,15.1c-1.71,0 -3.1,-1.39 -3.1,-3.1zM8,13h8v-2L8,11v2zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1s-1.39,3.1 -3.1,3.1h-4L13,17h4c2.76,0 5,-2.24 5,-5s-2.24,-5 -5,-5z"/>
</vector>

View File

@@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M16,6H13V7.9H16C18.26,7.9 20.1,9.73 20.1,12A4.1,4.1 0,0 1,16 16.1H13V18H16A6,6 0,0 0,22 12C22,8.68 19.31,6 16,6M3.9,12C3.9,9.73 5.74,7.9 8,7.9H11V6H8A6,6 0,0 0,2 12A6,6 0,0 0,8 18H11V16.1H8C5.74,16.1 3.9,14.26 3.9,12M8,13H16V11H8V13Z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="m21.6598,17.4732h-2.2959v3.0612H17.5118l3,3 3,-3h-1.852z"/>
</vector>

View File

@@ -1,12 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M16,6H13V7.9H16C18.26,7.9 20.1,9.73 20.1,12A4.1,4.1 0,0 1,16 16.1H13V18H16A6,6 0,0 0,22 12C22,8.68 19.31,6 16,6M3.9,12C3.9,9.73 5.74,7.9 8,7.9H11V6H8A6,6 0,0 0,2 12A6,6 0,0 0,8 18H11V16.1H8C5.74,16.1 3.9,14.26 3.9,12M8,13H16V11H8V13Z"/>
<path
android:fillColor="#FFFFFF"
android:pathData="M21.6598,23.5344H19.3639V20.4732H17.5118l3,-3 3,3h-1.852z"/>
</vector>

View File

@@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View File

@@ -1,5 +0,0 @@
<vector android:height="24dp" android:tint="#FFFFFF"
android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M15,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM6,10L6,7L4,7v3L1,10v2h3v3h2v-3h3v-2L6,10zM15,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
</vector>

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#2A93C6"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M3,11H5V13H3V11M11,5H13V9H11V5M9,11H13V15H11V13H9V11M15,11H17V13H19V11H21V13H19V15H21V19H19V21H17V19H13V21H11V17H15V15H17V13H15V11M19,19V15H17V19H19M15,3H21V9H15V3M17,5V7H19V5H17M3,3H9V9H3V3M5,5V7H7V5H5M3,15H9V21H3V15M5,17V19H7V17H5Z"/>
</vector>

View File

@@ -1,9 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<path
android:fillColor="#FFFFFF"
android:pathData="M4,4H10V10H4V4M20,4V10H14V4H20M14,15H16V13H14V11H16V13H18V11H20V13H18V15H20V18H18V20H16V18H13V20H11V16H14V15M16,15V18H18V15H16M4,20V14H10V20H4M6,6V8H8V6H6M16,6V8H18V6H16M6,16V18H8V16H6M4,11H6V13H4V11M9,11H13V15H11V13H9V11M11,6H13V10H11V6M2,2V6H0V2A2,2 0 0,1 2,0H6V2H2M22,0A2,2 0 0,1 24,2V6H22V2H18V0H22M2,18V22H6V24H2A2,2 0 0,1 0,22V18H2M22,22V18H24V22A2,2 0 0,1 22,24H18V22H22Z"/>
</vector>

View File

@@ -2,7 +2,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path

View File

@@ -2,7 +2,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path

View File

@@ -2,7 +2,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path

View File

@@ -2,7 +2,6 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path

View File

@@ -1,10 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="#2A93C6"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="#FFFFFFFF"
android:pathData="M18,16.08c-0.76,0 -1.44,0.3 -1.96,0.77L8.91,12.7c0.05,-0.23 0.09,-0.46 0.09,-0.7s-0.04,-0.47 -0.09,-0.7l7.05,-4.11c0.54,0.5 1.25,0.81 2.04,0.81 1.66,0 3,-1.34 3,-3s-1.34,-3 -3,-3 -3,1.34 -3,3c0,0.24 0.04,0.47 0.09,0.7L8.04,9.81C7.5,9.31 6.79,9 6,9c-1.66,0 -3,1.34 -3,3s1.34,3 3,3c0.79,0 1.5,-0.31 2.04,-0.81l7.12,4.16c-0.05,0.21 -0.08,0.43 -0.08,0.65 0,1.61 1.31,2.92 2.92,2.92 1.61,0 2.92,-1.31 2.92,-2.92s-1.31,-2.92 -2.92,-2.92z"/>
</vector>

View File

@@ -28,6 +28,8 @@
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_large"
app:hintEnabled="false"
@@ -50,6 +52,8 @@
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"

View File

@@ -40,6 +40,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_small"

View File

@@ -9,6 +9,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/margin_activity_horizontal"
android:layout_marginStart="@dimen/margin_activity_horizontal"
android:layout_marginTop="@dimen/margin_activity_vertical"
android:checked="false"
android:text="@string/don_t_ask_again"/>

View File

@@ -1,37 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/contactNameInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:hint="@string/contact_name_hint"
android:importantForAutofill="no"
android:inputType="text|textCapWords"
app:layout_constraintBottom_toTopOf="@id/linkInput"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"/>
<Button
android:id="@+id/addButton"
style="@style/BriarButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:layout_marginTop="8dp"
android:enabled="false"
android:text="@string/add_contact_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/contactNameInput"
tools:enabled="true"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -1,95 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/contactNameInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:drawableLeft="@drawable/ic_person"
android:drawablePadding="8dp"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_name_hint"
android:importantForAutofill="no"
android:inputType="text|textCapWords"
app:layout_constraintBottom_toTopOf="@id/linkInput"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
android:drawableStart="@drawable/ic_person"/>
<EditText
android:id="@+id/linkInput"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="@dimen/margin_large"
android:layout_marginRight="8dp"
android:layout_marginStart="@dimen/margin_large"
android:layout_marginTop="16dp"
android:drawableLeft="@drawable/ic_link"
android:drawablePadding="8dp"
android:drawableTint="?attr/colorControlNormal"
android:hint="@string/contact_link_hint"
android:importantForAutofill="no"
android:inputType="textUri"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/contactNameInput"/>
<Button
android:id="@+id/pasteButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:drawableLeft="@drawable/ic_content_paste"
android:drawablePadding="8dp"
android:text="@string/paste_button"
app:layout_constraintEnd_toStartOf="@+id/scanCodeButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkInput"/>
<Button
android:id="@+id/scanCodeButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:drawableLeft="@drawable/ic_qr_code"
android:drawablePadding="8dp"
android:text="Scan Code"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/pasteButton"
app:layout_constraintTop_toBottomOf="@+id/linkInput"/>
<Button
android:id="@+id/addButton"
style="@style/BriarButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:layout_marginTop="8dp"
android:enabled="false"
android:text="@string/add_contact_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.75"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pasteButton"
tools:enabled="true"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/linkIntro"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:text="@string/send_link_instructions"
android:textIsSelectable="true"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@id/linkView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"/>
<TextView
android:id="@+id/linkView"
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:background="@color/briar_white"
android:padding="8dp"
android:textColor="@color/briar_primary"
android:textIsSelectable="true"
android:textSize="18sp"
android:typeface="monospace"
app:layout_constraintBottom_toTopOf="@+id/copyButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/linkIntro"
tools:text="briar://scnsdflamslkfjgluoblmksdfbwevlewajfdlkjewwhqliafskfjhskdjhvoieiv"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/copyButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_large"
android:drawableLeft="@drawable/ic_content_copy"
android:drawablePadding="8dp"
android:text="@string/copy_button"
app:layout_constraintEnd_toStartOf="@+id/shareButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkView"/>
<Button
android:id="@+id/shareButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/social_share_blue"
android:drawablePadding="8dp"
android:text="@string/share_button"
app:layout_constraintBottom_toBottomOf="@id/copyButton"
app:layout_constraintEnd_toStartOf="@+id/showCodeButton"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/copyButton"
app:layout_constraintTop_toTopOf="@id/copyButton"/>
<Button
android:id="@+id/showCodeButton"
style="@style/BriarButtonFlat.Positive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/ic_qr_code"
android:drawablePadding="8dp"
android:drawableTint="@color/briar_button_text_positive"
android:text="QR Code"
app:layout_constraintBottom_toBottomOf="@+id/copyButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/shareButton"
app:layout_constraintTop_toTopOf="@+id/copyButton"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.briarproject.briar.android.view.BriarRecyclerView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:scrollToEnd="false"/>
<io.github.kobakei.materialfabspeeddial.FabSpeedDial
android:id="@+id/speedDial"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fab_fabDrawable="@drawable/ic_action_add"
app:fab_fabRippleColor="@android:color/transparent"
app:fab_menu="@menu/contact_list_actions"
app:fab_miniFabTextBackground="@color/briar_accent"
app:fab_miniFabTextColor="@android:color/white"/>
</android.support.design.widget.CoordinatorLayout>

View File

@@ -1,53 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.briarproject.briar.android.keyagreement.CameraView
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/textView3"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:visibility="gone"
android:text="or"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/enterLinkButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/camera_view"/>
<Button
android:id="@+id/enterLinkButton"
style="@style/BriarButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:drawableLeft="@drawable/ic_link"
android:drawablePadding="8dp"
android:visibility="gone"
android:text="Enter Link"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView3"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/linkIntro"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:text="@string/send_code_instructions"
android:textIsSelectable="true"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/qrCodeView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0"
android:visibility="gone"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintVertical_weight="1"
tools:visibility="gone"/>
<org.briarproject.briar.android.view.QrCodeView
android:id="@+id/qrCodeView"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="@android:color/white"
android:textIsSelectable="true"
android:textSize="18sp"
android:typeface="monospace"
app:layout_constraintBottom_toTopOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linkIntro"
app:layout_constraintVertical_weight="1"/>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="or"
android:visibility="gone"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/showLinkButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/qrCodeView"/>
<Button
android:id="@+id/showLinkButton"
style="@style/BriarButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:drawableLeft="@drawable/ic_link"
android:drawablePadding="8dp"
android:visibility="gone"
android:text="Show Link"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintVertical_bias="1.0"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -11,6 +11,8 @@
android:layout_width="128dp"
android:layout_height="128dp"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:src="@drawable/alerts_and_states_error"
@@ -25,6 +27,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="@string/sorry"

View File

@@ -27,6 +27,8 @@
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"
@@ -66,6 +68,8 @@
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"

View File

@@ -19,6 +19,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
android:layout_marginEnd="@dimen/listitem_vertical_margin"
android:layout_marginLeft="@dimen/listitem_vertical_margin"
android:layout_marginRight="@dimen/listitem_vertical_margin"
android:layout_marginStart="@dimen/listitem_vertical_margin"
android:layout_marginTop="@dimen/listitem_vertical_margin"
app:layout_constraintEnd_toStartOf="@+id/commentView"
@@ -32,10 +34,11 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
android:layout_marginEnd="@dimen/listitem_vertical_margin"
android:layout_marginLeft="@dimen/listitem_vertical_margin"
android:layout_marginRight="@dimen/listitem_vertical_margin"
android:layout_marginStart="@dimen/listitem_vertical_margin"
android:layout_marginTop="@dimen/listitem_vertical_margin"
app:layout_constraintEnd_toStartOf="@+id/commentView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/rebloggerView"/>

View File

@@ -48,6 +48,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginTop="@dimen/listitem_vertical_margin"
android:paddingEnd="@dimen/margin_medium"
@@ -67,6 +69,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/listitem_vertical_margin"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:paddingEnd="@dimen/margin_medium"
android:paddingStart="@dimen/margin_medium"

View File

@@ -24,6 +24,8 @@
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:layout_weight="1"
android:maxLines="2"

View File

@@ -5,11 +5,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:layout_marginTop="@dimen/message_bubble_margin"
android:orientation="vertical">
@@ -18,6 +13,10 @@
style="@style/TextMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:background="@drawable/msg_in_top"
android:elevation="@dimen/message_bubble_elevation"
tools:text="Short message"/>
@@ -26,6 +25,11 @@
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:background="@drawable/notice_in_bottom"
android:elevation="@dimen/message_bubble_elevation">

View File

@@ -5,11 +5,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
android:layout_marginRight="@dimen/message_bubble_margin_tail"
android:layout_marginStart="@dimen/message_bubble_margin_non_tail"
android:layout_marginTop="@dimen/message_bubble_margin"
android:orientation="vertical">
@@ -18,6 +13,10 @@
style="@style/TextMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/message_bubble_margin_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
android:layout_marginRight="@dimen/message_bubble_margin_tail"
android:layout_marginStart="@dimen/message_bubble_margin_non_tail"
android:background="@drawable/msg_out_top"
android:elevation="@dimen/message_bubble_elevation"
android:textColor="@color/briar_text_primary_inverse"
@@ -27,6 +26,11 @@
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_non_tail"
android:layout_marginRight="@dimen/message_bubble_margin_tail"
android:layout_marginStart="@dimen/message_bubble_margin_non_tail"
android:background="@drawable/notice_out_bottom"
android:elevation="@dimen/message_bubble_elevation">

View File

@@ -5,11 +5,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:layout_marginTop="@dimen/message_bubble_margin"
android:orientation="vertical">
@@ -18,6 +13,10 @@
style="@style/TextMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:background="@drawable/msg_in_top"
android:elevation="@dimen/message_bubble_elevation"
android:textColor="?android:attr/textColorPrimary"
@@ -27,6 +26,11 @@
android:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/message_bubble_margin"
android:layout_marginEnd="@dimen/message_bubble_margin_non_tail"
android:layout_marginLeft="@dimen/message_bubble_margin_tail"
android:layout_marginRight="@dimen/message_bubble_margin_non_tail"
android:layout_marginStart="@dimen/message_bubble_margin_tail"
android:background="@drawable/notice_in_bottom"
android:elevation="@dimen/message_bubble_elevation">

View File

@@ -22,6 +22,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_horizontal_margin"
android:textColor="?android:attr/textColorPrimary"

View File

@@ -47,6 +47,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/margin_medium"
android:textColor="?android:attr/textColorSecondary"
@@ -75,6 +77,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/margin_medium"
android:textColor="?android:attr/textColorTertiary"

View File

@@ -20,6 +20,7 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_medium"
app:layout_constraintEnd_toEndOf="parent"
@@ -46,6 +47,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/margin_medium"
android:text="@string/forum_invitation_exists"

View File

@@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:id="@+id/linearLayout4"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<org.briarproject.briar.android.view.TextAvatarView
android:id="@+id/avatar"
android:layout_width="@dimen/listitem_picture_frame_size"
android:layout_height="@dimen/listitem_picture_frame_size"
android:layout_marginBottom="8dp"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/divider"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<com.vanniktech.emoji.EmojiTextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_large"
android:layout_marginStart="@dimen/margin_large"
android:layout_marginTop="@dimen/margin_large"
android:textColor="?android:attr/textColorPrimary"
android:textSize="@dimen/text_size_medium"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toTopOf="@+id/status"
app:layout_constraintEnd_toStartOf="@+id/time"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="spread_inside"
app:layout_constraintStart_toEndOf="@+id/avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="This is a name of a contact"/>
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_marginTop="8dp"
android:text="@string/add_contact_remote_connecting"
app:layout_constraintBottom_toTopOf="@+id/divider"
app:layout_constraintEnd_toStartOf="@+id/time"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/name"
app:layout_constraintTop_toBottomOf="@+id/name"/>
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/margin_large"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:textColor="?android:attr/textColorSecondary"
android:textSize="@dimen/text_size_small"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/name"
app:layout_constraintTop_toTopOf="parent"
tools:text="Dec 24"/>
<View
android:id="@+id/divider"
style="@style/Divider.ContactList"
android:layout_width="0dp"
android:layout_marginLeft="8dp"
android:layout_marginStart="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/avatar"/>
</android.support.constraint.ConstraintLayout>

View File

@@ -23,6 +23,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_vertical_margin"
android:textColor="?android:attr/textColorPrimary"
@@ -51,6 +53,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/listitem_vertical_margin"
android:layout_marginEnd="@dimen/margin_small"
android:layout_marginLeft="@dimen/margin_small"
android:layout_marginRight="@dimen/margin_small"
android:layout_marginStart="@dimen/margin_small"
android:text="@string/groups_reveal_visible"
android:textColor="?android:attr/textColorSecondary"

View File

@@ -116,6 +116,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/margin_medium"
android:textColor="?android:attr/textColorSecondary"

View File

@@ -24,6 +24,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:layout_marginTop="@dimen/listitem_horizontal_margin"
android:textColor="?android:attr/textColorPrimary"
@@ -41,6 +43,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/listitem_horizontal_margin"
android:layout_marginEnd="@dimen/listitem_horizontal_margin"
android:layout_marginLeft="@dimen/listitem_horizontal_margin"
android:layout_marginRight="@dimen/listitem_horizontal_margin"
android:layout_marginStart="@dimen/listitem_horizontal_margin"
android:maxLines="2"
android:text="@string/forum_invitation_already_sharing"

View File

@@ -96,6 +96,8 @@
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/btn_reply"
@@ -109,6 +111,8 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:text="@string/btn_reply"
android:textSize="@dimen/text_size_tiny"

View File

@@ -13,6 +13,8 @@
android:layout_gravity="bottom|start"
android:layout_marginBottom="@dimen/margin_medium"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:contentDescription="@string/app_name"
android:src="@drawable/navigation_drawer_header"/>

View File

@@ -12,6 +12,8 @@
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:textSize="@dimen/text_size_medium"

View File

@@ -17,6 +17,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/listitem_picture_frame_offset_horizontal"
android:layout_marginRight="@dimen/listitem_picture_frame_offset_horizontal"
android:layout_marginTop="@dimen/listitem_picture_frame_offset_vertical"
android:maxLength="1"

View File

@@ -12,6 +12,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="@dimen/margin_medium"
android:layout_marginLeft="@dimen/margin_medium"
android:layout_marginRight="@dimen/margin_medium"
android:layout_marginStart="@dimen/margin_medium"
android:layout_marginTop="@dimen/margin_medium"
android:elevation="@dimen/cardview_default_elevation"

View File

@@ -5,23 +5,8 @@
<item
android:id="@+id/action_add_contact"
android:icon="@drawable/ic_add_nearby"
android:orderInCategory="3"
android:title="@string/add_contact_nearby_title"
app:showAsAction="never"/>
<item
android:id="@+id/action_open_link"
android:icon="@drawable/ic_link_down"
android:orderInCategory="2"
android:title="@string/open_code_title"
app:showAsAction="never"/>
<item
android:id="@+id/action_send_link"
android:icon="@drawable/ic_link_up"
android:orderInCategory="1"
android:title="@string/send_code_title"
app:showAsAction="never"/>
android:icon="@drawable/ic_add_white"
android:title="@string/add_contact_title"
app:showAsAction="ifRoom"/>
</menu>

View File

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_switch"
android:title="@string/show_link"
app:showAsAction="never"/>
</menu>

View File

@@ -149,7 +149,6 @@
<string name="contact_added_toast">تم إضافة جهة إتصال: %s</string>
<string name="contact_already_exists">جهة الإتصال %s بالفعل موجودة</string>
<string name="qr_code_invalid">رمز QR غير صالح</string>
<string name="qr_code_unsupported">رمز QR الذي تحاول مسحه يعود لإصدار قديم من %s لم يعد مدعومًا.\n\nمن فضلك تأكد أن كليكما يستخدم آخر إصدار ثم حاول مجددًا.</string>
<string name="camera_error">خطأ بالكاميرا</string>
<string name="connecting_to_device">يتم الإتصال بالجهاز\u2026</string>
<string name="authenticating_with_device">يتم التوثيق مع الجهاز\u2026</string>
@@ -379,10 +378,8 @@
<string name="tor_mobile_data_title">إستخدم بيانات الجوال</string>
<!--Settings Security and Panic-->
<string name="security_settings_title">الأمان</string>
<string name="pref_lock_title">قفل الشاشة</string>
<string name="pref_lock_summary">استخدم قفل شاشة الجهاز لحماية Briar (براير) في حال تسجيل الدخول</string>
<string name="pref_lock_disabled_summary">لاستخدام هذه الميزة، قم بإعداد قفل شاشة لجهازك</string>
<string name="pref_lock_timeout_title">زمن قفل الشاشة عند عدم النشاط</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">حينما لا تستخدم Briar (براير)، أقفله تلقائيا بعد %s</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
@@ -434,8 +431,6 @@
<string name="notify_blog_posts_setting_summary">أظهر التنبيهات للتدوينات</string>
<string name="notify_blog_posts_setting_summary_26">اضبط التنبيهات للتدوينات</string>
<string name="notify_vibration_setting">إهتزاز</string>
<string name="notify_lock_screen_setting_title">قفل الشاشة</string>
<string name="notify_lock_screen_setting_summary">أظهر التنبيهات على قفل الشاشة</string>
<string name="notify_sound_setting">الصوت</string>
<string name="notify_sound_setting_default">النغمة الافتراضية</string>
<string name="notify_sound_setting_disabled">لا شيء</string>

View File

@@ -129,7 +129,6 @@
<string name="contact_added_toast">S\'ha afegit el contacte %s</string>
<string name="contact_already_exists">El contacte %s ja existia</string>
<string name="qr_code_invalid">El codi QR és invàlid</string>
<string name="qr_code_unsupported">El codi QR que intenteu escanejar pertany a una versió antiga de %s que ja no és compatible.\n\nAssegureu-vos que tothom està executant la darrera versió i torneu a provar-ho.</string>
<string name="camera_error">Error de la càmera</string>
<string name="connecting_to_device">Connectant-se al dispositiu\u2026</string>
<string name="authenticating_with_device">Autenticant-se amb el dispositiu\u2026</string>
@@ -339,10 +338,8 @@
<string name="tor_mobile_data_title">Usa dades mòbils</string>
<!--Settings Security and Panic-->
<string name="security_settings_title">Seguretat</string>
<string name="pref_lock_title">Bloqueig de pantalla</string>
<string name="pref_lock_summary">Usa el bloqueig de pantalla del dispositiu per protegir Briar mentre inicieu la sessió</string>
<string name="pref_lock_disabled_summary">Per utilitzar aquesta funció, configureu el bloqueig de pantalla en el vostre dispositiu</string>
<string name="pref_lock_timeout_title">Temps d\'inactivitat del bloqueig de pantalla</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">Briar es bloquejarà automàticament després de %s de no usar-se.</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
@@ -394,8 +391,6 @@
<string name="notify_blog_posts_setting_summary">Mostra avisos pels apunts als blogs</string>
<string name="notify_blog_posts_setting_summary_26">Configura els avisos pels apunts als blogs</string>
<string name="notify_vibration_setting">Vibra</string>
<string name="notify_lock_screen_setting_title">Bloca la pantalla</string>
<string name="notify_lock_screen_setting_summary">Mostra les notificacions a la pantalla de bloqueig</string>
<string name="notify_sound_setting">So</string>
<string name="notify_sound_setting_default">So d\'avís predeterminat</string>
<string name="notify_sound_setting_disabled">Cap</string>

View File

@@ -132,7 +132,6 @@
<string name="contact_added_toast">Kontakt byl přidán: %s</string>
<string name="contact_already_exists">Kontakt %s již existuje</string>
<string name="qr_code_invalid">QR kód je neplatný</string>
<string name="qr_code_unsupported">QR kód, který se pokoušíte skenovat, patří k starší verzi %s, která již není podporována.\n\nJe potřebné, aby oba kontakty používali nejnovější verzi a následně to zkuste znovu.</string>
<string name="camera_error">Vyskytla se chyba fotoaparátu</string>
<string name="connecting_to_device">Připojování k zařízení\u2026</string>
<string name="authenticating_with_device">Ověřování se zařízením\u2026</string>
@@ -366,8 +365,6 @@
<string name="notify_blog_posts_setting_summary">Zobrazit upozornění pro příspěvky v blogu</string>
<string name="notify_blog_posts_setting_summary_26">Nastavení upozornění pro příspěvky blogu</string>
<string name="notify_vibration_setting">Vibrovat</string>
<string name="notify_lock_screen_setting_title">Zamčená obrazovka</string>
<string name="notify_lock_screen_setting_summary">Zobrazit oznámení na zamčené obrazovce</string>
<string name="notify_sound_setting">Zvuk</string>
<string name="notify_sound_setting_default">Výchozí vyzvánění</string>
<string name="notify_sound_setting_disabled">Žádný</string>

View File

@@ -129,7 +129,6 @@
<string name="contact_added_toast">Kontakt hinzugefügt: %s</string>
<string name="contact_already_exists">Kontakt %s existiert bereits</string>
<string name="qr_code_invalid">Der QR-Code ist ungültig</string>
<string name="qr_code_unsupported">Der QR-Code, den du zu scannen versuchst, gehört zu einer alten Version von %s, welche nicht mehr unterstützt wird.\n\nBitte versichert euch, dass bei euch beiden die neueste Version läuft und versucht es dann erneut.</string>
<string name="camera_error">Kamerafehler</string>
<string name="connecting_to_device">Verbinde mit Gerät\u2026</string>
<string name="authenticating_with_device">Authentifiziere Gerät\u2026</string>
@@ -339,10 +338,8 @@
<string name="tor_mobile_data_title">Mobile Daten benutzen</string>
<!--Settings Security and Panic-->
<string name="security_settings_title">Sicherheit</string>
<string name="pref_lock_title">Bildschirmsperre</string>
<string name="pref_lock_summary">Systemsperrbildschirm benutzen um Briar zu schützen, während angemeldet</string>
<string name="pref_lock_disabled_summary">Um dieses Feature zu benutzen aktiviere den Systemsperrbildschirm</string>
<string name="pref_lock_timeout_title">Inaktivitätstimeout Systemsperrbildschirm</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">Briar automatisch nach %s sperren, wenn unbenutzt.</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
@@ -394,8 +391,6 @@
<string name="notify_blog_posts_setting_summary">Benachrichtigungen für Blogbeiträge anzeigen</string>
<string name="notify_blog_posts_setting_summary_26">Benachrichtigungen für Blogbeiträge konfigurieren</string>
<string name="notify_vibration_setting">Vibration</string>
<string name="notify_lock_screen_setting_title">Sperrbildschirm</string>
<string name="notify_lock_screen_setting_summary">Benachrichtigungen auf dem Sperrbildschirm anzeigen</string>
<string name="notify_sound_setting">Ton</string>
<string name="notify_sound_setting_default">Standardklingelton</string>
<string name="notify_sound_setting_disabled">Keine</string>

View File

@@ -129,7 +129,8 @@
<string name="contact_added_toast">Contacto añadido: %s</string>
<string name="contact_already_exists">El contacto %s ya existe</string>
<string name="qr_code_invalid">El código QR no es válido</string>
<string name="qr_code_unsupported">El código QR que intentas escanear pertenece a una versión anterior de %s que ya no es compatible.\n\nAsegúrate de que ambos estén ejecutando la última versión y luego inténtalo de nuevo.</string>
<string name="qr_code_too_old">El código QR que has escaneado proviene de una versión anterior de %s.\n\nPor favor solicita a tu contacto que actualice a la última versión y luego intenta nuevamente.</string>
<string name="qr_code_too_new">El código QR que has escaneado proviene de una versión posterior de %s.\n\nPor favor actualiza a la última versión y luego intenta nuevamente.</string>
<string name="camera_error">Error de cámara</string>
<string name="connecting_to_device">Conectando al dispositivo\u2026</string>
<string name="authenticating_with_device">Autentificándose con el dispositivo\u2026</string>
@@ -339,10 +340,10 @@
<string name="tor_mobile_data_title">Usar datos móviles</string>
<!--Settings Security and Panic-->
<string name="security_settings_title">Seguridad</string>
<string name="pref_lock_title">Bloqueo de pantalla</string>
<string name="pref_lock_title">Bloqueo de apli</string>
<string name="pref_lock_summary">Usar el bloqueo de pantalla del dispositivo para proteger Briar mientras estés con sesión iniciada.</string>
<string name="pref_lock_disabled_summary">Para usar esta característica, configurar un bloqueo de pantalla para tu dispositivo</string>
<string name="pref_lock_timeout_title">Expiración por inactividad. Pantalla bloqueada</string>
<string name="pref_lock_timeout_title">Tiempo alcanzado para bloqueo de apli por inactividad</string>
<!--The %s placeholder is replaced with the following time spans, e.g. 5 Minutes, 1 Hour-->
<string name="pref_lock_timeout_summary">Cuando no se está usando Briar, bloquearlo automáticamente luego de %s</string>
<!--Will be shown in a list of lock times. Should fit into the %s of "automatically lock it after %s"-->
@@ -371,6 +372,7 @@
<string name="panic_app_setting_none">Ninguna</string>
<string name="dialog_title_connect_panic_app">Confirmar aplicación de pánico</string>
<string name="dialog_message_connect_panic_app">¿Seguro que quieres permitir que %1$s desencadene acciones destructivas de botón de pánico?</string>
<string name="panic_setting_destructive_action">Acciones destructivas</string>
<string name="panic_setting_signout_title">Cerrar sesión</string>
<string name="panic_setting_signout_summary">Cerrar la sesión de Briar si se pulsa un botón de pánico</string>
<string name="purge_setting_title">Eliminar cuenta</string>
@@ -394,8 +396,6 @@
<string name="notify_blog_posts_setting_summary">Mostrar notificaciones para artículos de blog</string>
<string name="notify_blog_posts_setting_summary_26">Configurar notificaciones para artículos de blog</string>
<string name="notify_vibration_setting">Vibrar</string>
<string name="notify_lock_screen_setting_title">Bloqueo de Pantalla</string>
<string name="notify_lock_screen_setting_summary">Notificaciones en la pantalla de bloqueo</string>
<string name="notify_sound_setting">Sonido</string>
<string name="notify_sound_setting_default">Tono de notificación predeterminado</string>
<string name="notify_sound_setting_disabled">Ninguno</string>

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