RotationPolicy.java revision 6090995951c6e2e4dcf38102f01793f8a94166e1
1/* 2 * Copyright (C) 2012 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 17package com.android.internal.view; 18 19import android.content.Context; 20import android.content.pm.PackageManager; 21import android.database.ContentObserver; 22import android.net.Uri; 23import android.os.AsyncTask; 24import android.os.Handler; 25import android.os.RemoteException; 26import android.os.UserHandle; 27import android.provider.Settings; 28import android.util.Log; 29import android.view.IWindowManager; 30import android.view.Surface; 31import android.view.WindowManagerGlobal; 32 33/** 34 * Provides helper functions for configuring the display rotation policy. 35 */ 36public final class RotationPolicy { 37 private static final String TAG = "RotationPolicy"; 38 39 private RotationPolicy() { 40 } 41 42 /** 43 * Gets whether the device supports rotation. In general such a 44 * device has an accelerometer and has the portrait and landscape 45 * features. 46 * 47 * @param context Context for accessing system resources. 48 * @return Whether the device supports rotation. 49 */ 50 public static boolean isRotationSupported(Context context) { 51 PackageManager pm = context.getPackageManager(); 52 return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_ACCELEROMETER) 53 && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT) 54 && pm.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE); 55 } 56 57 /** 58 * Returns true if the device supports the rotation-lock toggle feature 59 * in the system UI or system bar. 60 * 61 * When the rotation-lock toggle is supported, the "auto-rotate screen" option in 62 * Display settings should be hidden, but it should remain available in Accessibility 63 * settings. 64 */ 65 public static boolean isRotationLockToggleSupported(Context context) { 66 return isRotationSupported(context) 67 && context.getResources().getConfiguration().smallestScreenWidthDp >= 600; 68 } 69 70 /** 71 * Returns true if the rotation-lock toggle should be shown in the UI. 72 */ 73 public static boolean isRotationLockToggleVisible(Context context) { 74 return isRotationLockToggleSupported(context) && 75 Settings.System.getIntForUser(context.getContentResolver(), 76 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0, 77 UserHandle.USER_CURRENT) == 0; 78 } 79 80 /** 81 * Returns true if rotation lock is enabled. 82 */ 83 public static boolean isRotationLocked(Context context) { 84 return Settings.System.getIntForUser(context.getContentResolver(), 85 Settings.System.ACCELEROMETER_ROTATION, 0, UserHandle.USER_CURRENT) == 0; 86 } 87 88 /** 89 * Enables or disables rotation lock. 90 * 91 * Should be used by the rotation lock toggle. 92 */ 93 public static void setRotationLock(Context context, final boolean enabled) { 94 Settings.System.putIntForUser(context.getContentResolver(), 95 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0, 96 UserHandle.USER_CURRENT); 97 98 AsyncTask.execute(new Runnable() { 99 @Override 100 public void run() { 101 try { 102 IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 103 if (enabled) { 104 wm.freezeRotation(-1); 105 } else { 106 wm.thawRotation(); 107 } 108 } catch (RemoteException exc) { 109 Log.w(TAG, "Unable to save auto-rotate setting"); 110 } 111 } 112 }); 113 } 114 115 /** 116 * Enables or disables rotation lock and adjusts whether the rotation lock toggle 117 * should be hidden for accessibility purposes. 118 * 119 * Should be used by Display settings and Accessibility settings. 120 */ 121 public static void setRotationLockForAccessibility(Context context, final boolean enabled) { 122 Settings.System.putIntForUser(context.getContentResolver(), 123 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, enabled ? 1 : 0, 124 UserHandle.USER_CURRENT); 125 126 AsyncTask.execute(new Runnable() { 127 @Override 128 public void run() { 129 try { 130 IWindowManager wm = WindowManagerGlobal.getWindowManagerService(); 131 if (enabled) { 132 wm.freezeRotation(Surface.ROTATION_0); 133 } else { 134 wm.thawRotation(); 135 } 136 } catch (RemoteException exc) { 137 Log.w(TAG, "Unable to save auto-rotate setting"); 138 } 139 } 140 }); 141 } 142 143 /** 144 * Registers a listener for rotation policy changes affecting the caller's user 145 */ 146 public static void registerRotationPolicyListener(Context context, 147 RotationPolicyListener listener) { 148 registerRotationPolicyListener(context, listener, UserHandle.getCallingUserId()); 149 } 150 151 /** 152 * Registers a listener for rotation policy changes affecting a specific user, 153 * or USER_ALL for all users. 154 */ 155 public static void registerRotationPolicyListener(Context context, 156 RotationPolicyListener listener, int userHandle) { 157 context.getContentResolver().registerContentObserver(Settings.System.getUriFor( 158 Settings.System.ACCELEROMETER_ROTATION), 159 false, listener.mObserver, userHandle); 160 context.getContentResolver().registerContentObserver(Settings.System.getUriFor( 161 Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY), 162 false, listener.mObserver, userHandle); 163 } 164 165 /** 166 * Unregisters a listener for rotation policy changes. 167 */ 168 public static void unregisterRotationPolicyListener(Context context, 169 RotationPolicyListener listener) { 170 context.getContentResolver().unregisterContentObserver(listener.mObserver); 171 } 172 173 /** 174 * Listener that is invoked whenever a change occurs that might affect the rotation policy. 175 */ 176 public static abstract class RotationPolicyListener { 177 final ContentObserver mObserver = new ContentObserver(new Handler()) { 178 public void onChange(boolean selfChange, Uri uri) { 179 RotationPolicyListener.this.onChange(); 180 } 181 }; 182 183 public abstract void onChange(); 184 } 185}