diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fbfcd77e0d9a81981188a5ccbddbe47432abc4d0..8e2f31462cc1846f193f597d55388d36cf1a2ec9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -73,4 +73,5 @@ update-default-branch: UPSTREAM_BRANCH: upstream/master UPSTREAM_DEFAULT_BRANCH: master UPSTREAM_URL: https://git.code.sf.net/p/opencamera/code - TEMP_LATEST_TAG_BRANCH: latest_upstream_tag_branch \ No newline at end of file + TEMP_LATEST_TAG_BRANCH: latest_upstream_tag_branch + allow_failure: true diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 57b47934bf0eedd6633548c22f1c78f2070516fb..6adbfcf4052af026e899e2dbc0d22b84401bc427 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -47,6 +47,7 @@ android:name="net.sourceforge.opencamera.MainActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:theme="@style/AppTheme" + android:launchMode="singleInstance" android:clearTaskOnLaunch="true" android:exported="true" > diff --git a/app/src/main/java/net/sourceforge/opencamera/DeviceSettings.java b/app/src/main/java/net/sourceforge/opencamera/DeviceSettings.java index ed6011b1cd7ed2992bc01a722a2b4eb42fa1e5a7..b76e9fcb3174c548151be18c11c90c79409ef041 100644 --- a/app/src/main/java/net/sourceforge/opencamera/DeviceSettings.java +++ b/app/src/main/java/net/sourceforge/opencamera/DeviceSettings.java @@ -38,4 +38,8 @@ public class DeviceSettings { final boolean isOne = Build.DEVICE.equals("one") || Build.DEVICE.equals("X2"); return isMurena && isOne; } + + public static boolean isMurenaTwo() { + return Build.DEVICE.toLowerCase(Locale.US).contains("two"); + } } diff --git a/app/src/main/java/net/sourceforge/opencamera/MainActivity.java b/app/src/main/java/net/sourceforge/opencamera/MainActivity.java index 692599deee5ceb397a2946aa4e29d7c248857c50..19ced8e307d279f6a0eef8cf4f97ec5d16908f5c 100644 --- a/app/src/main/java/net/sourceforge/opencamera/MainActivity.java +++ b/app/src/main/java/net/sourceforge/opencamera/MainActivity.java @@ -105,6 +105,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; @@ -185,6 +186,11 @@ public class MainActivity extends AppCompatActivity { public static volatile boolean test_preview_want_no_limits; // test flag, if set to true then instead use test_preview_want_no_limits_value; needs to be static, as it needs to be set before activity is created to take effect public static volatile boolean test_preview_want_no_limits_value; + private boolean murenaTwoHwKill = false; + + private Handler handler; + private Runnable retryRunnable = null; + // whether this is a multi-camera device (note, this isn't simply having more than 1 camera, but also having more than one with the same facing) // note that in most cases, code should check the MultiCamButtonPreferenceKey preference as well as the is_multi_cam flag, // this can be done via isMultiCamEnabled(). @@ -358,6 +364,8 @@ public class MainActivity extends AppCompatActivity { magneticSensor = new MagneticSensor(this); //speechControl = new SpeechControl(this); + handler = new Handler(); + // determine whether we support Camera2 API // must be done before setDeviceDefaults() initCamera2Support(); @@ -1594,6 +1602,26 @@ public class MainActivity extends AppCompatActivity { else { mainUI.onKeyUp(keyCode, event); } + + if (!camera_in_background && keyCode == 131 && DeviceSettings.isMurenaTwo()) { + String cameraState = Utils.getProperty("persist.sys.hwswitch.state", null); + if (cameraState == null) return super.onKeyUp(keyCode, event); + + if (retryRunnable != null) { + handler.removeCallbacks(retryRunnable); + } + + murenaTwoHwKill = Objects.equals(cameraState, "1"); + retryRunnable = () -> { + if (!murenaTwoHwKill) { + preview.retryOpenCamera(); + } else { + restartOpenCamera(); + } + }; + handler.postDelayed(retryRunnable, murenaTwoHwKill ? 200 : 5000); + } + return super.onKeyUp(keyCode, event); } diff --git a/app/src/main/java/net/sourceforge/opencamera/MyApplicationInterface.java b/app/src/main/java/net/sourceforge/opencamera/MyApplicationInterface.java index 8c3aa4c1a2c8927223fa0046612137d219c56db5..372803e9509ff746b90fba31e087ec21887cd6d2 100644 --- a/app/src/main/java/net/sourceforge/opencamera/MyApplicationInterface.java +++ b/app/src/main/java/net/sourceforge/opencamera/MyApplicationInterface.java @@ -2633,6 +2633,7 @@ public class MyApplicationInterface extends BasicApplicationInterface { @Override public void onCameraError() { + if (DeviceSettings.isMurenaTwo()) return; main_activity.getPreview().showToast(null, R.string.camera_error); } diff --git a/app/src/main/java/net/sourceforge/opencamera/Utils.java b/app/src/main/java/net/sourceforge/opencamera/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..761e8e0d81e994b1a03692ff03f100b1a6631077 --- /dev/null +++ b/app/src/main/java/net/sourceforge/opencamera/Utils.java @@ -0,0 +1,19 @@ +package net.sourceforge.opencamera; + +import android.os.Build; + +import java.lang.reflect.Method; +import java.util.Locale; + +public class Utils { + public static String getProperty(String key, String defaultValue) { + try { + Class systemProperties = Class.forName("android.os.SystemProperties"); + Method get = systemProperties.getMethod("get", String.class, String.class); + return (String) get.invoke(null, key, defaultValue); + } catch (Exception e) { + e.printStackTrace(); + return defaultValue; + } + } +} 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 8c0cda5a2c71f23c9a2b904510e95a72aacf07b7..fd696a7b1d3715880221de62626d21c6be736282 100644 --- a/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java +++ b/app/src/main/java/net/sourceforge/opencamera/ui/DrawPreview.java @@ -31,6 +31,7 @@ import android.view.View; import androidx.annotation.NonNull; +import net.sourceforge.opencamera.DeviceSettings; import net.sourceforge.opencamera.GyroSensor; import net.sourceforge.opencamera.ImageSaver; import net.sourceforge.opencamera.LocationSupplier; @@ -38,6 +39,7 @@ import net.sourceforge.opencamera.MainActivity; import net.sourceforge.opencamera.MyApplicationInterface; import net.sourceforge.opencamera.MyDebug; import net.sourceforge.opencamera.PreferenceKeys; +import net.sourceforge.opencamera.Utils; import net.sourceforge.opencamera.cameracontroller.CameraController; import net.sourceforge.opencamera.preview.ApplicationInterface; import net.sourceforge.opencamera.preview.Preview; @@ -50,6 +52,7 @@ import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.Locale; +import java.util.Objects; import foundation.e.camera.R; @@ -2052,7 +2055,16 @@ public class DrawPreview { p.setTextAlign(Paint.Align.CENTER); int pixels_offset = (int) (20 * scale + 0.5f); // convert dps to pixels if( preview.hasPermissions() ) { - if( preview.openCameraFailed() ) { + String cameraState = Utils.getProperty("persist.sys.hwswitch.state", null); + if (cameraState != null && DeviceSettings.isMurenaTwo() && preview.openCameraFailed()) { + boolean enabled = Objects.equals(cameraState, "1"); + int text1 = enabled ? R.string.failed_to_open_camera_two_1_disabled : R.string.failed_to_open_camera_two_1_enabled; + int text2 = enabled ? R.string.failed_to_open_camera_two_2_disabled : R.string.failed_to_open_camera_two_2_enabled; + canvas.drawText(getContext().getResources().getString(text1), canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, p); + canvas.drawText(getContext().getResources().getString(text2), canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f + pixels_offset, p); + } + + if ( !DeviceSettings.isMurenaTwo() && preview.openCameraFailed() ) { canvas.drawText(getContext().getResources().getString(R.string.failed_to_open_camera_1), canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f, p); canvas.drawText(getContext().getResources().getString(R.string.failed_to_open_camera_2), canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f + pixels_offset, p); canvas.drawText(getContext().getResources().getString(R.string.failed_to_open_camera_3), canvas.getWidth() / 2.0f, canvas.getHeight() / 2.0f + 2 * pixels_offset, p); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a9737d854dc47fec6f95a067294e45ed47623354..bb18ff383dbf521c6506996c2ee7f85645d43a2c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1132,4 +1132,10 @@ Handle this FIDO QR code Use passkey Share with + + "YOUR PRIVACY SWITCH MUST BE ACTIVATED" + "AS THE CAMERA IS NOT AVAILABLE ;-)" + + "PLEASE WAIT 5 SECONDS FOR YOUR CAMERA" + "TO LOAD AS IT'S JUST BEEN ENABLED"