Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/permission settings #199

Merged
merged 32 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
82aaf55
add permissions in settings
dhruv2295 May 17, 2021
7054bf5
hook permission code
dhruv2295 May 18, 2021
55a5b8f
permission integration in settings successful
dhruv2295 May 19, 2021
a3ae8de
stylefile
dhruv2295 May 19, 2021
8f40698
Merge branch 'master' into feature/permissionSettings
dhruv2295 May 19, 2021
b25b84a
refactor permission utils
thias15 May 23, 2021
97eec0d
open app preferences to grant permission if user denies them
dhruv2295 May 24, 2021
2b45fe3
show permission message toast when user previously denied them
dhruv2295 May 28, 2021
7fe95d3
style
dhruv2295 May 28, 2021
1a817e1
settings permissions overhaul
dhruv2295 May 28, 2021
9de60bb
style
dhruv2295 May 28, 2021
a5abccf
model management, camera, and control fragment permission overhaul
dhruv2295 May 28, 2021
a2eb1f5
overhaul complete
dhruv2295 May 28, 2021
58c78d6
move toasts and string constants to common places
dhruv2295 May 28, 2021
8534e7c
more cleanup
dhruv2295 May 28, 2021
e676676
model management and settings screen permission messages cleanup
dhruv2295 May 28, 2021
a8de35d
remove kotlin plugin
dhruv2295 May 28, 2021
36f5b2d
location permission method call fix
dhruv2295 May 28, 2021
79ae710
remove unused storage permission check
dhruv2295 May 28, 2021
f87a7f8
style
dhruv2295 May 28, 2021
0745d0c
Remove LOGGER
thias15 Jun 2, 2021
c7400e3
fix permission text instead of resource id
dhruv2295 Jun 2, 2021
1493918
use stable versions
thias15 Jun 2, 2021
e39e647
control fragment toast cleanup
dhruv2295 Jun 2, 2021
722b2f4
refactor permissions --> permission for single
thias15 Jun 2, 2021
c169949
resolve conflicts
thias15 Jun 2, 2021
9e8104b
fix style
thias15 Jun 2, 2021
7c8f460
permission conditions test
dhruv2295 Jun 2, 2021
46f8e8c
Merge branch 'feature/permissionSettings' of https://github.com/dhruv…
dhruv2295 Jun 2, 2021
599d70e
unify toast messages
thias15 Jun 2, 2021
57fb453
Ensure camera fragment will ask for permission again
thias15 Jun 2, 2021
bc53130
fix logic bug
thias15 Jun 2, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,15 @@ dependencies {
implementation 'com.google.android.material:material:1.3.0'

// Build off of stable TensorFlow Lite
implementation 'org.tensorflow:tensorflow-lite:2.4.0'
implementation 'org.tensorflow:tensorflow-lite-gpu:2.4.0'
implementation 'org.tensorflow:tensorflow-lite:2.5.0'
implementation 'org.tensorflow:tensorflow-lite-gpu:2.5.0'

implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-location:18.0.0'
implementation 'com.github.felHR85:UsbSerial:6.1.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.1.0'
implementation 'org.zeroturnaround:zt-zip:1.14'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'

implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-nearby:17.0.0'

// RTSP server
Expand All @@ -74,36 +72,35 @@ dependencies {
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'org.jetbrains:annotations:16.0.1'

implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.0'
implementation 'androidx.recyclerview:recyclerview:1.2.0'
implementation 'androidx.lifecycle:lifecycle-livedata:2.3.1'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.3.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.preference:preference:1.1.1'

def nav_version = "2.3.2"
def nav_version = "2.3.5"
// Java language implementation
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

def camerax_version = "1.0.0-rc01"
def camerax_version = "1.0.0"
// CameraX core library using camera2 implementation
implementation "androidx.camera:camera-camera2:$camerax_version"
// CameraX Lifecycle Library
implementation "androidx.camera:camera-lifecycle:$camerax_version"
// CameraX View class
implementation "androidx.camera:camera-view:1.0.0-alpha20"
implementation "androidx.camera:camera-view:1.0.0-alpha24"
implementation 'com.github.anastr:speedviewlib:1.5.3'

implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'androidx.fragment:fragment:1.3.0-rc01'
implementation 'androidx.fragment:fragment:1.3.4'

testImplementation 'junit:junit:4.13.1'
testImplementation 'junit:junit:4.13.2'
testImplementation 'androidx.test.ext:junit:1.1.2'
testImplementation 'androidx.test:core:1.3.0'
testImplementation "org.robolectric:robolectric:4.4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,11 +563,8 @@ private void setControlMode(Enums.ControlMode controlMode) {
break;
case PHONE:
binding.controllerContainer.controlMode.setImageResource(R.drawable.ic_phone);
if (!PermissionUtils.hasPermission(requireContext(), Constants.PERMISSION_LOCATION))
PermissionUtils.requestPermissions(
this,
new String[] {Constants.PERMISSION_LOCATION},
Constants.REQUEST_LOCATION_PERMISSION_CONTROLLER);
if (!PermissionUtils.hasControllerPermissions(requireActivity()))
requestPermissionLauncher.launch(Constants.PERMISSIONS_CONTROLLER);
else connectPhoneController();

break;
Expand Down
57 changes: 27 additions & 30 deletions android/app/src/main/java/org/openbot/common/CameraFragment.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.openbot.common;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
Expand All @@ -10,6 +9,8 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.AspectRatio;
Expand All @@ -27,16 +28,16 @@
import java.util.concurrent.Executors;
import org.openbot.R;
import org.openbot.env.ImageUtils;
import org.openbot.env.Logger;
import org.openbot.utils.Constants;
import org.openbot.utils.Enums;
import org.openbot.utils.PermissionUtils;
import org.openbot.utils.YuvToRgbConverter;

import timber.log.Timber;

public abstract class CameraFragment extends ControlsFragment {

private ExecutorService cameraExecutor;
private final int PERMISSIONS_REQUEST_CODE = 10;
private final String[] PERMISSIONS_REQUIRED = new String[] {Manifest.permission.CAMERA};
private static final Logger LOGGER = new Logger();
private PreviewView previewView;
private Preview preview;
private static int lensFacing = CameraSelector.LENS_FACING_BACK;
Expand All @@ -62,8 +63,14 @@ private View addCamera(View view, LayoutInflater inflater, ViewGroup container)
previewView = cameraView.findViewById(R.id.viewFinder);
rootView.addView(view);

if (allPermissionsGranted()) setupCamera();
else requestPermissions(PERMISSIONS_REQUIRED, PERMISSIONS_REQUEST_CODE);
if (ContextCompat.checkSelfPermission(requireContext(), Constants.PERMISSION_CAMERA)
== PackageManager.PERMISSION_GRANTED) {
setupCamera();
} else if (shouldShowRequestPermissionRationale(Constants.PERMISSION_CAMERA)) {
PermissionUtils.showCameraPermissionControllerToast(requireActivity());
} else {
requestPermissionLauncherCamera.launch(Constants.PERMISSION_CAMERA);
}

return cameraView;
}
Expand All @@ -85,13 +92,13 @@ private void setupCamera() {
cameraProvider = cameraProviderFuture.get();
bindCameraUseCases();
} catch (ExecutionException | InterruptedException e) {
LOGGER.e(e.toString());
Timber.e("Camera setup failed: %s", e.toString());
}
},
ContextCompat.getMainExecutor(requireContext()));
}

