1bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang/* 2bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * Copyright (C) 2012 The Android Open Source Project 3bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * 4bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * you may not use this file except in compliance with the License. 6bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * You may obtain a copy of the License at 7bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * 8bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * http://www.apache.org/licenses/LICENSE-2.0 9bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * 10bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software 11bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS, 12bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * See the License for the specific language governing permissions and 14bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang * limitations under the License. 15bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang */ 16bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 17bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changpackage com.android.gallery3d.app; 18bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 19bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.app.Activity; 20d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Changimport android.content.ContentResolver; 21bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.content.Context; 22bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.content.pm.ActivityInfo; 23bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.content.res.Configuration; 24d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Changimport android.provider.Settings; 25bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.view.OrientationEventListener; 26bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport android.view.Surface; 27bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 282ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Changimport com.android.gallery3d.ui.OrientationSource; 292ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 30bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Changimport java.util.ArrayList; 31bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 322ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Changpublic class OrientationManager implements OrientationSource { 33bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private static final String TAG = "OrientationManager"; 34bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 35bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public interface Listener { 362ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public void onOrientationCompensationChanged(); 37bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 38bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 39bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Orientation hysteresis amount used in rounding, in degrees 40bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private static final int ORIENTATION_HYSTERESIS = 5; 41bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 42bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private Activity mActivity; 43bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private ArrayList<Listener> mListeners; 44bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private MyOrientationEventListener mOrientationListener; 45bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // The degrees of the device rotated clockwise from its natural orientation. 46bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mOrientation = OrientationEventListener.ORIENTATION_UNKNOWN; 47bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // If the framework orientation is locked. 48bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private boolean mOrientationLocked = false; 49bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // The orientation compensation: if the framwork orientation is locked, the 50bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // device orientation and the framework orientation may be different, so we 51bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // need to rotate the UI. For example, if this value is 90, the UI 52bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // components should be rotated 90 degrees counter-clockwise. 53bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private int mOrientationCompensation = 0; 54bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 55d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang // This is true if "Settings -> Display -> Rotation Lock" is checked. We 56d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang // don't allow the orientation to be unlocked if the value is true. 57d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang private boolean mRotationLockedSetting = false; 58d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang 59bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public OrientationManager(Activity activity) { 60bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mActivity = activity; 61bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mListeners = new ArrayList<Listener>(); 62bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationListener = new MyOrientationEventListener(activity); 63bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 64bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 65bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void resume() { 66d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang ContentResolver resolver = mActivity.getContentResolver(); 67d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang mRotationLockedSetting = Settings.System.getInt( 68d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang resolver, Settings.System.ACCELEROMETER_ROTATION, 0) != 1; 69bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationListener.enable(); 70bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 71bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 72bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void pause() { 73bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationListener.disable(); 74bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 75bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 76bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void addListener(Listener listener) { 77bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang synchronized (mListeners) { 78bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mListeners.add(listener); 79bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 80bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 81bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 82bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void removeListener(Listener listener) { 83bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang synchronized (mListeners) { 84bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mListeners.remove(listener); 85bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 86bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 87bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 88bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang //////////////////////////////////////////////////////////////////////////// 89bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Orientation handling 90bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // 91bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // We can choose to lock the framework orientation or not. If we lock the 92bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // framework orientation, we calculate a a compensation value according to 93bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // current device orientation and send it to listeners. If we don't lock 94bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // the framework orientation, we always set the compensation value to 0. 95bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang //////////////////////////////////////////////////////////////////////////// 96bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 97bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Lock the framework orientation to the current device orientation 98bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void lockOrientation() { 99bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mOrientationLocked) return; 100bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationLocked = true; 1015cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck int displayRotation = getDisplayRotation(); 102eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck // Display rotation >= 180 means we need to use the REVERSE landscape/portrait 1035cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck boolean standard = displayRotation < 180; 104bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mActivity.getResources().getConfiguration().orientation 105bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang == Configuration.ORIENTATION_LANDSCAPE) { 106bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang Log.d(TAG, "lock orientation to landscape"); 107eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck mActivity.setRequestedOrientation(standard 108eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE 109eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck : ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); 110bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 1115cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck if (displayRotation == 90 || displayRotation == 270) { 1125cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck // If displayRotation = 90 or 270 then we are on a landscape 1135cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck // device. On landscape devices, portrait is a 90 degree 1145cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck // clockwise rotation from landscape, so we need 1155cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck // to flip which portrait we pick as display rotation is counter clockwise 1165cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck standard = !standard; 1175cca8b99bebe6a9fbb191a8e1364b81e309a1390John Reck } 118bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang Log.d(TAG, "lock orientation to portrait"); 119eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck mActivity.setRequestedOrientation(standard 120eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 121eece6da4d344f7e1e937130c0d36cef8ef9dbe0cJohn Reck : ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); 122bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 123bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang updateCompensation(); 124bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 125bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 126bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Unlock the framework orientation, so it can change when the device 127bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // rotates. 128bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void unlockOrientation() { 129bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (!mOrientationLocked) return; 130d0781ecea9a9ad299c6466a81ef66ab78af9dee3Chih-Chung Chang if (mRotationLockedSetting) return; 131bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationLocked = false; 132bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang Log.d(TAG, "unlock orientation"); 133bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); 134bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang disableCompensation(); 135bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 136bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 137bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Calculate the compensation value and send it to listeners. 138bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private void updateCompensation() { 139bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mOrientation == OrientationEventListener.ORIENTATION_UNKNOWN) { 140bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang return; 141bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 142bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 143bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int orientationCompensation = 144bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang (mOrientation + getDisplayRotation(mActivity)) % 360; 145bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 146bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mOrientationCompensation != orientationCompensation) { 147bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationCompensation = orientationCompensation; 148bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang notifyListeners(); 149bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 150bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 151bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 152bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // Make the compensation value 0 and send it to listeners. 153bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private void disableCompensation() { 154bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mOrientationCompensation != 0) { 155bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientationCompensation = 0; 156bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang notifyListeners(); 157bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 158bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 159bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 160bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private void notifyListeners() { 161bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang synchronized (mListeners) { 162bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang for (int i = 0, n = mListeners.size(); i < n; i++) { 1632ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang mListeners.get(i).onOrientationCompensationChanged(); 164bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 165bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 166bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 167bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 168bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // This listens to the device orientation, so we can update the compensation. 169bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private class MyOrientationEventListener extends OrientationEventListener { 170bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public MyOrientationEventListener(Context context) { 171bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang super(context); 172bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 173bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 174bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang @Override 175bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public void onOrientationChanged(int orientation) { 176bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // We keep the last known orientation. So if the user first orient 177bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // the camera then point the camera to floor or sky, we still have 178bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // the correct orientation. 179bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (orientation == ORIENTATION_UNKNOWN) return; 180bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang mOrientation = roundOrientation(orientation, mOrientation); 181bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // If the framework orientation is locked, we update the 182bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang // compensation value and notify the listeners. 183bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (mOrientationLocked) updateCompensation(); 184bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 185bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 186bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 1872ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang @Override 188bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang public int getDisplayRotation() { 189bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang return getDisplayRotation(mActivity); 190bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 191bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 1922ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang @Override 1932ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang public int getCompensation() { 1942ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang return mOrientationCompensation; 1952ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang } 1962ef46ed28b28b355d7f3f1432c7b1196b832a859Chih-Chung Chang 197bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private static int roundOrientation(int orientation, int orientationHistory) { 198bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang boolean changeOrientation = false; 199bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) { 200bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang changeOrientation = true; 201bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } else { 202bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int dist = Math.abs(orientation - orientationHistory); 203bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang dist = Math.min(dist, 360 - dist); 204bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang changeOrientation = (dist >= 45 + ORIENTATION_HYSTERESIS); 205bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 206bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang if (changeOrientation) { 207bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang return ((orientation + 45) / 90 * 90) % 360; 208bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 209bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang return orientationHistory; 210bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 211bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang 212bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang private static int getDisplayRotation(Activity activity) { 213bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang int rotation = activity.getWindowManager().getDefaultDisplay() 214bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang .getRotation(); 215bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang switch (rotation) { 216bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang case Surface.ROTATION_0: return 0; 217bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang case Surface.ROTATION_90: return 90; 218bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang case Surface.ROTATION_180: return 180; 219bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang case Surface.ROTATION_270: return 270; 220bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 221bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang return 0; 222bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang } 223bd141b5a51c96f6fcaddfa547f0928ce69cf0755Chih-Chung Chang} 224