package com.afollestad.materialcamera.util; import android.app.Activity; import android.content.Context; import android.content.pm.ActivityInfo; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.util.Log; import android.view.Surface; import android.view.WindowManager; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * @author Aidan Follestad (afollestad) */ public class Degrees { @IntDef({ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE}) @Retention(RetentionPolicy.SOURCE) @interface ActivityOrientation { } @IntDef({DEGREES_0, DEGREES_90, DEGREES_180, DEGREES_270, DEGREES_360}) @Retention(RetentionPolicy.SOURCE) public @interface DegreeUnits { } public static final int DEGREES_0 = 0; public static final int DEGREES_90 = 90; public static final int DEGREES_180 = 180; public static final int DEGREES_270 = 270; static final int DEGREES_360 = 360; private Degrees() { } @DegreeUnits public static int mirror(@DegreeUnits int orientation) { switch (orientation) { case DEGREES_0: case DEGREES_360: return DEGREES_180; case DEGREES_90: return DEGREES_270; case DEGREES_180: return DEGREES_0; case DEGREES_270: return DEGREES_90; } return DEGREES_0; } @SuppressWarnings("ResourceType") @DegreeUnits private static int naturalize(@DegreeUnits int orientation) { if (orientation == 360) orientation = 0; else if (orientation > 360) { do { orientation = orientation - 360; } while (orientation > 360); } else if (orientation < 0) { do { orientation = 360 + orientation; } while (orientation < 0); } return orientation; } @DegreeUnits public static int getDisplayRotation(Context context) { WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); int rotation = windowManager.getDefaultDisplay().getRotation(); switch (rotation) { case Surface.ROTATION_0: return DEGREES_0; case Surface.ROTATION_90: return DEGREES_90; case Surface.ROTATION_180: return DEGREES_180; case Surface.ROTATION_270: return DEGREES_270; } return DEGREES_0; } @SuppressWarnings("ResourceType") @DegreeUnits public static int getDisplayOrientation(@Degrees.DegreeUnits int sensorOrientation, @Degrees.DegreeUnits int displayOrientation, boolean front) { final boolean isLandscape = isLandscape(displayOrientation); if (displayOrientation == DEGREES_0) displayOrientation = DEGREES_360; int result = sensorOrientation - displayOrientation; result = Degrees.naturalize(result); if (isLandscape && front) result = mirror(result); return result; } @ActivityOrientation public static int getActivityOrientation(@NonNull Activity context) { @DegreeUnits final int rotation = getDisplayRotation(context); switch (rotation) { case DEGREES_0: case DEGREES_360: return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; case DEGREES_90: return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; case DEGREES_180: return ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT; case DEGREES_270: return ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE; default: Log.e("Degrees", "Unknown screen orientation. Defaulting to portrait."); return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; } } public static boolean isPortrait(Context activity) { return isPortrait(getDisplayRotation(activity)); } public static boolean isLandscape(Context activity) { return isLandscape(getDisplayRotation(activity)); } public static boolean isPortrait(@Degrees.DegreeUnits int degrees) { return degrees == DEGREES_0 || degrees == DEGREES_180 || degrees == DEGREES_360; } private static boolean isLandscape(@Degrees.DegreeUnits int degrees) { return degrees == DEGREES_90 || degrees == DEGREES_270; } }