From bddc3e50b80e9355b7a4495e37ce1decec3d4867 Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 25 Dec 2023 11:26:27 +0530 Subject: [PATCH 1/6] camera: adjust focus timeout for faster clicks --- .../opencamera/cameracontroller/CameraController2.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java b/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java index 7104a1895..462eba930 100644 --- a/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java +++ b/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java @@ -180,7 +180,7 @@ public class CameraController2 extends CameraController { private boolean previewIsVideoMode; private AutoFocusCallback autofocus_cb; private long autofocus_time_ms = -1; // time we set autofocus_cb to non-null - private static final long autofocus_timeout_c = 1000; // timeout for calling autofocus_cb (applies for both auto and continuous focus) + private static final long autofocus_timeout_c = 250; // timeout for calling autofocus_cb (applies for both auto and continuous focus) private boolean capture_follows_autofocus_hint; private boolean ready_for_capture; private FaceDetectionListener face_detection_listener; @@ -265,8 +265,8 @@ public class CameraController2 extends CameraController { private static final int STATE_WAITING_FAKE_PRECAPTURE_DONE = 5; private int state = STATE_NORMAL; private long precapture_state_change_time_ms = -1; // time we changed state for precapture modes - private static final long precapture_start_timeout_c = 2000; - private static final long precapture_done_timeout_c = 3000; + private static final long precapture_start_timeout_c = 500; + private static final long precapture_done_timeout_c = 1000; private boolean use_fake_precapture; // see CameraController.setUseCamera2FakeFlash() for details - this is the user/application setting, see use_fake_precapture_mode for whether fake precapture is enabled (as we may do this for other purposes, e.g., front screen flash) private boolean use_fake_precapture_mode; // true if either use_fake_precapture is true, or we're temporarily using fake precapture mode (e.g., for front screen flash or exposure bracketing) -- GitLab From 0907b824b1862cce08e9cfdeb2b562f91718af7d Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 25 Dec 2023 11:36:22 +0530 Subject: [PATCH 2/6] camera: enable hw accelerated for smooth animations - Speed up the animation aswell --- app/src/main/AndroidManifest.xml | 1 + .../main/java/net/sourceforge/opencamera/ui/DrawPreview.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 0f69e855c..91ea491c1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -40,6 +40,7 @@ android:name="net.sourceforge.opencamera.OpenCameraApplication" android:theme="@style/AppTheme" android:largeHeap="true" + android:hardwareAccelerated="true" android:requestLegacyExternalStorage="true" > diff --git a/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java b/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java index 7285ac7fa..42769763f 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java +++ b/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java @@ -2484,7 +2484,7 @@ public class DrawPreview { if( camera_controller != null && this.thumbnail_anim && last_thumbnail != null ) { int ui_rotation = preview.getUIRotation(); long time = time_ms - this.thumbnail_anim_start_ms; - final long duration = 500; + final long duration = 400; if( time > duration ) { if( MyDebug.LOG ) Log.d(TAG, "thumbnail_anim finished"); -- GitLab From 47c3bf49bf9007fef83282d96f6e612e5c1935b8 Mon Sep 17 00:00:00 2001 From: Mark Harman Date: Fri, 21 Jul 2023 21:22:31 +0100 Subject: [PATCH 3/6] Tweak frame rate for Android 13+. --- .../net/sourceforge/opencamera/preview/Preview.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/preview/Preview.java b/app/src/main/java/net/sourceforge/opencamera/preview/Preview.java index 9d856a2ad..4e4fe633e 100644 --- a/app/src/main/java/net/sourceforge/opencamera/preview/Preview.java +++ b/app/src/main/java/net/sourceforge/opencamera/preview/Preview.java @@ -8527,9 +8527,17 @@ public class Preview implements SurfaceHolder.Callback, TextureView.SurfaceTextu frame rate when applying the dimming effect when reopening or updating the camera (see DrawPreview.setDimPreview()) (especially for MainActivity.updateForSettings() when we pause/unpause the preview instead of reopening the camera). + Update: On more recent Android versions, this effect no longer seems to happen, and on + Android 13 (at least Pixel 6 Pro), we see the reverse (but more reasonable) behaviour + where we have fewer janky frames with a longer frame rate. Behaviour is much better at + 32ms compared to 16ms; and we shouldn't go any slower (firstly so that UI still runs + smoothly; secondly for dimming effect as noted above). */ // - if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) { + if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ) { + return 32; + } + else if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N ) { if( is_test_junit4 ) { // see https://stackoverflow.com/questions/29550508/espresso-freezing-on-view-with-looping-animation return 32; -- GitLab From b84501e4d697ed90f485bb7db5ee7581a3ef6720 Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 25 Dec 2023 12:02:56 +0530 Subject: [PATCH 4/6] camera: Update gradle to 8.2.0 --- app/build.gradle | 27 ++++++++++--------- app/src/main/AndroidManifest.xml | 1 - .../opencamera/MyApplicationInterface.java | 2 +- app/src/main/res/values/styles.xml | 2 +- build.gradle | 2 +- gradle.properties | 2 ++ gradle/wrapper/gradle-wrapper.properties | 4 +-- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 52eeee9ed..4814d5afa 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' apply plugin: 'org.jetbrains.kotlin.android' android { - compileSdkVersion 31 + compileSdkVersion 33 compileOptions.encoding = 'UTF-8' compileOptions { @@ -23,7 +23,7 @@ android { defaultConfig { applicationId "foundation.e.camera" minSdkVersion 25 - targetSdkVersion 31 + targetSdkVersion 33 renderscriptTargetApi 21 //renderscriptSupportModeEnabled true // don't use support library as it bloats the APK, and we don't need pre-4.4 support @@ -56,28 +56,31 @@ android { abortOnError false checkReleaseBuilds false } + buildFeatures { + renderScript true + buildConfig true + } + namespace 'foundation.e.camera' //useLibrary 'android.test.mock' - } dependencies { //noinspection GradleCompatible implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation "androidx.constraintlayout:constraintlayout:2.1.3" + implementation "androidx.constraintlayout:constraintlayout:2.1.4" implementation "org.greenrobot:eventbus:3.3.1" - implementation 'androidx.core:core-ktx:1.8.0' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' // appcompat version must be 1.4.0 or later to satisfy emoji policy! - implementation 'androidx.appcompat:appcompat:1.4.1' + implementation 'androidx.appcompat:appcompat:1.6.1' - implementation 'androidx.exifinterface:exifinterface:1.3.3' + implementation 'androidx.exifinterface:exifinterface:1.3.7' implementation 'foundation.e:elib:0.0.1-alpha11' - testImplementation 'junit:junit:4.13.1' + testImplementation 'junit:junit:4.13.2' // newer AndroidJUnit4 InstrumentedTest - androidTestImplementation "androidx.test:runner:1.4.0" - androidTestImplementation "androidx.test:rules:1.4.0" - androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0" + androidTestImplementation "androidx.test:runner:1.5.2" + androidTestImplementation "androidx.test:rules:1.5.0" + androidTestImplementation "androidx.test.espresso:espresso-core:3.5.1" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 91ea491c1..b8fdfc42a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ true @null - + diff --git a/build.gradle b/build.gradle index e7b1b4e37..45066a3a4 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.2.0' + classpath 'com.android.tools.build:gradle:8.2.0' classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.10' } } diff --git a/gradle.properties b/gradle.properties index fa694f82c..4ff57088d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,5 @@ android.useAndroidX=true android.enableJetifier=true org.gradle.jvmargs=-Xmx1400m org.gradle.parallel=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0ba64bae1..828c5fc5e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Oct 13 22:07:50 BST 2020 +#Mon Dec 25 11:59:58 IST 2023 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip -- GitLab From d6d0728e075a5f0e93b2e629f8abbaf22846e42c Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 25 Dec 2023 12:11:55 +0530 Subject: [PATCH 5/6] camera: cleanup privacy preference --- .../opencamera/MyPreferenceFragment.java | 18 +++++++----------- app/src/main/res/values/strings.xml | 18 +++++++++--------- 2 files changed, 16 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/MyPreferenceFragment.java b/app/src/main/java/net/sourceforge/opencamera/MyPreferenceFragment.java index 4fd422c42..677f69f21 100644 --- a/app/src/main/java/net/sourceforge/opencamera/MyPreferenceFragment.java +++ b/app/src/main/java/net/sourceforge/opencamera/MyPreferenceFragment.java @@ -814,18 +814,14 @@ public class MyPreferenceFragment extends PreferenceFragment implements OnShared { final Preference pref = findPreference("preference_privacy_policy"); - pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference arg0) { - if( pref.getKey().equals("preference_privacy_policy") ) { - if( MyDebug.LOG ) - Log.d(TAG, "user clicked privacy policy"); - MainActivity main_activity = (MainActivity)MyPreferenceFragment.this.getActivity(); - main_activity.launchOnlinePrivacyPolicy(); - return false; - } - return false; + pref.setOnPreferenceClickListener(arg0 -> { + if( pref.getKey().equals("preference_privacy_policy") ) { + if( MyDebug.LOG ) + Log.d(TAG, "user clicked privacy policy"); + MainActivity main_activity = (MainActivity)MyPreferenceFragment.this.getActivity(); + main_activity.launchOnlinePrivacyPolicy(); } + return false; }); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 609ba6752..cabe24905 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1027,25 +1027,25 @@ Open Camera is developed by Mark Harman. - <br/>Open Camera accesses camera sensor and microphone data to fulfil its purpose as a camera. + \nOpen Camera accesses camera sensor and microphone data to fulfil its purpose as a camera. Microphone is also used for the optional \"Audio control\". - <br/>Access to files is needed (at least for Android 9 and earlier) to save resultant files such as photos and videos to your device. - <br/>Location permission is requested in order to deliver the optional geotagging features (for photos and videos, + \nAccess to files is needed (at least for Android 9 and earlier) to save resultant files such as photos and videos to your device. + \nLocation permission is requested in order to deliver the optional geotagging features (for photos and videos, including stamp and subtitles options). When relevant option(s) are enabled, your device location will be stored in photo/video/subtitle files. - <br/>Bluetooth permissions are used to allow the optional feature to discover and connect to Bluetooth LE remote control devices; + \nBluetooth permissions are used to allow the optional feature to discover and connect to Bluetooth LE remote control devices; the Bluetooth remote control feature also requires location permission (on Android 11 or earlier) or Nearby Devices permission (on Android 12 or later). - <br/>Resultant data such as photos or videos can be shared with + \nResultant data such as photos or videos can be shared with other apps if you use the share option in Open Camera, or when Open Camera is called by another app on your device, or when you use the Storage Access Framework option to save to another app or service. - <br/>Data handling procedures, data retention and deletion policies: Open Camera + \nData handling procedures, data retention and deletion policies: Open Camera does not transmit personal or sensitive information to me. - <br/>Since Open Camera also uses operating system APIs, you should review relevant privacy policies + \nSince Open Camera also uses operating system APIs, you should review relevant privacy policies such as for your device, manufacturer, operating system and/or Google accounts. For example: - <br/>*Apps/services such as cloud services on your device may auto-upload photos and videos that are saved on your device. - <br/>If you have inquiries about my privacy policy, please contact me by email at + \n*Apps/services such as cloud services on your device may auto-upload photos and videos that are saved on your device. + \nIf you have inquiries about my privacy policy, please contact me by email at <a href=\"mailto:mark.harman.apps@gmail.com?subject=Open%20Camera%20privacy%20policy\">mark.harman.apps@gmail.com</a>. -- GitLab From 6186e83d050b6690495bb97a92820746fe56cf60 Mon Sep 17 00:00:00 2001 From: althafvly Date: Mon, 25 Dec 2023 12:35:38 +0530 Subject: [PATCH 6/6] camera: alert user if camera is unable to focus --- .../cameracontroller/CameraController2.java | 36 +++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java b/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java index 462eba930..92648b9d0 100644 --- a/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java +++ b/app/src/main/java/net/sourceforge/opencamera/cameracontroller/CameraController2.java @@ -44,6 +44,7 @@ import android.view.Display; import android.view.Surface; import android.view.SurfaceHolder; import android.view.TextureView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; @@ -65,6 +66,8 @@ import java.util.Locale; import java.util.Queue; import java.util.concurrent.Executor; +import foundation.e.camera.R; + /** Provides support using Android 5's Camera 2 API * android.hardware.camera2.*. */ @@ -100,6 +103,8 @@ public class CameraController2 extends CameraController { private long min_exposure_time; private long max_exposure_time; + private int toastCounter = 0; + private final static int tonemap_log_max_curve_points_c = 64; private final static float [] jtvideo_values_base = new float[] { 0.00f, 0.00f, @@ -180,7 +185,7 @@ public class CameraController2 extends CameraController { private boolean previewIsVideoMode; private AutoFocusCallback autofocus_cb; private long autofocus_time_ms = -1; // time we set autofocus_cb to non-null - private static final long autofocus_timeout_c = 250; // timeout for calling autofocus_cb (applies for both auto and continuous focus) + private static final long autofocus_timeout_c = 500; // timeout for calling autofocus_cb (applies for both auto and continuous focus) private boolean capture_follows_autofocus_hint; private boolean ready_for_capture; private FaceDetectionListener face_detection_listener; @@ -8195,14 +8200,17 @@ public class CameraController2 extends CameraController { // need to check af_state != null, I received Google Play crash in 1.33 where it was null boolean focus_success = af_state != null && ( af_state == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED || af_state == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED ); if( MyDebug.LOG ) { - if( focus_success ) + if( focus_success ) { Log.d(TAG, "autofocus success"); - else + } else { Log.d(TAG, "autofocus failed"); - if( af_state == null ) + onFocusFailed(); + } + if( af_state == null ) { Log.e(TAG, "continuous focus mode but af_state is null"); - else + } else { Log.d(TAG, "af_state: " + af_state); + } } if( af_state == null ) { test_af_state_null_focus++; @@ -8255,10 +8263,12 @@ public class CameraController2 extends CameraController { ) { boolean focus_success = af_state == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED || af_state == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED; if( MyDebug.LOG ) { - if( focus_success ) + if( focus_success ) { Log.d(TAG, "onCaptureCompleted: autofocus success"); - else + } else { Log.d(TAG, "onCaptureCompleted: autofocus failed"); + onFocusFailed(); + } Log.d(TAG, "af_state: " + af_state); } state = STATE_NORMAL; @@ -8448,6 +8458,18 @@ public class CameraController2 extends CameraController { } } + private void onFocusFailed() { + // Show only if focus failed twice. + if (toastCounter == 1) { + Toast.makeText(context, + R.string.preference_failed_focus_mode_message, + Toast.LENGTH_SHORT).show(); + toastCounter = 0; + } else { + toastCounter++; + } + } + private void handleContinuousFocusMove(CaptureResult result) { Integer af_state = result.get(CaptureResult.CONTROL_AF_STATE); if( af_state != null && af_state == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN && af_state != last_af_state ) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cabe24905..2ab7f9bc1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -783,6 +783,7 @@ Unlock exposure Low light mode: please hold the camera steady + Please hold the camera steady for better photos. Pano Panorama -- GitLab