Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41096d3f authored by Mark Harman's avatar Mark Harman
Browse files

Aspect ratio and other fixes in split-screen and multi-window modes.

parent 09204171
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ FIXED Problem where if setting Video Picture Profiles to non-default value cau
        default.
FIXED   Allow trying to switch between photo and video mode if camera fails to open (in some case
        the failure may be specific to the mode).
FIXED   Aspect ratio and other fixes in split-screen and multi-window modes.
ADDED   Support for zoom with camera vendor extensions (for supported Android 13+ devices).
ADDED   Support for displaying on-screen ISO and exposure time with camera vendor extensions (for
        supported Android 13+ devices).
+2 −2
Original line number Diff line number Diff line
@@ -10488,7 +10488,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
        setToDefault();
        int display_orientation = mActivity.getApplicationInterface().getDisplayRotation();
        int display_orientation = mActivity.getApplicationInterface().getDisplayRotation(true);
        Log.d(TAG, "display_orientation = " + display_orientation);
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(mActivity);
@@ -10497,7 +10497,7 @@ public class MainActivityTest extends ActivityInstrumentationTestCase2<MainActiv
        editor.apply();
        updateForSettings();
        int new_display_orientation =  mActivity.getApplicationInterface().getDisplayRotation();
        int new_display_orientation =  mActivity.getApplicationInterface().getDisplayRotation(true);
        Log.d(TAG, "new_display_orientation = " + new_display_orientation);
        assertEquals(new_display_orientation, ((display_orientation + 2) % 4));
    }
+65 −5
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ public class MainActivity extends AppCompatActivity {

    private Preview preview;
    private OrientationEventListener orientationEventListener;
    private View.OnLayoutChangeListener layoutChangeListener;
    private int large_heap_memory;
    private boolean supports_auto_stabilise;
    private boolean supports_force_video_4k;
@@ -475,6 +476,38 @@ public class MainActivity extends AppCompatActivity {
        if( MyDebug.LOG )
            Log.d(TAG, "onCreate: time after setting orientation event listener: " + (System.currentTimeMillis() - debug_time));

        layoutChangeListener = new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                if( MyDebug.LOG )
                    Log.d(TAG, "onLayoutChange");

                if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode() ) {
                    Point display_size = new Point();
                    Display display = getWindowManager().getDefaultDisplay();
                    display.getSize(display_size);
                    if( MyDebug.LOG ) {
                        Log.d(TAG, "    display width: " + display_size.x);
                        Log.d(TAG, "    display height: " + display_size.y);
                        Log.d(TAG, "    layoutUI display width: " + mainUI.layoutUI_display_w);
                        Log.d(TAG, "    layoutUI display height: " + mainUI.layoutUI_display_h);
                    }
                    // We need to call layoutUI when the window is resized without an orientation change -
                    // this can happen in split-screen or multi-window mode, where onConfigurationChanged
                    // is not guaranteed to be called.
                    // We check against the size of when layoutUI was last called, to avoid repeated calls
                    // when the resize is due to the device rotating and onConfigurationChanged is called -
                    // in fact we'd have a problem of repeatedly calling layoutUI, since doing layoutUI
                    // causes onLayoutChange() to be called again.
                    if( display_size.x != mainUI.layoutUI_display_w || display_size.y != mainUI.layoutUI_display_h ) {
                        if( MyDebug.LOG )
                            Log.d(TAG, "call layoutUI due to resize");
                        mainUI.layoutUI();
                    }
                }
            }
        };

        // set up take photo long click
        takePhotoButton.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