@SuppressLint("UnsafeExperimentalUsageError")
@SuppressLint({"UnsafeExperimentalUsageError", "UnsafeOptInUsageError"})
private void bindCameraUseCases() {
converter = new YuvToRgbConverter(requireContext());
bitmapBuffer = null;
Expand Down Expand Up @@ -130,24 +137,24 @@ private void bindCameraUseCases() {
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
}
} catch (Exception e) {
LOGGER.e("Use case binding failed: %s", e);
Timber.e("Use case binding failed: %s", e.toString());
}
}

public int getRotationDegrees() {
return rotationDegrees;
}

@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSIONS_REQUEST_CODE) {
if (allPermissionsGranted()) {
setupCamera();
}
}
}
private final ActivityResultLauncher<String> requestPermissionLauncherCamera =
registerForActivityResult(
new ActivityResultContracts.RequestPermission(),
isGranted -> {
if (isGranted) {
setupCamera();
} else {
PermissionUtils.showCameraPermissionControllerToast(requireActivity());
}
});

@Override
public void onDestroy() {
Expand Down Expand Up @@ -182,15 +189,5 @@ public void setAnalyserResolution(Size resolutionSize) {
bindCameraUseCases();
}

private boolean allPermissionsGranted() {
boolean permissionsGranted = false;
for (String permission : PERMISSIONS_REQUIRED)
permissionsGranted =
ContextCompat.checkSelfPermission(requireContext(), permission)
== PackageManager.PERMISSION_GRANTED;

return permissionsGranted;
}

protected abstract void processFrame(Bitmap image, ImageProxy imageProxy);
}
56 changes: 14 additions & 42 deletions android/app/src/main/java/org/openbot/common/ControlsFragment.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package org.openbot.common;

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
Expand Down Expand Up @@ -226,46 +226,18 @@ private void toggleIndicatorEvent(int value) {
BotToControllerEventBus.emitEvent(ConnectionUtils.createStatus("INDICATOR_STOP", value == 0));
}

