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

Commit 4b9dea3a authored by Doris Liu's avatar Doris Liu Committed by Android (Google) Code Review
Browse files

Merge "Anchor camera controls when flipping device" into gb-ub-photos-bryce

parents b0a1e9fe 5a6cbd17
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -195,6 +195,9 @@ public class ApiHelper {
    public static final boolean HAS_MEDIA_MUXER =
                    Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2;

    public static final boolean HAS_DISPLAY_LISTENER =
            Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR1;

    public static int getIntFieldIfExists(Class<?> klass, String fieldName,
            Class<?> obj, int defaultVal) {
        try {
+70 −18
Original line number Diff line number Diff line
@@ -20,13 +20,15 @@ import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManager.DisplayListener;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;

import com.android.camera.Util;
import com.android.gallery3d.R;
import com.android.gallery3d.common.ApiHelper;

public class CameraControls extends RotatableLayout {

@@ -38,19 +40,40 @@ public class CameraControls extends RotatableLayout {
    private View mMenu;
    private View mIndicators;
    private View mPreview;
    private Object mDisplayListener = null;
    private int mLastRotation = 0;

    public CameraControls(Context context, AttributeSet attrs) {
        super(context, attrs);
        initDisplayListener();
    }

    public CameraControls(Context context) {
        super(context);
        initDisplayListener();
    }

    public void initDisplayListener() {
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            mDisplayListener = new DisplayListener() {

                @Override
    public void onConfigurationChanged(Configuration config) {
        super.onConfigurationChanged(config);
        adjustBackground();
                public void onDisplayAdded(int arg0) {}

                @Override
                public void onDisplayChanged(int arg0) {
                    int currentRotation = Util.getDisplayRotation((Activity) getContext());
                    if ((currentRotation - mLastRotation) % 180 == 0) {
                        flipChildren();
                        getParent().requestLayout();
                    }
                    mLastRotation = currentRotation;
                }

                @Override
                public void onDisplayRemoved(int arg0) {}
            };
        }
    }

    @Override
@@ -64,13 +87,39 @@ public class CameraControls extends RotatableLayout {
        mPreview = findViewById(R.id.preview_thumb);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        adjustControlsToRightPosition();
        mLastRotation = Util.getDisplayRotation((Activity) getContext());
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
            .registerDisplayListener((DisplayListener) mDisplayListener, null);
        }
    }

    @Override
    public void onDetachedFromWindow () {
        super.onDetachedFromWindow();
        if (ApiHelper.HAS_DISPLAY_LISTENER) {
            ((DisplayManager) getContext().getSystemService(Context.DISPLAY_SERVICE))
            .unregisterDisplayListener((DisplayListener) mDisplayListener);
        }
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        int orientation = getResources().getConfiguration().orientation;
        int rotation = Util.getDisplayRotation((Activity) getContext());
        int size = getResources().getDimensionPixelSize(R.dimen.camera_controls_size);
        rotation = correctRotation(rotation, orientation);
        int rotation = getUnifiedRotation();
        adjustBackground();
        super.onLayout(changed, l, t, r, b);
        // As l,t,r,b are positions relative to parents, we need to convert them
        // to child's coordinates
        r = r - l;
        b = b - t;
        l = 0;
        t = 0;
        Rect shutter = new Rect();
        topRight(mPreview, l, t, r, b, orientation, rotation);
        if (size > 0) {
@@ -104,9 +153,11 @@ public class CameraControls extends RotatableLayout {
        }
    }

    private int correctRotation(int rotation, int orientation) {
    private int getUnifiedRotation() {
        // all the layout code assumes camera device orientation to be portrait
        // adjust rotation for landscape
        int orientation = getResources().getConfiguration().orientation;
        int rotation = Util.getDisplayRotation((Activity) getContext());
        int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        if (camOrientation != orientation) {
@@ -241,27 +292,28 @@ public class CameraControls extends RotatableLayout {
    public void adjustControlsToRightPosition() {
        Configuration config = getResources().getConfiguration();
        int orientation = Util.getDisplayRotation((Activity) getContext());
        if (orientation == 270 && config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        if (orientation >= 180) {
            flipChildren();
        }
        if (orientation == 180 && config.orientation == Configuration.ORIENTATION_PORTRAIT) {
            flipChildren();
        }
        adjustBackground();
    }

    private void adjustBackground() {
        int rotation = getUnifiedRotation();
        // remove current drawable and reset rotation
        mBackgroundView.setBackgroundDrawable(null);
        mBackgroundView.setRotationX(0);
        mBackgroundView.setRotationY(0);
        // if the switcher background is top aligned we need to flip the background
        // drawable vertically; if left aligned, flip horizontally
        int gravity = ((LayoutParams) mBackgroundView.getLayoutParams()).gravity;
        if ((gravity & Gravity.TOP) == Gravity.TOP) {
        switch (rotation) {
            case 180:
                mBackgroundView.setRotationX(180);
        } else if ((gravity & Gravity.LEFT) == Gravity.LEFT) {
                break;
            case 270:
                mBackgroundView.setRotationY(180);
                break;
            default:
                break;
        }
        mBackgroundView.setBackgroundResource(R.drawable.switcher_bg);
    }
+54 −50
Original line number Diff line number Diff line
@@ -29,14 +29,14 @@ import android.widget.RelativeLayout;
import com.android.camera.Util;
import com.android.gallery3d.R;

public class CameraRootView extends RelativeLayout
    implements RotatableLayout.RotationListener {
public class CameraRootView extends RelativeLayout {

    private int mTopMargin = 0;
    private int mBottomMargin = 0;
    private int mLeftMargin = 0;
    private int mRightMargin = 0;
    private int mOffset = 0;
    private Rect mCurrentInsets;
    public CameraRootView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // Layout the window as if we did not need navigation bar
@@ -47,64 +47,68 @@ public class CameraRootView extends RelativeLayout
    @Override
    protected boolean fitSystemWindows(Rect insets) {
        super.fitSystemWindows(insets);
        mCurrentInsets = insets;
        // insets include status bar, navigation bar, etc
        // In this case, we are only concerned with the size of nav bar
        if (mOffset > 0) {
            // Add margin if necessary to the view to ensure nothing is covered
            // by navigation bar
            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
            int right, bottom;
            if (insets.right > 0) {
                // navigation bar on the right
                right = mRightMargin > 0 ? 0 : insets.right;
                bottom = 0;
            } else {
                // navigation bar on the bottom
                bottom = mBottomMargin > 0 ? 0 : insets.bottom;
                right = 0;
            }
            lp.setMargins(mLeftMargin, mTopMargin, mRightMargin + right, mBottomMargin + bottom);
            return true;
        }
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        if (mOffset > 0) return true;

        if (insets.bottom > 0) {
            mOffset = insets.bottom;
        } else if (insets.right > 0) {
            mOffset = insets.right;
        }
        Configuration config = getResources().getConfiguration();
        if (config.orientation == Configuration.ORIENTATION_PORTRAIT) {
            mBottomMargin = mOffset;
        } else if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            mRightMargin = mOffset;
        }
        lp.setMargins( mLeftMargin, mTopMargin, mRightMargin, mBottomMargin);
        CameraControls controls = (CameraControls) findViewById(R.id.camera_controls);
        if (controls != null) {
            controls.setRotationListener(this);
            controls.adjustControlsToRightPosition();
        }
        return true;
    }

    @Override
    public void onRotation(int rotation) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        int b = mBottomMargin;
        int t = mTopMargin;
        int l = mLeftMargin;
        int r = mRightMargin;
        rotation = (rotation + 360) % 360;
        if (rotation == 90) {
            lp.setMargins(b, l, t, r);
        } else if (rotation == 270) {
            lp.setMargins(t, r, b, l);
        } else if (rotation == 180) {
            lp.setMargins(r, b, l, t);
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        int rotation = Util.getDisplayRotation((Activity) getContext());
        // all the layout code assumes camera device orientation to be portrait
        // adjust rotation for landscape
        int orientation = getResources().getConfiguration().orientation;
        int camOrientation = (rotation % 180 == 0) ? Configuration.ORIENTATION_PORTRAIT
                : Configuration.ORIENTATION_LANDSCAPE;
        if (camOrientation != orientation) {
            rotation = (rotation + 90) % 360;
        }
        // calculate margins
        int left = 0;
        int right = 0;
        int bottom = 0;
        int top = 0;
        switch (rotation) {
            case 0:
                bottom += mOffset;
                break;
            case 90:
                right += mOffset;
                break;
            case 180:
                top += mOffset;
                break;
            case 270:
                left += mOffset;
                break;
        }
        if (mCurrentInsets.right > 0) {
            // navigation bar on the right
            right = right > 0 ? right : mCurrentInsets.right;
        } else {
            // navigation bar on the bottom
            bottom = bottom > 0 ? bottom : mCurrentInsets.bottom;
        }
        for (int i = 0; i < getChildCount(); i++) {
            View v = getChildAt(i);
            if (v instanceof CameraControls) {
                // Lay out camera controls to fill the short side of the screen
                // so that they stay in place during rotation
                if (rotation % 180 == 0) {
                    v.layout(l, t + top, r, b - bottom);
                } else {
                    v.layout(l + left, t, r - right, b);
                }
            } else {
                v.layout(l + left, t + top, r - right, b - bottom);
            }
        }
        mLeftMargin = lp.leftMargin;
        mTopMargin = lp.topMargin;
        mRightMargin = lp.rightMargin;
        mBottomMargin = lp.bottomMargin;
    }
}