Compare commits

...

10 Commits

Author SHA1 Message Date
akwizgran
264d110dbd Bump version numbers for 1.2.17 release. 2021-03-11 12:35:19 +00:00
akwizgran
839b871a45 Merge branch 'aarch64-finalization' into 'master'
Make headless work on aarch64 and armhf (armv7)

Closes #1854

See merge request briar/briar!1376
2021-03-11 12:28:55 +00:00
Torsten Grote
3f9a66b1b6 Merge branch '1964-no-colons' into 'master'
Remove colons from default filename

Closes #1964

See merge request briar/briar!1400
2021-03-11 11:36:49 +00:00
akwizgran
d796916387 Also remove colons on API >= 19. 2021-03-11 10:33:53 +00:00
akwizgran
fe07b760ea Remove colons from default filename. 2021-03-10 15:44:15 +00:00
Nico Alt
e21e6267d7 Update Tor dependency to include armhf binary
Related MR:
https://code.briarproject.org/briar/tor-reproducer/-/merge_requests/13
2021-03-09 10:46:43 +01:00
Nico Alt
d7afbdf690 Use Tor binary for armhf (armv7)
Example devices are Nexus 5 and Raspberry Pi v2.

Based on https://code.briarproject.org/briar/briar/-/merge_requests/1376

Related to https://code.briarproject.org/briar/briar/-/issues/1854
2021-03-09 12:00:00 +00:00
Torsten Grote
c5d2661c1d Merge branch '1919-password-fields-not-focusable' into 'master'
Condition display of progressbar on a isCreatingAccount LiveData

Closes #1819 and #1919

See merge request briar/briar!1355
2021-03-03 13:10:29 +00:00
Nico Alt
b738bdd14e Actually make headless work on arm aarch64
Following the two comments at
https://code.briarproject.org/briar/briar/-/issues/1854#note_44340

.jar files now get built with

    $ ./gradlew --configure-on-demand briar-headless:x86LinuxJar
    $ ./gradlew --configure-on-demand briar-headless:aarch64LinuxJar

Related to #1854
2021-03-03 12:00:00 +00:00
Daniel Lublin
6b61725c6a Condition display of progressbar on a isCreatingAccount LiveData
Avoiding the mess with saving onSaveInstanceState, and the (in this
case) unwanted restoring of it upon back-button tap.

Closes #1919

Test instructions:

- Precondition: fresh install, setting up a new account
  - Testing specific bug fix:
    - Choose a name, tap next
    - Choose a password, tap next
      - Not testable on some devices which display "Create account" instead of "Next"
    - You are now on Background connections screen
    - Tap Back-button ◁
    - Ensure that password can be changed again
  - During setup process, rotate device and ensure that:
    - entered text is kept
    - progressbar is continuously displayed
2021-02-17 13:57:08 +01:00
13 changed files with 87 additions and 75 deletions

View File

@@ -11,8 +11,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 10216 versionCode 10217
versionName "1.2.16" versionName "1.2.17"
consumerProguardFiles 'proguard-rules.txt' consumerProguardFiles 'proguard-rules.txt'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

View File