@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case Constants.REQUEST_CONTROLLER_PERMISSIONS:
// If the permission is granted, start advertising to controller,
// otherwise, show a Toast
if (grantResults.length > 1
&& (grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED)) {
phoneController.connect(requireContext());
} else {
if (PermissionUtils.shouldShowRational(
requireActivity(), Constants.PERMISSION_LOCATION)) {
Toast.makeText(
requireActivity().getApplicationContext(),
R.string.location_permission_denied_controller,
Toast.LENGTH_LONG)
.show();
}
if (PermissionUtils.shouldShowRational(
requireActivity(), Constants.PERMISSION_AUDIO_RECORDING)) {
Toast.makeText(
requireActivity().getApplicationContext(),
R.string.record_audio_permission_denied_controller,
Toast.LENGTH_LONG)
.show();
}
if (PermissionUtils.shouldShowRational(requireActivity(), Constants.PERMISSION_CAMERA)) {
Toast.makeText(
requireActivity().getApplicationContext(),
R.string.camera_permission_denied_controller,
Toast.LENGTH_LONG)
.show();
}
break;
}
}
}
private boolean allGranted = false;
protected final ActivityResultLauncher<String[]> requestPermissionLauncher =
registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
result -> {
result.forEach((permission, granted) -> allGranted = allGranted && granted);

if (allGranted) phoneController.connect(requireContext());
else {
PermissionUtils.showControllerPermissionsToast(requireActivity());
}
});

@Override
public void onResume() {
Expand Down
72 changes: 17 additions & 55 deletions android/app/src/main/java/org/openbot/logging/LoggerFragment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
Expand All @@ -22,7 +21,8 @@
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.ImageProxy;
Expand Down Expand Up @@ -330,15 +330,8 @@ private void stopLogging() {

protected void setIsLoggingActive(boolean loggingActive) {
if (loggingActive && !loggingEnabled) {
if (!PermissionUtils.hasPermission(requireContext(), Constants.PERMISSION_CAMERA)
&& (binding.previewCheckBox.isChecked() || binding.trainingDataCheckBox.isChecked())) {
PermissionUtils.requestCameraPermission(this);
loggingEnabled = false;
} else if (!PermissionUtils.hasPermission(requireContext(), Constants.PERMISSION_LOCATION)) {
PermissionUtils.requestLocationPermissionLogging(this);
loggingEnabled = false;
} else if (!PermissionUtils.hasPermission(requireContext(), Constants.PERMISSION_STORAGE)) {
PermissionUtils.requestStoragePermission(this);
if (!PermissionUtils.hasLoggingPermissions(requireActivity())) {
requestPermissionLauncherLogging.launch(Constants.PERMISSIONS_LOGGING);
loggingEnabled = false;
} else {
startLogging();
Expand All @@ -353,44 +346,17 @@ protected void setIsLoggingActive(boolean loggingActive) {
binding.loggerSwitch.setChecked(loggingEnabled);
}

@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case Constants.REQUEST_LOCATION_PERMISSION_LOGGING:
// If the permission is granted, start logging,
// otherwise, show a Toast
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setIsLoggingActive(true);
} else {
if (PermissionUtils.shouldShowRational(
requireActivity(), Constants.PERMISSION_LOCATION)) {
Toast.makeText(
requireContext().getApplicationContext(),
R.string.location_permission_denied_logging,
Toast.LENGTH_LONG)
.show();
}
}
break;
case Constants.REQUEST_STORAGE_PERMISSION:
// If the permission is granted, start logging,
// otherwise, show a Toast
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
setIsLoggingActive(true);
} else {
if (PermissionUtils.shouldShowRational(requireActivity(), Constants.PERMISSION_STORAGE)) {
Toast.makeText(
requireContext().getApplicationContext(),
R.string.storage_permission_denied_logging,
Toast.LENGTH_LONG)
.show();
}
}
break;
}
}
boolean allGranted = false;
protected final ActivityResultLauncher<String[]> requestPermissionLauncherLogging =
registerForActivityResult(
new ActivityResultContracts.RequestMultiplePermissions(),
result -> {
result.forEach((permission, granted) -> allGranted = allGranted && granted);
if (allGranted) setIsLoggingActive(true);
else {
PermissionUtils.showLoggingPermissionsToast(requireActivity());
}
});

protected void handleLogging() {
setIsLoggingActive(!loggingEnabled);
Expand Down Expand Up @@ -487,13 +453,9 @@ private void setControlMode(Enums.ControlMode controlMode) {
break;
case PHONE:
binding.controllerContainer.controlMode.setImageResource(R.drawable.ic_phone);
if (!PermissionUtils.hasPermission(requireContext(), Constants.PERMISSION_LOCATION))
PermissionUtils.requestPermissions(
this,
new String[] {Constants.PERMISSION_LOCATION},
Constants.REQUEST_LOCATION_PERMISSION_CONTROLLER);
if (!PermissionUtils.hasControllerPermissions(requireActivity()))
requestPermissionLauncher.launch(Constants.PERMISSIONS_CONTROLLER);
else connectPhoneController();

break;
}
Timber.d("Updating controlMode: %s", controlMode);
Expand Down
Loading