mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Merge branch '2266-target-sdk-33' into 'master'
Target SDK 33 Closes #2266 See merge request briar/briar!1800
This commit is contained in:
@@ -12,7 +12,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 33
|
||||||
versionCode 10504
|
versionCode 10504
|
||||||
versionName "1.5.4"
|
versionName "1.5.4"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.battery.BatteryManager;
|
import org.briarproject.bramble.api.battery.BatteryManager;
|
||||||
import org.briarproject.bramble.api.battery.event.BatteryEvent;
|
import org.briarproject.bramble.api.battery.event.BatteryEvent;
|
||||||
@@ -16,10 +17,17 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
import static android.content.Intent.ACTION_BATTERY_CHANGED;
|
||||||
import static android.content.Intent.ACTION_POWER_CONNECTED;
|
import static android.content.Intent.ACTION_POWER_CONNECTED;
|
||||||
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
|
import static android.content.Intent.ACTION_POWER_DISCONNECTED;
|
||||||
import static android.os.BatteryManager.EXTRA_PLUGGED;
|
import static android.os.BatteryManager.EXTRA_PLUGGED;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
|
||||||
|
import static android.os.PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED;
|
||||||
|
import static android.os.PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED;
|
||||||
|
import static android.os.PowerManager.ACTION_POWER_SAVE_MODE_CHANGED;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
@@ -57,6 +65,12 @@ class AndroidBatteryManager implements BatteryManager, Service {
|
|||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(ACTION_POWER_CONNECTED);
|
filter.addAction(ACTION_POWER_CONNECTED);
|
||||||
filter.addAction(ACTION_POWER_DISCONNECTED);
|
filter.addAction(ACTION_POWER_DISCONNECTED);
|
||||||
|
filter.addAction(ACTION_POWER_SAVE_MODE_CHANGED);
|
||||||
|
if (SDK_INT >= 23) filter.addAction(ACTION_DEVICE_IDLE_MODE_CHANGED);
|
||||||
|
if (SDK_INT >= 33) {
|
||||||
|
filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
|
||||||
|
filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED);
|
||||||
|
}
|
||||||
appContext.registerReceiver(batteryReceiver, filter);
|
appContext.registerReceiver(batteryReceiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,6 +90,33 @@ class AndroidBatteryManager implements BatteryManager, Service {
|
|||||||
eventBus.broadcast(new BatteryEvent(true));
|
eventBus.broadcast(new BatteryEvent(true));
|
||||||
else if (ACTION_POWER_DISCONNECTED.equals(action))
|
else if (ACTION_POWER_DISCONNECTED.equals(action))
|
||||||
eventBus.broadcast(new BatteryEvent(false));
|
eventBus.broadcast(new BatteryEvent(false));
|
||||||
|
else if (SDK_INT >= 23 &&
|
||||||
|
ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action) &&
|
||||||
|
LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Device idle mode changed to: " +
|
||||||
|
getPowerManager(ctx).isDeviceIdleMode());
|
||||||
|
} else if (SDK_INT >= 23 &&
|
||||||
|
ACTION_POWER_SAVE_MODE_CHANGED.equals(action) &&
|
||||||
|
LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Power save mode changed to: " +
|
||||||
|
getPowerManager(ctx).isPowerSaveMode());
|
||||||
|
} else if (SDK_INT >= 33 && LOG.isLoggable(INFO) &&
|
||||||
|
ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED.equals(action)) {
|
||||||
|
PowerManager powerManager =
|
||||||
|
ctx.getSystemService(PowerManager.class);
|
||||||
|
LOG.info("Low power standby now is: " +
|
||||||
|
powerManager.isLowPowerStandbyEnabled());
|
||||||
|
} else if (SDK_INT >= 33 && LOG.isLoggable(INFO) &&
|
||||||
|
ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED.equals(action)) {
|
||||||
|
PowerManager powerManager = getPowerManager(ctx);
|
||||||
|
LOG.info("Light idle mode now is: " +
|
||||||
|
powerManager.isDeviceLightIdleMode());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = 23)
|
||||||
|
private PowerManager getPowerManager(Context ctx) {
|
||||||
|
return ctx.getSystemService(PowerManager.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,10 +63,12 @@ public class AndroidUtils {
|
|||||||
return new Pair<>(address, "adapter");
|
return new Pair<>(address, "adapter");
|
||||||
}
|
}
|
||||||
// Return the address from settings if it's valid and not fake
|
// Return the address from settings if it's valid and not fake
|
||||||
address = Settings.Secure.getString(ctx.getContentResolver(),
|
if (SDK_INT < 33) {
|
||||||
"bluetooth_address");
|
address = Settings.Secure.getString(ctx.getContentResolver(),
|
||||||
if (isValidBluetoothAddress(address)) {
|
"bluetooth_address");
|
||||||
return new Pair<>(address, "settings");
|
if (isValidBluetoothAddress(address)) {
|
||||||
|
return new Pair<>(address, "settings");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Try to get the address via reflection
|
// Try to get the address via reflection
|
||||||
address = getBluetoothAddressByReflection(adapter);
|
address = getBluetoothAddressByReflection(adapter);
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 33
|
||||||
versionCode 10504
|
versionCode 10504
|
||||||
versionName "1.5.4"
|
versionName "1.5.4"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
|
|||||||
@@ -19,6 +19,10 @@
|
|||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
|
<uses-permission
|
||||||
|
android:name="android.permission.NEARBY_WIFI_DEVICES"
|
||||||
|
android:usesPermissionFlags="neverForLocation"
|
||||||
|
tools:targetApi="31" />
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
@@ -30,8 +34,10 @@
|
|||||||
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||||
android:maxSdkVersion="18"
|
android:maxSdkVersion="18"
|
||||||
tools:ignore="ScopedStorage" />
|
tools:ignore="ScopedStorage" />
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||||
|
|
||||||
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||||
|
android:maxSdkVersion="32" />
|
||||||
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission-sdk-23 android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission-sdk-23 android:name="android.permission.USE_BIOMETRIC" />
|
||||||
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
|
<uses-permission-sdk-23 android:name="android.permission.FOREGROUND_SERVICE" />
|
||||||
|
|||||||
@@ -7,17 +7,26 @@ import android.content.IntentFilter;
|
|||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.lifecycle.Service;
|
import org.briarproject.bramble.api.lifecycle.Service;
|
||||||
import org.briarproject.bramble.api.lifecycle.ServiceException;
|
|
||||||
import org.briarproject.briar.api.android.DozeWatchdog;
|
import org.briarproject.briar.api.android.DozeWatchdog;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import static android.content.Context.POWER_SERVICE;
|
import static android.content.Context.POWER_SERVICE;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
|
import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
|
||||||
|
import static android.os.PowerManager.ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED;
|
||||||
|
import static android.os.PowerManager.ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
class DozeWatchdogImpl implements DozeWatchdog, Service {
|
class DozeWatchdogImpl implements DozeWatchdog, Service {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(DozeWatchdogImpl.class.getName());
|
||||||
|
|
||||||
private final Context appContext;
|
private final Context appContext;
|
||||||
private final AtomicBoolean dozed = new AtomicBoolean(false);
|
private final AtomicBoolean dozed = new AtomicBoolean(false);
|
||||||
private final BroadcastReceiver receiver = new DozeBroadcastReceiver();
|
private final BroadcastReceiver receiver = new DozeBroadcastReceiver();
|
||||||
@@ -32,14 +41,18 @@ class DozeWatchdogImpl implements DozeWatchdog, Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startService() throws ServiceException {
|
public void startService() {
|
||||||
if (SDK_INT < 23) return;
|
if (SDK_INT < 23) return;
|
||||||
IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED);
|
IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED);
|
||||||
|
if (SDK_INT >= 33) {
|
||||||
|
filter.addAction(ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED);
|
||||||
|
filter.addAction(ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED);
|
||||||
|
}
|
||||||
appContext.registerReceiver(receiver, filter);
|
appContext.registerReceiver(receiver, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stopService() throws ServiceException {
|
public void stopService() {
|
||||||
if (SDK_INT < 23) return;
|
if (SDK_INT < 23) return;
|
||||||
appContext.unregisterReceiver(receiver);
|
appContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
@@ -49,9 +62,33 @@ class DozeWatchdogImpl implements DozeWatchdog, Service {
|
|||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (SDK_INT < 23) return;
|
if (SDK_INT < 23) return;
|
||||||
|
String action = intent.getAction();
|
||||||
PowerManager pm =
|
PowerManager pm =
|
||||||
(PowerManager) appContext.getSystemService(POWER_SERVICE);
|
(PowerManager) appContext.getSystemService(POWER_SERVICE);
|
||||||
if (pm.isDeviceIdleMode()) dozed.set(true);
|
if (ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)) {
|
||||||
|
if (pm.isDeviceIdleMode()) dozed.set(true);
|
||||||
|
} else if (SDK_INT >= 33) {
|
||||||
|
onReceive33(action, pm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(33)
|
||||||
|
private void onReceive33(String action, PowerManager pm) {
|
||||||
|
if (ACTION_LOW_POWER_STANDBY_ENABLED_CHANGED.equals(action)) {
|
||||||
|
if (pm.isLowPowerStandbyEnabled()) {
|
||||||
|
if (LOG.isLoggable(WARNING)) {
|
||||||
|
LOG.warning("System is in low power standby mode");
|
||||||
|
}
|
||||||
|
dozed.set(true);
|
||||||
|
}
|
||||||
|
} else if (ACTION_DEVICE_LIGHT_IDLE_MODE_CHANGED.equals(action)) {
|
||||||
|
if (pm.isDeviceLightIdleMode()) {
|
||||||
|
if (LOG.isLoggable(WARNING)) {
|
||||||
|
LOG.warning("System is in light idle mode");
|
||||||
|
}
|
||||||
|
dozed.set(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.android.account;
|
package org.briarproject.briar.android.account;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -8,6 +9,7 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.account.PowerView.OnCheckedChangedListener;
|
import org.briarproject.briar.android.account.PowerView.OnCheckedChangedListener;
|
||||||
@@ -18,6 +20,7 @@ import androidx.annotation.Nullable;
|
|||||||
|
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent;
|
import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
|
import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog;
|
||||||
@@ -113,7 +116,12 @@ public class DozeFragment extends SetupFragment
|
|||||||
private void askForDozeWhitelisting() {
|
private void askForDozeWhitelisting() {
|
||||||
if (getContext() == null) return;
|
if (getContext() == null) return;
|
||||||
Intent i = getDozeWhitelistingIntent(getContext());
|
Intent i = getDozeWhitelistingIntent(getContext());
|
||||||
startActivityForResult(i, REQUEST_DOZE_WHITELISTING);
|
try {
|
||||||
|
startActivityForResult(i, REQUEST_DOZE_WHITELISTING);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(requireContext(),
|
||||||
|
R.string.error_start_activity, LENGTH_LONG).show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import androidx.annotation.UiThread;
|
|||||||
|
|
||||||
import static org.briarproject.android.dontkillmelib.HuaweiUtils.getHuaweiProtectedAppsIntent;
|
import static org.briarproject.android.dontkillmelib.HuaweiUtils.getHuaweiProtectedAppsIntent;
|
||||||
import static org.briarproject.android.dontkillmelib.HuaweiUtils.protectedAppsNeedsToBeShown;
|
import static org.briarproject.android.dontkillmelib.HuaweiUtils.protectedAppsNeedsToBeShown;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -49,7 +50,7 @@ class HuaweiProtectedAppsView extends PowerView {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onButtonClick() {
|
protected void onButtonClick() {
|
||||||
getContext().startActivity(getHuaweiProtectedAppsIntent());
|
tryToStartActivity(getContext(), getHuaweiProtectedAppsIntent());
|
||||||
setChecked(true);
|
setChecked(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,17 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.POST_NOTIFICATIONS;
|
||||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||||
|
import static androidx.core.content.ContextCompat.checkSelfPermission;
|
||||||
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
|
import static org.briarproject.bramble.api.crypto.PasswordStrengthEstimator.QUITE_WEAK;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.setError;
|
import static org.briarproject.briar.android.util.UiUtils.setError;
|
||||||
|
|
||||||
@@ -38,6 +45,10 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
private StrengthMeter strengthMeter;
|
private StrengthMeter strengthMeter;
|
||||||
private Button nextButton;
|
private Button nextButton;
|
||||||
|
|
||||||
|
private final ActivityResultLauncher<String> requestPermissionLauncher =
|
||||||
|
registerForActivityResult(new RequestPermission(), isGranted ->
|
||||||
|
setPassword());
|
||||||
|
|
||||||
public static SetPasswordFragment newInstance() {
|
public static SetPasswordFragment newInstance() {
|
||||||
return new SetPasswordFragment();
|
return new SetPasswordFragment();
|
||||||
}
|
}
|
||||||
@@ -121,6 +132,18 @@ public class SetPasswordFragment extends SetupFragment {
|
|||||||
IBinder token = passwordEntry.getWindowToken();
|
IBinder token = passwordEntry.getWindowToken();
|
||||||
Object o = requireContext().getSystemService(INPUT_METHOD_SERVICE);
|
Object o = requireContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||||
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
((InputMethodManager) o).hideSoftInputFromWindow(token, 0);
|
||||||
|
if (SDK_INT >= 33 &&
|
||||||
|
checkSelfPermission(requireContext(), POST_NOTIFICATIONS) !=
|
||||||
|
PERMISSION_GRANTED) {
|
||||||
|
// this calls setPassword() when it returns
|
||||||
|
requestPermissionLauncher.launch(POST_NOTIFICATIONS);
|
||||||
|
} else {
|
||||||
|
setPassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPassword() {
|
||||||
viewModel.setPassword(passwordEntry.getText().toString());
|
viewModel.setPassword(passwordEntry.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public class SetupActivity extends BaseActivity
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
SetupViewModel viewModel;
|
private SetupViewModel viewModel;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
@@ -71,16 +71,16 @@ public class SetupActivity extends BaseActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showPasswordFragment() {
|
private void showPasswordFragment() {
|
||||||
showNextFragment(SetPasswordFragment.newInstance());
|
showNextFragment(SetPasswordFragment.newInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@TargetApi(23)
|
@TargetApi(23)
|
||||||
void showDozeFragment() {
|
private void showDozeFragment() {
|
||||||
showNextFragment(DozeFragment.newInstance());
|
showNextFragment(DozeFragment.newInstance());
|
||||||
}
|
}
|
||||||
|
|
||||||
void showApp() {
|
private void showApp() {
|
||||||
Intent i = new Intent(this, ENTRY_ACTIVITY);
|
Intent i = new Intent(this, ENTRY_ACTIVITY);
|
||||||
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME |
|
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME |
|
||||||
FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_CLEAR_TOP);
|
FLAG_ACTIVITY_CLEAR_TASK | FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.briarproject.briar.android.account;
|
package org.briarproject.briar.android.account;
|
||||||
|
|
||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.hardware.biometrics.BiometricPrompt;
|
import android.hardware.biometrics.BiometricPrompt;
|
||||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
||||||
@@ -28,6 +29,7 @@ import static android.hardware.biometrics.BiometricPrompt.BIOMETRIC_ERROR_CANCEL
|
|||||||
import static android.hardware.biometrics.BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED;
|
import static android.hardware.biometrics.BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_KEYGUARD_UNLOCK;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.hasKeyguardLock;
|
import static org.briarproject.briar.android.util.UiUtils.hasKeyguardLock;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.hasUsableFingerprint;
|
import static org.briarproject.briar.android.util.UiUtils.hasUsableFingerprint;
|
||||||
@@ -191,7 +193,12 @@ public class UnlockActivity extends BaseActivity {
|
|||||||
unlock();
|
unlock();
|
||||||
} else {
|
} else {
|
||||||
keyguardShown = true;
|
keyguardShown = true;
|
||||||
startActivityForResult(intent, REQUEST_KEYGUARD_UNLOCK);
|
try {
|
||||||
|
startActivityForResult(intent, REQUEST_KEYGUARD_UNLOCK);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(this, R.string.error_start_activity, LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
overridePendingTransition(0, 0);
|
overridePendingTransition(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package org.briarproject.briar.android.account;
|
package org.briarproject.briar.android.account;
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -60,12 +61,12 @@ class XiaomiLockAppsView extends PowerView {
|
|||||||
getContext().startActivity(getXiaomiLockAppsIntent());
|
getContext().startActivity(getXiaomiLockAppsIntent());
|
||||||
setChecked(true);
|
setChecked(true);
|
||||||
return;
|
return;
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException | ActivityNotFoundException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
|
Toast.makeText(getContext(),
|
||||||
|
R.string.dnkm_xiaomi_lock_apps_error_toast,
|
||||||
|
LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
Toast.makeText(getContext(),
|
|
||||||
R.string.dnkm_xiaomi_lock_apps_error_toast,
|
|
||||||
LENGTH_LONG).show();
|
|
||||||
// Let the user continue with setup
|
// Let the user continue with setup
|
||||||
setChecked(true);
|
setChecked(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
package org.briarproject.briar.android.activity;
|
package org.briarproject.briar.android.activity;
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.transition.Transition;
|
import android.transition.Transition;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.CheckBox;
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager;
|
import org.briarproject.android.dontkillmelib.wakelock.AndroidWakeLockManager;
|
||||||
import org.briarproject.bramble.api.system.Wakeful;
|
import org.briarproject.bramble.api.system.Wakeful;
|
||||||
@@ -34,9 +36,12 @@ import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
|
|||||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||||
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent;
|
import static org.briarproject.android.dontkillmelib.DozeUtils.getDozeWhitelistingIntent;
|
||||||
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_UNLOCK;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_UNLOCK;
|
||||||
@@ -179,7 +184,13 @@ public abstract class BriarActivity extends BaseActivity {
|
|||||||
b.setPositiveButton(R.string.fix,
|
b.setPositiveButton(R.string.fix,
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
Intent i = getDozeWhitelistingIntent(BriarActivity.this);
|
Intent i = getDozeWhitelistingIntent(BriarActivity.this);
|
||||||
startActivityForResult(i, REQUEST_DOZE_WHITELISTING);
|
try {
|
||||||
|
startActivityForResult(i, REQUEST_DOZE_WHITELISTING);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
logException(LOG, WARNING, e);
|
||||||
|
Toast.makeText(this, R.string.error_start_activity,
|
||||||
|
LENGTH_LONG).show();
|
||||||
|
}
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
});
|
});
|
||||||
b.setNegativeButton(R.string.cancel,
|
b.setNegativeButton(R.string.cancel,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import org.briarproject.briar.api.android.ScreenFilterMonitor;
|
|||||||
import org.briarproject.briar.api.android.ScreenFilterMonitor.AppDetails;
|
import org.briarproject.briar.api.android.ScreenFilterMonitor.AppDetails;
|
||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@@ -32,6 +33,7 @@ import androidx.fragment.app.DialogFragment;
|
|||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;
|
import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -68,6 +70,7 @@ public class ScreenFilterDialogFragment extends DialogFragment {
|
|||||||
((BaseActivity) requireActivity()).getActivityComponent().inject(this);
|
((BaseActivity) requireActivity()).getActivityComponent().inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
||||||
Activity activity = getActivity();
|
Activity activity = getActivity();
|
||||||
@@ -98,7 +101,7 @@ public class ScreenFilterDialogFragment extends DialogFragment {
|
|||||||
builder.setNeutralButton(R.string.screen_filter_review_apps,
|
builder.setNeutralButton(R.string.screen_filter_review_apps,
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
Intent i = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION);
|
Intent i = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION);
|
||||||
startActivity(i);
|
tryToStartActivity(requireActivity(), i);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
builder.setPositiveButton(R.string.continue_button, (dialog, which) -> {
|
builder.setPositiveButton(R.string.continue_button, (dialog, which) -> {
|
||||||
|
|||||||
@@ -1,21 +1,27 @@
|
|||||||
package org.briarproject.briar.android.hotspot;
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.net.wifi.WifiManager;
|
import android.net.wifi.WifiManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.util.Consumer;
|
import androidx.core.util.Consumer;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
|
||||||
import static android.content.Context.WIFI_SERVICE;
|
import static android.content.Context.WIFI_SERVICE;
|
||||||
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for the ConditionManagers that ensure that the conditions
|
* Abstract base class for the ConditionManagers that ensure that the conditions
|
||||||
* to open a hotspot are fulfilled. There are different extensions of this for
|
* to open a hotspot are fulfilled. There are different extensions of this for
|
||||||
* API levels lower than 29 and 29+.
|
* API levels lower than 29, 29+ and 33+.
|
||||||
*/
|
*/
|
||||||
abstract class AbstractConditionManager {
|
abstract class AbstractConditionManager {
|
||||||
|
|
||||||
@@ -28,6 +34,7 @@ abstract class AbstractConditionManager {
|
|||||||
final Consumer<Boolean> permissionUpdateCallback;
|
final Consumer<Boolean> permissionUpdateCallback;
|
||||||
protected FragmentActivity ctx;
|
protected FragmentActivity ctx;
|
||||||
WifiManager wifiManager;
|
WifiManager wifiManager;
|
||||||
|
private ActivityResultLauncher<Intent> wifiRequest;
|
||||||
|
|
||||||
AbstractConditionManager(Consumer<Boolean> permissionUpdateCallback) {
|
AbstractConditionManager(Consumer<Boolean> permissionUpdateCallback) {
|
||||||
this.permissionUpdateCallback = permissionUpdateCallback;
|
this.permissionUpdateCallback = permissionUpdateCallback;
|
||||||
@@ -38,8 +45,12 @@ abstract class AbstractConditionManager {
|
|||||||
*/
|
*/
|
||||||
void init(FragmentActivity ctx) {
|
void init(FragmentActivity ctx) {
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
this.wifiManager = (WifiManager) ctx.getApplicationContext()
|
wifiManager = (WifiManager) ctx.getApplicationContext()
|
||||||
.getSystemService(WIFI_SERVICE);
|
.getSystemService(WIFI_SERVICE);
|
||||||
|
wifiRequest = ctx.registerForActivityResult(
|
||||||
|
new ActivityResultContracts.StartActivityForResult(),
|
||||||
|
result -> permissionUpdateCallback
|
||||||
|
.accept(wifiManager.isWifiEnabled()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,6 +68,8 @@ abstract class AbstractConditionManager {
|
|||||||
*/
|
*/
|
||||||
abstract boolean checkAndRequestConditions();
|
abstract boolean checkAndRequestConditions();
|
||||||
|
|
||||||
|
abstract String getWifiSettingsAction();
|
||||||
|
|
||||||
void showRationale(Context ctx, @StringRes int title,
|
void showRationale(Context ctx, @StringRes int title,
|
||||||
@StringRes int body, Runnable onContinueClicked,
|
@StringRes int body, Runnable onContinueClicked,
|
||||||
Runnable onDismiss) {
|
Runnable onDismiss) {
|
||||||
@@ -69,4 +82,13 @@ abstract class AbstractConditionManager {
|
|||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void requestEnableWiFi() {
|
||||||
|
try {
|
||||||
|
wifiRequest.launch(new Intent(getWifiSettingsAction()));
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,12 @@
|
|||||||
package org.briarproject.briar.android.hotspot;
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultCaller;
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
|
|
||||||
import androidx.core.util.Consumer;
|
import androidx.core.util.Consumer;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
@@ -22,20 +19,14 @@ import static java.util.logging.Logger.getLogger;
|
|||||||
* As soon as {@link #checkAndRequestConditions()} returns true,
|
* As soon as {@link #checkAndRequestConditions()} returns true,
|
||||||
* all conditions are fulfilled.
|
* all conditions are fulfilled.
|
||||||
*/
|
*/
|
||||||
|
@NotNullByDefault
|
||||||
class ConditionManager extends AbstractConditionManager {
|
class ConditionManager extends AbstractConditionManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(ConditionManager.class.getName());
|
getLogger(ConditionManager.class.getName());
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> wifiRequest;
|
ConditionManager(Consumer<Boolean> permissionUpdateCallback) {
|
||||||
|
super( permissionUpdateCallback);
|
||||||
ConditionManager(ActivityResultCaller arc,
|
|
||||||
Consumer<Boolean> permissionUpdateCallback) {
|
|
||||||
super(permissionUpdateCallback);
|
|
||||||
wifiRequest = arc.registerForActivityResult(
|
|
||||||
new StartActivityForResult(),
|
|
||||||
result -> permissionUpdateCallback
|
|
||||||
.accept(wifiManager.isWifiEnabled()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -76,8 +67,9 @@ class ConditionManager extends AbstractConditionManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestEnableWiFi() {
|
@Override
|
||||||
wifiRequest.launch(new Intent(Settings.ACTION_WIFI_SETTINGS));
|
String getWifiSettingsAction() {
|
||||||
|
return Settings.ACTION_WIFI_SETTINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,17 @@
|
|||||||
package org.briarproject.briar.android.hotspot;
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.util.Permission;
|
import org.briarproject.briar.android.util.Permission;
|
||||||
import org.briarproject.briar.android.util.PermissionUtils;
|
import org.briarproject.briar.android.util.PermissionUtils;
|
||||||
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultCaller;
|
import androidx.activity.result.ActivityResultCaller;
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.RequiresApi;
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.core.util.Consumer;
|
import androidx.core.util.Consumer;
|
||||||
@@ -28,12 +27,13 @@ import static org.briarproject.briar.android.util.PermissionUtils.showLocationDi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This class ensures that the conditions to open a hotspot are fulfilled on
|
* This class ensures that the conditions to open a hotspot are fulfilled on
|
||||||
* API levels >= 29.
|
* API levels >= 29 and < 33.
|
||||||
* <p>
|
* <p>
|
||||||
* As soon as {@link #checkAndRequestConditions()} returns true,
|
* As soon as {@link #checkAndRequestConditions()} returns true,
|
||||||
* all conditions are fulfilled.
|
* all conditions are fulfilled.
|
||||||
*/
|
*/
|
||||||
@RequiresApi(29)
|
@RequiresApi(29)
|
||||||
|
@NotNullByDefault
|
||||||
class ConditionManager29 extends AbstractConditionManager {
|
class ConditionManager29 extends AbstractConditionManager {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -42,7 +42,6 @@ class ConditionManager29 extends AbstractConditionManager {
|
|||||||
private Permission locationPermission = Permission.UNKNOWN;
|
private Permission locationPermission = Permission.UNKNOWN;
|
||||||
|
|
||||||
private final ActivityResultLauncher<String> locationRequest;
|
private final ActivityResultLauncher<String> locationRequest;
|
||||||
private final ActivityResultLauncher<Intent> wifiRequest;
|
|
||||||
|
|
||||||
ConditionManager29(ActivityResultCaller arc,
|
ConditionManager29(ActivityResultCaller arc,
|
||||||
Consumer<Boolean> permissionUpdateCallback) {
|
Consumer<Boolean> permissionUpdateCallback) {
|
||||||
@@ -53,11 +52,6 @@ class ConditionManager29 extends AbstractConditionManager {
|
|||||||
onRequestPermissionResult(granted);
|
onRequestPermissionResult(granted);
|
||||||
permissionUpdateCallback.accept(TRUE.equals(granted));
|
permissionUpdateCallback.accept(TRUE.equals(granted));
|
||||||
});
|
});
|
||||||
wifiRequest = arc.registerForActivityResult(
|
|
||||||
new StartActivityForResult(),
|
|
||||||
result -> permissionUpdateCallback
|
|
||||||
.accept(wifiManager.isWifiEnabled())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -131,6 +125,11 @@ class ConditionManager29 extends AbstractConditionManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getWifiSettingsAction() {
|
||||||
|
return Settings.Panel.ACTION_WIFI;
|
||||||
|
}
|
||||||
|
|
||||||
private void onRequestPermissionResult(@Nullable Boolean granted) {
|
private void onRequestPermissionResult(@Nullable Boolean granted) {
|
||||||
if (granted != null && granted) {
|
if (granted != null && granted) {
|
||||||
locationPermission = Permission.GRANTED;
|
locationPermission = Permission.GRANTED;
|
||||||
@@ -146,8 +145,4 @@ class ConditionManager29 extends AbstractConditionManager {
|
|||||||
locationRequest.launch(ACCESS_FINE_LOCATION);
|
locationRequest.launch(ACCESS_FINE_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestEnableWiFi() {
|
|
||||||
wifiRequest.launch(new Intent(Settings.Panel.ACTION_WIFI));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,134 @@
|
|||||||
|
package org.briarproject.briar.android.hotspot;
|
||||||
|
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.util.Permission;
|
||||||
|
import org.briarproject.briar.android.util.PermissionUtils;
|
||||||
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultCaller;
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import androidx.core.util.Consumer;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.NEARBY_WIFI_DEVICES;
|
||||||
|
import static androidx.core.app.ActivityCompat.shouldShowRequestPermissionRationale;
|
||||||
|
import static java.lang.Boolean.TRUE;
|
||||||
|
import static java.util.logging.Level.INFO;
|
||||||
|
import static java.util.logging.Logger.getLogger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class ensures that the conditions to open a hotspot are fulfilled on
|
||||||
|
* API levels >= 33.
|
||||||
|
* <p>
|
||||||
|
* As soon as {@link #checkAndRequestConditions()} returns true,
|
||||||
|
* all conditions are fulfilled.
|
||||||
|
*/
|
||||||
|
@RequiresApi(33)
|
||||||
|
@NotNullByDefault
|
||||||
|
class ConditionManager33 extends AbstractConditionManager {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
getLogger(ConditionManager33.class.getName());
|
||||||
|
|
||||||
|
private Permission nearbyWifiPermission = Permission.UNKNOWN;
|
||||||
|
|
||||||
|
private final ActivityResultLauncher<String> nearbyWifiRequest;
|
||||||
|
|
||||||
|
ConditionManager33(ActivityResultCaller arc,
|
||||||
|
Consumer<Boolean> permissionUpdateCallback) {
|
||||||
|
super(permissionUpdateCallback);
|
||||||
|
// permissionUpdateCallback receives false if permissions were denied
|
||||||
|
nearbyWifiRequest = arc.registerForActivityResult(
|
||||||
|
new RequestPermission(), granted -> {
|
||||||
|
onRequestPermissionResult(granted);
|
||||||
|
permissionUpdateCallback.accept(TRUE.equals(granted));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void onStart() {
|
||||||
|
nearbyWifiPermission = Permission.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean areEssentialPermissionsGranted() {
|
||||||
|
boolean isWifiEnabled = wifiManager.isWifiEnabled();
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info(String.format("areEssentialPermissionsGranted(): " +
|
||||||
|
"nearbyWifiPermission? %s, " +
|
||||||
|
"wifiManager.isWifiEnabled()? %b",
|
||||||
|
nearbyWifiPermission, isWifiEnabled));
|
||||||
|
}
|
||||||
|
return nearbyWifiPermission == Permission.GRANTED && isWifiEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
boolean checkAndRequestConditions() {
|
||||||
|
if (areEssentialPermissionsGranted()) return true;
|
||||||
|
|
||||||
|
if (nearbyWifiPermission == Permission.UNKNOWN) {
|
||||||
|
requestPermissions();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the location permission has been permanently denied, ask the
|
||||||
|
// user to change the setting
|
||||||
|
if (nearbyWifiPermission == Permission.PERMANENTLY_DENIED) {
|
||||||
|
PermissionUtils.showDenialDialog(ctx,
|
||||||
|
R.string.permission_nearby_devices_title,
|
||||||
|
R.string.permission_hotspot_nearby_wifi_denied_body,
|
||||||
|
() -> permissionUpdateCallback.accept(false));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Should we show the rationale for location permission?
|
||||||
|
if (nearbyWifiPermission == Permission.SHOW_RATIONALE) {
|
||||||
|
showRationale(ctx,
|
||||||
|
R.string.permission_location_title,
|
||||||
|
R.string.permission_hotspot_nearby_wifi_request_body,
|
||||||
|
this::requestPermissions,
|
||||||
|
() -> permissionUpdateCallback.accept(false));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If Wifi is not enabled, we show the rationale for enabling Wifi?
|
||||||
|
if (!wifiManager.isWifiEnabled()) {
|
||||||
|
showRationale(ctx, R.string.wifi_settings_title,
|
||||||
|
R.string.wifi_settings_request_enable_body,
|
||||||
|
this::requestEnableWiFi,
|
||||||
|
() -> permissionUpdateCallback.accept(false));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we shouldn't usually reach this point, but if we do, return false
|
||||||
|
// anyway to force a recheck. Maybe some condition changed in the
|
||||||
|
// meantime.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
String getWifiSettingsAction() {
|
||||||
|
return Settings.Panel.ACTION_WIFI;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRequestPermissionResult(@Nullable Boolean granted) {
|
||||||
|
if (granted != null && granted) {
|
||||||
|
nearbyWifiPermission = Permission.GRANTED;
|
||||||
|
} else if (shouldShowRequestPermissionRationale(ctx,
|
||||||
|
NEARBY_WIFI_DEVICES)) {
|
||||||
|
nearbyWifiPermission = Permission.SHOW_RATIONALE;
|
||||||
|
} else {
|
||||||
|
nearbyWifiPermission = Permission.PERMANENTLY_DENIED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestPermissions() {
|
||||||
|
nearbyWifiRequest.launch(NEARBY_WIFI_DEVICES);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -31,6 +31,7 @@ import static android.view.View.VISIBLE;
|
|||||||
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
import static androidx.transition.TransitionManager.beginDelayedTransition;
|
||||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||||
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
import static org.briarproject.briar.android.hotspot.HotspotViewModel.getApkFileName;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -102,7 +103,7 @@ public class FallbackFragment extends BaseFragment {
|
|||||||
i.putExtra(EXTRA_STREAM, uri);
|
i.putExtra(EXTRA_STREAM, uri);
|
||||||
i.setType("*/*"); // gives us all sharing options
|
i.setType("*/*"); // gives us all sharing options
|
||||||
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
i.addFlags(FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
startActivity(Intent.createChooser(i, null));
|
tryToStartActivity(requireActivity(), Intent.createChooser(i, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,8 +49,10 @@ public class HotspotIntroFragment extends Fragment {
|
|||||||
private TextView progressTextView;
|
private TextView progressTextView;
|
||||||
|
|
||||||
private final AbstractConditionManager conditionManager = SDK_INT < 29 ?
|
private final AbstractConditionManager conditionManager = SDK_INT < 29 ?
|
||||||
new ConditionManager(this, this::onPermissionUpdate) :
|
new ConditionManager(this::onPermissionUpdate) :
|
||||||
new ConditionManager29(this, this::onPermissionUpdate);
|
SDK_INT >= 33 ?
|
||||||
|
new ConditionManager33(this, this::onPermissionUpdate) :
|
||||||
|
new ConditionManager29(this, this::onPermissionUpdate);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
@@ -87,7 +89,6 @@ public class HotspotIntroFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void onButtonClick(View view) {
|
private void onButtonClick(View view) {
|
||||||
startButton.setEnabled(false);
|
|
||||||
startHotspotIfConditionsFulfilled();
|
startHotspotIfConditionsFulfilled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,19 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.POST_NOTIFICATIONS;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||||
|
import static androidx.core.content.ContextCompat.checkSelfPermission;
|
||||||
import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHENER_ERROR;
|
import static org.briarproject.bramble.api.crypto.DecryptionResult.KEY_STRENGTHENER_ERROR;
|
||||||
import static org.briarproject.bramble.api.crypto.DecryptionResult.SUCCESS;
|
import static org.briarproject.bramble.api.crypto.DecryptionResult.SUCCESS;
|
||||||
import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog;
|
import static org.briarproject.briar.android.login.LoginUtils.createKeyStrengthenerErrorDialog;
|
||||||
@@ -52,6 +58,10 @@ public class PasswordFragment extends BaseFragment implements TextWatcher {
|
|||||||
private TextInputLayout input;
|
private TextInputLayout input;
|
||||||
private TextInputEditText password;
|
private TextInputEditText password;
|
||||||
|
|
||||||
|
private final ActivityResultLauncher<String> requestPermissionLauncher =
|
||||||
|
registerForActivityResult(new RequestPermission(), isGranted ->
|
||||||
|
validatePassword());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectFragment(ActivityComponent component) {
|
public void injectFragment(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -109,6 +119,17 @@ public class PasswordFragment extends BaseFragment implements TextWatcher {
|
|||||||
hideSoftKeyboard(password);
|
hideSoftKeyboard(password);
|
||||||
signInButton.setVisibility(INVISIBLE);
|
signInButton.setVisibility(INVISIBLE);
|
||||||
progress.setVisibility(VISIBLE);
|
progress.setVisibility(VISIBLE);
|
||||||
|
if (SDK_INT >= 33 &&
|
||||||
|
checkSelfPermission(requireContext(), POST_NOTIFICATIONS) !=
|
||||||
|
PERMISSION_GRANTED) {
|
||||||
|
// this calls validatePassword() when it returns
|
||||||
|
requestPermissionLauncher.launch(POST_NOTIFICATIONS);
|
||||||
|
} else {
|
||||||
|
validatePassword();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validatePassword() {
|
||||||
viewModel.validatePassword(password.getText().toString());
|
viewModel.validatePassword(password.getText().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.briar.android.reporting;
|
package org.briarproject.briar.android.reporting;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -33,13 +32,11 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.INVISIBLE;
|
import static android.view.View.INVISIBLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
import static org.briarproject.briar.android.util.UiUtils.onSingleLinkClick;
|
import static org.briarproject.briar.android.util.UiUtils.onSingleLinkClick;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -180,13 +177,7 @@ public class ReportFormFragment extends BaseFragment {
|
|||||||
private void triggerPrivacyPolicy() {
|
private void triggerPrivacyPolicy() {
|
||||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
Intent i = new Intent(Intent.ACTION_VIEW);
|
||||||
i.setData(Uri.parse("https://briarproject.org/privacy-policy/\\"));
|
i.setData(Uri.parse("https://briarproject.org/privacy-policy/\\"));
|
||||||
try {
|
tryToStartActivity(requireActivity(), i);
|
||||||
startActivity(i);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
Toast.makeText(requireContext(),
|
|
||||||
R.string.error_start_activity, LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.briar.android.settings;
|
package org.briarproject.briar.android.settings;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -8,7 +7,6 @@ import android.view.LayoutInflater;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.briarproject.briar.BuildConfig;
|
import org.briarproject.briar.BuildConfig;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
@@ -21,10 +19,9 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
import static android.content.Intent.ACTION_VIEW;
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -85,16 +82,9 @@ public class AboutFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void goToUrl(String url) {
|
private void goToUrl(String url) {
|
||||||
Intent i = new Intent(Intent.ACTION_VIEW);
|
Intent i = new Intent(ACTION_VIEW);
|
||||||
i.setData(Uri.parse(url));
|
i.setData(Uri.parse(url));
|
||||||
try {
|
tryToStartActivity(requireActivity(), i);
|
||||||
startActivity(i);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
Toast.makeText(requireContext(),
|
|
||||||
R.string.error_start_activity, LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,10 @@
|
|||||||
package org.briarproject.briar.android.settings;
|
package org.briarproject.briar.android.settings;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.mailbox.MailboxActivity;
|
import org.briarproject.briar.android.mailbox.MailboxActivity;
|
||||||
@@ -28,12 +26,12 @@ import androidx.preference.PreferenceGroup;
|
|||||||
|
|
||||||
import static android.content.Intent.ACTION_SEND;
|
import static android.content.Intent.ACTION_SEND;
|
||||||
import static android.content.Intent.EXTRA_TEXT;
|
import static android.content.Intent.EXTRA_TEXT;
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
import static org.briarproject.briar.android.AppModule.getAndroidComponent;
|
||||||
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.launchActivityToOpenFile;
|
import static org.briarproject.briar.android.util.UiUtils.launchActivityToOpenFile;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.triggerFeedback;
|
import static org.briarproject.briar.android.util.UiUtils.triggerFeedback;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -101,12 +99,8 @@ public class SettingsFragment extends PreferenceFragmentCompat {
|
|||||||
Intent sendIntent = new Intent(ACTION_SEND);
|
Intent sendIntent = new Intent(ACTION_SEND);
|
||||||
sendIntent.putExtra(EXTRA_TEXT, text);
|
sendIntent.putExtra(EXTRA_TEXT, text);
|
||||||
sendIntent.setType("text/plain");
|
sendIntent.setType("text/plain");
|
||||||
try {
|
tryToStartActivity(requireActivity(),
|
||||||
startActivity(Intent.createChooser(sendIntent, null));
|
Intent.createChooser(sendIntent, null));
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Toast.makeText(requireContext(),
|
|
||||||
R.string.error_start_activity, LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
Preference prefFeedback =
|
Preference prefFeedback =
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package org.briarproject.briar.android.util;
|
package org.briarproject.briar.android.util;
|
||||||
|
|
||||||
import android.content.ActivityNotFoundException;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||||
@@ -29,10 +27,10 @@ import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
|||||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS;
|
import static android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS;
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
|
||||||
import static androidx.core.content.ContextCompat.checkSelfPermission;
|
import static androidx.core.content.ContextCompat.checkSelfPermission;
|
||||||
import static java.lang.Boolean.TRUE;
|
import static java.lang.Boolean.TRUE;
|
||||||
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
import static org.briarproject.briar.BuildConfig.APPLICATION_ID;
|
||||||
|
import static org.briarproject.briar.android.util.UiUtils.tryToStartActivity;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -47,7 +45,7 @@ public class PermissionUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPermissionGranted(Context ctx, String permission) {
|
private static boolean isPermissionGranted(Context ctx, String permission) {
|
||||||
return checkSelfPermission(ctx, permission) ==
|
return checkSelfPermission(ctx, permission) ==
|
||||||
PERMISSION_GRANTED;
|
PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
@@ -68,7 +66,7 @@ public class PermissionUtils {
|
|||||||
gotPermission(ctx, grantedMap, BLUETOOTH_SCAN);
|
gotPermission(ctx, grantedMap, BLUETOOTH_SCAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DialogInterface.OnClickListener getGoToSettingsListener(
|
private static DialogInterface.OnClickListener getGoToSettingsListener(
|
||||||
Context context) {
|
Context context) {
|
||||||
return (dialog, which) -> {
|
return (dialog, which) -> {
|
||||||
Intent i = new Intent();
|
Intent i = new Intent();
|
||||||
@@ -76,7 +74,7 @@ public class PermissionUtils {
|
|||||||
i.addCategory(CATEGORY_DEFAULT);
|
i.addCategory(CATEGORY_DEFAULT);
|
||||||
i.setData(Uri.parse("package:" + APPLICATION_ID));
|
i.setData(Uri.parse("package:" + APPLICATION_ID));
|
||||||
i.addFlags(FLAG_ACTIVITY_NEW_TASK);
|
i.addFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||||
context.startActivity(i);
|
tryToStartActivity(context, i);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,12 +121,7 @@ public class PermissionUtils {
|
|||||||
builder.setPositiveButton(R.string.permission_location_setting_button,
|
builder.setPositiveButton(R.string.permission_location_setting_button,
|
||||||
(dialog, which) -> {
|
(dialog, which) -> {
|
||||||
Intent i = new Intent(ACTION_LOCATION_SOURCE_SETTINGS);
|
Intent i = new Intent(ACTION_LOCATION_SOURCE_SETTINGS);
|
||||||
try {
|
tryToStartActivity(ctx, i);
|
||||||
ctx.startActivity(i);
|
|
||||||
} catch (ActivityNotFoundException e) {
|
|
||||||
Toast.makeText(ctx, R.string.error_start_activity,
|
|
||||||
LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
builder.show();
|
builder.show();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,6 +157,15 @@ public class UiUtils {
|
|||||||
ta.commit();
|
ta.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void tryToStartActivity(Context ctx, Intent intent) {
|
||||||
|
try {
|
||||||
|
ctx.startActivity(intent);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Toast.makeText(ctx, R.string.error_start_activity, LENGTH_LONG)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static String getContactDisplayName(Author author,
|
public static String getContactDisplayName(Author author,
|
||||||
@Nullable String alias) {
|
@Nullable String alias) {
|
||||||
String name = author.getName();
|
String name = author.getName();
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
android:layout_margin="@dimen/margin_medium"
|
android:layout_margin="@dimen/margin_medium"
|
||||||
android:contentDescription="@string/info"
|
android:contentDescription="@string/info"
|
||||||
android:drawablePadding="@dimen/margin_medium"
|
android:drawablePadding="@dimen/margin_medium"
|
||||||
android:drawableTint="?attr/colorControlNormal"
|
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
app:drawableLeftCompat="@drawable/ic_info_dark"
|
app:drawableLeftCompat="@drawable/ic_info_dark"
|
||||||
app:drawableStartCompat="@drawable/ic_info_dark"
|
app:drawableStartCompat="@drawable/ic_info_dark"
|
||||||
|
app:drawableTint="?attr/colorControlNormal"
|
||||||
tools:text="Did you know that if you took all the veins out of your body and laid them out end to end, you would die?" />
|
tools:text="Did you know that if you took all the veins out of your body and laid them out end to end, you would die?" />
|
||||||
|
|
||||||
</merge>
|
</merge>
|
||||||
@@ -789,6 +789,7 @@
|
|||||||
<string name="permission_camera_title">Camera permission</string>
|
<string name="permission_camera_title">Camera permission</string>
|
||||||
<string name="permission_camera_request_body">To scan the QR code, Briar needs access to the camera.</string>
|
<string name="permission_camera_request_body">To scan the QR code, Briar needs access to the camera.</string>
|
||||||
<string name="permission_location_title">Location permission</string>
|
<string name="permission_location_title">Location permission</string>
|
||||||
|
<string name="permission_nearby_devices_title">Nearby devices permission</string>
|
||||||
<string name="permission_location_request_body">To discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
<string name="permission_location_request_body">To discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
||||||
<string name="permission_camera_location_title">Camera and location</string>
|
<string name="permission_camera_location_title">Camera and location</string>
|
||||||
<string name="permission_camera_location_request_body">To scan the QR code, Briar needs access to the camera.\n\nTo discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
<string name="permission_camera_location_request_body">To scan the QR code, Briar needs access to the camera.\n\nTo discover Bluetooth devices, Briar needs permission to access your location.\n\nBriar does not store your location or share it with anyone.</string>
|
||||||
@@ -833,6 +834,8 @@
|
|||||||
<string name="permission_hotspot_location_request_precise_body">To create a Wi-Fi hotspot, Briar needs permission to access your precise location.\n\nBriar does not store your location or share it with anyone.</string>
|
<string name="permission_hotspot_location_request_precise_body">To create a Wi-Fi hotspot, Briar needs permission to access your precise location.\n\nBriar does not store your location or share it with anyone.</string>
|
||||||
<string name="permission_hotspot_location_denied_body">You have denied access to your location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
<string name="permission_hotspot_location_denied_body">You have denied access to your location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
||||||
<string name="permission_hotspot_location_denied_precise_body">You have denied access to your precise location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
<string name="permission_hotspot_location_denied_precise_body">You have denied access to your precise location, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
||||||
|
<string name="permission_hotspot_nearby_wifi_request_body">To create a Wi-Fi hotspot, Briar needs permission to access nearby devices.</string>
|
||||||
|
<string name="permission_hotspot_nearby_wifi_denied_body">You have denied access to nearby devices, but Briar needs this permission to create a Wi-Fi hotspot.\n\nPlease consider granting access.</string>
|
||||||
<string name="wifi_settings_title">Wi-Fi setting</string>
|
<string name="wifi_settings_title">Wi-Fi setting</string>
|
||||||
<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
|
<string name="wifi_settings_request_enable_body">To create a Wi-Fi hotspot, Briar needs to use Wi-Fi. Please enable it.</string>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user