@@ -16,7 +16,7 @@ dependencies {
implementation fileTree(dir: 'libs', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar')
implementation 'net.java.dev.jna:jna:4.5.2' implementation 'net.java.dev.jna:jna:4.5.2'
implementation 'net.java.dev.jna:jna-platform:4.5.2' implementation 'net.java.dev.jna:jna-platform:4.5.2'
tor 'org.briarproject:tor:0.3.5.13@zip' tor 'org.briarproject:tor:0.3.5.13-1@zip'
tor 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a@zip' tor 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a@zip'
annotationProcessor 'com.google.dagger:dagger-compiler:2.24' annotationProcessor 'com.google.dagger:dagger-compiler:2.24'

View File

@@ -25,6 +25,7 @@ import javax.annotation.concurrent.Immutable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.net.SocketFactory; import javax.net.SocketFactory;
import static java.util.logging.Level.INFO;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.util.OsUtils.isLinux; import static org.briarproject.bramble.util.OsUtils.isLinux;
@@ -96,8 +97,15 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
String architecture = null; String architecture = null;
if (isLinux()) { if (isLinux()) {
String arch = System.getProperty("os.arch"); String arch = System.getProperty("os.arch");
if (LOG.isLoggable(INFO)) {
LOG.info("System's os.arch is " + arch);
}
if (arch.equals("amd64")) { if (arch.equals("amd64")) {
architecture = "linux-x86_64"; architecture = "linux-x86_64";
} else if (arch.equals("aarch64")) {
architecture = "linux-aarch64";
} else if (arch.equals("arm")) {
architecture = "linux-armhf";
} }
} }
if (architecture == null) { if (architecture == null) {
@@ -105,6 +113,10 @@ public class UnixTorPluginFactory implements DuplexPluginFactory {
return null; return null;
} }
if (LOG.isLoggable(INFO)) {
LOG.info("The selected architecture for Tor is " + architecture);
}
Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL, Backoff backoff = backoffFactory.createBackoff(MIN_POLLING_INTERVAL,
MAX_POLLING_INTERVAL, BACKOFF_BASE); MAX_POLLING_INTERVAL, BACKOFF_BASE);
TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl(); TorRendezvousCrypto torRendezvousCrypto = new TorRendezvousCryptoImpl();

View File

@@ -24,7 +24,7 @@ dependencyVerification {
'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8', 'org.apache.ant:ant:1.9.4:ant-1.9.4.jar:649ae0730251de07b8913f49286d46bba7b92d47c5f332610aa426c4f02161d8',
'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8', 'org.beanshell:bsh:1.3.0:bsh-1.3.0.jar:9b04edc75d19db54f1b4e8b5355e9364384c6cf71eb0a1b9724c159d779879f8',
'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766', 'org.briarproject:obfs4proxy:0.0.12-dev-40245c4a:obfs4proxy-0.0.12-dev-40245c4a.zip:172029e7058b3a83ac93ac4991a44bf76e16ce8d46f558f5836d57da3cb3a766',
'org.briarproject:tor:0.3.5.13:tor-0.3.5.13.zip:1c5f0b821ee2aadb0ea04aa96caab3ca0a08370cce8de81c2dfe04d172f8a2a0', 'org.briarproject:tor:0.3.5.13-1:tor-0.3.5.13-1.zip:ef35c16bf8dc1f4c75ed71d9f55e4514f383d124ec96b859aca647c990927c99',
'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d', 'org.checkerframework:checker-compat-qual:2.5.3:checker-compat-qual-2.5.3.jar:d76b9afea61c7c082908023f0cbc1427fab9abd2df915c8b8a3e7a509bccbc6d',
'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a', 'org.checkerframework:checker-qual:2.5.2:checker-qual-2.5.2.jar:64b02691c8b9d4e7700f8ee2e742dce7ea2c6e81e662b7522c9ee3bf568c040a',
'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53', 'org.codehaus.mojo:animal-sniffer-annotations:1.17:animal-sniffer-annotations-1.17.jar:92654f493ecfec52082e76354f0ebf87648dc3d5cec2e3c3cdb947c016747a53',

View File

@@ -22,8 +22,8 @@ android {
defaultConfig { defaultConfig {
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 10216 versionCode 10217
versionName "1.2.16" versionName "1.2.17"
applicationId "org.briarproject.briar.android" applicationId "org.briarproject.briar.android"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true

View File

@@ -33,7 +33,6 @@ public class DozeFragment extends SetupFragment
private DozeView dozeView; private DozeView dozeView;
private HuaweiView huaweiView; private HuaweiView huaweiView;
private Button next; private Button next;
private ProgressBar progressBar;
private boolean secondAttempt = false; private boolean secondAttempt = false;
public static DozeFragment newInstance() { public static DozeFragment newInstance() {
@@ -58,11 +57,19 @@ public class DozeFragment extends SetupFragment
huaweiView = v.findViewById(R.id.huaweiView); huaweiView = v.findViewById(R.id.huaweiView);
huaweiView.setOnCheckedChangedListener(this); huaweiView.setOnCheckedChangedListener(this);
next = v.findViewById(R.id.next); next = v.findViewById(R.id.next);
progressBar = v.findViewById(R.id.progress); ProgressBar progressBar = v.findViewById(R.id.progress);
dozeView.setOnButtonClickListener(this::askForDozeWhitelisting); dozeView.setOnButtonClickListener(this::askForDozeWhitelisting);
next.setOnClickListener(this); next.setOnClickListener(this);
viewModel.getIsCreatingAccount()
.observe(getViewLifecycleOwner(), isCreatingAccount -> {
if (isCreatingAccount) {
next.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
}
});
return v; return v;
} }
@@ -104,15 +111,6 @@ public class DozeFragment extends SetupFragment
@Override @Override
public void onClick(View view) { public void onClick(View view) {
setNextClicked();
viewModel.dozeExceptionConfirmed(); viewModel.dozeExceptionConfirmed();
} }
@Override
void setNextClicked() {
super.setNextClicked();
next.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
}
} }

View File

@@ -38,7 +38,6 @@ public class SetPasswordFragment extends SetupFragment {
private TextInputEditText passwordConfirmation; private TextInputEditText passwordConfirmation;
private StrengthMeter strengthMeter; private StrengthMeter strengthMeter;
private Button nextButton; private Button nextButton;
private ProgressBar progressBar;
public static SetPasswordFragment newInstance() { public static SetPasswordFragment newInstance() {
return new SetPasswordFragment(); return new SetPasswordFragment();
@@ -64,7 +63,7 @@ public class SetPasswordFragment extends SetupFragment {
v.findViewById(R.id.password_confirm_wrapper); v.findViewById(R.id.password_confirm_wrapper);
passwordConfirmation = v.findViewById(R.id.password_confirm); passwordConfirmation = v.findViewById(R.id.password_confirm);
nextButton = v.findViewById(R.id.next); nextButton = v.findViewById(R.id.next);
progressBar = v.findViewById(R.id.progress); ProgressBar progressBar = v.findViewById(R.id.progress);
passwordEntry.addTextChangedListener(this); passwordEntry.addTextChangedListener(this);
passwordConfirmation.addTextChangedListener(this); passwordConfirmation.addTextChangedListener(this);
@@ -75,6 +74,17 @@ public class SetPasswordFragment extends SetupFragment {
passwordConfirmation.setImeOptions(IME_ACTION_DONE); passwordConfirmation.setImeOptions(IME_ACTION_DONE);
} }
viewModel.getIsCreatingAccount()
.observe(getViewLifecycleOwner(), isCreatingAccount -> {
if (isCreatingAccount) {
nextButton.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
// this also avoids the keyboard popping up
passwordEntry.setFocusable(false);
passwordConfirmation.setFocusable(false);
}
});
return v; return v;
} }
@@ -116,20 +126,6 @@ public class SetPasswordFragment extends SetupFragment {
IBinder token = passwordEntry.getWindowToken(); IBinder token = passwordEntry.getWindowToken();
Object o = getContext().getSystemService(INPUT_METHOD_SERVICE); Object o = getContext().getSystemService(INPUT_METHOD_SERVICE);
((InputMethodManager) o).hideSoftInputFromWindow(token, 0); ((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
setNextClicked();
viewModel.setPassword(passwordEntry.getText().toString()); viewModel.setPassword(passwordEntry.getText().toString());
} }
@Override
void setNextClicked() {
super.setNextClicked();
passwordEntry.setFocusable(false);
passwordConfirmation.setFocusable(false);
if (!viewModel.needToShowDozeFragment()) {
nextButton.setVisibility(INVISIBLE);
progressBar.setVisibility(VISIBLE);
}
}
} }

View File

@@ -7,7 +7,6 @@ import android.view.KeyEvent;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.TextView; import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener; import android.widget.TextView.OnEditorActionListener;
@@ -19,8 +18,6 @@ import org.briarproject.briar.android.fragment.BaseFragment;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelProvider;
@@ -35,7 +32,6 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
OnEditorActionListener, OnClickListener { OnEditorActionListener, OnClickListener {
private final static String STATE_KEY_CLICKED = "setupFragmentClicked"; private final static String STATE_KEY_CLICKED = "setupFragmentClicked";
private boolean clicked = false;
@Inject @Inject
ViewModelProvider.Factory viewModelFactory; ViewModelProvider.Factory viewModelFactory;
@@ -48,27 +44,6 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
.get(SetupViewModel.class); .get(SetupViewModel.class);
} }
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
if (savedInstanceState != null) {
clicked = savedInstanceState.getBoolean(STATE_KEY_CLICKED);
}
if (clicked) {
setNextClicked();
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_KEY_CLICKED, clicked);
}
@CallSuper
void setNextClicked() {
this.clicked = true;
}
@Override @Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.help_action, menu); inflater.inflate(R.menu.help_action, menu);
@@ -114,5 +89,4 @@ abstract class SetupFragment extends BaseFragment implements TextWatcher,
public void afterTextChanged(Editable editable) { public void afterTextChanged(Editable editable) {
// noop // noop
} }
} }

