• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.util.leak;
18 
19 import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
20 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
21 
22 import android.annotation.IntDef;
23 import android.content.Context;
24 import android.content.res.Configuration;
25 import android.content.res.Resources;
26 import android.view.Surface;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 
31 /**
32  * Utility class that provides device orientation.
33  *
34  * <p>Consider using {@link Surface.Rotation} or add a function that respects device aspect ratio
35  * and {@code android.internal.R.bool.config_reverseDefaultRotation}.
36  *
37  * <p>If you only care about the rotation, use {@link Surface.Rotation}, as it always gives the
38  * counter clock-wise rotation. (e.g. If you have a device that has a charging port at the bottom,
39  * rotating three times in counter clock direction will give you {@link Surface#ROTATION_270} while
40  * having the charging port on the left side of the device.)
41  *
42  * <p>If you need whether the device is in portrait or landscape (or their opposites), please add a
43  * function here that respects the device aspect ratio and
44  * {@code android.internal.R.bool.config_reverseDefaultRotation} together.
45  *
46  * <p>Note that {@code android.internal.R.bool.config_reverseDefaultRotation} does not change the
47  * winding order. In other words, the rotation order (counter clock-wise) will remain the same. It
48  * only flips the device orientation, such that portrait becomes upside down, landscape becomes
49  * seascape.
50  */
51 public final class RotationUtils {
52 
53     public static final int ROTATION_NONE = 0;
54     public static final int ROTATION_LANDSCAPE = 1;
55     public static final int ROTATION_UPSIDE_DOWN = 2;
56     public static final int ROTATION_SEASCAPE = 3;
57 
58     // Not to be confused with Surface.Rotation
59     @IntDef(prefix = { "ROTATION_" }, value = {
60             ROTATION_NONE,
61             ROTATION_LANDSCAPE,
62             ROTATION_SEASCAPE,
63             ROTATION_UPSIDE_DOWN,
64     })
65     @Retention(RetentionPolicy.SOURCE)
66     public @interface Rotation {};
67 
68     /**
69      * @return the current rotation, differentiating between none (rot_0), landscape (rot_90), and
70      * seascape (rot_180). upside down is not distinguished here
71      */
72     @Rotation
getRotation(Context context)73     public static int getRotation(Context context) {
74         int rot = context.getDisplay().getRotation();
75         if (rot == Surface.ROTATION_90) {
76             return ROTATION_LANDSCAPE;
77         } else if (rot == Surface.ROTATION_270) {
78             return ROTATION_SEASCAPE;
79         } else {
80             return ROTATION_NONE;
81         }
82     }
83 
84     /**
85      * @return the current rotation, differentiating between landscape (rot_90), seascape
86      * (rot_270), and upside down (rot_180)
87      */
88     @Rotation
getExactRotation(Context context)89     public static int getExactRotation(Context context) {
90         int rot = context.getDisplay().getRotation();
91         if (rot == Surface.ROTATION_90) {
92             return ROTATION_LANDSCAPE;
93         } else if (rot == Surface.ROTATION_270) {
94             return ROTATION_SEASCAPE;
95         } else if (rot == Surface.ROTATION_180) {
96             return ROTATION_UPSIDE_DOWN;
97         } else {
98             return ROTATION_NONE;
99         }
100     }
101 
102     /** * To string */
toString(@otation int rot)103     public static String toString(@Rotation int rot) {
104         switch (rot) {
105             case ROTATION_NONE:
106                 return "None (0)";
107             case ROTATION_LANDSCAPE:
108                 return "Landscape (1)";
109             case ROTATION_UPSIDE_DOWN:
110                 return "Upside down (2)";
111             case ROTATION_SEASCAPE:
112                 return "Seascape (3)";
113             default:
114                 return "Unknown (" + rot + ")";
115         }
116     }
117 
118     /**
119      * Create a Resources using the specified rotation for the configuration. Use this to retrieve
120      * resources in values or values-land without needing an actual rotation to happen.
121      *
122      * @param rot the target rotation for which to create the resources
123      * @param context a context
124      * @return a Resources object configured for the given orientation
125      */
getResourcesForRotation(@otation int rot, Context context)126     public static Resources getResourcesForRotation(@Rotation int rot, Context context) {
127         int orientation;
128         switch (rot) {
129             case ROTATION_NONE:
130             case ROTATION_UPSIDE_DOWN:
131                 orientation = ORIENTATION_PORTRAIT;
132                 break;
133             case ROTATION_LANDSCAPE:
134             case ROTATION_SEASCAPE:
135                 orientation = ORIENTATION_LANDSCAPE;
136                 break;
137 
138             default:
139                 throw new IllegalArgumentException("Unknown rotation: " + rot);
140         }
141         Configuration c = new Configuration(context.getResources().getConfiguration());
142         c.orientation = orientation;
143         Context rotated = context.createConfigurationContext(c);
144         return rotated.getResources();
145     }
146 }
147