• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 package com.android.launcher3.states;
17 
18 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
19 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_NOSENSOR;
20 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
21 import static android.util.DisplayMetrics.DENSITY_DEVICE_STABLE;
22 
23 import static com.android.launcher3.Utilities.ATLEAST_NOUGAT;
24 
25 import android.app.Activity;
26 import android.content.SharedPreferences;
27 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
28 import android.content.res.Resources;
29 
30 import com.android.launcher3.R;
31 import com.android.launcher3.Utilities;
32 
33 /**
34  * Utility class to manage launcher rotation
35  */
36 public class RotationHelper implements OnSharedPreferenceChangeListener {
37 
38     public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
39 
getAllowRotationDefaultValue()40     public static boolean getAllowRotationDefaultValue() {
41         if (ATLEAST_NOUGAT) {
42             // If the device was scaled, used the original dimensions to determine if rotation
43             // is allowed of not.
44             Resources res = Resources.getSystem();
45             int originalSmallestWidth = res.getConfiguration().smallestScreenWidthDp
46                     * res.getDisplayMetrics().densityDpi / DENSITY_DEVICE_STABLE;
47             return originalSmallestWidth >= 600;
48         }
49         return false;
50     }
51 
52     public static final int REQUEST_NONE = 0;
53     public static final int REQUEST_ROTATE = 1;
54     public static final int REQUEST_LOCK = 2;
55 
56     private final Activity mActivity;
57     private final SharedPreferences mPrefs;
58 
59     private final boolean mIgnoreAutoRotateSettings;
60     private boolean mAutoRotateEnabled;
61 
62     /**
63      * Rotation request made by {@link InternalStateHandler}. This supersedes any other request.
64      */
65     private int mStateHandlerRequest = REQUEST_NONE;
66     /**
67      * Rotation request made by a Launcher State
68      */
69     private int mCurrentStateRequest = REQUEST_NONE;
70 
71     // This is used to defer setting rotation flags until the activity is being created
72     private boolean mInitialized;
73     public boolean mDestroyed;
74 
75     private int mLastActivityFlags = -1;
76 
RotationHelper(Activity activity)77     public RotationHelper(Activity activity) {
78         mActivity = activity;
79 
80         // On large devices we do not handle auto-rotate differently.
81         mIgnoreAutoRotateSettings = mActivity.getResources().getBoolean(R.bool.allow_rotation);
82         if (!mIgnoreAutoRotateSettings) {
83             mPrefs = Utilities.getPrefs(mActivity);
84             mPrefs.registerOnSharedPreferenceChangeListener(this);
85             mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
86                     getAllowRotationDefaultValue());
87         } else {
88             mPrefs = null;
89         }
90     }
91 
92     @Override
onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s)93     public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
94         mAutoRotateEnabled = mPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
95                 getAllowRotationDefaultValue());
96         notifyChange();
97     }
98 
setStateHandlerRequest(int request)99     public void setStateHandlerRequest(int request) {
100         if (mStateHandlerRequest != request) {
101             mStateHandlerRequest = request;
102             notifyChange();
103         }
104     }
105 
setCurrentStateRequest(int request)106     public void setCurrentStateRequest(int request) {
107         if (mCurrentStateRequest != request) {
108             mCurrentStateRequest = request;
109             notifyChange();
110         }
111     }
112 
initialize()113     public void initialize() {
114         if (!mInitialized) {
115             mInitialized = true;
116             notifyChange();
117         }
118     }
119 
destroy()120     public void destroy() {
121         if (!mDestroyed) {
122             mDestroyed = true;
123             if (mPrefs != null) {
124                 mPrefs.unregisterOnSharedPreferenceChangeListener(this);
125             }
126         }
127     }
128 
notifyChange()129     private void notifyChange() {
130         if (!mInitialized || mDestroyed) {
131             return;
132         }
133 
134         final int activityFlags;
135         if (mStateHandlerRequest != REQUEST_NONE) {
136             activityFlags = mStateHandlerRequest == REQUEST_LOCK ?
137                     SCREEN_ORIENTATION_LOCKED : SCREEN_ORIENTATION_UNSPECIFIED;
138         } else if (mCurrentStateRequest == REQUEST_LOCK) {
139             activityFlags = SCREEN_ORIENTATION_LOCKED;
140         } else if (mIgnoreAutoRotateSettings || mCurrentStateRequest == REQUEST_ROTATE
141                 || mAutoRotateEnabled) {
142             activityFlags = SCREEN_ORIENTATION_UNSPECIFIED;
143         } else {
144             // If auto rotation is off, allow rotation on the activity, in case the user is using
145             // forced rotation.
146             activityFlags = SCREEN_ORIENTATION_NOSENSOR;
147         }
148         if (activityFlags != mLastActivityFlags) {
149             mLastActivityFlags = activityFlags;
150             mActivity.setRequestedOrientation(activityFlags);
151         }
152     }
153 
154     @Override
toString()155     public String toString() {
156         return String.format("[mStateHandlerRequest=%d, mCurrentStateRequest=%d,"
157                 + " mLastActivityFlags=%d, mIgnoreAutoRotateSettings=%b, mAutoRotateEnabled=%b]",
158                 mStateHandlerRequest, mCurrentStateRequest, mLastActivityFlags,
159                 mIgnoreAutoRotateSettings, mAutoRotateEnabled);
160     }
161 }
162