View File

@@ -17,6 +17,8 @@ import javax.inject.Inject;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.briar.android.account.SetupViewModel.State.AUTHOR_NAME; import static org.briarproject.briar.android.account.SetupViewModel.State.AUTHOR_NAME;
@@ -36,6 +38,8 @@ class SetupViewModel extends AndroidViewModel {
@Nullable @Nullable
private String authorName, password; private String authorName, password;
private final MutableLiveEvent<State> state = new MutableLiveEvent<>(); private final MutableLiveEvent<State> state = new MutableLiveEvent<>();
private final MutableLiveData<Boolean> isCreatingAccount =
new MutableLiveData<>(false);
private final AccountManager accountManager; private final AccountManager accountManager;
private final Executor ioExecutor; private final Executor ioExecutor;
@@ -67,6 +71,10 @@ class SetupViewModel extends AndroidViewModel {
return state; return state;
} }
LiveData<Boolean> getIsCreatingAccount() {
return isCreatingAccount;
}
void setAuthorName(String authorName) { void setAuthorName(String authorName) {
this.authorName = authorName; this.authorName = authorName;
state.setEvent(SET_PASSWORD); state.setEvent(SET_PASSWORD);
@@ -97,6 +105,7 @@ class SetupViewModel extends AndroidViewModel {
private void createAccount() { private void createAccount() {
if (authorName == null) throw new IllegalStateException(); if (authorName == null) throw new IllegalStateException();
if (password == null) throw new IllegalStateException(); if (password == null) throw new IllegalStateException();
isCreatingAccount.setValue(true);
ioExecutor.execute(() -> { ioExecutor.execute(() -> {
if (accountManager.createAccount(authorName, password)) { if (accountManager.createAccount(authorName, password)) {
LOG.info("Created account"); LOG.info("Created account");

View File

@@ -24,10 +24,7 @@ import org.briarproject.briar.android.attachment.AttachmentItem;
import org.briarproject.briar.android.util.BriarSnackbarBuilder; import org.briarproject.briar.android.util.BriarSnackbarBuilder;
import org.briarproject.briar.android.view.PullDownLayout; import org.briarproject.briar.android.view.PullDownLayout;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.inject.Inject; import javax.inject.Inject;
@@ -293,13 +290,10 @@ public class ImageActivity extends BriarActivity
@RequiresApi(api = 19) @RequiresApi(api = 19)
private Intent getCreationIntent() { private Intent getCreationIntent() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss",
Locale.getDefault());
String fileName = sdf.format(new Date());
Intent intent = new Intent(ACTION_CREATE_DOCUMENT); Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
intent.addCategory(CATEGORY_OPENABLE); intent.addCategory(CATEGORY_OPENABLE);
intent.setType(getVisibleAttachment().getMimeType()); intent.setType(getVisibleAttachment().getMimeType());
intent.putExtra(EXTRA_TITLE, fileName); intent.putExtra(EXTRA_TITLE, viewModel.getFileName());
return intent; return intent;
} }

View File

@@ -225,8 +225,8 @@ public class ImageViewModel extends DbViewModel implements EventListener {
}); });
} }
private String getFileName() { String getFileName() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd",
Locale.getDefault()); Locale.getDefault());
return sdf.format(new Date()); return sdf.format(new Date());
} }

View File

@@ -11,9 +11,11 @@ The REST API peer comes as a `jar` file
and needs a Java Runtime Environment (JRE) that supports at least Java 8. and needs a Java Runtime Environment (JRE) that supports at least Java 8.
It currently works only on GNU/Linux operating systems. It currently works only on GNU/Linux operating systems.
To build the `jar` file, you can do this: To build the `jar` file, you need to specify the combination of architecture and platform:
$ ./gradlew --configure-on-demand briar-headless:jar $ ./gradlew --configure-on-demand briar-headless:x86LinuxJar
$ ./gradlew --configure-on-demand briar-headless:aarch64LinuxJar
$ ./gradlew --configure-on-demand briar-headless:armhfLinuxJar
You can start the peer (and its API server) like this: You can start the peer (and its API server) like this:

View File

@@ -44,18 +44,32 @@ dependencies {
kaptTest "com.google.dagger:dagger-compiler:$daggerVersion" kaptTest "com.google.dagger:dagger-compiler:$daggerVersion"
} }
jar { void jarFactory(Jar jarTask, jarArchitecture) {
manifest { jarTask.doFirst {
println 'Building ' + jarArchitecture + ' version has started'
}
jarTask.manifest {
attributes( attributes(
'Main-Class': 'org.briarproject.briar.headless.MainKt' 'Main-Class': 'org.briarproject.briar.headless.MainKt'
) )
} }
from { jarTask.setArchiveClassifier(jarArchitecture)
jarTask.from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
} }
doLast() { {
String[] architectures = ["linux-aarch64", "linux-armhf", "linux-x86_64"]
for (String arch : architectures) {
if (arch != jarArchitecture) {
exclude "obfs4proxy_" + arch + ".zip"
exclude "tor_" + arch + ".zip"
}
}
}
jarTask.with jar
jarTask.doLast {
// Rename the original jar // Rename the original jar
File jar = project.jar.archivePath File jar = jarTask.archivePath
String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar') String srcPath = jar.toString().replaceFirst('\\.jar$', '.unsorted.jar')
File srcFile = new File(srcPath) File srcFile = new File(srcPath)
jar.renameTo(srcFile) jar.renameTo(srcFile)
@@ -80,9 +94,22 @@ jar {
} }
destStream.close() destStream.close()
srcJarFile.close() srcJarFile.close()
println 'Building ' + jarArchitecture + ' version has finished'
} }
} }
task aarch64LinuxJar(type: Jar) {
jarFactory(it, 'linux-aarch64')
}
task armhfLinuxJar(type: Jar) {
jarFactory(it, 'linux-armhf')
}
task x86LinuxJar(type: Jar) {
jarFactory(it, 'linux-x86_64')
}
// At the moment for non-Android projects we need to explicitly mark the code generated by kapt // At the moment for non-Android projects we need to explicitly mark the code generated by kapt
// as 'generated source code' for correct highlighting and resolve in IDE. // as 'generated source code' for correct highlighting and resolve in IDE.
idea { idea {