mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Merge branch '158-permission-requests' into 'master'
Add permission requests for Android 6+ Closes #158 See merge request !601
This commit is contained in:
@@ -10,5 +10,6 @@ public interface RequestCodes {
|
|||||||
int REQUEST_WRITE_BLOG_POST = 6;
|
int REQUEST_WRITE_BLOG_POST = 6;
|
||||||
int REQUEST_SHARE_BLOG = 7;
|
int REQUEST_SHARE_BLOG = 7;
|
||||||
int REQUEST_RINGTONE = 8;
|
int REQUEST_RINGTONE = 8;
|
||||||
|
int REQUEST_PERMISSION_CAMERA = 9;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
package org.briarproject.briar.android.keyagreement;
|
package org.briarproject.briar.android.keyagreement;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.UiThread;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import android.support.v7.app.AlertDialog.Builder;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
@@ -19,19 +25,25 @@ import org.briarproject.bramble.api.keyagreement.event.KeyAgreementFinishedEvent
|
|||||||
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.R.string;
|
||||||
|
import org.briarproject.briar.R.style;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.briar.android.keyagreement.IntroFragment.IntroScreenSeenListener;
|
import org.briarproject.briar.android.keyagreement.IntroFragment.IntroScreenSeenListener;
|
||||||
|
import org.briarproject.briar.android.util.UiUtils;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.Manifest.permission.CAMERA;
|
||||||
|
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
import static android.widget.Toast.LENGTH_LONG;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA;
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -51,6 +63,8 @@ public class KeyAgreementActivity extends BriarActivity implements
|
|||||||
@Inject
|
@Inject
|
||||||
volatile IdentityManager identityManager;
|
volatile IdentityManager identityManager;
|
||||||
|
|
||||||
|
private boolean continueClicked, gotCameraPermission;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -96,10 +110,27 @@ public class KeyAgreementActivity extends BriarActivity implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostResume() {
|
||||||
|
super.onPostResume();
|
||||||
|
// Workaround for
|
||||||
|
// https://code.google.com/p/android/issues/detail?id=190966
|
||||||
|
if (continueClicked && gotCameraPermission) {
|
||||||
|
showQrCodeFragment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showNextScreen() {
|
public void showNextScreen() {
|
||||||
// FIXME #824
|
// FIXME #824
|
||||||
// showNextFragment(ShowQrCodeFragment.newInstance());
|
// showNextFragment(ShowQrCodeFragment.newInstance());
|
||||||
|
continueClicked = true;
|
||||||
|
if (checkPermissions()) {
|
||||||
|
showQrCodeFragment();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showQrCodeFragment() {
|
||||||
BaseFragment f = ShowQrCodeFragment.newInstance();
|
BaseFragment f = ShowQrCodeFragment.newInstance();
|
||||||
getSupportFragmentManager().beginTransaction()
|
getSupportFragmentManager().beginTransaction()
|
||||||
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
.replace(R.id.fragmentContainer, f, f.getUniqueTag())
|
||||||
@@ -107,6 +138,73 @@ public class KeyAgreementActivity extends BriarActivity implements
|
|||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean checkPermissions() {
|
||||||
|
if (ContextCompat.checkSelfPermission(this, CAMERA) !=
|
||||||
|
PERMISSION_GRANTED) {
|
||||||
|
// Should we show an explanation?
|
||||||
|
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||||
|
CAMERA)) {
|
||||||
|
OnClickListener continueListener = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
requestPermission();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Builder builder = new Builder(this, style.BriarDialogTheme);
|
||||||
|
builder.setTitle(string.permission_camera_title);
|
||||||
|
builder.setMessage(string.permission_camera_request_body);
|
||||||
|
builder.setNeutralButton(string.continue_button,
|
||||||
|
continueListener);
|
||||||
|
builder.show();
|
||||||
|
} else {
|
||||||
|
requestPermission();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestPermission() {
|
||||||
|
ActivityCompat.requestPermissions(this, new String[] {CAMERA},
|
||||||
|
REQUEST_PERMISSION_CAMERA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@UiThread
|
||||||
|
public void onRequestPermissionsResult(int requestCode,
|
||||||
|
String permissions[], int[] grantResults) {
|
||||||
|
if (requestCode == REQUEST_PERMISSION_CAMERA) {
|
||||||
|
// If request is cancelled, the result arrays are empty.
|
||||||
|
if (grantResults.length > 0 &&
|
||||||
|
grantResults[0] == PERMISSION_GRANTED) {
|
||||||
|
gotCameraPermission = true;
|
||||||
|
} else {
|
||||||
|
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,
|
||||||
|
CAMERA)) {
|
||||||
|
// The user has permanently denied the request
|
||||||
|
OnClickListener cancelListener = new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
supportFinishAfterTransition();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Builder builder = new Builder(this, style.BriarDialogTheme);
|
||||||
|
builder.setTitle(string.permission_camera_title);
|
||||||
|
builder.setMessage(string.permission_camera_denied_body);
|
||||||
|
builder.setPositiveButton(string.ok,
|
||||||
|
UiUtils.getGoToSettingsListener(this));
|
||||||
|
builder.setNegativeButton(string.cancel, cancelListener);
|
||||||
|
builder.show();
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, string.permission_camera_denied_toast,
|
||||||
|
LENGTH_LONG).show();
|
||||||
|
supportFinishAfterTransition();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof KeyAgreementFinishedEvent) {
|
if (e instanceof KeyAgreementFinishedEvent) {
|
||||||
@@ -189,5 +287,4 @@ public class KeyAgreementActivity extends BriarActivity implements
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
|||||||
public View onCreateView(LayoutInflater inflater,
|
public View onCreateView(LayoutInflater inflater,
|
||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
|
||||||
return inflater.inflate(R.layout.fragment_keyagreement_qr, container,
|
return inflater.inflate(R.layout.fragment_keyagreement_qr, container,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
@@ -144,13 +145,11 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
|||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cameraView.start();
|
cameraView.start();
|
||||||
} catch (CameraException e) {
|
} catch (CameraException e) {
|
||||||
logCameraExceptionAndFinish(e);
|
logCameraExceptionAndFinish(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen for changes to the Bluetooth state
|
// Listen for changes to the Bluetooth state
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(ACTION_STATE_CHANGED);
|
filter.addAction(ACTION_STATE_CHANGED);
|
||||||
@@ -158,7 +157,8 @@ public class ShowQrCodeFragment extends BaseEventFragment
|
|||||||
getActivity().registerReceiver(receiver, filter);
|
getActivity().registerReceiver(receiver, filter);
|
||||||
|
|
||||||
// Enable BT adapter if it is not already on.
|
// Enable BT adapter if it is not already on.
|
||||||
final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
final BluetoothAdapter adapter =
|
||||||
|
BluetoothAdapter.getDefaultAdapter();
|
||||||
if (adapter != null && !adapter.isEnabled()) {
|
if (adapter != null && !adapter.isEnabled()) {
|
||||||
waitingForBluetooth = true;
|
waitingForBluetooth = true;
|
||||||
eventBus.broadcast(new EnableBluetoothEvent());
|
eventBus.broadcast(new EnableBluetoothEvent());
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
package org.briarproject.briar.android.util;
|
package org.briarproject.briar.android.util;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
import android.support.design.widget.TextInputLayout;
|
import android.support.design.widget.TextInputLayout;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
@@ -18,12 +23,14 @@ import android.view.View;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
|
import org.briarproject.briar.BuildConfig;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.view.ArticleMovementMethod;
|
import org.briarproject.briar.android.view.ArticleMovementMethod;
|
||||||
import org.briarproject.briar.android.widget.LinkDialogFragment;
|
import org.briarproject.briar.android.widget.LinkDialogFragment;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import static android.content.Intent.*;
|
||||||
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
import static android.text.format.DateUtils.DAY_IN_MILLIS;
|
||||||
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
|
import static android.text.format.DateUtils.FORMAT_ABBREV_MONTH;
|
||||||
import static android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE;
|
import static android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE;
|
||||||
@@ -31,6 +38,7 @@ import static android.text.format.DateUtils.FORMAT_ABBREV_TIME;
|
|||||||
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
|
import static android.text.format.DateUtils.FORMAT_SHOW_DATE;
|
||||||
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
|
||||||
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
import static android.text.format.DateUtils.WEEK_IN_MILLIS;
|
||||||
|
import static org.briarproject.briar.BuildConfig.*;
|
||||||
import static org.briarproject.briar.android.BriarApplication.EXPIRY_DATE;
|
import static org.briarproject.briar.android.BriarApplication.EXPIRY_DATE;
|
||||||
|
|
||||||
public class UiUtils {
|
public class UiUtils {
|
||||||
@@ -127,4 +135,18 @@ public class UiUtils {
|
|||||||
return "bulb" + c.getInt();
|
return "bulb" + c.getInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OnClickListener getGoToSettingsListener(
|
||||||
|
final Context context) {
|
||||||
|
return new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
|
||||||
|
i.addCategory(CATEGORY_DEFAULT);
|
||||||
|
i.setData(Uri.parse("package:" + APPLICATION_ID));
|
||||||
|
i.addFlags(FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
context.startActivity(i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -381,4 +381,10 @@
|
|||||||
<string name="screen_filter_title">Screen overlay detected</string>
|
<string name="screen_filter_title">Screen overlay detected</string>
|
||||||
<string name="screen_filter_body">Another app is drawing on top of Briar. To protect your security, Briar will not respond to touches when another app is drawing on top.\n\nTry turning off the following apps when using Briar:\n\n%1$s</string>
|
<string name="screen_filter_body">Another app is drawing on top of Briar. To protect your security, Briar will not respond to touches when another app is drawing on top.\n\nTry turning off the following apps when using Briar:\n\n%1$s</string>
|
||||||
|
|
||||||
|
<!-- Permission Requests and Doze Mode -->
|
||||||
|
<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_denied_body">You have denied access to the camera, but adding contacts requires using the camera.\n\nPlease consider granting access.</string>
|
||||||
|
<string name="permission_camera_denied_toast">Camera permission was not granted</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user