@@ -1167,6 +1200,17 @@ public class MainActivity extends AppCompatActivity {
        // and we want to avoid notifications hanging around
        cancelImageSavingNotification();

        if( want_no_limits && navigation_gap != 0 ) {
            if( MyDebug.LOG )
                Log.d(TAG, "clear FLAG_LAYOUT_NO_LIMITS");
            // it's unclear why this matters - but there is a bug when exiting split-screen mode, if the split-screen mode had set want_no_limits:
            // even though the application is created when leaving split-screen mode, we still end up with the window flags for showing
            // under the navigation bar!
            // update: this issue is also fixed by not allowing want_no_limits mode in multi-window mode, but still good to reset things here
            // just in case
            showUnderNavigation(false);
        }

        // reduce risk of losing any images
        // we don't do this in onPause or onStop, due to risk of ANRs
        // note that even if we did call this earlier in onPause or onStop, we'd still want to wait again here: as it can happen
@@ -1423,6 +1467,7 @@ public class MainActivity extends AppCompatActivity {
        mSensorManager.registerListener(accelerometerListener, mSensorAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
        magneticSensor.registerMagneticListener(mSensorManager);
        orientationEventListener.enable();
        getWindow().getDecorView().addOnLayoutChangeListener(layoutChangeListener);

        // if BLE remote control is enabled, then start the background BLE service
        bluetoothRemoteControl.startRemoteControl();
@@ -1556,6 +1601,7 @@ public class MainActivity extends AppCompatActivity {
        mSensorManager.unregisterListener(accelerometerListener);
        magneticSensor.unregisterMagneticListener(mSensorManager);
        orientationEventListener.disable();
        getWindow().getDecorView().removeOnLayoutChangeListener(layoutChangeListener);
        bluetoothRemoteControl.stopRemoteControl();
        freeAudioListener(false);
        //speechControl.stopSpeechRecognizer();
@@ -1669,6 +1715,8 @@ public class MainActivity extends AppCompatActivity {
        // n.b., need to call this first, before preview.setCameraDisplayOrientation(), since
        // preview.setCameraDisplayOrientation() will call getDisplayRotation() and we don't want
        // to be using the outdated cached value now that the rotation has changed!
        // update: no longer relevant, as preview.setCameraDisplayOrientation() now sets
        // prefer_later to true to avoid using cached value. But might as well call it first anyway.
        resetCachedSystemOrientation();

        preview.setCameraDisplayOrientation();
@@ -1797,11 +1845,14 @@ public class MainActivity extends AppCompatActivity {
    }

    /** A wrapper for getWindowManager().getDefaultDisplay().getRotation(), except if
     *  lock_to_landscape==false, this checks for the display being inconsistent with the system
     *  orientation, and if so, returns a cached value.
     *  lock_to_landscape==false && prefer_later==false, this uses a cached value.
     */
    public int getDisplayRotation() {
        if( lock_to_landscape ) {
    public int getDisplayRotation(boolean prefer_later) {
        /*if( MyDebug.LOG ) {
            Log.d(TAG, "getDisplayRotationDegrees");
            Log.d(TAG, "prefer_later: " + prefer_later);
        }*/
        if( lock_to_landscape || prefer_later ) {
            return getWindowManager().getDefaultDisplay().getRotation();
        }
        // we cache to reduce effect of annoying problem where rotation changes shortly before the
@@ -4987,7 +5038,16 @@ public class MainActivity extends AppCompatActivity {

        boolean old_want_no_limits = want_no_limits;
        this.want_no_limits = false;
        if( set_window_insets_listener ) {
        if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && isInMultiWindowMode() ) {
            if( MyDebug.LOG )
                Log.d(TAG, "multi-window mode");
            // don't support want_no_limits mode in multi-window mode - extra complexity that the
            // preview size could change from simply resizing the window; also problem that the
            // navigation_gap, and whether we'd want want_no_limits, can both change depending on
            // device orientation (because application can e.g. be in landscape mode even if device
            // has switched to portrait)
        }
        else if( set_window_insets_listener ) {
            Point display_size = new Point();
            Display display = getWindowManager().getDefaultDisplay();
            display.getSize(display_size);
+3 −2
Original line number Diff line number Diff line
@@ -1458,13 +1458,14 @@ public class MyApplicationInterface extends BasicApplicationInterface {
    /** Returns the ROTATION_* enum of the display relative to the natural device orientation, but
     *  also checks for the preview being rotated due to user preference
     *  RotatePreviewPreferenceKey.
     *  See ApplicationInterface.getDisplayRotation() for more details, including for prefer_later.
     */
    @Override
    public int getDisplayRotation() {
    public int getDisplayRotation(boolean prefer_later) {
        // important to use cached rotation to reduce issues of incorrect focus square location when
        // rotating device, due to strange Android behaviour where rotation changes shortly before
        // the configuration actually changes
        int rotation = main_activity.getDisplayRotation();
        int rotation = main_activity.getDisplayRotation(prefer_later);

        String rotate_preview = sharedPreferences.getString(PreferenceKeys.RotatePreviewPreferenceKey, "0");
        if( MyDebug.LOG )
+12 −1
Original line number Diff line number Diff line
@@ -143,7 +143,18 @@ public interface ApplicationInterface {
    double getCalibratedLevelAngle(); // set to non-zero to calibrate the accelerometer used for the level angles
    boolean canTakeNewPhoto(); // whether taking new photos is allowed (e.g., can return false if queue for processing images would become full)
    boolean imageQueueWouldBlock(int n_raw, int n_jpegs); // called during some burst operations, whether we can allow taking the supplied number of extra photos
    int getDisplayRotation(); // same behaviour as Activity.getWindowManager().getDefaultDisplay().getRotation() (including returning a member of Surface.ROTATION_*), but allows application to modify e.g. for upside-down preview
    /** Same behaviour as Activity.getWindowManager().getDefaultDisplay().getRotation() (including
     *  returning a member of Surface.ROTATION_*), but allows application to modify e.g. for
     *  upside-down preview.
     * @param prefer_later When the device orientation changes, there can be some ambiguity if this
     *                     is called during this rotation, since getRotation() may updated shortly
     *                     before the UI appears to rotate. If prefer_later==false, then prefer the
     *                     previous rotation in such cases. This can be implemented by caching the
     *                     value. prefer_later should be set to false when this is being called
     *                     frequently e.g. as part of a UI that should smoothly rotate as the device
     *                     rotates. prefer_later should be set to true for "one-off" calls.
     */
    int getDisplayRotation(boolean prefer_later);
    // Camera2 only modes:
    long getExposureTimePref(); // only called if getISOPref() is not "default"
    float getFocusDistancePref(boolean is_target_distance);
Loading